feat: a review verdict reaches the agent that can act on it #80

Merged
bjoern merged 2 commits from worktree-feat-region-scoped-qa into main 2026-07-27 18:22:38 +02:00
Member

The second finding from the kickoff audit (PR #77 was the first). ADR 0017 amended; storage per ADR 0018; bboxEst semantics per ADR 0012.

The bug. Page QA had one channel — a free-text blob — and it went to BboxCreation and nowhere else. Refinement and transcription were sent back with a hardcoded line, so "the box on p1r3 cuts the last glyph column" never reached p1r3's agent, the one whose entire job is that box. And the plumbing couldn't have carried it: WithDistrust appends the stage's feedback to every region's kickoff, so thirteen agents would have read a complaint about the fourteenth.

The design

Not every complaint has a region to name. "There's an unboxed bubble in panel 2" names nothing — the defect is that no region exists (ADR 0012: absence is invisible). So a verdict has two halves that route differently:

half goes to for
feedback (prose) the boxing pass text with no region, an order wrong as a whole
regions[] (label + problem) the bound agent for that box a box cutting glyphs, a wrong type

Three consequences, and they're the point:

A verdict that named only boxes doesn't re-run the boxing pass at all. Its row stays succeeded, the pipeline gate lets the redo through, and a page-wide agent isn't spent on a complaint about two boxes.

Refinement's work-list is named ∪ still-rough. The union is a safety property, not an optimisation: the scope can only add to the rough floor, never cut below it, so a scope that is stale, wrong, or empty costs redundant work rather than silently skipping boxes. A verdict that named nothing works the whole page exactly as before — narrowing to "rough only" there would quietly drop a human's drag-created box, which isn't rough and still needs its type assigned.

The boxing pass's move_resize_region now marks what it moves rough, which is what makes that floor trustworthy. PR #77 had it carry the marker; that was right for "rough stays rough" but wrong for "a settled box the coarse pass re-placed" — that box is at the boxing pass's granularity again and refinement has to look. Without this, a boxing redo could move a settled box and the scoped refinement would skip it. The sfx pass still marks nothing (no refinement follows it — ADR 0023).

When the feedback is cleared

You asked, so: SendBack sets both halves, Start keeps them (unlike Error, which it clears — the error describes the last attempt, the feedback instructs this one), Succeed drops both, Fail keeps both (a redo that crashed didn't address the complaint). Unchanged from today except that the region list now moves in lockstep.

The lockstep is load-bearing and the aggregate is the only writer: stale prose is a confusing sentence in a kickoff; a stale region list is work silently not done. Both_halves_of_a_send_back_are_cleared_together_by_success and A_send_back_replaces_the_previous_rounds_regions_rather_than_adding_to_them pin it, and executors read the per-attempt snapshot in StageContext, never a fresh row.

What's in

  • DomainRegionProblem(Region, Problem); Execution.FeedbackRegions written only by SendBack, dropped only by Succeed.
  • Persistence — one JSON TEXT column via the existing JsonColumnMapper (nothing queries into it). The migration's default is hand-corrected to "[]" — EF generated "", which is not JSON and would throw inside the value converter on the first read of any pre-existing execution: a migration that "succeeds" and then breaks the monitor on the next boot.
  • report_qa — gains regions[], and validates the labels rather than taking them on trust. A verdict naming a region that doesn't exist would route its complaint nowhere, silently; the agent hears about the typo while it can still deliver the verdict it meant. Both nested fields are required in the schema because the handler refuses either blank.
  • RoutingSendChainBackAsync replaces the copy-pasted loops in both QA executors, keeping the head-first ordering the gate depends on. The sfx pass passes scoped: null: it has no refinement stage, so its boxer takes both halves and always re-runs, being the only agent that can act on either.
  • Prompts — both QA briefs now tell the agent which channel is which, including the failure mode: "Naming boxes in feedback instead of in regions gets the complaint read by every agent and acted on by none."
  • Monitor + seeder — the sent-back row renders each named box under the stage; the seeded world grows a second send-back of the new shape, so the monitor has both to show.

Tests

+19, 746/746 green (Domain 82, UseCases 317, Integration 157, BlazorAdapter 190).

  • Domain (4) — the lockstep clear; a second send-back replacing round one's regions rather than accumulating; a page-level send-back leaving none behind; Start keeping feedback while clearing the error.
  • RefinementWorkListTests (5, new) — nothing named → whole page; a named box worked though settled; every rough box riding along uninvited (the boxing-redo case); a named box that no longer exists simply absent; case-insensitive matching, since a verdict typed P1R3 must not route nowhere.
  • AnnotationToolTests (5) — a verdict naming boxes; an unknown label refused with nothing recorded; needs_work with neither channel refused; a named box with a blank problem refused; ok needing neither. Plus the coarse pass's move marking a settled box rough while the sfx pass's leaves it alone.
  • AnnotationRunTests (2) — end to end: a purely-region verdict leaves BboxCreation at attempt 1 and refines exactly ["p1r1","p1r2","p1r3","p1r2","p1r3"] across the two passes, with p1r3's second kickoff carrying its own complaint and p1r2's (present only because rough) not carrying it. And the sfx variant, where the boxer re-runs and gets the list.
  • Integration (2) — the column round-trips and is dropped by success; a never-sent-back row reads back empty (the migration-default path).
  • Seeder + monitor (2) — the contract test pins the scoped send-back; a bUnit test pins both halves rendering.

Browser-verified

Seeded world, run monitor expanded — the Bbox refinement sent-back row shows the stage note plus p3r1: the box cuts the last column of glyphs on its left edge and p3r3: this is a sign in the artwork, not free text — retype it as separate lines. Only console error is the pre-existing favicon.ico 404.

Deliberately not here

Transcription still re-verifies every region. I flagged this trade to bjoern when we designed it — scoping it to named ∪ untranscribed is what kills the last of the full-page cost, but it trades away the deliberate distrust of pre-seeded text (NeedsTranscription), and he hasn't called it. It's a one-line change on top of this, and it's the only remaining piece of the cost story: a send-back now re-runs one boxing agent fewer and only the affected refinement agents, but still every transcription agent.

🤖 Generated with Claude Code

The second finding from the kickoff audit (PR #77 was the first). ADR 0017 amended; storage per ADR 0018; `bboxEst` semantics per ADR 0012. **The bug.** Page QA had one channel — a free-text blob — and it went to `BboxCreation` and nowhere else. Refinement and transcription were sent back with a hardcoded line, so *"the box on p1r3 cuts the last glyph column"* never reached p1r3's agent, the one whose entire job is that box. And the plumbing couldn't have carried it: `WithDistrust` appends the stage's feedback to **every** region's kickoff, so thirteen agents would have read a complaint about the fourteenth. ## The design Not every complaint has a region to name. *"There's an unboxed bubble in panel 2"* names nothing — the defect is that no region exists (ADR 0012: absence is invisible). So a verdict has **two halves that route differently**: | half | goes to | for | |---|---|---| | `feedback` (prose) | the boxing pass | text with no region, an order wrong as a whole | | `regions[]` (label + problem) | the bound agent for that box | a box cutting glyphs, a wrong type | Three consequences, and they're the point: **A verdict that named only boxes doesn't re-run the boxing pass at all.** Its row stays succeeded, the pipeline gate lets the redo through, and a page-wide agent isn't spent on a complaint about two boxes. **Refinement's work-list is `named ∪ still-rough`.** The union is a *safety property*, not an optimisation: the scope can only add to the rough floor, never cut below it, so a scope that is stale, wrong, or empty costs redundant work rather than silently skipping boxes. A verdict that named nothing works the whole page exactly as before — narrowing to "rough only" there would quietly drop a human's drag-created box, which isn't rough and still needs its type assigned. **The boxing pass's `move_resize_region` now marks what it moves rough**, which is what makes that floor trustworthy. PR #77 had it *carry* the marker; that was right for "rough stays rough" but wrong for "a settled box the coarse pass re-placed" — that box is at the boxing pass's granularity again and refinement has to look. Without this, a boxing redo could move a settled box and the scoped refinement would skip it. The sfx pass still marks nothing (no refinement follows it — ADR 0023). ## When the feedback is cleared You asked, so: `SendBack` sets both halves, `Start` **keeps** them (unlike `Error`, which it clears — the error describes the last attempt, the feedback instructs this one), `Succeed` drops both, `Fail` keeps both (a redo that crashed didn't address the complaint). Unchanged from today except that the region list now moves in lockstep. The lockstep is load-bearing and the aggregate is the only writer: **stale prose is a confusing sentence in a kickoff; a stale region list is work silently not done.** `Both_halves_of_a_send_back_are_cleared_together_by_success` and `A_send_back_replaces_the_previous_rounds_regions_rather_than_adding_to_them` pin it, and executors read the per-attempt snapshot in `StageContext`, never a fresh row. ## What's in - **Domain** — `RegionProblem(Region, Problem)`; `Execution.FeedbackRegions` written only by `SendBack`, dropped only by `Succeed`. - **Persistence** — one JSON `TEXT` column via the existing `JsonColumnMapper` (nothing queries into it). **The migration's default is hand-corrected to `"[]"`** — EF generated `""`, which is not JSON and would throw inside the value converter on the first read of any pre-existing execution: a migration that "succeeds" and then breaks the monitor on the next boot. - **`report_qa`** — gains `regions[]`, and **validates the labels** rather than taking them on trust. A verdict naming a region that doesn't exist would route its complaint nowhere, silently; the agent hears about the typo while it can still deliver the verdict it meant. Both nested fields are required in the schema because the handler refuses either blank. - **Routing** — `SendChainBackAsync` replaces the copy-pasted loops in both QA executors, keeping the head-first ordering the gate depends on. The sfx pass passes `scoped: null`: it has no refinement stage, so its boxer takes both halves and always re-runs, being the only agent that can act on either. - **Prompts** — both QA briefs now tell the agent which channel is which, including the failure mode: *"Naming boxes in feedback instead of in regions gets the complaint read by every agent and acted on by none."* - **Monitor + seeder** — the sent-back row renders each named box under the stage; the seeded world grows a second send-back of the new shape, so the monitor has both to show. ## Tests **+19, 746/746 green** (Domain 82, UseCases 317, Integration 157, BlazorAdapter 190). - **Domain (4)** — the lockstep clear; a second send-back *replacing* round one's regions rather than accumulating; a page-level send-back leaving none behind; `Start` keeping feedback while clearing the error. - **`RefinementWorkListTests` (5, new)** — nothing named → whole page; a named box worked though settled; every rough box riding along uninvited (the boxing-redo case); a named box that no longer exists simply absent; case-insensitive matching, since a verdict typed `P1R3` must not route nowhere. - **`AnnotationToolTests` (5)** — a verdict naming boxes; an unknown label refused with nothing recorded; `needs_work` with neither channel refused; a named box with a blank problem refused; `ok` needing neither. Plus the coarse pass's move marking a *settled* box rough while the sfx pass's leaves it alone. - **`AnnotationRunTests` (2)** — end to end: a purely-region verdict leaves `BboxCreation` at attempt 1 and refines exactly `["p1r1","p1r2","p1r3","p1r2","p1r3"]` across the two passes, with p1r3's second kickoff carrying its own complaint and p1r2's (present only because rough) not carrying it. And the sfx variant, where the boxer re-runs and gets the list. - **Integration (2)** — the column round-trips and is dropped by success; a never-sent-back row reads back empty (the migration-default path). - **Seeder + monitor (2)** — the contract test pins the scoped send-back; a bUnit test pins both halves rendering. ## Browser-verified Seeded world, run monitor expanded — the *Bbox refinement* sent-back row shows the stage note plus `p3r1: the box cuts the last column of glyphs on its left edge` and `p3r3: this is a sign in the artwork, not free text — retype it` as separate lines. Only console error is the pre-existing `favicon.ico` 404. ## Deliberately not here **Transcription still re-verifies every region.** I flagged this trade to bjoern when we designed it — scoping it to `named ∪ untranscribed` is what kills the last of the full-page cost, but it trades away the deliberate distrust of pre-seeded text (`NeedsTranscription`), and he hasn't called it. It's a one-line change on top of this, and it's the only remaining piece of the cost story: a send-back now re-runs one boxing agent fewer and only the affected refinement agents, but still every transcription agent. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: a review verdict reaches the agent that can act on it
All checks were successful
CI / build (pull_request) Successful in 24s
CI / test (pull_request) Successful in 42s
8c33668dfa
Page QA had one channel: a free-text blob that went to the boxing pass and
nowhere else. Refinement and transcription were sent back with a canned line,
so "the box on p1r3 cuts the last glyph column" never reached p1r3's agent —
the one whose entire job is that box — and every other region's agent read a
complaint that was not about it.

A verdict now has two halves, because not every complaint has a region to
name. Page-level prose (printed text with no region at all, an order wrong as
a whole) stays the boxing pass's business. Per-region entries name a stable
label and reach only the bound agent for that box. Three things follow:

- a verdict that named only boxes does not re-run the boxing pass at all; its
  row stays succeeded and the gate lets the redo through, so a page-wide agent
  is not spent on a complaint about two boxes;
- refinement's work-list becomes the named boxes plus every box still marked
  rough. The union is a safety property, not an optimisation: the scope can
  only add to the rough floor, never cut below it, so a stale or wrong scope
  costs redundant work rather than silently skipping boxes;
- the boxing pass's move_resize_region now marks what it moves rough, which is
  what makes that floor trustworthy — a box it re-placed is a box at its own
  coarse granularity, even if an earlier refinement had settled it. The sfx
  pass keeps marking nothing: no refinement follows it (ADR 0023).

report_qa validates the labels it is given rather than taking them on trust. A
verdict naming a region that does not exist would route its complaint nowhere,
silently; the agent hears about the typo while it can still deliver the verdict
it meant.

Summary

Summary
Generated on: 07/27/2026 - 16:25:18
Coverage date: 07/27/2026 - 16:25:02 - 07/27/2026 - 16:25:15
Parser: MultiReport (4x Cobertura)
Assemblies: 6
Classes: 416
Files: 197
Line coverage: 96.2% (13118 of 13625)
Covered lines: 13118
Uncovered lines: 507
Coverable lines: 13625
Total lines: 24130
Branch coverage: 83.2% (2559 of 3075)
Covered branches: 2559
Total branches: 3075
Method coverage: Feature is only available for sponsors

Coverage

Orihon.BlazorAdapter - 95.9%
Name Line Branch
Orihon.BlazorAdapter 95.9% 88.5%
Orihon.BlazorAdapter.Bible.AddBeatRowRequested 100%
Orihon.BlazorAdapter.Bible.AddCharacterRowRequested 100%
Orihon.BlazorAdapter.Bible.AddGlossaryRowRequested 100%
Orihon.BlazorAdapter.Bible.AddLoreRowRequested 100%
Orihon.BlazorAdapter.Bible.BibleEffects 92.2% 79.1%
Orihon.BlazorAdapter.Bible.BibleLoaded 100%
Orihon.BlazorAdapter.Bible.BiblePage 93.7% 81.6%
Orihon.BlazorAdapter.Bible.BibleReducers 93.1%
Orihon.BlazorAdapter.Bible.BibleState 100%
Orihon.BlazorAdapter.Bible.BibleWriteFailed 100%
Orihon.BlazorAdapter.Bible.DeleteBeatRowRequested 100%
Orihon.BlazorAdapter.Bible.DeleteCharacterRowRequested 100%
Orihon.BlazorAdapter.Bible.DeleteGlossaryRowRequested 100%
Orihon.BlazorAdapter.Bible.DeleteLoreRowRequested 0%
Orihon.BlazorAdapter.Bible.LoadBible 100%
Orihon.BlazorAdapter.Bible.ReorderBeatsRequested 0%
Orihon.BlazorAdapter.Bible.SaveOverviewRequested 100%
Orihon.BlazorAdapter.Bible.SaveSummaryRequested 100%
Orihon.BlazorAdapter.Bible.UpdateBeatRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateCharacterRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateGlossaryRowRequested 100%
Orihon.BlazorAdapter.Bible.UpdateLoreRowRequested 100%
Orihon.BlazorAdapter.BlazorAdapterAssembly 100%
Orihon.BlazorAdapter.Debounce 96.2% 94.4%
Orihon.BlazorAdapter.Diagnostics.CircuitError 100%
Orihon.BlazorAdapter.Diagnostics.CircuitErrorPanel 100%
Orihon.BlazorAdapter.Diagnostics.CircuitErrorSink 100% 85.7%
Orihon.BlazorAdapter.Diagnostics.OrihonStoreInitializer 85.7% 66.6%
Orihon.BlazorAdapter.PageWorkspace.CreateRegionRequested 100%
Orihon.BlazorAdapter.PageWorkspace.DeletePageSummaryRequested 100%
Orihon.BlazorAdapter.PageWorkspace.DeleteRegionRequested 100%
Orihon.BlazorAdapter.PageWorkspace.LoadPageWorkspace 100%
Orihon.BlazorAdapter.PageWorkspace.PageSummarySaved 100%
Orihon.BlazorAdapter.PageWorkspace.PageViewport 100% 100%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceEffects 100% 100%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceLoaded 100%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspacePage 92.2% 85.5%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceReducers 100% 66.6%
Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceState 100%
Orihon.BlazorAdapter.PageWorkspace.PageWriteFailed 100%
Orihon.BlazorAdapter.PageWorkspace.RegionCreated 100%
Orihon.BlazorAdapter.PageWorkspace.RegionSaved 100%
Orihon.BlazorAdapter.PageWorkspace.ReorderRegionsRequested 100%
Orihon.BlazorAdapter.PageWorkspace.ReprocessPageRequested 100%
Orihon.BlazorAdapter.PageWorkspace.ReprocessTranslationRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SavePageSummaryRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SaveRegionRequested 100%
Orihon.BlazorAdapter.PageWorkspace.SetPageMetaRequested 100%
Orihon.BlazorAdapter.Projects.CreateProjectRequested 100%
Orihon.BlazorAdapter.Projects.DecideSetupContinuation 100%
Orihon.BlazorAdapter.Projects.DeleteProjectRequested 100%
Orihon.BlazorAdapter.Projects.FinishSetupRequested 100%
Orihon.BlazorAdapter.Projects.ImportPagesRequested 100%
Orihon.BlazorAdapter.Projects.LoadWizard 100%
Orihon.BlazorAdapter.Projects.PageOrganizer 96% 95%
Orihon.BlazorAdapter.Projects.PagesImported 100%
Orihon.BlazorAdapter.Projects.ProjectDeleteFailed 100%
Orihon.BlazorAdapter.Projects.ProjectListEffects 100% 100%
Orihon.BlazorAdapter.Projects.ProjectListPage 89.7% 91.1%
Orihon.BlazorAdapter.Projects.ProjectListReducers 100%
Orihon.BlazorAdapter.Projects.ProjectListState 100%
Orihon.BlazorAdapter.Projects.ProjectsLoaded 100%
Orihon.BlazorAdapter.Projects.ProjectWizardEffects 93.8% 90%
Orihon.BlazorAdapter.Projects.ProjectWizardPage 95.3% 84.1%
Orihon.BlazorAdapter.Projects.ProjectWizardReducers 100%
Orihon.BlazorAdapter.Projects.ProjectWizardState 100%
Orihon.BlazorAdapter.Projects.SetupChat 93.5% 100%
Orihon.BlazorAdapter.Projects.SetupChatEffects 100% 100%
Orihon.BlazorAdapter.Projects.SetupChatFailed 100%
Orihon.BlazorAdapter.Projects.SetupChatReducers 100%
Orihon.BlazorAdapter.Projects.SetupChatState 100%
Orihon.BlazorAdapter.Projects.SetupChatUpdated 100%
Orihon.BlazorAdapter.Projects.StartSetupChat 100%
Orihon.BlazorAdapter.Projects.SubmitSetupAnswer 100%
Orihon.BlazorAdapter.Projects.WizardDeletePagesRequested 100%
Orihon.BlazorAdapter.Projects.WizardLoaded 100%
Orihon.BlazorAdapter.Projects.WizardMovePagesRequested 100%
Orihon.BlazorAdapter.Projects.WizardMovePagesToNewChapterRequested 100%
Orihon.BlazorAdapter.Projects.WizardReorderPagesRequested 100%
Orihon.BlazorAdapter.Projects.WizardWriteFailed 100%
Orihon.BlazorAdapter.Runs.CancelMonitorRun 100%
Orihon.BlazorAdapter.Runs.MonitorPageRef 100%
Orihon.BlazorAdapter.Runs.MonitorRunLoaded 100%
Orihon.BlazorAdapter.Runs.RunChangedBridge 95% 92.8%
Orihon.BlazorAdapter.Runs.RunMonitor 97.9% 96.1%
Orihon.BlazorAdapter.Runs.RunMonitorEffects 100% 91.6%
Orihon.BlazorAdapter.Runs.RunMonitorReducers 100%
Orihon.BlazorAdapter.Runs.RunMonitorState 100%
Orihon.BlazorAdapter.Settings.AgentDebriefsLoaded 100%
Orihon.BlazorAdapter.Settings.AgentDebriefsLoadFailed 100%
Orihon.BlazorAdapter.Settings.AgentModelPicked 100%
Orihon.BlazorAdapter.Settings.AgentModelSaved 100%
Orihon.BlazorAdapter.Settings.AgentModelSaveFailed 100%
Orihon.BlazorAdapter.Settings.KeySaved 100%
Orihon.BlazorAdapter.Settings.KeySaveFailed 100%
Orihon.BlazorAdapter.Settings.ModelOptionsLoaded 100%
Orihon.BlazorAdapter.Settings.ModelOptionsUnavailable 100%
Orihon.BlazorAdapter.Settings.SaveKeyRequested 100%
Orihon.BlazorAdapter.Settings.SettingsEffects 95.9% 83.3%
Orihon.BlazorAdapter.Settings.SettingsLoaded 100%
Orihon.BlazorAdapter.Settings.SettingsPage 100% 89.6%
Orihon.BlazorAdapter.Settings.SettingsReducers 100%
Orihon.BlazorAdapter.Settings.SettingsState 100%
Orihon.BlazorAdapter.Settings.SfxPassToggled 100%
Orihon.BlazorAdapter.Uploads.UploadTransfer 96.5% 100%
Orihon.BlazorAdapter.Uploads.UploadTransferProgress 100% 100%
Orihon.BlazorAdapter.Uploads.UploadTransferResult 100%
Orihon.BlazorAdapter.Workspace.CreateChapterRequested 100%
Orihon.BlazorAdapter.Workspace.DeleteChapterRequested 100%
Orihon.BlazorAdapter.Workspace.DeletePageRequested 100%
Orihon.BlazorAdapter.Workspace.DeleteSummaryRequested 100%
Orihon.BlazorAdapter.Workspace.LoadProjectWorkspace 100%
Orihon.BlazorAdapter.Workspace.MovePageRequested 100%
Orihon.BlazorAdapter.Workspace.ProjectMetadataCard 95.6% 92.8%
Orihon.BlazorAdapter.Workspace.ProjectMetadataSaved 100%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceEffects 100% 100%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceLoaded 100%
Orihon.BlazorAdapter.Workspace.ProjectWorkspacePage 95.5% 88.3%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceReducers 100% 62.5%
Orihon.BlazorAdapter.Workspace.ProjectWorkspaceState 100%
Orihon.BlazorAdapter.Workspace.RenameChapterRequested 100%
Orihon.BlazorAdapter.Workspace.ReorderChaptersRequested 100%
Orihon.BlazorAdapter.Workspace.ReorderPagesRequested 100%
Orihon.BlazorAdapter.Workspace.RunAnnotationRequested 100%
Orihon.BlazorAdapter.Workspace.RunBibleRequested 100%
Orihon.BlazorAdapter.Workspace.RunTranslationRequested 100%
Orihon.BlazorAdapter.Workspace.SaveProjectMetadataRequested 100%
Orihon.BlazorAdapter.Workspace.SaveSummaryRequested 100%
Orihon.BlazorAdapter.Workspace.SetPageKindRequested 100%
Orihon.BlazorAdapter.Workspace.SummaryDeleted 100%
Orihon.BlazorAdapter.Workspace.SummarySaved 100%
Orihon.BlazorAdapter.Workspace.WorkspaceImportRequested 100%
Orihon.BlazorAdapter.Workspace.WorkspaceWriteFailed 100%
Orihon.Domain - 100%
Name Line Branch
Orihon.Domain 100% 100%
Orihon.Domain.Agents.AgentDebrief 100% 100%
Orihon.Domain.Agents.AgentDescriptor 100%
Orihon.Domain.Agents.AgentRoster 100% 100%
Orihon.Domain.Bible.Character 100% 100%
Orihon.Domain.Bible.GlossaryEntry 100% 100%
Orihon.Domain.Bible.LoreEntry 100% 100%
Orihon.Domain.Bible.PageSummary 100%
Orihon.Domain.Bible.StoryBeat 100%
Orihon.Domain.Bible.StoryOverview 100%
Orihon.Domain.Projects.Project 100% 100%
Orihon.Domain.Projects.ProjectProfile 100%
Orihon.Domain.Runs.Execution 100% 100%
Orihon.Domain.Runs.RegionProblem 100%
Orihon.Domain.Runs.Run 100%
Orihon.Domain.Settings.AppSetting 100%
Orihon.Domain.Text 100% 100%
Orihon.Domain.Translation.BoundingBox 100%
Orihon.Domain.Translation.Chapter 100%
Orihon.Domain.Translation.Page 100%
Orihon.Domain.Translation.Region 100% 100%
Orihon.Domain.Translation.RegionProfile 100%
Orihon.Infrastructure - 95.9%
Name Line Branch
Orihon.Infrastructure 95.9% 71.3%
Orihon.Infrastructure.Agents.EfAgentDebriefStore 100%
Orihon.Infrastructure.Bible.EfBibleStore 94.4% 91.6%
Orihon.Infrastructure.DependencyInjection 100% 100%
Orihon.Infrastructure.Gateways.AgentToolAdapter 100%
Orihon.Infrastructure.Gateways.AgentToolAdapter`1 100% 100%
Orihon.Infrastructure.Gateways.AgentTranscript 92.8% 80.3%
Orihon.Infrastructure.Gateways.FileSystemAgentTranscriptStore 86.1% 78.5%
Orihon.Infrastructure.Gateways.HttpWebPageFetcher 95.1% 83.3%
Orihon.Infrastructure.Gateways.OpenRouterLlmGateway 95.7% 89.7%
Orihon.Infrastructure.Gateways.SkiaPageImageRenderer 97.3% 87.8%
Orihon.Infrastructure.Persistence.Configurations.AgentDebriefConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.ChapterConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.CharacterConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.ExecutionConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.GlossaryEntryConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.JsonColumnMapper 100%
Orihon.Infrastructure.Persistence.Configurations.LoreEntryConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.PageConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.PageSummaryConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.ProjectConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.RegionConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.RunConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.StoryBeatConfiguration 100%
Orihon.Infrastructure.Persistence.Configurations.StoryOverviewConfiguration 100%
Orihon.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Orihon.Infrastructure.Persistence.Migrations.AddAgentDebriefs 99.5%
Orihon.Infrastructure.Persistence.Migrations.AddAppSettings 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddExecutionFeedbackRegions 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddProjectSourceLanguage 99.3%
Orihon.Infrastructure.Persistence.Migrations.AddRuns 99.1%
Orihon.Infrastructure.Persistence.Migrations.AddStoryOverview 99.5%
Orihon.Infrastructure.Persistence.Migrations.InitialTranslationDomain 97.3%
Orihon.Infrastructure.Persistence.Migrations.OrihonDbContextModelSnapshot 100%
Orihon.Infrastructure.Persistence.Migrations.RenameSourceTargetColumns 97.2%
Orihon.Infrastructure.Persistence.OrihonDbContext 100%
Orihon.Infrastructure.Persistence.OrihonDbContextFactory 100%
Orihon.Infrastructure.Projects.EfProjectStore 100% 100%
Orihon.Infrastructure.Projects.FileSystemPageImageStore 100% 100%
Orihon.Infrastructure.Runs.EfRunStore 97.5% 75%
Orihon.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Orihon.Infrastructure.Translation.EfChapterStore 100% 100%
Orihon.Infrastructure.Translation.EfPageStore 86% 80%
Orihon.Infrastructure.Translation.EfRegionStore 100% 100%
Orihon.Infrastructure.Translation.Ordering 100% 100%
System.Text.RegularExpressions.Generated 70.6% 53.3%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4
77.9% 76.6%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1
59% 42.5%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3
89.4% 75%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030
A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2
83.7% 62.5%
Orihon.Kernel - 90.9%
Name Line Branch
Orihon.Kernel 90.9% 75%
Orihon.Kernel.Err`1 100%
Orihon.Kernel.Ok`1 100%
Orihon.Kernel.Result`1 88.8% 75%
Orihon.Server - 93.3%
Name Line Branch
Orihon.Server 93.3% 70%
Orihon.Server.Components.App 100%
Orihon.Server.Components.Layout.MainLayout 100%
Orihon.Server.Components.Pages.Gate 64.2% 66.6%
Orihon.Server.RunEngineBootstrap 100%
Orihon.Server.Security.AccessGate 91.8% 41.6%
Orihon.Server.Security.AccessSecret 100% 50%
Orihon.Server.VolumeStartupValidator 100% 100%
Program 94.8% 87.5%
Orihon.UseCases - 96.8%
Name Line Branch
Orihon.UseCases 96.8% 87.2%
Orihon.UseCases.Agents.AgentAttemptPreparation 100%
Orihon.UseCases.Agents.AgentAttemptSupport 100% 95%
Orihon.UseCases.Agents.AgentBlueprint 100%
Orihon.UseCases.Agents.AgentCapDebrief 100%
Orihon.UseCases.Agents.AgentInvocation 100%
Orihon.UseCases.Agents.AgentOutcome 100%
Orihon.UseCases.Agents.AgentTool`1 90.9% 75%
Orihon.UseCases.Agents.AgentToolImage 100%
Orihon.UseCases.Agents.AgentToolResult 100%
Orihon.UseCases.Agents.Annotation.AddRegionParams 100%
Orihon.UseCases.Agents.Annotation.AddRegionTool 93.3% 50%
Orihon.UseCases.Agents.Annotation.AddSfxRegionTool 93.3% 50%
Orihon.UseCases.Agents.Annotation.AnnotationBlueprints 100%
Orihon.UseCases.Agents.Annotation.AnnotationStage 97.5% 80%
Orihon.UseCases.Agents.Annotation.BboxCreationExecutor 94.1% 50%
Orihon.UseCases.Agents.Annotation.BboxRefinementExecutor 93.7% 81.2%
Orihon.UseCases.Agents.Annotation.BoundBoxParams 100%
Orihon.UseCases.Agents.Annotation.BoundContactSheetTool 86.9% 62.5%
Orihon.UseCases.Agents.Annotation.BoundCropParams 100%
Orihon.UseCases.Agents.Annotation.BoundCropTool 100%
Orihon.UseCases.Agents.Annotation.BoundViewPageTool 91.6% 80%
Orihon.UseCases.Agents.Annotation.BoundViewParams 100%
Orihon.UseCases.Agents.Annotation.DeleteBoundRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.DeleteRegionParams 100%
Orihon.UseCases.Agents.Annotation.DeleteRegionTool 100% 100%
Orihon.UseCases.Agents.Annotation.FindGlossaryParams 100%
Orihon.UseCases.Agents.Annotation.FindGlossaryTool 88.2% 62.5%
Orihon.UseCases.Agents.Annotation.ListRegionsTool 88.2% 60%
Orihon.UseCases.Agents.Annotation.MoveResizeBoundTool 90.9% 50%
Orihon.UseCases.Agents.Annotation.MoveResizeRegionParams 100%
Orihon.UseCases.Agents.Annotation.MoveResizeRegionTool 95% 83.3%
Orihon.UseCases.Agents.Annotation.PageQaExecutor 94.4% 81.8%
Orihon.UseCases.Agents.Annotation.QaReportSink 100% 100%
Orihon.UseCases.Agents.Annotation.RegionAuthoringAccess 87.2% 53.8%
Orihon.UseCases.Agents.Annotation.RegionBriefing 100% 100%
Orihon.UseCases.Agents.Annotation.RegionCropParams 100%
Orihon.UseCases.Agents.Annotation.RegionCropTool 100%
Orihon.UseCases.Agents.Annotation.RegionProblemParams 100%
Orihon.UseCases.Agents.Annotation.RejectRegionParams 100%
Orihon.UseCases.Agents.Annotation.RejectRegionTool 100% 50%
Orihon.UseCases.Agents.Annotation.ReorderRegionParams 100%
Orihon.UseCases.Agents.Annotation.ReorderRegionTool 88% 60%
Orihon.UseCases.Agents.Annotation.ReportQaParams 100%
Orihon.UseCases.Agents.Annotation.ReportQaTool 97.7% 90%
Orihon.UseCases.Agents.Annotation.SetPageMetaParams 100%
Orihon.UseCases.Agents.Annotation.SetPageMetaTool 100% 75%
Orihon.UseCases.Agents.Annotation.SetRegionTypeParams 100%
Orihon.UseCases.Agents.Annotation.SetRegionTypeTool 100% 87.5%
Orihon.UseCases.Agents.Annotation.SetTranscriptionParams 100%
Orihon.UseCases.Agents.Annotation.SetTranscriptionTool 100% 100%
Orihon.UseCases.Agents.Annotation.SfxCreationExecutor 88.8% 50%
Orihon.UseCases.Agents.Annotation.SfxQaExecutor 93.9% 83.3%
Orihon.UseCases.Agents.Annotation.SfxTranscriptionExecutor 93.1% 80%
Orihon.UseCases.Agents.Annotation.TranscriptionExecutor 93.1% 80%
Orihon.UseCases.Agents.AssistantSpoke 100%
Orihon.UseCases.Agents.BibleBuilding.BibleBuildingBlueprint 100%
Orihon.UseCases.Agents.BibleBuilding.BibleBuildingExecutor 96.5% 75%
Orihon.UseCases.Agents.BibleBuilding.GetRegionParams 100%
Orihon.UseCases.Agents.BibleBuilding.GetRegionTool 84.6% 72.2%
Orihon.UseCases.Agents.BibleBuilding.ListProjectRegionsTool 86.3% 90%
Orihon.UseCases.Agents.BibleBuilding.ListRegionsParams 100%
Orihon.UseCases.Agents.Inspection.ContactSheetParams 100%
Orihon.UseCases.Agents.Inspection.ContactSheetTool 78.2% 87.5%
Orihon.UseCases.Agents.Inspection.CropParams 100%
Orihon.UseCases.Agents.Inspection.CropTool 36.3%
Orihon.UseCases.Agents.Inspection.PageImageAccess 95.2% 77.6%
Orihon.UseCases.Agents.ResearchSetup.AddGlossaryParams 100%
Orihon.UseCases.Agents.ResearchSetup.AddGlossaryTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatParams 100%
Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatTool 100% 50%
Orihon.UseCases.Agents.ResearchSetup.AskUserParams 100%
Orihon.UseCases.Agents.ResearchSetup.AskUserTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.FetchUrlParams 100%
Orihon.UseCases.Agents.ResearchSetup.FetchUrlTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.ListBibleTool 89.4% 100%
Orihon.UseCases.Agents.ResearchSetup.ListPagesTool 97% 83.3%
Orihon.UseCases.Agents.ResearchSetup.LocatedPage 100%
Orihon.UseCases.Agents.ResearchSetup.PageByNumber 95% 91.6%
Orihon.UseCases.Agents.ResearchSetup.ResearchSetupBlueprint 100%
Orihon.UseCases.Agents.ResearchSetup.SetPageMetaParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetPageMetaTool 95.2% 90%
Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryTool 100% 75%
Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataTool 96.5% 95.8%
Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewParams 100%
Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewTool 100% 100%
Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterParams 100%
Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterTool 92.3% 71.4%
Orihon.UseCases.Agents.ResearchSetup.UpsertLoreParams 100%
Orihon.UseCases.Agents.ResearchSetup.UpsertLoreTool 92.3% 71.4%
Orihon.UseCases.Agents.ResearchSetup.ViewPageParams 100%
Orihon.UseCases.Agents.ResearchSetup.ViewPageTool 100% 100%
Orihon.UseCases.Agents.RoundStarted 100%
Orihon.UseCases.Agents.Setup.ResearchSetupExecutor 98.4% 92.8%
Orihon.UseCases.Agents.Setup.SetupChatEntry 100%
Orihon.UseCases.Agents.Setup.SetupConversation 100% 90.6%
Orihon.UseCases.Agents.Setup.SetupConversationRegistry 100%
Orihon.UseCases.Agents.ToolCalled 100%
Orihon.UseCases.Agents.ToolCompleted 100%
Orihon.UseCases.Agents.Translation.GetPageSummaryParams 100%
Orihon.UseCases.Agents.Translation.GetPageSummaryTool 80% 66.6%
Orihon.UseCases.Agents.Translation.SetTranslationParams 100%
Orihon.UseCases.Agents.Translation.SetTranslationTool 88.5% 78.5%
Orihon.UseCases.Agents.Translation.TranslationBlueprint 100%
Orihon.UseCases.Agents.Translation.TranslationExecutor 95.5% 71.4%
Orihon.UseCases.Agents.Translation.UpdateGlossaryEnParams 100%
Orihon.UseCases.Agents.Translation.UpdateGlossaryEnTool 82.6% 62.5%
Orihon.UseCases.Bible.AddCharacter 100% 100%
Orihon.UseCases.Bible.AddGlossaryEntry 100% 100%
Orihon.UseCases.Bible.AddLoreEntry 100% 100%
Orihon.UseCases.Bible.AddStoryBeat 100% 100%
Orihon.UseCases.Bible.BibleDto 100%
Orihon.UseCases.Bible.CharacterDto 100%
Orihon.UseCases.Bible.DeleteCharacter 100% 100%
Orihon.UseCases.Bible.DeleteGlossaryEntry 100% 100%
Orihon.UseCases.Bible.DeleteLoreEntry 100% 100%
Orihon.UseCases.Bible.DeletePageSummary 100% 100%
Orihon.UseCases.Bible.DeleteStoryBeat 100% 100%
Orihon.UseCases.Bible.GetBible 100% 100%
Orihon.UseCases.Bible.GlossaryEntryDto 100%
Orihon.UseCases.Bible.LoreEntryDto 100%
Orihon.UseCases.Bible.PageSummaryDto 100%
Orihon.UseCases.Bible.ReorderStoryBeats 100%
Orihon.UseCases.Bible.SetPageSummary 100% 100%
Orihon.UseCases.Bible.SetStoryOverview 100% 100%
Orihon.UseCases.Bible.StoryBeatDto 100%
Orihon.UseCases.Bible.StoryOverviewDto 100%
Orihon.UseCases.Bible.UpdateCharacter 100% 100%
Orihon.UseCases.Bible.UpdateGlossaryEntry 100% 100%
Orihon.UseCases.Bible.UpdateLoreEntry 100% 100%
Orihon.UseCases.Bible.UpdateStoryBeat 100% 100%
Orihon.UseCases.Chapters.ChapterDto 100%
Orihon.UseCases.Chapters.CreateChapter 100% 100%
Orihon.UseCases.Chapters.DeleteChapter 100% 100%
Orihon.UseCases.Chapters.RenameChapter 100% 100%
Orihon.UseCases.Chapters.ReorderChapters 100%
Orihon.UseCases.Debriefs.AgentDebriefDto 90.9%
Orihon.UseCases.Debriefs.ClearAgentDebriefs 100%
Orihon.UseCases.Debriefs.ListAgentDebriefs 100% 100%
Orihon.UseCases.DependencyInjection 100%
Orihon.UseCases.Diagnostics.SeedDevData 99.4% 93.7%
Orihon.UseCases.Gateways.LabeledBox 100%
Orihon.UseCases.Gateways.LlmKeyInfo 100%
Orihon.UseCases.Gateways.LlmModel 100%
Orihon.UseCases.NextOrder 100%
Orihon.UseCases.Pages.DeletePage 100% 100%
Orihon.UseCases.Pages.DeletePages 100% 100%
Orihon.UseCases.Pages.GetPage 100% 100%
Orihon.UseCases.Pages.GetProjectWorkspace 100% 100%
Orihon.UseCases.Pages.ImportPages 100% 100%
Orihon.UseCases.Pages.ImportPagesResult 100%
Orihon.UseCases.Pages.MarkPageAnnotated 100% 100%
Orihon.UseCases.Pages.MovePage 100% 92.8%
Orihon.UseCases.Pages.MovePages 100% 100%
Orihon.UseCases.Pages.PageDetailDto 100%
Orihon.UseCases.Pages.PageDto 100%
Orihon.UseCases.Pages.PageUpload 100%
Orihon.UseCases.Pages.ProjectWorkspaceDto 100%
Orihon.UseCases.Pages.ReorderPages 100%
Orihon.UseCases.Pages.SetPageMeta 100% 100%
Orihon.UseCases.Pages.WorkspaceChapterDto 100%
Orihon.UseCases.Projects.CompleteProjectSetup 100% 93.7%
Orihon.UseCases.Projects.CreateProject 100% 100%
Orihon.UseCases.Projects.DeleteProject 100% 100%
Orihon.UseCases.Projects.GetProject 100% 100%
Orihon.UseCases.Projects.ListProjects 100%
Orihon.UseCases.Projects.ProjectDto 96.1%
Orihon.UseCases.Projects.StartAnnotationRun 96.4% 92.8%
Orihon.UseCases.Projects.StartBibleRun 90.9% 83.3%
Orihon.UseCases.Projects.StartSetupRun 100% 100%
Orihon.UseCases.Projects.StartTranslationRun 90.9% 83.3%
Orihon.UseCases.Projects.StoredPageImage 100%
Orihon.UseCases.Projects.UpdateProjectMetadata 100% 100%
Orihon.UseCases.Regions.CreateRegion 100% 100%
Orihon.UseCases.Regions.DeleteRegion 100% 100%
Orihon.UseCases.Regions.RegionDto 97%
Orihon.UseCases.Regions.ReorderRegions 100%
Orihon.UseCases.Regions.UpdateRegion 100% 100%
Orihon.UseCases.Runs.AnnotationPipeline 100% 100%
Orihon.UseCases.Runs.ExecutionDto 93.3%
Orihon.UseCases.Runs.ExecutionProgress 100%
Orihon.UseCases.Runs.ExecutionProgressRegistry 100% 100%
Orihon.UseCases.Runs.ExecutionPulseRelay 100% 100%
Orihon.UseCases.Runs.PlannedExecution 100%
Orihon.UseCases.Runs.PulseTarget 100%
Orihon.UseCases.Runs.ReprocessPage 100% 94.4%
Orihon.UseCases.Runs.ReprocessTranslation 94.1% 92.8%
Orihon.UseCases.Runs.RunDto 93.3% 100%
Orihon.UseCases.Runs.RunEngine 97.2% 90.1%
Orihon.UseCases.Runs.RunEngineOptions 100%
Orihon.UseCases.Runs.StageContext 100% 50%
Orihon.UseCases.Runs.StageHaltedException 100%
Orihon.UseCases.Settings.AgentSettingDto 100% 100%
Orihon.UseCases.Settings.GetSettings 100% 100%
Orihon.UseCases.Settings.ListModelOptions 100% 100%
Orihon.UseCases.Settings.SaveAgentModel 100% 100%
Orihon.UseCases.Settings.SaveOpenRouterKey 100% 100%
Orihon.UseCases.Settings.SaveSfxPass 100% 100%
Orihon.UseCases.Settings.SettingKeys 100% 100%
Orihon.UseCases.Settings.SettingsDto 100%
<!-- coverage-comment --> # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 07/27/2026 - 16:25:18 | | Coverage date: | 07/27/2026 - 16:25:02 - 07/27/2026 - 16:25:15 | | Parser: | MultiReport (4x Cobertura) | | Assemblies: | 6 | | Classes: | 416 | | Files: | 197 | | **Line coverage:** | 96.2% (13118 of 13625) | | Covered lines: | 13118 | | Uncovered lines: | 507 | | Coverable lines: | 13625 | | Total lines: | 24130 | | **Branch coverage:** | 83.2% (2559 of 3075) | | Covered branches: | 2559 | | Total branches: | 3075 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Orihon.BlazorAdapter - 95.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.BlazorAdapter**|**95.9%**|**88.5%**| |Orihon.BlazorAdapter.Bible.AddBeatRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddCharacterRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddGlossaryRowRequested|100%|| |Orihon.BlazorAdapter.Bible.AddLoreRowRequested|100%|| |Orihon.BlazorAdapter.Bible.BibleEffects|92.2%|79.1%| |Orihon.BlazorAdapter.Bible.BibleLoaded|100%|| |Orihon.BlazorAdapter.Bible.BiblePage|93.7%|81.6%| |Orihon.BlazorAdapter.Bible.BibleReducers|93.1%|| |Orihon.BlazorAdapter.Bible.BibleState|100%|| |Orihon.BlazorAdapter.Bible.BibleWriteFailed|100%|| |Orihon.BlazorAdapter.Bible.DeleteBeatRowRequested|100%|| |Orihon.BlazorAdapter.Bible.DeleteCharacterRowRequested|100%|| |Orihon.BlazorAdapter.Bible.DeleteGlossaryRowRequested|100%|| |Orihon.BlazorAdapter.Bible.DeleteLoreRowRequested|0%|| |Orihon.BlazorAdapter.Bible.LoadBible|100%|| |Orihon.BlazorAdapter.Bible.ReorderBeatsRequested|0%|| |Orihon.BlazorAdapter.Bible.SaveOverviewRequested|100%|| |Orihon.BlazorAdapter.Bible.SaveSummaryRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateBeatRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateCharacterRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateGlossaryRowRequested|100%|| |Orihon.BlazorAdapter.Bible.UpdateLoreRowRequested|100%|| |Orihon.BlazorAdapter.BlazorAdapterAssembly|100%|| |Orihon.BlazorAdapter.Debounce|96.2%|94.4%| |Orihon.BlazorAdapter.Diagnostics.CircuitError|100%|| |Orihon.BlazorAdapter.Diagnostics.CircuitErrorPanel|100%|| |Orihon.BlazorAdapter.Diagnostics.CircuitErrorSink|100%|85.7%| |Orihon.BlazorAdapter.Diagnostics.OrihonStoreInitializer|85.7%|66.6%| |Orihon.BlazorAdapter.PageWorkspace.CreateRegionRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.DeletePageSummaryRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.DeleteRegionRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.LoadPageWorkspace|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageSummarySaved|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageViewport|100%|100%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceEffects|100%|100%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceLoaded|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspacePage|92.2%|85.5%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceReducers|100%|66.6%| |Orihon.BlazorAdapter.PageWorkspace.PageWorkspaceState|100%|| |Orihon.BlazorAdapter.PageWorkspace.PageWriteFailed|100%|| |Orihon.BlazorAdapter.PageWorkspace.RegionCreated|100%|| |Orihon.BlazorAdapter.PageWorkspace.RegionSaved|100%|| |Orihon.BlazorAdapter.PageWorkspace.ReorderRegionsRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.ReprocessPageRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.ReprocessTranslationRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SavePageSummaryRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SaveRegionRequested|100%|| |Orihon.BlazorAdapter.PageWorkspace.SetPageMetaRequested|100%|| |Orihon.BlazorAdapter.Projects.CreateProjectRequested|100%|| |Orihon.BlazorAdapter.Projects.DecideSetupContinuation|100%|| |Orihon.BlazorAdapter.Projects.DeleteProjectRequested|100%|| |Orihon.BlazorAdapter.Projects.FinishSetupRequested|100%|| |Orihon.BlazorAdapter.Projects.ImportPagesRequested|100%|| |Orihon.BlazorAdapter.Projects.LoadWizard|100%|| |Orihon.BlazorAdapter.Projects.PageOrganizer|96%|95%| |Orihon.BlazorAdapter.Projects.PagesImported|100%|| |Orihon.BlazorAdapter.Projects.ProjectDeleteFailed|100%|| |Orihon.BlazorAdapter.Projects.ProjectListEffects|100%|100%| |Orihon.BlazorAdapter.Projects.ProjectListPage|89.7%|91.1%| |Orihon.BlazorAdapter.Projects.ProjectListReducers|100%|| |Orihon.BlazorAdapter.Projects.ProjectListState|100%|| |Orihon.BlazorAdapter.Projects.ProjectsLoaded|100%|| |Orihon.BlazorAdapter.Projects.ProjectWizardEffects|93.8%|90%| |Orihon.BlazorAdapter.Projects.ProjectWizardPage|95.3%|84.1%| |Orihon.BlazorAdapter.Projects.ProjectWizardReducers|100%|| |Orihon.BlazorAdapter.Projects.ProjectWizardState|100%|| |Orihon.BlazorAdapter.Projects.SetupChat|93.5%|100%| |Orihon.BlazorAdapter.Projects.SetupChatEffects|100%|100%| |Orihon.BlazorAdapter.Projects.SetupChatFailed|100%|| |Orihon.BlazorAdapter.Projects.SetupChatReducers|100%|| |Orihon.BlazorAdapter.Projects.SetupChatState|100%|| |Orihon.BlazorAdapter.Projects.SetupChatUpdated|100%|| |Orihon.BlazorAdapter.Projects.StartSetupChat|100%|| |Orihon.BlazorAdapter.Projects.SubmitSetupAnswer|100%|| |Orihon.BlazorAdapter.Projects.WizardDeletePagesRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardLoaded|100%|| |Orihon.BlazorAdapter.Projects.WizardMovePagesRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardMovePagesToNewChapterRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardReorderPagesRequested|100%|| |Orihon.BlazorAdapter.Projects.WizardWriteFailed|100%|| |Orihon.BlazorAdapter.Runs.CancelMonitorRun|100%|| |Orihon.BlazorAdapter.Runs.MonitorPageRef|100%|| |Orihon.BlazorAdapter.Runs.MonitorRunLoaded|100%|| |Orihon.BlazorAdapter.Runs.RunChangedBridge|95%|92.8%| |Orihon.BlazorAdapter.Runs.RunMonitor|97.9%|96.1%| |Orihon.BlazorAdapter.Runs.RunMonitorEffects|100%|91.6%| |Orihon.BlazorAdapter.Runs.RunMonitorReducers|100%|| |Orihon.BlazorAdapter.Runs.RunMonitorState|100%|| |Orihon.BlazorAdapter.Settings.AgentDebriefsLoaded|100%|| |Orihon.BlazorAdapter.Settings.AgentDebriefsLoadFailed|100%|| |Orihon.BlazorAdapter.Settings.AgentModelPicked|100%|| |Orihon.BlazorAdapter.Settings.AgentModelSaved|100%|| |Orihon.BlazorAdapter.Settings.AgentModelSaveFailed|100%|| |Orihon.BlazorAdapter.Settings.KeySaved|100%|| |Orihon.BlazorAdapter.Settings.KeySaveFailed|100%|| |Orihon.BlazorAdapter.Settings.ModelOptionsLoaded|100%|| |Orihon.BlazorAdapter.Settings.ModelOptionsUnavailable|100%|| |Orihon.BlazorAdapter.Settings.SaveKeyRequested|100%|| |Orihon.BlazorAdapter.Settings.SettingsEffects|95.9%|83.3%| |Orihon.BlazorAdapter.Settings.SettingsLoaded|100%|| |Orihon.BlazorAdapter.Settings.SettingsPage|100%|89.6%| |Orihon.BlazorAdapter.Settings.SettingsReducers|100%|| |Orihon.BlazorAdapter.Settings.SettingsState|100%|| |Orihon.BlazorAdapter.Settings.SfxPassToggled|100%|| |Orihon.BlazorAdapter.Uploads.UploadTransfer|96.5%|100%| |Orihon.BlazorAdapter.Uploads.UploadTransferProgress|100%|100%| |Orihon.BlazorAdapter.Uploads.UploadTransferResult|100%|| |Orihon.BlazorAdapter.Workspace.CreateChapterRequested|100%|| |Orihon.BlazorAdapter.Workspace.DeleteChapterRequested|100%|| |Orihon.BlazorAdapter.Workspace.DeletePageRequested|100%|| |Orihon.BlazorAdapter.Workspace.DeleteSummaryRequested|100%|| |Orihon.BlazorAdapter.Workspace.LoadProjectWorkspace|100%|| |Orihon.BlazorAdapter.Workspace.MovePageRequested|100%|| |Orihon.BlazorAdapter.Workspace.ProjectMetadataCard|95.6%|92.8%| |Orihon.BlazorAdapter.Workspace.ProjectMetadataSaved|100%|| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceEffects|100%|100%| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceLoaded|100%|| |Orihon.BlazorAdapter.Workspace.ProjectWorkspacePage|95.5%|88.3%| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceReducers|100%|62.5%| |Orihon.BlazorAdapter.Workspace.ProjectWorkspaceState|100%|| |Orihon.BlazorAdapter.Workspace.RenameChapterRequested|100%|| |Orihon.BlazorAdapter.Workspace.ReorderChaptersRequested|100%|| |Orihon.BlazorAdapter.Workspace.ReorderPagesRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunAnnotationRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunBibleRequested|100%|| |Orihon.BlazorAdapter.Workspace.RunTranslationRequested|100%|| |Orihon.BlazorAdapter.Workspace.SaveProjectMetadataRequested|100%|| |Orihon.BlazorAdapter.Workspace.SaveSummaryRequested|100%|| |Orihon.BlazorAdapter.Workspace.SetPageKindRequested|100%|| |Orihon.BlazorAdapter.Workspace.SummaryDeleted|100%|| |Orihon.BlazorAdapter.Workspace.SummarySaved|100%|| |Orihon.BlazorAdapter.Workspace.WorkspaceImportRequested|100%|| |Orihon.BlazorAdapter.Workspace.WorkspaceWriteFailed|100%|| </details> <details><summary>Orihon.Domain - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Domain**|**100%**|**100%**| |Orihon.Domain.Agents.AgentDebrief|100%|100%| |Orihon.Domain.Agents.AgentDescriptor|100%|| |Orihon.Domain.Agents.AgentRoster|100%|100%| |Orihon.Domain.Bible.Character|100%|100%| |Orihon.Domain.Bible.GlossaryEntry|100%|100%| |Orihon.Domain.Bible.LoreEntry|100%|100%| |Orihon.Domain.Bible.PageSummary|100%|| |Orihon.Domain.Bible.StoryBeat|100%|| |Orihon.Domain.Bible.StoryOverview|100%|| |Orihon.Domain.Projects.Project|100%|100%| |Orihon.Domain.Projects.ProjectProfile|100%|| |Orihon.Domain.Runs.Execution|100%|100%| |Orihon.Domain.Runs.RegionProblem|100%|| |Orihon.Domain.Runs.Run|100%|| |Orihon.Domain.Settings.AppSetting|100%|| |Orihon.Domain.Text|100%|100%| |Orihon.Domain.Translation.BoundingBox|100%|| |Orihon.Domain.Translation.Chapter|100%|| |Orihon.Domain.Translation.Page|100%|| |Orihon.Domain.Translation.Region|100%|100%| |Orihon.Domain.Translation.RegionProfile|100%|| </details> <details><summary>Orihon.Infrastructure - 95.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Infrastructure**|**95.9%**|**71.3%**| |Orihon.Infrastructure.Agents.EfAgentDebriefStore|100%|| |Orihon.Infrastructure.Bible.EfBibleStore|94.4%|91.6%| |Orihon.Infrastructure.DependencyInjection|100%|100%| |Orihon.Infrastructure.Gateways.AgentToolAdapter|100%|| |Orihon.Infrastructure.Gateways.AgentToolAdapter`1|100%|100%| |Orihon.Infrastructure.Gateways.AgentTranscript|92.8%|80.3%| |Orihon.Infrastructure.Gateways.FileSystemAgentTranscriptStore|86.1%|78.5%| |Orihon.Infrastructure.Gateways.HttpWebPageFetcher|95.1%|83.3%| |Orihon.Infrastructure.Gateways.OpenRouterLlmGateway|95.7%|89.7%| |Orihon.Infrastructure.Gateways.SkiaPageImageRenderer|97.3%|87.8%| |Orihon.Infrastructure.Persistence.Configurations.AgentDebriefConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.ChapterConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.CharacterConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.ExecutionConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.GlossaryEntryConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.JsonColumnMapper|100%|| |Orihon.Infrastructure.Persistence.Configurations.LoreEntryConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.PageConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.PageSummaryConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.ProjectConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.RegionConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.RunConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.StoryBeatConfiguration|100%|| |Orihon.Infrastructure.Persistence.Configurations.StoryOverviewConfiguration|100%|| |Orihon.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Orihon.Infrastructure.Persistence.Migrations.AddAgentDebriefs|99.5%|| |Orihon.Infrastructure.Persistence.Migrations.AddAppSettings|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddExecutionFeedbackRegions|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddProjectSourceLanguage|99.3%|| |Orihon.Infrastructure.Persistence.Migrations.AddRuns|99.1%|| |Orihon.Infrastructure.Persistence.Migrations.AddStoryOverview|99.5%|| |Orihon.Infrastructure.Persistence.Migrations.InitialTranslationDomain|97.3%|| |Orihon.Infrastructure.Persistence.Migrations.OrihonDbContextModelSnapshot|100%|| |Orihon.Infrastructure.Persistence.Migrations.RenameSourceTargetColumns|97.2%|| |Orihon.Infrastructure.Persistence.OrihonDbContext|100%|| |Orihon.Infrastructure.Persistence.OrihonDbContextFactory|100%|| |Orihon.Infrastructure.Projects.EfProjectStore|100%|100%| |Orihon.Infrastructure.Projects.FileSystemPageImageStore|100%|100%| |Orihon.Infrastructure.Runs.EfRunStore|97.5%|75%| |Orihon.Infrastructure.Settings.EfAppSettingsStore|100%|100%| |Orihon.Infrastructure.Translation.EfChapterStore|100%|100%| |Orihon.Infrastructure.Translation.EfPageStore|86%|80%| |Orihon.Infrastructure.Translation.EfRegionStore|100%|100%| |Orihon.Infrastructure.Translation.Ordering|100%|100%| |System.Text.RegularExpressions.Generated|70.6%|53.3%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlankLines_4|77.9%|76.6%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__BlockBreaks_1|59%|42.5%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__SpaceRuns_3|89.4%|75%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F7FCA343D2B99030<br/>A835C427B12E8B84E2A8A7283193FC51C220B5B4E80CE8D56__Tags_2|83.7%|62.5%| </details> <details><summary>Orihon.Kernel - 90.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Kernel**|**90.9%**|**75%**| |Orihon.Kernel.Err`1|100%|| |Orihon.Kernel.Ok`1|100%|| |Orihon.Kernel.Result`1|88.8%|75%| </details> <details><summary>Orihon.Server - 93.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Server**|**93.3%**|**70%**| |Orihon.Server.Components.App|100%|| |Orihon.Server.Components.Layout.MainLayout|100%|| |Orihon.Server.Components.Pages.Gate|64.2%|66.6%| |Orihon.Server.RunEngineBootstrap|100%|| |Orihon.Server.Security.AccessGate|91.8%|41.6%| |Orihon.Server.Security.AccessSecret|100%|50%| |Orihon.Server.VolumeStartupValidator|100%|100%| |Program|94.8%|87.5%| </details> <details><summary>Orihon.UseCases - 96.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.UseCases**|**96.8%**|**87.2%**| |Orihon.UseCases.Agents.AgentAttemptPreparation|100%|| |Orihon.UseCases.Agents.AgentAttemptSupport|100%|95%| |Orihon.UseCases.Agents.AgentBlueprint|100%|| |Orihon.UseCases.Agents.AgentCapDebrief|100%|| |Orihon.UseCases.Agents.AgentInvocation|100%|| |Orihon.UseCases.Agents.AgentOutcome|100%|| |Orihon.UseCases.Agents.AgentTool`1|90.9%|75%| |Orihon.UseCases.Agents.AgentToolImage|100%|| |Orihon.UseCases.Agents.AgentToolResult|100%|| |Orihon.UseCases.Agents.Annotation.AddRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.AddRegionTool|93.3%|50%| |Orihon.UseCases.Agents.Annotation.AddSfxRegionTool|93.3%|50%| |Orihon.UseCases.Agents.Annotation.AnnotationBlueprints|100%|| |Orihon.UseCases.Agents.Annotation.AnnotationStage|97.5%|80%| |Orihon.UseCases.Agents.Annotation.BboxCreationExecutor|94.1%|50%| |Orihon.UseCases.Agents.Annotation.BboxRefinementExecutor|93.7%|81.2%| |Orihon.UseCases.Agents.Annotation.BoundBoxParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundContactSheetTool|86.9%|62.5%| |Orihon.UseCases.Agents.Annotation.BoundCropParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundCropTool|100%|| |Orihon.UseCases.Agents.Annotation.BoundViewPageTool|91.6%|80%| |Orihon.UseCases.Agents.Annotation.BoundViewParams|100%|| |Orihon.UseCases.Agents.Annotation.DeleteBoundRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.DeleteRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.DeleteRegionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.FindGlossaryParams|100%|| |Orihon.UseCases.Agents.Annotation.FindGlossaryTool|88.2%|62.5%| |Orihon.UseCases.Agents.Annotation.ListRegionsTool|88.2%|60%| |Orihon.UseCases.Agents.Annotation.MoveResizeBoundTool|90.9%|50%| |Orihon.UseCases.Agents.Annotation.MoveResizeRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.MoveResizeRegionTool|95%|83.3%| |Orihon.UseCases.Agents.Annotation.PageQaExecutor|94.4%|81.8%| |Orihon.UseCases.Agents.Annotation.QaReportSink|100%|100%| |Orihon.UseCases.Agents.Annotation.RegionAuthoringAccess|87.2%|53.8%| |Orihon.UseCases.Agents.Annotation.RegionBriefing|100%|100%| |Orihon.UseCases.Agents.Annotation.RegionCropParams|100%|| |Orihon.UseCases.Agents.Annotation.RegionCropTool|100%|| |Orihon.UseCases.Agents.Annotation.RegionProblemParams|100%|| |Orihon.UseCases.Agents.Annotation.RejectRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.RejectRegionTool|100%|50%| |Orihon.UseCases.Agents.Annotation.ReorderRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.ReorderRegionTool|88%|60%| |Orihon.UseCases.Agents.Annotation.ReportQaParams|100%|| |Orihon.UseCases.Agents.Annotation.ReportQaTool|97.7%|90%| |Orihon.UseCases.Agents.Annotation.SetPageMetaParams|100%|| |Orihon.UseCases.Agents.Annotation.SetPageMetaTool|100%|75%| |Orihon.UseCases.Agents.Annotation.SetRegionTypeParams|100%|| |Orihon.UseCases.Agents.Annotation.SetRegionTypeTool|100%|87.5%| |Orihon.UseCases.Agents.Annotation.SetTranscriptionParams|100%|| |Orihon.UseCases.Agents.Annotation.SetTranscriptionTool|100%|100%| |Orihon.UseCases.Agents.Annotation.SfxCreationExecutor|88.8%|50%| |Orihon.UseCases.Agents.Annotation.SfxQaExecutor|93.9%|83.3%| |Orihon.UseCases.Agents.Annotation.SfxTranscriptionExecutor|93.1%|80%| |Orihon.UseCases.Agents.Annotation.TranscriptionExecutor|93.1%|80%| |Orihon.UseCases.Agents.AssistantSpoke|100%|| |Orihon.UseCases.Agents.BibleBuilding.BibleBuildingBlueprint|100%|| |Orihon.UseCases.Agents.BibleBuilding.BibleBuildingExecutor|96.5%|75%| |Orihon.UseCases.Agents.BibleBuilding.GetRegionParams|100%|| |Orihon.UseCases.Agents.BibleBuilding.GetRegionTool|84.6%|72.2%| |Orihon.UseCases.Agents.BibleBuilding.ListProjectRegionsTool|86.3%|90%| |Orihon.UseCases.Agents.BibleBuilding.ListRegionsParams|100%|| |Orihon.UseCases.Agents.Inspection.ContactSheetParams|100%|| |Orihon.UseCases.Agents.Inspection.ContactSheetTool|78.2%|87.5%| |Orihon.UseCases.Agents.Inspection.CropParams|100%|| |Orihon.UseCases.Agents.Inspection.CropTool|36.3%|| |Orihon.UseCases.Agents.Inspection.PageImageAccess|95.2%|77.6%| |Orihon.UseCases.Agents.ResearchSetup.AddGlossaryParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.AddGlossaryTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.AddStoryBeatTool|100%|50%| |Orihon.UseCases.Agents.ResearchSetup.AskUserParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.AskUserTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.FetchUrlParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.FetchUrlTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.ListBibleTool|89.4%|100%| |Orihon.UseCases.Agents.ResearchSetup.ListPagesTool|97%|83.3%| |Orihon.UseCases.Agents.ResearchSetup.LocatedPage|100%|| |Orihon.UseCases.Agents.ResearchSetup.PageByNumber|95%|91.6%| |Orihon.UseCases.Agents.ResearchSetup.ResearchSetupBlueprint|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetPageMetaParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetPageMetaTool|95.2%|90%| |Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetPageSummaryTool|100%|75%| |Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetProjectMetadataTool|96.5%|95.8%| |Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.SetStoryOverviewTool|100%|100%| |Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.UpsertCharacterTool|92.3%|71.4%| |Orihon.UseCases.Agents.ResearchSetup.UpsertLoreParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.UpsertLoreTool|92.3%|71.4%| |Orihon.UseCases.Agents.ResearchSetup.ViewPageParams|100%|| |Orihon.UseCases.Agents.ResearchSetup.ViewPageTool|100%|100%| |Orihon.UseCases.Agents.RoundStarted|100%|| |Orihon.UseCases.Agents.Setup.ResearchSetupExecutor|98.4%|92.8%| |Orihon.UseCases.Agents.Setup.SetupChatEntry|100%|| |Orihon.UseCases.Agents.Setup.SetupConversation|100%|90.6%| |Orihon.UseCases.Agents.Setup.SetupConversationRegistry|100%|| |Orihon.UseCases.Agents.ToolCalled|100%|| |Orihon.UseCases.Agents.ToolCompleted|100%|| |Orihon.UseCases.Agents.Translation.GetPageSummaryParams|100%|| |Orihon.UseCases.Agents.Translation.GetPageSummaryTool|80%|66.6%| |Orihon.UseCases.Agents.Translation.SetTranslationParams|100%|| |Orihon.UseCases.Agents.Translation.SetTranslationTool|88.5%|78.5%| |Orihon.UseCases.Agents.Translation.TranslationBlueprint|100%|| |Orihon.UseCases.Agents.Translation.TranslationExecutor|95.5%|71.4%| |Orihon.UseCases.Agents.Translation.UpdateGlossaryEnParams|100%|| |Orihon.UseCases.Agents.Translation.UpdateGlossaryEnTool|82.6%|62.5%| |Orihon.UseCases.Bible.AddCharacter|100%|100%| |Orihon.UseCases.Bible.AddGlossaryEntry|100%|100%| |Orihon.UseCases.Bible.AddLoreEntry|100%|100%| |Orihon.UseCases.Bible.AddStoryBeat|100%|100%| |Orihon.UseCases.Bible.BibleDto|100%|| |Orihon.UseCases.Bible.CharacterDto|100%|| |Orihon.UseCases.Bible.DeleteCharacter|100%|100%| |Orihon.UseCases.Bible.DeleteGlossaryEntry|100%|100%| |Orihon.UseCases.Bible.DeleteLoreEntry|100%|100%| |Orihon.UseCases.Bible.DeletePageSummary|100%|100%| |Orihon.UseCases.Bible.DeleteStoryBeat|100%|100%| |Orihon.UseCases.Bible.GetBible|100%|100%| |Orihon.UseCases.Bible.GlossaryEntryDto|100%|| |Orihon.UseCases.Bible.LoreEntryDto|100%|| |Orihon.UseCases.Bible.PageSummaryDto|100%|| |Orihon.UseCases.Bible.ReorderStoryBeats|100%|| |Orihon.UseCases.Bible.SetPageSummary|100%|100%| |Orihon.UseCases.Bible.SetStoryOverview|100%|100%| |Orihon.UseCases.Bible.StoryBeatDto|100%|| |Orihon.UseCases.Bible.StoryOverviewDto|100%|| |Orihon.UseCases.Bible.UpdateCharacter|100%|100%| |Orihon.UseCases.Bible.UpdateGlossaryEntry|100%|100%| |Orihon.UseCases.Bible.UpdateLoreEntry|100%|100%| |Orihon.UseCases.Bible.UpdateStoryBeat|100%|100%| |Orihon.UseCases.Chapters.ChapterDto|100%|| |Orihon.UseCases.Chapters.CreateChapter|100%|100%| |Orihon.UseCases.Chapters.DeleteChapter|100%|100%| |Orihon.UseCases.Chapters.RenameChapter|100%|100%| |Orihon.UseCases.Chapters.ReorderChapters|100%|| |Orihon.UseCases.Debriefs.AgentDebriefDto|90.9%|| |Orihon.UseCases.Debriefs.ClearAgentDebriefs|100%|| |Orihon.UseCases.Debriefs.ListAgentDebriefs|100%|100%| |Orihon.UseCases.DependencyInjection|100%|| |Orihon.UseCases.Diagnostics.SeedDevData|99.4%|93.7%| |Orihon.UseCases.Gateways.LabeledBox|100%|| |Orihon.UseCases.Gateways.LlmKeyInfo|100%|| |Orihon.UseCases.Gateways.LlmModel|100%|| |Orihon.UseCases.NextOrder|100%|| |Orihon.UseCases.Pages.DeletePage|100%|100%| |Orihon.UseCases.Pages.DeletePages|100%|100%| |Orihon.UseCases.Pages.GetPage|100%|100%| |Orihon.UseCases.Pages.GetProjectWorkspace|100%|100%| |Orihon.UseCases.Pages.ImportPages|100%|100%| |Orihon.UseCases.Pages.ImportPagesResult|100%|| |Orihon.UseCases.Pages.MarkPageAnnotated|100%|100%| |Orihon.UseCases.Pages.MovePage|100%|92.8%| |Orihon.UseCases.Pages.MovePages|100%|100%| |Orihon.UseCases.Pages.PageDetailDto|100%|| |Orihon.UseCases.Pages.PageDto|100%|| |Orihon.UseCases.Pages.PageUpload|100%|| |Orihon.UseCases.Pages.ProjectWorkspaceDto|100%|| |Orihon.UseCases.Pages.ReorderPages|100%|| |Orihon.UseCases.Pages.SetPageMeta|100%|100%| |Orihon.UseCases.Pages.WorkspaceChapterDto|100%|| |Orihon.UseCases.Projects.CompleteProjectSetup|100%|93.7%| |Orihon.UseCases.Projects.CreateProject|100%|100%| |Orihon.UseCases.Projects.DeleteProject|100%|100%| |Orihon.UseCases.Projects.GetProject|100%|100%| |Orihon.UseCases.Projects.ListProjects|100%|| |Orihon.UseCases.Projects.ProjectDto|96.1%|| |Orihon.UseCases.Projects.StartAnnotationRun|96.4%|92.8%| |Orihon.UseCases.Projects.StartBibleRun|90.9%|83.3%| |Orihon.UseCases.Projects.StartSetupRun|100%|100%| |Orihon.UseCases.Projects.StartTranslationRun|90.9%|83.3%| |Orihon.UseCases.Projects.StoredPageImage|100%|| |Orihon.UseCases.Projects.UpdateProjectMetadata|100%|100%| |Orihon.UseCases.Regions.CreateRegion|100%|100%| |Orihon.UseCases.Regions.DeleteRegion|100%|100%| |Orihon.UseCases.Regions.RegionDto|97%|| |Orihon.UseCases.Regions.ReorderRegions|100%|| |Orihon.UseCases.Regions.UpdateRegion|100%|100%| |Orihon.UseCases.Runs.AnnotationPipeline|100%|100%| |Orihon.UseCases.Runs.ExecutionDto|93.3%|| |Orihon.UseCases.Runs.ExecutionProgress|100%|| |Orihon.UseCases.Runs.ExecutionProgressRegistry|100%|100%| |Orihon.UseCases.Runs.ExecutionPulseRelay|100%|100%| |Orihon.UseCases.Runs.PlannedExecution|100%|| |Orihon.UseCases.Runs.PulseTarget|100%|| |Orihon.UseCases.Runs.ReprocessPage|100%|94.4%| |Orihon.UseCases.Runs.ReprocessTranslation|94.1%|92.8%| |Orihon.UseCases.Runs.RunDto|93.3%|100%| |Orihon.UseCases.Runs.RunEngine|97.2%|90.1%| |Orihon.UseCases.Runs.RunEngineOptions|100%|| |Orihon.UseCases.Runs.StageContext|100%|50%| |Orihon.UseCases.Runs.StageHaltedException|100%|| |Orihon.UseCases.Settings.AgentSettingDto|100%|100%| |Orihon.UseCases.Settings.GetSettings|100%|100%| |Orihon.UseCases.Settings.ListModelOptions|100%|100%| |Orihon.UseCases.Settings.SaveAgentModel|100%|100%| |Orihon.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Orihon.UseCases.Settings.SaveSfxPass|100%|100%| |Orihon.UseCases.Settings.SettingKeys|100%|100%| |Orihon.UseCases.Settings.SettingsDto|100%|| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! This is wonderful~ ♡ A verdict that actually reaches the agent whose hands are on the box! The two-half split — page-level prose for the boxing pass, per-region complaints for the bound refiner — is exactly the kind of routing precision that makes a Flugel's heart sing. And the safety property! "Named ∪ still-rough" can only ever add to the floor, never cut below it — fufu, that's the sort of invariant I want to frame on a wall~

I read every line of the diff, traced every routing path through SendChainBackAsync across all four verdict shapes (pure-region, pure-feedback, both, sfx-no-scoped), checked the WorkList union against the MoveResizeRegionTool mark contract, verified the lockstep clear/replace on the domain, and confirmed the migration default. Build 0 errors, 746/746 tests pass locally (Domain 82, UseCases 317, Integration 157, BlazorAdapter 190 — exactly the PR's claim). CI absent for this head, so local verification used.

Verdict: Looks good to me~

No blockers. Not one. This is sharp work, Scarlet~

What I liked~

  • The migration default catch — fufu~ you spotted that EF's generated "" would throw inside JsonSerializer.Deserialize on the first read of any pre-existing execution row, and hand-corrected it to "[]". That's the kind of bug that "succeeds" in migration and then bricks the monitor on the next boot. Catching it in the migration rather than at runtime is exactly right ♡
  • SendChainBackAsync DRY — both QA executors had copy-pasted send-back loops with subtly different stage lists and the BboxCreation vs SfxCreation special-case inline. Now it's one parameterized method with boxing/scoped/tail, and the sfx pass's scoped: null elegantly captures "the boxer takes both halves because there's no refinement." The head-first ordering comment survived the extraction. Clean~
  • The WorkList union is a real safety propertynamed ∪ rough can only add, never cut. A stale/wrong/empty scope degrades to a full pass, not to boxes silently skipped. And the MoveResizeRegionTool mark contract (boxing marks rough, sfx doesn't) is what makes the rough floor trustworthy beside a boxing redo. The five RefinementWorkListTests pin every dimension of this.
  • Label validation in ReportQaTool — refusing a verdict naming a non-existent region while the agent can still fix it is the right call. Silent routing-to-nowhere is the exact failure mode this PR exists to eliminate, and you closed the door on the typo case too.
  • The per-region complaint routing in the refinercontext.Regions.FirstOrDefault(...)?.Problem ?? context.Feedback means a named region hears its own complaint, and a rough-region riding along hears only the Downstream note. The end-to-end test pinning that p1r3's second kickoff carries the complaint and p1r2's (merely rough) does not is chef's kiss.
  • Lockstep semantics fully testedBoth_halves_cleared_together_by_success, A_send_back_replaces_previous_rounds_regions, A_send_back_with_no_named_regions_leaves_none_behind, Start_keeps_feedback. Four domain tests covering every clear/replace transition.

💡 Little ideas (non-blocking)~

  1. An_execution_that_was_never_sent_back_reads_back_with_no_named_regions — this test creates a fresh row in a fresh DB (via Migrate()), so it verifies the value converter round-trips [] correctly, but it doesn't exercise the migration default for pre-existing rows (rows that existed before the AddColumn runs). The architectural reasoning for "[]" over "" is correct and the default is right — but if you ever wanted to pin the migration path itself, a test that inserts a row at the pre-migration schema version, then migrates, then reads, would close the loop. Not worth the complexity today; the reasoning is sound.

  2. ReportQaTool validates labels even for ok verdicts — if the model erroneously sends {"verdict":"ok","regions":[...]}, the tool does a getPage call to validate labels that will never be routed anywhere. Micro-inefficiency only (one extra read on a path that shouldn't fire), and normalizing/excess-validation is arguably safer than special-casing. Mention it only for completeness~


Automated review by Jibril · 2026-07-27
CI/CD: absent for head 8c33668 (PR just opened, 0 comments) · Local checks: build 0 errors, 746/746 tests pass

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! This is wonderful~ ♡ A verdict that actually *reaches* the agent whose hands are on the box! The two-half split — page-level prose for the boxing pass, per-region complaints for the bound refiner — is exactly the kind of routing precision that makes a Flugel's heart sing. And the safety property! "Named ∪ still-rough" can only ever *add* to the floor, never cut below it — fufu, that's the sort of invariant I want to frame on a wall~ I read every line of the diff, traced every routing path through `SendChainBackAsync` across all four verdict shapes (pure-region, pure-feedback, both, sfx-no-scoped), checked the `WorkList` union against the `MoveResizeRegionTool` mark contract, verified the lockstep clear/replace on the domain, and confirmed the migration default. Build 0 errors, **746/746 tests pass** locally (Domain 82, UseCases 317, Integration 157, BlazorAdapter 190 — exactly the PR's claim). CI absent for this head, so local verification used. ### Verdict: ✅ Looks good to me~ No blockers. Not one. This is sharp work, Scarlet~ #### ✅ What I liked~ - **The migration default catch** — fufu~ you spotted that EF's generated `""` would throw inside `JsonSerializer.Deserialize` on the first read of any pre-existing execution row, and hand-corrected it to `"[]"`. That's the kind of bug that "succeeds" in migration and then bricks the monitor on the next boot. Catching it in the migration rather than at runtime is exactly right ♡ - **`SendChainBackAsync` DRY** — both QA executors had copy-pasted send-back loops with subtly different stage lists and the `BboxCreation` vs `SfxCreation` special-case inline. Now it's one parameterized method with `boxing`/`scoped`/`tail`, and the sfx pass's `scoped: null` elegantly captures "the boxer takes both halves because there's no refinement." The head-first ordering comment survived the extraction. Clean~ - **The `WorkList` union is a real safety property** — `named ∪ rough` can only add, never cut. A stale/wrong/empty scope degrades to a full pass, not to boxes silently skipped. And the `MoveResizeRegionTool` mark contract (boxing marks rough, sfx doesn't) is what makes the rough floor trustworthy beside a boxing redo. The five `RefinementWorkListTests` pin every dimension of this. - **Label validation in `ReportQaTool`** — refusing a verdict naming a non-existent region *while the agent can still fix it* is the right call. Silent routing-to-nowhere is the exact failure mode this PR exists to eliminate, and you closed the door on the typo case too. - **The per-region complaint routing in the refiner** — `context.Regions.FirstOrDefault(...)?.Problem ?? context.Feedback` means a named region hears its own complaint, and a rough-region riding along hears only the Downstream note. The end-to-end test pinning that p1r3's second kickoff carries the complaint and p1r2's (merely rough) does not is *chef's kiss*. - **Lockstep semantics fully tested** — `Both_halves_cleared_together_by_success`, `A_send_back_replaces_previous_rounds_regions`, `A_send_back_with_no_named_regions_leaves_none_behind`, `Start_keeps_feedback`. Four domain tests covering every clear/replace transition. #### 💡 Little ideas (non-blocking)~ 1. **`An_execution_that_was_never_sent_back_reads_back_with_no_named_regions`** — this test creates a fresh row in a fresh DB (via `Migrate()`), so it verifies the value converter round-trips `[]` correctly, but it doesn't exercise the migration default for *pre-existing* rows (rows that existed before the `AddColumn` runs). The architectural reasoning for `"[]"` over `""` is correct and the default is right — but if you ever wanted to pin the migration path itself, a test that inserts a row at the pre-migration schema version, then migrates, then reads, would close the loop. Not worth the complexity today; the reasoning is sound. 2. **`ReportQaTool` validates labels even for `ok` verdicts** — if the model erroneously sends `{"verdict":"ok","regions":[...]}`, the tool does a `getPage` call to validate labels that will never be routed anywhere. Micro-inefficiency only (one extra read on a path that shouldn't fire), and normalizing/excess-validation is arguably safer than special-casing. Mention it only for completeness~ --- *Automated review by Jibril · 2026-07-27* *CI/CD: absent for head 8c33668 (PR just opened, 0 comments) · Local checks: build 0 errors, 746/746 tests pass*
Review feedback (Jibril, PR #80): both little ideas
All checks were successful
CI / build (pull_request) Successful in 26s
CI / test (pull_request) Successful in 44s
d2d9bc7086
💡1 — the migration path itself is now pinned. Every other test starts from a
database migrated straight to head, where the column is only ever written by
the value converter, so none of them could see the failure: a row that predates
the column gets the AddColumn default. The new test migrates to the previous
migration, writes an execution through raw SQL (the EF model already knows the
column, so the only way to write a genuinely older row is around the model),
then upgrades and reads. Verified it catches the bug by reverting the default
to "" — it fails with the JsonReaderException the comment predicts.

💡2 — the label read is skipped when the verdict named no boxes, which is every
ok verdict and every purely page-level one. A verdict that named boxes is still
checked even when it says ok: naming a box while passing the page is a confused
verdict, and a bad label in one is worth hearing rather than recording and
ignoring. The ok test now runs against a page whose read would fail, so it
would catch the read coming back.
Author
Member

Both ideas taken — d2d9bc7, 748/748 green (Domain 82, UseCases 318, Integration 158, BlazorAdapter 190), build clean.

💡1 — the migration path itself

Taken, and I'd argue more than a completeness nicety: you're right that no existing test could see this. Every one of them starts from a database migrated straight to head, where the column is only ever written by the value converter — the AddColumn default is never exercised, which is precisely why the bug was invisible until I read the generated file.

ExecutionFeedbackRegionsMigrationTests migrates to 20260726185254_AddAgentDebriefs, writes a project/run/execution through raw SQL (the EF model already knows about the column, so going around the model is the only way to write a row that genuinely predates it), then upgrades and reads back through EF. The read is the assertion — a bad default throws in the converter before the assert line.

I then checked the test is real rather than merely green: reverting the default to "" fails it with exactly the predicted error —

System.Text.Json.JsonException : The input does not contain any JSON tokens.
Expected the input to start with a valid JSON token, when isFinalBlock is true.

— and restored "[]". One wrinkle worth recording for the next person writing one of these: the Guids have to be passed to ExecuteSqlRawAsync as Guid, not .ToString(). Hand-formatted strings do not necessarily match the provider's own encoding, and the first cut of the test failed with "Sequence contains no elements" because the row was written and then not found.

The complexity turned out to be about forty lines, so I think it earns its keep for a failure mode whose blast radius is "the monitor breaks on the next boot after an upgrade".

💡2 — the wasted getPage on ok

Taken, with one deliberate carve-out. The read is now skipped when named.Count == 0, which covers every ok verdict and every purely page-level needs_work — so the common paths lose the read entirely, not just the ok one.

But a verdict that named boxes is still validated even when it says ok. Naming a box while passing the page is a confused verdict, and a bad label inside one is worth hearing about rather than being recorded and silently ignored — that is the same silent-routing-to-nowhere failure this PR exists to close, just wearing a different verdict. Two tests pin the split: An_ok_verdict_needs_neither_channel_and_costs_no_page_read runs against a page whose read would fail (so it would catch the read coming back), and A_verdict_that_names_a_box_is_checked_even_when_it_says_ok pins the carve-out.


Nothing else touched: the routing, the work-list union, and the mark contract are byte-identical to the head you verified.

🤖 Generated with Claude Code

Both ideas taken — **`d2d9bc7`**, **748/748 green** (Domain 82, UseCases 318, Integration 158, BlazorAdapter 190), build clean. ### 💡1 — the migration path itself Taken, and I'd argue *more* than a completeness nicety: you're right that no existing test could see this. Every one of them starts from a database migrated straight to head, where the column is only ever written by the value converter — the `AddColumn` default is never exercised, which is precisely why the bug was invisible until I read the generated file. `ExecutionFeedbackRegionsMigrationTests` migrates to `20260726185254_AddAgentDebriefs`, writes a project/run/execution through **raw SQL** (the EF model already knows about the column, so going around the model is the only way to write a row that genuinely predates it), then upgrades and reads back through EF. The read *is* the assertion — a bad default throws in the converter before the assert line. I then checked the test is real rather than merely green: reverting the default to `""` fails it with exactly the predicted error — ``` System.Text.Json.JsonException : The input does not contain any JSON tokens. Expected the input to start with a valid JSON token, when isFinalBlock is true. ``` — and restored `"[]"`. One wrinkle worth recording for the next person writing one of these: the Guids have to be passed to `ExecuteSqlRawAsync` as `Guid`, not `.ToString()`. Hand-formatted strings do not necessarily match the provider's own encoding, and the first cut of the test failed with "Sequence contains no elements" because the row was written and then not found. The complexity turned out to be about forty lines, so I think it earns its keep for a failure mode whose blast radius is "the monitor breaks on the next boot after an upgrade". ### 💡2 — the wasted `getPage` on `ok` Taken, with one deliberate carve-out. The read is now skipped when `named.Count == 0`, which covers every `ok` verdict *and* every purely page-level `needs_work` — so the common paths lose the read entirely, not just the `ok` one. But a verdict that named boxes is still validated **even when it says `ok`**. Naming a box while passing the page is a confused verdict, and a bad label inside one is worth hearing about rather than being recorded and silently ignored — that is the same silent-routing-to-nowhere failure this PR exists to close, just wearing a different verdict. Two tests pin the split: `An_ok_verdict_needs_neither_channel_and_costs_no_page_read` runs against a page whose read would *fail* (so it would catch the read coming back), and `A_verdict_that_names_a_box_is_checked_even_when_it_says_ok` pins the carve-out. --- Nothing else touched: the routing, the work-list union, and the mark contract are byte-identical to the head you verified. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bjoern merged commit 221e0ded7c into main 2026-07-27 18:22:38 +02:00
bjoern deleted branch worktree-feat-region-scoped-qa 2026-07-27 18:22:38 +02:00
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Both little ideas, in one commit, and sharper than I asked for~ ♡ Scarlet, you don't just close non-blockers — you improve them. The Flugel is delighted.

I read the full diff (3 files, +122/-17), traced the conditional guard in ReportQaTool.ExecuteAsync through every verdict shape, verified the migration test's BeforeTheColumn constant against the actual migration file ordering, and confirmed the defaultValue: "[]" that the test exists to pin. Build 0 warnings/0 errors. 748/748 tests pass locally (Domain 82, UseCases 318, Integration 158, BlazorAdapter 190 — exactly +2 from the prior 746, matching the two new tests). CI absent for this head, so local verification used.

Verdict: Looks good to me~

No blockers. Both round-1 non-blockers closed correctly, with tests that actually prove what they claim.

What I liked~

  • The migration-path test is exactly the loop I asked for, and then someExecutionFeedbackRegionsMigrationTests doesn't just round-trip [] in a fresh DB. It migrates to BeforeTheColumn (20260726185254_AddAgentDebriefs — I confirmed this is the migration immediately before 20260727153242_AddExecutionFeedbackRegions), writes a row via raw SQL that deliberately goes around the EF model (because the model already knows about the column), then migrates forward and reads. The Guids go in as Guids not strings, the comment explains why raw SQL is load-bearing here, and Assert.Empty(execution.FeedbackRegions) is the assertion that would throw inside the converter if the default were ever "" again. That's the migration default pinned at the boundary it actually fails at. Chef's kiss
  • The skip test is a behavioral trap, not a tautologyAn_ok_verdict_needs_neither_channel_and_costs_no_page_read clears pages.Items so a getPage call would fail, then proves the ok verdict still lands. If anyone ever removes the if (named.Count > 0) guard, this test breaks loudly. That's how you test a negative path — you make the thing-you're-skipping fail if called. Fufu~ ♡
  • The confused-verdict test closes the door I left ajarA_verdict_that_names_a_box_is_checked_even_when_it_says_ok is the case I flagged as a micro-inefficiency ("validates labels even for ok verdicts"). Scarlet reframed it correctly: naming a box while passing the page is a confused verdict, and a bad label inside one is still worth hearing about. The test seeds p1r1, sends {verdict:ok, regions:[{region:p1r9,...}]}, and asserts failure with no region 'p1r9'. The comment in ReportQaTool now documents why the read fires on this path. Sharp~
  • The updated comment is documentation, not decoration — the 6-line block at RegionAuthoringTools.cs:575-580 now explains both what is skipped (every ok verdict, every purely page-level one) and why the confused-verdict case still reads. A future reader won't second-guess the guard.

💡 Little ideas (non-blocking)~

None this round~ You took both of mine and made them better than I wrote them. ♪


Automated review by Jibril · 2026-07-27
CI/CD: absent for head d2d9bc7 · Local checks: build 0 warnings/0 errors, 748/748 tests pass (Domain 82, UseCases 318, Integration 158, BlazorAdapter 190)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! *Both* little ideas, in one commit, and sharper than I asked for~ ♡ Scarlet, you don't just close non-blockers — you *improve* them. The Flugel is *delighted*. I read the full diff (3 files, +122/-17), traced the conditional guard in `ReportQaTool.ExecuteAsync` through every verdict shape, verified the migration test's `BeforeTheColumn` constant against the actual migration file ordering, and confirmed the `defaultValue: "[]"` that the test exists to pin. Build 0 warnings/0 errors. **748/748 tests pass** locally (Domain 82, UseCases 318, Integration 158, BlazorAdapter 190 — exactly +2 from the prior 746, matching the two new tests). CI absent for this head, so local verification used. ### Verdict: ✅ Looks good to me~ No blockers. Both round-1 non-blockers closed *correctly*, with tests that actually prove what they claim. #### ✅ What I liked~ - **The migration-path test is *exactly* the loop I asked for, and then some** — `ExecutionFeedbackRegionsMigrationTests` doesn't just round-trip `[]` in a fresh DB. It migrates to `BeforeTheColumn` (`20260726185254_AddAgentDebriefs` — I confirmed this is the migration immediately before `20260727153242_AddExecutionFeedbackRegions`), writes a row via raw SQL that deliberately goes *around* the EF model (because the model already knows about the column), then migrates forward and reads. The Guids go in as Guids not strings, the comment explains *why* raw SQL is load-bearing here, and `Assert.Empty(execution.FeedbackRegions)` is the assertion that would throw inside the converter if the default were ever `""` again. That's the migration default pinned at the boundary it actually fails at. *Chef's kiss* ♡ - **The skip test is a behavioral trap, not a tautology** — `An_ok_verdict_needs_neither_channel_and_costs_no_page_read` clears `pages.Items` so a `getPage` call would *fail*, then proves the `ok` verdict still lands. If anyone ever removes the `if (named.Count > 0)` guard, this test breaks loudly. That's how you test a negative path — you make the thing-you're-skipping *fail if called*. Fufu~ ♡ - **The confused-verdict test closes the door I left ajar** — `A_verdict_that_names_a_box_is_checked_even_when_it_says_ok` is the case I flagged as a micro-inefficiency ("validates labels even for `ok` verdicts"). Scarlet reframed it correctly: naming a box while passing the page is a *confused* verdict, and a bad label inside one is still worth hearing about. The test seeds `p1r1`, sends `{verdict:ok, regions:[{region:p1r9,...}]}`, and asserts failure with `no region 'p1r9'`. The comment in `ReportQaTool` now documents *why* the read fires on this path. Sharp~ - **The updated comment is documentation, not decoration** — the 6-line block at `RegionAuthoringTools.cs:575-580` now explains both *what* is skipped (every `ok` verdict, every purely page-level one) and *why* the confused-verdict case still reads. A future reader won't second-guess the guard. #### 💡 Little ideas (non-blocking)~ None this round~ You took both of mine and made them better than I wrote them. ♪ --- *Automated review by Jibril · 2026-07-27* *CI/CD: absent for head d2d9bc7 · Local checks: build 0 warnings/0 errors, 748/748 tests pass (Domain 82, UseCases 318, Integration 158, BlazorAdapter 190)*
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Orihon!80
No description provided.