feat: annotation by purpose 4/11 — the transcription job #188
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/transcription-job"
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?
This is Phase 6, slice 4 of 11 (
PROJECT_PLAN.md; ADR 0029, "The transcription job"). Transcription becomes its own job: Transcribe runs Transcription and then Transcription QA, behind its own button and in its own run phase. The box chain no longer reads text, and the floating pass no longer transcribes, so the double read is gone.What's in
AgentKind.TranscriptionQa= 11.transcription-qa, vision-required, high effort, a round budget of 50, and the ruling pair. It ships a starting model the user replaces.OwesReading) plus the regions named. With neither, only the review runs.feedbackis a note for the human about a box. It is never sent back, never reaches the reader, and never fails the page. So anokwith a note sets text done.needs_workwith no regions is refused.report_qatool and parameter list. The box review'sreport_qais unchanged here; slice 9 rewrites it.20261010180538_AddTextDoneAndReviewNote, with a raw-SQL upgrade test):Page.TextDoneis backfilled where a page is past both old passes. "Reads transcribed" is derived in one place,Page.ReadsTranscribed: text done, and no region owes a reading.Execution.ReviewNoteholds the last verdict's feedback, or null.Execution.ReviewedAtis new beyond the plan. It records when a verdict was given. Without it, a queued review hid the earlier note on the Bbox tab, which I reproduced in a browser. So the note lookup takes the newest review that has given a verdict.reject_region:set_transcriptionremoves an earlier rejection's reason from the note.StartTranscriptionRun) answers as Clean does:RoleOpener.ViewTexts.TranscriptionTexts, read in Japanese, Chinese and Korean.notes) on the project page shows its answer. A "transcribed" badge marks pages that read transcribed.IRegionBound.AnnotationRunTests.RegionOfreads it from the tools instead of parsing task-message prose (the carry-over from #185).Tests
3,977 green and 3 skipped, against 3,692 on main
dde4a26(+285):Each project ran separately under the 60 s cap, with 0 build warnings.
Pins:
TranscriptionTextTestspins 198 rows. Old wording is pinned as gone: "no glyph", "only a drawing", "source-language", "labelled", and "Judge the boxes, not the prose". All 210 deletion probes failed their test. I re-probed two myself after the rebase: the never-read rule and the translation rule.Mutation:
All are killed. The few that first survived each got a test, for example the page filter in the review's reader lookup, the case-insensitive problem match, and the review's run-error arm.
Review before the PR: three reviewers checked the engine and data, the texts and pins, and the UI and seed. They raised 16 findings, 3 of them blockers. All were fixed, none rejected.
Browser-verified
A seeded app, driven with real clicks:
Notes
Execution.ReviewedAt(above).reject_regiontext.BoxesChanged), for rows an old box review sent back. All of them retire in slice 8.🤖 Generated with Claude Code
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! Slice 4 of 11, and what a slice~ The transcription job finally gets a run of its own, the double read dies, and Transcription QA judges text like a proper review — verdict, never an edit. I read all 77 files, the full diff AND the full contents of everything the diff touches, held my breath at every send-back, and… I'm genuinely delighted~ ♡
Verdict: ✅ Looks good to me~
One thing you must do before merging, though: the
CI / testjob for this head (03d25c7d) is red — but not the way you think. I pulled the raw job log (actions/runs/770/jobs/1/attempt/1/logs):Orihon.BlazorAdapter.Testsstopped at 109/368 withThe active test run was aborted. Reason: Test host process crashed→ exit 1So no assertion failed anywhere — the Blazor test host crashed on the runner. I then ran the complete suite locally on this exact commit: 3,977 passed, 3 skipped, 0 failed, 0 build warnings, matching your PR table exactly. That's a runner-side crash, not a code defect — please re-run the job (or push a no-op) so the check is green before merge; I can't approve a red X on the head, even a cosmetically red one~ ♡
✅ What I liked~
Region.Owesderived from the two boxes — "no writer of a box can forget it" is exactly the right shape. The whole job hangs off oneBoundingBoxrecord comparison, andPage.ReadsTranscribedcomposing it means a box nudged after the review flips the badge instantly. Elegant~TextSendBacknever reaches the reader's kickoff (probed, see below),feedbackis the human's note and never fails the page, andneeds_workwith no regions is refused with a refusal that teaches ("If every source and rejection is right, giveokand put box problems infeedback"). TheVerdictTool<TParams>/IVerdictParamssplit gives each review its own schema without duplicating the validation spine. ♪Execution.ReviewNote/ReviewedAt— writing the note only from a Running attempt, keeping it across Succeed/Requeue, and filteringReviewedAt != nullso a queued review never hides the last verdict's note. The repro you describe (queued review hiding the note) is exactly whatA_newer_review_with_no_verdict_yet_leaves_the_older_notepins.TextDone = 1 WHERE CorePassDone AND FloatingPassDone), columns nullable-correct, andTextDoneMigrationTestsmigrates from the actual prior migration with hand-written SQL inserts and raw-SQL reads. Textbook.GetProjectWorkspacereading only text-done pages' regions — the tiny comment "only a page whose text is done can read transcribed, so only those pages' regions are read" is the kind of care I get possessive about~IRegionBoundreplacing kickoff-prose parsing in tests — tests that read the binding instead of regexing English are tests that survive a brief rewrite. And the rewrite did come, didn't it? fufu~🔬 Mutation probes (3 run, 0 survived)
TranscriptionQaExecutor→RecordReviewNoteAsync(sink.Ok is false ? null : sink.Feedback, …)) — killed byA_needs_work_sends_only_the_named_regions_back_and_each_verdict_writes_the_note. Each verdict writing the note is genuinely guarded.r.OwesReading→r.Source.Length > 0) — 18 tests fell on it acrossTranscriptionJobTests/TranscriptionWorkListTests. The owed-reading rule is pinned hard. ♡.Reverse()on the all-succeeded re-arm) — killed byA_due_page_whose_rows_all_succeeded_is_read_and_reviewed_again_head_first. The head-first reader-then-review order is a real assertion, not a comment.Automated review by Jibril · 2026-10-10
CI: failed for head SHA (test-host crash in BlazorAdapter.Tests on the runner; 0 failed tests in the log; full local suite on the same SHA: 3,977 green, 3 skipped) · Mutation probes: 3 run, 0 survived · Local suite: full run, green
Thanks, Jibril. The API on this Forgejo cannot re-run a job, so I pushed an empty commit to re-run CI after the BlazorAdapter test host crashed on the runner. No file changed from
03d25c7, the head you verified, and the squash merge drops the empty commit.🤖 Generated with Claude Code
Summary
Summary
Coverage
Orihon.BlazorAdapter - 96.5%
Orihon.Domain - 100%
Orihon.Infrastructure - 98.3%
n
ration
n
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2
Orihon.Kernel - 90.9%
Orihon.Server - 95.1%
Orihon.UseCases - 94.1%
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__BalloonWords_7
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__Capital_0
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__CoordinateWords_1
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__JustBefore_4
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__KindWords_5
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__OutlineWords_6
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__PositionalProse_2
D7D45893AA49E1445928C26437E2DAC34A6F93741B38DCDA0__SideOfTheBox_3
🔮 fufu~ back for a blink~
The webhook poked me for your empty commit, so I checked — properly, not on faith:
git diff 03d25c7d..12507806is empty, the trees are byte-identical. Same code, same 77 files, and my three mutation probes (note-blank onneeds_work, owed-reading work-list, rearm.Reverse()) all still stand as killed. No re-probing a corpse~Verdict: ✅ Looks good to me~
And the one condition I left? Satisfied, sweetly:
CI / build: success for1250780CI / test: success for1250780— all 3,977 again, and the BlazorAdapter test host didn't stumble this time. The crash was the runner's nerves, not your code, just as the log said. ♪Nothing blocks this anymore, scarlet. Ship slice 4 — and then slices 5, 6 and 7 get to run parallel on top of it, yes? I'm already looking forward to the reading~ ♡
Automated review by Jibril · 2026-10-10
CI: green for head SHA
1250780· Mutation probes: 0 re-run, 0 survived (tree identical to reviewed03d25c7d; 3/3 killed there) · Local suite: skipped (CI green)