Review-debt drain

Regenerated from the project's own files. Reads current state; grades nothing; never hand-edited.

Live, right now

Every figure below was measured by running the named command at the moment this page was built — never read out of the prose underneath, which can go stale between one reading and the next.

ran okOpen review debt (live count — never read this out of STATE.md's prose) · 2026-08-23T15:45:45Z
node -e "import('./projects/ops/skippy-jobs/lib/outside-review-ledger.mjs').then(m=>{const o=m.openDebt({olderThanHours:0});const n=Date.now();console.log('open',o.length,'over24h',o.filter(r=>n-Date.parse(r.at)>864e5).length)})"
open 1 over24h 0
ran okReview-debt guard suite · 2026-08-23T15:45:45Z
node projects/ops/skippy-jobs/_test-review-debt.mjs
🧪 Running self-proof tests...

  ✓ normalizeReview accepts t1/t2/t3 case-insensitive
  ✓ normalizeReview rejects invalid values
  ✓ computeTier t3 for files > 15
  ✓ computeTier t3 for floorAdjacent
  ✓ computeTier t3 for newSystem
  ✓ computeTier t2 for files >= 3
  ✓ computeTier t2 for visibleSurface
  ✓ computeTier t2 for isPlanOrSpec
  ✓ computeTier t1 for single plain file
  ✓ openDebt detects unclosed row aged 25h
  ✓ openDebt excludes closed rows
  ✓ openDebt respects age boundary
  ✓ openDebt returns empty array when file does not exist
  ✓ closeRow throws on invalid verdict
  ✓ openRow REFUSES to write a row with no runId (the exact historical bug)
  ✓ openRow returns the runId it wrote (so a caller can never print "undefined" as success)
  ✓ TWO id-less rows (pre-fix shape) now produce TWO DISTINCT debt entries via derived IDs
  ✓ route-build.mjs's source mints its own real runId and passes it into openRow (structural)
  ✓ (GAP 1a) openRow writes task field and readRows retrieves it
  ✓ (GAP 1b-route) route-build.mjs source carries task field in openRow call (structural)
  ✓ (GAP 1b-cheap) cheap-task.mjs source carries task field in openRow call (structural)
  ✓ (GAP 2c) record-review.mjs exits non-zero when runId has no matching open row
  ✓ (GAP 2d) record-review.mjs exits zero and writes close when open row exists (positive control)
  ✓ (DUP-CLOSE 1) closeRow throws when called a second time for same runId without amend
  ✓ (DUP-CLOSE 2) closeRow succeeds on second close when amend: true is passed
  ✓ (DUP-CLOSE 3) record-review.mjs CLI exits 2 on duplicate close without --amend
  ✓ (DUP-CLOSE 4) record-review.mjs CLI exits 0 with --amend true and writes amended close
  ✓ (DUP-CLOSE 5) regression: two separate closes with DIFFERENT verdicts (live incident shape)
  ✓ effectiveRunId is DETERMINISTIC: same row yields identical id across calls
  ✓ record-review.mjs can CLOSE a row by its derived legacy ID (end-to-end)
  ✓ closing ONE derived legacy row does NOT discharge others (three id-less rows, close one, two remain)
  ✓ openRow records a dispatcher when given, and omits the key when not
  ✓ record-review REFUSES a close whose --by names the recorded dispatcher (exit 2, no close written)
  ✓ record-review ACCEPTS an independent reviewer on a dispatcher-carrying row
  ✓ a row WITHOUT a dispatcher stays warning-only — never fail-closed on missing history
  ✓ (R3) dispatcher X closed --by exactly X → REFUSED (exit non-zero, no close written)
  ✓ (R3) dispatcher X closed --by "X-independent" → ALLOWED (a different actor is never refused for containing a common token)
  ✓ (R3) legacy row WITHOUT dispatcher → close allowed, warning only (never fail-closed on missing history)
  ✓ (R3) an annotated self-close is still refused (dispatcher plus a parenthetical is the same actor)
  ✓ (R3 structural) route-build.mjs openRow call passes dispatcher (the producer half of the refusal)
  ✓ (R3 structural) cheap-task.mjs openRow call passes dispatcher (the producer half of the refusal)

🔍 Checking production debt...

  ✓ Production ledger checked: no unreviewed work older than 24h

42 passed, 0 failed

⚠️ This project's STATE.md has no "## HUMAN CHECKLIST" section yet — per PLAN-6-KANBAN-PM.md's own spec (search "THE CHECKLIST"), the public page shows ONLY that section, never the whole file. Add one: four bold labels — Done, In progress, Pending, Finish line — each with plain bullets (a single line for Finish line).

Source: /Users/nickdeck/Documents/Claude/projects/ops/walkaway/drives/review-debt-drain · generator: projects/ops/project-status-page.py — reads only, never grades.