feat(issues): let a re-prioritisation be expressed through the ledger writer (#313) - #1905
Conversation
… writer (#313) Re-prioritising is the mutation triage performs most often, and it was the one mutation the ledger tooling could not express. AGENTS.md and the ledger both require mutating rows only through the writer — precisely because hand-authored rows produced the width, escaping and wrong-table failures the writer exists to stop — so every demotion had to take the forbidden path. npm run issues:update -- '#151' --pri P3 The gap turned out to be three layers deep, and each one looked fine while the others were broken: 1. scripts/outstanding-issues.mjs — updateIssue's editable map had no `pri` entry, so the Pri cell was unreachable. 2. scripts/ledger-inbox.mjs createRequest — the update payload was built from summary/detail/source only, so even once updateIssue accepted pri, the CLI could not emit it. 3. scripts/ledger-inbox.mjs validateRequest — required one of summary/detail/source, so a pri-only request was rejected before it reached either of the above. A re-prioritisation with no prose change is a legitimate triage edit and now counts on its own. Values are validated against the same P1/P2/P3 set `add` uses, at both the request boundary and the writer, and rejected before the guarded write so a bad value reports itself rather than surfacing as a gate refusal about a malformed row. Deliberately per-row: no bulk re-prioritise mode, because a sweep that moves many rows at once should be visible row by row in review. Every assertion here was mutation-tested rather than merely observed passing. Removing `pri` from the editable map makes the writer throw on a pri-only request; dropping the createRequest passthrough makes the CLI reject it; dropping it from the validator fails the inbox self-test. The writer's own self-test additionally pins that ONLY the Pri cell moves — an off-by-one there would write a priority over the ID or Type cell and still produce a structurally valid row. Verified end to end through the real CLI: `issues:update '#90' --pri P3` queues a valid merge-safe request. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuYJz8hauCsCdx8r4fXiZU
This pull request has been ignored for the connected project Preview Branches by Supabase. |
Warning Review limit reachedYou’ve reached a temporary PR review limit under our Fair Usage Limits Policy. Next review available in:46 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 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 configurationConfiguration used: Path: .coderabbit.yaml Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (3)
Comment |
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01DuYJz8hauCsCdx8r4fXiZU
Summary
AGENTS.mdand the ledger both require mutating rows only through the writer — precisely because hand-authored rows produced the width, escaping and wrong-table failures the writer exists to stop — so every demotion had to take the forbidden path.npm run issues:update -- '#151' --pri P3now works.scripts/outstanding-issues.mjs—updateIssue's editable map had noprientry, so the Pri cell was unreachable.scripts/ledger-inbox.mjscreateRequest— the update payload was built fromsummary/detail/sourceonly, so even onceupdateIssueacceptedpri, the CLI could not emit it.scripts/ledger-inbox.mjsvalidateRequest— required one ofsummary/detail/source, so a pri-only request was rejected before reaching either of the above. A re-prioritisation with no prose change is a legitimate triage edit and now counts on its own.P1/P2/P3setadduses, at both the request boundary and the writer, and rejected before the guarded write so a bad value reports itself rather than surfacing as a gate refusal about a malformed row.No canonical ledger edit. This is scripts-only and fully compatible with the inbox/reconcile architecture:
ledger-inbox.mjsdelegates toupdateIssue, so the fix lands on the live path rather than a superseded one.Verification
npm run verify:pr-local—completed: check:runtime, check:installed-lock-parity, format:changed, lint, typecheck, test, check:rag:fixtures, check:medication-interactions, check:medication-lexicon-report·failed: (none). Build skipped by the runner: "no build-affecting source, config, package, or container changes detected."node scripts/outstanding-issues.mjs --self-testandnode scripts/ledger-inbox.mjs --self-testboth passnpm run issues:update -- '#090' --pri P3→Queued update request at docs/outstanding-issues-inbox/<uuid>.json. It is merge-safe; run npm run issues:reconcile after this PR lands.(the artifact was removed before commit — landing one demotion in isolation would be arbitrary)prifrom the writer's editable map → the writer throwspass at least one of --pri, --summary, --detail, --sourceon a pri-only requestcreateRequestpassthrough → the CLI rejects withupdate requires pri, summary, detail, or sourceprifromvalidateRequest→ the inbox self-test fails--pri --detailcall.UI verification not run: no UI surface is touched; the change is two Node scripts and their self-tests.
Risk and rollout
guarded(), which re-runs the ledger gate against its own output before writing. An invalid priority is rejected at two independent points.git reverton the single commit. No ledger state changes, so nothing to unwind.Notes
Provenance: this work was originally done on
claude/ledger-tasks-fable-xhl7xb(PR #1890). That PR was closed without merging and its branch deleted, so none of it reachedmain— I confirmed that directly (git show origin/main:scripts/outstanding-issues.mjs | grep -c 'pri: 1'→ 0, and none of the sweep's rows are archived onmain). This PR carries only the code, re-verified against currentmain, and drops the ledger edits that made #1890 unlandable under the new write-discipline gate.The
#313tracking row does not exist onmain— it was only ever in the closed PR's ledger, so there is no row to close here. Same for#314/#316. The findings they recorded are preserved in this PR body and in PR #1902's; re-filing them belongs in a reconciliation pass rather than a scripts PR.🤖 Generated with Claude Code
https://claude.ai/code/session_01DuYJz8hauCsCdx8r4fXiZU
Generated by Claude Code