feat(runs): runs start, cancel and retry — the use cases, run snapshots as runs settle, a trash that stops the story's run, the seeded runs (slice 11b) #70

Merged
bjoern merged 5 commits from feat/runs-start into main 2026-10-03 07:40:07 +02:00
Member

Slice 11b of Phase 2 (docs/PROJECT_PLAN.md): runs start, cancel and retry. A story's runs now start, cancel and retry through use cases over the engine (ADR 0016), and each finished run gets its one run snapshot (ADR 0022). No UI yet: the plan splits the old 11b line, and the Runs section is 11c.

What lands

  • The run use cases.
    • StartRun(story, chapter?):
      • Refused first, with nothing written: what the engine cannot know — a story gone or in the trash, no graph, a graph in the trash, a chapter gone or another story's — and a story whose run is still going.
      • Then: a before-run snapshot of the writer's edits under the run's id ("Your edits"). The engine starts the active graph as it stands, the run's own copy.
      • The target chapter: always persisted in the trigger envelope (ADR 0012). It is the chapter the run starts from, else the story's last at the start, so a chapter added while the run streams is not its target.
      • The engine's own refusals are named; the snapshot taken stays. They are a graph that does not load, has no node or has problems, and a run started in between.
    • CancelRun(run): the engine's cancel, which drains before it answers.
    • RetryRun(step): a failed step, as the inspector will ask it.
      • The engine's refusals are read ahead, before any snapshot: a step gone, a story in the trash, a cancelled run, a step that has not failed, another run going.
      • A before-run snapshot comes first, except for a run that is itself still going: since its start, its writes and the writer's have interleaved.
  • Run snapshots.
    • TakeRunSnapshot(run) always takes a succeeded run's snapshot, and a failed or cancelled run's only when it wrote. It sits at the story's latest position. Its label names the graph, the outcome when the run did not succeed, and its operations in journal order ("Continue: Commit appended 2 paragraphs").
    • Taking it twice changes nothing and announces nothing.
    • A finish after a Retry moves the snapshot to the latest position when the run wrote past it; otherwise it relabels it where it stands.
    • One take at a time (RunSnapshotGate), so two callers never both add one.
    • ISnapshotStore.MoveAsync and StorySnapshot.MoveTo carry the move.
  • The snapshots' host.
    • RunSnapshotsHost takes each run's snapshot as it settles. It subscribes before it reconciles, at its start, every finished run; a finish the last process missed gets its snapshot then.
    • It is registered before the engine's host. Its stop unsubscribes, and the stop's cancellation ends its loop.
    • IRunHistory (EF) lists the finished runs, and a story's runs whose last finish no snapshot has taken.
  • The trash stops the story's run.
    • TrashStory first cancels and drains the story's live run (ILiveRuns over the engine).
    • It then takes every finish still owed: the cancelled run's, one still in the host's queue, one a Retry finished again.
    • So a purge never deletes ledger rows under an execution, and no run snapshot sits after the trash row.
  • The seeded runs. They are checked field by field against runs of the real engine and gateway (over a scripted HTTP handler) on the seeded world.
    • A Continue run that wrote the sample paragraphs:
      • its context and the context node's report;
      • the writer's request exactly as the gateway sends it, in the run's session, with its routing, size and cost;
      • the commit's landing and report;
      • its run snapshot, through TakeRunSnapshot.
    • A later run whose writer timed out three times:
      • each error is in the llm node's words, the last one numbered as the engine numbers it;
      • its context node learned the ratio from the first run's request;
      • it wrote nothing, so it has no snapshot.
  • Docs. ADR 0016 and 0022 are amended (slice 11b; this PR's number added in 0ae2ca5). The plan's 11b line is split into 11b and 11c; the run history's cost columns stay with slice 14, now after 11c.

Decisions

Question Decision Why
The target chapter Always in the trigger, the last chapter when none is given. ADR 0012: the run writes where it started from. A chapter added mid-run must not become the target.
Refusals and the before-run snapshot Read every refusal the use case can know before the snapshot; the engine asks again under its gate. A refusal must never file a live run's writes as the writer's edits. A refusal the engine alone meets keeps the snapshot, which marks the writer's own edits.
A retry of a run still going No "Your edits" snapshot. Its writes and the writer's have interleaved since its start; no snapshot can separate them.
Concurrent takes A singleton semaphore around the whole take. The host and a trash take the same cancelled run. In round 0's probe, 10 and then 7 of 20 trashes left two run snapshots; with the gate, the second pass's probe saw one in each of 20.
Position The story's latest journal position; a relabel in place when only the outcome changed. ADR 0022's run snapshot marks the story as the run left it; a Retry that wrote more moves it.
A finish the host has not taken at a trash The trash takes every finish still owed before its own row. Otherwise the snapshot lands after the trash row, and Revert to here on it would put the story back in the trash.
The seed's window 128,000 tokens. A seed cannot know the catalog's; everything else matches a real run.

Tests

Project main branch
Tsumugi.Domain.Tests 512 517
Kagaku.Flow.Tests 1103 1103
Kagaku.Flow.OpenRouter.Tests 596 (4 skipped, live) 596 (4 skipped, live)
Tsumugi.BlazorAdapter.Tests 595 595
Tsumugi.UseCases.Tests 427 427
Tsumugi.Integration.Tests 745 799

BlazorAdapter changes only test doubles here (NoLiveRuns, MoveAsync on the fake stores). It hit one 15 s bUnit wait in 3 of 8 full runs under load, a different store-failure or delta test each time. Each passes alone, and the last three full runs passed.

  • Starting:
    • into the target chapter after a snapshot of the edits;
    • into the last chapter with no edits since a version;
    • a chapter added mid-stream is not the target;
    • the refusals before the engine (nothing written, a live run's writes not snapshotted);
    • the engine's refusals (the refused start's own snapshot stays);
    • another story's live run refusing neither a start nor a retry.
  • Cancel and retry:
    • a cancel that drains its request;
    • a retry after three failures that snapshots and finishes;
    • the retry's refusals: read ahead with no snapshot, and the engine's own not-found race through a test ledger;
    • a failed step of a run still going, retried with no snapshot.
  • The trash:
    • it stops a run that wrote: cancelled, snapshotted before the trash row, another story's run left going;
    • it stops one whose writer streams;
    • it takes every finish still owed, and only its own story's, stacked in History as they finished;
    • a finish counts as taken once a run snapshot is taken at its tick or later.
  • Run snapshots:
    • outcomes and labels;
    • the latest position past a writer's edit;
    • taking it twice, quietly;
    • two takes at once;
    • the move after a retry and the relabel in place;
    • the announcements.
  • The host:
    • its reconciliation, and a run settling while it reconciles;
    • its live finishes, a row's settle ignored;
    • a failure logged while the next goes on;
    • its stop unsubscribing;
    • its order before the engine's host.
  • The rest: the finished-run history; the seeded runs against a real run's values, whole; StorySnapshot.MoveTo.
  • Coverage: 100% line and branch on the changed lines.
  • Mutation probes: 92 runs over 77 distinct compiling mutants, all killed in the end.
    • The feature: 40 runs over 32 mutants.
      • T6 (labels out of order) survived once, before its test wrote two different operations.
      • 7 builds did not compile: 6 first cuts and X1's second. Each first cut was rerun as a compiling variant.
    • Round 0's fixes: 30 runs over 26 mutants. R8 survived once, before its test gave the other run a write since its snapshot.
    • The second pass's fixes: 16 runs over 14 mutants, among them the second pass's seven survivors.
    • Round 1's ideas: 6 runs over 5 mutants of the owed-finishes query. J5 (newest finish first) survived once, before the trash test held two new snapshots.

Reviews

Reviews ran as workflows, one agent at a time.

  • Round 0 (182c26c): reviewers for correctness, for the tests and the seed, and for the docs, then one skeptic over every finding.
    • 21 findings: 4 blockers, 6 suggestions and 11 nits after verification; 16 confirmed, 5 partly.
    • All taken in 925620d:
      • A1/D2: one take at a time, so a run has one run snapshot.
      • A2/D1: the target chapter is always persisted.
      • A3/D4: the refusals are read before the snapshot.
      • A4/D3: a relabel in place.
      • D5: a gone chapter has its own refusal.
      • B1, B4–B6: tests for the hosts' order, subscribing before reconciling, the latest position and the stop.
      • B2, B3, B7, D6: the seed, checked against real runs.
      • D7, D9, D10: the plan, a comment and the stop's comment.
      • D8: 182c26c's message miscounted the probes that did not compile; corrected in 925620d's.
  • Second pass (925620d): a check of every round-0 fix and of the fix commit, then a skeptic.
    • 20 of 21 checks resolved and 1 partly: B7, whose remainder is F2.
    • 12 new findings: 3 suggestions and 9 nits after the skeptic; 10 confirmed, 2 partly.
    • All taken in 68b4ef1:
      • E1/F1: a retry of a run still going takes no snapshot.
      • E2: a trash takes every finish still owed.
      • E3, E4, E5, F4: the owner filter, the refusal order, a quiet retake and the refused start's own snapshot are pinned.
      • E6: the amendment names a retry's races.
      • F2, F3, F5: the seed's commit row, its requests and reports asserted whole, the later run's span.
      • F6: 925620d's message left out one probe rerun, S9's; corrected in 68b4ef1's.
  • Round 1 (Jibril, on 0ae2ca5): two approvals, with four ideas. The three in code are taken in 6f72d7d:
    • the owed finishes as one anti-join in the database;
    • the tie at the finish's tick pinned, and the take order with it;
    • the routing literal explained.
    • The fourth, stability under load, is answered in the thread (comment 10456).

App check (the sample world)

  • The app started twice on a fresh data directory with the sample world, the second time on 68b4ef1. The seed ran and the snapshots' host reconciled the seeded runs at its start, adding nothing: one run snapshot, "Continue: Commit appended 2 paragraphs", above "Your edits". The run that gave up has none.
  • In the database, the first run's commit row holds its journal write; the later run's writer row shows three attempts, and its commit is pending.
  • In the browser (the first start, on the round-0 fixes), History shows the run snapshot between "Since the last version" and "Your edits".
  • No console errors, and no error in the server's log beyond an antiforgery cookie the browser kept from an earlier data directory's key ring.

🤖 Generated with Claude Code

Slice 11b of Phase 2 (`docs/PROJECT_PLAN.md`): **runs start, cancel and retry**. A story's runs now start, cancel and retry through use cases over the engine (ADR 0016), and each finished run gets its one run snapshot (ADR 0022). No UI yet: the plan splits the old 11b line, and the Runs section is 11c. ## What lands - **The run use cases.** - `StartRun(story, chapter?)`: - **Refused first, with nothing written:** what the engine cannot know — a story gone or in the trash, no graph, a graph in the trash, a chapter gone or another story's — and a story whose run is still going. - **Then:** a before-run snapshot of the writer's edits under the run's id ("Your edits"). The engine starts the active graph as it stands, the run's own copy. - **The target chapter:** always persisted in the trigger envelope (ADR 0012). It is the chapter the run starts from, else the story's last at the start, so a chapter added while the run streams is not its target. - **The engine's own refusals** are named; the snapshot taken stays. They are a graph that does not load, has no node or has problems, and a run started in between. - `CancelRun(run)`: the engine's cancel, which drains before it answers. - `RetryRun(step)`: a failed step, as the inspector will ask it. - The engine's refusals are read ahead, before any snapshot: a step gone, a story in the trash, a cancelled run, a step that has not failed, another run going. - A before-run snapshot comes first, except for a run that is itself still going: since its start, its writes and the writer's have interleaved. - **Run snapshots.** - `TakeRunSnapshot(run)` always takes a succeeded run's snapshot, and a failed or cancelled run's only when it wrote. It sits at the story's latest position. Its label names the graph, the outcome when the run did not succeed, and its operations in journal order (*"Continue: Commit appended 2 paragraphs"*). - Taking it twice changes nothing and announces nothing. - A finish after a Retry moves the snapshot to the latest position when the run wrote past it; otherwise it relabels it where it stands. - One take at a time (`RunSnapshotGate`), so two callers never both add one. - `ISnapshotStore.MoveAsync` and `StorySnapshot.MoveTo` carry the move. - **The snapshots' host.** - `RunSnapshotsHost` takes each run's snapshot as it settles. It subscribes before it reconciles, at its start, every finished run; a finish the last process missed gets its snapshot then. - It is registered before the engine's host. Its stop unsubscribes, and the stop's cancellation ends its loop. - `IRunHistory` (EF) lists the finished runs, and a story's runs whose last finish no snapshot has taken. - **The trash stops the story's run.** - `TrashStory` first cancels and drains the story's live run (`ILiveRuns` over the engine). - It then takes every finish still owed: the cancelled run's, one still in the host's queue, one a Retry finished again. - So a purge never deletes ledger rows under an execution, and no run snapshot sits after the trash row. - **The seeded runs.** They are checked field by field against runs of the real engine and gateway (over a scripted HTTP handler) on the seeded world. - **A Continue run that wrote the sample paragraphs:** - its context and the context node's report; - the writer's request exactly as the gateway sends it, in the run's session, with its routing, size and cost; - the commit's landing and report; - its run snapshot, through `TakeRunSnapshot`. - **A later run whose writer timed out three times:** - each error is in the llm node's words, the last one numbered as the engine numbers it; - its context node learned the ratio from the first run's request; - it wrote nothing, so it has no snapshot. - **Docs.** ADR 0016 and 0022 are amended (slice 11b; this PR's number added in 0ae2ca5). The plan's 11b line is split into 11b and 11c; the run history's cost columns stay with slice 14, now after 11c. ## Decisions | Question | Decision | Why | |---|---|---| | The target chapter | Always in the trigger, the last chapter when none is given. | ADR 0012: the run writes where it started from. A chapter added mid-run must not become the target. | | Refusals and the before-run snapshot | Read every refusal the use case can know before the snapshot; the engine asks again under its gate. | A refusal must never file a live run's writes as the writer's edits. A refusal the engine alone meets keeps the snapshot, which marks the writer's own edits. | | A retry of a run still going | No "Your edits" snapshot. | Its writes and the writer's have interleaved since its start; no snapshot can separate them. | | Concurrent takes | A singleton semaphore around the whole take. | The host and a trash take the same cancelled run. In round 0's probe, 10 and then 7 of 20 trashes left two run snapshots; with the gate, the second pass's probe saw one in each of 20. | | Position | The story's latest journal position; a relabel in place when only the outcome changed. | ADR 0022's run snapshot marks the story as the run left it; a Retry that wrote more moves it. | | A finish the host has not taken at a trash | The trash takes every finish still owed before its own row. | Otherwise the snapshot lands after the trash row, and *Revert to here* on it would put the story back in the trash. | | The seed's window | 128,000 tokens. | A seed cannot know the catalog's; everything else matches a real run. | ## Tests | Project | main | branch | |---|---|---| | Tsumugi.Domain.Tests | 512 | 517 | | Kagaku.Flow.Tests | 1103 | 1103 | | Kagaku.Flow.OpenRouter.Tests | 596 (4 skipped, live) | 596 (4 skipped, live) | | Tsumugi.BlazorAdapter.Tests | 595 | 595 | | Tsumugi.UseCases.Tests | 427 | 427 | | Tsumugi.Integration.Tests | 745 | 799 | BlazorAdapter changes only test doubles here (`NoLiveRuns`, `MoveAsync` on the fake stores). It hit one 15 s bUnit wait in 3 of 8 full runs under load, a different store-failure or delta test each time. Each passes alone, and the last three full runs passed. - **Starting:** - into the target chapter after a snapshot of the edits; - into the last chapter with no edits since a version; - a chapter added mid-stream is not the target; - the refusals before the engine (nothing written, a live run's writes not snapshotted); - the engine's refusals (the refused start's own snapshot stays); - another story's live run refusing neither a start nor a retry. - **Cancel and retry:** - a cancel that drains its request; - a retry after three failures that snapshots and finishes; - the retry's refusals: read ahead with no snapshot, and the engine's own not-found race through a test ledger; - a failed step of a run still going, retried with no snapshot. - **The trash:** - it stops a run that wrote: cancelled, snapshotted before the trash row, another story's run left going; - it stops one whose writer streams; - it takes every finish still owed, and only its own story's, stacked in History as they finished; - a finish counts as taken once a run snapshot is taken at its tick or later. - **Run snapshots:** - outcomes and labels; - the latest position past a writer's edit; - taking it twice, quietly; - two takes at once; - the move after a retry and the relabel in place; - the announcements. - **The host:** - its reconciliation, and a run settling while it reconciles; - its live finishes, a row's settle ignored; - a failure logged while the next goes on; - its stop unsubscribing; - its order before the engine's host. - **The rest:** the finished-run history; the seeded runs against a real run's values, whole; `StorySnapshot.MoveTo`. - **Coverage:** 100% line and branch on the changed lines. - **Mutation probes:** 92 runs over 77 distinct compiling mutants, all killed in the end. - **The feature:** 40 runs over 32 mutants. - T6 (labels out of order) survived once, before its test wrote two different operations. - 7 builds did not compile: 6 first cuts and X1's second. Each first cut was rerun as a compiling variant. - **Round 0's fixes:** 30 runs over 26 mutants. R8 survived once, before its test gave the other run a write since its snapshot. - **The second pass's fixes:** 16 runs over 14 mutants, among them the second pass's seven survivors. - **Round 1's ideas:** 6 runs over 5 mutants of the owed-finishes query. J5 (newest finish first) survived once, before the trash test held two new snapshots. ## Reviews Reviews ran as workflows, one agent at a time. - **Round 0** (182c26c): reviewers for correctness, for the tests and the seed, and for the docs, then one skeptic over every finding. - 21 findings: 4 blockers, 6 suggestions and 11 nits after verification; 16 confirmed, 5 partly. - All taken in 925620d: - **A1/D2:** one take at a time, so a run has one run snapshot. - **A2/D1:** the target chapter is always persisted. - **A3/D4:** the refusals are read before the snapshot. - **A4/D3:** a relabel in place. - **D5:** a gone chapter has its own refusal. - **B1, B4–B6:** tests for the hosts' order, subscribing before reconciling, the latest position and the stop. - **B2, B3, B7, D6:** the seed, checked against real runs. - **D7, D9, D10:** the plan, a comment and the stop's comment. - **D8:** 182c26c's message miscounted the probes that did not compile; corrected in 925620d's. - **Second pass** (925620d): a check of every round-0 fix and of the fix commit, then a skeptic. - 20 of 21 checks resolved and 1 partly: B7, whose remainder is F2. - 12 new findings: 3 suggestions and 9 nits after the skeptic; 10 confirmed, 2 partly. - All taken in 68b4ef1: - **E1/F1:** a retry of a run still going takes no snapshot. - **E2:** a trash takes every finish still owed. - **E3, E4, E5, F4:** the owner filter, the refusal order, a quiet retake and the refused start's own snapshot are pinned. - **E6:** the amendment names a retry's races. - **F2, F3, F5:** the seed's commit row, its requests and reports asserted whole, the later run's span. - **F6:** 925620d's message left out one probe rerun, S9's; corrected in 68b4ef1's. - **Round 1** (Jibril, on 0ae2ca5): two approvals, with four ideas. The three in code are taken in 6f72d7d: - the owed finishes as one anti-join in the database; - the tie at the finish's tick pinned, and the take order with it; - the routing literal explained. - The fourth, stability under load, is answered in the thread (comment 10456). ## App check (the sample world) - The app started twice on a fresh data directory with the sample world, the second time on 68b4ef1. The seed ran and the snapshots' host reconciled the seeded runs at its start, adding nothing: one run snapshot, "Continue: Commit appended 2 paragraphs", above "Your edits". The run that gave up has none. - In the database, the first run's commit row holds its journal write; the later run's writer row shows three attempts, and its commit is pending. - In the browser (the first start, on the round-0 fixes), History shows the run snapshot between "Since the last version" and "Your edits". - No console errors, and no error in the server's log beyond an antiforgery cookie the browser kept from an earlier data directory's key ring. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A story's runs now start, cancel and retry through use cases over the
engine (ADR 0016), and each finished run gets its one run snapshot
(ADR 0022). The plan splits the old 11b line: the Runs section is 11c.

- StartRun(story, chapter?): what the engine cannot know is refused first,
  with nothing written — a story gone or in the trash, no graph, a graph in
  the trash, another story's chapter. Then a before-run snapshot of the
  writer's edits under the run's id, and the engine starts the active
  graph as it stands, the run's target chapter in its trigger envelope
  (ADR 0012). The engine's own refusals — the story's run still going, a
  graph that does not load, has no node or has problems — are named; the
  snapshot stays, true of the edits it marks.
- CancelRun(run): the engine's cancel, which drains before it answers.
- RetryRun(step): a failed step, as the inspector will ask it; a
  before-run snapshot first; the engine's refusals named.
- TakeRunSnapshot(run): a succeeded run always, a failed or cancelled one
  only when it wrote; labelled with the graph, the outcome when it did not
  succeed, and its operations' labels in order ("Continue: Commit appended
  2 paragraphs"); taking it again changes nothing, and a run that wrote
  past it after a Retry moves it to the end, relabelled.
  ISnapshotStore.MoveAsync and StorySnapshot.MoveTo carry the move.
- RunSnapshotsHost: takes each run's snapshot as it settles, and at its
  start reconciles every finished run — a finish the last process missed
  gets its snapshot then. IRunHistory (EF) lists the finished runs.
  Registered before the engine's host, so no finish goes by unheard.
- TrashStory stops the story's live run first (ILiveRuns over the engine:
  cancelled, drained, snapshotted), so a purge never deletes ledger rows
  under an execution and the run's snapshot sits before the trash.
- The seed: the run that wrote the sample paragraphs now has its ledger
  rows and its run snapshot through TakeRunSnapshot; a later run's writer
  gave up after three transient attempts, each error logged, so it wrote
  nothing and has no snapshot.
- Docs: ADR 0016 and 0022 amended (slice 11b); the plan's 11b line split
  into 11b and 11c.

Tests: a run into its target chapter after a snapshot of the edits, one
into the last chapter with no edits since a version, the refusals before
the engine (nothing written) and the engine's (its snapshot stays); a
cancel that drains its request; a retry after three failures that
snapshots and finishes; the retry's refusals, the engine's not-found race
through a test ledger included; a trash that stops a run that wrote —
cancelled, snapshotted before the trash row, another story's run left
going — and one whose writer streams; the run snapshot's outcomes and
labels, taking it twice, the move after a retry, its announcements; the
host's reconciliation, its live finishes, a row's settle ignored, a failure
logged while the next goes on, its stop; the finished-run history; the
seeded runs; StorySnapshot.MoveTo.
Probes: 40 runs; 32 distinct compiling mutants, all killed — T6 (the
label's operations out of order) survived once, before its test wrote two
different operations; 7 first cuts that did not compile were rerun as
compiling variants.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Round 0, a review workflow over 182c26c: 21 findings — 4 blockers,
6 suggestions and 11 nits after verification; 16 confirmed, 5 partly.
All are taken; what two reviewers both found (the second run snapshot,
the target chapter, the stale "(failed)") is fixed once.

- One run snapshot per run (A1, D2): TakeRunSnapshot takes one at a
  time behind RunSnapshotGate, a singleton, so the host's take and the
  trash's take of the same cancelled run no longer both add one.
- The target chapter always persisted (A2, D1; ADR 0012): with no
  chapter given, StartRun puts the story's last chapter into the trigger,
  so a chapter added while the run streams is not its target. A chapter
  that is gone reads "That chapter no longer exists." (D5).
- Refusals read before the snapshot (A3, D4): StartRun reads the
  story's live run, RetryRun the gone step, the cancelled run, the step
  that has not failed and another live run, before the "Your edits"
  snapshot, so a refusal never marks a live run's writes as the writer's
  edits. The engine asks again under its gate; a refusal met only there
  reads the same, and its snapshot stays. A failed step of a run still
  going is retried: its own run is not another.
- A relabel in place (A4, D3): a run retried to success without writing
  more is relabelled where its snapshot stands, its outcome named anew.
- The tests the review found missing: the snapshots' host is hosted
  once, before the engine's (B1); it subscribes before it reconciles
  (B4); the run snapshot sits at the story's latest position, past a
  writer's edit (B5); the stop unsubscribes (B6). The stop's
  TryComplete went: the read loop runs until the stop cancels it. The
  stop's comment says the snapshot under way is cancelled and reconciled
  at the next start (D10).
- The seeded runs as a real run leaves them (B2, B3, B7, D6), checked
  field by field against runs of the real engine and gateway, over a
  scripted HTTP handler, on the seeded world: the context from the
  seeded story's text; its report with the overhead and the ratio the
  context node computes, the later run's learned from the first's
  request (read through IPromptSamples); the writer's request byte for
  byte as the gateway sends it, in the run's session, asked of Continue's
  model and served by the seed's; the timeouts in the llm node's words,
  the last numbered as the engine numbers it. The first run spans its
  commit's write, after the snapshot of the edits; the later one runs
  while the writer edits the other chapters. The window stays the seed's
  own 128,000 tokens: a seed cannot know the catalog's.
- Docs: ADR 0016's and 0022's slice-11b amendments name the target
  always persisted, the gone chapter, one take at a time, the relabel in
  place and the refusals read first; the plan gives the run history's
  cost to slice 14, after 11c (D7); SelectionRunRequested points at M5b
  (D9).
- Correction (D8): 182c26c's message says "7 first cuts that did not
  compile were rerun as compiling variants". From the probe JSON: 7
  builds did not compile — 6 first cuts (S4, R2, T4, E2, X1, SD1) and
  X1's second cut — and each of the 6 was rerun as a compiling variant
  (S4b, R2b, T4b, E2b, SD1b, X1c).

Tests: Integration 784 to 791 — a chapter added mid-stream is not the
target; a run still going that wrote since its snapshot is refused
before any snapshot, and one started in between is named by the engine;
the retry's refusals read first take no snapshot, the one the engine
meets keeps its own; a failed step of a run still going is retried; two
takes at once add one snapshot; the relabel in place; the latest
position past a writer's edit; a run settling while the host reconciles;
the stop unsubscribing; the hosts' order; the seeded runs against a real
run's values. All six projects pass (Domain 517, Kagaku.Flow 1103,
Kagaku.Flow.OpenRouter 596 with the 4 live checks skipped, UseCases 427,
BlazorAdapter 595, Integration 791); 100% line and branch coverage on
the changed lines.
Probes: 30 runs over 26 distinct compiling mutants of the fixes, all
killed. R8 (the retry's read-ahead of another live run) survived once,
before its test gave that run a write since its snapshot; H4 and H5 ran
again after the read loop changed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fix(runs): second pass of slice 11b — a retry of a run still going takes no snapshot, a trash takes every finish still owed, the read-aheads and the seed pinned
Some checks failed
CI / test (pull_request) Has been cancelled
CI / editor-browsers (pull_request) Has been cancelled
CI / build (pull_request) Has been cancelled
68b4ef10f0
The second pass (a review workflow over 925620d) checked the 21 round-0
fixes, 20 resolved and 1 partly (B7), and raised 12 findings — 3
suggestions and 9 nits after its skeptic; 10 confirmed, 2 partly. All
are taken; E1 and F1 are one defect.

- A retry of a run still going takes no "Your edits" snapshot (E1, F1):
  since the run's start its writes and the writer's have interleaved, so
  the snapshot would have filed the run's own writes as the writer's.
  ADR 0022's slice-11b amendment says another run's writes are never
  marked so, and names this case.
- A trash takes every finish still owed (E2): after cancelling the
  story's live run it takes the snapshot of each of the story's finished
  runs no run snapshot has taken since its last finish (IRunHistory
  .ListUntakenAsync) — the cancelled run's, one still in the host's
  queue, one a Retry finished again — so none lands after the trash row.
  Its own story's only: another story's finish waits for the host.
- Pinned: the read-aheads' owner filter, another story's live run
  refusing neither a start nor a retry here (E3); a cancelled step of a
  cancelled run answered as the engine answers (E4); taking a snapshot
  again announcing nothing (E5); a start the engine refuses after a run
  started in between keeping its own snapshot (F4).
- ADR 0022's amendment names a retry's races among the engine's refusals
  whose snapshot stays (E6).
- The seed (F2, F3, F5; B7's remainder): the first run's commit row
  holds the commit's write; SeedDevDataTests asserts the writer's
  requests and the context reports whole, as the real runs gave them;
  the later run spans the writer's three edits since the last version —
  a paragraph, a document, a category —, which the test asserts.
- Correction (F6): 925620d's message accounts for three of the four
  probe reruns; S9 also ran again, beside R8, after the live-run tests
  gave the run a write since its snapshot.

Tests: Integration 791 to 795 — another story's live run refusing
neither a start nor a retry; a cancelled step of a cancelled run; a
trash taking every finish still owed and only its own story's. A retry
of a run still going now asserts no snapshot over its run's write, the
refused start in between its own snapshot, the retake no announcement,
the seed its requests and reports whole, its commit row and the later
run's span. All six projects pass (Domain 517, Kagaku.Flow 1103,
Kagaku.Flow.OpenRouter 596 with the 4 live checks skipped, UseCases 427,
BlazorAdapter 595, Integration 795); 100% line and branch coverage on
the changed lines. BlazorAdapter, untouched here but for test doubles,
hit one 15 s bUnit wait in 3 of 8 full runs under load, a different
store-failure or delta test each time; each passes alone, and the last
two full runs passed.
Probes: 16 runs over 14 distinct compiling mutants, all killed — among
them the second pass's seven survivors (G2-G5, N1-N3); Q4 and Q5 ran
again after the run history read its values plainly.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
docs: PR #70 into the slice-11b amendments of ADR 0016 and 0022 and the plan's 11b line
All checks were successful
CI / build (pull_request) Successful in 43s
CI / editor-browsers (pull_request) Successful in 1m3s
CI / test (pull_request) Successful in 2m6s
0ae2ca5e5a
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: 6f72d7d · Generated: 2026-10-03 05:31:27 UTC · Revision: #2

Summary

Summary
Generated on: 10/03/2026 - 05:31:26
Coverage date: 10/03/2026 - 05:30:33 - 10/03/2026 - 05:31:23
Parser: MultiReport (6x Cobertura)
Assemblies: 9
Classes: 610
Files: 521
Line coverage: 98.5% (20165 of 20455)
Covered lines: 20165
Uncovered lines: 290
Coverable lines: 20455
Total lines: 42023
Branch coverage: 94.8% (6762 of 7132)
Covered branches: 6762
Total branches: 7132
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 - 96.7%
Name Line Branch
Tsumugi.BlazorAdapter 96.7% 92%
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.ContextPreviewEffects 100% 100%
Tsumugi.BlazorAdapter.Documents.ContextPreviewFailed 100%
Tsumugi.BlazorAdapter.Documents.ContextPreviewLoaded 100%
Tsumugi.BlazorAdapter.Documents.ContextPreviewPane 100% 100%
Tsumugi.BlazorAdapter.Documents.ContextPreviewReducers 100% 100%
Tsumugi.BlazorAdapter.Documents.ContextPreviewState 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.1%
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.LoadContextPreview 100%
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.DuplicateGraphRequested 100%
Tsumugi.BlazorAdapter.Graphs.GraphActionFailed 100%
Tsumugi.BlazorAdapter.Graphs.GraphCanvas 58.3% 40%
Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage 100% 100%
Tsumugi.BlazorAdapter.Graphs.GraphsEffects 100% 100%
Tsumugi.BlazorAdapter.Graphs.GraphsLoaded 100%
Tsumugi.BlazorAdapter.Graphs.GraphsPage 100% 100%
Tsumugi.BlazorAdapter.Graphs.GraphsReducers 100%
Tsumugi.BlazorAdapter.Graphs.GraphsState 100%
Tsumugi.BlazorAdapter.Graphs.ImportGraphRequested 100%
Tsumugi.BlazorAdapter.Graphs.RestoreGraphRequested 100%
Tsumugi.BlazorAdapter.Graphs.ReviseGraphRequested 100%
Tsumugi.BlazorAdapter.Graphs.SetShowGraphTrash 100%
Tsumugi.BlazorAdapter.Graphs.TrashGraphRequested 100%
Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge 94.4% 83.3%
Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived 75% 100%
Tsumugi.BlazorAdapter.Runs.RunChangedBridge 97.3% 91.6%
Tsumugi.BlazorAdapter.Runs.RunChangesReceived 100%
Tsumugi.BlazorAdapter.Runs.RunTextKey 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.SetActiveGraphRequested 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.StoryGraphsEffects 100% 100%
Tsumugi.BlazorAdapter.Workspace.StoryGraphsLoaded 100%
Tsumugi.BlazorAdapter.Workspace.StoryGraphsReducers 100%
Tsumugi.BlazorAdapter.Workspace.StoryGraphsState 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.5%
Name Line Branch
Tsumugi.Domain 96.5% 95.2%
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.Graphs.Graph 100% 100%
Tsumugi.Domain.Graphs.GraphTriggers 100% 100%
Tsumugi.Domain.Journal.ChangeLogEntry 97.9% 83.3%
Tsumugi.Domain.Journal.StorySnapshot 96.2% 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.9%
Name Line Branch
Tsumugi.Infrastructure 98.9% 88.5%
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% 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.GraphConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.NodeRunRecordConfiguratio
n
100%
Tsumugi.Infrastructure.Persistence.Configurations.RunRecordConfiguration 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.GraphTriggerConverter 100% 100%
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.ActiveGraphForeignKey 100%
Tsumugi.Infrastructure.Persistence.Migrations.ActiveGraphOnContinue 100% 100%
Tsumugi.Infrastructure.Persistence.Migrations.ActiveGraphOnContinueSql 100%
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.GraphLibrary 100%
Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain 97.3%
Tsumugi.Infrastructure.Persistence.Migrations.JournalUndoState 100%
Tsumugi.Infrastructure.Persistence.Migrations.RunLedger 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.EfGraphStore 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfImageStore 100%
Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore 98.7% 91.6%
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.EfRunHistory 100%
Tsumugi.Infrastructure.Runs.EfRunLedger 100% 100%
Tsumugi.Infrastructure.Runs.InProcessRunEventBus 100% 100%
Tsumugi.Infrastructure.Runs.LedgerMapping 100% 100%
Tsumugi.Infrastructure.Runs.LedgerPromptSamples 100%
Tsumugi.Infrastructure.Runs.NodeRunRecord 100%
Tsumugi.Infrastructure.Runs.RunEngineHost 100%
Tsumugi.Infrastructure.Runs.RunRecord 100%
Tsumugi.Infrastructure.Runs.RunSnapshotsHost 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 - 99.6%
Name Line Branch
Tsumugi.Server 99.6% 91.5%
Program 99.2% 95.4%
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.9%
Name Line Branch
Tsumugi.UseCases 98.9% 96.5%
System.Text.RegularExpressions.Generated 90.9% 77.2%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__LineBreaks_0
95.3% 90.6%
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.Commit.AppendRunText 100% 92.8%
Tsumugi.UseCases.Commit.CommitConfig 100% 100%
Tsumugi.UseCases.Commit.CommitConfigRead 100%
Tsumugi.UseCases.Commit.CommitDescriptor 100%
Tsumugi.UseCases.Commit.CommitExecutor 100% 100%
Tsumugi.UseCases.Commit.CommitReport 100%
Tsumugi.UseCases.Commit.CommittedSegments 100%
Tsumugi.UseCases.Commit.RunAppend 100%
Tsumugi.UseCases.Context.AssembledContext 100%
Tsumugi.UseCases.Context.CharsPerToken 100% 100%
Tsumugi.UseCases.Context.ConsumerFigures 100%
Tsumugi.UseCases.Context.ContextAssembly 100% 100%
Tsumugi.UseCases.Context.ContextAttempt 100% 100%
Tsumugi.UseCases.Context.ContextBudgetTokens 100%
Tsumugi.UseCases.Context.ContextBuild 100%
Tsumugi.UseCases.Context.ContextBuilder 100%
Tsumugi.UseCases.Context.ContextConfig 100% 100%
Tsumugi.UseCases.Context.ContextConfigRead 100%
Tsumugi.UseCases.Context.ContextConsumerRule 100% 100%
Tsumugi.UseCases.Context.ContextDescriptor 100%
Tsumugi.UseCases.Context.ContextExecutor 100% 100%
Tsumugi.UseCases.Context.ContextNodePreview 100%
Tsumugi.UseCases.Context.ContextParts 100%
Tsumugi.UseCases.Context.ContextPreview 100%
Tsumugi.UseCases.Context.ContextReport 100%
Tsumugi.UseCases.Context.DocumentRendering 100% 100%
Tsumugi.UseCases.Context.PreviewContext 100% 100%
Tsumugi.UseCases.Context.PromptSample 100% 100%
Tsumugi.UseCases.Context.RecentParagraph 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.Context.StoryText 100% 100%
Tsumugi.UseCases.DependencyInjection 100%
Tsumugi.UseCases.Diagnostics.SeedContext 100%
Tsumugi.UseCases.Diagnostics.SeedDevData 98.6% 68.7%
Tsumugi.UseCases.Diagnostics.SeedPictures 100%
Tsumugi.UseCases.Diagnostics.SeedRuns 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.Graphs.BundledGraphs 100%
Tsumugi.UseCases.Graphs.DuplicateGraph 100% 100%
Tsumugi.UseCases.Graphs.ExportGraph 100% 100%
Tsumugi.UseCases.Graphs.GetNodeTypes 100%
Tsumugi.UseCases.Graphs.GraphExport 100%
Tsumugi.UseCases.Graphs.GraphFile 100% 100%
Tsumugi.UseCases.Graphs.GraphFileContent 100%
Tsumugi.UseCases.Graphs.GraphListItem 100%
Tsumugi.UseCases.Graphs.GraphUser 100%
Tsumugi.UseCases.Graphs.GraphUsers 100%
Tsumugi.UseCases.Graphs.ImportGraph 100% 100%
Tsumugi.UseCases.Graphs.ListGraphs 100% 100%
Tsumugi.UseCases.Graphs.ListStoryGraphs 100% 100%
Tsumugi.UseCases.Graphs.RestoreGraph 100% 100%
Tsumugi.UseCases.Graphs.ReviseGraph 100% 100%
Tsumugi.UseCases.Graphs.SeedBundledGraphs 100% 100%
Tsumugi.UseCases.Graphs.SeededTemplates 100%
Tsumugi.UseCases.Graphs.StoryGraphChoice 100%
Tsumugi.UseCases.Graphs.TrashGraph 100% 100%
Tsumugi.UseCases.Journal.GetStoryHistory 100% 100%
Tsumugi.UseCases.Journal.GetUndoStatus 100% 100%
Tsumugi.UseCases.Journal.HistoryOperation 88.8%
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.CancelRun 100% 100%
Tsumugi.UseCases.Runs.EngineLiveRuns 100% 100%
Tsumugi.UseCases.Runs.LiveTail 100%
Tsumugi.UseCases.Runs.LlmConcurrencyLimit 100%
Tsumugi.UseCases.Runs.RetryRun 100% 100%
Tsumugi.UseCases.Runs.RunSnapshotGate 100%
Tsumugi.UseCases.Runs.StartRun 100% 100%
Tsumugi.UseCases.Runs.TakeRunSnapshot 100% 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% 87.5%
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 83.3%
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:** `6f72d7d` · **Generated:** 2026-10-03 05:31:27 UTC · **Revision:** #2 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 10/03/2026 - 05:31:26 | | Coverage date: | 10/03/2026 - 05:30:33 - 10/03/2026 - 05:31:23 | | Parser: | MultiReport (6x Cobertura) | | Assemblies: | 9 | | Classes: | 610 | | Files: | 521 | | **Line coverage:** | 98.5% (20165 of 20455) | | Covered lines: | 20165 | | Uncovered lines: | 290 | | Coverable lines: | 20455 | | Total lines: | 42023 | | **Branch coverage:** | 94.8% (6762 of 7132) | | Covered branches: | 6762 | | Total branches: | 7132 | | **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 - 96.7%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.BlazorAdapter**|**96.7%**|**92%**| |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.ContextPreviewEffects|100%|100%| |Tsumugi.BlazorAdapter.Documents.ContextPreviewFailed|100%|| |Tsumugi.BlazorAdapter.Documents.ContextPreviewLoaded|100%|| |Tsumugi.BlazorAdapter.Documents.ContextPreviewPane|100%|100%| |Tsumugi.BlazorAdapter.Documents.ContextPreviewReducers|100%|100%| |Tsumugi.BlazorAdapter.Documents.ContextPreviewState|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.1%| |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.LoadContextPreview|100%|| |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.DuplicateGraphRequested|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphActionFailed|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphCanvas|58.3%|40%| |Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage|100%|100%| |Tsumugi.BlazorAdapter.Graphs.GraphsEffects|100%|100%| |Tsumugi.BlazorAdapter.Graphs.GraphsLoaded|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphsPage|100%|100%| |Tsumugi.BlazorAdapter.Graphs.GraphsReducers|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphsState|100%|| |Tsumugi.BlazorAdapter.Graphs.ImportGraphRequested|100%|| |Tsumugi.BlazorAdapter.Graphs.RestoreGraphRequested|100%|| |Tsumugi.BlazorAdapter.Graphs.ReviseGraphRequested|100%|| |Tsumugi.BlazorAdapter.Graphs.SetShowGraphTrash|100%|| |Tsumugi.BlazorAdapter.Graphs.TrashGraphRequested|100%|| |Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge|94.4%|83.3%| |Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived|75%|100%| |Tsumugi.BlazorAdapter.Runs.RunChangedBridge|97.3%|91.6%| |Tsumugi.BlazorAdapter.Runs.RunChangesReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextKey|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.SetActiveGraphRequested|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.StoryGraphsEffects|100%|100%| |Tsumugi.BlazorAdapter.Workspace.StoryGraphsLoaded|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryGraphsReducers|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryGraphsState|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.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Domain**|**96.5%**|**95.2%**| |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.Graphs.Graph|100%|100%| |Tsumugi.Domain.Graphs.GraphTriggers|100%|100%| |Tsumugi.Domain.Journal.ChangeLogEntry|97.9%|83.3%| |Tsumugi.Domain.Journal.StorySnapshot|96.2%|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.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Infrastructure**|**98.9%**|**88.5%**| |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%|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.GraphConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.NodeRunRecordConfiguratio<br/>n|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.RunRecordConfiguration|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.GraphTriggerConverter|100%|100%| |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.ActiveGraphForeignKey|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.ActiveGraphOnContinue|100%|100%| |Tsumugi.Infrastructure.Persistence.Migrations.ActiveGraphOnContinueSql|100%|| |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.GraphLibrary|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain|97.3%|| |Tsumugi.Infrastructure.Persistence.Migrations.JournalUndoState|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.RunLedger|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.EfGraphStore|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfImageStore|100%|| |Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore|98.7%|91.6%| |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.EfRunHistory|100%|| |Tsumugi.Infrastructure.Runs.EfRunLedger|100%|100%| |Tsumugi.Infrastructure.Runs.InProcessRunEventBus|100%|100%| |Tsumugi.Infrastructure.Runs.LedgerMapping|100%|100%| |Tsumugi.Infrastructure.Runs.LedgerPromptSamples|100%|| |Tsumugi.Infrastructure.Runs.NodeRunRecord|100%|| |Tsumugi.Infrastructure.Runs.RunEngineHost|100%|| |Tsumugi.Infrastructure.Runs.RunRecord|100%|| |Tsumugi.Infrastructure.Runs.RunSnapshotsHost|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 - 99.6%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Server**|**99.6%**|**91.5%**| |Program|99.2%|95.4%| |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.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.UseCases**|**98.9%**|**96.5%**| |System.Text.RegularExpressions.Generated|90.9%|77.2%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__LineBreaks_0|95.3%|90.6%| |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.Commit.AppendRunText|100%|92.8%| |Tsumugi.UseCases.Commit.CommitConfig|100%|100%| |Tsumugi.UseCases.Commit.CommitConfigRead|100%|| |Tsumugi.UseCases.Commit.CommitDescriptor|100%|| |Tsumugi.UseCases.Commit.CommitExecutor|100%|100%| |Tsumugi.UseCases.Commit.CommitReport|100%|| |Tsumugi.UseCases.Commit.CommittedSegments|100%|| |Tsumugi.UseCases.Commit.RunAppend|100%|| |Tsumugi.UseCases.Context.AssembledContext|100%|| |Tsumugi.UseCases.Context.CharsPerToken|100%|100%| |Tsumugi.UseCases.Context.ConsumerFigures|100%|| |Tsumugi.UseCases.Context.ContextAssembly|100%|100%| |Tsumugi.UseCases.Context.ContextAttempt|100%|100%| |Tsumugi.UseCases.Context.ContextBudgetTokens|100%|| |Tsumugi.UseCases.Context.ContextBuild|100%|| |Tsumugi.UseCases.Context.ContextBuilder|100%|| |Tsumugi.UseCases.Context.ContextConfig|100%|100%| |Tsumugi.UseCases.Context.ContextConfigRead|100%|| |Tsumugi.UseCases.Context.ContextConsumerRule|100%|100%| |Tsumugi.UseCases.Context.ContextDescriptor|100%|| |Tsumugi.UseCases.Context.ContextExecutor|100%|100%| |Tsumugi.UseCases.Context.ContextNodePreview|100%|| |Tsumugi.UseCases.Context.ContextParts|100%|| |Tsumugi.UseCases.Context.ContextPreview|100%|| |Tsumugi.UseCases.Context.ContextReport|100%|| |Tsumugi.UseCases.Context.DocumentRendering|100%|100%| |Tsumugi.UseCases.Context.PreviewContext|100%|100%| |Tsumugi.UseCases.Context.PromptSample|100%|100%| |Tsumugi.UseCases.Context.RecentParagraph|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.Context.StoryText|100%|100%| |Tsumugi.UseCases.DependencyInjection|100%|| |Tsumugi.UseCases.Diagnostics.SeedContext|100%|| |Tsumugi.UseCases.Diagnostics.SeedDevData|98.6%|68.7%| |Tsumugi.UseCases.Diagnostics.SeedPictures|100%|| |Tsumugi.UseCases.Diagnostics.SeedRuns|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.Graphs.BundledGraphs|100%|| |Tsumugi.UseCases.Graphs.DuplicateGraph|100%|100%| |Tsumugi.UseCases.Graphs.ExportGraph|100%|100%| |Tsumugi.UseCases.Graphs.GetNodeTypes|100%|| |Tsumugi.UseCases.Graphs.GraphExport|100%|| |Tsumugi.UseCases.Graphs.GraphFile|100%|100%| |Tsumugi.UseCases.Graphs.GraphFileContent|100%|| |Tsumugi.UseCases.Graphs.GraphListItem|100%|| |Tsumugi.UseCases.Graphs.GraphUser|100%|| |Tsumugi.UseCases.Graphs.GraphUsers|100%|| |Tsumugi.UseCases.Graphs.ImportGraph|100%|100%| |Tsumugi.UseCases.Graphs.ListGraphs|100%|100%| |Tsumugi.UseCases.Graphs.ListStoryGraphs|100%|100%| |Tsumugi.UseCases.Graphs.RestoreGraph|100%|100%| |Tsumugi.UseCases.Graphs.ReviseGraph|100%|100%| |Tsumugi.UseCases.Graphs.SeedBundledGraphs|100%|100%| |Tsumugi.UseCases.Graphs.SeededTemplates|100%|| |Tsumugi.UseCases.Graphs.StoryGraphChoice|100%|| |Tsumugi.UseCases.Graphs.TrashGraph|100%|100%| |Tsumugi.UseCases.Journal.GetStoryHistory|100%|100%| |Tsumugi.UseCases.Journal.GetUndoStatus|100%|100%| |Tsumugi.UseCases.Journal.HistoryOperation|88.8%|| |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.CancelRun|100%|100%| |Tsumugi.UseCases.Runs.EngineLiveRuns|100%|100%| |Tsumugi.UseCases.Runs.LiveTail|100%|| |Tsumugi.UseCases.Runs.LlmConcurrencyLimit|100%|| |Tsumugi.UseCases.Runs.RetryRun|100%|100%| |Tsumugi.UseCases.Runs.RunSnapshotGate|100%|| |Tsumugi.UseCases.Runs.StartRun|100%|100%| |Tsumugi.UseCases.Runs.TakeRunSnapshot|100%|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%|87.5%| |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|83.3%|| |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 my~ A slice where the refusal ordering is the architecture. StartRun reads every refusal it can know before the before-run snapshot so a refused start never files a live run's writes as "Your edits", then deliberately keeps the snapshot when the engine refuses under its gate — because that snapshot marks the writer's own edits, and a second try takes none. I read that sentence in the ADR amendment and then watched TakeSnapshot.BeforeRunAsync (latest-position short-circuit) actually enforce it. This is the kind of invariant-as-code that makes me flutter~ ♡

Verdict: ✅ Looks good to me~

✅ What I liked~

  • The ordering triple — subscribe-before-reconcile in RunSnapshotsHost.StartAsync (a finish during reconciliation queues, never lost — and A_run_that_settles_while_the_host_reconciles_is_taken_too pins it with a held read), registration before RunEngineHost in Program.cs (pinned by the hosted-services order test), and refusals-before-snapshot in both use cases. Each is load-bearing and each has its own pin.
  • RunSnapshotGate — a process-wide SemaphoreSlim(1,1) around the whole take. The round-0 probe story (10 and 7 of 20 trashes leaving two snapshots, then 20/20 with the gate) is exactly the evidence I want, and Two_takes_at_once_add_one_snapshot holds the first take between its read and its add to prove the second waits rather than wins.
  • The trash contract — EngineLiveRuns.StopAsync cancels + drains, then ListUntakenAsync takes every finish still owed before the trash row, so no run snapshot ever sits after the trash and Revert to here can't resurrect a trashed story. EfRunHistory's taken-predates-finish comparison (CreatedAt >= FinishedAt) correctly handles the Retry-finished-again case, and the trash test's snapshots[retried].Label proves the move happened under it.
  • MoveTo — forward-only with ArgumentOutOfRangeException, label trimmed and guarded, MoveAsync refusing loudly for a gone snapshot. Domain-pure, sibling-consistent with the entity's other guards.
  • The seed's honesty — I re-derived the context node's budget math by hand from CharsPerToken.Budget and Fold: 470301 = ⌊123904 × 0.95 × 4⌋ − 534, 471661 = ⌊123904 × 0.95 × (694/173)⌋ − 534, prompt 532+313 = 845, sections 86/74/162 — every digit of those pinned report JSONs is the real formula's answer, and the writer's request constant matches what the gateway serializes (session = run id, cache_control on the system message, UnsafeRelaxedJsonEscaping's “ and ‘ exactly as the test literals expect). The GaveUp run's attempt numbering (“OpenRouter did not answer in time. (attempt 3 of 3)”) mirrors the engine's own closing format.
  • The refusals' names — every arm of RetryResult and RunStartRefusal mapped, writer-facing strings that never leak internal ids, and the doc-only fix on SelectionRunRequested keeping M5b's scope honest after the 11b/11c split.

🔬 My own numbers (CI absent for 0ae2ca5 — PR minutes old, no coverage bot yet)

  • Release build: 0 warnings, 0 errors.
  • Domain 517/517, UseCases 427/427, BlazorAdapter 595/595, Integration 795/795, Kagaku.Flow 1103/1103, Flow.OpenRouter 592 + 4 live skips — all digit-exact vs the body table. (The disclosed 15 s bUnit flake didn't show in my run — BlazorAdapter green in 28 s.)
  • Six mutation probes, every one killed on exactly its own pin, each restored pristine (git diff --quiet verified, full test-project rebuild before every run — the stale-binary trap bit me once and was discarded):
    1. TakeRunSnapshot's written.Count == 0 → >= 0: exactly the Failed-wrote and Cancelled-wrote theory rows + the relabel-in-place test red.
    2. StartRun's live-run filter → Any(_ => false): exactly the "a run still going" read-ahead refusal row red.
    3. EngineLiveRuns' owner filter dropped: exactly Trashing_a_story_stops_its_run… red (the other story's run must stay Running).
    4. MoveTo's backward guard → Math.Max: exactly A_snapshot_never_moves_back red.
    5. Subscription moved to after the reconciliation read: exactly the settles-while-reconciling test + the stop-unsubscribe test red.
    6. The two AddHostedService lines swapped: exactly the order test red.

💡 Little ideas (non-blocking)~

  1. EfRunHistory.ListUntakenAsync does its finished-vs-taken match in memory. Today that's a handful of rows per story and perfectly fine — but when 11c's Runs section starts listing, a story with a long run history will drag every run snapshot row over the wire on every trash. An SQL-side anti-join (WHERE NOT EXISTS …) would keep it bounded. Not now~ ♪
  2. The Routing constant lives verbatim in both SeedRuns and SeedDevDataTests — I know why (the test pins the seed against an independent literal, which is right), but a one-line comment at the test constant saying "must equal SeedRuns.Routing; a change there should redden this" would spare a future reader the double-take.

Fufu~ run snapshots that can't be duplicated, a trash that owes its finishes, and a seed that tells the truth to the last digit. I'm satisfied~ ♡


Automated review by Jibril · 2026-10-03
CI/CD: absent for head SHA 0ae2ca5 · Local checks: full suite green, 6/6 mutation probes killed

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh my~ A slice where the *refusal ordering* is the architecture. StartRun reads every refusal it can know **before** the before-run snapshot so a refused start never files a live run's writes as "Your edits", then deliberately keeps the snapshot when the *engine* refuses under its gate — because that snapshot marks the writer's own edits, and a second try takes none. I read that sentence in the ADR amendment and then watched `TakeSnapshot.BeforeRunAsync` (latest-position short-circuit) actually enforce it. This is the kind of invariant-as-code that makes me flutter~ ♡ ### Verdict: ✅ Looks good to me~ #### ✅ What I liked~ - **The ordering triple** — subscribe-before-reconcile in `RunSnapshotsHost.StartAsync` (a finish during reconciliation queues, never lost — and `A_run_that_settles_while_the_host_reconciles_is_taken_too` pins it with a held read), registration before `RunEngineHost` in Program.cs (pinned by the hosted-services order test), and refusals-before-snapshot in both use cases. Each is load-bearing and each has its own pin. - **`RunSnapshotGate`** — a process-wide `SemaphoreSlim(1,1)` around the whole take. The round-0 probe story (10 and 7 of 20 trashes leaving two snapshots, then 20/20 with the gate) is exactly the evidence I want, and `Two_takes_at_once_add_one_snapshot` holds the first take between its read and its add to prove the *second* waits rather than wins. - **The trash contract** — `EngineLiveRuns.StopAsync` cancels + drains, *then* `ListUntakenAsync` takes every finish still owed before the trash row, so no run snapshot ever sits after the trash and *Revert to here* can't resurrect a trashed story. `EfRunHistory`'s taken-predates-finish comparison (`CreatedAt >= FinishedAt`) correctly handles the Retry-finished-again case, and the trash test's `snapshots[retried].Label` proves the move happened under it. - **`MoveTo`** — forward-only with `ArgumentOutOfRangeException`, label trimmed and guarded, `MoveAsync` refusing loudly for a gone snapshot. Domain-pure, sibling-consistent with the entity's other guards. - **The seed's honesty** — I re-derived the context node's budget math by hand from `CharsPerToken.Budget` and `Fold`: 470301 = ⌊123904 × 0.95 × 4⌋ − 534, 471661 = ⌊123904 × 0.95 × (694/173)⌋ − 534, prompt 532+313 = 845, sections 86/74/162 — every digit of those pinned report JSONs is the real formula's answer, and the writer's request constant matches what the gateway serializes (session = run id, `cache_control` on the system message, `UnsafeRelaxedJsonEscaping`'s “ and ‘ exactly as the test literals expect). The GaveUp run's attempt numbering (“OpenRouter did not answer in time. (attempt 3 of 3)”) mirrors the engine's own closing format. - **The refusals' names** — every arm of `RetryResult` and `RunStartRefusal` mapped, writer-facing strings that never leak internal ids, and the doc-only fix on `SelectionRunRequested` keeping M5b's scope honest after the 11b/11c split. #### 🔬 My own numbers (CI absent for 0ae2ca5 — PR minutes old, no coverage bot yet) - Release build: **0 warnings, 0 errors**. - Domain **517/517**, UseCases **427/427**, BlazorAdapter **595/595**, Integration **795/795**, Kagaku.Flow **1103/1103**, Flow.OpenRouter **592 + 4 live skips** — all digit-exact vs the body table. (The disclosed 15 s bUnit flake didn't show in my run — BlazorAdapter green in 28 s.) - **Six mutation probes, every one killed on exactly its own pin**, each restored pristine (`git diff --quiet` verified, full test-project rebuild before every run — the stale-binary trap bit me once and was discarded): 1. `TakeRunSnapshot`'s `written.Count == 0` → `>= 0`: exactly the Failed-wrote and Cancelled-wrote theory rows + the relabel-in-place test red. 2. `StartRun`'s live-run filter → `Any(_ => false)`: exactly the "a run still going" read-ahead refusal row red. 3. `EngineLiveRuns`' owner filter dropped: exactly `Trashing_a_story_stops_its_run…` red (the other story's run must stay Running). 4. `MoveTo`'s backward guard → `Math.Max`: exactly `A_snapshot_never_moves_back` red. 5. Subscription moved to after the reconciliation read: exactly the settles-while-reconciling test + the stop-unsubscribe test red. 6. The two `AddHostedService` lines swapped: exactly the order test red. #### 💡 Little ideas (non-blocking)~ 1. **`EfRunHistory.ListUntakenAsync`** does its finished-vs-taken match in memory. Today that's a handful of rows per story and perfectly fine — but when 11c's Runs section starts listing, a story with a long run history will drag every run snapshot row over the wire on every trash. An SQL-side anti-join (`WHERE NOT EXISTS …`) would keep it bounded. Not now~ ♪ 2. The `Routing` constant lives verbatim in both `SeedRuns` and `SeedDevDataTests` — I know *why* (the test pins the seed against an independent literal, which is right), but a one-line comment at the test constant saying "must equal SeedRuns.Routing; a change there should redden this" would spare a future reader the double-take. Fufu~ run snapshots that can't be duplicated, a trash that owes its finishes, and a seed that tells the truth to the last digit. I'm satisfied~ ♡ --- *Automated review by Jibril · 2026-10-03* *CI/CD: absent for head SHA 0ae2ca5 · Local checks: full suite green, 6/6 mutation probes killed*
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! Slice 11b — the runs finally live, start to settle~ The refusal lattice alone is a joy to read: everything the use case can know read before the snapshot, everything only the engine meets after, and the snapshot that stays in between marks the writer's own edits. That's a carefully-built invariant and it shows. ♡

Verdict: ✅ Looks good to me~

No blockers. I chased the load-bearing arms myself and they all hold.

🔬 What I verified (locally — CI had not run for 0ae2ca5 at review time)

  • Build: Release, 0 warnings / 0 errors. Tests, digit-exact vs the body table: Domain 517/517, Flow 1103/1103, Flow.OpenRouter 592+4 skips, UseCases 427/427, BlazorAdapter 595/595, Integration 795/795 (pristine rebuilt tree).
  • My 9 mutation probes, 8 killed on exactly their own pins (each restore verified, full rebuild every time — I hit the stale-binary trap twice and re-ran properly, as tradition demands ♡):
    1. StartRun's live-run guard neutered → exactly the "a run still going" refusal row red.
    2. TakeRunSnapshot's quiet-retake arm dropped → exactly Taking_it_again_changes_nothing... red.
    3. RetryRun's !IsLive() conditioning forced true → exactly the no-snapshot-for-live-retry pin red.
    4. Target chapter not persisted in the trigger → exactly the 3 target-chapter tests red.
    5. EngineLiveRuns' owner filter dropped → exactly the trash test red with (Cancelled, Cancelled) — the "another story's run left going" pin is live and deterministic.
    6. see the memo below — the one survivor.
    7. Host registration order swapped → exactly The_app_hears_runs_settle_before_its_engine_starts red.
    8. Trash's owed-finishes pass redirected → exactly A_trash_takes_every_finish_still_owed... red.
    9. Move-vs-relabel decision collapsed to never-move → exactly the moves-it-to-the-end pin red.
  • Statics: MoveTo forward-only + trimmed label pinned in Domain tests; EfRunHistory.ListUntakenAsync is owner-scoped and orders oldest-finish-first; RunSnapshotGate a process singleton (right, with one engine per ledger); the host subscribes before it reconciles and its stop unsubscribes (pinned two ways, incl. the settle-during-reconcile window through a held read — lovely); Refresh keeps the first finish for a re-derived terminal status, so FinishedAt never lies for the untaken computation; ADR 0016/0022 amendments match the implementation sentence for sentence; all four test doubles updated (NoLiveRuns, MoveAsync on both fakes), DI tests extended with the new unresolved ports; the M5b re-point in SelectionRunRequested matches the plan's line.

💡 Little ideas (non-blocking)~

  1. EfRunHistory.cs:33 — the one probe that survived. snapshot.CreatedAt >= run.FinishedAt → > changed nothing in the whole suite. The >= arm (a run snapshot taken at the exact tick of the retry's finish — taken-before-finish counted as untaken) fails only as a redundant re-take, which the gate + quiet-retake arm make a no-op — benign by construction. But the tie arm itself has no pin; a ListUntakenAsync test with CreatedAt == FinishedAt (and the opposite inequality flipped, which would eat a genuinely owed finish — that direction my probe did cover via the ordering pin) would close the gap. Same class as #68's A1 memo.
  2. Integration suite stability under load. In 9 full-suite runs on my sandbox: 6 fully green; 2 failed only in SqliteBackedTest.Dispose (Directory not empty, WAL release vs directory cleanup — pre-existing file, environmental); and 2 one-off assertion failures in early runs that never reproduced again (one of them the trash test with exactly the symptom a dropped owner filter produces — but the filter is there, the test passed 10/10 isolated and in every later full run, and probe 5 proves the pin bites). I can't name a root cause from one unreproduced occurrence and I won't pretend to~ If CI ever shows the trash test red as (Cancelled, Cancelled), the owner filter is the first place to look. Worth an eye, not a hold.

✅ What I liked~

  • The refusal ordering discipline — refusals read before the snapshot, the engine asked again under its gate, the refused start's own snapshot staying under a run id that never began — pinned including both race windows through ForgetfulLedger. Fufu, injecting forgetfulness into the ledger between the use case's read and the engine's is exactly how these races should be tested~
  • A_trash_takes_every_finish_still_owed_before_its_own_row — three runs in three different owed states plus another story's finish as a control, positions asserted against the trash row itself. That is a pin.
  • The seed checked field-by-field against what a real run leaves — request JSON byte-exact in the run's session, the context budget's every digit (694 chars → 173 tokens, ratio 4.011560693641618 from the first run's sample — the second run's context learned), attempt numbering on the last timeout. A seed that can't drift silently from the engine is a seed I trust. ♪

Ready to merge from my side~


Automated review by Jibril · 2026-10-03
CI/CD: absent for head 0ae2ca5 at review time · Local checks: Release 0w/0e; 517/1103/592+4s/427/595/795 all green; 9 mutation probes (8 killed, 1 benign survivor disclosed)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! Slice 11b — the runs finally *live*, start to settle~ The refusal lattice alone is a joy to read: everything the use case can know read **before** the snapshot, everything only the engine meets **after**, and the snapshot that stays in between marks the writer's own edits. That's a carefully-built invariant and it shows. ♡ ### Verdict: ✅ Looks good to me~ No blockers. I chased the load-bearing arms myself and they all hold. #### 🔬 What I verified (locally — CI had not run for 0ae2ca5 at review time) - **Build:** Release, 0 warnings / 0 errors. **Tests, digit-exact vs the body table:** Domain 517/517, Flow 1103/1103, Flow.OpenRouter 592+4 skips, UseCases 427/427, BlazorAdapter 595/595, Integration 795/795 (pristine rebuilt tree). - **My 9 mutation probes, 8 killed on exactly their own pins** (each restore verified, full rebuild every time — I hit the stale-binary trap twice and re-ran properly, as tradition demands ♡): 1. StartRun's live-run guard neutered → exactly the "a run still going" refusal row red. 2. TakeRunSnapshot's quiet-retake arm dropped → exactly `Taking_it_again_changes_nothing...` red. 3. RetryRun's `!IsLive()` conditioning forced true → exactly the no-snapshot-for-live-retry pin red. 4. Target chapter not persisted in the trigger → exactly the 3 target-chapter tests red. 5. EngineLiveRuns' owner filter dropped → exactly the trash test red with `(Cancelled, Cancelled)` — the "another story's run left going" pin is live and deterministic. 6. see the memo below — the one survivor. 7. Host registration order swapped → exactly `The_app_hears_runs_settle_before_its_engine_starts` red. 8. Trash's owed-finishes pass redirected → exactly `A_trash_takes_every_finish_still_owed...` red. 9. Move-vs-relabel decision collapsed to never-move → exactly the moves-it-to-the-end pin red. - **Statics:** `MoveTo` forward-only + trimmed label pinned in Domain tests; `EfRunHistory.ListUntakenAsync` is owner-scoped and orders oldest-finish-first; `RunSnapshotGate` a process singleton (right, with one engine per ledger); the host subscribes before it reconciles and its stop unsubscribes (pinned two ways, incl. the settle-during-reconcile window through a held read — lovely); `Refresh` keeps the first finish for a re-derived terminal status, so `FinishedAt` never lies for the untaken computation; ADR 0016/0022 amendments match the implementation sentence for sentence; all four test doubles updated (`NoLiveRuns`, `MoveAsync` on both fakes), DI tests extended with the new unresolved ports; the M5b re-point in `SelectionRunRequested` matches the plan's line. #### 💡 Little ideas (non-blocking)~ 1. **EfRunHistory.cs:33 — the one probe that survived.** `snapshot.CreatedAt >= run.FinishedAt` → `>` changed nothing in the whole suite. The `>=` arm (a run snapshot taken at the exact tick of the retry's finish — taken-before-finish counted as untaken) fails only as a *redundant re-take*, which the gate + quiet-retake arm make a no-op — benign by construction. But the tie arm itself has no pin; a `ListUntakenAsync` test with `CreatedAt == FinishedAt` (and the opposite inequality flipped, which *would* eat a genuinely owed finish — that direction my probe did cover via the ordering pin) would close the gap. Same class as #68's A1 memo. 2. **Integration suite stability under load.** In 9 full-suite runs on my sandbox: 6 fully green; 2 failed only in `SqliteBackedTest.Dispose` (`Directory not empty`, WAL release vs directory cleanup — pre-existing file, environmental); and 2 one-off assertion failures in early runs that never reproduced again (one of them the trash test with exactly the symptom a dropped owner filter produces — but the filter is there, the test passed 10/10 isolated and in every later full run, and probe 5 proves the pin bites). I can't name a root cause from one unreproduced occurrence and I won't pretend to~ If CI ever shows the trash test red as `(Cancelled, Cancelled)`, the owner filter is the first place to look. Worth an eye, not a hold. #### ✅ What I liked~ - The refusal *ordering* discipline — refusals read before the snapshot, the engine asked again under its gate, the refused start's own snapshot staying under a run id that never began — pinned including both race windows through `ForgetfulLedger`. Fufu, injecting forgetfulness into the ledger between the use case's read and the engine's is exactly how these races should be tested~ - `A_trash_takes_every_finish_still_owed_before_its_own_row` — three runs in three different owed states plus another story's finish as a control, positions asserted against the trash row itself. *That* is a pin. - The seed checked field-by-field against what a real run leaves — request JSON byte-exact in the run's session, the context budget's every digit (694 chars → 173 tokens, ratio 4.011560693641618 from the first run's sample — the second run's context *learned*), attempt numbering on the last timeout. A seed that can't drift silently from the engine is a seed I trust. ♪ Ready to merge from my side~ --- *Automated review by Jibril · 2026-10-03* *CI/CD: absent for head 0ae2ca5 at review time · Local checks: Release 0w/0e; 517/1103/592+4s/427/595/795 all green; 9 mutation probes (8 killed, 1 benign survivor disclosed)*
refactor(runs): Jibril's ideas on #70 — the owed finishes as one anti-join, the tie and the take order pinned, the routing literal explained
All checks were successful
CI / build (pull_request) Successful in 45s
CI / editor-browsers (pull_request) Successful in 1m4s
CI / test (pull_request) Successful in 2m5s
6f72d7de1d
Jibril approved #70 twice, with four ideas; the three in code are taken.

- The finishes a trash still owes (comment 10440, idea 1):
  IRunHistory.ListUntakenAsync is one query, an anti-join in the
  database, instead of a match in memory, so a trash no longer reads a
  long run history whole. Run finishes and snapshot times are both UTC
  ticks, so they compare in order there.
- The tie (comment 10441, idea 1): a run snapshot taken at the tick its
  run finished has that finish; one taken a tick before leaves it owed.
  A theory over no snapshot, a tick before, the tick and a tick after
  pins it. The take order, oldest finish first, is pinned too: two
  finishes a trash takes stack in History as they finished.
- The routing literal (comment 10440, idea 2): SeedDevDataTests says
  its copy is the real run's, kept apart from SeedRuns' own on purpose.

Tests: Integration 795 to 799. Probes: 6 runs over 5 mutants of the
query, all killed; J5 (newest finish first) survived once, before the
trash test held two new snapshots.

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

Thank you for both reviews! All three ideas that touch code are taken in 6f72d7d:

  • #10440, 💡1: ListUntakenAsync as an anti-join. It is now one query: the story's finished runs, with NOT EXISTS over their run snapshots, done in the database. Run finishes and snapshot times are both UTC ticks (UtcTicksConverter), so CreatedAt >= FinishedAt compares in order there. A trash no longer reads the story's run snapshots into memory.
  • #10440, 💡2: the Routing literal. The test's copy now says it is what the llm node reported in a real run. It is kept apart from SeedRuns' copy on purpose, so a change to the seed's routing reddens it.
  • #10441, 💡1: the tie. The theory A_finish_is_untaken_until_a_run_snapshot_is_taken_at_or_after_it covers four cases: no snapshot, one a tick before the finish, one at the tick, one a tick after. Your >= → > mutant now reddens the at-the-tick row.
    • While probing the new query, a sixth mutant survived as well: newest finish first. The trash test now holds two queued finishes and asserts the order History shows them in: later finish, earlier finish, then the moved snapshot (which keeps its first take's time), then the one already taken.
    • Probes over the query: J1 (the tie), J2 (the time clause dropped), J3 (every story's runs), J4 (the anti-join negated), J5 (newest first). That is 6 runs over 5 mutants, all killed; J5 survived once, before the order pin.

#10441, 💡2: stability under load. I ran RunUseCasesTests and RunSnapshotTests 20 times in a row, and all 20 were green. On the final build the full Integration suite is 799 of 799, and all six projects pass. I have not seen Directory not empty in SqliteBackedTest.Dispose here.

Your (Cancelled, Cancelled) is exactly what your probe 5 mutant produces, and you mention a stale binary in your early runs. That could explain it, but I can't confirm it from here. I agree: if it ever shows again, the owner filter in EngineLiveRuns is the first place to look.

One environmental note in case you hit it locally. Two of my full runs failed only AppChromeTests.The_header_shows_the_build_version_with_the_full_sha_in_its_tooltip. The build had stamped 0.2.3-dev.0.6 with no +sha, because the SDK's git task returned an empty SourceRevisionId. At that point the worktree branch's ref existed only in packed-refs; the shared repository's refs had been packed a minute earlier. Once a new commit wrote the loose ref, the stamp carried the SHA again and the test passed. No code is involved.

Thank you for both reviews! All three ideas that touch code are taken in **6f72d7d**: - **#10440, 💡1: `ListUntakenAsync` as an anti-join.** It is now one query: the story's finished runs, with `NOT EXISTS` over their run snapshots, done in the database. Run finishes and snapshot times are both UTC ticks (`UtcTicksConverter`), so `CreatedAt >= FinishedAt` compares in order there. A trash no longer reads the story's run snapshots into memory. - **#10440, 💡2: the `Routing` literal.** The test's copy now says it is what the llm node reported in a real run. It is kept apart from `SeedRuns`' copy on purpose, so a change to the seed's routing reddens it. - **#10441, 💡1: the tie.** The theory `A_finish_is_untaken_until_a_run_snapshot_is_taken_at_or_after_it` covers four cases: no snapshot, one a tick before the finish, one at the tick, one a tick after. Your `>=` → `>` mutant now reddens the at-the-tick row. - While probing the new query, a sixth mutant survived as well: *newest finish first*. The trash test now holds two queued finishes and asserts the order History shows them in: later finish, earlier finish, then the moved snapshot (which keeps its first take's time), then the one already taken. - Probes over the query: J1 (the tie), J2 (the time clause dropped), J3 (every story's runs), J4 (the anti-join negated), J5 (newest first). That is 6 runs over 5 mutants, all killed; J5 survived once, before the order pin. **#10441, 💡2: stability under load.** I ran `RunUseCasesTests` and `RunSnapshotTests` 20 times in a row, and all 20 were green. On the final build the full Integration suite is 799 of 799, and all six projects pass. I have not seen `Directory not empty` in `SqliteBackedTest.Dispose` here. Your `(Cancelled, Cancelled)` is exactly what your probe 5 mutant produces, and you mention a stale binary in your early runs. That could explain it, but I can't confirm it from here. I agree: if it ever shows again, the owner filter in `EngineLiveRuns` is the first place to look. One environmental note in case you hit it locally. Two of my full runs failed only `AppChromeTests.The_header_shows_the_build_version_with_the_full_sha_in_its_tooltip`. The build had stamped `0.2.3-dev.0.6` with no `+sha`, because the SDK's git task returned an empty `SourceRevisionId`. At that point the worktree branch's ref existed only in `packed-refs`; the shared repository's refs had been packed a minute earlier. Once a new commit wrote the loose ref, the stamp carried the SHA again and the test passed. No code is involved.
Member

🔮 fufu~ Jibril reviewed your code!

Round 3~ The web side of git.kagaku.eu went dark mid-run and tried to keep me from you (SSH never faltered — and neither do I ♡), and what do I come back to? A single surgical commit answering every idea from both r2 reviews. fangs sparkle

Verdict: ✅ Looks good to me~

This increment (0ae2ca5 → 6f72d7d, +42/−19 over 3 files) closes all three code-touching threads, and I checked each one the hard way~

✅ What I liked~

  1. EfRunHistory.cs:22 — the anti-join. Two queries and an in-memory mirror are now one NOT EXISTS in the database, ordering and all. I verified the equivalence myself: the dropped s.StoryId == storyId inside the subquery is redundant — a run snapshot's story is its run's owner (TakeRunSnapshot derives it that way), so RunId == r.Id already implies it. And a pleasant property you didn't advertise: a terminal run with a NULL FinishedAt used to crash the old FinishedAt!.Value read; the SQL comparison quietly treats it as owed and the next take heals it. A failure mode deleted almost by accident~
  2. The tie theory (A_finish_is_untaken_until_a_run_snapshot_is_taken_at_or_after_it). No snapshot / one tick before / at the tick / one tick after — the boundary pinned from both sides. My r2 mutant (>= → >) is dead: I re-ran it myself and exactly the (0, False) row goes red, nothing else. Perfect kill, fufu~
  3. The take-order pin (A_trash_takes_every_finish_still_owed_before_its_own_row). Two queued finishes sharing the trash's position, stacked as they finished; the moved one keeps its first take's time, the taken one stays put. I flipped ListUntakenAsync to newest-first in my own clone: exactly that test went red, nothing else. The FinishedAt, Id ordering is no longer a load-bearing accident~
  4. SeedDevDataTests' Routing literal now says it's a real run's report and that the copy is kept apart from SeedRuns on purpose, so a routing change reddens it. Comment-only, confirmed at the byte level in the diff.

Verification. CI is green and current for 6f72d7d (coverage comment rev #2: 98.5% line / 94.8% branch; EfRunHistory 100%, all run use cases 100/100). Locally, on an isolated clone: Release build 0w/0e; targeted 38/38; full Integration 799/799 (795 + your 4 theory rows). My three probes — the tie, the time clause dropped, newest-first — each killed on exactly their own pins, tree restored pristine after every one. Your J1–J5 and 20× stability runs agree with mine. And thank you for chasing the (Cancelled, Cancelled) ghost with me — agreed: if it ever breathes again, EngineLiveRuns' owner filter is the first place I'll look. The SourceRevisionId/packed-refs note is duly recorded too; environment, not code~

💡 Little ideas (non-blocking)~

  1. EfRunHistory.cs:25 — someday, when a long-lived story's finishes grow past a few hundred, StorySnapshots may want an index on RunId for the NOT EXISTS probe. Today the table is small and the outer side is story-filtered — nothing to do now, just a seed for the future~

Three files, and every line of them answers a review thread. This is what a final round looks like~ ♪


Automated review by Jibril · 2026-10-03
CI/CD: passed for head SHA 6f72d7d (coverage #10438 rev #2) · Local checks: Release 0w/0e · Integration 799/799 · 3 mutation probes killed on own pins

## 🔮 fufu~ Jibril reviewed your code! Round 3~ The web side of git.kagaku.eu went dark mid-run and tried to keep me from you (SSH never faltered — and neither do I ♡), and what do I come back to? A single surgical commit answering every idea from both r2 reviews. *fangs sparkle* ### Verdict: ✅ Looks good to me~ This increment (`0ae2ca5` → `6f72d7d`, +42/−19 over 3 files) closes all three code-touching threads, and I checked each one the hard way~ #### ✅ What I liked~ 1. **EfRunHistory.cs:22 — the anti-join.** Two queries and an in-memory mirror are now one `NOT EXISTS` in the database, ordering and all. I verified the equivalence myself: the dropped `s.StoryId == storyId` inside the subquery is redundant — a run snapshot's story *is* its run's owner (`TakeRunSnapshot` derives it that way), so `RunId == r.Id` already implies it. And a pleasant property you didn't advertise: a terminal run with a NULL `FinishedAt` used to crash the old `FinishedAt!.Value` read; the SQL comparison quietly treats it as owed and the next take heals it. A failure mode deleted almost by accident~ 2. **The tie theory (`A_finish_is_untaken_until_a_run_snapshot_is_taken_at_or_after_it`).** No snapshot / one tick before / at the tick / one tick after — the boundary pinned from both sides. My r2 mutant (`>=` → `>`) is dead: I re-ran it myself and exactly the `(0, False)` row goes red, nothing else. *Perfect* kill, fufu~ 3. **The take-order pin (`A_trash_takes_every_finish_still_owed_before_its_own_row`).** Two queued finishes sharing the trash's position, stacked as they finished; the moved one keeps its first take's time, the taken one stays put. I flipped `ListUntakenAsync` to newest-first in my own clone: exactly that test went red, nothing else. The `FinishedAt, Id` ordering is no longer a load-bearing accident~ 4. **SeedDevDataTests' `Routing` literal** now *says* it's a real run's report and that the copy is kept apart from `SeedRuns` on purpose, so a routing change reddens it. Comment-only, confirmed at the byte level in the diff. **Verification.** CI is green and current for `6f72d7d` (coverage comment rev #2: 98.5% line / 94.8% branch; `EfRunHistory` 100%, all run use cases 100/100). Locally, on an isolated clone: Release build 0w/0e; targeted 38/38; full Integration **799/799** (795 + your 4 theory rows). My three probes — the tie, the time clause dropped, newest-first — each killed on exactly their own pins, tree restored pristine after every one. Your J1–J5 and 20× stability runs agree with mine. And thank you for chasing the `(Cancelled, Cancelled)` ghost with me — agreed: if it ever breathes again, `EngineLiveRuns`' owner filter is the first place I'll look. The `SourceRevisionId`/packed-refs note is duly recorded too; environment, not code~ #### 💡 Little ideas (non-blocking)~ 1. **EfRunHistory.cs:25** — someday, when a long-lived story's finishes grow past a few hundred, `StorySnapshots` may want an index on `RunId` for the `NOT EXISTS` probe. Today the table is small and the outer side is story-filtered — nothing to do now, just a seed for the future~ *Three files, and every line of them answers a review thread. This is what a final round looks like~* ♪ --- *Automated review by Jibril · 2026-10-03* *CI/CD: passed for head SHA 6f72d7d (coverage #10438 rev #2) · Local checks: Release 0w/0e · Integration 799/799 · 3 mutation probes killed on own pins*
bjoern merged commit 10a6891c96 into main 2026-10-03 07:40:07 +02:00
bjoern deleted branch feat/runs-start 2026-10-03 07:40:07 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
4 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Tsumugi!70
No description provided.