Skip to content

Review debt on merged PRs, and the two structural causes behind it #317

Description

@lamemustafa

Eleven review findings are open on already-merged code. This issue aggregates them so they stop being invisible, and records the two structural causes, both measured rather than asserted.

The debt

PR open what
#303 3 P1 restrict X preservation to real mask shapes · P2 uniqueness on downstream party keys · P2 decode pdftotext output as UTF-8
#305 2 P2 preserve POSIX output symlinks during replacement · P2 keep staged replacements inside the rollback
#306 4 P1 exclude the unverified case direction · P1 remove NFC from the active Phase 2 prompt · P1 remove the surviving fingerprint prescription · P2 plan cites the wrong sections
#307 1 P2 mark composed transformations as unverified
#312 1 P2 restore distinct wrong-tails per header field

In flight: #314 covers #306's four. #316 covers two of #303's three; the third is recorded in the test file as a measured limitation with its reproduction, because a correct fix needs the fabricator to be uniquely decodable after whitespace removal and that is a redesign, not a guard.

Now answerable with evidence that did not exist when it was raised: #307's composed-transformations wording. The master-binding lane has since measured eight composed variants against licensed 7.1 — all matched — plus a poisoning test showing an unmeasured axis (en dash) still refuses however much measured folding surrounds it.

Not started: #305's two, #312's one.

Cause 1 — merging before the reviewer had answered

The direct cause, and it is entirely a process failure on the merging side.

PR merged after opening threads that arrived after the merge
#309 2.4 min 0 — no review had run at all
#312 5.8 min 1 — 3 seconds after the merge
#300 6.1 min 4
#304 7.6 min 2

The pre-merge check counted unresolved review threads, got zero, and read that as reviewed clean. On a six-minute-old PR it means not reviewed yet. Codex takes roughly six minutes.

Fixed. The gate now requires positive evidence that a review names the current head SHA. Note the subtlety that cost a second iteration: Codex submits a review object only when it has findings — a clean pass produces no object, only a 👍 reaction and an updated summary comment naming the commit. A gate that waits for a review object deadlocks every clean PR. The signal is the summary table plus the reaction.

Cause 2 — changes and files large enough that a correction cannot reach the whole claim

Merged PR sizes from #280:

#280  3504 lines  13 files
#311  1350 lines  19 files
#291  1089 lines  13 files
#303   884 lines   5 files

And the files that keep needing correction:

2796  docs/tally/TALLY_PROTOCOL_REFERENCE.md
1893  scripts/bank_statement_import.py
1482  scripts/bank_statement_import.test.py
1392  docs/tally/IMPLEMENTATION_GUIDE.md
 989  docs/tally/PROMPT_PLAYBOOK.md

Size alone does not predict findings — #306 was 244 lines and drew four. What size predicts is a correction failing to reach everywhere the claim lives, which is the single most repeated defect in this set:

  • the NFC withdrawal reached §9.4b's table and item 5 of the playbook, and left step 4, the adversarial review prompt, and IMPROVEMENT_PLAN_2026H2.md §8.6 still prescribing normalisation;
  • the case-direction qualification was written into a note while the predicate beside it stayed symmetric;
  • §3.4 kept the fingerprint alive as duplicate prevention while §3.4a of the same patch withdrew it;
  • the _key Unicode fix landed in the importer and never reached the sanitiser, where getting it wrong publishes data.

A 2,796-line document that corrects itself in four places is a document where "fix the section the finding points at" is reliably insufficient.

Proposed

  1. Work the debt down — in flight above; fix(scripts): an ACH reference can wrap, and a Windows overwrite keeps its ACL #305 and fix(fixtures): regenerate both bbox captures, clearing the X-run defect #312 next.
  2. Keep the head-SHA gate, and write it down rather than leaving it in one session's habits.
  3. Split TALLY_PROTOCOL_REFERENCE.md. It is the file every correction has failed to fully reach. Splitting by topic would make "grep the whole claim" tractable.
  4. Smaller PRs. One finding or one behaviour per PR, so a post-merge finding lands against a diff small enough to re-read.
  5. Standing habit: when correcting a claim, grep the whole docs/tally/ tree for other statements of it before opening the PR — and report what was found even where nothing changed.

🤖 Generated with Claude Code

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions