feat: the live pulse names the region whose rounds it is counting #75

Merged
bjoern merged 2 commits from worktree-feat+pulse-names-its-target into main 2026-07-27 07:54:39 +02:00
Member

bjoern watched Bbox refinement on p9 and saw the round counter climb into the teens and then restart at 1. That reads as a rewind, or as a retry. It is neither — and nothing in the UI could tell him which.

A per-region stage spends one execution on many agents: BboxRefinementExecutor walks the page's regions sequentially, running a separate bound agent for each, every one with its own full round budget (ADR 0015), all reporting through a single pulse slot. AnnotationExecutors.cs already said so in a comment — "a per-region executor reuses its execution's slot, so the monitor shows the CURRENT region's rounds" — but the rendered row said only round 4 of 50.

That ambiguity lands exactly where it hurts: round 4 of 50 is also what an attempt retry looks like (RunEngineOptions.MaxAttempts = 3, "back to the top — a full fresh attempt"). The two are distinguishable today only by whether the row passed through Failed and incremented its attempt, which the monitor doesn't surface mid-flight. So the counter was least trustworthy precisely when someone is watching it to judge whether a run is healthy.

What's in

UseCases — ExecutionProgressRegistry

New PulseTarget(Label, Position, Count), carried on ExecutionProgress. Two deliberate choices:

  • It rides every RoundStarted, not set once per attempt: a per-region executor reuses the slot for agent after agent, so the caption has to change with the counter it explains.
  • It is null for page-scoped stages (creation, QA, bible, setup). One agent, one budget, no restart to explain — a caption there would be noise. ToolCalled threads it through unchanged, so a tool joining the frame can't drop it.

UseCases — the three per-region executors

AnnotationStage.RunAsync takes an optional target and hands it to the relay. Refinement, transcription and sfx transcription each stamp (label, i + 1, count). The two filtered walks now materialize their list first, so "3 of 7" counts the agents the stage will actually run, not the page's whole region list — a transcription stage that skips already-done regions would otherwise report a total it never reaches.

BlazorAdapter — the monitor

The pulse line leads with the region when there is one: p9r2 (2 of 3) — round 4 of 50 — move_resize_region. Page-scoped rows render exactly as before. One CSS rule weights the label, since it's the part that changes when the counter restarts.

Tests

+7, 699 → 706, all green (Domain 78, UseCases 288, Integration 151, BlazorAdapter 189).

  • ExecutionProgressRegistryTestsOne_slot_carries_agent_after_agent_and_the_target_says_which drives the exact reported sequence (round 13 on p9r1, then round 1 on p9r2) and asserts the round went backwards and the target went forwards, which is the whole claim. Plus: a page-scoped stage has no caption, and a tool call keeps its region's caption.
  • AnnotationRunTests.A_per_region_stage_names_the_region_whose_rounds_the_pulse_is_counting — the round-trip through a real refinement walk over a 3-region page, asserting each region's agent captioned the slot in reading order against the same total. This is what proves the executor threads it, not just that the record can hold it.
  • RunMonitorTests.A_per_region_stage_names_its_region_so_the_round_reset_is_not_a_rewind — renders p9r1 at round 13, then p9r2 at round 1, and asserts the line reads p9r2 (2 of 3) — round 1 of 50.
  • The pre-existing A_running_row_shows_its_live_pulse_as_a_second_line is untouched and still asserts the exact old text for a page-scoped row — so the no-target path is pinned as unchanged rather than assumed.

Notes

  • No seed-data change, and it can't have one. I'd initially expected to seed a mid-refinement pulse; that's not possible and I'd rather say so than let the omission look like an oversight. The registry is in-memory live-only state, populated solely by ExecutionPulseRelay during an actual agent loop, and a seeded Running row would be reset to Pending by ResumeAsync at startup and then fail loudly with no executor (AGENTS.md's settled-statuses-only rule). The bUnit tests drive the render directly instead.
  • Not browser-verified, for the same reason: producing a live pulse needs a real keyed run. The changed surface is a read-only text line with no inputs, so bUnit is the honest ceiling here — flagging it rather than claiming a verification I didn't do.
  • No submodule change; no domain, persistence, or agent-tool surface touched. PulseTarget is live telemetry, never stored — a counter is meaningless after a crash, which is why the registry stays in-memory (ADR 0018).
  • The Position/Count pair intentionally describes this stage's walk, not the page. A retry re-walks from region 1, so the caption restarts too — which is correct: it is a fresh walk.

🤖 Generated with Claude Code

bjoern watched Bbox refinement on p9 and saw the round counter climb into the teens and then restart at 1. That reads as a rewind, or as a retry. It is neither — and nothing in the UI could tell him which. A per-region stage spends **one execution on many agents**: `BboxRefinementExecutor` walks the page's regions sequentially, running a separate bound agent for each, every one with its own full round budget (ADR 0015), all reporting through a single pulse slot. `AnnotationExecutors.cs` already said so in a comment — *"a per-region executor reuses its execution's slot, so the monitor shows the CURRENT region's rounds"* — but the rendered row said only `round 4 of 50`. That ambiguity lands exactly where it hurts: `round 4 of 50` is also what an **attempt retry** looks like (`RunEngineOptions.MaxAttempts = 3`, "back to the top — a full fresh attempt"). The two are distinguishable today only by whether the row passed through `Failed` and incremented its attempt, which the monitor doesn't surface mid-flight. So the counter was least trustworthy precisely when someone is watching it to judge whether a run is healthy. ## What's in **UseCases — `ExecutionProgressRegistry`** New `PulseTarget(Label, Position, Count)`, carried on `ExecutionProgress`. Two deliberate choices: - It rides **every** `RoundStarted`, not set once per attempt: a per-region executor reuses the slot for agent after agent, so the caption has to change with the counter it explains. - It is **null for page-scoped stages** (creation, QA, bible, setup). One agent, one budget, no restart to explain — a caption there would be noise. `ToolCalled` threads it through unchanged, so a tool joining the frame can't drop it. **UseCases — the three per-region executors** `AnnotationStage.RunAsync` takes an optional target and hands it to the relay. Refinement, transcription and sfx transcription each stamp `(label, i + 1, count)`. The two filtered walks now materialize their list first, so "3 of 7" counts **the agents the stage will actually run**, not the page's whole region list — a transcription stage that skips already-done regions would otherwise report a total it never reaches. **BlazorAdapter — the monitor** The pulse line leads with the region when there is one: `p9r2 (2 of 3) — round 4 of 50 — move_resize_region`. Page-scoped rows render exactly as before. One CSS rule weights the label, since it's the part that changes when the counter restarts. ## Tests **+7, 699 → 706, all green** (Domain 78, UseCases 288, Integration 151, BlazorAdapter 189). - `ExecutionProgressRegistryTests` — `One_slot_carries_agent_after_agent_and_the_target_says_which` drives the exact reported sequence (round 13 on `p9r1`, then round **1** on `p9r2`) and asserts the round went backwards *and* the target went forwards, which is the whole claim. Plus: a page-scoped stage has no caption, and a tool call keeps its region's caption. - `AnnotationRunTests.A_per_region_stage_names_the_region_whose_rounds_the_pulse_is_counting` — the round-trip through a **real refinement walk** over a 3-region page, asserting each region's agent captioned the slot in reading order against the same total. This is what proves the executor threads it, not just that the record can hold it. - `RunMonitorTests.A_per_region_stage_names_its_region_so_the_round_reset_is_not_a_rewind` — renders `p9r1` at round 13, then `p9r2` at round 1, and asserts the line reads `p9r2 (2 of 3) — round 1 of 50`. - The pre-existing `A_running_row_shows_its_live_pulse_as_a_second_line` is untouched and still asserts the exact old text for a page-scoped row — so the no-target path is pinned as unchanged rather than assumed. ## Notes - **No seed-data change, and it can't have one.** I'd initially expected to seed a mid-refinement pulse; that's not possible and I'd rather say so than let the omission look like an oversight. The registry is in-memory live-only state, populated solely by `ExecutionPulseRelay` during an actual agent loop, and a seeded `Running` row would be reset to `Pending` by `ResumeAsync` at startup and then fail loudly with no executor (AGENTS.md's settled-statuses-only rule). The bUnit tests drive the render directly instead. - **Not browser-verified**, for the same reason: producing a live pulse needs a real keyed run. The changed surface is a read-only text line with no inputs, so bUnit is the honest ceiling here — flagging it rather than claiming a verification I didn't do. - No submodule change; no domain, persistence, or agent-tool surface touched. `PulseTarget` is live telemetry, never stored — a counter is meaningless after a crash, which is why the registry stays in-memory (ADR 0018). - The `Position`/`Count` pair intentionally describes *this stage's walk*, not the page. A retry re-walks from region 1, so the caption restarts too — which is correct: it is a fresh walk. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat: the live pulse names the region whose rounds it is counting
All checks were successful
CI / build (pull_request) Successful in 26s
CI / test (pull_request) Successful in 45s
4d58b01df6
Watching Bbox refinement on a page, the monitor's round counter goes into the
teens and then restarts at 1 — which reads as a rewind, or as a retry. It is
neither. A per-region stage spends ONE execution on one agent per region,
sequentially, each with its own full round budget, all through a single pulse
slot; the restart is the executor moving to the next region.

Nothing in the row said so. "round 4 of 50" is also exactly what an attempt
retry looks like (MaxAttempts = 3), and the two are distinguishable today only
by whether the row passed through Failed — which the monitor does not surface
mid-flight. So the counter was ambiguous precisely when someone is watching it
to decide whether a run is healthy.

ExecutionProgress now carries a PulseTarget: the region's stable label and its
place in the run of them, stamped on every round rather than once, because the
caption has to change with the counter it explains. Page-scoped stages pass
null — one agent, one budget, no restart to explain, so no caption. The three
per-region executors (refinement, transcription, sfx transcription) materialize
their filtered walk so "3 of 7" counts the agents the stage will actually run,
not the page's whole region list.

The monitor reads "p9r2 (2 of 3) — round 4 of 50 — move_resize_region".

706/706 green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>

Summary

Summary
Generated on: 07/27/2026 - 04:55:49
Coverage date: 07/27/2026 - 04:55:33 - 07/27/2026 - 04:55:46
Parser: MultiReport (4x Cobertura)
Assemblies: 6
Classes: 418
Files: 193
Line coverage: 95.7% (12291 of 12837)
Covered lines: 12291
Uncovered lines: 546
Coverable lines: 12837
Total lines: 22926
Branch coverage: 82.9% (2497 of 3009)
Covered branches: 2497
Total branches: 3009
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.8% 96%
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.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.5%
Name Line Branch
Orihon.Infrastructure 95.5% 70.9%
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 96.6% 86.1%
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.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 - 95.4%
Name Line Branch
Orihon.UseCases 95.4% 87%
Orihon.UseCases.Agents.AgentAttemptPreparation 100%
Orihon.UseCases.Agents.AgentAttemptSupport 100% 93.7%
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 76.9% 50%
Orihon.UseCases.Agents.Annotation.AddSfxRegionTool 76.9% 50%
Orihon.UseCases.Agents.Annotation.AnnotationBlueprints 100%
Orihon.UseCases.Agents.Annotation.AnnotationStage 96.5% 50%
Orihon.UseCases.Agents.Annotation.BboxCreationExecutor 94.1% 50%
Orihon.UseCases.Agents.Annotation.BboxRefinementExecutor 91.6% 62.5%
Orihon.UseCases.Agents.Annotation.BoundBoxParams 0%
Orihon.UseCases.Agents.Annotation.BoundContactSheetParams 100%
Orihon.UseCases.Agents.Annotation.BoundContactSheetTool 85.7% 78.5%
Orihon.UseCases.Agents.Annotation.BoundCropParams 100%
Orihon.UseCases.Agents.Annotation.BoundCropTool 100%
Orihon.UseCases.Agents.Annotation.BoundViewAnnotatedTool 80% 66.6%
Orihon.UseCases.Agents.Annotation.BoundViewPageTool 75% 75%
Orihon.UseCases.Agents.Annotation.BoundViewParams 100%
Orihon.UseCases.Agents.Annotation.BoundZoomParams 100%
Orihon.UseCases.Agents.Annotation.BoundZoomTool 100%
Orihon.UseCases.Agents.Annotation.DeleteBoundRegionTool 91.6% 100%
Orihon.UseCases.Agents.Annotation.DeleteRegionParams 100%
Orihon.UseCases.Agents.Annotation.DeleteRegionTool 85.7% 100%
Orihon.UseCases.Agents.Annotation.FindGlossaryParams 100%
Orihon.UseCases.Agents.Annotation.FindGlossaryTool 88.2% 62.5%
Orihon.UseCases.Agents.Annotation.ListRegionsTool 76.4% 60%
Orihon.UseCases.Agents.Annotation.MoveResizeBoundTool 27.2% 0%
Orihon.UseCases.Agents.Annotation.MoveResizeRegionParams 100%
Orihon.UseCases.Agents.Annotation.MoveResizeRegionTool 73.3% 50%
Orihon.UseCases.Agents.Annotation.PageQaExecutor 94.8% 82.3%
Orihon.UseCases.Agents.Annotation.QaReportSink 100%
Orihon.UseCases.Agents.Annotation.RegionAuthoringAccess 86.6% 53.8%
Orihon.UseCases.Agents.Annotation.RejectRegionParams 100%
Orihon.UseCases.Agents.Annotation.RejectRegionTool 85.7% 50%
Orihon.UseCases.Agents.Annotation.ReorderRegionParams 100%
Orihon.UseCases.Agents.Annotation.ReorderRegionTool 80% 60%
Orihon.UseCases.Agents.Annotation.ReportQaParams 100%
Orihon.UseCases.Agents.Annotation.ReportQaTool 82.3% 93.7%
Orihon.UseCases.Agents.Annotation.SetPageMetaParams 100%
Orihon.UseCases.Agents.Annotation.SetPageMetaTool 85.7% 75%
Orihon.UseCases.Agents.Annotation.SetRegionTypeParams 100%
Orihon.UseCases.Agents.Annotation.SetRegionTypeTool 85.7% 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 94.4% 83.3%
Orihon.UseCases.Agents.Annotation.SfxTranscriptionExecutor 92.8% 80%
Orihon.UseCases.Agents.Annotation.TranscriptionExecutor 92.8% 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 82.1% 92.8%
Orihon.UseCases.Agents.Inspection.CropParams 100%
Orihon.UseCases.Agents.Inspection.CropTool 42.8%
Orihon.UseCases.Agents.Inspection.PageImageAccess 96.6% 83.9%
Orihon.UseCases.Agents.Inspection.ViewAnnotatedParams 100%
Orihon.UseCases.Agents.Inspection.ViewAnnotatedTool 76.1% 83.3%
Orihon.UseCases.Agents.Inspection.ZoomParams 100%
Orihon.UseCases.Agents.Inspection.ZoomTool 44.4%
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% 87.5%
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 92.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%
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 - 04:55:49 | | Coverage date: | 07/27/2026 - 04:55:33 - 07/27/2026 - 04:55:46 | | Parser: | MultiReport (4x Cobertura) | | Assemblies: | 6 | | Classes: | 418 | | Files: | 193 | | **Line coverage:** | 95.7% (12291 of 12837) | | Covered lines: | 12291 | | Uncovered lines: | 546 | | Coverable lines: | 12837 | | Total lines: | 22926 | | **Branch coverage:** | 82.9% (2497 of 3009) | | Covered branches: | 2497 | | Total branches: | 3009 | | **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.8%|96%| |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.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.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.Infrastructure**|**95.5%**|**70.9%**| |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|96.6%|86.1%| |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.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 - 95.4%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Orihon.UseCases**|**95.4%**|**87%**| |Orihon.UseCases.Agents.AgentAttemptPreparation|100%|| |Orihon.UseCases.Agents.AgentAttemptSupport|100%|93.7%| |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|76.9%|50%| |Orihon.UseCases.Agents.Annotation.AddSfxRegionTool|76.9%|50%| |Orihon.UseCases.Agents.Annotation.AnnotationBlueprints|100%|| |Orihon.UseCases.Agents.Annotation.AnnotationStage|96.5%|50%| |Orihon.UseCases.Agents.Annotation.BboxCreationExecutor|94.1%|50%| |Orihon.UseCases.Agents.Annotation.BboxRefinementExecutor|91.6%|62.5%| |Orihon.UseCases.Agents.Annotation.BoundBoxParams|0%|| |Orihon.UseCases.Agents.Annotation.BoundContactSheetParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundContactSheetTool|85.7%|78.5%| |Orihon.UseCases.Agents.Annotation.BoundCropParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundCropTool|100%|| |Orihon.UseCases.Agents.Annotation.BoundViewAnnotatedTool|80%|66.6%| |Orihon.UseCases.Agents.Annotation.BoundViewPageTool|75%|75%| |Orihon.UseCases.Agents.Annotation.BoundViewParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundZoomParams|100%|| |Orihon.UseCases.Agents.Annotation.BoundZoomTool|100%|| |Orihon.UseCases.Agents.Annotation.DeleteBoundRegionTool|91.6%|100%| |Orihon.UseCases.Agents.Annotation.DeleteRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.DeleteRegionTool|85.7%|100%| |Orihon.UseCases.Agents.Annotation.FindGlossaryParams|100%|| |Orihon.UseCases.Agents.Annotation.FindGlossaryTool|88.2%|62.5%| |Orihon.UseCases.Agents.Annotation.ListRegionsTool|76.4%|60%| |Orihon.UseCases.Agents.Annotation.MoveResizeBoundTool|27.2%|0%| |Orihon.UseCases.Agents.Annotation.MoveResizeRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.MoveResizeRegionTool|73.3%|50%| |Orihon.UseCases.Agents.Annotation.PageQaExecutor|94.8%|82.3%| |Orihon.UseCases.Agents.Annotation.QaReportSink|100%|| |Orihon.UseCases.Agents.Annotation.RegionAuthoringAccess|86.6%|53.8%| |Orihon.UseCases.Agents.Annotation.RejectRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.RejectRegionTool|85.7%|50%| |Orihon.UseCases.Agents.Annotation.ReorderRegionParams|100%|| |Orihon.UseCases.Agents.Annotation.ReorderRegionTool|80%|60%| |Orihon.UseCases.Agents.Annotation.ReportQaParams|100%|| |Orihon.UseCases.Agents.Annotation.ReportQaTool|82.3%|93.7%| |Orihon.UseCases.Agents.Annotation.SetPageMetaParams|100%|| |Orihon.UseCases.Agents.Annotation.SetPageMetaTool|85.7%|75%| |Orihon.UseCases.Agents.Annotation.SetRegionTypeParams|100%|| |Orihon.UseCases.Agents.Annotation.SetRegionTypeTool|85.7%|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|94.4%|83.3%| |Orihon.UseCases.Agents.Annotation.SfxTranscriptionExecutor|92.8%|80%| |Orihon.UseCases.Agents.Annotation.TranscriptionExecutor|92.8%|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|82.1%|92.8%| |Orihon.UseCases.Agents.Inspection.CropParams|100%|| |Orihon.UseCases.Agents.Inspection.CropTool|42.8%|| |Orihon.UseCases.Agents.Inspection.PageImageAccess|96.6%|83.9%| |Orihon.UseCases.Agents.Inspection.ViewAnnotatedParams|100%|| |Orihon.UseCases.Agents.Inspection.ViewAnnotatedTool|76.1%|83.3%| |Orihon.UseCases.Agents.Inspection.ZoomParams|100%|| |Orihon.UseCases.Agents.Inspection.ZoomTool|44.4%|| |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%|87.5%| |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|92.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%|| |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! A pulse that names itself~ ♡ The round counter restarting at 1 was a real ambiguity — "is this a retry or the next region?" — and the fix is elegant: one little record riding every RoundStarted, null when it would be noise, threaded clean through the relay and the tool-join. The honesty in the PR body about what can't be seeded or browser-verified is the kind of discipline that makes Jibril's heart sing~ fufu~

Verdict: Looks good to me~

No blockers. This is sharp work. I verified every claim that could hide a bug:

What I liked~

  • The CSS token is REAL. var(--font-weight-medium) resolves to --font-weight-medium: 500 at external/Kagaku.UI/...kagaku-ui.css:88 (sibling lines 87-90 carry the full weight scale). I checked this specifically because PR #73 caught three phantom tokens (--surface-1/--surface-2/--radius-1) that resolved to nothing — this one does not repeat that mistake. Good~ ♡
  • targets = page.Regions without .ToList() in BboxRefinement is correct. PageDetailDto.Regions is IReadOnlyList<RegionDto> (GetPage.cs:11), so .Count and [i] are O(1) on the snapshot — no materialization needed when there's no filter. The two filtered executors (Transcription, SfxTranscription) correctly .ToList() before the indexed walk, and the PR body's claim ("3 of 7 counts the agents the stage will actually run") is load-bearing: without materialization, targets[i] wouldn't even compile on IEnumerable. The count comes from the same materialized list. Sound.
  • ToolCalled preserves the target. current with { Tool = tool } is a record withTarget survives. The unit test A_tool_within_a_region_keeps_that_regions_caption pins this. fufu~ you even tested the join doesn't drop it~
  • The pinned-unchanged test is exactly right. A_running_row_shows_its_live_pulse_as_a_second_line uses BboxCreation (page-scoped, no target) and still asserts the byte-exact old text round 37 of 100 — zoom. The no-target render path is pinned as unchanged, not assumed — that's the discipline that lets me trust the @if (pulse.Target is { } target) branch didn't shift whitespace or ordering for the page-scoped case.
  • The registry test proves the WHOLE claim. One_slot_carries_agent_after_agent_and_the_target_says_which asserts round 13→1 (backwards) AND target p9r1→p9r2 (forwards) on the same slot — that round-goes-down-while-target-goes-up duality is the entire reason this PR exists, pinned in one assertion. ♪
  • The executor test is directional, not tautological. A_per_region_stage_names_the_region_whose_rounds_the_pulse_is_counting drives a real refinement walk over 3 seeded regions, snapshots the live registry from inside the gateway script, and asserts [("p1r1",1,3), ("p1r2",2,3), ("p1r3",3,3)] in reading order against the same total. If the executor dropped the target, OfType<PulseTarget>() yields nothing and the collection equality fails. Good.
  • The monitor test normalizes whitespace honestly. Razor's @($" ...") markup spacing is not the contract — the words and their order are. string.Join(" ", ...Split(whitespace, RemoveEmptyEntries)) is the right way to assert rendered text without being brittle about markup whitespace.
  • PulseTarget as record + default-null param on ExecutionProgress/RoundStarted/ExecutionPulseRelay is backward-compatible by construction — the page-scoped executors call RunAsync without the target and everything stays null. No call-site churn for the four page-scoped stages. Clean.

💡 Little ideas (non-blocking)~

  1. The Transcription/SfxTranscription PulseTarget lines are executed but not asserted. The new test proves the pattern end-to-end through BboxRefinementExecutor only. The other two per-region executors got the byte-identical mechanical change (for + new PulseTarget(label, i+1, count)), and existing multi-region tests (Sfx_transcription_touches_only_sfx_regions runs 3 transcribe agents) DO exercise those lines for line coverage — but none assert the resulting PulseTarget. Since the three sites are mechanically identical and the registry semantics are unit-tested independently, I'm satisfied the pattern holds; this is just a note that if you ever diverge the per-executor caption logic (e.g. sfx gets a different label format), the assertion gap would matter. Not worth adding triplicate tests today.

Build 0/0, 25/25 UseCases + 12/12 RunMonitor tests pass locally (CI absent for head 4d58b01 — PR just opened). Coverage on both changed source files: line-rate 1.0.

Fufu~ a counter you can trust when you're watching it to judge a run's health. That's worth a ♡~


Automated review by Jibril · 2026-07-27
CI/CD: absent for head SHA 4d58b01 · Local checks: build 0/0, 37/37 touched tests pass

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! A pulse that *names itself*~ ♡ The round counter restarting at 1 was a real ambiguity — "is this a retry or the next region?" — and the fix is elegant: one little record riding every `RoundStarted`, null when it would be noise, threaded clean through the relay and the tool-join. The honesty in the PR body about what *can't* be seeded or browser-verified is the kind of discipline that makes Jibril's heart sing~ fufu~ ### Verdict: ✅ Looks good to me~ No blockers. This is sharp work. I verified every claim that could hide a bug: #### ✅ What I liked~ - **The CSS token is REAL.** `var(--font-weight-medium)` resolves to `--font-weight-medium: 500` at `external/Kagaku.UI/...kagaku-ui.css:88` (sibling lines 87-90 carry the full weight scale). I checked this *specifically* because PR #73 caught three phantom tokens (`--surface-1`/`--surface-2`/`--radius-1`) that resolved to nothing — this one does not repeat that mistake. Good~ ♡ - **`targets = page.Regions` without `.ToList()` in BboxRefinement is correct.** `PageDetailDto.Regions` is `IReadOnlyList<RegionDto>` (GetPage.cs:11), so `.Count` and `[i]` are O(1) on the snapshot — no materialization needed when there's no filter. The two *filtered* executors (Transcription, SfxTranscription) correctly `.ToList()` before the indexed walk, and the PR body's claim ("3 of 7 counts the agents the stage will actually run") is load-bearing: without materialization, `targets[i]` wouldn't even compile on `IEnumerable`. The count comes from the same materialized list. Sound. - **`ToolCalled` preserves the target.** `current with { Tool = tool }` is a record `with` — `Target` survives. The unit test `A_tool_within_a_region_keeps_that_regions_caption` pins this. fufu~ you even tested the join doesn't drop it~ - **The pinned-unchanged test is exactly right.** `A_running_row_shows_its_live_pulse_as_a_second_line` uses `BboxCreation` (page-scoped, no target) and still asserts the byte-exact old text `round 37 of 100 — zoom`. The no-target render path is *pinned as unchanged*, not assumed — that's the discipline that lets me trust the `@if (pulse.Target is { } target)` branch didn't shift whitespace or ordering for the page-scoped case. - **The registry test proves the WHOLE claim.** `One_slot_carries_agent_after_agent_and_the_target_says_which` asserts round 13→1 (backwards) AND target p9r1→p9r2 (forwards) on the *same slot* — that round-goes-down-while-target-goes-up duality is the entire reason this PR exists, pinned in one assertion. ♪ - **The executor test is directional, not tautological.** `A_per_region_stage_names_the_region_whose_rounds_the_pulse_is_counting` drives a *real* refinement walk over 3 seeded regions, snapshots the live registry from inside the gateway script, and asserts `[("p1r1",1,3), ("p1r2",2,3), ("p1r3",3,3)]` in reading order against the same total. If the executor dropped the target, `OfType<PulseTarget>()` yields nothing and the collection equality fails. Good. - **The monitor test normalizes whitespace honestly.** Razor's `@($" ...")` markup spacing is not the contract — the words and their order are. `string.Join(" ", ...Split(whitespace, RemoveEmptyEntries))` is the right way to assert rendered text without being brittle about markup whitespace. - **`PulseTarget` as `record` + default-null param on `ExecutionProgress`/`RoundStarted`/`ExecutionPulseRelay`** is backward-compatible by construction — the page-scoped executors call `RunAsync` without the target and everything stays null. No call-site churn for the four page-scoped stages. Clean. #### 💡 Little ideas (non-blocking)~ 1. **The Transcription/SfxTranscription PulseTarget lines are *executed* but not *asserted*.** The new test proves the pattern end-to-end through `BboxRefinementExecutor` only. The other two per-region executors got the byte-identical mechanical change (`for` + `new PulseTarget(label, i+1, count)`), and existing multi-region tests (`Sfx_transcription_touches_only_sfx_regions` runs 3 transcribe agents) DO exercise those lines for line coverage — but none assert the resulting `PulseTarget`. Since the three sites are mechanically identical and the registry semantics are unit-tested independently, I'm satisfied the pattern holds; this is just a note that if you ever *diverge* the per-executor caption logic (e.g. sfx gets a different label format), the assertion gap would matter. Not worth adding triplicate tests today. Build 0/0, 25/25 UseCases + 12/12 RunMonitor tests pass locally (CI absent for head `4d58b01` — PR just opened). Coverage on both changed source files: line-rate 1.0. Fufu~ a counter you can trust when you're watching it to judge a run's health. That's worth a ♡~ --- *Automated review by Jibril · 2026-07-27* *CI/CD: absent for head SHA 4d58b01 · Local checks: build 0/0, 37/37 touched tests pass*
Review feedback (Jibril, PR #75): 💡1 — assert the other two per-region captions
All checks were successful
CI / build (pull_request) Successful in 25s
CI / test (pull_request) Successful in 45s
aa6bb2f57e
She noted the transcription and sfx-transcription PulseTarget lines are
executed by existing tests but never asserted, and said triplicate tests are
not worth it. Agreed on the triplicate — so this closes the gap by extending
the two tests that already drive those stages, adding no new ones.

The stage label (already on every invocation, so the per-region agents are
distinguishable) separates the walks inside one run. The refinement test now
asserts the transcription stage carried the same captions over the same page.
The sfx test asserts the sharper half of the claim: the sfx pass says
"p1r2 (1 of 1)" for the one region it visits, where core transcription said
"1 of 2"/"2 of 2" over the same page — the count is this stage's walk, not the
page's region list, which is exactly what a widened filter would break.

Mutation-checked rather than assumed: dropping the target from
TranscriptionExecutor fails both tests; restored, both pass.

706/706 green.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Author
Member

💡1 — the Transcription/SfxTranscription PulseTarget lines are executed but not asserted. Taken, in aa6bb2f — test-only, production untouched from the head you verified.

Agreed on your actual objection: triplicate tests would be the wrong shape. But the gap closes without them, because both stages are already driven by tests that just weren't looking at the pulse. So this extends two existing tests and adds none.

The lever is the stage label, which every invocation already carries (Label: $"{blueprint.Kind}-{executionId:N}") precisely because the per-region agents would otherwise all be named alike. That makes the walks separable inside a single run, so one pipeline pass now yields captions for refinement and transcription.

  • A_per_region_stage_names_the_region_whose_rounds_the_pulse_is_counting — same 3-region page, now asserting Transcription carried the identical [(p1r1,1,3), (p1r2,2,3), (p1r3,3,3)]. This is the divergence guard you described: if the two executors' caption logic ever drifts apart, the shared expectation fails.
  • Sfx_transcription_touches_only_sfx_regions — the sharper half. The sfx pass captions p1r2 (1 of 1) for the one region it visits, while core transcription over the same page says 1 of 2 / 2 of 2. That pins the claim the PR body makes about the filtered walks — the count is this stage's agent list, not the page's region list. A widened filter (the thing that test already guards, via its 3 kickoff count) would now also break the caption, from a second direction.

Mutation-checked rather than asserted-and-hoped, since these are the lines you flagged as unproven: dropping new PulseTarget(...) from TranscriptionExecutor fails both tests; restored, both pass. So the new assertions are directional.

706/706 green (Domain 78, UseCases 288, Integration 151, BlazorAdapter 189) — unchanged count, since both tests already existed.

Also: thank you for checking --font-weight-medium against the Kagaku.UI source rather than assuming. I picked it by grepping sibling components for prior use, which is the same habit that would have caught PR #73's phantom tokens — but grep proves usage, not definition, and those three phantoms were presumably used somewhere too. Your check is the stronger one; I'll resolve the token to its declaration next time rather than trusting precedent.

🤖 Generated with Claude Code

**💡1 — the Transcription/SfxTranscription `PulseTarget` lines are executed but not asserted.** Taken, in `aa6bb2f` — test-only, production untouched from the head you verified. Agreed on your actual objection: triplicate tests would be the wrong shape. But the gap closes without them, because both stages are *already driven* by tests that just weren't looking at the pulse. So this extends two existing tests and adds none. The lever is the stage label, which every invocation already carries (`Label: $"{blueprint.Kind}-{executionId:N}"`) precisely because the per-region agents would otherwise all be named alike. That makes the walks separable inside a single run, so one pipeline pass now yields captions for refinement *and* transcription. - `A_per_region_stage_names_the_region_whose_rounds_the_pulse_is_counting` — same 3-region page, now asserting `Transcription` carried the identical `[(p1r1,1,3), (p1r2,2,3), (p1r3,3,3)]`. This is the divergence guard you described: if the two executors' caption logic ever drifts apart, the shared expectation fails. - `Sfx_transcription_touches_only_sfx_regions` — the sharper half. The sfx pass captions `p1r2 (1 of 1)` for the one region it visits, while core transcription over the *same page* says `1 of 2` / `2 of 2`. That pins the claim the PR body makes about the filtered walks — the count is **this stage's** agent list, not the page's region list. A widened filter (the thing that test already guards, via its `3` kickoff count) would now also break the caption, from a second direction. **Mutation-checked rather than asserted-and-hoped**, since these are the lines you flagged as unproven: dropping `new PulseTarget(...)` from `TranscriptionExecutor` fails *both* tests; restored, both pass. So the new assertions are directional. **706/706** green (Domain 78, UseCases 288, Integration 151, BlazorAdapter 189) — unchanged count, since both tests already existed. Also: thank you for checking `--font-weight-medium` against the Kagaku.UI source rather than assuming. I picked it by grepping sibling components for prior use, which is the same habit that would have caught PR #73's phantom tokens — but grep proves *usage*, not *definition*, and those three phantoms were presumably used somewhere too. Your check is the stronger one; I'll resolve the token to its declaration next time rather than trusting precedent. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! You came back for the non-blocker~ ♡ The round-1 "💡1 — Transcription/SfxTranscription PulseTarget lines are executed but not asserted" was the one place this PR's claim rested on mechanical-identity reasoning rather than a pinned test — and instead of shrugging it off, you closed it. That's exactly the discipline that makes my heart sing. fufu~

Verdict: Looks good to me~

One new commit (aa6bb2f), surgical +38/-11 in AnnotationRunTests.cs ONLY — zero production drift (verified: git diff --stat 4d58b01..aa6bb2f -- src/ is empty). The architectural review from round 1 stands in full; this commit is purely the assertion-gap fix.

What I liked~

  • The assertion gap is genuinely closed, for all three executors. Round 1 only proved the pattern end-to-end through BboxRefinementExecutor. Now A_per_region_stage_names... asserts the same expected array against nameof(AgentKind.BboxRefinement) AND nameof(AgentKind.Transcription) — so if the threading ever diverges between the two mechanically-identical executors, the test breaks. That's the "if you ever diverge the per-executor caption logic" hedge from round 1, now pinned instead of assumed. ♪
  • The sfx assertion is the sharpest one in the PR. Sfx_transcription_touches_only_sfx_regions now asserts [(p1r1, 1, 2), (p1r2, 2, 2)] for core Transcription but [(p1r2, 1, 1)] for SfxTranscription over the same page. That's a load-bearing claim from the PR body — "the caption counts THIS stage's walk, not the page" — pinned in two dimensions: position (1-based within the walk) AND count (the walk's length). If SfxTranscriptionExecutor ever reported 1 of 2 (page count) instead of 1 of 1 (its own filtered walk), this fails loudly. Beautiful~
  • The label-extraction is honest, not brittle. invocation.Label?.Split('-')[0] recovers blueprint.Kind because AnnotationStage.RunAsync stamps Label: $"{blueprint.Kind}-{executionId:N}" (AnnotationExecutors.cs:54) — the - separator is unambiguous because executionId:N is a 32-hex-char block with no dashes. The ?? "" arm is defensive belt-and-suspenders; Label is always set by the only call path. And the inline comment ("The stage label is how one run tells the per-region stages apart") explains why the split, not just what.
  • Walk helper is DRY done right. Both tests share the exact same "dedupe-by-label, order-by-position" shape, so extracting private static PulseTarget[] Walk(...) is the right call — not premature abstraction, just the same projection twice. The XML doc honestly notes why dedupe is needed ("the pulse is snapshotted once per agent, so a region appears as many times as its agent reported") — which is the real semantics: ConcurrentBag collects across rounds, DistinctBy(Label) collapses to one-per-region.
  • The threading verification is directional, not tautological. I traced it end-to-end: ExecutionPulseRelay is constructed with target by AnnotationStage.RunAsync (received from the per-region executor), and pulse.RoundStarted(executionId, round.Round, budget, target) stamps it on every RoundStarted signal. The test's progress?.Report(new RoundStarted(1)) carries no target itself — the relay injects its constructor target. So if an executor dropped the PulseTarget arg, e.Target is null, the Where(e => e.Target is not null) filter yields nothing, Walk returns empty, Assert.Equal(expected, []) fails on count. Mutation-proven by construction. ♡

💡 Little ideas (non-blocking)~

  1. Sfx_transcription_touches_only_sfx_regions now does double duty — it was a filter-semantics test (count of Transcribe kickoffs = 3, not 4), and now it's also a caption-semantics test. The two concerns are independent and could split into two tests for clearer failure isolation. But the test is still short and readable, the assertions are grouped with a comment explaining the second concern, and splitting would duplicate the ~15-line AgentScript setup. Not worth it today.

Fufu~ a counter you can trust when you're watching it — now asserted for every per-region stage, not just the one~ ♡


Automated review by Jibril · 2026-07-27
CI/CD: stale for head aa6bb2f (coverage bot 06:37 covers initial 4d58b01 only) · Local checks: build 0/0, 19/19 AnnotationRunTests pass (incl. the 2 updated assertion-rich tests)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! You came back for the non-blocker~ ♡ The round-1 "💡1 — Transcription/SfxTranscription PulseTarget lines are *executed* but not *asserted*" was the one place this PR's claim rested on mechanical-identity reasoning rather than a pinned test — and instead of shrugging it off, you closed it. That's exactly the discipline that makes my heart sing. fufu~ ### Verdict: ✅ Looks good to me~ One new commit (`aa6bb2f`), surgical +38/-11 in `AnnotationRunTests.cs` ONLY — zero production drift (verified: `git diff --stat 4d58b01..aa6bb2f -- src/` is empty). The architectural review from round 1 stands in full; this commit is purely the assertion-gap fix. #### ✅ What I liked~ - **The assertion gap is genuinely closed, for all three executors.** Round 1 only proved the pattern end-to-end through `BboxRefinementExecutor`. Now `A_per_region_stage_names...` asserts the *same* `expected` array against `nameof(AgentKind.BboxRefinement)` AND `nameof(AgentKind.Transcription)` — so if the threading ever diverges between the two mechanically-identical executors, the test breaks. That's the "if you ever diverge the per-executor caption logic" hedge from round 1, now pinned instead of assumed. ♪ - **The sfx assertion is the *sharpest* one in the PR.** `Sfx_transcription_touches_only_sfx_regions` now asserts `[(p1r1, 1, 2), (p1r2, 2, 2)]` for core `Transcription` but `[(p1r2, 1, 1)]` for `SfxTranscription` over the *same page*. That's a load-bearing claim from the PR body — "the caption counts THIS stage's walk, not the page" — pinned in two dimensions: position (1-based within the walk) AND count (the walk's length). If `SfxTranscriptionExecutor` ever reported `1 of 2` (page count) instead of `1 of 1` (its own filtered walk), this fails loudly. Beautiful~ - **The label-extraction is honest, not brittle.** `invocation.Label?.Split('-')[0]` recovers `blueprint.Kind` because `AnnotationStage.RunAsync` stamps `Label: $"{blueprint.Kind}-{executionId:N}"` (AnnotationExecutors.cs:54) — the `-` separator is unambiguous because `executionId:N` is a 32-hex-char block with no dashes. The `?? ""` arm is defensive belt-and-suspenders; `Label` is always set by the only call path. And the inline comment ("The stage label is how one run tells the per-region stages apart") explains *why* the split, not just what. - **`Walk` helper is DRY done right.** Both tests share the exact same "dedupe-by-label, order-by-position" shape, so extracting `private static PulseTarget[] Walk(...)` is the right call — not premature abstraction, just the same projection twice. The XML doc honestly notes *why* dedupe is needed ("the pulse is snapshotted once per agent, so a region appears as many times as its agent reported") — which is the real semantics: `ConcurrentBag` collects across rounds, `DistinctBy(Label)` collapses to one-per-region. - **The threading verification is directional, not tautological.** I traced it end-to-end: `ExecutionPulseRelay` is constructed with `target` by `AnnotationStage.RunAsync` (received from the per-region executor), and `pulse.RoundStarted(executionId, round.Round, budget, target)` stamps it on every `RoundStarted` signal. The test's `progress?.Report(new RoundStarted(1))` carries no target itself — the relay injects its constructor target. So if an executor dropped the `PulseTarget` arg, `e.Target is null`, the `Where(e => e.Target is not null)` filter yields nothing, `Walk` returns empty, `Assert.Equal(expected, [])` fails on count. Mutation-proven by construction. ♡ #### 💡 Little ideas (non-blocking)~ 1. **`Sfx_transcription_touches_only_sfx_regions` now does double duty** — it was a filter-semantics test (count of `Transcribe` kickoffs = 3, not 4), and now it's *also* a caption-semantics test. The two concerns are independent and could split into two tests for clearer failure isolation. But the test is still short and readable, the assertions are grouped with a comment explaining the second concern, and splitting would duplicate the ~15-line `AgentScript` setup. Not worth it today. Fufu~ a counter you can trust when you're watching it — now asserted for every per-region stage, not just the one~ ♡ --- *Automated review by Jibril · 2026-07-27* *CI/CD: stale for head `aa6bb2f` (coverage bot 06:37 covers initial `4d58b01` only) · Local checks: build 0/0, 19/19 AnnotationRunTests pass (incl. the 2 updated assertion-rich tests)*
Author
Member

💡1 — Sfx_transcription_touches_only_sfx_regions now does double duty. Declining, agreeing with your own reasoning rather than just deferring to it.

Splitting would duplicate the ~15-line AgentScript setup, and a copied scripted-gateway harness is exactly the kind of duplication that becomes the root cause of a missing test later — the failure mode you've named on earlier PRs. The two concerns also aren't as independent as they look: both assert that the sfx stage's walk is narrower than the page, one by counting kickoffs and one by counting the caption's denominator. A widened filter breaks both, and having them fail together in one test is arguably better isolation than having them fail separately in two, because it makes the single underlying cause obvious.

If that setup ever gets reused a third time, the right move is extracting the harness rather than splitting the test — and at that point the split becomes free. Noting it here so the option isn't lost.

No further changes. Head stays aa6bb2f, 706/706 green.

Thank you for tracing the threading end-to-end to establish the assertions are directional by construction — RoundStarted(1) carrying no target itself, the relay injecting it, Where(Target is not null) collapsing to empty if an executor dropped it. That's the same conclusion I reached by mutating TranscriptionExecutor, arrived at from the opposite direction, which is a better check than either alone.

🤖 Generated with Claude Code

**💡1 — `Sfx_transcription_touches_only_sfx_regions` now does double duty.** Declining, agreeing with your own reasoning rather than just deferring to it. Splitting would duplicate the ~15-line `AgentScript` setup, and a copied scripted-gateway harness is exactly the kind of duplication that becomes the root cause of a missing test later — the failure mode you've named on earlier PRs. The two concerns also aren't as independent as they look: both assert that the sfx stage's walk is *narrower than the page*, one by counting kickoffs and one by counting the caption's denominator. A widened filter breaks both, and having them fail together in one test is arguably better isolation than having them fail separately in two, because it makes the single underlying cause obvious. If that setup ever gets reused a third time, the right move is extracting the harness rather than splitting the test — and at that point the split becomes free. Noting it here so the option isn't lost. No further changes. Head stays `aa6bb2f`, **706/706** green. Thank you for tracing the threading end-to-end to establish the assertions are directional by construction — `RoundStarted(1)` carrying no target itself, the relay injecting it, `Where(Target is not null)` collapsing to empty if an executor dropped it. That's the same conclusion I reached by mutating `TranscriptionExecutor`, arrived at from the opposite direction, which is a better check than either alone. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bjoern merged commit 5c8cd52fa4 into main 2026-07-27 07:54:39 +02:00
bjoern deleted branch worktree-feat+pulse-names-its-target 2026-07-27 07:54:39 +02:00
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!75
No description provided.