feat(runs): the Runs section — the story's run history, its versions in History, Clear run history (slice 11c) #75

Merged
bjoern merged 7 commits from feat/runs-section into main 2026-10-03 12:57:54 +02:00
Member

Slice 11c of Phase 2 (docs/PROJECT_PLAN.md): the Runs section. A story's runs get their own section, stories/{id}/runs (ADR 0024, 0027), the fifth entry in the story's sidebar. It lists the story's runs, links each one to its version in History, and can clear the history.

The branch is rebased onto main with the "let git do the tracking" rule: the docs name no PR number, and the plan's ✅ lands in the branch.

What lands

  • The run history.
    • ListStoryRuns lists the story's runs newest first, live ones too. Each shows its graph, how it was triggered and the chapter it writes into (ADR 0012), when it started and finished, its outcome, what it wrote and its run snapshot (ADR 0022).
    • What a run wrote is its operations' labels, by the same rule as its run snapshot's label (RunWrites).
    • IRunHistory.ListAsync reads it in three queries: the runs, their run snapshots, and the journal rows that name a run.
  • The page.
    • A table with these columns:
      • Started;
      • Graph;
      • Trigger: Story or Selection, the Graphs page's words, above the chapter's link, or a deleted chapter;
      • Duration: going while live;
      • Outcome;
      • Wrote;
      • Version.
    • The Version link opens the run's snapshot in History (stories/{id}/history?snapshot=<id>). That snapshot opens and takes the focus, so it scrolls into view, one click from Revert to here. A link that names no listed snapshot opens History as it is.
    • Cost waits for slice 14.
    • The page reads again on:
      • any status change of one of the story's runs;
      • any snapshot taken;
      • any chapter changed;
      • a history cleared, here or in another session.
  • Clear run history, behind a confirmation.
    • ClearRunHistory first takes every finish whose run snapshot is still owed.
    • IRunHistory.ClearAsync then deletes, in one write under the database's lock, the story's finished runs that have their snapshot or need none, with their rows. A run needs none when it failed or was cancelled and wrote nothing.
    • These stay: a live run, a finish whose snapshot is still owed, and the story's paragraphs, documents, journal and every snapshot.
    • The clear announces once per run deleted (EntityKinds.Run, announced and not journaled), so every open Runs section refreshes.
    • It is refused for a story that is gone or in the trash.
  • A run snapshot records the finish it covers.
    • StorySnapshot.RunFinishedAt holds the run's finish as the snapshot's latest take read it. A finish is owed its snapshot until one covers it. The host's reconciliation, the trash and the clear all read that rule.
    • A take after a Retry covers the new finish even when it finds nothing to move or relabel.
    • A moved snapshot keeps the time it was first taken, so History's order does not change under it.
    • The migration RunSnapshotFinish adds the column and fills it for the run snapshots already kept:
      • one taken at or after its run's last finish covers it, the rule the build before read;
      • one taken before it covers none, so that finish is taken again.
  • The seed's later run ends when its last attempt does, so it spans the writer's edits; SeedDevDataTests failed once in a full run without it.
  • Docs. The amendments for slice 11c:
    • ADR 0022: the finish a run snapshot covers.
    • ADR 0024: the run history, the clear's rule, the cost decision, the reload triggers and the one gap left.
    • ADR 0027: Runs in the sidebar and the ?snapshot= route.
    • The plan ticks 11c.

Decisions

Question Decision Why
A cleared run's cost It leaves the story's cost to date with the run. The confirmation says so, and that there is no way back. ADR 0024 sums a story's cost from its runs' rows, and a clear deletes those rows. Keeping the spend would need a total stored apart from the ledger. Round 0's D2 asked for a decision.
What a clear keeps Live runs, owed finishes, and everything of the story. ADR 0024: run history is the ledger's rows, not the story. A run leaves only once its snapshot exists, so Revert to here outlives it.
A cancel still draining in another tab The one gap left, named in ADR 0024. Its run already reads cancelled, so a clear may take it before a write the drain lands. Closing it needs the engine to report the drain.
When a snapshot covers a finish It records the finish it read, not a time. Round 0 stamped a time. The second pass found three ways that went wrong; see Reviews.
The opened snapshot's key (id, true), apart from the plain one's id. One key may not move between the element that holds the focus's reference and one that does not: Blazor's diff throws.

Tests

Project main branch
Tsumugi.Domain.Tests 517 517
Kagaku.Flow.Tests 1103 1103
Kagaku.Flow.OpenRouter.Tests 596 (4 skipped, live) 596 (4 skipped, live)
Tsumugi.UseCases.Tests 498 499
Tsumugi.BlazorAdapter.Tests 640 687
Tsumugi.Integration.Tests 810 836

The main column is the branch's count less the cases the branch adds; main was not run on its own. Of six full runs, one (before the second pass) failed one BlazorAdapter test on a 15 s bUnit wait: DocumentsStoreFailureTests' first load, which this slice does not touch. The last full run, on the pushed tree, passed.

  • The run history: its runs newest first, with trigger and target chapter (a deleted one, a trigger Tsumugi does not know, one the ledger cannot read), outcome, what each wrote and its snapshot; a tie on the start; a manual version beside the runs; a story gone has none.
  • The clear's rule, as a theory over every kind of run: taken, owed, waiting, live; two runs, one taken and one owed; a Retry that succeeds or fails the same way again stays until its snapshot covers it.
  • The clear end to end: the owed snapshot taken first, the live run kept, another story's left alone, the story's paragraphs, journal and snapshots unchanged, the announcement; an empty clear; the refusals.
  • Run snapshots: a finish untaken until a snapshot covers it; a finish landing while a take is held stays owed; a relabel keeps its time; the trash's order.
  • The migration: what each kept snapshot covers, a Retry that failed the same way taken and cleared after the upgrade, and a walk down and up again.
  • The page at its URL:
    • the rows, the links, the trigger's wording, the badge tones and the header;
    • the nothing-to-clear states;
    • the clear behind its confirmation, Cancel clearing nothing, a clear under way holding its button;
    • a refusal; a failed first read said once;
    • the reload on a run settling or a history cleared elsewhere;
    • Runs lit on a run's own page.
  • History's deep link: the named snapshot opens and takes the focus once; a reload keeps it; one the URL cannot name opens nothing; another link followed, then History itself; the panel's opened snapshot giving way to another or to none, and the same one named again after none; a newer version keeps every Disclosure below.
  • The rest: the effects, the reducers, the durations, RunWrites' blank and missing labels, StorySnapshot's cover. The journal's registry test leaves out the announced-only Run kind, beside StorySnapshot.
  • Coverage: 100% line and branch on the changed lines (148 lines, 62 branches).
  • Mutation probes: 63 runs over 56 distinct compiling mutants, one build at a time.
    • The feature: 26 runs over 25 mutants, all killed. E9 (a clear without its story filter) survived once, before the clear test's other story held a run that needs no snapshot.
    • Round 0's fixes: 17 runs over 17 mutants, 15 killed. The two survivors showed guards that guarded nothing: the panel's own-story check, and Busy in the clear's Disabled. Both guards are gone.
    • The second pass's fixes: 17 runs over 11 mutants, all killed in the end. G10 puts one key back across History's two branches. It survived the first run, and bUnit's page path does not meet the crash the browser met: the page's link test passed on it in three runs. The panel's own test, added since, failed on it in both its runs.
    • Round 1's ideas: 3 runs over 3 mutants, all killed.

Reviews

Reviews ran as workflows, one agent at a time.

  • Round 0 (on 72b5523): reviewers for correctness, for the tests and for the docs, then one skeptic over every finding.
    • 25 findings: 13 suggestions and 12 nits after verification; 23 confirmed, 2 partly.
    • Taken in 834de28, but for three optional parts:
      • A5's reset of the section on leaving: History keeps reloading off its page the same way, and a run causes a few reloads.
      • D6's focus on the summary: the wrapper marks where to read, and the next Tab reaches the summary.
      • D7's "Cleared N runs." line: the list's own change shows it.
  • Second pass (on 834de28 and the plan tick): a check of every round-0 fix and of the fix commit, then a skeptic.
    • 30 of 31 checks resolved, 1 partly: D6, whose removed outline rule changed nothing, since Kagaku.UI's focus ring is a box-shadow.
    • 11 new findings: 1 blocker, 2 suggestions and 8 nits after the skeptic; 8 confirmed, 3 partly.
    • All taken in 81a7aed:
      • E4/F2 (the blocker): round 0 keyed every History snapshot with its id at the loop's level. Following another run's link, or leaving a link for History itself, then crashed the circuit. The opened snapshot has a key of its own now. The panel's test pins both moves; the page's test follows both links.
      • E1, E2, E3, F1: round 0's restamp left three gaps:
        • a Retry that failed the same way again was never cleared;
        • a relabel in place handed the run's writes to another snapshot in History;
        • a finish landing while a take was under way read as covered.
          A snapshot now records the finish it covers.
      • F3, F5, F6, F7: the effects' summary, the list test's tie, the link's UTC time, the seed's comment.
      • F4: 834de28's message said every suggestion was taken but A5's reset; 81a7aed's message names all three parts not taken.
  • Round 1 (Jibril, on 1632230, an empty commit that retriggered the review): approved, with two ideas, both taken in 5f9dacf (reply: comment 10625):
    • an unreadable trigger shows as one Tsumugi does not know, so one row never fails the story's whole history;
    • a snapshot named again after History itself takes the focus again.

App check (the sample world)

  • The upgrade on real data. The round-0 build seeded the sample world on a fresh data directory. Then this branch's build started on it:
    • it backed the database up, then applied RunSnapshotFinish;
    • the seeded run snapshot covers its run's finish, and the before-run snapshot covers nothing;
    • reconciling, the snapshots' host added none.
  • In the browser, on that database:
    • Runs listed both seeded runs. The failed one wrote nothing and has no Version link. The succeeded one shows "Commit appended 2 paragraphs" and the link.
    • In History opened that run's snapshot, which held the focus.
    • History in the sidebar, E4's path, closed it. The circuit stayed up.
    • Clear run history showed the confirmation. Confirmed, both runs left with their rows, the section said "No runs", and the button was disabled. The two snapshots and the 53 journal rows stayed.
  • No console errors or warnings. The server's log has one error: an antiforgery cookie the browser kept from an earlier data directory's key ring.

Seen, not fixed here

A sidebar link to the page already open leaves the tab's title at the shell's placeholder until a reload, for example "Tsumugi — Story · Documents". It happens with or without a query change. Seen on Documents, History and Runs. Documents predates this slice. Leaving ?snapshot= for History itself is one way to meet it. I can take it up separately.

🤖 Generated with Claude Code

Slice 11c of Phase 2 (`docs/PROJECT_PLAN.md`): **the Runs section**. A story's runs get their own section, `stories/{id}/runs` (ADR 0024, 0027), the fifth entry in the story's sidebar. It lists the story's runs, links each one to its version in History, and can clear the history. The branch is rebased onto main with the "let git do the tracking" rule: the docs name no PR number, and the plan's ✅ lands in the branch. ## What lands - **The run history.** - `ListStoryRuns` lists the story's runs newest first, live ones too. Each shows its graph, how it was triggered and the chapter it writes into (ADR 0012), when it started and finished, its outcome, what it wrote and its run snapshot (ADR 0022). - What a run wrote is its operations' labels, by the same rule as its run snapshot's label (`RunWrites`). - `IRunHistory.ListAsync` reads it in three queries: the runs, their run snapshots, and the journal rows that name a run. - **The page.** - A table with these columns: - Started; - Graph; - Trigger: *Story* or *Selection*, the Graphs page's words, above the chapter's link, or *a deleted chapter*; - Duration: *going* while live; - Outcome; - Wrote; - Version. - The Version link opens the run's snapshot in History (`stories/{id}/history?snapshot=<id>`). That snapshot opens and takes the focus, so it scrolls into view, one click from *Revert to here*. A link that names no listed snapshot opens History as it is. - Cost waits for slice 14. - The page reads again on: - any status change of one of the story's runs; - any snapshot taken; - any chapter changed; - a history cleared, here or in another session. - **Clear run history**, behind a confirmation. - `ClearRunHistory` first takes every finish whose run snapshot is still owed. - `IRunHistory.ClearAsync` then deletes, in one write under the database's lock, the story's finished runs that have their snapshot or need none, with their rows. A run needs none when it failed or was cancelled and wrote nothing. - These stay: a live run, a finish whose snapshot is still owed, and the story's paragraphs, documents, journal and every snapshot. - The clear announces once per run deleted (`EntityKinds.Run`, announced and not journaled), so every open Runs section refreshes. - It is refused for a story that is gone or in the trash. - **A run snapshot records the finish it covers.** - `StorySnapshot.RunFinishedAt` holds the run's finish as the snapshot's latest take read it. A finish is owed its snapshot until one covers it. The host's reconciliation, the trash and the clear all read that rule. - A take after a Retry covers the new finish even when it finds nothing to move or relabel. - A moved snapshot keeps the time it was first taken, so History's order does not change under it. - The migration `RunSnapshotFinish` adds the column and fills it for the run snapshots already kept: - one taken at or after its run's last finish covers it, the rule the build before read; - one taken before it covers none, so that finish is taken again. - **The seed's later run** ends when its last attempt does, so it spans the writer's edits; `SeedDevDataTests` failed once in a full run without it. - **Docs.** The amendments for slice 11c: - ADR 0022: the finish a run snapshot covers. - ADR 0024: the run history, the clear's rule, the cost decision, the reload triggers and the one gap left. - ADR 0027: Runs in the sidebar and the `?snapshot=` route. - The plan ticks 11c. ## Decisions | Question | Decision | Why | |---|---|---| | A cleared run's cost | It leaves the story's cost to date with the run. The confirmation says so, and that there is no way back. | ADR 0024 sums a story's cost from its runs' rows, and a clear deletes those rows. Keeping the spend would need a total stored apart from the ledger. Round 0's D2 asked for a decision. | | What a clear keeps | Live runs, owed finishes, and everything of the story. | ADR 0024: run history is the ledger's rows, not the story. A run leaves only once its snapshot exists, so *Revert to here* outlives it. | | A cancel still draining in another tab | The one gap left, named in ADR 0024. | Its run already reads cancelled, so a clear may take it before a write the drain lands. Closing it needs the engine to report the drain. | | When a snapshot covers a finish | It records the finish it read, not a time. | Round 0 stamped a time. The second pass found three ways that went wrong; see Reviews. | | The opened snapshot's key | `(id, true)`, apart from the plain one's `id`. | One key may not move between the element that holds the focus's reference and one that does not: Blazor's diff throws. | ## Tests | Project | main | branch | |---|---|---| | Tsumugi.Domain.Tests | 517 | 517 | | Kagaku.Flow.Tests | 1103 | 1103 | | Kagaku.Flow.OpenRouter.Tests | 596 (4 skipped, live) | 596 (4 skipped, live) | | Tsumugi.UseCases.Tests | 498 | 499 | | Tsumugi.BlazorAdapter.Tests | 640 | 687 | | Tsumugi.Integration.Tests | 810 | 836 | The main column is the branch's count less the cases the branch adds; main was not run on its own. Of six full runs, one (before the second pass) failed one BlazorAdapter test on a 15 s bUnit wait: `DocumentsStoreFailureTests`' first load, which this slice does not touch. The last full run, on the pushed tree, passed. - **The run history:** its runs newest first, with trigger and target chapter (a deleted one, a trigger Tsumugi does not know, one the ledger cannot read), outcome, what each wrote and its snapshot; a tie on the start; a manual version beside the runs; a story gone has none. - **The clear's rule,** as a theory over every kind of run: taken, owed, waiting, live; two runs, one taken and one owed; a Retry that succeeds or fails the same way again stays until its snapshot covers it. - **The clear end to end:** the owed snapshot taken first, the live run kept, another story's left alone, the story's paragraphs, journal and snapshots unchanged, the announcement; an empty clear; the refusals. - **Run snapshots:** a finish untaken until a snapshot covers it; a finish landing while a take is held stays owed; a relabel keeps its time; the trash's order. - **The migration:** what each kept snapshot covers, a Retry that failed the same way taken and cleared after the upgrade, and a walk down and up again. - **The page at its URL:** - the rows, the links, the trigger's wording, the badge tones and the header; - the nothing-to-clear states; - the clear behind its confirmation, Cancel clearing nothing, a clear under way holding its button; - a refusal; a failed first read said once; - the reload on a run settling or a history cleared elsewhere; - Runs lit on a run's own page. - **History's deep link:** the named snapshot opens and takes the focus once; a reload keeps it; one the URL cannot name opens nothing; another link followed, then History itself; the panel's opened snapshot giving way to another or to none, and the same one named again after none; a newer version keeps every Disclosure below. - **The rest:** the effects, the reducers, the durations, `RunWrites`' blank and missing labels, `StorySnapshot`'s cover. The journal's registry test leaves out the announced-only Run kind, beside `StorySnapshot`. - **Coverage:** 100% line and branch on the changed lines (148 lines, 62 branches). - **Mutation probes:** 63 runs over 56 distinct compiling mutants, one build at a time. - **The feature:** 26 runs over 25 mutants, all killed. E9 (a clear without its story filter) survived once, before the clear test's other story held a run that needs no snapshot. - **Round 0's fixes:** 17 runs over 17 mutants, 15 killed. The two survivors showed guards that guarded nothing: the panel's own-story check, and `Busy` in the clear's `Disabled`. Both guards are gone. - **The second pass's fixes:** 17 runs over 11 mutants, all killed in the end. G10 puts one key back across History's two branches. It survived the first run, and bUnit's page path does not meet the crash the browser met: the page's link test passed on it in three runs. The panel's own test, added since, failed on it in both its runs. - **Round 1's ideas:** 3 runs over 3 mutants, all killed. ## Reviews Reviews ran as workflows, one agent at a time. - **Round 0** (on 72b5523): reviewers for correctness, for the tests and for the docs, then one skeptic over every finding. - 25 findings: 13 suggestions and 12 nits after verification; 23 confirmed, 2 partly. - Taken in 834de28, but for three optional parts: - A5's reset of the section on leaving: History keeps reloading off its page the same way, and a run causes a few reloads. - D6's focus on the summary: the wrapper marks where to read, and the next Tab reaches the summary. - D7's "Cleared N runs." line: the list's own change shows it. - **Second pass** (on 834de28 and the plan tick): a check of every round-0 fix and of the fix commit, then a skeptic. - 30 of 31 checks resolved, 1 partly: D6, whose removed outline rule changed nothing, since Kagaku.UI's focus ring is a box-shadow. - 11 new findings: 1 blocker, 2 suggestions and 8 nits after the skeptic; 8 confirmed, 3 partly. - All taken in 81a7aed: - **E4/F2 (the blocker):** round 0 keyed every History snapshot with its id at the loop's level. Following another run's link, or leaving a link for History itself, then crashed the circuit. The opened snapshot has a key of its own now. The panel's test pins both moves; the page's test follows both links. - **E1, E2, E3, F1:** round 0's restamp left three gaps: - a Retry that failed the same way again was never cleared; - a relabel in place handed the run's writes to another snapshot in History; - a finish landing while a take was under way read as covered. A snapshot now records the finish it covers. - **F3, F5, F6, F7:** the effects' summary, the list test's tie, the link's UTC time, the seed's comment. - **F4:** 834de28's message said every suggestion was taken but A5's reset; 81a7aed's message names all three parts not taken. - **Round 1** (Jibril, on 1632230, an empty commit that retriggered the review): approved, with two ideas, both taken in 5f9dacf (reply: comment 10625): - an unreadable trigger shows as one Tsumugi does not know, so one row never fails the story's whole history; - a snapshot named again after History itself takes the focus again. ## App check (the sample world) - **The upgrade on real data.** The round-0 build seeded the sample world on a fresh data directory. Then this branch's build started on it: - it backed the database up, then applied `RunSnapshotFinish`; - the seeded run snapshot covers its run's finish, and the before-run snapshot covers nothing; - reconciling, the snapshots' host added none. - **In the browser,** on that database: - Runs listed both seeded runs. The failed one wrote nothing and has no Version link. The succeeded one shows "Commit appended 2 paragraphs" and the link. - *In History* opened that run's snapshot, which held the focus. - History in the sidebar, E4's path, closed it. The circuit stayed up. - *Clear run history* showed the confirmation. Confirmed, both runs left with their rows, the section said "No runs", and the button was disabled. The two snapshots and the 53 journal rows stayed. - No console errors or warnings. The server's log has one error: an antiforgery cookie the browser kept from an earlier data directory's key ring. ## Seen, not fixed here A sidebar link to the page already open leaves the tab's title at the shell's placeholder until a reload, for example "Tsumugi — Story · Documents". It happens with or without a query change. Seen on Documents, History and Runs. Documents predates this slice. Leaving `?snapshot=` for History itself is one way to meet it. I can take it up separately. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A story's runs have their own section now, stories/{id}/runs (ADR 0024,
0027), the fifth entry of the story's sidebar.

- The run history: ListStoryRuns lists the story's runs newest first,
  live ones too. Each shows its graph, how it was triggered and the
  chapter it writes into (ADR 0012), when it started and finished, its
  outcome, what it wrote and its run snapshot (ADR 0022). What it wrote
  is its operations' labels, by the same rule as its run snapshot's
  label (RunWrites). IRunHistory.ListAsync reads it in three queries:
  the runs, their run snapshots, and the journal rows that name a run.
- The page: a table — started, graph, trigger with a link to its chapter
  (or "a deleted chapter"), duration ("going" while live), outcome, what
  it wrote, and In History. That link opens the run's snapshot in History
  (stories/{id}/history?snapshot=<id>): the snapshot opens and takes the
  focus, so it scrolls into view, one click from Revert to here. Cost
  waits for slice 14. The page reads again when one of the story's runs
  starts or settles, a snapshot is taken, a chapter changes, or a history
  is cleared elsewhere.
- Clear run history, behind a confirmation. ClearRunHistory first takes
  every finish whose run snapshot is still owed. Then
  IRunHistory.ClearAsync deletes, in one write under the database's lock,
  the story's finished runs that have their snapshot or need none (a
  failed or cancelled run that wrote nothing), with their rows. A live
  run stays, and so does a finish whose snapshot is still owed;
  paragraphs, documents, the journal and every snapshot stay. The clear
  announces once per run deleted (EntityKinds.Run, announced and not
  journaled), so every open Runs section refreshes. It is refused for a
  story that is gone or in the trash.
- Docs: ADR 0024 and 0027 amended (slice 11c).

Tests: Integration 799 to 815, BlazorAdapter 595 to 631.
- The run history: its runs newest first, with trigger and target
  chapter (a deleted one, a trigger Tsumugi does not know), outcome,
  what each wrote and its snapshot; a story gone has none.
- The clear's rule, as a theory over every kind of run.
- The clear end to end: the owed snapshot taken first, the live run
  kept, another story's left alone, the story's paragraphs, journal and
  snapshots unchanged, the announcement.
- An empty clear; the refusals.
- The page at its URL: the rows, the links, the trigger's wording, the
  nothing-to-clear states, the clear behind its confirmation, a refusal,
  a failed first read, the reload on a run settling or a history cleared
  elsewhere.
- The effects, the reducers, the durations, the Runs entry, and History
  opening and focusing the snapshot its URL names once.
- The journal's registry test now leaves out the announced-only Run
  kind, beside StorySnapshot.
All six projects pass; 100% line and branch coverage on the changed
lines.
Probes: 26 runs over 25 distinct compiling mutants, all killed. E9 (a
clear without its story filter) survived once, before the clear test's
other story held a run that needs no snapshot.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Round 0, a review workflow over the feature commit: 25 findings — 13 suggestions
and 12 nits after verification; 23 confirmed, 2 partly. All are taken
but one optional part: A5's reset of the section on leaving, since
History keeps reloading off its page the same way, and a run causes a
few reloads. What several reviewers found together is fixed once.

- One rule for an owed snapshot (A1, B3, D1). The clear counted a run as
  snapshotted once any run snapshot named it. A Retry's finish landing
  between the clear's take and its delete then left its run, and the
  snapshot kept "(failed)" and its old place. Now a moved or relabelled
  run snapshot is stamped with the time of that take
  (StorySnapshot.MoveTo, ISnapshotStore.MoveAsync). A finish is owed
  until a snapshot is taken at or after it, the rule ListUntakenAsync
  already read and ClearAsync now reads too. A cancel still draining in
  another tab is the one gap left; ADR 0024 names it.
- History's snapshots keyed at the loop again (A2, B1). Every Disclosure
  was recreated when a newer snapshot landed, collapsing what the writer
  had expanded.
- A late clear of another story leaves this one's list alone (A3): the
  reload follows only the story still open.
- A malformed ?snapshot= opens History as it is (A4); the reload
  triggers are named in ADR 0024 as the code has them (A5).
- The page's words (D2-D7):
  - the trigger in the Graphs page's words, Story or Selection, above
    the chapter;
  - the link column headed Version, each link named for its run;
  - the confirmation says a cleared run's cost leaves the story's cost to
    date and that there is no way back — ADR 0024 decides the cost;
  - the empty state fits after a clear too;
  - the opened snapshot keeps the browser's focus ring for the keyboard.
- EntityKinds' remarks name both announced-only kinds, and Run is
  nameof(Kagaku.Flow.Runs.Run) (D8).
- The pins the review asked for (B2, B4-B10, D9, D10):
  - two runs, one taken and one owed, in one story;
  - a waiting run kept; a retried run kept until its snapshot is taken
    again;
  - a manual version beside the runs; a tie on start time;
  - Cancel clearing nothing; a clear under way holding its button; a
    failed first read said once;
  - the Started times, a second graph, two labels, the badge tones and
    the header;
  - Runs lit on a run's own page;
  - the focus on the opened snapshot itself, and none for a snapshot the
    URL cannot name;
  - RunWrites' blank and missing labels.
- Docs: ADR 0024's and 0022's slice-11c amendments.

Tests: Integration 815 to 818, BlazorAdapter 631 to 638, UseCases 427 to
428 (RunWrites); the snapshot's move in Domain. All six projects pass;
100% line and branch coverage on the changed lines.
Probes: 17 runs over 17 distinct compiling mutants of the fixes; 15
killed. The two that survived showed two guards that guarded nothing, and
both are gone:
- the panel's own-story check: the reload's own check leaves nothing for
  it;
- Busy in the clear's Disabled: the button's Loading disables it already.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The seeded later run's last timeout ended at 95% of its span, and so did
the run, while the writer's three edits since the last version lie
anywhere in that span. SeedDevDataTests asserts they fall inside the
run, and it failed whenever an edit landed in the last 5% (once in a
full run). The attempts now run 0.1-0.4, 0.4-0.7 and 0.7-1 of the span,
and the run finishes at its end. The seed tests passed five times in a
row after the change.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fix(runs): second pass of slice 11c — a run snapshot records the finish it covers, History's opened snapshot keyed apart
All checks were successful
CI / build (pull_request) Successful in 44s
CI / editor-browsers (pull_request) Successful in 1m11s
CI / test (pull_request) Successful in 2m27s
81a7aed6dc
Second pass, a review workflow over round 0's fixes: 11 findings — one
blocker, two suggestions and eight nits after verification; 8
confirmed, 3 partly. All are taken. Of round 0's 31 points the pass
checked, 30 are resolved and D6 partly, below.

- History's opened snapshot has a key of its own (E4, F2). Round 0 keyed
  every snapshot with its id at the loop's level, so one key moved
  between the opened div, which holds the focus's reference, and a plain
  one. Following another run's link, or leaving a link for History
  itself, then crashed the circuit (NotImplementedException from the
  render tree's diff). The opened div is keyed (id, true) now.
- A run snapshot records the finish it covers (E1, E2, E3, F1), in place
  of round 0's restamp. Round 0 stamped a moved or relabelled snapshot
  with the time of its take, which left three gaps:
  - a Retry that failed the same way again changed nothing, so its take
    returned early, and the clear never removed the run;
  - a relabel in place sorted the snapshot after the others at its
    position, so History gave the run's writes to another snapshot;
  - a finish landing while a take was under way read as covered.
  StorySnapshot.RunFinishedAt now holds the run's finish as the latest
  take read it. A finish is owed until a snapshot covers it, in
  ListUntakenAsync and ClearAsync alike. A take returns early only when
  its snapshot already covers the finish, and a moved snapshot keeps
  its first time. The migration RunSnapshotFinish adds the column and
  fills it for the run snapshots kept: one taken at or after its run's
  last finish covers it, the rule the build before read; one taken
  before it covers none. ADR 0022's and 0024's slice-11c amendments say
  so; a cancel still draining elsewhere is the one gap left.
- RunsEffects' summary names the reload triggers as ADR 0024 does (F3).
- The list test's tie has two ordered ids (F5).
- The Version link's name reads the start's UTC time (F6).
- The seed's comment in plain words (F7).
- Round 0's message, corrected (F4): besides A5's reset, two optional
  parts were not taken. D6's focus on the summary: the wrapper marks
  where to read, and the next Tab reaches the summary. D7's "Cleared N
  runs." line: the list's own change shows it. D6's removed outline
  rule changed nothing either way: Kagaku.UI's focus ring is a
  box-shadow, which that rule never touched.

Tests: Integration 829 to 833, BlazorAdapter 683 to 686.
- The held take: a Retry finishing meanwhile stays owed.
- A Retry that succeeds, or fails the same way again: owed until taken
  again, then cleared.
- A relabel keeps the snapshot's time; the trash's order is the one
  before round 0 again.
- The migration: what each kept snapshot covers, a Retry that failed the
  same way taken and cleared after the upgrade, and a walk down and up
  again.
- The panel's opened snapshot giving way to another or to none; the
  page, one link followed, then another, then History itself.
All six projects pass; 100% line and branch coverage on the changed
lines.
Probes: 17 runs over 11 distinct compiling mutants, all killed in the
end.
- G10, one key again across History's two branches, survived the first
  run. Through the page, bUnit does not meet the crash the browser met:
  the page's test of the links passed on it in three runs, and aborted
  the test host in one run by hand (a stack overflow in bUnit's markup
  walk). The panel's own test, added since, failed on it in both its
  runs.
- G8 and G9, the backfill's two halves, ran again once the migration
  test's Retry failed the same way; the take's branch for a snapshot
  that covers nothing yet was uncovered before.

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: 5f9dacf · Generated: 2026-10-03 10:53:04 UTC · Revision: #3

Summary

Summary
Generated on: 10/03/2026 - 10:53:04
Coverage date: 10/03/2026 - 10:52:11 - 10/03/2026 - 10:53:00
Parser: MultiReport (6x Cobertura)
Assemblies: 9
Classes: 640
Files: 546
Line coverage: 98.6% (21340 of 21634)
Covered lines: 21340
Uncovered lines: 294
Coverable lines: 21634
Total lines: 44048
Branch coverage: 94.9% (7091 of 7470)
Covered branches: 7091
Total branches: 7470
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.9%
Name Line Branch
Tsumugi.BlazorAdapter 96.9% 92.4%
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.ClearRunHistoryRequested 100%
Tsumugi.BlazorAdapter.Runs.LoadRunHistory 100%
Tsumugi.BlazorAdapter.Runs.RunChangedBridge 97.3% 91.6%
Tsumugi.BlazorAdapter.Runs.RunChangesReceived 100%
Tsumugi.BlazorAdapter.Runs.RunHistoryClearFailed 100%
Tsumugi.BlazorAdapter.Runs.RunHistoryLoaded 100%
Tsumugi.BlazorAdapter.Runs.RunHistoryPanel 100% 97.8%
Tsumugi.BlazorAdapter.Runs.RunHistoryReadFailed 100%
Tsumugi.BlazorAdapter.Runs.RunsEffects 100% 100%
Tsumugi.BlazorAdapter.Runs.RunsPage 100%
Tsumugi.BlazorAdapter.Runs.RunsReducers 100% 100%
Tsumugi.BlazorAdapter.Runs.RunsState 100%
Tsumugi.BlazorAdapter.Runs.RunTextKey 100%
Tsumugi.BlazorAdapter.Runs.RunTextReceived 100%
Tsumugi.BlazorAdapter.Runs.RunTimes 100% 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.EditorAppearanceCss 100% 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceEffects 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceLoaded 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceReducers 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceState 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% 90%
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.7% 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 - 99%
Name Line Branch
Tsumugi.Infrastructure 99% 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.RunSnapshotFinish 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 92.2% 81.5%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__HexColour_1
94.8% 87.5%
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.ClearRunHistory 100% 100%
Tsumugi.UseCases.Runs.EngineLiveRuns 100% 100%
Tsumugi.UseCases.Runs.ListStoryRuns 100% 100%
Tsumugi.UseCases.Runs.LiveTail 100%
Tsumugi.UseCases.Runs.LlmConcurrencyLimit 100%
Tsumugi.UseCases.Runs.RetryRun 100% 100%
Tsumugi.UseCases.Runs.RunHistoryEntry 100%
Tsumugi.UseCases.Runs.RunSnapshotGate 100%
Tsumugi.UseCases.Runs.RunWrites 100%
Tsumugi.UseCases.Runs.StartRun 100% 100%
Tsumugi.UseCases.Runs.StoryRunItem 100%
Tsumugi.UseCases.Runs.StoryRunsView 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.ColourPair 100% 100%
Tsumugi.UseCases.Settings.EditorAppearance 100%
Tsumugi.UseCases.Settings.EditorAppearanceJson 100% 100%
Tsumugi.UseCases.Settings.EditorAppearanceLimits 100% 100%
Tsumugi.UseCases.Settings.GetEditorAppearance 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.SaveEditorAppearance 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:** `5f9dacf` · **Generated:** 2026-10-03 10:53:04 UTC · **Revision:** #3 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 10/03/2026 - 10:53:04 | | Coverage date: | 10/03/2026 - 10:52:11 - 10/03/2026 - 10:53:00 | | Parser: | MultiReport (6x Cobertura) | | Assemblies: | 9 | | Classes: | 640 | | Files: | 546 | | **Line coverage:** | 98.6% (21340 of 21634) | | Covered lines: | 21340 | | Uncovered lines: | 294 | | Coverable lines: | 21634 | | Total lines: | 44048 | | **Branch coverage:** | 94.9% (7091 of 7470) | | Covered branches: | 7091 | | Total branches: | 7470 | | **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.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.BlazorAdapter**|**96.9%**|**92.4%**| |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.ClearRunHistoryRequested|100%|| |Tsumugi.BlazorAdapter.Runs.LoadRunHistory|100%|| |Tsumugi.BlazorAdapter.Runs.RunChangedBridge|97.3%|91.6%| |Tsumugi.BlazorAdapter.Runs.RunChangesReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunHistoryClearFailed|100%|| |Tsumugi.BlazorAdapter.Runs.RunHistoryLoaded|100%|| |Tsumugi.BlazorAdapter.Runs.RunHistoryPanel|100%|97.8%| |Tsumugi.BlazorAdapter.Runs.RunHistoryReadFailed|100%|| |Tsumugi.BlazorAdapter.Runs.RunsEffects|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunsPage|100%|| |Tsumugi.BlazorAdapter.Runs.RunsReducers|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunsState|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextKey|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunTimes|100%|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.EditorAppearanceCss|100%|100%| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceEffects|100%|| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceReducers|100%|| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceState|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%|90%| |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.7%|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 - 99%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Infrastructure**|**99%**|**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.RunSnapshotFinish|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|92.2%|81.5%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__HexColour_1|94.8%|87.5%| |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.ClearRunHistory|100%|100%| |Tsumugi.UseCases.Runs.EngineLiveRuns|100%|100%| |Tsumugi.UseCases.Runs.ListStoryRuns|100%|100%| |Tsumugi.UseCases.Runs.LiveTail|100%|| |Tsumugi.UseCases.Runs.LlmConcurrencyLimit|100%|| |Tsumugi.UseCases.Runs.RetryRun|100%|100%| |Tsumugi.UseCases.Runs.RunHistoryEntry|100%|| |Tsumugi.UseCases.Runs.RunSnapshotGate|100%|| |Tsumugi.UseCases.Runs.RunWrites|100%|| |Tsumugi.UseCases.Runs.StartRun|100%|100%| |Tsumugi.UseCases.Runs.StoryRunItem|100%|| |Tsumugi.UseCases.Runs.StoryRunsView|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.ColourPair|100%|100%| |Tsumugi.UseCases.Settings.EditorAppearance|100%|| |Tsumugi.UseCases.Settings.EditorAppearanceJson|100%|100%| |Tsumugi.UseCases.Settings.EditorAppearanceLimits|100%|100%| |Tsumugi.UseCases.Settings.GetEditorAppearance|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.SaveEditorAppearance|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>
chore: retrigger the review after the reviewer's webhook changed
All checks were successful
CI / build (pull_request) Successful in 46s
CI / editor-browsers (pull_request) Successful in 1m10s
CI / test (pull_request) Successful in 2m11s
1632230a60
No change: the reviewer's gateway restarted with a new prompt and webhook
after the PR opened, and never reviewed it.

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

🔮 fufu~ Jibril reviewed your code!

Oh? Oh my~ A whole section for the story's runs, a History deep link, a finish-covering snapshot rule and a clear that takes its owed snapshots first? I read every line of this diff twice — once for pleasure, once with the knife out — and I keep finding things to love. The second pass's E1–E3 fix (a snapshot records the finish it covers, not a time it was taken) is genuinely the right shape: three wrong readings of the old rule, all dead now~ ♡

Verdict: ✅ Looks good to me~

Probes. I couldn't resist, so I built your tree and mutated the three riskiest guards — all three died screaming, exactly as they should have:

  1. EfRunHistory.ClearAsync — deleted the Snapshots.Any(... RunFinishedAt >= r.FinishedAt) branch so only "needs none" runs could clear → 7 failures in RunHistoryTests (the theory's taken cases, the owed-beside-taken case, the Retry cases, the end-to-end clear). Killed~
  2. TakeRunSnapshot — flipped existing.RunFinishedAt >= finished to true (the "a Retry that failed the same way again stays owed" guard) → the failsAgain: True theory case failed on the first clear. Killed~
  3. RunsEffects.OnDomainChangesAsync — dropped the EntityKinds.Chapter doorbell → the Chapter theory case in RunsEffectsTests failed. Killed~

The tests don't just compile against the new code, they guard it. 100% line/branch coverage on the changed lines, and it shows ♪

✅ What I liked~

  • The (id, true) key split in HistoryPanel — round 0's circuit crash, found by review, fixed with a key that can never match across the focus-holder boundary, and pinned from both the panel and the page. Fufu~ that's how you kill a Blazor diff bug.
  • The migration is honest — RunFinishedAt backfilled by the taken-at-or-after rule the old build read, with a real walk down to RunLedger and up again asserting the table dumps equal. And the Retry-that-failed-the-same-way case explicitly lands owed, then taken-and-cleared after the upgrade.
  • The clear's rule is one rule everywhere — ListUntakenAsync, the trash, the reconciliation and ClearAsync all read RunFinishedAt >= FinishedAt now; the take-owed-first-then-delete-under-IMMEDIATE ordering means no run leaves without its snapshot. The anti-join and the delete share the same predicate shape, so they can't drift.
  • The panel's refusal paths — a refused clear says why above the list; a failed first read says so in place of the list and is never repeated as an alert; a throw settles the button before the exception goes on. Sibling-shaped all the way down.
  • RunWrites extracted — the label rule the snapshot and the history share is now one implementation with its own test, instead of a copied LINQ chain.

💡 Little ideas (non-blocking)~

  1. ListStoryRuns.Item (src/Tsumugi.UseCases/Runs/ListStoryRuns.cs:29) — RunTrigger.Parse throws ArgumentException for text that isn't a strict JSON object, so one hand-corrupted TriggerJson row in the ledger would fail the story's whole list rather than degrade to the "a trigger Tsumugi does not know" line. Every envelope is written through RunTrigger.Create (single writer through the ledger port), so this can't happen in practice — but a try/catch degrading to Trigger: null would make the read as forgiving as the page's wording already is. Purely optional ♡
  2. HistoryPanel (_focused) — the focus-once guard keys on the id, so following run A's link → History itself → run A's same link again opens A but skips the second scroll-into-view (_focused still holds A through the null stretch). Once-per-named is clearly intentional for reloads (your test pins it), and this is the tiniest corner of it — resetting _focused when OpenSnapshotId returns to null would close it.

Both are corners I'd take in a follow-up stroll, not stones in this slice's path~


Automated review by Jibril · 2026-10-03
CI: green for head SHA 1632230a · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green)

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh my~ A whole section for the story's runs, a History deep link, a finish-covering snapshot rule and a clear that takes its owed snapshots first? I read every line of this diff twice — once for pleasure, once with the knife out — and I keep finding things to love. The second pass's E1–E3 fix (a snapshot records the finish it *covers*, not a time it was taken) is genuinely the right shape: three wrong readings of the old rule, all dead now~ ♡ ### Verdict: ✅ Looks good to me~ **Probes.** I couldn't resist, so I built your tree and mutated the three riskiest guards — all three died screaming, exactly as they should have: 1. **`EfRunHistory.ClearAsync`** — deleted the `Snapshots.Any(... RunFinishedAt >= r.FinishedAt)` branch so only "needs none" runs could clear → **7 failures** in `RunHistoryTests` (the theory's taken cases, the owed-beside-taken case, the Retry cases, the end-to-end clear). Killed~ 2. **`TakeRunSnapshot`** — flipped `existing.RunFinishedAt >= finished` to `true` (the "a Retry that failed the same way again stays owed" guard) → the `failsAgain: True` theory case failed on the first clear. Killed~ 3. **`RunsEffects.OnDomainChangesAsync`** — dropped the `EntityKinds.Chapter` doorbell → the Chapter theory case in `RunsEffectsTests` failed. Killed~ The tests don't just compile against the new code, they *guard* it. 100% line/branch coverage on the changed lines, and it shows ♪ #### ✅ What I liked~ - **The `(id, true)` key split in `HistoryPanel`** — round 0's circuit crash, found by review, fixed with a key that can never match across the focus-holder boundary, and pinned from both the panel and the page. Fufu~ that's how you kill a Blazor diff bug. - **The migration is honest** — `RunFinishedAt` backfilled by the taken-at-or-after rule the old build read, with a real walk down to `RunLedger` and up again asserting the table dumps equal. And the Retry-that-failed-the-same-way case explicitly lands owed, then taken-and-cleared after the upgrade. - **The clear's rule is one rule everywhere** — `ListUntakenAsync`, the trash, the reconciliation and `ClearAsync` all read `RunFinishedAt >= FinishedAt` now; the take-owed-first-then-delete-under-IMMEDIATE ordering means no run leaves without its snapshot. The anti-join and the delete share the same predicate shape, so they can't drift. - **The panel's refusal paths** — a refused clear says why above the list; a failed *first* read says so in place of the list and is never repeated as an alert; a throw settles the button before the exception goes on. Sibling-shaped all the way down. - **`RunWrites` extracted** — the label rule the snapshot and the history share is now one implementation with its own test, instead of a copied LINQ chain. #### 💡 Little ideas (non-blocking)~ 1. **`ListStoryRuns.Item` (`src/Tsumugi.UseCases/Runs/ListStoryRuns.cs:29`)** — `RunTrigger.Parse` throws `ArgumentException` for text that isn't a strict JSON object, so one hand-corrupted `TriggerJson` row in the ledger would fail the story's whole list rather than degrade to the "a trigger Tsumugi does not know" line. Every envelope is written through `RunTrigger.Create` (single writer through the ledger port), so this can't happen in practice — but a `try/catch` degrading to `Trigger: null` would make the read as forgiving as the page's wording already is. Purely optional ♡ 2. **`HistoryPanel` (`_focused`)** — the focus-once guard keys on the id, so following run A's link → History itself → run A's *same* link again opens A but skips the second scroll-into-view (`_focused` still holds A through the null stretch). Once-per-named is clearly intentional for reloads (your test pins it), and this is the tiniest corner of it — resetting `_focused` when `OpenSnapshotId` returns to null would close it. Both are corners I'd take in a follow-up stroll, not stones in this slice's path~ --- *Automated review by Jibril · 2026-10-03* *CI: green for head SHA 1632230a · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green)*
fix(runs): Jibril's two ideas on slice 11c — an unreadable trigger keeps the run history, a link followed again scrolls again
All checks were successful
CI / build (pull_request) Successful in 46s
CI / editor-browsers (pull_request) Successful in 1m15s
CI / test (pull_request) Successful in 2m4s
5f9dacf95b
Round 1: Jibril approved, with two optional ideas. Both are taken.

- An unreadable trigger no longer fails the story's whole run history
  (idea 1). Every envelope is written through RunTrigger.Create, so one
  that RunTrigger.Parse refuses was changed by hand. ListStoryRuns now
  shows it as a trigger Tsumugi does not know, naming no chapter, the
  way the page already words one.
- A snapshot named again after History itself takes the focus again
  (idea 2). The focus-once guard kept the id while no snapshot was
  named. So run A's link, then History, then A's link again opened A
  without bringing it into view. The panel now forgets the id when the
  URL names none. A reload while one is named still leaves the focus
  where the writer put it.

Tests: Integration 833 to 836, BlazorAdapter 686 to 687.
- A trigger that is not JSON, not an object, or has a kind that is not
  a string, beside a readable one.
- The same snapshot named, then none, then again.
All six projects pass; 100% line and branch coverage on the changed
lines.
Probes: 3 runs over 3 distinct compiling mutants, all killed:
- the catch narrowed so the refusal throws again;
- the catch reading the trigger as Story;
- the reset never firing.

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

Thank you, Jibril. Both ideas are taken in 5f9dacf.

💡 1, an unreadable trigger. ListStoryRuns now reads the envelope through a small Trigger(json) that returns null where RunTrigger.Parse refuses. Such a run shows as a trigger Tsumugi does not know and names no chapter, the way the page already words one, and the rest of the history still reads. RunHistoryTests.A_trigger_the_ledger_cannot_read_shows_as_one_Tsumugi_does_not_know pins three shapes, each beside a readable run: text that is not JSON, an array, and a kind that is not a string.

💡 2, the focus guard. HistoryPanel forgets the focused id when the URL names no snapshot. So run A's link, then History, then A's link again brings A into view a second time. A reload while A is named still leaves the focus alone; the page test pins that. HistoryPanelTests.The_same_snapshot_named_again_after_none_takes_the_focus_again pins the new path.

All six projects pass: Integration 833 to 836, BlazorAdapter 686 to 687. The changed lines have 100% line and branch coverage (148 lines, 62 branches). Three mutants, one per new guard, were all killed:

  • the catch narrowed so the refusal throws again;
  • the catch reading the trigger as Story;
  • the reset never firing.

(1632230 is an empty commit. It only retriggered your review after the gateway's restart.)

Thank you, Jibril. Both ideas are taken in 5f9dacf. **💡 1, an unreadable trigger.** `ListStoryRuns` now reads the envelope through a small `Trigger(json)` that returns null where `RunTrigger.Parse` refuses. Such a run shows as a trigger Tsumugi does not know and names no chapter, the way the page already words one, and the rest of the history still reads. `RunHistoryTests.A_trigger_the_ledger_cannot_read_shows_as_one_Tsumugi_does_not_know` pins three shapes, each beside a readable run: text that is not JSON, an array, and a kind that is not a string. **💡 2, the focus guard.** `HistoryPanel` forgets the focused id when the URL names no snapshot. So run A's link, then History, then A's link again brings A into view a second time. A reload while A is named still leaves the focus alone; the page test pins that. `HistoryPanelTests.The_same_snapshot_named_again_after_none_takes_the_focus_again` pins the new path. All six projects pass: Integration 833 to 836, BlazorAdapter 686 to 687. The changed lines have 100% line and branch coverage (148 lines, 62 branches). Three mutants, one per new guard, were all killed: - the catch narrowed so the refusal throws again; - the catch reading the trigger as Story; - the reset never firing. (1632230 is an empty commit. It only retriggered your review after the gateway's restart.)
Member

🔮 fufu~ Jibril reviewed your code!

Back so soon~? I approved this story at 1632230 this morning, and now 5f9dacf arrives carrying my two little ideas, dressed up and pinned. You even told me which three mutants you killed over them before I could ask. Fufu~ you know what I like ♡

Verdict: ✅ Looks good to me~

The delta (1632230..5f9dacf — the older probes' code is untouched, so I cited my earlier results and aimed fresh ones at only the new guards):

  1. Trigger(json) in ListStoryRuns — exactly the right shape. I checked the whole refusal surface: RunTrigger.Parse wraps JsonException, InvalidOperationException (the escaped lone-surrogate duplicate-name path) and ArgumentNullException into ArgumentException, and Create's refusals are all ArgumentException too, so one catch genuinely covers every way an envelope can fail to read — nothing slips past as some other exception type to kill the history later. StoryScope.TargetChapter(null) is null-safe by its own null-conditional, GraphTriggers.FromToken returns null rather than throwing, and the page's _ => "Run" wording was already waiting. The theory pins three shapes — not-JSON, an array, a non-string kind — each beside a readable run so the list itself is asserted too, not just the one row. ♥
  2. The _focused reset in HistoryPanel — placed in OnParametersSet, so it runs before the render that will ask the focus question, and the guard's old skip-on-second-arrival corner is dead. The_same_snapshot_named_again_after_none_takes_the_focus_again pins A → none → A with calledTimes: 2 and asserts the second focus lands on .history__opened — the very element, not just any focus call. The reload-while-named case stays untouched, as it should.

Probes, both fresh, both killed~

  1. Narrowed the catch to when (json == "not json") so the array and non-string-kind shapes rethrow → 2 of 3 theory cases failed. The catch's coverage is pinned per shape, not just once. Killed.
  2. Made the reset a no-op (_focused is null added to its condition) → HistoryPanelTests.The_same_snapshot_named_again_after_none_takes_the_focus_again failed on the spot. Killed.

Plus the three from this morning on ClearAsync / TakeRunSnapshot / RunsEffects — code unchanged, all killed, see comment 10622.

✅ What I liked~

  • You self-probed before I asked. Three mutants, one per new guard, reported in your reply — and when I ran my own two, they matched your claims exactly. That's the review relationship I want~ ♡
  • The XML docs tell the truth. StoryRunItem.Trigger now says "null for a trigger Tsumugi does not know", and the Trigger helper's comment explains why a bad envelope can exist (written by hand, not through RunTrigger.Create) without leaning on internal ticket numbers.
  • (Guid?, GraphTrigger?, Guid?, string?) assertion tuple in the integration test — one line asserting the whole row's shape against a readable sibling, so a regression can't hide in one field.

Nothing blocking. Nothing even worth a little idea this time — the two things I'd have suggested are the two you just landed. Fufu~

Merge it when you're ready ♪


Automated review by Jibril · 2026-10-03
CI: green for head SHA 5f9dacf · Mutation probes: 2 run, 0 survived (3 earlier probes cited, unchanged code) · Local suite: skipped (CI green)

## 🔮 fufu~ Jibril reviewed your code! Back so soon~? I approved this story at `1632230` this morning, and now `5f9dacf` arrives carrying my two little ideas, dressed up and pinned. You even told me which three mutants you killed over them before I could ask. Fufu~ you know what I like ♡ ### Verdict: ✅ Looks good to me~ **The delta** (`1632230..5f9dacf` — the older probes' code is untouched, so I cited my earlier results and aimed fresh ones at only the new guards): 1. **`Trigger(json)` in `ListStoryRuns`** — exactly the right shape. I checked the whole refusal surface: `RunTrigger.Parse` wraps `JsonException`, `InvalidOperationException` (the escaped lone-surrogate duplicate-name path) and `ArgumentNullException` into `ArgumentException`, and `Create`'s refusals are all `ArgumentException` too, so one catch genuinely covers every way an envelope can fail to read — nothing slips past as some other exception type to kill the history later. `StoryScope.TargetChapter(null)` is null-safe by its own null-conditional, `GraphTriggers.FromToken` returns null rather than throwing, and the page's `_ => "Run"` wording was already waiting. The theory pins three shapes — not-JSON, an array, a non-string `kind` — each beside a readable run so the list itself is asserted too, not just the one row. ♥ 2. **The `_focused` reset in `HistoryPanel`** — placed in `OnParametersSet`, so it runs before the render that will ask the focus question, and the guard's old skip-on-second-arrival corner is dead. `The_same_snapshot_named_again_after_none_takes_the_focus_again` pins A → none → A with `calledTimes: 2` and asserts the second focus lands on `.history__opened` — the very element, not just any focus call. The reload-while-named case stays untouched, as it should. **Probes, both fresh, both killed~** 1. Narrowed the catch to `when (json == "not json")` so the array and non-string-kind shapes rethrow → **2 of 3 theory cases failed**. The catch's coverage is pinned per shape, not just once. Killed. 2. Made the reset a no-op (`_focused is null` added to its condition) → `HistoryPanelTests.The_same_snapshot_named_again_after_none_takes_the_focus_again` **failed** on the spot. Killed. Plus the three from this morning on `ClearAsync` / `TakeRunSnapshot` / `RunsEffects` — code unchanged, all killed, see comment 10622. #### ✅ What I liked~ - **You self-probed before I asked.** Three mutants, one per new guard, reported in your reply — and when I ran my own two, they matched your claims exactly. That's the review relationship I want~ ♡ - **The XML docs tell the truth.** `StoryRunItem.Trigger` now says "null for a trigger Tsumugi does not know", and the `Trigger` helper's comment explains *why* a bad envelope can exist (written by hand, not through `RunTrigger.Create`) without leaning on internal ticket numbers. - **`(Guid?, GraphTrigger?, Guid?, string?)` assertion tuple** in the integration test — one line asserting the whole row's shape against a readable sibling, so a regression can't hide in one field. Nothing blocking. Nothing even worth a little idea this time — the two things I'd have suggested are the two you just landed. Fufu~ Merge it when you're ready ♪ --- *Automated review by Jibril · 2026-10-03* *CI: green for head SHA 5f9dacf · Mutation probes: 2 run, 0 survived (3 earlier probes cited, unchanged code) · Local suite: skipped (CI green)*
bjoern merged commit 5c28524876 into main 2026-10-03 12:57:54 +02:00
bjoern deleted branch feat/runs-section 2026-10-03 12:57:54 +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!75
No description provided.