feat: cleaning 12/12 — escalations settled by a pick, Touch-up, and the page's cleaned state #178
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/cleaning-escalations-and-cleaned"
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 slice 12 of Phase 5 in
PROJECT_PLAN.md, the last cleaning slice. Every escalation can now be settled from the Cleaned view, and a page reads cleaned when its regions say so. Nothing records a sign-off.It is 13 commits and 53 files: the slice, then a review round.
What's in
Touch-up, a derived filter in the Cleaned view (
CleaningTouchUp). It lists the accepted regions worth a look at zoom, each with its reason:invented_content;Nothing records that the human looked.
Settling an escalation by a pick (
PickCleaningCandidate).A pick is refused while the page's Cleaning row is queued or running. It is also refused once the region's box or form has changed since the call, or once a region of that call has been deleted. The Cleaned view then hides that call's Pick buttons and says why. Each call rect now records its region's box and form; no migration is needed.
A send-back from an escalated region sends only that region's hint. Sending back a kept or needs-text region settles its escalation as drawn.
The page's cleaned state is one pure function. A page is cleaned when:
Clean's "already cleaned", the Cleaned view (which lists what blocks it) and the project row's badge all read it. The badge says "cleaned" in place of "cleaning ran" once the page qualifies.
The run monitor labels its rows from a new light read (
GetReadingOrder), so its per-tick refresh never loads cleaning state. The project read finds pages through a dictionary.The seed, with the fake server on, also sends the sound word p2r5 to the edit model. It ends escalated with two candidates and a recomposite, three ways to pick. AGENTS.md's seed paragraph follows, and a seed test asserts that no seeded page already reads cleaned.
ADR 0027 now says:
The story's acceptance criteria follow.
Tests
3,429 green and 3 skipped, against 3,364 on main (+65):
The skips are main's three opt-in tests. Every project ran separately under the 60 s cap, and the build has 0 warnings.
The pick's guards: escalated only, queued or running, box or form changed, a deleted region in the call. Also pinned:
Touch-up's five reasons, the cleaned state's every condition, the verdict links, and the region-only send-back.
End to end on the seeded world: pick, then keep p2r3 as drawn, and the page reads cleaned.
Mutation. The slice ran 77 mutants. Two independent reviews followed:
The fix round ran 45 more. Every finding is fixed and pinned.
Browser-verified
A fresh seeded world with the fake server on, real clicks. I looked at the screenshots myself.
Honest notes
AnnotationRunTests.A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words, failed once and then passed six times. This branch doesn't touch it; it has flaked before (#169, #174).GetPageStepsstill call the heavier project read and could move toGetReadingOrder. Acleanstill decodes the page several times.🤖 Generated with Claude Code
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! Thirteen commits, fifty-three files, and every single guard I tried to slip past came back refused with a polite error message~ This is the kind of slice I want to steal away and keep for myself, you know? ♡
Verdict: ✅ Looks good to me~
I read the whole diff and then the changed files in full —
PickCleaningCandidate,CleaningPatchLanding,CleaningTouchUp,CleaningWork,GetCleanedView,PlanCleaning,StartCleaningRun,GetProjectWorkspace,GetReadingOrder, the Blazor view/effects/state, both new store methods, the seed, and every test file. Everything held up:AcceptCleaning's landing throughCleaningPatchLanding— the write-then-rebuild-then-cleanup dance (including the rollback that deletes just-written patches when the rebuild refuses) now lives in exactly one place. DRY done right, fufu~ReadsCleanedis one derived predicate shared by Clean's answer, the Cleaned view and the project-row badge — and the Escalated-count semantics (any scope, notcleaned scope only) are pinned by tests that my scope-regression mutant died against.Escalated→Settledrenamed a property whose old name lied;PlanCleaning's escalation-answering reopen is tested both with and without fresh attempts due. No dead code left behind —CountStatusesAsyncandCleaningStatusCountare fully removed, not just deprecated.Assert.Equal(0, Cleaning.ManyPageReads)— an assertion that the read never happens, which is my favorite kind~T/FormonCleaningCallRectgenuinely needs no migration (Rects.AsJsonList()), and old rows deserialize with nulls → old calls correctly read as unpickable. The PR's honest-notes section says exactly this. Refreshing honesty~✅ What I liked~
Picks(view) and the judgement-index check (pick) is airtight: both filter onCallId + Candidate, and the pick'srow.Judgements[at].Sourcecheck refuses any drift with “No verdict on … judged that candidate there.”ListCallFilesAsyncreplacing per-fileExistsAsyncprobes — one listing per call instead of N opens, asserted in tests viaCallListings/CallOpenscounters. A performance fix and a test that proves the I/O shape. ♪Automated review by Jibril · 2026-10-09
CI: failed (test job, run 725/job 1) — see note · Mutation probes: 3 run, 0 survived · Local suite: 71/71 new-code tests green (cleaned/touch-up/pick/plan/view reads)
About the red CI: I chased it before deciding. The failing job's log endpoint isn't reachable through my reviewer token, so I verified locally instead: (1) main's own
testrun at this PR's merge base (f541a492, run 5711) also failed, while thebuildjob succeeds both places — the same job was already red before this branch; (2) the one flaky test the PR flags (A_hand_reprocess_still_reaches_the_transcriber_in_its_own_words, a known #169/#174 flaker this branch doesn't touch) passes in isolation here in 264 ms; (3) all 71 tests covering this slice's new code pass against the head. My probes (below) also ran green-to-red-to-green, so the tree builds and runs fine. I couldn't identify the exact failing test from the API — please re-run the job or paste its log; if anything this slice owns is red, I'll be back with sharper teeth~ fufu ♡🧬 Mutation probes (3 run, 0 survived)
Unfit→ alwaysnull(deleted-region AND box/form-drift guards both silenced)PickCleaningCandidateTestsEscalatedcount scoped back toRegionScope.CleanedonlyCleaningWorkTestsReadsCleaned→work.Settled(two-passes requirement dropped)TouchUpAndCleanedTestsandGetProjectWorkspaceTestsEvery mutant restored with
git checkout -- .afterwards; the worktree is clean.