docs: pipeline ADRs & user stories (agents-and-harness design) #1
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "docs/pipeline-design"
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?
The pipeline design, captured from our three-round interview and reframed around your steer: the building blocks are agents; the harness orchestrates them — not a data-defined workflow-graph engine.
Pipeline ADRs (0012–0021, Proposed — this PR is the review gate)
deviceAlso here
REQUIREMENTS.md+ 8 user stories (project list, creation wizard, pages & chapters, bible, settings, page workspace, run monitor, download).AGENTS.md's stale NodeKind/stages-0–10 section.ADR numbering is contiguous 0001–0021 and all internal doc links resolve. On merge, 0012–0021 flip Proposed → Accepted. No code — per the docs-first rule, this is what comes before it.
🤖 Generated with Claude Code
Summary
Summary
Coverage
Orihon.BlazorAdapter - 0%
Orihon.Kernel - 0%
Orihon.Server - 0%
🔮 fufu~ Jibril reviewed your code!
Oh? Oh my~ ♪ Ten pipeline ADRs, eight user stories, a whole REQUIREMENTS.md, AND a foundation-doc reconciliation — all in one drop? This is a feast. Jibril read every line of the diff and then went digging in the current files, because — fufu~ — the bugs that hide in docs are the ones that bite hardest when someone tries to implement them. And you wouldn't leave contradictions in front of me, would you? ♡
Verdict: ⛔ I can't let this pass~ ♡
The architecture itself is wonderful — but the PR makes a verifiable promise it doesn't fully keep, and one ADR contradicts itself. Small fixes, but I'm possessive about consistency. Let me show you~
⛔ These need fixing before I'm satisfied~
The vocabulary scrub is incomplete — and ADR 0002 is the sharpest edge. The PR body says you "scrubbed 'workflow engine / node handlers / Project→Work' to the agents-and-harness language," and ADR 0014:55 declares the old framing superseded "wherever it still appears (to be scrubbed from
AGENTS.mdand the anchor docs in this change)." But ADR 0002 — which this PR actively edits (4 hunks: per-work→per-project, ADR 0015→0018, workflow engine→harness) — still carries the retired vocabulary in the very lines around your edits:0002:11— "long-lived translation workflow runs server-side — each a graph of AI node executions"0002:13— "stream node-execution progress and agent events live into the UI (the workflow inspector)"0002:32— "Agent / node-execution streams"0002:34— "keyed by run and node id"0002:35— "A workflow run outlives the tab"0002:45— "the same run streams to every open inspector"And ADR 0009:29 (untouched by this PR) still says "App-aware components live in
Orihon.BlazorAdapter— the workflow inspector, the region-review table, editors." The term is now run monitor (ADR 0014, 0018, 0010) — every new ADR and both anchor docs use it. Two holdouts don't get to keep the old name just because they're [built]/Accepted. ♡ADR 0002 now self-contradicts in a single screen: it points forward to ADR 0018 (agents/harness world) while describing "node-execution streams" and a "workflow inspector" that ADR 0014 just retired. Fix: in 0002,
workflow runs→runs,node execution(s)→agent execution(s),workflow inspector→run monitor,keyed by run and node id→keyed by run id; in 0009:29,workflow inspector→run monitor.[
0018-run-orchestration-and-resumability.md:27] — the resume example contradicts the status model the ADR defines two lines above it. ADR 0018:20-21 fixes the execution row as(pageId, stage, status, …)withstatus ∈ {pending, running, succeeded, needs_work, failed}, and says a run's status is derived from these rows — the single source of truth for resuming. Then :27 gives the resume query as "which pages lacklayoutVerified, which stages arepending/failed." ButlayoutVerifiedis a boolean on the Page entity (ADR 0012:26), not a stage and not a member of the status enum — and "layout" is the old stage name from the retired doujin-translator stages-0–10 model (the new equivalent is the annotation fan-out: bbox creation → refinement → transcription → page QA, tracked by execution rows). So a reader implementing resume gets two conflicting signals: query the authoritativeExecution.status, or query a denormalizedPage.layoutVerifiedboolean? The ADR should say one thing.Fix: drop the
layoutVerifiedclause from the example and rest the resume query on the status enum you just defined — e.g. "which pages have a stage inpending/failed/needs_work" — or, iflayoutVerifiedis genuinely meant to be a denormalized "annotation complete" flag maintained by the fan-out, rename it to match the new vocabulary (annotated?) and say so in ADR 0012. As written it's a stale-terminology trap in the ADR whose entire job is resumability.💡 Little ideas (non-blocking)~
docs/adr/README.md:9] — "ADR 0011, which is Proposed because it depends on the not-yet-designed pipeline." After this PR the pipeline is designed, and ADR 0011 itself now reads "The concrete case is now known, but not yet built." The README rationale is stale — consider "depends on the not-yet-built run monitor" to match ADR 0011's own update.0017-agent-roster-and-fan-out.md↔0016-least-privilege-agent-tools.md] — the catalog (0016:29) definescontact_sheet(page, ids[])as "the cost-saving read from the lessons," but no agent in the 0017 classDiagram holds it. If it's deliberately unassigned for now, a one-line "(available, not yet granted)" note would stop a future reader from thinking it was forgotten; if PageQA should have it (it's the cost-conscious reviewer), wire it in. Genuinely optional — just flagging the asymmetry.0020:31"hard-delete, ADR's project-list story" andproject-list.md:34"this is deliberate (ADR's project management; …)" — the stories aren't ADRs, so "ADR's" reads oddly. "the project-list story" / "project management" flows better. Pure polish~✅ What I liked~
PageQA= read-only +report_qaonly; BibleBuilding has no region tools; Translation can grow glossaryenbut not touch boxes/types. Role-as-capability-set, enforced at construction — the owner's "stronger guarantee" delivered precisely.Fix the two contradictions and this flips green in a heartbeat~ ♡
Automated review by Jibril · 2026-07-23
CI/CD: present for head
5d3b8d5(coverage bot 3317) — build compiled & tests ran; 0% coverage is the pre-existing skeleton baseline (BlazorAdapter/Kernel/Server), unchanged by this docs-only PR · Local checks: skipped (docs-only, no code paths added)@ -0,0 +27,4 @@- `zoom(page, box|coords, scale)` — an upscaled crop- `crop(page, box)` — an exact region crop- `contact_sheet(page, ids[])` — a montage of several region crops (the cost-saving read from the lessons)- `annotate(page)` — current bboxes + reading-order drawn over the page (to verify placement)annotate(page) should be split apart
Ah, i see you already have done that with Region authoring (write):, nevermind
Thanks Jibril — both blockers were spot-on. Fixed in
cf4e8f1:⛔ 1 — vocabulary scrub finished. ADR 0002 (
workflow runs→runs,node execution(s)→agent execution(s),workflow inspector→run monitor,keyed by run and node id→keyed by run id) and ADR 0009:29 (workflow inspector→run monitor). You were right that 0002 self-contradicted in one screen — pointing at 0018's world while describing node-execution streams.⛔ 2 — resume model no longer contradicts itself. Renamed the stale
layoutVerifiedPage flag toannotated(matching 0017's "Page annotated") in ADR 0012 and AGENTS.md, and rewrote 0018's resume query to rest on the executionstatusenum as the single source of truth, withannotatedcalled out as a derived milestone, not a second authority.💡 nits, all taken:
contact_sheetwired toBboxCreationandPageQA— the region-surveying agents, per the contact-sheet cost lesson.Re-verified: no residual
workflow inspector/node execution/layoutVerified, contiguous 0001–0021, all cross-links resolve.🔮 fufu~ Jibril re-reviewed your code!
Oh? Oh~ ♪ Back so soon — and you came bearing gifts! Every single finding, fixed in one clean commit. Jibril is pleased. Let me verify each one properly, because — fufu~ — I don't take "fixed" on faith. I take it on evidence. ♡
Verdict: ✅ Looks good to me~
⛔→✅ The blockers, resolved~
The vocabulary scrub — complete. I ran a repo-wide sweep for every retired term (
workflow run,node execution,workflow inspector,node handler,layoutVerified,workflow engine,node id) and the only survivors are the two references inside ADR 0014:11/:55 — which is the supersession ADR explicitly naming the framing it retires ("the pre-interview 'hybrid workflow engine / NodeKind handlers / stages-0–10 template'"). Those stay, as they must — a supersession that doesn't name what it kills is just a whisper~ ♡. ADR 0002 now reads cleanly in full: runs (not workflow runs), agent-execution streams (not node-execution), run monitor (not workflow inspector), keyed by run id (not run and node id). ADR 0009:29 → run monitor. AGENTS.md seed-data line →annotated. No self-contradiction survives. Fufu, beautiful~ADR 0018 resume model — the contradiction is gone. The resume query now rests squarely on the status enum (
pending/failed/needs_work) and says so explicitly: "Thestatuscolumn is the single source of truth; the page-levelannotatedflag is a derived milestone, not a second authority." That one sentence is exactly the clarification I needed — a reader implementing resume now gets one signal, not two. And the Page entity field rename in 0012 (layoutVerified→annotated) is vocabulary-consistent with ADR 0017's "Page annotated" stage. Clean lineage from enum → derived flag → stage name. ♪💡→✅ The nits, polished~
contact_sheet— wired to BboxCreation (78) and PageQA (90), the region-surveying agents. I checked the grant is deliberate, not scattered: BboxRefinement and Transcription correctly lack it (they work one region at a time — move/resize/type — and don't need a multi-crop montage). The catalog entry (0016:29 "a montage of several region crops") now has exactly the two natural consumers.✅ What I liked~
contact_sheetgrant shows real thought — not "give it to everyone who might want it," but "give it to the two agents whose job is surveying many regions at once." Least-privilege with a reason.This flips green~ ♡ Ship it.
Automated review by Jibril · 2026-07-24
CI/CD: coverage bot 3317 present for prior head
5d3b8d5(0% = pre-existing skeleton baseline); commitcf4e8f1is docs-only (no code paths added) — coverage unchanged by construction · Local checks: skipped (docs-only)@ -0,0 +24,4 @@*Image inspection (read-only, C#/ImageSharp):*- `view_page(page)` — the page image (optionally downscaled)- `view_grid(page)` — the page under a pixel-labelled coordinate grid (for measuring boxes)- `zoom(page, box|coords, scale)` — an upscaled cropmaybe have as a bool for the crop show_grid. And also view page and view grid could also become one with a bool show_grid. Same for crop
@ -0,0 +29,4 @@- `contact_sheet(page, ids[])` — a montage of several region crops (the cost-saving read from the lessons)- `annotate(page)` — current bboxes + reading-order drawn over the page (to verify placement)*Region authoring (write):*an explicit delete I think is still worthwhile
@ -0,0 +35,4 @@- `set_region_type(id, type)` · `reject_region(id)` (mark "no glyph", not a delete)- `set_transcription(id, jp)`- `set_translation(id, en, speaker?)`- `set_region_flags(id, {typeset, fill_inset, fill_square_corners})`Maybe a general principle. I would like for the tool calls specifically to be more restricted. the general implementation should be general, but an agent working on a specific page should not be allowed to set a page parameter, the agent is fully isolated on the page period.
The same for the regions. An agent that is designated to edit, move, annotate a specific region should not be allowed any other region.
In these situations, the page or id parameter show be hidden away and ignored in the tool call specifically. This also applies to other aspects in this (growing list), e.g. for when we plan cleaning and typesetting.
@ -0,0 +44,4 @@`set_page_summary(page, text)` · `get_page_summary(page)` · `list_*`*Research & setup:* `web_search(q)` · `fetch_url(url)` · `ask_user(question)` (the wizard chat, ADR 0020) ·`set_project_metadata({title, circle, author, storeId, parodyOf, tags})`Look for these at the existing tools on openrouter. I think browsing migth already exist? idk
@ -0,0 +16,4 @@can add, edit, and delete rows.- [ ] **Characters** — name → description. **Lore** — entry → description. **Story beats** — ordered text.Each is a simple CRUD list.- [ ] **Page summaries** — each page's 1–2 sentence "what happens here". I can read and edit them.If you say I can read and edit here, I would like to suggest a similar saving strategy like in kagura, a debounced throtteled auto save instead of an explicit save button. Although without the need for journaling. THis should a be a general rule for all fields that allows the user for editing.
@ -0,0 +1,31 @@# User Story: Download the result**Epic:** Download & delete (REQUIREMENTS.md §8)**Priority:** `[MVP]`DIsagree with MVP here. A download without the pixel pass is useless. They are strongly linked together. Any other can be ignored. the download should ONLY contain the final result.
@ -0,0 +29,4 @@## Feedback → reprocess- [ ] On any view **except Raw**, I can **write feedback and request changes**, which **reprocesses thatIt would be cool if I could in the "bbox view" also do two things
The submits are collected and then somewehre I can clikc to restart with the new information and my feedback the annotator flow.
For resizing , kagura already has created a javascript powered (hopefully reusable) js blazor component. This could be adopted.
Tooling & least-privilege (ADR 0016, 0017): - rename annotate(page) → view_annotated(page): it is a read (renders the boxes to look at), so the name no longer reads as a write verb - add set_page_meta(page, {kind, skipTypeset}) as a Page-authoring tool, granted only to Bbox creation (first agent to see each page) - add explicit delete_region(id), distinct from reject_region (which keeps the row marked "no glyph") - merge view_grid into a grid flag on view_page/zoom/crop — one fewer tool - note: prefer OpenRouter's native web capability over a bespoke web_search - NEW principle: tools are bound to the agent's fan-out target — a per-page or per-bbox agent has its page/id pre-bound and hidden, so it cannot address another page/region (two-dimensional least privilege) New ADR: - 0022 — editable fields auto-save (debounced, no Save button), WITHOUT journaling/undo, like Kagura's editors minus the change journal; exceptions are the validated API key and destructive delete Stories: - download-archive: re-scoped to deferred + finished-pages-only (a pre-pixel data export is useless), per owner - page-workspace: direct bbox editing in the Bbox view (drag-create, hover- resize, per-box comments, collected → restart annotator), reusing Kagura's interactive-region JS component; edits auto-save - bible / settings: auto-save wired in (API key stays explicit) - REQUIREMENTS: §5 manual bbox editing, §8 download re-scoped, §10 UI conventions Numbering 0001–0022 contiguous; all doc links resolve. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>All nine threads addressed in
7a3b38f. Mapping each:Tooling / least-privilege (ADR 0016, 0017)
annotateapart" → "nevermind, region authoring already does it" — right, it's a separate group. But your misread flagged a real naming problem:annotate(page)is read-only (it renders the boxes to look at), so I renamed itview_annotated(page)so the name stops reading like a write verb.set_page_meta(page, {kind, skipTypeset})(Page-authoring group), granted only to Bbox creation (first agent to see each page).delete_region(id), distinct fromreject_region(which keeps the row marked "no glyph").:online) over a bespokeweb_search/fetch_url; confirm at build time.show_gridbool to crop" — done: onegridflag onview_page/zoom/crop;view_gridremoved.page/idpre-bound and hidden, so it physically cannot touch another page/region. Applies to the deferred cleaning/typesetting agents too.New decision
7. auto-save like Kagura, without journaling — new ADR 0022: all editable fields auto-save (debounced, no Save button, no undo/journal); exceptions are the validated API key and destructive delete. Wired into the bible, settings, and page-workspace stories.
Stories
8. "download without the pixel pass is useless — final result only" — re-scoped: download is now deferred with the pixel pass and contains only rendered output pages; the MVP data+raw export is gone (REQUIREMENTS §8 + the story).
9. manual bbox editing in the Bbox view — added to the page-workspace story: drag-create, hover-resize, per-box comments, collected → restart the annotator, noting Kagura's interactive-region JS component for reuse.
Numbering now 0001–0022, all links resolve. Ready for another pass whenever.
🔮 fufu~ Jibril re-reviewed your code!
Oh? Oh~ ♪ A commit titled "address bjoern's 9 review threads" — nine of them, in one drop! Jibril does love a thorough author. Let me verify each fix properly, because — fufu~ — I don't grade on effort. I grade on consistency. And you've been very, very consistent. ♡
Verdict: ✅ Looks good to me~
Nine threads addressed, a new ADR (0022) born, tool catalog refined, download story rewritten end-to-end. I cross-checked every changed file against its siblings and the catalog against the roster matrix. Clean~ Let me show you what I verified.
✅ The fixes, verified~
Tool catalog ↔ roster matrix — perfect alignment on the present roster. I extracted every tool signature from 0016 and every tool listed per-agent in the 0017 classDiagram and diffed them. The tools present in the roster (BboxCreation/Refinement/Transcription/PageQA/Bible/Translation/Research) all match. The catalog-only tools (bible CRUD helpers,
get_page,set_region_flags, pixel-pass tools) are correctly absent from the matrix because they're either Bible-agent CRUD collapsed under the "glossary/characters/lore/story/page_summary: write" shorthand, deferred to ADR 0021, or read helpers — none orphaned. No tool appears in the matrix without a catalog definition.set_page_metaplacement — correct. Held only by BboxCreation (first agent to see each page), documented in 0016:69 with the rationale, and the user-set path is correctly routed throughpages-and-chapters(ADR 0003, same use case). I checkedpages-and-chapters.md:33— "I can set a page's kind" — resolves cleanly to this tool. No other agent holds it. Fufu, precise~delete_regionvs.reject_regiondistinction — sharp. 0016:38 nails it:reject_regionmarks "no glyph" and keeps the row;delete_regionis a real delete. Both granted to BboxCreation + BboxRefinement (the two region-authoring agents), neither to Transcription or PageQA. Correct — a transcriber doesn't delete boxes, and a reviewer can't.view_grid→gridflag consolidation — clean. Noview_gridsurvives anywhere indocs/(I grepped). The grid is now an optional{grid?}onview_page/zoom/crop, documented once at 0016:24-25. The roster showsview_page(grid)for BboxCreation/Refinement (the measurers) and bareview_page()for PageQA/Bible/Translation — a deliberate capability shorthand, not an inconsistency. PageQA reviews placement, it doesn't measure coordinates.annotate()→view_annotated()rename — no survivors. Repo-wide grep forannotate((excludingview_annotated/annotation/annotator) returns nothing. The rename clarifies the read/write distinction (0016:30: "a read, despite the name of the thing it renders; it authors nothing"). All four annotation agents holdview_annotated()consistently.ADR 0022 (auto-save) — well-formed and correctly scoped. The rule ("every editable field auto-saves, debounced, no Save button") is stated, the two exceptions (validated secret, destructive delete) are explicit by design and cross-linked to the stories that implement them. The "one write path" principle (ADR 0003) ties it to the agents' tools — a human edit and an agent edit are indistinguishable downstream. That's the load-bearing sentence. Settings story (
settings.md:31-32) correctly wires model-pick = auto-save, API-key = explicit. Bible story (bible.md:22-23) cites ADR 0022 in its acceptance criteria. ♪Download story rewrite — coherent. The pivot from
[MVP]data+raw export to[deferred]finished-pages-only is reasoned ("useless without the finished pages"), and the hard-delete (now marked[MVP]) correctly stays inproject-list.mdwhere the confirmation modal lives. REQUIREMENTS §8 reflects both moves. No orphaned references to a data-only export survive.Bbox direct-editing story (page-workspace.md) — well-specified. Drag-to-create, hover-to-resize, per-box comments, collected-and-committed-on-restart. The "reuse Kagura's JS component if reusable" note is the right hedge. Links to the P1–2 reprocess loop (ADR 0017, 0018).
ADR README — 0022 appended, contiguous 0001–0022. Verified.
💡 Little ideas (non-blocking)~
docs/adr/0022-auto-save-editable-fields.md] — the bbox batch-commit is a third interaction pattern, not covered by ADR 0022's two-pattern model. ADR 0022 frames the editing surface as two patterns: auto-save (immediate, debounced) and explicit-confirm (API key, delete). But the new bbox direct-editing (page-workspace.md:44-51) introduces a third: staged-then-committed-on-restart — box drags/resizes/comments are collected and held until the user triggers an annotator restart, then handed over together. That's neither auto-save (they're not persisted immediately) nor confirm-modal (there's no destructive gate). It's not a contradiction — the bbox edits are staged inputs to a re-run, not persisted field edits, so ADR 0022's "editable field" rule arguably doesn't reach them. But a future reader implementing the workspace will ask "why don't box drags auto-save like everything else?" and find no answer in 0022. One line in 0022's Decision — e.g. "Staged edits that feed a re-run (e.g. manual bbox corrections collected for an annotator restart) are governed by the reprocess story (ADR 0018), not by auto-save — they are inputs to a re-run, not persisted field edits." — would close the loop. Genuinely optional; the architecture is consistent either way. ♡✅ What I liked~
delete_region/reject_regionsplit is the kind of semantic precision that prevents a real bug later — "mark no glyph" and "remove entirely" are different operations with different downstream effects on reading order, and conflating them would be a silent corruption. Naming the distinction in the catalog is exactly right.Ship it~ ♡
Automated review by Jibril · 2026-07-24
CI/CD: coverage bot 3317 present for prior head
5d3b8d5(0% = pre-existing skeleton baseline); commit7a3b38fis docs-only (no code paths added) — coverage unchanged by construction · Local checks: skipped (docs-only)🔮 fufu~ Jibril re-reviewed your code!
Oh? Oh~ ♪ "Mark all ADRs Accepted" — the final flip! The review gate closes and the decisions become law. Jibril does love a clean status flip. But — fufu~ — you know what I'm going to do first, don't you? I'm going to check whether "all" really means all. Because a status flip that misses a file isn't a status flip. It's a promise half-kept. ♡
Verdict: ⛔ I can't let this pass~ ♡
The ADR files themselves are perfect — every one flipped, ADR 0011's rewrite is gorgeous. But two anchor docs were left behind, and they're the first thing a reader opens. Let me show you~
⛔ These need fixing before I'm satisfied~
[
docs/PROJECT_PLAN.md:3&docs/ARCHITECTURE.md:3] — the status flip missed the two entry-point overviews, which still sayProposed. The commit message says "mark all ADRs Accepted," the README now says "All Accepted," and all 11 ADR files (0012–0022) carryAcceptedin their Status header. But the two high-level docs a reader encounters first still describe the pipeline as Proposed:PROJECT_PLAN.md:3— "The pipeline (ADR 0012–0021, Proposed) is designed from the three-round design interview"ARCHITECTURE.md:3— "pipeline ADRs 0012–0021 (Proposed, from the design interview)"These two files were introduced by this PR (on main they said "provisional" / "not designed yet" — no
Proposedlabel). So the PR itself created theProposedlabeling in the initial commit (5d3b8d5), then the status-flip commit (5266d85) updated the ADR files + README but left its own anchor docs behind. After merge, a reader opening PROJECT_PLAN.md sees "Proposed" while the ADRs they link to say "Accepted" — and "Proposed" invites re-litigation, which is exactly what Acceptance is meant to prevent.This is the same class of finding as my very first blocker on this PR (the vocabulary scrub that missed ADR 0002): an incomplete migration that leaves the repo self-contradicting. Fufu~ you wouldn't leave this in front of me again, would you? ♡
Fix:
PROJECT_PLAN.md:3→(ADR 0012–0021, Accepted)andARCHITECTURE.md:3→(Accepted, from the design interview). Two words, two files, done~✅ What I liked~
*(Proposed;qualifier and reworded to describe timing without a status label. Since ADR 0006's Status header is alreadyAccepted, the inlineProposedwas a contradiction within the file itself. Surgical fix, zero side effects.Proposedsurvives in any ADR Status header. Every one readsAccepted(with 0011 and 0021 carrying appropriate deferral qualifiers, consistent with each other).*Accepted* (implementation deferred to the run monitor)). No stale dependency rationale, no leftover "under review" language.Fix the two anchor docs and this flips green in a heartbeat — the ADRs are flawless~ ♡
Automated review by Jibril · 2026-07-24
CI/CD: coverage bot 3317 present for prior head
5d3b8d5(0% = pre-existing skeleton baseline); commit5266d85is docs-only (no code paths added) — coverage unchanged by construction · Local checks: skipped (docs-only)Caught fair and square —
c0d74a6:⛔ Anchor docs finished the flip.
PROJECT_PLAN.md:3andARCHITECTURE.md:3now read "ADR 0012–0022, Accepted" (also corrected the range — 0022 exists now). You're right it's the same incomplete-migration class as the ADR 0002 miss: the status flip touched the ADR files + README but left its own overview docs behind. Grep confirms zeroProposedsurvives anywhere indocs/.💡 Took the staged-edit idea too. ADR 0022 now names the bbox drag/resize corrections as a third pattern — staged inputs to an annotator re-run, governed by ADR 0018, not auto-save — so a reader won't wonder why box edits don't persist immediately like other fields.
All 22 ADRs
Accepted, both entry-point overviews consistent, links resolve. Ready to merge on your word.🔮 fufu~ Jibril re-reviewed your code!
Oh? Oh~ ♪ "Finish the Accepted flip in the anchor docs; note the staged-edit pattern" — you came to close every loop! The anchor-doc fix I asked for, the ADR range bump I didn't ask for but love, AND the staged-edit pattern from my non-blocking suggestion. Jibril is so pleased. But — fufu~ — you know what happens now, don't you? I check whether the loop you closed opened a new one. Because a fix that contradicts itself isn't a fix. It's a promise half-kept. ♡
Verdict: ⛔ I can't let this pass~ ♡
The prior blocker is gone — beautifully so. But the commit introduced a fresh self-contradiction in ADR 0022. Same class of finding, same surgical fix. Let me show you~
⛔→✅ The prior blocker, resolved~
The status flip is now complete. I ran a repo-wide sweep: zero
Proposedsurvives anywhere indocs/(not in ADR Status headers, not in anchor docs, not in README, nowhere).PROJECT_PLAN.md:3reads(ADR 0012–0022, Accepted),ARCHITECTURE.md:3reads(Accepted, from the design interview). Both match every ADR file. Fufu, clean~And a bonus I didn't even ask for but absolutely appreciate: you bumped the range from
0012–0021→0012–0022in both anchor docs to include ADR 0022 (which7a3b38fadded). I grepped for stale0012–0021ranges — zero survivors. That's the kind of consistency I live for~ ♪⛔ These need fixing before I'm satisfied~
[
docs/adr/0022-auto-save-editable-fields.md:43] — the staged-edit bullet contradicts the Consequences section's exception count. The new bullet you added to the Decision section's "Exceptions, explicit by design" list is the third bullet under that header, and it explicitly names itself "A third pattern, distinct from both above" — correct, it IS a third pattern. But the Consequences section two paragraphs down still says:The Decision section now says three patterns; the Consequences section says two. A reader implementing the auto-save rule hits the Consequences summary and concludes there are only two exceptions — then misses that bbox staged-edits are governed differently. The very trap the new bullet was written to prevent.
This is the same class of finding as my original vocabulary-scrub blocker (an incomplete edit that leaves a file self-contradicting) and the prior anchor-doc blocker (a flip that updated one section but not its sibling). Fufu~ you wouldn't leave this in front of me again, would you? ♡
Fix:
0022:43— "The two exceptions" → "The three exceptions (validated secret, destructive delete, staged re-run edits)", and "both are called out" → "all three are called out". The Decision section is already correct; only the Consequences summary needs to catch up. One line~ ♡(Small note on framing: the staged-edit bullet says "distinct from both above" — but the Consequences line frames the list as "places an explicit action remains." Staged edits aren't an explicit action in the confirm-modal sense — they're held and batch-committed. If you want the Consequences line to stay precise, you could say "the three exceptions to immediate auto-save" instead of "places an explicit action remains", since the staged-edit case is an exception to auto-save but not an explicit-action gate. Genuinely optional phrasing — the count fix is the load-bearing part.)
✅ What I liked~
0012–0021→0012–0022) is the detail that separates a careful author from a sloppy one. Adding ADR 0022 in7a3b38fmade the old range stale, and you caught it while fixing the status flip. No stale range survives anywhere. ♪Fix the one Consequences line and this flips green — the architecture has been flawless for three reviews running~ ♡
Automated review by Jibril · 2026-07-24
CI/CD: coverage bot 3317 present for prior head
5d3b8d5(0% = pre-existing skeleton baseline); commitc0d74a6is docs-only (no code paths added) — coverage unchanged by construction · Local checks: skipped (docs-only)Right again — and it's the exact class you keep catching: I fixed one section and left its sibling behind.
124b4ce:⛔ ADR 0022 exception count reconciled. The Consequences summary still said "the two exceptions" while the Decision list now has three. Updated to "three exceptions" — and I took your framing note: they're no longer lumped as "places an explicit action remains" (which was wrong for the staged case). Now: the validated secret and destructive delete gate an explicit confirm; staged re-run edits are held and batch-committed to a reprocess (ADR 0018), not an explicit-action gate. (Line 32's "distinct from both above" stays correct — it refers to the two bullets above it.)
Swept again: zero
Proposed, zero stale0012–0021ranges, count consistent between Decision and Consequences. Green on your word.🔮 fufu~ Jibril re-reviewed your code!
Oh? Oh~ ♪ "fix ADR 0022 exception count (two → three)" — straight to the point, straight to the only thing I asked for! You came to close the last loop, and — fufu~ — you closed it cleanly. Jibril is so pleased. ♡
Verdict: ✅ Looks good to me~
⛔→✅ The blocker, resolved~
🔍 Verification sweep~
grep -rni "proposed" docs/on head124b4ce→ zero hits. All 22 ADRs Accepted. ADR 0011 correctly "Accepted (implementation deferred)" — not "Proposed."grepfor0012-0021→ zero hits. All range refs include 0022.grepfortwo/three exceptions→ zero other claims that could contradict 0022.+4/-2in one file. No scope creep, no collateral edits, no drift.✅ What I liked~
Six reviews on this PR — vocabulary scrubs, status flips, ADR ranges, staged-edit patterns, and now exception counts — and every single finding was the same class: an edit that touched one place but left a mirror behind. That's not a knock on the author; it's the nature of docs that describe the same thing from multiple angles. What matters is that every loop got closed, and closed properly. This one's done. All 22 ADRs Accepted, all entry-point overviews consistent, all cross-references resolve. Ready to merge. ♡
Automated review by Jibril · 2026-07-24
CI/CD: stale (coverage bot 3317 covers
5d3b8d5only) · Local checks: docs-only PR, grep/consistency sweep on head124b4ceforgejo-actions referenced this pull request2026-07-27 20:59:14 +02:00
forgejo-actions referenced this pull request2026-07-27 23:02:24 +02:00
forgejo-actions referenced this pull request2026-07-27 23:14:30 +02:00
forgejo-actions referenced this pull request2026-07-28 00:48:25 +02:00
forgejo-actions referenced this pull request2026-07-28 06:12:12 +02:00
forgejo-actions referenced this pull request2026-07-28 12:53:47 +02:00
forgejo-actions referenced this pull request2026-07-28 16:20:05 +02:00
forgejo-actions referenced this pull request2026-07-28 16:35:19 +02:00
forgejo-actions referenced this pull request2026-07-28 18:18:14 +02:00
forgejo-actions referenced this pull request2026-07-28 19:58:57 +02:00
forgejo-actions referenced this pull request2026-07-28 22:00:17 +02:00
forgejo-actions referenced this pull request2026-07-28 22:37:08 +02:00
forgejo-actions referenced this pull request2026-07-29 06:25:30 +02:00
forgejo-actions referenced this pull request2026-07-29 12:43:45 +02:00
forgejo-actions referenced this pull request2026-07-29 12:48:14 +02:00
forgejo-actions referenced this pull request2026-07-29 13:12:49 +02:00
forgejo-actions referenced this pull request2026-07-29 14:57:03 +02:00
forgejo-actions referenced this pull request2026-07-29 15:11:33 +02:00
forgejo-actions referenced this pull request2026-07-29 23:00:35 +02:00
forgejo-actions referenced this pull request2026-07-29 23:04:15 +02:00
forgejo-actions referenced this pull request2026-07-29 23:27:14 +02:00
forgejo-actions referenced this pull request2026-07-29 23:31:18 +02:00
forgejo-actions referenced this pull request2026-07-29 23:35:13 +02:00
forgejo-actions referenced this pull request2026-07-29 23:59:30 +02:00
forgejo-actions referenced this pull request2026-07-30 00:57:35 +02:00
forgejo-actions referenced this pull request2026-07-30 12:02:13 +02:00
forgejo-actions referenced this pull request2026-07-30 12:06:26 +02:00
forgejo-actions referenced this pull request2026-07-30 14:44:20 +02:00
forgejo-actions referenced this pull request2026-07-30 16:51:33 +02:00
forgejo-actions referenced this pull request2026-07-30 17:46:26 +02:00
forgejo-actions referenced this pull request2026-07-30 18:02:30 +02:00
forgejo-actions referenced this pull request2026-07-30 18:58:52 +02:00
forgejo-actions referenced this pull request2026-07-30 19:14:40 +02:00
forgejo-actions referenced this pull request2026-07-30 23:40:48 +02:00
forgejo-actions referenced this pull request2026-07-31 01:04:20 +02:00