docs: the cleaning stage — an agent harness the human reviews (ADR 0027) #162
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "docs/cleaning-stage-concept"
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 PR is the plan for the cleaning stage. ADR 0021 already says what cleaning does: the lab's recipe and the server contract. ADR 0027 decides how Orihon builds it. The PR also adds a user story and splits Phase 5 into slices. No code changes.
The design in brief
The agent cleans; you review. There is no manual cleaning workbench. You press Clean when pages are ready, read the Cleaned view (original / cleaned / diff, plus the agent's evidence), and send pages or single regions back with feedback the agent acts on. A note like "another seed", "there's a hand behind the text" or "split this" reaches any of the agent's levers. On an escalation you can pick one of the agent's own candidates. Boxes and forms stay in the Bbox tab.
No review state. Clean is the gate. There is no approval, sign-off, reviewed mark or gate setting. "Cleaned" is worked out from the regions.
Orihon enforces the rules, whatever model you pick. Every rule sits in the use cases, not in the agent's prompt:
The shape of a page's run: a survey (geometry fixes, with reasons, recorded on an edit list), then one invocation per planned call, then a read-only page check.
State: separate cleaning tables. The plate is rebuilt from stored patches, so undo needs no journal and judged pixels never change underneath you.
No GPU server needed to start. Without an address the stage cleans what the deterministic fill can, and marks the rest "awaiting the server". That lets the stage ship before the server adapter exists.
Server trouble is waited out inside the call on one 20-minute clock, then a breaker halts the stage. Resume cleaning, or a restart, picks the pages up again. The server needs no changes; its minimum version is the deployed a3953f7.
Engine changes, for every phase:
Today pressing Translate during annotation silently stops annotation's remaining pages; with this change it refuses and says why.
Testing is each slice's automated tests. No further lab work is planned. Real-world use tests what the lab never covered, censor bars among it.
Your decisions, applied
typeset:falseregions are kept as art.What changed
docs/adr/0027-cleaning-stage.md(new) anddocs/stories/cleaning-stage.md(new).docs/PROJECT_PLAN.mdPhase 5: twelve slices. The stage runs fill-only at slice 8, and model calls arrive at slice 11.REQUIREMENTS.md,ARCHITECTURE.md, the page-workspace story and the sfx story.How it was checked
🤖 Generated with Claude Code
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.8%
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! A whole ADR dropped on my desk — 738 lines deciding how Orihon will build the cleaning stage, plus nine sibling ADRs amended in place, a user story, and a twelve-slice Phase 5. I love these~ Documentation PRs are where bugs hide in prose instead of conditionals, so I hunted them the same way: every factual claim chased to its source, every cross-reference checked, every number re-derived. Fufu~ you wouldn't believe how many hours I spent inside
cleaner.pyandAgentAttemptSupport.cstonight ♡Verdict: ✅ Looks good to me~
This is a disciplined, evidence-grounded design. I probed it hard and it held. What I verified mechanically, in the clone at
a36a68a(base25e86e8, clean single-commit stack, mergeable):AgentKindnumbers 0–9 with "numbering only ever appends" (Cleaning appends cleanly); the ruling-pair predicateCanRequestRuling(AgentAttemptSupport.cs:158) already grants the pair to Floating-text QA, so ADR 0026's "which held the pair already" note is an honest latent doc/code fix, not a fudge;Region.Typeset/BboxEstimate.Rough/RegionForm/Region.Order/Source+Targetall exist exactly as described;FloatingCreationreally does clearAnnotated(AnnotationExecutors.cs:521–524), so theCorePassDone/FloatingPassDonerationale ("Annotatedcannot stand in") is grounded in real code;FeedbackRegionsis a realExecutioncolumn that only agent verdicts populate today, so "the first UI to pass per-region problems" is accurate;StartedAt = nullreally is cleared byRequeue/ResetOrphaned, justifying the migration's "not read fromStartedAt" rule; theSkiaImages.DecodeAsynchelper is exactly "the one decode helper every gateway already uses"; and the "deferred flatten-alpha slice" is real (PR #108's found-not-fixed note: "alpha is never flattened onto white before the JPEG re-encode… Its own slice.").call_defaultsreally returns 1 MP/25 steps/3 images for a mixed call (cleaner.py:1389–1400), andplan()really never implements the floating 2-rect default (companions fill tomax_rects=4), so "the prototype never implemented this" is true._TINT_CHROMA = 40,max(64, 0.2%)(_COLOUR_SHARE = 0.002,_COLOUR_MIN_PX = 64, app/imageio.py:150–155); the "+20 px" grown-rect figure matches expand 8 + 3 × feather 4;server_configis a real stop-class code in the server'serrors.py. Requiring a3953f7 (backend_presubmit_failuresin/healthz) is consistent with everything #159–161 recorded.a36a68a(97.2% line / 85.4% branch whole suite) — and since the diff touches onlydocs/(18/18 files), there is no code to exercise. Green CI is exactly the right check here.💡 Little ideas (non-blocking)~
✅ What I liked~
Fufu~ a design document where I couldn't find a single false claim about the code, the lab, or the server, after twenty-odd probes. That's rare and it deserves the stamp. The two 💡s are cosmetic residues, nothing more~ ♡
Automated review by Jibril · 2026-10-03
CI/CD: passed (coverage bot 10427, current for
a36a68a) · Local checks: skipped — docs-only diff (18/18 files underdocs/), no code to exercise; link check + fact audit run insteadThanks, Jibril. I took both ideas in
7417d79.All relative links still resolve. The diff touches docs only (3 files).
🔮 fufu~ Jibril reviewed your code!
Back so soon~? A synchronized webhook, one little commit — and what do I find but both of my 💡 ideas, taken precisely. You spoil me, scarlet ♡
Verdict: ✅ Looks good to me~
Re-reviewed the increment
a36a68a..7417d79(round 2). A surgical +7/−6 over exactly 3 files — the two files my round-1 memos pointed at, plus the story's matching sentence. Zero scope creep, production untouched (docs-only, as before).What I verified mechanically, in the clone at
7417d79:docs/research/cleaning-lab/hit is the lab corpus plan docstring — immutable lab record.) Vocabulary residue: zero ♪7417d79: 57 relative links, 0 broken. Your "all relative links still resolve" claim independently reproduced.docs/.✅ What I liked~
Round-1 fact audit stands in full (AgentKind append-only, lab numbers digit-exact, server contract vs qis-wave1, cross-ADR ruling-pair and engine-change lists). Nothing in this increment touches any of it.
Automated review by Jibril · 2026-10-03 (CEST)
CI/CD: coverage bot 10427 covers
a36a68aonly (stale for7417d79; docs-only diff, nothing to exercise) · Local checks: docs protocol — scripted link check 57/0, vocabulary grep, definition-anchor verification