Skip to content

fix: ledger merge dedupe + L4 quarterly archive rotation - #1418

Merged
BigSimmo merged 10 commits into
mainfrom
cursor/ledger-merge-dedupe-ad64
Jul 30, 2026
Merged

fix: ledger merge dedupe + L4 quarterly archive rotation#1418
BigSimmo merged 10 commits into
mainfrom
cursor/ledger-merge-dedupe-ad64

Conversation

@BigSimmo

@BigSimmoBigSimmo commented Jul 30, 2026

Copy link
Copy Markdown
Owner

Summary

Combines the former #1418 + #1419 work into one PR:

  • Replace stock merge=union with custom merge=ledger (union + exact-row dedupe); install via postinstall / hooks:install.
  • Add npm run ledger:dedupe for checkouts without the driver.
  • Document Run PR anti-churn ledger policy (no ledger-only tips; --supersede on later sweeps).
  • Close #088 (union-driver duplication watch).
  • Ship maturity L4: npm run ledger:rotate; bootstrap archives 1206 pre-2026-07-29 rows into docs/archive/branch-review-ledger-2026-q3.md.
  • ledger:lookup / sweep:branch-ledger / check:branch-review-ledger read and validate the live + archive corpus.
  • Harden CLI entry guards against endsWith("branch-review-ledger.mjs") false-matches.
  • Fix Static PR typecheck: JSDoc types for calendarQuarterStart / rotateLedgerMarkdown.
  • Follow-up polish: maturity progress table L4 → DONE (fix: ledger merge dedupe + L4 quarterly archive rotation #1418); drop L4 from #086 Remaining; capture #126 quarterly rotate reminder; document exact-only dedupe / install-required driver / quarterly rotate practice on the ledger README. Deleted stale cursor/ledger-l4-rotation-ad64 (feat: rotate branch-review ledger into quarterly archives (L4) #1419).

Verification

  • npm run check:branch-review-ledger → ledger merge active; live + archive corpus validated
  • npm run check:outstanding-issues58 open / 63 archived; #088 closed; #126 present; next-id=127
  • npx vitest run tests/repo-hygiene.test.ts42 passed (prior tip)
  • npm run typecheck → clean (JSDoc fix on prior tip)
  • npx prettier --check on touched docs
  • Verification not run: full npm run verify:pr-local (docs/scripts/process scope; gates above cover the change)
  • UI verification not run: no UI/routing/styling change

Risk and rollout

  • Risk: operational — git merge-driver install, package.json scripts, large historical ledger move into archive. Content is preserved, not deleted.
  • Rollback: revert this PR; .gitattributes returns to merge=union; restore single-file ledger from git history if needed.
  • Provider or production effects: None

Clinical Governance Preflight

Not applicable — docs/scripts/process only; no clinical, RAG, ingestion, privacy, or Supabase behavior change.

Notes

Supersedes #1419 (same L4 commits folded in here). Branch is synced with main (merge-tree clean).

Open in WebOpen in Cursor

Replace stock merge=union with a custom ledger driver that unions
concurrent appends and drops byte-identical twins, add ledger:dedupe
for checkouts without the driver, tighten Run PR babysit append policy,
and close#88 now that the residual exact-dupe class is gated.
@supabase

supabaseBot commented Jul 30, 2026

Copy link
Copy Markdown

This pull request has been ignored for the connected project sjrfecxgysukkwxsowpy because there are no changes detected in supabase directory. You can change this behaviour in Project Integrations Settings ↗︎.


Preview Branches by Supabase.
Learn more about Supabase Branching ↗︎.

@coderabbitai

coderabbitaiBot commented Jul 30, 2026

Copy link
Copy Markdown
Contributor

Warning

Review limit reached

You’ve reached a temporary PR review limit under our Fair Usage Limits Policy.

Your recent review volume is higher than typical usage, so adaptive limits are currently applied.

Next review available in:51 minutes

Your organization has reached its usage spending cap. Adjust your spending cap in the billing tab.

How can I continue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews.

How do review limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please refer docs for additional details.

Review details
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 6156dd2e-26b5-435c-8cbc-77ee28f741f7

📥 Commits

Reviewing files that changed from the base of the PR and between 14321d8 and fb8e48e.

📒 Files selected for processing (16)
  • .claude/skills/run-pr/SKILL.md
  • .gitattributes
  • AGENTS.md
  • docs/README.md
  • docs/archive/branch-review-ledger-2026-q3.md
  • docs/branch-review-ledger.md
  • docs/codex-review-protocol.md
  • docs/maturity-backlog-workorders.md
  • docs/outstanding-issues.md
  • package.json
  • scripts/branch-review-ledger.mjs
  • scripts/check-branch-review-ledger.mjs
  • scripts/install-git-hooks.mjs
  • scripts/merge-branch-review-ledger.mjs
  • scripts/sweep-branch-ledger.mjs
  • tests/repo-hygiene.test.ts

Comment @coderabbitai help to get the list of available commands.

Add ledger:rotate to move older dated rows into
docs/archive/branch-review-ledger-<yyyy-qN>.md, teach lookup/sweep/check
to read the archive corpus, bootstrap by archiving pre-2026-07-29 rows,
and mark maturity backlog L4 done. Also fix the CLI entry guard so
check-branch-review-ledger no longer falsely matches as the ledger CLI.
check-branch-review-ledger.mjs ends with branch-review-ledger.mjs, so a
bare endsWith guard can execute the wrong CLI when modules import each
other. Match on a path segment instead.
Single PR ships merge=ledger + ledger:dedupe, Run PR anti-churn policy,
#88 closeout, and quarterly ledger:rotate with live/archive corpus
lookup (80 live + 1206 archived).
@cursorcursorBot changed the title fix: ledger merge driver dedupes exact rows on syncfix: ledger merge dedupe + L4 quarterly archive rotationJul 30, 2026
@github-actions

Copy link
Copy Markdown
Contributor

CI triage

CI failed on this PR. Automated classification of the 2 failed job(s):

  • Static PR checksneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.
  • PR requiredneeds investigation: inspect the failing step and uploaded diagnostics; rerun only after classifying the cause.

Compared with main CI run #6744 (success).

Classification is evidence routing, not permission to ignore a failure. Exact quarantined Playwright identities remain governed by the flake ledger.

TypeScript inferred calendarQuarterStart(value = new Date()) as Date-only
and dropped `before` from rotateLedgerMarkdown's options object, which
failed Static PR typecheck on the hygiene tests.
@BigSimmo
BigSimmo marked this pull request as ready for review July 30, 2026 06:35
@BigSimmo
BigSimmo enabled auto-merge (squash) July 30, 2026 06:35
@BigSimmo
BigSimmo disabled auto-merge July 30, 2026 06:38
@chatgpt-codex-connector

Copy link
Copy Markdown

💡 Codex Review

consttheirs=readFileSync(theirsPath,"utf8");
const{ markdown }=mergeLedgerMarkdown(ours,theirs);

P1 Badge Respect archive rotations in the merge driver

When either merge tip still contains the pre-rotation ledger, ignoring %O and unioning both complete tips restores every archived row to the live file. An exact-target reproducer merging a 1,287-row pre-rotation tip with this commit's 80-row live ledger produced 1,287 live rows, duplicating history across the live and archive corpus while the guard still passes. Use the ancestor to distinguish concurrent appends from rows deliberately removed by rotation; the merge test should cover this scenario.

AGENTS.md reference: AGENTS.md:L145-L147


https://github.com/BigSimmo/Database/blob/60ffc9a8bba5c8d3f1f8f10daf2a5919a08ea746/docs/archive/branch-review-ledger-2026-q3.md#L691
P2 Badge Preserve historical row payloads during rotation

When the generated archive is compared cell-for-cell with the parent ledger, three historical records have changed rather than merely moved. For example, this row changes RAG_EVAL_*_USD_PER_MILLION to RAG_EVAL__\_USD_PER_MILLION and alters the recorded MHSP.* patterns; another archived row loses leading characters from \trustGatedAnswerForClinicalNotes and \test:standalone. This corrupts append-only review evidence, so generate the archive without Markdown reformatting or escape vulnerable payloads, and add a parsed-cell equality check against the source ledger.

AGENTS.md reference: AGENTS.md:L145-L145


exportfunctionrotateLedgerMarkdown(liveMarkdown,{ before, existingArchives =newMap()}={}){
if(!/^\d{4}-\d{2}-\d{2}$/.test(before)){
thrownewError(`before must be YYYY-MM-DD (got ${JSON.stringify(before)})`);

P2 Badge Reject impossible rotation cutoff dates

When an operator mistypes a structurally valid but impossible cutoff such as --before 2026-13-01, this regex accepts it and the lexical comparison moves every 2026 live record into archives instead of refusing the command. The resulting empty live ledger can still pass the guard. Validate that the cutoff is a real calendar date, as the checker already does for record dates, and add a rejection test for impossible month/day values.

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

cursoragentand others added 4 commits July 30, 2026 07:23
…edupe-ad64
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
…edupe-ad64
Co-authored-by: BigSimmo <BigSimmo@users.noreply.github.com>
L4 shipped in #1418. Track a quarterly ledger:rotate reminder so the live
table does not grow unbounded again.
Progress summary table still said OPEN after L4 shipped. Document exact-only
dedupe, install-required merge driver, and quarterly rotate practice.
@BigSimmo
BigSimmo merged commit 41c7433 into mainJul 30, 2026
19 of 20 checks passed
@BigSimmo
BigSimmo deleted the cursor/ledger-merge-dedupe-ad64 branch July 30, 2026 07:47
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
PR #1418 landed its own `#126` (quarterly ledger rotation) on main while
this branch was carrying one — the same unprotected read-modify-write
race archived as #112, hit for the second time in an hour. Main holds
first claim, so its row keeps #126, the phone-scroll CI capture moves to
#127, and the marker advances to 128. Both rows are kept.
check:outstanding-issues: 125 rows (62 open, 63 archived), unique ids,
next-id=128 above the highest.
check:branch-review-ledger: 90 live + 1206 archived, ledger merge active.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XrPbbfU9yWuEjEVypCr4ZQ
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
main's #1418 (ledger merge dedupe + L4 quarterly archive rotation) and #1413
both edited docs/outstanding-issues.md, so this was a real content conflict
rather than staleness: git merge-tree --write-tree confirmed CONFLICT before
any resolution was attempted.
Resolved by taking main's version of the ledger wholesale and re-applying this
branch's five-row archive move on top, so neither side's work is lost:
- from main: #88 and #97 archived, new open row #126 (quarterly ledger
rotation) with queue order 35, the #23 "When" update (release-browser-matrix
no longer blocked by pr-required), the #86 detail update, and the
issues:next-id bump to 127.
- from this branch: #95, #96, #104, #109 and #115 moved from Open items to
Resolved / archive.
No row from either side was dropped, and no id appears in both tables.
Verified: 121 rows (52 open, 69 archived), marker next-id=127 above the highest;
each of #88, #97, #95, #96, #104, #109, #115 resolves to exactly one archive
row and #126 to one open row; zero conflict markers remain.
npm run verify:cheap -> EXIT=0; "Gate-manifest OK: all 29 verify:cheap gates are
enforced in CI"; "Test Files 431 passed (431)"; "Tests 4496 passed | 4 skipped
(4500)". npx prettier --check . -> "All matched files use Prettier code style!"
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YdPS2KhKqz2buzsUgmX3c
BigSimmo pushed a commit that referenced this pull request Jul 30, 2026
GitHub reported this PR dirty, but `git merge-tree --write-tree origin/main HEAD`
exited 0: clean. That is the anti-churn case, not a content fight — GitHub's
server-side merge does not read custom merge drivers, which is already recorded
as ledger #127. So the documented remedy applied: merge locally and push.
`git merge origin/main` then produced a CORRUPT tree and it must not be pushed
as-is. `.gitattributes` sets `merge=union` for this file (added by #1418), and
union keeps both sides of every differing line. Prettier pads these tables to
the widest cell, so a single row's edit re-pads every other row — both sides'
copies of all 128 rows are textually distinct, and union kept both. Result:
every row duplicated, both table headers duplicated, 133 insertions.
`npm run check:outstanding-issues` caught it, failing with 128 duplicate-id
errors, both separator rows reported as non-canonical ids, and all five archived
rows "in BOTH the open and archive tables". The gate #112 added is what stopped
a silently doubled ledger from reaching the PR — it failed closed exactly as
designed.
This is the outcome ledger #127 predicted: it records that `merge=union` is the
wrong fix for this file, with evidence, "so nobody re-proposes it". #1418
enabled it anyway. Union is safe for append-only single-line records like
docs/branch-review-ledger.md; it is actively destructive on a width-padded
table, because padding turns every unrelated row into a conflicting line.
Recovered without a destructive reset: the merge commit and both parents are
kept, only its tree was rebuilt — take origin/main's ledger, re-apply the
five-row archive move, reformat. Proven lossless against origin/main rather
than assumed:
origin/main : 63 open + 65 archived = 128, 0 duplicates
rebuilt : 58 open + 70 archived = 128, 0 duplicates
IDs lost from main: NONE IDs invented: NONE
open == main's open minus the five moved: True
Verified: npm run verify:cheap -> EXIT=0; "Test Files 434 passed (434)";
"Tests 4563 passed | 4 skipped (4567)"; "Outstanding-issues guard passed: 128
rows (58 open, 70 archived), unique ids, next-id=131 above the highest, union
merge active". npx prettier --check . -> "All matched files use Prettier code
style!"
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_011YdPS2KhKqz2buzsUgmX3c
Sign up for freeto 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.

2 participants

@BigSimmo@cursoragent