Skip to content

v0.16.0 — UAT gap close: cursor IDE adapter + on-demand history + doctor honesty#22

Merged
cote-star merged 14 commits into
mainfrom
feat/uat-gap-close-prio-1
Jun 3, 2026
Merged

v0.16.0 — UAT gap close: cursor IDE adapter + on-demand history + doctor honesty#22
cote-star merged 14 commits into
mainfrom
feat/uat-gap-close-prio-1

Conversation

@cote-star
Copy link
Copy Markdown
Owner

Summary

Cycle goal: close every gap from the v0.15.0 UAT, then run two fresh-context UAT-review rounds against the changes to make sure they actually hold up.

Result: 6 PRIO-1 scopes (N1-N7) shipped, 9 follow-up fixes (F1-F13) from independent UAT review, 5 R2 defects found by a second review round and fixed. 164 cargo tests + full conformance green. All breaking changes documented.

The headline capabilities for end users:

  • Cursor IDE app sessions are now readable end-to-end (~/.cursor/chats/<hash>/<uuid>/store.db SQLite). Previously chorus could only read cursor-agent CLI transcripts; the IDE surface was invisible.
  • chorus read --history=on-demand is the contracted default. Agents reading the provider snippet at session start now see a top-of-block instruction to NOT eagerly loop prior sessions — closes the 2.5x token-inflation finding from the field study.
  • cwd_mismatch field on read output explicitly flags fallback when --cwd doesn't match any session. No more silent wrong-session returns to JSON-only consumers.
  • Doctor honesty pass: info severity (doesn't elevate overall), env-var dangling-path detection, git-aware hooks checks, stale-snippet detection that flags pre-v0.16.0 setups.

What's in the PR

14 commits, file-disjoint where possible:

v0.16.0 docs (bac6dbe)
R2-defect — round-2 UAT follow-ups (e788a61)
F9/F10/F11/F13 hygiene (616eaec)
F5 provider snippets carry on-demand contract (471fbef)
F6/F7/F8 fixture coverage gaps closed (3b098b5)
F4 read⊆search invariant for every adapter (e622802)
F1 cwd_mismatch structured field + stderr (3dede54)
F2/F3/F12 doctor follow-ups (51d1978)
N7 --history flag scaffold (84879a5)
N6 --tool-calls parity (0336bb4)
N2 codex search extractor parity (24222a6)
N1 Cursor IDE SQLite adapter (5fefa40)
N4 per-subcommand --help (95059fc)
N3 doctor self-consistency (c04f274)

Full per-commit detail is in RELEASE_NOTES.md (v0.16.0 entry at the top of the file).

Breaking changes

Called out explicitly in RELEASE_NOTES, summarized here for review:

  • sessions_cursor doctor check is split into sessions_cursor_cli + sessions_cursor_app. Consumers parsing doctor JSON by check ID need to update.
  • --tool-calls on gemini/hermes now emits a uniform warning in warnings[] (previously silent). The flag still sets included_tool_calls: true.
  • Rust cwd_matches_project no longer treats a session with cwd: "/" as a wildcard match. Real bug fix but flips behavior for any consumer that relied on the old broken matcher.
  • Optional cwd_mismatch: true field added to read output when fallback fires. Schema additive; existing consumers unaffected unless they have strict additionalProperties: false.

Acceptance

  • 164 cargo tests pass (added 3 in cursor_app.rs; was 161 at v0.15.0).
  • Full conformance green, including new cases: read-cursor-app, read-cursor-app-tool-calls, read-cursor-app-redaction, read-{claude,codex}-tool-fixture, read-hermes, read-hermes-tool-calls, read-gemini-tool-calls, read-codex-history-{eager,none}, and 5x search-read-parity <agent>.
  • chorus doctor correctly fires integration_claude_stale against this repo's hand-authored CLAUDE.md (proves stale-snippet detection works on a real not-yet-refreshed managed block).
  • Live Cursor IDE sessions on the dev machine are readable via chorus read --agent cursor --id <uuid> end-to-end, including tool_use rendering with --tool-calls, and redaction applies to SQLite content via the existing redactSensitiveText wrap.

UAT discipline used

Two independent rounds of fresh-context sub-agent UAT review verified the work:

  1. Round 1 (after N1-N7): 6 agents, one per scope. Found 13 follow-up issues (F1-F13) — all addressed in this PR.
  2. Round 2 (after F-fixes): 6 agents, one per F bundle + one regression agent across all N items. Found 5 real defects (R2): Rust matcher root cause, Rust relative_path() symlink bug, missing stale-snippet detection, sparse Rust setup --help, History contract buried mid-block. All addressed.

Acceptance for every scope is in research/next-scopes-post-v0.15.0-2026-06-03.md (gitignored; cited in RELEASE_NOTES credits).

Upgrade notes

Detailed in RELEASE_NOTES; TL;DR:

  • Run chorus setup --force to refresh provider snippets + managed blocks with the on-demand history contract. Doctor will flag stale ones via snippet_<agent>_stale / integration_<agent>_stale until you do.
  • Node 22.5+ recommended for full Cursor IDE app surface (built-in node:sqlite). Older Node gracefully degrades to CLI/JSONL cursor only.
  • Clean up any stale BRIDGE_* or CHORUS_*_DIR env vars pointing at non-existent directories — chorus doctor now flags them via env_override_dangling.

Test plan

  • cargo test --manifest-path cli/Cargo.toml → 164 pass
  • bash scripts/conformance.sh → ends with Conformance complete: Node and Rust outputs match …
  • chorus doctor --json shows new severity levels and no self-contradictions
  • chorus list --agent cursor returns both source: "cli" and source: "app" entries when both surfaces have data
  • chorus read --agent codex --cwd /nonexistent/path --json returns cwd_mismatch: true AND echoes the fallback warning to stderr
  • chorus report --help includes the handoff JSON schema and a copy-pasteable example
  • chorus setup --force on a clean tmpdir produces provider snippets containing "History contract"
  • chorus list --bogus-flag fails closed with "Unknown flag for 'list': --bogus-flag"

🤖 Generated with Claude Code

cote-star and others added 14 commits June 3, 2026 17:43
Two related fixes to make `chorus doctor` a self-consistent diagnostic:

1. Introduce `info` severity for un-setup repos.
   integration_*, snippet_*, setup_intents previously emitted `warn` even
   when the repo had intentionally not been initialized via `chorus setup`
   (e.g. hand-authored CLAUDE.md). They now emit `info` in that state.
   Initialization is detected by INTENTS.md or providers/ presence; the
   bare .agent-chorus/ directory does not count because the messaging
   subsystem creates .agent-chorus/messages/ on first `send`.

2. Reconcile context_pack_hooks_path vs context_pack_pre_push.
   The path check used to warn whenever core.hooksPath != ".githooks",
   while the pre-push check happily reported the hook installed at the
   warned-against path. The two now have one role each:
   - context_pack_hooks_path is informational (info severity); reports
     the effective hooks path (configured value or default `.git/hooks`).
   - context_pack_pre_push is the truth check; warn iff no pre-push hook
     is discoverable at the effective path.

Node + Rust mirror each other. Golden fixture updated for the empty
tempdir conformance scenario. UAT findings P2/P4 from
research/uat-cli-features-2026-06-03.md closed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Restructure printHelp() so `chorus <sub> --help` outputs the
subcommand's usage, options, and examples first — not the global
command blob. The global blob is still emitted for top-level
`chorus --help` and `chorus help`, but per-topic help now answers the
question the user actually asked.

Specific improvements (all from UAT P2/P4):

- `chorus report --help` now includes the handoff JSON schema with
  field-by-field annotations AND a minimal copy-pasteable example.
  The example loads without INVALID_HANDOFF.
- `chorus messages --help` has `--clear` documented above the fold
  (was buried below the global Commands list).
- `chorus doctor --help` documents the four severity levels and the
  overall-elevation rule introduced in the N3 doctor fix.
- Every subcommand's first line is now `Usage: <bin> <sub> ...`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds a second cursor surface alongside the v0.15.0 cursor-agent CLI
JSONL adapter. Sessions stored as SQLite databases under

  ~/.cursor/chats/<dir-hash>/<session-uuid>/store.db

are now first-class citizens of every cursor command (list, read,
search, timeline) at full Node/Rust parity.

Format spec is documented in cli/src/cursor_app.rs:
  - meta(key,value)  hex-encoded JSON {agentId, latestRootBlobId, ...}
  - blobs(id,data)   SHA-256 content-addressed
  - root blob        protobuf-style stream of child SHAs
  - message blobs    {"role","content"} matching Claude's shape so the
                     existing claude/cursor-cli tool-call extractor
                     renders them at parity
  - workspace path   recovered from "Workspace Path:" header in the
                     first user-role message, mirroring cursor-cli's
                     .workspace-trusted/demangle resolution

Changes:

  cli:
    + cli/src/cursor_app.rs   new module: SQLite reader, root-blob
                              protobuf parser, workspace recovery
    M cli/Cargo.toml          add rusqlite 0.31 (bundled feature; no
                              host SQLite dep)
    M cli/src/agents.rs       cursor list/read/search merge both
                              surfaces; expose ConversationTurn +
                              file_modified_iso + cursor_base_dir_public
                              + list_cursor_cli_sessions_count helpers
    M cli/src/doctor.rs       split sessions_cursor into
                              sessions_cursor_cli + sessions_cursor_app;
                              surface checks are presence-only (no cwd
                              filter) to answer "is the surface
                              reachable" not "do we have sessions here"
    M cli/src/timeline.rs     snippet read uses session_id from the
                              listing (not file_stem) — store.db's stem
                              is "store", not the session uuid

  node:
    + scripts/adapters/cursor_app.cjs   SQLite reader using built-in
                                        node:sqlite (Node >= 22.5);
                                        graceful fallback on older Node
                                        leaves the surface invisible
    M scripts/adapters/cursor.cjs       resolve/read/list/search merge
                                        both surfaces; read() detects
                                        store.db by path suffix and
                                        dispatches to the SQLite reader
    M scripts/read_session.cjs          doctor mirrors Rust per-surface
                                        split; uses cursor adapter list
                                        directly (no cwd filter for
                                        surface health)

  schema + fixtures:
    M schemas/list-output.schema.json   optional `source` field (cursor
                                        only): "cli" | "app"
    M fixtures/golden/doctor.json       sessions_cursor_cli +
                                        sessions_cursor_app entries
    + fixtures/golden/read-cursor-app.json   parity baseline for the
                                             SQLite read path
    M fixtures/golden/timeline.json     includes cursor-app fixture row
    + fixtures/session-store/cursor/chats/.../store.db   synthetic
        SQLite fixture covering user/assistant turns, multi-segment
        content, tool_use, and the Workspace Path header
    M scripts/conformance.sh            adds CHORUS_CURSOR_APP_DATA_DIR
                                        env to the parity matrix and a
                                        new read-cursor-app case

164 cargo tests + conformance green (including the new read-cursor-app
golden + cross-surface timeline assertion). UAT P1 from
research/uat-cli-features-2026-06-03.md closed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The codex search path used `extract_assistant_text_jsonl` (Rust) and an
inline reader in `search()` (Node) that both walked a top-level
`{role:"assistant", content:"..."}` schema. No real codex session has
ever used that shape — codex stores assistant messages in nested
envelopes:

    {type:"response_item", payload:{type:"message", role:"assistant",
                                    content:[{text:"..."}, ...]}}
    {type:"event_msg",     payload:{type:"agent_message", message:"..."}}

Effect: `chorus search --agent codex <query>` returned an empty array
for every query against every real codex session. Read worked because
parse_codex_jsonl handles the real format correctly; search was a dead
extractor.

This is the UAT P3 finding from research/uat-cli-features-2026-06-03.md:
"search 'agent-context' returns empty while session contains it".

Fix mirrors parse_codex_jsonl in both runtimes — handles both envelopes,
delegates to the shared extract_text() helper for content arrays, and
falls back to the string form of event_msg messages when present.

Conformance gains a regression test asserting the invariant
read(text) ⊆ search(text-tokens) for both runtimes against the codex
fixture. The invariant generalizes to every adapter; codex is the only
agent that was failing it pre-fix.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ILABLE for gemini/hermes

Two pieces of the --tool-calls parity matrix:

1. Cursor IDE (app) sessions render tool_use / tool_result content
   identical to claude/codex/cursor-cli. The shared claude content
   extractor already handles cursor's content shape (verified in N1);
   this commit just adds the conformance case + golden so the path is
   regression-protected.

2. Gemini and hermes sessions don't carry tool calls in their on-disk
   format. Previously --tool-calls was silently a no-op for these
   agents — the output looked indistinguishable from "this session had
   no tool calls". Now both runtimes emit a uniform warning when
   --tool-calls is requested for an agent that doesn't support it:

     "--tool-calls has no effect for <agent> sessions: this agent's
      transcript format does not carry tool calls."

   `included_tool_calls: true` is still set (the flag was acknowledged);
   the warning is the only behavioral change. This eliminates the
   silent failure mode where a downstream tool would see
   `included_tool_calls: true` and assume tool calls were considered.

Cross-cuts:
  - cli/src/main.rs           agent_has_no_tool_calls helper + dispatcher push
  - scripts/read_session.cjs  AGENTS_WITHOUT_TOOL_CALLS set + dispatcher push
  - gemini.cjs / hermes.cjs   acknowledge --tool-calls in output shape
  - conformance               parity case for cursor-app + gemini --tool-calls

UAT P3 from research/uat-cli-features-2026-06-03.md closed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Adds the `--history=on-demand|none|eager` flag to `chorus read` that
makes the existing on-demand default behavior explicit and contracted:

  on-demand (default): return only the latest session for the cwd.
                       chorus does NOT auto-pull prior sessions; callers
                       use `chorus list / timeline / search` explicitly
                       when they want historical context.
  none:                metadata only (alias for --metadata-only). For
                       consumers that want to know a session exists
                       without paying the content tokens.
  eager:               reserved for a future multi-session merge.
                       Today behaves identically to on-demand and emits
                       a uniform warning so consumers don't silently
                       rely on a behavior chorus doesn't yet implement.

This is N7 from research/next-scopes-post-v0.15.0-2026-06-03.md. The
field-study finding (`research/context-pack-field-findings-2026-03-20.md`
Finding 3) measured a 2.5x token inflation from agents (Claude)
eagerly reading multiple prior chorus sessions at startup. The chorus
binary itself was already on-demand; this flag makes the contract
explicit so consumers can rely on it, and reserves the future surface
for the multi-session merge.

Mirrored across Rust + Node with conformance for both eager (warning
emitted) and none (content nulled) modes. Invalid values fail closed.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three related doctor improvements caught by the independent UAT replay:

F12. Optional adapters report `info` when their data directory is
     absent. cursor_cli, cursor_app, and hermes were all `warn` on
     repos where the user simply hadn't installed the tool — same
     noisy-warn pattern N3 fixed for integration_*. Now `warn` is
     reserved for "directory exists but no sessions" (installed but
     quiet); bare absence is `info`.

F3.  hooks_path + pre_push checks are git-aware. Previously on a
     non-git cwd, `git config core.hooksPath` resolved to the user's
     global value and doctor reported a pre-push hook as installed
     even though the cwd had no `.git/`. Both checks now report
     `info: cwd is not a git repository` in that case.

F2.  New `env_override_dangling` check. When a CHORUS_*_DIR or
     BRIDGE_*_DIR env var points at a non-existent directory, doctor
     emits a `warn` naming the env var, the bound adapter, and the
     dangling path. Previously this misconfiguration produced silent
     partial coverage — sessions just vanished with no signal. The
     N1 reviewer caught this case on the test workstation where the
     legacy bridge env was still set.

Mirrored Rust + Node. hermes_base_dir_public + is_git_repo helpers
added. Doctor golden updated for the empty-tempdir scenario:
sessions_hermes is now `info: Hermes not configured ...`.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tderr

When --cwd is passed but no session matches, adapters fall back to the
latest session and push a "falling back to latest session" warning to
the warnings array. JSON-only consumers that don't scan that array
silently get an unrelated session — the failure mode the N1 reviewer
caught for cursor and which is symmetrically present in codex/claude/
hermes.

Two improvements:

1. New optional `cwd_mismatch: true` field on read output (Rust + Node).
   Detection: Rust threads a `cwd_mismatch` bool from each adapter that
   has the fallback path (codex, claude, cursor, hermes). Node detects
   by phrase-matching the warning string from any adapter. Gemini
   doesn't scope by absolute cwd so the field never fires for it.

2. The fallback warning is also echoed to stderr (`chorus: ...`) so
   humans watching the terminal see it even when stdout is piped into
   another tool.

Schema: `cwd_mismatch` added as optional boolean in
schemas/read-output.schema.json. Absent when no fallback occurred,
so existing goldens are unaffected.

Session struct gains a `cwd_mismatch: bool` field; updated at the
6 Session struct constructions in cli/src/agents.rs.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The N2 fix added a regression test for codex specifically. The same
class of bug — search extractor walking a schema read doesn't —
could silently regress any adapter. Per the F4 follow-up identified
in research/uat-replay-followups-2026-06-03.md, the invariant
read(text) ⊆ search(text-tokens) is now asserted for claude, gemini,
cursor (CLI), and cursor (IDE app) in addition to codex.

Each agent's fixture has a distinctive assistant message string. The
test runs both Node and Rust searches against the full conformance
fixture store and asserts the expected session_id appears in results.
Pre-fix any agent's search extractor could be broken in isolation
and ship; post-fix every adapter is gated by CI on this contract.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Three coverage gaps from the UAT replay (see
research/uat-replay-followups-2026-06-03.md):

F6. Claude + Codex --tool-calls fixtures with real tool_use entries.
    The existing `claude-fixture` / `codex-fixture` JSONLs contain no
    tool_use / function_call entries, so `read-claude-tool-calls` and
    `read-codex-tool-calls` only verified the flag was honored, not
    that the renderer emits `[TOOL: <name>]` blocks. New dedicated
    fixtures `session-claude-tool-fixture.jsonl` and
    `session-codex-tool-fixture.jsonl` exercise the renderer
    end-to-end; new goldens assert the `[TOOL: ...]` block content.

F7. Live hermes fixture. Hermes was scaffolded in the
    AGENTS_WITHOUT_TOOL_CALLS set alongside gemini, but had no on-disk
    test exercising the uniform no-tool-calls warning path. New
    fixture `session-hermes-fixture.jsonl` + two conformance cases
    (`read-hermes`, `read-hermes-tool-calls`) gate the contract in CI.
    Doctor now sees the hermes fixture during conformance and reports
    sessions_hermes: pass (golden updated). The Node hermes env-var
    expectation was corrected to CHORUS_HERMES_DATA_DIR (matched both
    Rust and the adapter); env_override_dangling list extended.

F8. SQLite-redaction fixture. The redaction pipeline applies to both
    cursor surfaces logically (same `redactSensitiveText` wrap), but
    no fixture exercised it on SQLite-sourced content specifically. A
    second cursor IDE store.db fixture (`cursor-app-redaction-uuid`)
    embeds an API-token-shaped string and a Bearer-token-shaped
    string inside the message blobs. New conformance case
    `read-cursor-app-redaction` asserts both runtimes emit
    `[REDACTED]` for the offending substrings.

Side-effects:
  - timeline + list-codex goldens regenerated to incorporate the new
    fixtures (they show up in unscoped listings).
  - doctor golden updated for the hermes-fixture-present case.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The provider snippet template (`.agent-chorus/providers/<agent>.md`)
and the managed block template (the CLAUDE.md / AGENTS.md / GEMINI.md
block) now document the on-demand history contract introduced in N7,
so consumer agents reading the snippet on first session encounter the
rule explicitly rather than only via `chorus read --help`.

Two changes both mirrored across Rust (cli/src/setup.rs) and Node
(scripts/read_session.cjs):

1. Managed block template extended with the missing support-command
   list (diff, audit-redactions, relevance, send, messages) so a
   regenerated block doesn't lose richer hand-authored content.

2. Both templates gain a "History contract" section explaining:
   - `chorus read` defaults to --history=on-demand (latest only)
   - DO NOT eagerly loop prior sessions; the field study measured a
     2.5x token inflation when agents did this.
   - Use `chorus list / timeline / search` for explicit historical
     recall.
   - `--history=eager` is reserved; do not depend on it.

This closes the F5 follow-up. The provider snippet files themselves
live under .agent-chorus/providers/ (gitignored, materialized by
`chorus setup`); the dead reference in CLAUDE.md is no longer a
contract gap because every consumer who runs `chorus setup` ends up
with the contract documented locally.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Four hygiene items the independent UAT reviewers flagged:

F9.  Rust report --help / doctor --help schema parity. Clap's auto-help
     from the doc comment was collapsing the handoff JSON schema into a
     single line. Now both subcommands use long_about with explicit
     formatting so the Rust binary's --help matches Node's for these
     two information-dense surfaces.

F10. Suppress node:sqlite ExperimentalWarning. Every chorus invocation
     that touched the cursor adapter emitted
       (node:NNNNN) ExperimentalWarning: SQLite is an experimental
       feature and might change at any time
     to stderr, corrupting any naive stdout/stderr capture. Replace
     the default warning listener once at module load with one that
     drops only the SQLite Experimental warning and forwards every
     other category through. Verified: `node ... 2>/tmp/log` is now
     empty for the cursor doctor path.

F11. Node parser rejects unknown flags. Hand-rolled getOptionValue +
     hasFlag previously silently ignored typos like `--Json` or
     `--limt 3` — the Rust CLI (clap) already fails closed. A new
     ALLOWED_FLAGS map per subcommand drives validateFlags() at
     dispatch; unknown `--foo` produces "Unknown flag for '<cmd>':
     --foo. Run `chorus <cmd> --help` to see allowed flags."

F13. cli/src/cursor_app.rs dead-code warnings cleared. CursorAppSession
     fields (`name`, `mode`, `created_at_ms`) and `find_session_db` are
     reserved for a future verbose-listing surface; tagged
     #[allow(dead_code)] with comments explaining the intent.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Five real defects + one minor gap surfaced by the fresh-context UAT
round-2 reviewers:

1. Rust cwd_matches_project too permissive (cli/src/agents.rs:1369).
   The hierarchical matcher used `Path::starts_with`, which is
   component-aware and treats root `/` as a prefix of every absolute
   path — meaning a session whose recorded cwd was `/` would silently
   match every --cwd <X> request and short-circuit the cwd_mismatch
   fallback. Rust+codex never reported cwd_mismatch when such a
   session existed in history. Align with Node's algorithm:
   string-based with explicit trailing `/` separator. Now any-path
   sessions don't act as wildcards.

2. Rust relative_path symlink bug (cli/src/setup.rs:604).
   When `chorus setup --cwd /tmp/...` ran on macOS, the managed block
   wrote `Provider snippet: ../../../tmp/.../providers/<agent>.md`
   instead of `.agent-chorus/providers/<agent>.md`. Root cause:
   canonicalize() resolved /tmp -> /private/tmp for `base` but left
   `target` literal because the snippet file didn't exist yet. New
   canonicalize_via_parent() walks up to the nearest existing
   ancestor and re-appends the missing tail, so both paths share a
   canonical prefix.

3. Stale-snippet detection in doctor. A user who ran `chorus setup`
   before v0.16.0 will not have the on-demand history contract in
   their provider snippets or managed blocks, and `chorus setup`
   without --force says "unchanged" and silently leaves them
   outdated. New doctor checks `snippet_<agent>_stale` and
   `integration_<agent>_stale` probe for the load-bearing "History
   contract" phrase; if absent, emit warn with the explicit
   "Run `chorus setup --force` to refresh." remediation.

4. Rust `setup --help` carries the same enumeration as Node — what
   files get created, the teardown reversal note, the global plugin
   caveat. Previously it was flag-list-only.

5. History contract promoted to the top of the managed block so an
   agent reading CLAUDE.md/AGENTS.md/GEMINI.md at session start
   encounters the on-demand rule BEFORE the routing bullets and
   command examples. Violating it is the most expensive failure
   mode (2.5x token inflation); placement reflects that.

6. ALLOWED_FLAGS now covers `trash-talk` and `agent-context` so a
   typo on those subcommands fails closed like every other.

Files: cli/src/agents.rs (matcher), cli/src/setup.rs (relative_path
+ template), cli/src/main.rs (setup long_about), cli/src/doctor.rs
(stale_snippet_checks), scripts/read_session.cjs (mirror).

164 cargo tests + conformance green. Live doctor on this repo
correctly fires `integration_claude_stale` against the hand-authored
CLAUDE.md whose managed block predates v0.16.0.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lockstep version bump 0.15.0 → 0.16.0 across package.json,
cli/Cargo.toml, cli/Cargo.lock.

User-facing docs updated for v0.16.0 capabilities:

README.md
  Cut from 466 lines to a focused marketing landing (progressive
  disclosure). Keeps hook + demos + 60-second quickstart up top;
  consolidates capabilities into one runnable block; adds terse
  "What's New in v0.16.0" section linking to RELEASE_NOTES.
  Removed: stale comparison tables, duplicate demo callouts, full
  flag matrices (CLI_REFERENCE owns those), per-feature deep dives,
  inline Mermaid sequence (kept the SVG), Roadmap section.

docs/CLI_REFERENCE.md
  Authoritative reference. Adds:
  - `--history` (on-demand / none / eager) full semantics table
  - `cwd_mismatch` field semantics + stderr mirror rule
  - Cursor source field (`"cli" | "app"`) + two-surface adapter doc
  - Doctor 4-tier severity model + full check catalogue including
    new v0.16.0 IDs (sessions_cursor_{cli,app}, env_override_dangling,
    snippet_<agent>_stale, integration_<agent>_stale)
  - `report --help` handoff schema cross-link
  - Unknown-flag rejection (F11) section
  - Search invariant section documenting CI-enforced read ⊆ search
  - CHORUS_CURSOR_APP_DATA_DIR env override
  - Setup operations table with History contract enrichment +
    stale-snippet detection callout

PROTOCOL.md
  Bumped to v0.16.0. Adds rules 18-24 covering --history contract,
  cwd_mismatch emission, --tool-calls uniform warning, dual-runtime
  parity, F11 fail-closed unknown flags, search invariant, Cursor
  IDE surface + Node 22.5 graceful fallback. Doctor contract
  rewritten with severity model + check-ID catalogue. JSON Output
  Contract extended with conditional fields and cursor `source`.

RELEASE_NOTES.md
  New top entry for v0.16.0. Structured: headline → highlights →
  what's new (by category: Adapter coverage / Read contract /
  Doctor honesty / Help & docs / Hygiene) → breaking changes →
  upgrade notes → acceptance → known limitations → credits. Maps
  every line back to a commit in main..HEAD. Existing v0.15.0
  entry preserved verbatim below.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
@cote-star cote-star merged commit 664abaf into main Jun 3, 2026
2 checks passed
@cote-star cote-star deleted the feat/uat-gap-close-prio-1 branch June 3, 2026 20:06
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant