Review ledger
One row per finding that changed a merge decision. Keep resolved rows; do not delete the history. The reviewer adds a row when a finding blocks, and the author adds the resolution and target when it is fixed or deferred.
Status values: open, fixed, deferred, rejected.
2026-11-06, state-machine and proof batch
| Area | Finding | Status | Resolution or target |
|---|---|---|---|
| Semantic | In-place index.json write can truncate the last complete index | fixed | #227 writes through .tmp, keeps .bak, and serves the backup on read |
| Semantic | Cross-window lease is in-memory; separate windows are not covered | fixed | #237 adds a vault-scoped IndexedDB lease; a store failure fails closed |
| Semantic | Closing the view orphans a running index | fixed | #232 disposes the controller in ChatView.onClose |
| Compaction | Manual /compact audit start can land in a new session during a swap | deferred | Unowned follow-up |
| Compaction | /compact instructions are ignored when it joins an auto run | fixed | #230 returns busy instead of joining with different instructions |
| Compaction | Recovery loads outside the swap queue | deferred | Unowned follow-up |
| Approval | A deny reason equal to STOPPED_APPROVAL_REASON triggers the stop path | fixed | #235 uses an explicit stopped flag |
| Approval | stopRequested and the approval request are not tied to a turn or session token | deferred | Unowned follow-up |
| Plugins | Concurrent install sweeps are not single-flight | fixed | #232 shares one in-flight reload |
| Plugins | A sweep and an install can race on the same stage or backup | fixed | #236 serializes both with one maintenance lock |
| Tests | Two-tab Stop aborting only the active tab has no e2e | fixed | #239 adds a two-tab Stop e2e |
| Session | A failed resource reload invalidated the token while the old session stayed live | fixed | #229 commits the token change only after the reload |
| MCP | A plugin clone's refreshed tokens and challenge never reached mcpState | fixed | #231 writes the clone back before save |
| MCP | A moved mcp.json URL replayed tokens and a challenge minted for the old host | fixed | #231 clears them in resolveMcpServers and reconcile |
| MCP | A "Test connection" challenge was lost for plugin servers | fixed | #231 syncs the changed server before save |
| Tests | Approval e2e could leave .agentic-chat-approval open and cascade ten click failures | fixed | #224 dismisses it in afterEach; beforeEach asserts closed |
| Release | semantic-release could not push its version bump to protected main | fixed | Ruleset plus repo-scoped deploy key; #223 wires the workflow |
| Feature map | Unit-only tests were marked covered | fixed | #221 requires e2e, probe, or replay proof |
| Feature map | 18 source refs pointed at blank lines; command anchors were wrong | fixed | #221 fixes the refs and adds the checker |
| Witness | Loader, timeout, skip, and no-count reds could pass as witnesses | fixed | #220 requires a failed-test count and rejects loader output |
| MCP OAuth | A rejected refresh flight was reused | fixed | #222 adds a retry witness |
| Agent turn | User Stop did not prove a queued follow-up was cleared | fixed | #222 adds the witness |
| Session swap | Duplicate-load test asserted the wrong counter | fixed | #222 asserts one load |
How to add a row
- Copy the reviewer's finding, not the fix.
- Name the user-visible or data-loss impact.
- Use the PR that fixed it, or the structural PR that will.
- If rejected, say why in one sentence.