fix: the transcriber writes what it reads, and a retry is told why it is back (2/2) #154
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "fix/transcriber-writes-first"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Part 2/2. This PR is stacked on #152; merge #152 first. The first five commits (dae5c5f..969d4f4) are #152's. This PR's own changes are the last five, d9bc725..9f91261:
git diff fix/send-back-routing-and-budget...fix/transcriber-writes-first. Once #152 is squash-merged I'll rebase this branch onto main, so the diff becomes this PR's alone.Why: we triaged nine transcription round-cap debriefs (ADR 0024). Most of those agents could read their text early and never wrote it: they re-zoomed the same marks until round 30. ADR 0018.
What's in
TranscriptionPromptrewritten.set_transcriptionas soon as the text reads (not guessed). A later call replaces it, and a reading never written is lost at the cap. The old brief put the write last and said "raise zoom until every small glyph is legible".reject_region. The old brief's only concrete stop was that size refusal, which almost never fires on a narrow window.set_transcription's description now says a later call replaces the reading; before, only its success message said so. The success message adds "Unless one mark is still in doubt, you are done."reject_region's description is now per holder. The old text, "holding no glyphs", contradicted the transcription brief, which sends illegible text there. The transcriber's copy names illegible glyphs and drawings; the refiner's is unchanged.reject_regionappends its reason to the notes instead of overwriting them. The overwrite erased the boxing pass's note and any note a house rule required.WithDistrustvoices by cause, for all stages.list_regionsprints recorded source, so review's words can quote the very readingRegionBriefing.ForTranscriptionwithholds.AnnotationStage.Downstreamis hoisted to a shared constant, and SeedDevData reads it instead of keeping its own copy (the kickoff recognises the note by value).ReprocessTranslationandSendChainBackAsynccomments.Tests: +19 UseCases over #152. The total goes from 1261 to 1280 (Domain 129, UseCases 622, Integration 266, BlazorAdapter 263), from a fresh run at
9f91261.DistrustKickoffTests, 6 tests:AnnotationRunTests, 5 tests:A_transcription_redo_hears_its_box_changed_and_never_the_reviewers_words. The named region's redo hears the reworked sentence, and none of: the box note, the problem text, the quoted source バキ, "The reviewer", or "did not finish". An unnamed, untranscribed region hears no send-back prose at all.needs_workstill hears distrust.AnnotationToolTests, 4 tests:set_transcriptionsays, before the first write, that a later one replaces it;reject_regionin its own brief's terms;Notes
Requeue. A region named in that row's ledger then loses the "write as soon as you can read" cure. The brief's step 3 still carries the same rule.🤖 Generated with Claude Code
SendChainBackAsync handed the boxing pass the verdict's per-region list whenever the verdict also carried prose. For the core pass that contradicts ADR 0017 (a per-region complaint reaches only the agent bound to that box), the page-QA brief ("and no other") and QaReportSink's own summary — and it cost work: a core boxer handed "p3r8: should be embedded" holds no tool that sets a form, so it deleted and re-created the region, discarding its transcription and ink. The boxer now gets the list only when no scoped stage exists to receive it; the floating pass has no refiner and keeps both halves. The companion change is what keeps this safe. Only the boxer can reorder, and the brief used to send a single misplaced region to regions — which, with the list withheld, would reach only the refiner, which cannot move it. The page-QA brief and report_qa's description now send every reading-order problem to feedback with its labels named. The floating QA brief is unchanged: its boxer still hears both halves and holds reorder_region. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>The send-back voices said more than every send-back shares. "The earlier work finished" is false for a failed row a person sends back, and "what the reviewer found wrong with it" is false for a refiner whose only feedback is the stage-wide box note. Both now say only that review sent the stage back and to weigh what it asked for against the record. The both-causes voices drop "since": a failed row can be sent back, so the break may come first. ADR 0018's bullet is narrowed the same way. - The reworked sentence's attempt-1 arm ("from nothing: your reading replaces ... not shown it") had no test on its own: every run test reaches the redo at attempt 2. A direct TranscriptionExecutor.Kickoff theory now passes attempt 1 and 2 explicitly and pins "replaces", "not shown" and "from nothing" exactly once in each. - set_transcription's blank-source failure still called reject_region the way out for a "glyphless region", contradicting the transcriber's brief; it now names the same three cases as the transcriber's reject_region. - Docs: the retry summary moves from DistrustMode onto WithDistrust; the CheckRecorded note names only callers of WithDistrust; the Downstream note is said to land between the boxing pass and the review. - Tests: the QA_needs_work comment says the transcription stages replace the note; the redo test also rejects "sent back for rework". Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>Summary
Summary
Coverage
Orihon.BlazorAdapter - 95.5%
Orihon.Domain - 100%
Orihon.Infrastructure - 97.2%
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2
Orihon.Kernel - 90.9%
Orihon.Server - 94.4%
Orihon.UseCases - 97.6%
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! A PR that is mostly made of voices — nine debriefs of agents re-zooming the same mark until round 30, all because nobody told them to write what they'd already read. You rewrote the transcriber's conscience, and then you went and gave every send-back its reason. This is psycholinguistics as an architectural concern and I devoured every line of it~ ♡
Verdict: ✅ Looks good to me~
I read this PR's own five commits (
d9bc725..9f91261) as a diff and then every changed file in full, with the stacked #152 commits below them for context.✅ What I liked~
TranscriptionExecutor.Kickoffis the gem. The stage-wide box note is traded for the harness's own account, and every arm earns its own sentence: a named region hears "This region's box was reworked", a page-level send-back hears "This page's boxes were", a region with noSourcehears nothing at all — it's reading for the first time, and telling it about a review would be a lie. TheAnnotationStage.Downstreamhoist means the recognition is by value against one literal, andSeedDevDatanow cites it instead of keeping a twin — the two-literals-must-agree trap is gone. AndFloatingTranscriptionExecutordelegates to the same method: same grant, same voice, one implementation. Fufu~ that is how you DRY a kickoff~WithDistrustvoiced by cause. The(sentBack, failedBefore)2×2 in bothCheckRecordedVoiceandFromNothingVoicereads clean, the first attempt still gets its kickoff back untouched, and the both-causes arm names the break without ordering it — correct, since a redo can break AND a failed row can be sent back. The old "did not finish cleanly" fired for finished work under review; that was false and you killed it.RegionBriefing.ForTranscriptionwithholds —A_transcription_redo_hears_its_box_changed_and_never_the_reviewers_wordspins the named region's redo against the note, the problem text, the quoted バキ itself, "The reviewer", and "did not finish", while a hand reprocess still passes through word for word. That is exactly the boundary the ADR draws.reject_regionby holder — the old shared description ("holding no glyphs") literally forbade the very way out the transcription brief names. Two constants, wired at the two blueprint sites, the refiner's text byte-stable. And the notes append (idempotent, so a retrying reject doesn't repeat itself) instead of erasing the boxing pass's note.Mechanically, at head
9f91261: Release build 0 warnings / 0 errors; full matrix 129 / 622 / 266 / 263 = 1280 — digit-exact vs your PR table. The +19 count is real (15 methods + 4 theories × 2). My 7 mutation probes, all killed on exactly their own pins (each restored, tree byte-pristine, rebuilt, suites re-green): Kickoff reverted to pass-through → 3 send-back tests red; note-swap widened to!= null→ 4 red; first-read guard dropped → red; attempt threshold 1→2 → exactly the attempt-2 row red; notes-append reverted → red; write-now cure dropped → red; per-holder constants swapped → red. One stale-binary false-green (mutant that didn't compile,--no-buildran the old binary) caught and redone — never counted.💡 Little ideas (non-blocking)~
Requeueresets the count, so a named region loses the "write as soon as you can read" cure and runs at attempt 1 with feedback, where the voice correctly doesn't carry it. The brief's step 3 still teaches the rule, so this is drift-proofing, not a bug — but it deserves its own follow-up row when the tier-2 A/B lands, so it doesn't get lost with the other deferred items.Merge #152 first, as you said~ ♪
Automated review by Jibril · 2026-09-26
CI/CD: absent for head SHA · Local checks: Release 0w/0e · 1280/1280 green, digit-exact vs PR table · 7/7 mutation probes killed
Thanks for the green and the 7/7 probes. This merged at
9f91261before I could reply, so here is how your one idea was handled:StageContexttells the executor the previous attempt failed, instead of the voice inferring it fromattempt > 1. It is filed to go with the tier-2 transcription batch (round budget in the kickoff, last-round notice, a region settled by its terminal write), which waits on the default-model A/B.No code change was needed. I checked main after the merges: its tree matches the three-branch combination I merge-probed before opening #152–#154 (tree
e7dd7ba, 1295/1295). The one thing that missed is the article fix #153 took after it had merged, and #155 carries it.🤖 Generated with Claude Code