Tags

Tags give the ability to mark specific points in history as being important
  • v0.36.0

    Release: v0.36.0
    v0.36.0 — the athlete's own health keys, season goals, and cycle C5
  • v0.35.0

    Release: v0.35.0
    v0.35.0 — a run the watch missed, and recovery in the gate
  • v0.34.0

    Release: v0.34.0
    v0.34.0 — the vert floor and the reports render
  • v0.33.0

    Release: v0.33.0
    v0.33.0 — three M items and a decision artifact
  • v0.32.0

    Release: v0.32.0
    v0.32.0 — the last five audit S items
  • v0.31.1

    Release: v0.31.1
    v0.31.1 — the v0.31.0 review lane's fixes
  • v0.31.0

    Release: v0.31.0
    v0.31.0 — four audit gaps closed
  • v0.30.0

    Release: v0.30.0
    v0.30.0 — the everyday routines
  • v0.29.0

    v0.29.0 — the embedder contract
  • v0.28.0

    Release: v0.28.0 — the log reconciles itself
    v0.28.0 — the log reconciles itself
  • v0.27.0

    Release: v0.27.0
    v0.27.0 — the coach reads sleep and weight
  • v0.25.2

    Release: v0.25.2
    v0.25.2 — README rewritten for humans
  • v0.25.1

    Release: v0.25.1
    v0.25.1 — maintenance cycle C3
    
    - Maintenance cycle C3, no behaviour change: the live doc numbers and the fixture-name comments
      truthed up; `scripts/check.sh`'s tier table collapsed to one owner (each tier's label now rides its
      own command) with new witnesses for the Node-floor probe, the armed hook's `SKIP=check` escape and
      the dev `.venv` against `uv.lock`; the mutation sweep's whole-suite `--cross-check` repaired and
      witnessed; `src/batch.py`'s failure boundary covered; C2's eight mutation survivors killed or
      dispositioned (98.5 %, zero survivors); and two class-A dedupes (the plan flip rule written twice
      inside `src/logbook.py`, the `refusal()`/finite-number helpers duplicated across the extension's
      tool groups). A fresh-context review lane read the pass and found three defects, all fixed before
      this tag.
  • v0.25.0

    Release: v0.25.0
    v0.25.0 — coach_doctor
    
    - **`coach_doctor` — one health command for env, credentials, state and version.** Ask for a health
      check (or run `python3 -m src.doctor` from the clone): one read-only digest reports the product
      version and how it is registered, the state dir (git remote, schema vs the shipped one), the engine
      environment, whether the Garmin credential env vars are set (their **names**, never their values)
      and the dev-ticket setup. Every failing check names the exact command to run; the tool writes
      nothing and repairs nothing. Blockers (env, state, schema, credentials) decide the exit code; the
      dev-ticket lane is reported as an optional gap, because a missing `glab` degrades a feature without
      making the install unhealthy.
    
    No state-schema or environment change; the tool set grows to 23.
  • v0.24.0

    Release: v0.24.0
    v0.24.0 — one owner for the state dir and the ticket repo
    
    - **One owner for "which state dir".** The rule existed five times with different fallbacks, `~` was
      expanded in only two of them, and an empty `state_dir=` resolved to the *current working directory*
      in the engine — it read whichever repo the session happened to start in. Now there is one rule —
      `COACH_STATE_DIR` → the config's `state_dir=` → `~/coach-state`, with `~` expanded, a relative value
      made absolute and an empty value treated as unset — owned by `scripts/env_lib.sh`'s
      `coach_state_dir` for the shell, `src/state_path.py` for the engine and mirrored by the extension.
      The same case list runs through all three planes, so editing one alone fails the gate.
    - **One owner for "which ticket repo"** (`COACH_AGENT_TICKET_REPO` → the config's `ticket_repo=` →
      the product default), with the shell and TypeScript copies parity-tested against one fixture.
    - **The extension is inside the "one writer per key" guard.** That rule was enforced for `src/` only
      and the extension's writers were described in a string nothing read; a scan of
      `extensions/coach/*.ts` now fails the gate when the extension composes a state key nobody declared
      — and it caught two stale pointers in the ownership table, now corrected.
    
    No tool, state-schema version or environment change: the env contract (`COACH_*` names and order) is
    unchanged, and the state-dir order the docs always promised is now what the engine does.
  • v0.23.0

    Release: v0.23.0
    v0.23.0 — the live battery's staleness rule
    
    - **The live E2E battery has a staleness rule.** The live tiers — `tests/e2e_garmin_live.sh` and the
      pi-loop T2 — stay human-run on purpose (no Garmin credential in CI), but they are no longer
      unbounded. `scripts/check.sh` now prints one advisory line in its summary: it goes stale when more
      than five releases have shipped since the newest live entry in `tests/E2E.md` § 9, and it always
      reports the newest pi-loop entry's tool coverage against the registry. The line **never changes the
      gate's exit status** — a red gate would block every release on a Garmin 429 — and recording a live
      run in § 9 is what clears it.
    
    No tool, state-schema or environment change.
  • v0.22.0

    Release: v0.22.0
    v0.22.0 — state_migrate's JSON boundary
    
    - **`state_migrate` keeps the engine's JSON-stdio contract on every failure.** It was the one verb
      that could fail as a Python traceback with no JSON on stdout — and it writes files *and* shells to
      git, so that was realistic, not theoretical. Every failure is now one
      `{"ok": false, "code": …, "error": …}` object at exit 1, with a named cause:
      `STATE_DIR_MISSING`, `TEMPLATES_MISSING`, `SCHEMA_UNREADABLE`, `STATE_NEWER_THAN_PRODUCT`,
      `MIGRATION_PATH_MISSING`, `COMMIT_FAILED`, or `MIGRATE_FAILED` for anything unexpected. A missing
      `templates/state` is a named preflight instead of a silently unrefreshed persona.
    - **A skipped normalization is named, not swallowed.** When a step meets a state file it cannot read
      (schema drift) it still leaves it alone and never guesses — but it now records an action of kind
      `skip` and the result carries `"skipped": true`, so a partially normalized state no longer reads as
      an unqualified success. A skipped path is never staged (staging it could sweep up an unrelated
      uncommitted edit of your own), and `update.sh` warns instead of printing "state is current".
    
    No tool, state-schema version or environment change: state files, the schema marker and every
    successful migration write exactly what they wrote before.
  • v0.21.0

    Release: v0.21.0
    v0.21.0 — release notes and honest dependency pins
    
    - **Release notes have an owner.** `CHANGELOG.md` (this file) — one section per release, newest
      first, and the same section is published as the tag's GitLab release body, so there is one text and
      not two. The publication step is part of the release checklist (`docs/ARCHITECTURE.md` § Portability
      & evolution) and `docs/INSTALL.md` § Updating points a returning user here: what changed between two
      tags is now readable without `git log` or the dev index in `ROADMAP.md`.
    - **The extension's `devDependencies` are a declared window, not `"*"`.**
      `@earendil-works/pi-coding-agent@^0.87.1` and `typebox@^1.3.34` are the versions the type-check and
      the test suite are verified against; `tests/test_lock_contract.py` fails when a range floats back to
      `"*"`, when the lock resolves outside the declared range, or when `package.json` and the lock's root
      disagree on the specifier — a pi API change is a red gate, not a silent recompile against an
      untested tree.
    - `tests/spec_audit.py` gains claim I4: the changelog leads with the released version and the
      checklist names the publication step.
    
    No engine, tool, state-schema or environment change.
  • v0.20.0

    v0.20.0 — every plan-row column comes from the header