docs(ledger): add a generated index and archival policy for branch-review records - #2524
Conversation
…view records docs/branch-review-records/ holds 576 immutable records whose filenames are raw SHA-256 content addresses, so the directory is unnavigable by hand. The hash-filename -> review-row join existed in no static artifact: the repo-awareness generator reads each record's path and drops it, keeping only the six cells. Add docs/branch-review-index.md, generated by `npm run ledger:index` from the existing corpus reader (listLedgerRecordPaths + parseLedgerRows, never a second parser). It carries a summary, a newest-first table of all 576 records linking each back to its file, and a section grouping repeated (ref, head) pairs so supersession chains are visible. Deliberately not a gate. Records are appended ~26 a day, so a byte-equality drift check would redden main after nearly every merge and conflict between concurrent PRs -- the same reasoning already recorded at check-repo-awareness-snapshot.ts:21-28, which excludes review_state from comparison for exactly this. `ledger:index:check` is advisory and wired into no gate; docs:update refreshes the file; ledger:lookup stays authoritative. Tests pin generator behaviour (escaped-pipe parsing, truncation that cannot split `\|` or leave a dangling backslash, total sort order, full corpus coverage) rather than committed bytes. One incidental gain: linking every record makes docs:check-links the first enforcement of the never-delete-a-record rule, which policy forbids (codex-review-protocol.md:65) but no gate previously caught. Add docs/branch-review-archival-policy.md recording what may and may not be done here, with the enforcing code quoted, so it is not re-derived. Editing a row and compacting records are blocked by code; deletion is forbidden and nearly unenforced; and moving records into subdirectories is silent data loss, because the only reader is a non-recursive readdirSync filtered to *.record.md, so a nested record vanishes from every consumer while all gates still pass green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
|
Important
This repository does not receive automatic reviews because it has fewer than 10 stars. ⚙️ Run configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Team Run ID: Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
|
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_fc614172-b2e7-4e41-90ca-11269a7646a8) |
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
The PR policy check passed while the PR was a draft only because
.github/workflows/pr-policy.yml returns early on drafts (":68-71"), so
the first real evaluation happened when the PR was marked ready and it
failed: regenerating data/repo-awareness-snapshot.json and
data/outstanding-issues-snapshot.json classifies the diff as
clinical-risk, which requires a complete "Clinical Governance Preflight"
section that the body did not carry.
Add PR_POLICY_BODY.md so the sync-pr-policy-body job applies the
corrected description from the branch rather than needing a manual edit.
The template deliberately omits the GOVERNANCE_PREFLIGHT placeholder,
because that placeholder renders every item from the boxes already
checked in the existing body and would therefore emit all seven
unchecked.
Each governance item is confirmed against the diff rather than assumed:
no file under src/, worker/, supabase/ or src/lib/rag/ is touched, the
Supabase integration reported no changes in the supabase directory, and
both secret scanners passed.
Reproduced offline with evaluatePullRequestPolicy against the real
changed-file list: 1 blocking error before, 0 after. The single
remaining warning (operational and clinical paths bundled) is advisory
and is explained in the body: package.json and the regenerated snapshots
must land with the generator they describe.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Resolves the two conflicts the PR mergeability check reported. Confirmed a real conflict with git merge-tree first rather than trusting the GitHub label, per the anti-churn guidance in AGENTS.md. docs/README.md: kept main's subdirectory table, which adds the agents/ row from the instruction-surface tiering (#2523), and re-inserted the branch-review-records/ row this branch adds, before archive/. data/repo-awareness-snapshot.json and docs/branch-review-index.md: regenerated with their own generators rather than hand-resolved. Main added review record 9b97c2e6, so the index genuinely needed rebuilding — the first live demonstration of the staleness this branch documents and deliberately does not gate. data/outstanding-issues-snapshot.json is left at main's committed version. Regenerating it here only rewrote the `pending` block to absorb the inbox request main added, and check:outstanding-issues excludes `pending` from comparison, so the regeneration was unrelated churn on a file two concurrent ledger PRs already contend over (#Y090R5). The gate reports it in step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
CI triageCI failed on this PR. Automated classification of the 2 failed job(s):
Compared with main CI run #14836 (success). Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger. |
Two things this resolves. Merge conflict: main advanced to 686ce37 and conflicted on data/repo-awareness-snapshot.json only. Regenerated it and docs/branch-review-index.md with their own generators rather than hand-resolving. data/outstanding-issues-snapshot.json is taken from main, which reconciled its queued ledger requests in a4a95ec. CI failure (Unit coverage, 1 of 12080 tests): ci-cache-safety.test.ts requires every suite that loads a committed workflow file to appear in the test:ci-workflows focused script, and tests/branch-review-index.test.ts reads .github/workflows/ci.yml at line 231 to assert this change wires no gate into CI. Registered it rather than dropping the assertion: that negative check is what would catch someone later adding the index to CI and reintroducing the drift-gate churn this branch exists to avoid, so it belongs in the suite that runs when workflows change. Verified by reproducing the failure and the fix: npx vitest run tests/ci-cache-safety.test.ts tests/branch-review-index.test.ts -> Test Files 2 passed (2), Tests 79 passed (79). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_966c9a4b-c2dc-4aaf-a2ae-da39f9602358) |
main's #2553 (smart test selection) added tests/browser-test-plan.test.ts to test:ci-workflows on the same line this branch added tests/branch-review-index.test.ts, so package.json conflicted on that one script. Both suites load a committed workflow file and both are required there by ci-cache-safety.test.ts, so the resolution is the union, not a choice: main's list with branch-review-index re-inserted. Verified the union rather than assuming it: npx vitest run tests/ci-cache-safety.test.ts tests/branch-review-index.test.ts tests/browser-test-plan.test.ts -> Test Files 3 passed (3), Tests 134 passed (134). docs/branch-review-index.md, data/repo-awareness-snapshot.json and docs/scripts-index.md regenerated with their own generators. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
main's #2530 ("stop the two generated snapshots conflicting on every PR") rewrote both snapshot generators and their checkers, which moved code this branch's policy document quotes by file and line. Conflicts were confined to the two generated files; both were regenerated with the merged generators rather than hand-resolved. Three citations in docs/branch-review-archival-policy.md had gone stale and are corrected: - generate-repo-awareness-snapshot.ts:314 -> :323 (REVIEW_RECORDS_PATHSPEC) - generate-repo-awareness-snapshot.ts:379-386 -> :388-395 (fs fallback) - check-repo-awareness-snapshot.ts:21-28 -> :22-41 (the review_state exclusion) The third mattered for more than its line numbers. #2530 inserted a paragraph inside the block this document quotes, and the old elided quote skipped it silently. That paragraph is the sharper lesson and is now quoted and answered: excluding a key from comparison was not enough on its own, because the un-compared content still conflicted on every append, which sets mergeable_state=dirty and leaves the check list empty rather than red. The document now states why the index avoids that trap for a structural reason rather than by luck — nothing regenerates it on an ordinary PR — and what would have to change first if that ever stopped being true. All 16 code citations in the document were re-checked against the merged tree and resolve to real line ranges. The PR body's citation and its verification evidence are refreshed to this tree rather than left describing the original run. Verified: 7 test files, 245 tests passed; typecheck 6025 files; policy evaluator 0 blocking errors; ledger, snapshot, links, inventory and index gates all green. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_edbed845-c7f2-4d39-84f2-19cbc4ada9c0) |
main advanced to a68f34a (#2520, five ledger items) and conflicted on data/repo-awareness-snapshot.json only. Regenerated that snapshot and docs/branch-review-index.md with their own generators; .prettierignore auto-merged, since #2520 added a rationale comment beside the entry this branch contributes rather than changing it. Auto-merge is armed on this PR and is user-owned, so this is an ordinary merge-main-in sync to unblock it: no force-push, no history rewrite, no change to the auto-merge state or the base. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
The merge of origin/main (f2c8d6c) was conflict-free; this only regenerates data/repo-awareness-snapshot.json for the four inbox requests that merge brought in, so check:repo-awareness-snapshot stays in step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_e2c790be-bff9-4429-b2de-05ef833da896) |
Conflict-free merge of origin/main. Regenerates docs/branch-review-index.md (main added review records) and data/repo-awareness-snapshot.json (main added inbox requests) so both gates stay in step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Conflict-free merge of origin/main; regenerates the review index and the repo-awareness snapshot so both gates stay in step. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
main's #2536 appended tests/bundle-budget-refresh-workflow.test.ts to test:ci-workflows on the same line this branch adds tests/branch-review-index.test.ts, so package.json conflicted there for the second time. Same resolution as before, and for the same reason: both suites load a committed workflow file, ci-cache-safety.test.ts requires every such suite to be listed, so the union is correct and dropping either would silently stop that suite running. Verified rather than assumed: npx vitest run tests/ci-cache-safety.test.ts tests/branch-review-index.test.ts tests/bundle-budget-refresh-workflow.test.ts tests/browser-test-plan.test.ts -> 151 tests passed. docs/scripts-index.md, docs/branch-review-index.md and data/repo-awareness-snapshot.json regenerated with their own generators. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Conflict confined to data/repo-awareness-snapshot.json; regenerated with its own generator rather than hand-resolved, along with the review index. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Bugbot couldn't run - usage limit reachedBugbot is counted against Cursor usage for this user or team, and this run hit a usage or spend limit. A user or team admin can review and increase usage limits in the Cursor dashboard. (requestId: serverGenReqId_3867d838-6a62-42f0-8e15-870bb4deeabb) |
Conflicts confined to data/repo-awareness-snapshot.json and docs/scripts-index.md; both regenerated with their own generators rather than hand-resolved, along with the review index. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
Conflict confined to data/repo-awareness-snapshot.json; regenerated with its own generator, along with the review index. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF
.prettierignore was a real conflict, not a generated one: main's #2524 added docs/branch-review-index.md at the same place this branch added docs/branch-review-records/. Both entries are wanted — one protects a generated index from table repadding, the other protects content-addressed records whose filenames are SHA-256 hashes of their own content — so both were kept. check:branch-review-ledger passes on the result. The two snapshots and docs/scripts-index.md were generated: took main and re-ran their generators. Verified: check:mockups (all three modes), check:gate-manifest, the ledger guard, check:diff-integrity, both snapshot gates, sitemap:check, docs:check-inventory, and prettier on every changed file. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015UPvNZYvyuDxc1o7xfTGCS
PR #2524 landed a generated index over docs/branch-review-records/ after this branch was cut, so merging main in left the index one record short of the tree. Regenerated with scripts/generate-branch-review-index.mjs rather than edited by hand. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Cq952TVk67XZzJnjiKt5pU
Summary
docs/branch-review-index.md, a generated, human-readable index of the 577 immutable records indocs/branch-review-records/. Every filename there is a raw SHA-256 content address, so the directory cannot be navigated by hand, and the hash-filename to review-row join existed in no static artifact:scripts/generate-repo-awareness-snapshot.tsreads each record's path inreadReviewRecordRowsand then discards it inbuildReviewStateSection, emitting only the six cells. The index supplies that missing join.scripts/generate-branch-review-index.mjs(npm run ledger:index, refreshed bynpm run docs:update) plustests/branch-review-index.test.ts. The generator reuses the existing corpus reader —listLedgerRecordPathsandparseLedgerRowsfromscripts/branch-review-ledger.mjs— rather than adding a third parser, which matters because four records carry escaped pipes that a naive split on the pipe character would mis-parse.docs/branch-review-archival-policy.md, recording what may and may not be done to the append-only corpus with the enforcing code quoted at file and line, so the constraint is not re-derived by the next session.docs/README.md, extenddocs/branch-review-records/README.mdwith pointers, add the index toGENERATED_CATALOGSinscripts/check-stale-docs.mjsand to.prettierignore, and refresh the generateddocs/scripts-index.mdanddata/repo-awareness-snapshot.json.Deliberately not a gate. Records are appended at roughly 26 a day (576 records spanning only 2026-08-12 to 2026-09-02, 570 of them in August). A byte-equality drift check on a file derived from that corpus would turn
mainred after nearly every merge and would conflict between concurrent pull requests. This is not a new judgement:scripts/check-repo-awareness-snapshot.ts:22-41already excludesreview_statefromCOMPARED_CONTENT_KEYSfor exactly this reason. So nothing is added toverify:cheap:internal, CI,verify-pr-local.mjs, or the pre-commit hook;ledger:index:checkis advisory; andnpm run ledger:lookupremains authoritative for "has this ref been reviewed?". The index states its own possible staleness in its header.Scope note — no archival. The task also asked whether records could be archived. They cannot, and the policy document records why with the code quoted. Editing a row is blocked (
check-branch-review-ledger.mjs:379-381recomputes the filename as the sha256 of the row); compacting rows into one file is blocked (:374-377); deletion is forbidden bydocs/codex-review-protocol.md:65and caught by nothing. Moving records into subdirectories is the dangerous one: the only reader is a non-recursivereaddirSyncfiltered to*.record.md(branch-review-ledger.mjs:172-180), so a nested record disappears fromledger:lookup, fromcheck:branch-review-ledger, and from the repo-awareness snapshot while every gate still passes green. No gate was weakened, exempted, or bypassed.One incidental gain: because the index links every record relatively,
npm run docs:check-linksnow resolves 578 more references than before, which makes it the first — partial — enforcement of the never-delete-a-record rule. It only catches deletions of records the index already lists, and the policy document says so rather than overstating it.Verification
Local gates were selected to match the change (documentation, a new offline generator, and generated-document machinery) rather than running a broad gate that covers no plausible failure path here. All output quoted below is verbatim.
npm run check:ledger-write-discipline—Ledger write discipline passed for c0ee4ddd5fdd..HEAD.npm run check:branch-review-ledger—Branch review ledger guard passed: 880 live table records + 1206 archived + 577 immutable (880 under the 2026-07-29 machine-readable contract), immutable review writes, six cells each, no conflict markers, mojibake, heading records, or duplicates.npm run check:outstanding-issues—[snapshot] in step with data/outstanding-issues-snapshot.json (70 open, 0 pending)npm run check:repo-awareness-snapshot—[repo-awareness] in step with data/repo-awareness-snapshot.json (204 pages, 578 documents, 2663 reviews)npm run docs:check-links—docs link check passed: 5412 repo path references resolve.npm run docs:check-scripts—docs script-ref check passed: 1222 npm-run reference(s) resolve to real scripts.npm run docs:check-inventory—Docs inventory current: 285 script files, 289 npm scripts.npm run ledger:index:check—[ledger:index] docs/branch-review-index.md is current.npm run format:check—All matched files use Prettier code style!npm run typecheck— exit 0,[gate-receipts] recorded a pass for "typecheck:internal" (6025 input files).npx eslint scripts/generate-branch-review-index.mjs tests/branch-review-index.test.ts— exit 0, no output.npx vitest run tests/branch-review-index.test.ts—Test Files 1 passed (1),Tests 22 passed (22)npx vitest run tests/branch-review-index.test.ts tests/ci-cache-safety.test.ts tests/browser-test-plan.test.ts tests/docs-inventory.test.ts tests/repo-hygiene.test.ts tests/site-map.test.ts tests/repo-awareness-generator.test.ts—Test Files 7 passed (7),Tests 245 passed (245)Verification not run:
npm run verify:pr-local,npm run verify:uiandnpm run verify:releasewere deliberately skipped. The focused gates above cover this diff's plausible failure paths, no UI, routing, styling or browser behaviour changed, and no release confidence is claimed. CI remains the authoritative merge gate.No provider-backed gate was run. Nothing touching OpenAI, Supabase, live CI, or any paid API was executed.
Two defects were found and fixed during verification rather than being left for CI: a stray NUL byte embedded in the generator's supersession-key separator, which made
greptreat the source file as binary, replaced with its escape sequence; and a TypeScript error in the test fixture, whose spread through aRecord<string, string>cast erased thehashproperty.Risk and rollout
docs/branch-review-index.md— it contains a singlewriteFileSyncand no rename or unlink call, and it never modifies anything underdocs/branch-review-records/. Nothing was added to any verification gate, so no existing gate changes behaviour. The one edit to an existing script is a single new entry in the advisoryGENERATED_CATALOGSlist inscripts/check-stale-docs.mjs.src/lib/rag/, no retrieval RPC, no ranking surface, no golden fixture, and no eval harness file is touched by this diff.Clinical Governance Preflight
This diff is documentation and offline tooling. It is classified clinical-risk solely because it regenerates
data/outstanding-issues-snapshot.jsonanddata/repo-awareness-snapshot.json, which the path classifier treats as clinical data exports. Both regenerations are mechanical output of committed generators, required because this change adds two documents; no clinical content, answer path, or access rule is touched. Each item below is confirmed against the actual diff, not assumed.Clinical KB Database(sjrfecxgysukkwxsowpy)Evidence for the above: no file under
src/,worker/,supabase/, orsrc/lib/rag/is in this diff; the Supabase integration bot confirmed on this PR that it detected no changes in thesupabasedirectory; Gitleaks and GitGuardian both passed; and no clinical decision-support behaviour changed, so the TGA SaMD classification is unaffected.Notes
The policy check reports one advisory warning that is accurate and not worth splitting the PR over: operational-risk and clinical-risk paths are bundled, because
package.json(two new npm scripts) and the regenerateddata/snapshots must land in the same commit as the generator they describe. Splitting them would leave either the snapshot stale or the scripts unregistered, and each half would fail its own gate.The index is 644 lines and about 172 KB, roughly 0.6% of the documentation tree — a real but small cost, stated plainly in the policy document alongside the growth figures rather than glossed over. The archival-policy document's size measurements are quoted with the measuring method (
du -shversusdu -sh --apparent-sizediffer by about 6 MB across thousands of small files), so a later reader does not "correct" one figure into the other.A repo audit of the diff found no defects; its residual observations — the size-measurement ambiguity and a missing curated entry in
docs/scripts-index.md— were both fixed before the first push.🤖 Generated with Claude Code
https://claude.ai/code/session_01AxPVZhAvzE2YupMiDz8sqF