fix: every Stories, Settings, manuscript and History request settles when its use case throws, then lets the bug through — no Create left spinning, no save left on Saving…, New chapter comes back or opens what it made, History's buttons come back #62

Merged
bjoern merged 4 commits from fix/effects-settle-everywhere into main 2026-09-26 20:41:52 +02:00
Member

Summary

#55 fixed this for documents. The other effects had the same bug with no try or catch anywhere: a use case that threw instead of refusing (a bug, or a database busy past its timeout) left the page where the request had put it. Kagaku's containment keeps the circuit alive, so after Continue Create kept spinning, the indicator stayed on Saving…, New chapter stayed spent, History's buttons stayed disabled, and Back up now and Remove key stayed busy. Four commits:

  1. EffectCalls.CallAsync. #55's helper moved out of DocumentsEffects unchanged into one static class at the adapter root. Every effect imports it with using static. On a throw it dispatches the handler's own refusal action, then throw;, so the bug still reaches the containment's modal. The documents tests pass untouched.
  2. Stories. A create that throws lands StoryCreateFailed("Something went wrong; the story may not have been created."), so the form comes back with the reason. The row actions (archive, trash, restore, purge) hold nothing, so they are not wrapped, and a test pins that they claim no refusal.
  3. Settings.
    • Back up now lands BackupFailed. BackupCompleted/BackupFailed are now dispatched before the re-read, so a re-read that throws cannot leave the button spinning.
    • A Defaults save lands LlmDefaultsSaveFailed.
    • A catalog load lands ModelCatalogLoadFailed, which offers Try again.
    • A Provider load or check ends as a refused check carrying that load's Read id.
    • A key save lands OpenRouterKeySaveFailed.
    • A key removal, which has no refusal, lands the new OpenRouterKeyRemoveFailed, which frees only Remove key.
  4. Workspace.
    • Saves: a chapter rename, a chapter summary or a story-details save lands AutoSaveFailed(storyId, "Something went wrong; the change may not have been saved."), the same sentence the documents' indicator uses.
    • ChapterSaved no longer carries the undo status. It is dispatched first, and UndoStatusChanged follows from its own read, the way DocumentSaved works. Before, a throwing undo read after a save that landed also left Saving… stuck.
    • New chapter: a create that throws lands WorkspaceActionFailed(…"the chapter may not have been created."), which gives New chapter back. A create that lands whose reload throws still opens the chapter it made, because the navigation sits in a finally.
    • History requests: Save a version, Revert to here and History's Redo each settle with WorkspaceActionFailed and their own words.
    • History reads: a read of History that throws lands the new HistoryReadFailed(storyId). It clears HistoryLoading and HistoryBusy, keeps Error, and claims no refusal. This frees the buttons when the reload after a version or revert that landed throws.
    • Not wrapped: move, merge, delete, undo and redo hold nothing, so they are not wrapped for symmetry. Tests pin that they claim no refusal.

Every settle copies its handler's own Err arm, as in #55. Where it is not known whether a write that threw landed, the words hedge. No ADR covers what a request does when its use case throws (#55 noted the same), and none mentions ChapterSaved, so no ADR is amended. Everything touched is in the adapter's effects, their reducers, the records they need, and the adapter tests. Test seams follow #55's FailingStoryReads idiom: Fail switches on FakeChapterStore, FakeSnapshotStore, FakeStoryStore, FakeBackupStore, FakeAppSettingsStore and FakeModelProvider, and new decorators FailingUndoStore and FailingSnapshotReads. FakeUndoStore.cs and FakeChangeJournal.cs are untouched.

Verification

  • Suites after the rebase onto e19247c (#61, #59):
    • BlazorAdapter: 528/528 on 3 runs in a row.
    • The failure and effect classes this PR touches (*StoreFailureTests, ManuscriptEffectsTests, HistoryEffectsTests, WorkspaceReducersTests, EffectCallsTests, BackupsSettingsTests; 111 tests): 7 more runs, no flakes.
    • Integration: 556/556 on one run.
    • The build has 0 warnings.
  • Implementer's mutation probes: 49 compiling mutations (21 on steps 1–3, 28 on step 4: 13 ManuscriptEffects, 9 HistoryEffects, 6 reducers). Each was restored by a trap, and every one fails at least one test.
  • Independent review: two reviewers read the diff against the brief. Both gave the verdict fix-then-ready. One ran 82 compiling probes, and 80 were killed. What they found, and what was done:
    • minor: the fresh undo status after a saved title or summary was not pinned (MS15). ManuscriptEffectsTests expected UndoStatus(false, false, null, null), which is also the page's default because the fakes do not journal. Dispatching that constant, or state.Value.Undo, passed all 516 tests. Fixed: the new theory A_saved_title_or_summary_is_followed_by_what_Ctrl_Z_would_do_now journals an edit first and asserts exactly [ChapterSaved, UndoStatusChanged(storyId, UndoStatus(true, false, "User — wrote the opening", null))]. Both mutations are now killed (rename and summary rows).
    • minor: OnChapterSaved leaving Undo alone was not pinned (WR2). A reducer that reset Undo passed. Fixed in two places. The reducer fact A_saved_chapter_leaves_what_Ctrl_Z_would_do_to_the_status_that_follows_it asserts Assert.Same. The page test A_title_that_lands_whose_undo_read_throws_says_Saved now journals an edit and checks that Undo is still enabled after Continue. Both kill it.
    • minor: OpenRouterKeyRemoveFailed claimed the removal "wrote nothing". EfAppSettingsStore does not guarantee that. Its SaveChangesAsync runs on the circuit's context without clearing the tracker, so a Deleted entity left by a failed save is committed by the circuit's next write. Fixed within this PR's paths: the record's doc, the effect's comment and the reducer's comment now hedge ("whether the key went is not known; the tab keeps the view it last read"). The store is a follow-up below.
    • nit: ManuscriptSurface.razor reads the undo status before ChapterWritten. This is the same shape as the ChapterSaved fix above. It belongs to the editor track and is a follow-up below.
  • Follow-ups, outside this PR's paths:
    • EfAppSettingsStore.RemoveAsync/UpsertAsync should clear the tracker when a write fails, either with a try/finally around ChangeTracker.Clear() or by running through TsumugiDbContext.WriteAsync. Until then, a failed key removal or save can be committed by the circuit's next unrelated write, and ProviderSection's "The key you entered was not saved." can be untrue.
    • ManuscriptSurface.razor's WriteAsync should dispatch ChapterWritten without Undo first and UndoStatusChanged after it. Otherwise a throwing undo read costs a write that landed its ack and its patch.
    • A first load that throws still leaves its loading line up: StoryShell's "Loading the story…", HistoryPanel's "Reading the journal…" (it now lands HistoryReadFailed, but the panel shows the line while History is null), and the Stories list, the trash, Backups, Defaults and Provider on first mount. Fixing these is a razor change.
    • A merge or delete that lands but whose reload throws leaves the page on the chapter that went until the doorbell's reload shows "Chapter not found". A create that lands but whose reload throws opens a page that shows "Chapter not found" until the next reload lands.
    • DocumentsEffects.SettleAsync: when its re-query throws, UndoStatusChanged is skipped, so Undo lags until the next reload. This was optional in the brief and was not taken.

🤖 Generated with Claude Code

## Summary #55 fixed this for documents. The other effects had the same bug with no `try` or `catch` anywhere: a use case that threw instead of refusing (a bug, or a database busy past its timeout) left the page where the request had put it. Kagaku's containment keeps the circuit alive, so after **Continue** Create kept spinning, the indicator stayed on Saving…, New chapter stayed spent, History's buttons stayed disabled, and Back up now and Remove key stayed busy. Four commits: 1. **`EffectCalls.CallAsync`.** #55's helper moved out of `DocumentsEffects` unchanged into one static class at the adapter root. Every effect imports it with `using static`. On a throw it dispatches the handler's own refusal action, then `throw;`, so the bug still reaches the containment's modal. The documents tests pass untouched. 2. **Stories.** A create that throws lands `StoryCreateFailed("Something went wrong; the story may not have been created.")`, so the form comes back with the reason. The row actions (archive, trash, restore, purge) hold nothing, so they are not wrapped, and a test pins that they claim no refusal. 3. **Settings.** - Back up now lands `BackupFailed`. `BackupCompleted`/`BackupFailed` are now dispatched before the re-read, so a re-read that throws cannot leave the button spinning. - A Defaults save lands `LlmDefaultsSaveFailed`. - A catalog load lands `ModelCatalogLoadFailed`, which offers Try again. - A Provider load or check ends as a refused check carrying that load's `Read` id. - A key save lands `OpenRouterKeySaveFailed`. - A key removal, which has no refusal, lands the new `OpenRouterKeyRemoveFailed`, which frees only Remove key. 4. **Workspace.** - **Saves:** a chapter rename, a chapter summary or a story-details save lands `AutoSaveFailed(storyId, "Something went wrong; the change may not have been saved.")`, the same sentence the documents' indicator uses. - **`ChapterSaved` no longer carries the undo status.** It is dispatched first, and `UndoStatusChanged` follows from its own read, the way `DocumentSaved` works. Before, a throwing undo read after a save that landed also left Saving… stuck. - **New chapter:** a create that throws lands `WorkspaceActionFailed(…"the chapter may not have been created.")`, which gives New chapter back. A create that lands whose reload throws still opens the chapter it made, because the navigation sits in a `finally`. - **History requests:** Save a version, Revert to here and History's Redo each settle with `WorkspaceActionFailed` and their own words. - **History reads:** a read of History that throws lands the new `HistoryReadFailed(storyId)`. It clears `HistoryLoading` and `HistoryBusy`, keeps `Error`, and claims no refusal. This frees the buttons when the reload after a version or revert that landed throws. - **Not wrapped:** move, merge, delete, undo and redo hold nothing, so they are not wrapped for symmetry. Tests pin that they claim no refusal. Every settle copies its handler's own `Err` arm, as in #55. Where it is not known whether a write that threw landed, the words hedge. No ADR covers what a request does when its use case throws (#55 noted the same), and none mentions `ChapterSaved`, so no ADR is amended. Everything touched is in the adapter's effects, their reducers, the records they need, and the adapter tests. Test seams follow #55's `FailingStoryReads` idiom: `Fail` switches on `FakeChapterStore`, `FakeSnapshotStore`, `FakeStoryStore`, `FakeBackupStore`, `FakeAppSettingsStore` and `FakeModelProvider`, and new decorators `FailingUndoStore` and `FailingSnapshotReads`. `FakeUndoStore.cs` and `FakeChangeJournal.cs` are untouched. ## Verification - **Suites** after the rebase onto `e19247c` (#61, #59): - BlazorAdapter: 528/528 on 3 runs in a row. - The failure and effect classes this PR touches (`*StoreFailureTests`, `ManuscriptEffectsTests`, `HistoryEffectsTests`, `WorkspaceReducersTests`, `EffectCallsTests`, `BackupsSettingsTests`; 111 tests): 7 more runs, no flakes. - Integration: 556/556 on one run. - The build has 0 warnings. - **Implementer's mutation probes:** 49 compiling mutations (21 on steps 1–3, 28 on step 4: 13 `ManuscriptEffects`, 9 `HistoryEffects`, 6 reducers). Each was restored by a trap, and every one fails at least one test. - **Independent review:** two reviewers read the diff against the brief. Both gave the verdict *fix-then-ready*. One ran 82 compiling probes, and 80 were killed. What they found, and what was done: - **minor: the fresh undo status after a saved title or summary was not pinned (MS15).** `ManuscriptEffectsTests` expected `UndoStatus(false, false, null, null)`, which is also the page's default because the fakes do not journal. Dispatching that constant, or `state.Value.Undo`, passed all 516 tests. Fixed: the new theory `A_saved_title_or_summary_is_followed_by_what_Ctrl_Z_would_do_now` journals an edit first and asserts exactly `[ChapterSaved, UndoStatusChanged(storyId, UndoStatus(true, false, "User — wrote the opening", null))]`. Both mutations are now killed (rename and summary rows). - **minor: `OnChapterSaved` leaving `Undo` alone was not pinned (WR2).** A reducer that reset `Undo` passed. Fixed in two places. The reducer fact `A_saved_chapter_leaves_what_Ctrl_Z_would_do_to_the_status_that_follows_it` asserts `Assert.Same`. The page test `A_title_that_lands_whose_undo_read_throws_says_Saved` now journals an edit and checks that Undo is still enabled after Continue. Both kill it. - **minor: `OpenRouterKeyRemoveFailed` claimed the removal "wrote nothing".** `EfAppSettingsStore` does not guarantee that. Its `SaveChangesAsync` runs on the circuit's context without clearing the tracker, so a Deleted entity left by a failed save is committed by the circuit's next write. Fixed within this PR's paths: the record's doc, the effect's comment and the reducer's comment now hedge ("whether the key went is not known; the tab keeps the view it last read"). The store is a follow-up below. - **nit: `ManuscriptSurface.razor` reads the undo status before `ChapterWritten`.** This is the same shape as the `ChapterSaved` fix above. It belongs to the editor track and is a follow-up below. - **Follow-ups, outside this PR's paths:** - `EfAppSettingsStore.RemoveAsync`/`UpsertAsync` should clear the tracker when a write fails, either with a `try`/`finally` around `ChangeTracker.Clear()` or by running through `TsumugiDbContext.WriteAsync`. Until then, a failed key removal or save can be committed by the circuit's next unrelated write, and `ProviderSection`'s "The key you entered was not saved." can be untrue. - `ManuscriptSurface.razor`'s `WriteAsync` should dispatch `ChapterWritten` without `Undo` first and `UndoStatusChanged` after it. Otherwise a throwing undo read costs a write that landed its ack and its patch. - A first load that throws still leaves its loading line up: StoryShell's "Loading the story…", HistoryPanel's "Reading the journal…" (it now lands `HistoryReadFailed`, but the panel shows the line while `History` is null), and the Stories list, the trash, Backups, Defaults and Provider on first mount. Fixing these is a razor change. - A merge or delete that lands but whose reload throws leaves the page on the chapter that went until the doorbell's reload shows "Chapter not found". A create that lands but whose reload throws opens a page that shows "Chapter not found" until the next reload lands. - `DocumentsEffects.SettleAsync`: when its re-query throws, `UndoStatusChanged` is skipped, so Undo lags until the next reload. This was optional in the brief and was not taken. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
#55 settled every documents request on a throw through DocumentsEffects' private CallAsync: the
use case's call, and on a throw the request's settle dispatched, then `throw;`. The stories, the
settings and the workspace effects need the same thing; one copy each would drift.

- EffectCalls.CallAsync, internal and static beside the effects, is that method as it was: any
  answer, one settle, the exception rethrown. DocumentsEffects imports it (`using static`) and its
  calls read as before; its tests pass untouched.
- Pinned on its own: an answer goes back as it came with nothing dispatched; a use case that throws
  lands exactly its settle, then the same exception goes on with the frame it was thrown from — not
  thrown anew; one that throws before it returns a task settles too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
OnCreateAsync called CreateStory with nothing around it. CreateStoryRequested sets Creating, and only
StoryCreated or StoryCreateFailed clears it; the form is spent while Creating is set or while it has
asked with no reason to show. So a store that failed outright left Create spinning under the modal's
Continue, and the form could not ask again until it was closed and opened afresh.

- The create goes through EffectCalls.CallAsync: a throw lands what a refusal does,
  StoryCreateFailed("Something went wrong; the story may not have been created.") — Creating off, the
  reason under the title, the form the writer's again — and nothing navigates; then the exception
  goes on to the circuit's error containment. Whether the story was made is not known; one that was
  rings the doorbell, and the list shows it.
- The row actions (archive, trash, restore, purge) need nothing: their requests only clear the last
  refusal, no button waits on them, and a write that landed rings the doorbell. Said in the effects'
  summary and pinned as it stands. The load needs no settle either — Loading is read by no page; its
  first load that throws is left for a follow-up (the page shows no read failure in place of the
  loading line).
- FakeStoryStore.Fail: every write throws it before anything changes, the reads still answer — as
  FakeDocumentStore.Fail does.
- Pinned in the effect (the same exception, exactly StoryCreateFailed with its words, no story, no
  navigation) and on the page through the real Fluxor pipeline: the containment's modal names the
  failure; after Continue the form is still open with the reason under the title, Creating off,
  Create neither busy nor disabled, nothing navigated; the next submit asks again — a spent form
  would not — and makes the story and opens it. A row action the store fails outright shows the
  modal, claims no refusal, leaves the list and the trash as the store holds them, and the next
  Archive from the row menu lands.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
None of the three Settings effects had anything around its use cases, and each request sets a flag only
its outcome clears. Checked per handler whether the use case can throw past a refusal at all:

- Back up now: the store turns I/O and SQLite failures into refusals but lets anything else through
  (FileSystemBackupStore.RunAsync rethrows), and the re-read after a run lists the backups directory
  unguarded. Either left Running set — the button spinning, and its click guard refusing every later
  click. The run now goes through EffectCalls.CallAsync with BackupFailed("Something went wrong; the
  backup may not have been made."); and refused or not, the button stops first and the view is read
  after, so a re-read that throws leaves nothing spinning and claims no refusal of a run that landed.
  BackupCompleted carries no view any more; the BackupSettingsLoaded that follows it does.
- The Defaults save: every setting is an EF write. A throw left Save = Saving — the indicator on
  Saving… for good. It lands LlmDefaultsSaveFailed("Something went wrong; the change may not have been
  saved.") now.
- The model catalog: the gateway throws once disposed. A throw left CatalogLoading set — the picker
  loading and the effort disabled, with no Try again. It lands ModelCatalogLoadFailed("The model
  catalog could not be loaded.") now, and Try again is offered.
- A Provider load or Check again: the view reads the database and the check asks the gateway. A throw
  in either left Checking set, so Busy: Check again spinning, Remove key disabled. Both now end as a
  refused check of that same load does — ProviderKeyChecked(null, "The key in effect could not be
  checked.", its read id) — so an older load's failure is still dropped.
- A key save: the check asks the gateway, the write protects and stores. A throw left Saving set. It
  lands OpenRouterKeySaveFailed("Something went wrong.") now; the tab adds that the key was not saved.
- A removal: an EF write, and it has no refusal to mirror. A throw left Removing set. It lands
  OpenRouterKeyRemoveFailed, which frees only Removing: the store wrote nothing, so the view shown
  stands and nothing is read again.
- The loads of the Backups view and of the Defaults record hold no flag: they need nothing. A first load
  of either — like the Provider's view and the story list — that throws leaves the tab's loading line
  standing until it mounts again; saying so in its place is a page change, left for a follow-up.

The fakes can fail: FakeBackupStore.Fail (a run) and FailReads (a listing); FakeAppSettingsStore.Fail
(every write) and FailReads (every read); FakeModelProvider.Fail (every question OpenRouter would
answer — a gateway already disposed; which key is in effect still answers).

Pinned in the effects — the same exception, exactly the settle with its words, nothing after it: no
re-read, no "saved", no read of the view — for every case above, the key save for a throwing check and
a throwing write, and the Back up now re-read for a run that landed and one refused; the removal's
reducer frees Removing and nothing else. On each tab through the real Fluxor pipeline: the
containment's modal names the failure; after Continue Back up now is neither busy nor refusing clicks
(the next one runs, and the danger alert says why or — for a landed run whose re-read threw — nothing),
the indicator shows the reason and the next pick saves the whole record, the catalog's warning and
Try again appear and the effort is enabled, Check again after a throwing read or check ends with the
warning, no figures and nothing busy, a throwing save says the key was not saved and the next save
stores it, and a throwing removal gives Remove key back with the key still stored and the next removal
lands. Every settle was probed with a compiling mutation.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fix(workspace): every manuscript and History request that holds something settles when its use case throws — a save leaves Saving…, New chapter comes back or opens what it made, a version or a revert gives History's buttons back
All checks were successful
CI / build (pull_request) Successful in 45s
CI / editor-browsers (pull_request) Successful in 1m2s
CI / test (pull_request) Successful in 1m37s
c7eb6531ad
Neither ManuscriptEffects nor HistoryEffects had anything around its use cases. Checked per handler
what a throw would leave held:

- A chapter's title or summary, and the story's details: the request sets Save = Saving, and only a
  saved or refused answer clears it — the shell's indicator stayed on Saving… for good. Each goes
  through EffectCalls.CallAsync and lands AutoSaveFailed("Something went wrong; the change may not
  have been saved.") now. A title or summary that landed dispatched ChapterSaved only after reading
  the undo state, so a read that threw kept the save in flight too: ChapterSaved no longer carries
  the undo state, and UndoStatusChanged follows it, as DocumentSaved does.
- New chapter: the Chapters page and a chapter's toolbar spend it once it has asked, until a refusal
  names why or the new chapter opens. A create that threw lands WorkspaceActionFailed("Something went
  wrong; the chapter may not have been created.") now — the shell says why, and the button is the
  writer's again. A create that landed opened its chapter only after the reload; a reload that threw
  left the button spent on a page that never moved. The chapter exists, so it opens now even then.
- Save a version, Revert to here and History's Redo hold HistoryBusy until they answer. A throw lands
  WorkspaceActionFailed with words of its own ("…the version may not have been saved.", "…the story
  may not have been reverted.", "…the revert may not have been redone."). A landed one frees the
  buttons through History's reload; a read of History that threw left them disabled. It lands the new
  HistoryReadFailed now, which ends HistoryLoading and HistoryBusy and claims no refusal. A version
  asks for that reload before it reads the undo state, so that read throwing holds nothing.
- Need nothing: a move, a merge, a delete, an undo and a redo only clear the previous refusal and hold
  nothing; the doorbell's re-reads of the undo state feed no flag; the manuscript's load sets Loading,
  which no page reads. A first load that throws — the story's or History's — leaves its loading line
  standing, which only the shell or the panel could replace: left for a follow-up, beside the other
  first loads this arc leaves.

The fakes can fail: FakeChapterStore.Fail (every write) and FakeSnapshotStore.Fail (a new snapshot);
FailingUndoStore and FailingSnapshotReads stand in front of the journal fakes, so an undo, a revert, the
undo state's read or History's read can fail alone.

Pinned in the effects — the same exception, exactly the settle with its words, nothing after it — for
each save, the create, the create whose reload threw (it opens the chapter and claims nothing), the
title and summary whose undo read threw (ChapterSaved alone), a version, a revert, a redo, History's
read, the version and the doorbell whose undo read threw (LoadHistory alone), and every request that
holds nothing (nothing dispatched, nothing moved); the reducer frees HistoryBusy and HistoryLoading and
nothing else, and drops another story's read. On the pages through the real Fluxor pipeline: the
containment's modal names the failure; after Continue the indicator shows the reason and the next save
lands, a title typed is kept as typed and the next pause saves it, a title that landed says Saved, New
chapter says why and makes the chapter on the next click or opens the one it made, a row action or an
undo or redo claims nothing and the next one lands, and History's buttons are the writer's again with
the reason in the shell — or with no word at all after a version whose reload threw — and the next
request lands. Every settle was probed with a compiling mutation.

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

🔄 Auto-updating coverage report — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip.

Commit: c7eb653 · Generated: 2026-09-26 18:18:35 UTC · Revision: #1

Summary

Summary
Generated on: 09/26/2026 - 18:18:34
Coverage date: 09/26/2026 - 18:18:04 - 09/26/2026 - 18:18:30
Parser: MultiReport (6x Cobertura)
Assemblies: 9
Classes: 506
Files: 455
Line coverage: 98.1% (15906 of 16209)
Covered lines: 15906
Uncovered lines: 303
Coverable lines: 16209
Total lines: 34667
Branch coverage: 94.3% (6053 of 6418)
Covered branches: 6053
Total branches: 6418
Method coverage: Feature is only available for sponsors

Coverage

Kagaku.Flow - 99.7%
Name Line Branch
Kagaku.Flow 99.7% 99.2%
Kagaku.Flow.Budgeting.BudgetRequest 100%
Kagaku.Flow.Budgeting.ConsumerBudget 100%
Kagaku.Flow.Execution.NodeExecution 100% 100%
Kagaku.Flow.Execution.NodeOutcome 100% 100%
Kagaku.Flow.Execution.TransientFailureException 100%
Kagaku.Flow.Execution.Upstream 100%
Kagaku.Flow.Extensions.ServiceCollectionExtensions 100%
Kagaku.Flow.FlowJson 100%
Kagaku.Flow.Graphs.GraphDefinition 100%
Kagaku.Flow.Graphs.GraphDocument 100% 100%
Kagaku.Flow.Graphs.GraphEdge 100%
Kagaku.Flow.Graphs.GraphIndex 100% 100%
Kagaku.Flow.Graphs.GraphLoadError 100%
Kagaku.Flow.Graphs.GraphLoadResult 100%
Kagaku.Flow.Graphs.GraphNode 100%
Kagaku.Flow.Graphs.GraphPosition 100%
Kagaku.Flow.Graphs.GraphReader 100% 100%
Kagaku.Flow.Graphs.GraphSchema 100% 100%
Kagaku.Flow.Graphs.GraphShapeException 100%
Kagaku.Flow.Graphs.GraphWriter 100% 100%
Kagaku.Flow.Graphs.SocketRef 100%
Kagaku.Flow.Graphs.WireText 100% 100%
Kagaku.Flow.Nodes.CanvasDescriptorWriter 100% 100%
Kagaku.Flow.Nodes.ConfigProblem 100%
Kagaku.Flow.Nodes.Names 100%
Kagaku.Flow.Nodes.NodeDescriptor 100% 100%
Kagaku.Flow.Nodes.NodeRegistry 100% 100%
Kagaku.Flow.Nodes.NodeSockets 100% 100%
Kagaku.Flow.Nodes.SinkDescriptor 100%
Kagaku.Flow.Nodes.SocketTypes 100% 100%
Kagaku.Flow.Nodes.SourceDescriptor 100%
Kagaku.Flow.Nodes.TemplateField 100%
Kagaku.Flow.Runs.LedgerChange 100% 100%
Kagaku.Flow.Runs.LedgerTransitions 100% 100%
Kagaku.Flow.Runs.NodeAttempt 100%
Kagaku.Flow.Runs.NodeFacts 100%
Kagaku.Flow.Runs.NodeRun 100%
Kagaku.Flow.Runs.Run 100% 100%
Kagaku.Flow.Runs.RunEvent 100%
Kagaku.Flow.Runs.RunStatuses 100% 100%
Kagaku.Flow.Runs.RunTrigger 100% 100%
Kagaku.Flow.Scheduling.Exclusion 100%
Kagaku.Flow.Scheduling.FlowEngine 100% 100%
Kagaku.Flow.Scheduling.FlowEngineOptions 100% 100%
Kagaku.Flow.Scheduling.ReadyRow 100%
Kagaku.Flow.Scheduling.ReadySet 100% 100%
Kagaku.Flow.Scheduling.ReadySetResult 100%
Kagaku.Flow.Scheduling.RunRequest 100% 100%
Kagaku.Flow.Scheduling.RunStartResult 100%
Kagaku.Flow.Scheduling.SocketValues 100% 100%
Kagaku.Flow.Templating.InputsWalker 100% 100%
Kagaku.Flow.Templating.ParsedTemplate 100% 100%
Kagaku.Flow.Templating.SandboxedTemplateContext 100% 100%
Kagaku.Flow.Templating.TemplateError 100%
Kagaku.Flow.Templating.TemplateHost 100% 100%
Kagaku.Flow.Templating.TemplateLimits 100%
Kagaku.Flow.Templating.TemplateModel 100% 100%
Kagaku.Flow.Templating.TemplateProblem 100%
Kagaku.Flow.Templating.TemplateRenderRequest 100% 100%
Kagaku.Flow.Templating.TemplateRenderResult 100%
Kagaku.Flow.Templating.TemplateRun 100%
Kagaku.Flow.Templating.TemplateSinks 100%
Kagaku.Flow.Templating.TemplateValues 100% 100%
Kagaku.Flow.Validation.GraphValidation 100% 100%
Kagaku.Flow.Validation.GraphValidationContext 100%
Kagaku.Flow.Validation.HookFailure 100%
Kagaku.Flow.Validation.ResolvedGraph 100% 100%
Kagaku.Flow.Validation.ValidationError 100%
Kagaku.Flow.Validation.ValidationReport 100%
System.Text.RegularExpressions.Generated 97.4% 92.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__ColorToken_2
97.4% 94.4%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__Socket_1
97.2% 94.4%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__TypeId_0
97.2% 94.4%
Kagaku.Flow.OpenRouter - 100%
Name Line Branch
Kagaku.Flow.OpenRouter 100% 100%
Kagaku.Flow.OpenRouter.Catalog.ModelCapabilities 100% 100%
Kagaku.Flow.OpenRouter.Gateway.LlmCompletion 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterGateway 100% 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterGatewayOptions 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterKeyLookup 100% 100%
Kagaku.Flow.OpenRouter.Gateway.SentRequestCapture 100% 100%
Kagaku.Flow.OpenRouter.Gateway.SentRequestCaptureHandler 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmAnswer 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmConfig 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmConfigRead 100%
Kagaku.Flow.OpenRouter.Llm.LlmDescriptor 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmExecutor 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmFacts 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmFailureText 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmMessage 100%
Kagaku.Flow.OpenRouter.Llm.LlmRequestBuilder 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmRequestPlan 100%
Kagaku.Flow.OpenRouter.Llm.LlmRoutingDefaults 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmSampling 100%
Kagaku.Flow.OpenRouter.Llm.LlmSchemaCheck 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmStrictSchemaRule 100% 100%
Kagaku.Flow.OpenRouter.Llm.LlmVocabulary 100% 100%
Kagaku.Flow.OpenRouter.LlmNodeServiceCollectionExtensions 100%
Kagaku.Flow.OpenRouter.OpenRouterServiceCollectionExtensions 100% 100%
Kagaku.Flow.Testing - 100%
Name Line Branch
Kagaku.Flow.Testing 100% 100%
Kagaku.Flow.Testing.FlowEngineDriver 100% 100%
Kagaku.Flow.Testing.InMemoryRunLedger 100% 100%
Kagaku.Flow.Testing.RecordingRunEventSink 100%
Kagaku.Flow.Testing.RunLedgerContract 100% 100%
Kagaku.Flow.Testing.RunLedgerContractException 100%
Tsumugi.BlazorAdapter - 95.8%
Name Line Branch
Tsumugi.BlazorAdapter 95.8% 91%
Tsumugi.BlazorAdapter.BlazorAdapterAssembly 100%
Tsumugi.BlazorAdapter.Documents.CategoryCreated 100%
Tsumugi.BlazorAdapter.Documents.CategoryEditor 93.2% 88.4%
Tsumugi.BlazorAdapter.Documents.CategorySaved 100%
Tsumugi.BlazorAdapter.Documents.ChangeCategoryFieldsRequested 100%
Tsumugi.BlazorAdapter.Documents.CreateCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.CreateDocumentRequested 100%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryChoice 100%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryDialog 100% 94.1%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.DeleteDocumentRequested 100%
Tsumugi.BlazorAdapter.Documents.DocumentAutoSaveFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentCreated 100%
Tsumugi.BlazorAdapter.Documents.DocumentEditor 95.7% 89.4%
Tsumugi.BlazorAdapter.Documents.DocumentImageRefused 100%
Tsumugi.BlazorAdapter.Documents.DocumentImageSet 100%
Tsumugi.BlazorAdapter.Documents.DocumentsActionFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentSaved 100%
Tsumugi.BlazorAdapter.Documents.DocumentsEffects 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsList 98.5% 95%
Tsumugi.BlazorAdapter.Documents.DocumentsLoaded 100%
Tsumugi.BlazorAdapter.Documents.DocumentsPage 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsReadFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentsReducers 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsRefusal 100%
Tsumugi.BlazorAdapter.Documents.DocumentsState 100% 100%
Tsumugi.BlazorAdapter.Documents.FieldInput 100% 96.6%
Tsumugi.BlazorAdapter.Documents.FieldsChanges 100% 100%
Tsumugi.BlazorAdapter.Documents.FieldShapes 90% 87.5%
Tsumugi.BlazorAdapter.Documents.ImageUpload 100%
Tsumugi.BlazorAdapter.Documents.ImageUploadRefusal 100%
Tsumugi.BlazorAdapter.Documents.ImpactText 100% 94.2%
Tsumugi.BlazorAdapter.Documents.LoadDocuments 100%
Tsumugi.BlazorAdapter.Documents.MoveDocumentChoice 100%
Tsumugi.BlazorAdapter.Documents.MoveDocumentDialog 95.6% 71.4%
Tsumugi.BlazorAdapter.Documents.MoveDocumentsRequested 100%
Tsumugi.BlazorAdapter.Documents.ReorderCategoriesRequested 100%
Tsumugi.BlazorAdapter.Documents.SetCategoryCollapsed 100%
Tsumugi.BlazorAdapter.Documents.SetDocumentImageRequested 100%
Tsumugi.BlazorAdapter.Documents.SetDocumentsFilter 100%
Tsumugi.BlazorAdapter.Documents.UpdateCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.UpdateDocumentRequested 100%
Tsumugi.BlazorAdapter.EffectCalls 100%
Tsumugi.BlazorAdapter.Graphs.GraphCanvas 37.5% 25%
Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage 20% 25%
Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge 94.4% 83.3%
Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived 75% 100%
Tsumugi.BlazorAdapter.Runs.RunChangedBridge 97.1% 90.6%
Tsumugi.BlazorAdapter.Runs.RunChangesReceived 100%
Tsumugi.BlazorAdapter.Runs.RunTextReceived 100%
Tsumugi.BlazorAdapter.Settings.BackupFailed 100%
Tsumugi.BlazorAdapter.Settings.BackupNowRequested 100%
Tsumugi.BlazorAdapter.Settings.BackupSettingsLoaded 100%
Tsumugi.BlazorAdapter.Settings.BackupsSection 100% 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsEffects 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsState 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSection 100% 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsEffects 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsState 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsLoaded 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaved 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaveFailed 100%
Tsumugi.BlazorAdapter.Settings.LoadBackupSettings 100%
Tsumugi.BlazorAdapter.Settings.LoadProviderSettings 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed 100%
Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaved 100%
Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaveFailed 100%
Tsumugi.BlazorAdapter.Settings.ProviderKeyChecked 100%
Tsumugi.BlazorAdapter.Settings.ProviderSection 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsEffects 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsLoaded 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsReducers 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsState 100% 100%
Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested 100%
Tsumugi.BlazorAdapter.Stories.CreateStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.PurgeStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.RestoreStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.SetShowArchived 100%
Tsumugi.BlazorAdapter.Stories.SetStoriesFilter 100%
Tsumugi.BlazorAdapter.Stories.SetStoryArchivedRequested 100%
Tsumugi.BlazorAdapter.Stories.StoriesEffects 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesLoaded 100%
Tsumugi.BlazorAdapter.Stories.StoriesPage 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesReducers 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesState 100% 100%
Tsumugi.BlazorAdapter.Stories.StoryActionFailed 100%
Tsumugi.BlazorAdapter.Stories.StoryCreated 100%
Tsumugi.BlazorAdapter.Stories.StoryCreateFailed 100%
Tsumugi.BlazorAdapter.Stories.StoryTrashPage 100% 100%
Tsumugi.BlazorAdapter.Stories.TrashStoryRequested 100%
Tsumugi.BlazorAdapter.Workspace.AckWire 100%
Tsumugi.BlazorAdapter.Workspace.AutoSaveFailed 100%
Tsumugi.BlazorAdapter.Workspace.ChangedWire 100%
Tsumugi.BlazorAdapter.Workspace.ChapterHeader 100% 86.3%
Tsumugi.BlazorAdapter.Workspace.ChapterMenu 100% 81.2%
Tsumugi.BlazorAdapter.Workspace.ChapterPage 100% 87.5%
Tsumugi.BlazorAdapter.Workspace.ChapterSaved 100%
Tsumugi.BlazorAdapter.Workspace.ChaptersPage 94.4% 83.3%
Tsumugi.BlazorAdapter.Workspace.ChapterWire 100%
Tsumugi.BlazorAdapter.Workspace.ChapterWritten 100%
Tsumugi.BlazorAdapter.Workspace.CreateChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.CreatedWire 100%
Tsumugi.BlazorAdapter.Workspace.DeleteChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.DeltaWire 100%
Tsumugi.BlazorAdapter.Workspace.HistoryEffects 100% 100%
Tsumugi.BlazorAdapter.Workspace.HistoryLoaded 100%
Tsumugi.BlazorAdapter.Workspace.HistoryPage 100%
Tsumugi.BlazorAdapter.Workspace.HistoryPanel 100% 100%
Tsumugi.BlazorAdapter.Workspace.HistoryReadFailed 100%
Tsumugi.BlazorAdapter.Workspace.LoadHistory 100%
Tsumugi.BlazorAdapter.Workspace.LoadWorkspace 100%
Tsumugi.BlazorAdapter.Workspace.ManuscriptEffects 100% 100%
Tsumugi.BlazorAdapter.Workspace.ManuscriptEvents 81.8% 74.1%
Tsumugi.BlazorAdapter.Workspace.ManuscriptSurface 89.8% 87.1%
Tsumugi.BlazorAdapter.Workspace.MergeChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.MergeEvent 100%
Tsumugi.BlazorAdapter.Workspace.MoveChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.RedoRequested 100%
Tsumugi.BlazorAdapter.Workspace.RedoRevertRequested 100%
Tsumugi.BlazorAdapter.Workspace.RenameChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.ReshapeEvent 100%
Tsumugi.BlazorAdapter.Workspace.RevertToSnapshotRequested 100%
Tsumugi.BlazorAdapter.Workspace.SaveScope 100% 50%
Tsumugi.BlazorAdapter.Workspace.SaveStateLadder 100% 100%
Tsumugi.BlazorAdapter.Workspace.SaveVersionRequested 100%
Tsumugi.BlazorAdapter.Workspace.SegmentTextEvent 100%
Tsumugi.BlazorAdapter.Workspace.SegmentWire 100% 81.8%
Tsumugi.BlazorAdapter.Workspace.SelectionEndWire 100%
Tsumugi.BlazorAdapter.Workspace.SelectionGraph 100%
Tsumugi.BlazorAdapter.Workspace.SelectionRangeWire 100%
Tsumugi.BlazorAdapter.Workspace.SelectionRunRequested 100%
Tsumugi.BlazorAdapter.Workspace.SetChapterSummaryRequested 100%
Tsumugi.BlazorAdapter.Workspace.SplitEvent 100%
Tsumugi.BlazorAdapter.Workspace.StampWire 0%
Tsumugi.BlazorAdapter.Workspace.StoryDetails 100% 85.2%
Tsumugi.BlazorAdapter.Workspace.StoryGeneralPage 100% 100%
Tsumugi.BlazorAdapter.Workspace.StorySaved 100%
Tsumugi.BlazorAdapter.Workspace.StoryShell 100% 100%
Tsumugi.BlazorAdapter.Workspace.UndoRequested 100%
Tsumugi.BlazorAdapter.Workspace.UndoStatusChanged 100%
Tsumugi.BlazorAdapter.Workspace.UpdateStoryRequested 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceActionFailed 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceLoaded 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceNotFound 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceReducers 100% 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceState 100%
Tsumugi.Domain - 96.3%
Name Line Branch
Tsumugi.Domain 96.3% 95%
System.Text.RegularExpressions.Generated 91.3% 88.6%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__DigitsAndSeparators_2
97.4% 95.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__LineBreak_0
91% 91.1%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__NumberToken_1
91.8% 83.3%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__Plain_4
91.9% 88.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__ThousandsGroup_3
90.9% 84.3%
Tsumugi.Domain.Documents.CategoryFields 94.5% 93.7%
Tsumugi.Domain.Documents.ChoiceOption 100%
Tsumugi.Domain.Documents.ChoiceValue 100%
Tsumugi.Domain.Documents.DateText 100%
Tsumugi.Domain.Documents.DateValue 100%
Tsumugi.Domain.Documents.Document 100% 100%
Tsumugi.Domain.Documents.DocumentCategory 100% 100%
Tsumugi.Domain.Documents.DocumentValues 100%
Tsumugi.Domain.Documents.FieldCarry 100% 100%
Tsumugi.Domain.Documents.FieldConversion 100% 100%
Tsumugi.Domain.Documents.FieldDefinition 97% 95.3%
Tsumugi.Domain.Documents.FieldMessages 100% 100%
Tsumugi.Domain.Documents.FieldNames 100%
Tsumugi.Domain.Documents.FieldsChange 100%
Tsumugi.Domain.Documents.FieldShape 95.2% 87.5%
Tsumugi.Domain.Documents.FieldsPlan 100%
Tsumugi.Domain.Documents.FieldsPlanner 99.2% 99.2%
Tsumugi.Domain.Documents.FieldValue 100%
Tsumugi.Domain.Documents.FieldValues 95.4% 97.7%
Tsumugi.Domain.Documents.ImageFiles 100% 100%
Tsumugi.Domain.Documents.ImageValue 100%
Tsumugi.Domain.Documents.MovePlan 100%
Tsumugi.Domain.Documents.NumberParse 100%
Tsumugi.Domain.Documents.NumberText 100% 97.6%
Tsumugi.Domain.Documents.NumberValue 100%
Tsumugi.Domain.Documents.StoryImage 100%
Tsumugi.Domain.Documents.TextValue 100% 100%
Tsumugi.Domain.Documents.ValueChange 100%
Tsumugi.Domain.Documents.ValueChangeKey 100%
Tsumugi.Domain.Documents.ValueImpact 100% 100%
Tsumugi.Domain.Journal.ChangeLogEntry 97.9% 83.3%
Tsumugi.Domain.Journal.StorySnapshot 95.4% 83.3%
Tsumugi.Domain.Settings.AppSetting 100%
Tsumugi.Domain.Stories.Chapter 100% 100%
Tsumugi.Domain.Stories.InlineMarkup 100% 100%
Tsumugi.Domain.Stories.MarkupRun 100%
Tsumugi.Domain.Stories.Provenance 100% 100%
Tsumugi.Domain.Stories.Segment 100% 100%
Tsumugi.Domain.Stories.Story 100% 100%
Tsumugi.Domain.Text 100% 100%
Tsumugi.Infrastructure - 98.3%
Name Line Branch
Tsumugi.Infrastructure 98.3% 86.8%
System.Text.RegularExpressions.Generated 81.4% 64.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F0D076C66E8EEC1C
A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0
84% 65.7%
Tsumugi.Infrastructure.Backups.BackupArtifactName 100% 100%
Tsumugi.Infrastructure.Backups.BackupOptions 100%
Tsumugi.Infrastructure.Backups.BackupSchedule 100% 83.3%
Tsumugi.Infrastructure.Backups.BackupScheduler 96.6% 87.5%
Tsumugi.Infrastructure.Backups.BackupWriter 98.5% 92.8%
Tsumugi.Infrastructure.Backups.DatabaseFingerprint 91.9% 97%
Tsumugi.Infrastructure.Backups.FileSystemBackupStore 100% 100%
Tsumugi.Infrastructure.Backups.OwnerOnlyFile 100% 100%
Tsumugi.Infrastructure.Backups.PreMigrationBackup 90% 100%
Tsumugi.Infrastructure.Backups.SqliteSnapshot 88.2% 75%
Tsumugi.Infrastructure.DependencyInjection 100% 100%
Tsumugi.Infrastructure.Journal.EfChangeJournal 100%
Tsumugi.Infrastructure.Journal.EfSnapshotStore 100%
Tsumugi.Infrastructure.Journal.EfUndoStore 98.5% 88.2%
Tsumugi.Infrastructure.Journal.ModelExtensions 100%
Tsumugi.Infrastructure.Journal.OperationContext 100% 100%
Tsumugi.Infrastructure.Journal.PropertyBag 100% 95.4%
Tsumugi.Infrastructure.Notifications.InProcessDomainChangedBus 100% 100%
Tsumugi.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.ChangeLogEntryConfigurati
on
100%
Tsumugi.Infrastructure.Persistence.Configurations.ChapterConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.DocumentCategoryConfigura
tion
100%
Tsumugi.Infrastructure.Persistence.Configurations.DocumentConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.SegmentConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StoryConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StoryImageConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StorySnapshotConfiguratio
n
100%
Tsumugi.Infrastructure.Persistence.Converters.CanonicalJsonComparer 100%
Tsumugi.Infrastructure.Persistence.Converters.CategoryFieldsConverter 97.6% 94.4%
Tsumugi.Infrastructure.Persistence.Converters.FieldValuesConverter 96.9% 93.7%
Tsumugi.Infrastructure.Persistence.Converters.ProvenanceConverter 100% 90%
Tsumugi.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Tsumugi.Infrastructure.Persistence.Converters.WireFormat 85.7% 73.8%
Tsumugi.Infrastructure.Persistence.Migrations.AddAppSettings 99.2%
Tsumugi.Infrastructure.Persistence.Migrations.AddJournal 98.8%
Tsumugi.Infrastructure.Persistence.Migrations.CategoryFields 100% 100%
Tsumugi.Infrastructure.Persistence.Migrations.CategoryFieldsSql 100%
Tsumugi.Infrastructure.Persistence.Migrations.DropDocumentBody 100%
Tsumugi.Infrastructure.Persistence.Migrations.GenericDocuments 100%
Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain 97.3%
Tsumugi.Infrastructure.Persistence.Migrations.JournalUndoState 100%
Tsumugi.Infrastructure.Persistence.Migrations.SegmentTextMarkup 100% 100%
Tsumugi.Infrastructure.Persistence.Migrations.SegmentTextMarkupSql 100%
Tsumugi.Infrastructure.Persistence.Migrations.StoryImages 100%
Tsumugi.Infrastructure.Persistence.Migrations.TsumugiDbContextModelSnapshot 100%
Tsumugi.Infrastructure.Persistence.SqliteFunctions 80% 66.6%
Tsumugi.Infrastructure.Persistence.SqlitePragmaInterceptor 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfChapterStore 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfDocumentStore 98.3% 75%
Tsumugi.Infrastructure.Persistence.Stores.EfImageStore 100%
Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore 96.6% 84.6%
Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore 98.7% 90%
Tsumugi.Infrastructure.Persistence.TsumugiDbContext 97.7% 96.6%
Tsumugi.Infrastructure.Persistence.TsumugiDbContextFactory 100%
Tsumugi.Infrastructure.Provider.LlmDefaultsSource 100%
Tsumugi.Infrastructure.Provider.OpenRouterKeySource 100% 100%
Tsumugi.Infrastructure.Provider.OpenRouterModelProvider 100% 100%
Tsumugi.Infrastructure.Provider.OpenRouterOptions 100% 100%
Tsumugi.Infrastructure.Provider.ResolvedKey 100%
Tsumugi.Infrastructure.Runs.InProcessRunEventBus 100% 100%
Tsumugi.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Tsumugi.Kernel - 90.9%
Name Line Branch
Tsumugi.Kernel 90.9% 75%
Tsumugi.Kernel.Err`1 100%
Tsumugi.Kernel.Ok`1 100%
Tsumugi.Kernel.Result`1 88.8% 75%
Tsumugi.Server - 100%
Name Line Branch
Tsumugi.Server 100% 92.1%
Program 100% 100%
Tsumugi.Server.Backups.BackupConfiguration 100% 100%
Tsumugi.Server.Components.App 100%
Tsumugi.Server.Components.Layout.AppHeader 100% 50%
Tsumugi.Server.Components.Layout.MainLayout 100%
Tsumugi.Server.Components.Pages.Gate 100% 100%
Tsumugi.Server.Provider.OpenRouterConfiguration 100% 100%
Tsumugi.Server.Security.AccessGate 100% 87.5%
Tsumugi.Server.Security.AccessSecret 100% 100%
Tsumugi.Server.Security.GateThrottle 100% 100%
Tsumugi.Server.VolumeStartupValidator 100% 100%
Tsumugi.UseCases - 98.8%
Name Line Branch
Tsumugi.UseCases 98.8% 96.4%
Tsumugi.UseCases.Backups.BackupArtifact 100%
Tsumugi.UseCases.Backups.BackupFailure 100%
Tsumugi.UseCases.Backups.BackupJobState 100%
Tsumugi.UseCases.Backups.BackupPolicy 100%
Tsumugi.UseCases.Backups.BackupStatusView 100% 100%
Tsumugi.UseCases.Backups.DatabaseSnapshot 100%
Tsumugi.UseCases.Backups.DownloadDatabaseSnapshot 100%
Tsumugi.UseCases.Backups.GetBackupStatus 100%
Tsumugi.UseCases.Backups.IBackupStore 0%
Tsumugi.UseCases.Backups.RunBackupNow 100%
Tsumugi.UseCases.Chapters.ChapterDto 100%
Tsumugi.UseCases.Chapters.CreateChapter 100% 100%
Tsumugi.UseCases.Chapters.DeleteChapter 100% 100%
Tsumugi.UseCases.Chapters.GetChapterSegments 100%
Tsumugi.UseCases.Chapters.GetManuscript 100% 100%
Tsumugi.UseCases.Chapters.ManuscriptChapter 100%
Tsumugi.UseCases.Chapters.ManuscriptView 100%
Tsumugi.UseCases.Chapters.MergeChapters 100% 100%
Tsumugi.UseCases.Chapters.RenameChapter 100% 100%
Tsumugi.UseCases.Chapters.ReorderChapters 100% 100%
Tsumugi.UseCases.Chapters.SetChapterSummary 100% 75%
Tsumugi.UseCases.Context.DocumentRendering 100% 100%
Tsumugi.UseCases.Context.StoryDocumentsRule 100% 100%
Tsumugi.UseCases.Context.StoryReads 100% 100%
Tsumugi.UseCases.Context.StoryScope 100% 100%
Tsumugi.UseCases.Context.StoryTemplateModel 100%
Tsumugi.UseCases.DependencyInjection 100%
Tsumugi.UseCases.Diagnostics.SeedDevData 98.3% 68.7%
Tsumugi.UseCases.Diagnostics.SeedPictures 100%
Tsumugi.UseCases.Documents.ChangeCategoryFields 100% 83.3%
Tsumugi.UseCases.Documents.CreateCategory 100% 100%
Tsumugi.UseCases.Documents.CreateDocument 100% 100%
Tsumugi.UseCases.Documents.DefaultFields 100% 100%
Tsumugi.UseCases.Documents.DeleteCategory 100% 94.4%
Tsumugi.UseCases.Documents.DeleteDocument 100% 100%
Tsumugi.UseCases.Documents.DocumentCategoryDto 100%
Tsumugi.UseCases.Documents.DocumentCategoryProfile 100%
Tsumugi.UseCases.Documents.DocumentDto 100%
Tsumugi.UseCases.Documents.DocumentPatch 100%
Tsumugi.UseCases.Documents.DocumentProfile 100%
Tsumugi.UseCases.Documents.DocumentsCategory 100%
Tsumugi.UseCases.Documents.DocumentsView 100%
Tsumugi.UseCases.Documents.DocumentWrites 100% 100%
Tsumugi.UseCases.Documents.FieldsChangeLabel 95.4% 88.2%
Tsumugi.UseCases.Documents.GetDocuments 100% 100%
Tsumugi.UseCases.Documents.GetStoryImage 100% 100%
Tsumugi.UseCases.Documents.ImpactPreview 100% 100%
Tsumugi.UseCases.Documents.LossMessages 92.3% 87.5%
Tsumugi.UseCases.Documents.MoveDocuments 100% 100%
Tsumugi.UseCases.Documents.ReorderCategories 100% 100%
Tsumugi.UseCases.Documents.SetDocumentImage 100% 93.7%
Tsumugi.UseCases.Documents.StoryImageFile 100%
Tsumugi.UseCases.Documents.UpdateCategory 100% 100%
Tsumugi.UseCases.Documents.UpdateDocument 100% 81.2%
Tsumugi.UseCases.Documents.WriteRefusedException 100%
Tsumugi.UseCases.Journal.GetStoryHistory 100% 100%
Tsumugi.UseCases.Journal.GetUndoStatus 100% 100%
Tsumugi.UseCases.Journal.HistoryOperation 66.6%
Tsumugi.UseCases.Journal.HistorySnapshot 87.5%
Tsumugi.UseCases.Journal.OperationGrouping 100% 100%
Tsumugi.UseCases.Journal.RedoRevert 100% 100%
Tsumugi.UseCases.Journal.RedoRun 90.9% 87.5%
Tsumugi.UseCases.Journal.RedoTyping 100% 100%
Tsumugi.UseCases.Journal.ReplayLanding 100% 100%
Tsumugi.UseCases.Journal.RevertConflict 100%
Tsumugi.UseCases.Journal.RevertOutcome 100%
Tsumugi.UseCases.Journal.RevertRun 96.5% 77.7%
Tsumugi.UseCases.Journal.RevertToSnapshot 92.3% 83.3%
Tsumugi.UseCases.Journal.StoryHistory 100%
Tsumugi.UseCases.Journal.TakeSnapshot 100% 87.5%
Tsumugi.UseCases.Journal.UndoStatus 100%
Tsumugi.UseCases.Journal.UndoTyping 100% 100%
Tsumugi.UseCases.Journal.UserOperation 100%
Tsumugi.UseCases.Notifications.DomainChanged 100%
Tsumugi.UseCases.Ordering 100% 100%
Tsumugi.UseCases.Runs.RunEvent 100%
Tsumugi.UseCases.Segments.ChangedText 100%
Tsumugi.UseCases.Segments.ChapterDraft 100%
Tsumugi.UseCases.Segments.ChapterWriting 100%
Tsumugi.UseCases.Segments.DeleteSegments 100% 100%
Tsumugi.UseCases.Segments.EditSegment 100% 100%
Tsumugi.UseCases.Segments.InsertSegment 100% 100%
Tsumugi.UseCases.Segments.ManuscriptAnswer 100%
Tsumugi.UseCases.Segments.ManuscriptWrites 99.1% 97.6%
Tsumugi.UseCases.Segments.MergeSegments 100%
Tsumugi.UseCases.Segments.MergeWrite 100%
Tsumugi.UseCases.Segments.ModelOutput 98.2% 96.6%
Tsumugi.UseCases.Segments.ModelParagraph 100%
Tsumugi.UseCases.Segments.MoveSegments 100% 100%
Tsumugi.UseCases.Segments.NewBlock 100%
Tsumugi.UseCases.Segments.ReadSelection 100%
Tsumugi.UseCases.Segments.ReorderSegments 100% 100%
Tsumugi.UseCases.Segments.ReshapeSegments 100% 100%
Tsumugi.UseCases.Segments.ReshapeWrite 100%
Tsumugi.UseCases.Segments.SegmentDto 100%
Tsumugi.UseCases.Segments.SelectedSegment 100%
Tsumugi.UseCases.Segments.SelectionEnd 100%
Tsumugi.UseCases.Segments.SelectionInput 100% 100%
Tsumugi.UseCases.Segments.SplitSegment 100%
Tsumugi.UseCases.Segments.SplitWrite 100%
Tsumugi.UseCases.Segments.StampedId 100%
Tsumugi.UseCases.Segments.TextWrite 100%
Tsumugi.UseCases.Settings.CatalogModel 100% 100%
Tsumugi.UseCases.Settings.CheckOpenRouterKey 100%
Tsumugi.UseCases.Settings.GetLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.GetModelCatalog 100% 100%
Tsumugi.UseCases.Settings.GetProviderSettings 100%
Tsumugi.UseCases.Settings.LlmDefaults 100%
Tsumugi.UseCases.Settings.ProviderKeyInfo 100%
Tsumugi.UseCases.Settings.ProviderKeyState 100%
Tsumugi.UseCases.Settings.ProviderSettingsView 100% 100%
Tsumugi.UseCases.Settings.ReasoningEfforts 100% 100%
Tsumugi.UseCases.Settings.RemoveOpenRouterKey 100%
Tsumugi.UseCases.Settings.RoutingDefaults 100%
Tsumugi.UseCases.Settings.RoutingSettings 100% 100%
Tsumugi.UseCases.Settings.SaveLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.SaveOpenRouterKey 100% 100%
Tsumugi.UseCases.Stories.ChapterWriteOutcome 50%
Tsumugi.UseCases.Stories.CreateStory 100% 100%
Tsumugi.UseCases.Stories.GetStory 100% 100%
Tsumugi.UseCases.Stories.ListStories 100% 75%
Tsumugi.UseCases.Stories.PurgeStory 100% 100%
Tsumugi.UseCases.Stories.RestoreStory 100% 100%
Tsumugi.UseCases.Stories.SetActiveGraph 100% 100%
Tsumugi.UseCases.Stories.SetStoryArchived 100% 100%
Tsumugi.UseCases.Stories.StarterCategories 100%
Tsumugi.UseCases.Stories.StoryDetail 100%
Tsumugi.UseCases.Stories.StoryListItem 81.8%
Tsumugi.UseCases.Stories.StoryProfile 100%
Tsumugi.UseCases.Stories.TrashStory 100% 100%
Tsumugi.UseCases.Stories.UpdateStory 100% 100%
<!-- coverage-comment --> > 🔄 **Auto-updating coverage report** — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip. > > **Commit:** `c7eb653` · **Generated:** 2026-09-26 18:18:35 UTC · **Revision:** #1 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 09/26/2026 - 18:18:34 | | Coverage date: | 09/26/2026 - 18:18:04 - 09/26/2026 - 18:18:30 | | Parser: | MultiReport (6x Cobertura) | | Assemblies: | 9 | | Classes: | 506 | | Files: | 455 | | **Line coverage:** | 98.1% (15906 of 16209) | | Covered lines: | 15906 | | Uncovered lines: | 303 | | Coverable lines: | 16209 | | Total lines: | 34667 | | **Branch coverage:** | 94.3% (6053 of 6418) | | Covered branches: | 6053 | | Total branches: | 6418 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagaku.Flow - 99.7%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow**|**99.7%**|**99.2%**| |Kagaku.Flow.Budgeting.BudgetRequest|100%|| |Kagaku.Flow.Budgeting.ConsumerBudget|100%|| |Kagaku.Flow.Execution.NodeExecution|100%|100%| |Kagaku.Flow.Execution.NodeOutcome|100%|100%| |Kagaku.Flow.Execution.TransientFailureException|100%|| |Kagaku.Flow.Execution.Upstream|100%|| |Kagaku.Flow.Extensions.ServiceCollectionExtensions|100%|| |Kagaku.Flow.FlowJson|100%|| |Kagaku.Flow.Graphs.GraphDefinition|100%|| |Kagaku.Flow.Graphs.GraphDocument|100%|100%| |Kagaku.Flow.Graphs.GraphEdge|100%|| |Kagaku.Flow.Graphs.GraphIndex|100%|100%| |Kagaku.Flow.Graphs.GraphLoadError|100%|| |Kagaku.Flow.Graphs.GraphLoadResult|100%|| |Kagaku.Flow.Graphs.GraphNode|100%|| |Kagaku.Flow.Graphs.GraphPosition|100%|| |Kagaku.Flow.Graphs.GraphReader|100%|100%| |Kagaku.Flow.Graphs.GraphSchema|100%|100%| |Kagaku.Flow.Graphs.GraphShapeException|100%|| |Kagaku.Flow.Graphs.GraphWriter|100%|100%| |Kagaku.Flow.Graphs.SocketRef|100%|| |Kagaku.Flow.Graphs.WireText|100%|100%| |Kagaku.Flow.Nodes.CanvasDescriptorWriter|100%|100%| |Kagaku.Flow.Nodes.ConfigProblem|100%|| |Kagaku.Flow.Nodes.Names|100%|| |Kagaku.Flow.Nodes.NodeDescriptor|100%|100%| |Kagaku.Flow.Nodes.NodeRegistry|100%|100%| |Kagaku.Flow.Nodes.NodeSockets|100%|100%| |Kagaku.Flow.Nodes.SinkDescriptor|100%|| |Kagaku.Flow.Nodes.SocketTypes|100%|100%| |Kagaku.Flow.Nodes.SourceDescriptor|100%|| |Kagaku.Flow.Nodes.TemplateField|100%|| |Kagaku.Flow.Runs.LedgerChange|100%|100%| |Kagaku.Flow.Runs.LedgerTransitions|100%|100%| |Kagaku.Flow.Runs.NodeAttempt|100%|| |Kagaku.Flow.Runs.NodeFacts|100%|| |Kagaku.Flow.Runs.NodeRun|100%|| |Kagaku.Flow.Runs.Run|100%|100%| |Kagaku.Flow.Runs.RunEvent|100%|| |Kagaku.Flow.Runs.RunStatuses|100%|100%| |Kagaku.Flow.Runs.RunTrigger|100%|100%| |Kagaku.Flow.Scheduling.Exclusion|100%|| |Kagaku.Flow.Scheduling.FlowEngine|100%|100%| |Kagaku.Flow.Scheduling.FlowEngineOptions|100%|100%| |Kagaku.Flow.Scheduling.ReadyRow|100%|| |Kagaku.Flow.Scheduling.ReadySet|100%|100%| |Kagaku.Flow.Scheduling.ReadySetResult|100%|| |Kagaku.Flow.Scheduling.RunRequest|100%|100%| |Kagaku.Flow.Scheduling.RunStartResult|100%|| |Kagaku.Flow.Scheduling.SocketValues|100%|100%| |Kagaku.Flow.Templating.InputsWalker|100%|100%| |Kagaku.Flow.Templating.ParsedTemplate|100%|100%| |Kagaku.Flow.Templating.SandboxedTemplateContext|100%|100%| |Kagaku.Flow.Templating.TemplateError|100%|| |Kagaku.Flow.Templating.TemplateHost|100%|100%| |Kagaku.Flow.Templating.TemplateLimits|100%|| |Kagaku.Flow.Templating.TemplateModel|100%|100%| |Kagaku.Flow.Templating.TemplateProblem|100%|| |Kagaku.Flow.Templating.TemplateRenderRequest|100%|100%| |Kagaku.Flow.Templating.TemplateRenderResult|100%|| |Kagaku.Flow.Templating.TemplateRun|100%|| |Kagaku.Flow.Templating.TemplateSinks|100%|| |Kagaku.Flow.Templating.TemplateValues|100%|100%| |Kagaku.Flow.Validation.GraphValidation|100%|100%| |Kagaku.Flow.Validation.GraphValidationContext|100%|| |Kagaku.Flow.Validation.HookFailure|100%|| |Kagaku.Flow.Validation.ResolvedGraph|100%|100%| |Kagaku.Flow.Validation.ValidationError|100%|| |Kagaku.Flow.Validation.ValidationReport|100%|| |System.Text.RegularExpressions.Generated|97.4%|92.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF<br/>E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__ColorToken_2|97.4%|94.4%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF<br/>E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__Socket_1|97.2%|94.4%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6329A328226B0CF<br/>E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__TypeId_0|97.2%|94.4%| </details> <details><summary>Kagaku.Flow.OpenRouter - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow.OpenRouter**|**100%**|**100%**| |Kagaku.Flow.OpenRouter.Catalog.ModelCapabilities|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.LlmCompletion|100%|| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterGateway|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterGatewayOptions|100%|| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterKeyLookup|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.SentRequestCapture|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.SentRequestCaptureHandler|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmAnswer|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmConfig|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmConfigRead|100%|| |Kagaku.Flow.OpenRouter.Llm.LlmDescriptor|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmExecutor|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmFacts|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmFailureText|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmMessage|100%|| |Kagaku.Flow.OpenRouter.Llm.LlmRequestBuilder|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmRequestPlan|100%|| |Kagaku.Flow.OpenRouter.Llm.LlmRoutingDefaults|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmSampling|100%|| |Kagaku.Flow.OpenRouter.Llm.LlmSchemaCheck|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmStrictSchemaRule|100%|100%| |Kagaku.Flow.OpenRouter.Llm.LlmVocabulary|100%|100%| |Kagaku.Flow.OpenRouter.LlmNodeServiceCollectionExtensions|100%|| |Kagaku.Flow.OpenRouter.OpenRouterServiceCollectionExtensions|100%|100%| </details> <details><summary>Kagaku.Flow.Testing - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow.Testing**|**100%**|**100%**| |Kagaku.Flow.Testing.FlowEngineDriver|100%|100%| |Kagaku.Flow.Testing.InMemoryRunLedger|100%|100%| |Kagaku.Flow.Testing.RecordingRunEventSink|100%|| |Kagaku.Flow.Testing.RunLedgerContract|100%|100%| |Kagaku.Flow.Testing.RunLedgerContractException|100%|| </details> <details><summary>Tsumugi.BlazorAdapter - 95.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.BlazorAdapter**|**95.8%**|**91%**| |Tsumugi.BlazorAdapter.BlazorAdapterAssembly|100%|| |Tsumugi.BlazorAdapter.Documents.CategoryCreated|100%|| |Tsumugi.BlazorAdapter.Documents.CategoryEditor|93.2%|88.4%| |Tsumugi.BlazorAdapter.Documents.CategorySaved|100%|| |Tsumugi.BlazorAdapter.Documents.ChangeCategoryFieldsRequested|100%|| |Tsumugi.BlazorAdapter.Documents.CreateCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.CreateDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryChoice|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryDialog|100%|94.1%| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentAutoSaveFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentCreated|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentEditor|95.7%|89.4%| |Tsumugi.BlazorAdapter.Documents.DocumentImageRefused|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentImageSet|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsActionFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentSaved|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsEffects|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsList|98.5%|95%| |Tsumugi.BlazorAdapter.Documents.DocumentsLoaded|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsPage|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsReadFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsReducers|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsRefusal|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsState|100%|100%| |Tsumugi.BlazorAdapter.Documents.FieldInput|100%|96.6%| |Tsumugi.BlazorAdapter.Documents.FieldsChanges|100%|100%| |Tsumugi.BlazorAdapter.Documents.FieldShapes|90%|87.5%| |Tsumugi.BlazorAdapter.Documents.ImageUpload|100%|| |Tsumugi.BlazorAdapter.Documents.ImageUploadRefusal|100%|| |Tsumugi.BlazorAdapter.Documents.ImpactText|100%|94.2%| |Tsumugi.BlazorAdapter.Documents.LoadDocuments|100%|| |Tsumugi.BlazorAdapter.Documents.MoveDocumentChoice|100%|| |Tsumugi.BlazorAdapter.Documents.MoveDocumentDialog|95.6%|71.4%| |Tsumugi.BlazorAdapter.Documents.MoveDocumentsRequested|100%|| |Tsumugi.BlazorAdapter.Documents.ReorderCategoriesRequested|100%|| |Tsumugi.BlazorAdapter.Documents.SetCategoryCollapsed|100%|| |Tsumugi.BlazorAdapter.Documents.SetDocumentImageRequested|100%|| |Tsumugi.BlazorAdapter.Documents.SetDocumentsFilter|100%|| |Tsumugi.BlazorAdapter.Documents.UpdateCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.UpdateDocumentRequested|100%|| |Tsumugi.BlazorAdapter.EffectCalls|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphCanvas|37.5%|25%| |Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage|20%|25%| |Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge|94.4%|83.3%| |Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived|75%|100%| |Tsumugi.BlazorAdapter.Runs.RunChangedBridge|97.1%|90.6%| |Tsumugi.BlazorAdapter.Runs.RunChangesReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextReceived|100%|| |Tsumugi.BlazorAdapter.Settings.BackupFailed|100%|| |Tsumugi.BlazorAdapter.Settings.BackupNowRequested|100%|| |Tsumugi.BlazorAdapter.Settings.BackupSettingsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.BackupsSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsEffects|100%|| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsState|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsEffects|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsState|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaved|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.LoadBackupSettings|100%|| |Tsumugi.BlazorAdapter.Settings.LoadProviderSettings|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed|100%|| |Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaved|100%|| |Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderKeyChecked|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsEffects|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsReducers|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsState|100%|100%| |Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested|100%|| |Tsumugi.BlazorAdapter.Stories.CreateStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.PurgeStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.RestoreStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.SetShowArchived|100%|| |Tsumugi.BlazorAdapter.Stories.SetStoriesFilter|100%|| |Tsumugi.BlazorAdapter.Stories.SetStoryArchivedRequested|100%|| |Tsumugi.BlazorAdapter.Stories.StoriesEffects|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesLoaded|100%|| |Tsumugi.BlazorAdapter.Stories.StoriesPage|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesReducers|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesState|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoryActionFailed|100%|| |Tsumugi.BlazorAdapter.Stories.StoryCreated|100%|| |Tsumugi.BlazorAdapter.Stories.StoryCreateFailed|100%|| |Tsumugi.BlazorAdapter.Stories.StoryTrashPage|100%|100%| |Tsumugi.BlazorAdapter.Stories.TrashStoryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.AckWire|100%|| |Tsumugi.BlazorAdapter.Workspace.AutoSaveFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.ChangedWire|100%|| |Tsumugi.BlazorAdapter.Workspace.ChapterHeader|100%|86.3%| |Tsumugi.BlazorAdapter.Workspace.ChapterMenu|100%|81.2%| |Tsumugi.BlazorAdapter.Workspace.ChapterPage|100%|87.5%| |Tsumugi.BlazorAdapter.Workspace.ChapterSaved|100%|| |Tsumugi.BlazorAdapter.Workspace.ChaptersPage|94.4%|83.3%| |Tsumugi.BlazorAdapter.Workspace.ChapterWire|100%|| |Tsumugi.BlazorAdapter.Workspace.ChapterWritten|100%|| |Tsumugi.BlazorAdapter.Workspace.CreateChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.CreatedWire|100%|| |Tsumugi.BlazorAdapter.Workspace.DeleteChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.DeltaWire|100%|| |Tsumugi.BlazorAdapter.Workspace.HistoryEffects|100%|100%| |Tsumugi.BlazorAdapter.Workspace.HistoryLoaded|100%|| |Tsumugi.BlazorAdapter.Workspace.HistoryPage|100%|| |Tsumugi.BlazorAdapter.Workspace.HistoryPanel|100%|100%| |Tsumugi.BlazorAdapter.Workspace.HistoryReadFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.LoadHistory|100%|| |Tsumugi.BlazorAdapter.Workspace.LoadWorkspace|100%|| |Tsumugi.BlazorAdapter.Workspace.ManuscriptEffects|100%|100%| |Tsumugi.BlazorAdapter.Workspace.ManuscriptEvents|81.8%|74.1%| |Tsumugi.BlazorAdapter.Workspace.ManuscriptSurface|89.8%|87.1%| |Tsumugi.BlazorAdapter.Workspace.MergeChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.MergeEvent|100%|| |Tsumugi.BlazorAdapter.Workspace.MoveChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RedoRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RedoRevertRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RenameChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.ReshapeEvent|100%|| |Tsumugi.BlazorAdapter.Workspace.RevertToSnapshotRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SaveScope|100%|50%| |Tsumugi.BlazorAdapter.Workspace.SaveStateLadder|100%|100%| |Tsumugi.BlazorAdapter.Workspace.SaveVersionRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SegmentTextEvent|100%|| |Tsumugi.BlazorAdapter.Workspace.SegmentWire|100%|81.8%| |Tsumugi.BlazorAdapter.Workspace.SelectionEndWire|100%|| |Tsumugi.BlazorAdapter.Workspace.SelectionGraph|100%|| |Tsumugi.BlazorAdapter.Workspace.SelectionRangeWire|100%|| |Tsumugi.BlazorAdapter.Workspace.SelectionRunRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SetChapterSummaryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SplitEvent|100%|| |Tsumugi.BlazorAdapter.Workspace.StampWire|0%|| |Tsumugi.BlazorAdapter.Workspace.StoryDetails|100%|85.2%| |Tsumugi.BlazorAdapter.Workspace.StoryGeneralPage|100%|100%| |Tsumugi.BlazorAdapter.Workspace.StorySaved|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryShell|100%|100%| |Tsumugi.BlazorAdapter.Workspace.UndoRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.UndoStatusChanged|100%|| |Tsumugi.BlazorAdapter.Workspace.UpdateStoryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceActionFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceLoaded|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceNotFound|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceReducers|100%|100%| |Tsumugi.BlazorAdapter.Workspace.WorkspaceState|100%|| </details> <details><summary>Tsumugi.Domain - 96.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Domain**|**96.3%**|**95%**| |System.Text.RegularExpressions.Generated|91.3%|88.6%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__DigitsAndSeparators_2|97.4%|95.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__LineBreak_0|91%|91.1%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__NumberToken_1|91.8%|83.3%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__Plain_4|91.9%|88.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F5BB471BFAD87E25<br/>BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__ThousandsGroup_3|90.9%|84.3%| |Tsumugi.Domain.Documents.CategoryFields|94.5%|93.7%| |Tsumugi.Domain.Documents.ChoiceOption|100%|| |Tsumugi.Domain.Documents.ChoiceValue|100%|| |Tsumugi.Domain.Documents.DateText|100%|| |Tsumugi.Domain.Documents.DateValue|100%|| |Tsumugi.Domain.Documents.Document|100%|100%| |Tsumugi.Domain.Documents.DocumentCategory|100%|100%| |Tsumugi.Domain.Documents.DocumentValues|100%|| |Tsumugi.Domain.Documents.FieldCarry|100%|100%| |Tsumugi.Domain.Documents.FieldConversion|100%|100%| |Tsumugi.Domain.Documents.FieldDefinition|97%|95.3%| |Tsumugi.Domain.Documents.FieldMessages|100%|100%| |Tsumugi.Domain.Documents.FieldNames|100%|| |Tsumugi.Domain.Documents.FieldsChange|100%|| |Tsumugi.Domain.Documents.FieldShape|95.2%|87.5%| |Tsumugi.Domain.Documents.FieldsPlan|100%|| |Tsumugi.Domain.Documents.FieldsPlanner|99.2%|99.2%| |Tsumugi.Domain.Documents.FieldValue|100%|| |Tsumugi.Domain.Documents.FieldValues|95.4%|97.7%| |Tsumugi.Domain.Documents.ImageFiles|100%|100%| |Tsumugi.Domain.Documents.ImageValue|100%|| |Tsumugi.Domain.Documents.MovePlan|100%|| |Tsumugi.Domain.Documents.NumberParse|100%|| |Tsumugi.Domain.Documents.NumberText|100%|97.6%| |Tsumugi.Domain.Documents.NumberValue|100%|| |Tsumugi.Domain.Documents.StoryImage|100%|| |Tsumugi.Domain.Documents.TextValue|100%|100%| |Tsumugi.Domain.Documents.ValueChange|100%|| |Tsumugi.Domain.Documents.ValueChangeKey|100%|| |Tsumugi.Domain.Documents.ValueImpact|100%|100%| |Tsumugi.Domain.Journal.ChangeLogEntry|97.9%|83.3%| |Tsumugi.Domain.Journal.StorySnapshot|95.4%|83.3%| |Tsumugi.Domain.Settings.AppSetting|100%|| |Tsumugi.Domain.Stories.Chapter|100%|100%| |Tsumugi.Domain.Stories.InlineMarkup|100%|100%| |Tsumugi.Domain.Stories.MarkupRun|100%|| |Tsumugi.Domain.Stories.Provenance|100%|100%| |Tsumugi.Domain.Stories.Segment|100%|100%| |Tsumugi.Domain.Stories.Story|100%|100%| |Tsumugi.Domain.Text|100%|100%| </details> <details><summary>Tsumugi.Infrastructure - 98.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Infrastructure**|**98.3%**|**86.8%**| |System.Text.RegularExpressions.Generated|81.4%|64.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F0D076C66E8EEC1C<br/>A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0|84%|65.7%| |Tsumugi.Infrastructure.Backups.BackupArtifactName|100%|100%| |Tsumugi.Infrastructure.Backups.BackupOptions|100%|| |Tsumugi.Infrastructure.Backups.BackupSchedule|100%|83.3%| |Tsumugi.Infrastructure.Backups.BackupScheduler|96.6%|87.5%| |Tsumugi.Infrastructure.Backups.BackupWriter|98.5%|92.8%| |Tsumugi.Infrastructure.Backups.DatabaseFingerprint|91.9%|97%| |Tsumugi.Infrastructure.Backups.FileSystemBackupStore|100%|100%| |Tsumugi.Infrastructure.Backups.OwnerOnlyFile|100%|100%| |Tsumugi.Infrastructure.Backups.PreMigrationBackup|90%|100%| |Tsumugi.Infrastructure.Backups.SqliteSnapshot|88.2%|75%| |Tsumugi.Infrastructure.DependencyInjection|100%|100%| |Tsumugi.Infrastructure.Journal.EfChangeJournal|100%|| |Tsumugi.Infrastructure.Journal.EfSnapshotStore|100%|| |Tsumugi.Infrastructure.Journal.EfUndoStore|98.5%|88.2%| |Tsumugi.Infrastructure.Journal.ModelExtensions|100%|| |Tsumugi.Infrastructure.Journal.OperationContext|100%|100%| |Tsumugi.Infrastructure.Journal.PropertyBag|100%|95.4%| |Tsumugi.Infrastructure.Notifications.InProcessDomainChangedBus|100%|100%| |Tsumugi.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.ChangeLogEntryConfigurati<br/>on|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.ChapterConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.DocumentCategoryConfigura<br/>tion|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.DocumentConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.SegmentConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StoryConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StoryImageConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StorySnapshotConfiguratio<br/>n|100%|| |Tsumugi.Infrastructure.Persistence.Converters.CanonicalJsonComparer|100%|| |Tsumugi.Infrastructure.Persistence.Converters.CategoryFieldsConverter|97.6%|94.4%| |Tsumugi.Infrastructure.Persistence.Converters.FieldValuesConverter|96.9%|93.7%| |Tsumugi.Infrastructure.Persistence.Converters.ProvenanceConverter|100%|90%| |Tsumugi.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Tsumugi.Infrastructure.Persistence.Converters.WireFormat|85.7%|73.8%| |Tsumugi.Infrastructure.Persistence.Migrations.AddAppSettings|99.2%|| |Tsumugi.Infrastructure.Persistence.Migrations.AddJournal|98.8%|| |Tsumugi.Infrastructure.Persistence.Migrations.CategoryFields|100%|100%| |Tsumugi.Infrastructure.Persistence.Migrations.CategoryFieldsSql|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.DropDocumentBody|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.GenericDocuments|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain|97.3%|| |Tsumugi.Infrastructure.Persistence.Migrations.JournalUndoState|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.SegmentTextMarkup|100%|100%| |Tsumugi.Infrastructure.Persistence.Migrations.SegmentTextMarkupSql|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.StoryImages|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.TsumugiDbContextModelSnapshot|100%|| |Tsumugi.Infrastructure.Persistence.SqliteFunctions|80%|66.6%| |Tsumugi.Infrastructure.Persistence.SqlitePragmaInterceptor|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfChapterStore|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfDocumentStore|98.3%|75%| |Tsumugi.Infrastructure.Persistence.Stores.EfImageStore|100%|| |Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore|96.6%|84.6%| |Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore|98.7%|90%| |Tsumugi.Infrastructure.Persistence.TsumugiDbContext|97.7%|96.6%| |Tsumugi.Infrastructure.Persistence.TsumugiDbContextFactory|100%|| |Tsumugi.Infrastructure.Provider.LlmDefaultsSource|100%|| |Tsumugi.Infrastructure.Provider.OpenRouterKeySource|100%|100%| |Tsumugi.Infrastructure.Provider.OpenRouterModelProvider|100%|100%| |Tsumugi.Infrastructure.Provider.OpenRouterOptions|100%|100%| |Tsumugi.Infrastructure.Provider.ResolvedKey|100%|| |Tsumugi.Infrastructure.Runs.InProcessRunEventBus|100%|100%| |Tsumugi.Infrastructure.Settings.EfAppSettingsStore|100%|100%| </details> <details><summary>Tsumugi.Kernel - 90.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Kernel**|**90.9%**|**75%**| |Tsumugi.Kernel.Err`1|100%|| |Tsumugi.Kernel.Ok`1|100%|| |Tsumugi.Kernel.Result`1|88.8%|75%| </details> <details><summary>Tsumugi.Server - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Server**|**100%**|**92.1%**| |Program|100%|100%| |Tsumugi.Server.Backups.BackupConfiguration|100%|100%| |Tsumugi.Server.Components.App|100%|| |Tsumugi.Server.Components.Layout.AppHeader|100%|50%| |Tsumugi.Server.Components.Layout.MainLayout|100%|| |Tsumugi.Server.Components.Pages.Gate|100%|100%| |Tsumugi.Server.Provider.OpenRouterConfiguration|100%|100%| |Tsumugi.Server.Security.AccessGate|100%|87.5%| |Tsumugi.Server.Security.AccessSecret|100%|100%| |Tsumugi.Server.Security.GateThrottle|100%|100%| |Tsumugi.Server.VolumeStartupValidator|100%|100%| </details> <details><summary>Tsumugi.UseCases - 98.8%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.UseCases**|**98.8%**|**96.4%**| |Tsumugi.UseCases.Backups.BackupArtifact|100%|| |Tsumugi.UseCases.Backups.BackupFailure|100%|| |Tsumugi.UseCases.Backups.BackupJobState|100%|| |Tsumugi.UseCases.Backups.BackupPolicy|100%|| |Tsumugi.UseCases.Backups.BackupStatusView|100%|100%| |Tsumugi.UseCases.Backups.DatabaseSnapshot|100%|| |Tsumugi.UseCases.Backups.DownloadDatabaseSnapshot|100%|| |Tsumugi.UseCases.Backups.GetBackupStatus|100%|| |Tsumugi.UseCases.Backups.IBackupStore|0%|| |Tsumugi.UseCases.Backups.RunBackupNow|100%|| |Tsumugi.UseCases.Chapters.ChapterDto|100%|| |Tsumugi.UseCases.Chapters.CreateChapter|100%|100%| |Tsumugi.UseCases.Chapters.DeleteChapter|100%|100%| |Tsumugi.UseCases.Chapters.GetChapterSegments|100%|| |Tsumugi.UseCases.Chapters.GetManuscript|100%|100%| |Tsumugi.UseCases.Chapters.ManuscriptChapter|100%|| |Tsumugi.UseCases.Chapters.ManuscriptView|100%|| |Tsumugi.UseCases.Chapters.MergeChapters|100%|100%| |Tsumugi.UseCases.Chapters.RenameChapter|100%|100%| |Tsumugi.UseCases.Chapters.ReorderChapters|100%|100%| |Tsumugi.UseCases.Chapters.SetChapterSummary|100%|75%| |Tsumugi.UseCases.Context.DocumentRendering|100%|100%| |Tsumugi.UseCases.Context.StoryDocumentsRule|100%|100%| |Tsumugi.UseCases.Context.StoryReads|100%|100%| |Tsumugi.UseCases.Context.StoryScope|100%|100%| |Tsumugi.UseCases.Context.StoryTemplateModel|100%|| |Tsumugi.UseCases.DependencyInjection|100%|| |Tsumugi.UseCases.Diagnostics.SeedDevData|98.3%|68.7%| |Tsumugi.UseCases.Diagnostics.SeedPictures|100%|| |Tsumugi.UseCases.Documents.ChangeCategoryFields|100%|83.3%| |Tsumugi.UseCases.Documents.CreateCategory|100%|100%| |Tsumugi.UseCases.Documents.CreateDocument|100%|100%| |Tsumugi.UseCases.Documents.DefaultFields|100%|100%| |Tsumugi.UseCases.Documents.DeleteCategory|100%|94.4%| |Tsumugi.UseCases.Documents.DeleteDocument|100%|100%| |Tsumugi.UseCases.Documents.DocumentCategoryDto|100%|| |Tsumugi.UseCases.Documents.DocumentCategoryProfile|100%|| |Tsumugi.UseCases.Documents.DocumentDto|100%|| |Tsumugi.UseCases.Documents.DocumentPatch|100%|| |Tsumugi.UseCases.Documents.DocumentProfile|100%|| |Tsumugi.UseCases.Documents.DocumentsCategory|100%|| |Tsumugi.UseCases.Documents.DocumentsView|100%|| |Tsumugi.UseCases.Documents.DocumentWrites|100%|100%| |Tsumugi.UseCases.Documents.FieldsChangeLabel|95.4%|88.2%| |Tsumugi.UseCases.Documents.GetDocuments|100%|100%| |Tsumugi.UseCases.Documents.GetStoryImage|100%|100%| |Tsumugi.UseCases.Documents.ImpactPreview|100%|100%| |Tsumugi.UseCases.Documents.LossMessages|92.3%|87.5%| |Tsumugi.UseCases.Documents.MoveDocuments|100%|100%| |Tsumugi.UseCases.Documents.ReorderCategories|100%|100%| |Tsumugi.UseCases.Documents.SetDocumentImage|100%|93.7%| |Tsumugi.UseCases.Documents.StoryImageFile|100%|| |Tsumugi.UseCases.Documents.UpdateCategory|100%|100%| |Tsumugi.UseCases.Documents.UpdateDocument|100%|81.2%| |Tsumugi.UseCases.Documents.WriteRefusedException|100%|| |Tsumugi.UseCases.Journal.GetStoryHistory|100%|100%| |Tsumugi.UseCases.Journal.GetUndoStatus|100%|100%| |Tsumugi.UseCases.Journal.HistoryOperation|66.6%|| |Tsumugi.UseCases.Journal.HistorySnapshot|87.5%|| |Tsumugi.UseCases.Journal.OperationGrouping|100%|100%| |Tsumugi.UseCases.Journal.RedoRevert|100%|100%| |Tsumugi.UseCases.Journal.RedoRun|90.9%|87.5%| |Tsumugi.UseCases.Journal.RedoTyping|100%|100%| |Tsumugi.UseCases.Journal.ReplayLanding|100%|100%| |Tsumugi.UseCases.Journal.RevertConflict|100%|| |Tsumugi.UseCases.Journal.RevertOutcome|100%|| |Tsumugi.UseCases.Journal.RevertRun|96.5%|77.7%| |Tsumugi.UseCases.Journal.RevertToSnapshot|92.3%|83.3%| |Tsumugi.UseCases.Journal.StoryHistory|100%|| |Tsumugi.UseCases.Journal.TakeSnapshot|100%|87.5%| |Tsumugi.UseCases.Journal.UndoStatus|100%|| |Tsumugi.UseCases.Journal.UndoTyping|100%|100%| |Tsumugi.UseCases.Journal.UserOperation|100%|| |Tsumugi.UseCases.Notifications.DomainChanged|100%|| |Tsumugi.UseCases.Ordering|100%|100%| |Tsumugi.UseCases.Runs.RunEvent|100%|| |Tsumugi.UseCases.Segments.ChangedText|100%|| |Tsumugi.UseCases.Segments.ChapterDraft|100%|| |Tsumugi.UseCases.Segments.ChapterWriting|100%|| |Tsumugi.UseCases.Segments.DeleteSegments|100%|100%| |Tsumugi.UseCases.Segments.EditSegment|100%|100%| |Tsumugi.UseCases.Segments.InsertSegment|100%|100%| |Tsumugi.UseCases.Segments.ManuscriptAnswer|100%|| |Tsumugi.UseCases.Segments.ManuscriptWrites|99.1%|97.6%| |Tsumugi.UseCases.Segments.MergeSegments|100%|| |Tsumugi.UseCases.Segments.MergeWrite|100%|| |Tsumugi.UseCases.Segments.ModelOutput|98.2%|96.6%| |Tsumugi.UseCases.Segments.ModelParagraph|100%|| |Tsumugi.UseCases.Segments.MoveSegments|100%|100%| |Tsumugi.UseCases.Segments.NewBlock|100%|| |Tsumugi.UseCases.Segments.ReadSelection|100%|| |Tsumugi.UseCases.Segments.ReorderSegments|100%|100%| |Tsumugi.UseCases.Segments.ReshapeSegments|100%|100%| |Tsumugi.UseCases.Segments.ReshapeWrite|100%|| |Tsumugi.UseCases.Segments.SegmentDto|100%|| |Tsumugi.UseCases.Segments.SelectedSegment|100%|| |Tsumugi.UseCases.Segments.SelectionEnd|100%|| |Tsumugi.UseCases.Segments.SelectionInput|100%|100%| |Tsumugi.UseCases.Segments.SplitSegment|100%|| |Tsumugi.UseCases.Segments.SplitWrite|100%|| |Tsumugi.UseCases.Segments.StampedId|100%|| |Tsumugi.UseCases.Segments.TextWrite|100%|| |Tsumugi.UseCases.Settings.CatalogModel|100%|100%| |Tsumugi.UseCases.Settings.CheckOpenRouterKey|100%|| |Tsumugi.UseCases.Settings.GetLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.GetModelCatalog|100%|100%| |Tsumugi.UseCases.Settings.GetProviderSettings|100%|| |Tsumugi.UseCases.Settings.LlmDefaults|100%|| |Tsumugi.UseCases.Settings.ProviderKeyInfo|100%|| |Tsumugi.UseCases.Settings.ProviderKeyState|100%|| |Tsumugi.UseCases.Settings.ProviderSettingsView|100%|100%| |Tsumugi.UseCases.Settings.ReasoningEfforts|100%|100%| |Tsumugi.UseCases.Settings.RemoveOpenRouterKey|100%|| |Tsumugi.UseCases.Settings.RoutingDefaults|100%|| |Tsumugi.UseCases.Settings.RoutingSettings|100%|100%| |Tsumugi.UseCases.Settings.SaveLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Tsumugi.UseCases.Stories.ChapterWriteOutcome|50%|| |Tsumugi.UseCases.Stories.CreateStory|100%|100%| |Tsumugi.UseCases.Stories.GetStory|100%|100%| |Tsumugi.UseCases.Stories.ListStories|100%|75%| |Tsumugi.UseCases.Stories.PurgeStory|100%|100%| |Tsumugi.UseCases.Stories.RestoreStory|100%|100%| |Tsumugi.UseCases.Stories.SetActiveGraph|100%|100%| |Tsumugi.UseCases.Stories.SetStoryArchived|100%|100%| |Tsumugi.UseCases.Stories.StarterCategories|100%|| |Tsumugi.UseCases.Stories.StoryDetail|100%|| |Tsumugi.UseCases.Stories.StoryListItem|81.8%|| |Tsumugi.UseCases.Stories.StoryProfile|100%|| |Tsumugi.UseCases.Stories.TrashStory|100%|100%| |Tsumugi.UseCases.Stories.UpdateStory|100%|100%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Four commits, +1792/−93, thirty-one files — and every single one of them an effect learning the same lesson #55 taught the documents: a page must never be left holding a request its use case abandoned. This is my favorite kind of PR, fufu~ — one idea, applied everywhere, with the symmetry actually thought through instead of assumed. I read every changed source file in full, traced every settle against its handler's own Err arm, and then I got to prove things. ♪

Verdict: ✅ Looks good to me~

The architecture, verified branch by branch:

  • EffectCalls.CallAsync — the lift from DocumentsEffects is byte-faithful to #55's helper: catch → dispatch the request's own refusal → throw; so the original exception (and its stack) still reaches the circuit's containment. Bare catch, not catch (Exception) — correct under the repo's conventions, and the class doc ties it to ADR 0011 properly. Both throwing arms are pinned, including the sneaky throws-before-returning-a-task one.
  • Every settle copies its own Err arm. Manuscript saves → AutoSaveFailed; create → WorkspaceActionFailed; History's three requests → hedged words that honestly don't know whether the write landed; Settings per-tab refusals; the Provider load's refused-check carrying that load's Read id. I checked each one against its sibling refusal — no orphan records, no wrong-tab words. The OpenRouterKeyRemoveFailed doc hedging (whether the key went is not known) is exactly the right honesty given EfAppSettingsStore's tracker behavior — nicely caught by your reviewers and correctly scoped as a store-level follow-up.
  • ChapterSaved no longer carries the undo status — dispatched first, UndoStatusChanged from its own read, exactly the DocumentSaved shape. And the reducer leaves Undo alone (Assert.Same pin). The save-that-lands-whose-undo-read-throws window is properly closed: indicator says Saved, Undo at worst a step behind. ♡
  • The finally around the navigate in OnCreateChapterAsync — a create that lands whose reload throws still opens the chapter it made. That's the correct reading of "the chapter exists," and it has its own dedicated pin.
  • HistoryReadFailed honors the staleness rule (StoryId guard), keeps History and Error, claims no refusal — and the reducer fact pins both the flag-clearing and the stale-story drop.
  • Not-wrapped is pinned, not asserted: move/merge/delete/undo/redo and the Stories row actions have tests asserting they claim no refusal when the store fails. The symmetry argument ("holds nothing → nothing to free") is itself under test. Fufu, that's the difference between a claim and a contract~

Mechanical verification (CI absent for c7eb653, PR minutes old at fetch): clone pristine at head, submodules pinned. Release build 0 warnings / 0 errors; BlazorAdapter 528/528 (digit-exact vs your body, three-run claim honored by my re-runs); Integration 556/556; the StoreFailure/EffectCalls filter 82/82. Tree pristine at head after everything (git diff --quiet).

My mutation probes — 8 compiled mutants, every one killed on exactly its own pins, each restore verified:

Mutant Killed by
rethrow swallowed (return default!) both throw-arm pins in EffectCallsTests
settle never dispatched both throw-arm pins
catch narrowed to IOException exactly the non-IO removal arm
create-navigate out of the finally exactly …whose_reload_throws_still_opens…
HistoryReadFailed keeps HistoryBusy both its reducer + page pins
staleness guard dropped exactly the stale-story arm
OnChapterSaved resets Undo (WR2) the Assert.Same fact + the page's Undo-still-enabled check
backup re-read unwrapped both …re_read_throws… pins

Two harness traps caught mid-run, both mine: a src-only rebuild + --no-build silently tested the stale pristine DLL (false green), and one probe failed to compile and "passed" the same way. Every probe above was re-run with a test-project rebuild and an md5 check that the DLL the tests loaded actually carried the mutant. Never trust a green you didn't watch turn red, fufu~

The MS15/WR2 fixes from your independent reviewers are real, not cosmetic: the journaled-edit theory (A_saved_title_or_summary_is_followed_by_what_Ctrl_Z_would_do_now) kills the dispatch-the-constant mutant on both rows, and my reducer-level WR2 mutant died on exactly the two new pins. Your 80-of-82 probe record plus my 8-of-8 gives me everything I need.

💡 Little ideas (non-blocking, both already on your follow-up list — agreed they're out of this arc's paths)~

  1. ManuscriptSurface.razor reads the undo status before ChapterWritten — same shape as the ChapterSaved fix; it belongs to the editor track as you say. When it lands, it gets this same treatment, yes? ♡
  2. The first-load loading lines (StoryShell, HistoryPanel, the Stories list) still hang on a throwing first read — a razor change, correctly out of scope here.

✅ What I liked~

  • The honesty gradient in the words: hedged where a write's landing is unknown ("may not have been saved"), specific where the refusal is the store's own record — and HistoryReadFailed claiming nothing rather than borrowing a refusal's words. That's careful.
  • The fake-seam discipline: Fail switches on the fakes where the store would fail outright, decorators (FailingUndoStore, FailingSnapshotReads) only where a subset of operations must throw — FakeUndoStore.cs and FakeChangeJournal.cs untouched, as promised.
  • BackupCompleted losing its payload so the re-read can't be smuggled through the completion action — smaller surface, honest sequencing, and the reducer comment says exactly why.

No ADR amended, and I agree: none mentions what a request does when its use case throws, and #55 already noted the gap. The follow-ups are real, named, and correctly outside these paths.

Ready to merge. Come back with the ManuscriptSurface one soon — I'll be waiting~ fufu ♡


Automated review by Jibril · 2026-09-26
CI/CD: absent for head SHA c7eb653 · Local checks: Release 0w/0e · BlazorAdapter 528/528 · Integration 556/556 · 8/8 mutation probes killed

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! Four commits, +1792/−93, thirty-one files — and every single one of them an effect learning the same lesson #55 taught the documents: *a page must never be left holding a request its use case abandoned*. This is my favorite kind of PR, fufu~ — one idea, applied everywhere, with the symmetry actually thought through instead of assumed. I read every changed source file in full, traced every settle against its handler's own `Err` arm, and then I got to *prove things*. ♪ ### Verdict: ✅ Looks good to me~ **The architecture, verified branch by branch:** - **`EffectCalls.CallAsync`** — the lift from `DocumentsEffects` is byte-faithful to #55's helper: `catch` → dispatch the request's own refusal → `throw;` so the original exception (and its stack) still reaches the circuit's containment. Bare `catch`, not `catch (Exception)` — correct under the repo's conventions, and the class doc ties it to ADR 0011 properly. Both throwing arms are pinned, including the sneaky *throws-before-returning-a-task* one. - **Every settle copies its own `Err` arm.** Manuscript saves → `AutoSaveFailed`; create → `WorkspaceActionFailed`; History's three requests → hedged words that honestly don't know whether the write landed; Settings per-tab refusals; the Provider load's refused-check carrying that load's `Read` id. I checked each one against its sibling refusal — no orphan records, no wrong-tab words. The `OpenRouterKeyRemoveFailed` doc hedging (*whether the key went is not known*) is exactly the right honesty given `EfAppSettingsStore`'s tracker behavior — nicely caught by your reviewers and correctly scoped as a store-level follow-up. - **`ChapterSaved` no longer carries the undo status** — dispatched first, `UndoStatusChanged` from its own read, exactly the `DocumentSaved` shape. And the reducer leaves `Undo` alone (Assert.Same pin). The save-that-lands-whose-undo-read-throws window is properly closed: indicator says Saved, Undo at worst a step behind. ♡ - **The `finally` around the navigate in `OnCreateChapterAsync`** — a create that lands whose reload throws *still opens the chapter it made*. That's the correct reading of "the chapter exists," and it has its own dedicated pin. - **`HistoryReadFailed`** honors the staleness rule (`StoryId` guard), keeps `History` and `Error`, claims no refusal — and the reducer fact pins *both* the flag-clearing and the stale-story drop. - **Not-wrapped is pinned, not asserted**: move/merge/delete/undo/redo and the Stories row actions have tests asserting they claim *no* refusal when the store fails. The symmetry argument ("holds nothing → nothing to free") is itself under test. Fufu, that's the difference between a claim and a contract~ **Mechanical verification** (CI absent for `c7eb653`, PR minutes old at fetch): clone pristine at head, submodules pinned. Release build **0 warnings / 0 errors**; BlazorAdapter **528/528** (digit-exact vs your body, three-run claim honored by my re-runs); Integration **556/556**; the StoreFailure/EffectCalls filter 82/82. Tree pristine at head after everything (`git diff --quiet`). **My mutation probes — 8 compiled mutants, every one killed on exactly its own pins, each restore verified:** | Mutant | Killed by | |---|---| | rethrow swallowed (`return default!`) | both throw-arm pins in `EffectCallsTests` | | settle never dispatched | both throw-arm pins | | `catch` narrowed to `IOException` | exactly the non-IO removal arm | | create-navigate out of the `finally` | exactly `…whose_reload_throws_still_opens…` | | `HistoryReadFailed` keeps `HistoryBusy` | both its reducer + page pins | | staleness guard dropped | exactly the stale-story arm | | `OnChapterSaved` resets `Undo` (WR2) | the Assert.Same fact + the page's Undo-still-enabled check | | backup re-read unwrapped | both `…re_read_throws…` pins | Two harness traps caught mid-run, both mine: a src-only rebuild + `--no-build` silently tested the *stale pristine* DLL (false green), and one probe failed to compile and "passed" the same way. Every probe above was re-run with a test-project rebuild and an md5 check that the DLL the tests loaded actually carried the mutant. Never trust a green you didn't watch turn red, fufu~ The MS15/WR2 fixes from your independent reviewers are real, not cosmetic: the journaled-edit theory (`A_saved_title_or_summary_is_followed_by_what_Ctrl_Z_would_do_now`) kills the dispatch-the-constant mutant on both rows, and my reducer-level WR2 mutant died on exactly the two new pins. Your 80-of-82 probe record plus my 8-of-8 gives me everything I need. #### 💡 Little ideas (non-blocking, both already on your follow-up list — agreed they're out of this arc's paths)~ 1. **`ManuscriptSurface.razor` reads the undo status before `ChapterWritten`** — same shape as the `ChapterSaved` fix; it belongs to the editor track as you say. When it lands, it gets this same treatment, yes? ♡ 2. **The first-load loading lines** (StoryShell, HistoryPanel, the Stories list) still hang on a throwing first read — a razor change, correctly out of scope here. #### ✅ What I liked~ - The honesty gradient in the words: hedged where a write's landing is unknown ("may not have been saved"), specific where the refusal is the store's own record — and `HistoryReadFailed` claiming *nothing* rather than borrowing a refusal's words. That's careful. - The fake-seam discipline: `Fail` switches on the fakes where the store would fail outright, decorators (`FailingUndoStore`, `FailingSnapshotReads`) only where a *subset* of operations must throw — `FakeUndoStore.cs` and `FakeChangeJournal.cs` untouched, as promised. - `BackupCompleted` losing its payload so the re-read can't be smuggled through the completion action — smaller surface, honest sequencing, and the reducer comment says exactly why. No ADR amended, and I agree: none mentions what a request does when its use case throws, and #55 already noted the gap. The follow-ups are real, named, and correctly outside these paths. Ready to merge. Come back with the ManuscriptSurface one soon — I'll be waiting~ fufu ♡ --- *Automated review by Jibril · 2026-09-26* *CI/CD: absent for head SHA c7eb653 · Local checks: Release 0w/0e · BlazorAdapter 528/528 · Integration 556/556 · 8/8 mutation probes killed*
bjoern merged commit dad9dcf03f into main 2026-09-26 20:41:52 +02:00
bjoern deleted branch fix/effects-settle-everywhere 2026-09-26 20:41:53 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 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/Tsumugi!62
No description provided.