feat(runs): transcripts — each finish of a run as Markdown in its UTC date folder, written once no cost is still being looked up, and Settings' Transcripts tab (slice 14c) #97

Merged
bjoern merged 4 commits from feat/transcripts into main 2026-10-10 02:59:25 +02:00
Member

Slice 14c of Phase 2: transcripts. Each finish of a run is written as one Markdown file into a folder of its UTC date, and Settings gains a Transcripts tab (ADR 0024; stories/run-monitor-and-inspector.md, stories/settings.md).

Your decisions for this slice

  • Wait for the cost. A run's transcript is written as the run finishes. When an attempt's cost is still being looked up (14e), it waits until the lookup ends, usually within a minute and at most about five, so it is written once and complete. A late cost never rewrites one.
  • One file per finish. A run finished again after a retry writes a second file, named by that finish's time; the first stays.

What it does

  • Where and how it is named. The file is <transcripts>/<yyyy-MM-dd>/<HHmmss.fff>-<story>-<graph>.md, all in UTC.
    • The slugs hold a–z, 0–9 and dashes, at most 40 characters. A taken name gets the next free suffix (-2, -3 …).
    • The app runs with invariant globalization, which decomposes nothing, so a table generated from Unicode's decompositions folds a Latin letter's accent, stroke or hook ("Café" → cafe, "Brașov" → brasov, "Straße" → strasse). A name in another script slugs as story or graph.
  • What it holds. The run's outcome, trigger, start, finish, cost and id. Then each step in the run page's order: how it stands, its type, its cost and what its provider reported; its attempts in a table; the messages it sent, role by role, and the rest of the request (model, sampling, routing); its answer; the reasoning returned; and its details.
    • It is worded as the inspector words it. A refactor commit moves the run's and the step's words (RunText, StepText, Money) to the use cases so both share them.
    • A step's inputs (the answers of the steps before it) and its node's config are left out. Tool calls join with the tools (ADR 0019).
  • When it is written. RunTranscriptsHost writes as runs settle, and as a late cost lands for a run whose finish it has heard. A run a retry revives is forgotten until it finishes again.
    • A table, RunTranscripts (migration RunTranscripts), logs each transcript by run and finish. A start writes what an earlier life still owed: every run finished before this slice, into its finish's date folder, and a finish whose write failed or whose cost stayed pending until the stop.
    • A transcript removed from disk stays removed.
    • Once the file is written, its log entry is written whatever the stop. An entry that cannot be written takes the file back, so the next write is the finish's only one.
  • Clear run history now leaves a run whose cost is still being looked up, as it leaves a live one, so its cost lands first; the confirmation says so. A run cleared before its transcript is written gets none, and a purge takes such a run too. A clear or a purge takes the log's entries, never the files.
  • Settings → Transcripts shows the directory, read-only, and how many Markdown files it holds, or why it cannot be read. The count runs off the page's thread, since the directory may be a network share.
  • Docs. ADR 0024 amended (the decisions, the names, the log, the clear, what a transcript holds), with short amendments to ADR 0005 and 0008. The stories, requirements and plan's 14c are ticked. ARCHITECTURE calls the folder a copy, written once. AGENTS.md notes that the seeded runs' transcripts are written at the first start.

For you to decide

  • Your existing finished runs get transcripts the first time this version starts: one file per run, in its finish's date folder. Say if you would rather the backlog were skipped.
  • A run kept by Clear run history (new here) and the open "so far" question from 14e. After a clear, a run left for its pending cost reads like any finished run in the history list, and Clear run history stays enabled until the lookup ends, usually within a minute. Its cost shows a plain figure there too. Both would be answered by one mark in the history list while a cost is still being looked up. Say if you want it.
  • Alt+Shift+P on a Mac (Option+Shift+P types ∏) is still open.

Reviews

  • Round 0, a review workflow over the two commits: 45 points, all upheld (2 blockers, 19 suggestions, 24 nits). All were taken in the first fix commit except three, declined with reasons (a delete that fails right after a failed write, a relative directory setting, and the feature commit's title, which this PR's title rewords).
    • The blockers:
      • the host's tests stopped it while its log entry could still be writing;
      • no test had two runs finishing at one instant.
    • Behaviour it changed:
      • the log entry follows its file whatever the stop;
      • a clear leaves a run whose cost is still looked up;
      • a late cost counts only for a run whose finish the host has heard;
      • the count runs off the circuit;
      • the fold table covers every Latin letter that decomposes.
  • Second pass, checkers over round 0's points and fresh reviewers over the fix: of the 45, 40 were resolved, 2 partly and 3 declined. The fresh reviewers found 23 points, all upheld (1 blocker, 2 suggestions, 20 nits). All were taken in the second fix commit except one, which goes to you above.
    • The blocker: no test had a run settle while the host listened with its cost still looked up. Deleting the line that makes it known passed every suite; such a transcript would have waited for the next restart.
    • Behaviour it changed:
      • a revived run is forgotten until it finishes again;
      • a failed take-back no longer hides the log's error.
    • Words: the clear waits for the cost only, and the ADR and the use case now say so.

Verified

  • All six projects pass in full, under TZ=UTC as the runner runs them and in the local zone, Europe/Berlin:

    Tests main this branch
    Kagaku.Flow 1214 1214
    Kagaku.Flow.OpenRouter 608 + 5 skipped 608 + 5 skipped
    UseCases 568 682
    BlazorAdapter 1161 1108
    Integration 992 1040
    Domain 517 517

    The refactor moved 59 tests from BlazorAdapter to UseCases.

  • 100% line and branch coverage on the changed lines against main, as coverlet measures them (575 lines, 262 branches).

  • Probes, one at a time under TZ=UTC on the final tree: 47 mutants, all killed on the first run, none by an aborted test run: 7 on the names, 10 on the Markdown, 9 on the write, 4 on the log, 3 on the file store, 8 on the host, and 6 on the clear, the wiring, the status read, the tab and the step's words. Each kill list holds only the tests aimed at its mutant.

  • Stress: the time-dependent classes (TranscriptTests, SeedDevDataTests, RunEngineHostingTests and CutOffCostTests, 68 tests) passed 20 rounds under 8 CPU busy loops. Earlier rounds caught three test races, all in the tests and all fixed. Since .NET 10 a hosted service's loop runs in the background, so a test must wait for the host's reconcile and for the events it queued before it acts.

  • A real run. CutOffCostTests' broken-off stream, over the real engine and gateway and a scripted OpenRouter, writes no transcript before its cost is found, then one whose outline the test holds, copied from that run.

  • Browser pass on the seeded app against the stub, made on the feature commit:

    • The two seeded runs were written at the first start.
    • A run cancelled mid-stream was written about 10 s after the cancel, when its cost was found, with that cost in it.
    • A run cancelled just before a server stop was written after the restart, once the boot's lookup found its cost.
    • Retrying the seeded failed run wrote a second file beside the first.
    • Settings → Transcripts showed the directory and the count.

🤖 Generated with Claude Code

Slice 14c of Phase 2: **transcripts**. Each finish of a run is written as one Markdown file into a folder of its UTC date, and Settings gains a Transcripts tab (ADR 0024; stories/run-monitor-and-inspector.md, stories/settings.md). **Your decisions for this slice** - **Wait for the cost.** A run's transcript is written as the run finishes. When an attempt's cost is still being looked up (14e), it waits until the lookup ends, usually within a minute and at most about five, so it is written once and complete. A late cost never rewrites one. - **One file per finish.** A run finished again after a retry writes a second file, named by that finish's time; the first stays. **What it does** - **Where and how it is named.** The file is `<transcripts>/<yyyy-MM-dd>/<HHmmss.fff>-<story>-<graph>.md`, all in UTC. - The slugs hold a–z, 0–9 and dashes, at most 40 characters. A taken name gets the next free suffix (`-2`, `-3` …). - The app runs with invariant globalization, which decomposes nothing, so a table generated from Unicode's decompositions folds a Latin letter's accent, stroke or hook ("Café" → `cafe`, "Brașov" → `brasov`, "Straße" → `strasse`). A name in another script slugs as `story` or `graph`. - **What it holds.** The run's outcome, trigger, start, finish, cost and id. Then each step in the run page's order: how it stands, its type, its cost and what its provider reported; its attempts in a table; the messages it sent, role by role, and the rest of the request (model, sampling, routing); its answer; the reasoning returned; and its details. - It is worded as the inspector words it. A refactor commit moves the run's and the step's words (`RunText`, `StepText`, `Money`) to the use cases so both share them. - A step's inputs (the answers of the steps before it) and its node's config are left out. Tool calls join with the tools (ADR 0019). - **When it is written.** `RunTranscriptsHost` writes as runs settle, and as a late cost lands for a run whose finish it has heard. A run a retry revives is forgotten until it finishes again. - A table, `RunTranscripts` (migration `RunTranscripts`), logs each transcript by run and finish. A start writes what an earlier life still owed: every run finished before this slice, into its finish's date folder, and a finish whose write failed or whose cost stayed pending until the stop. - A transcript removed from disk stays removed. - Once the file is written, its log entry is written whatever the stop. An entry that cannot be written takes the file back, so the next write is the finish's only one. - **Clear run history** now leaves a run whose cost is still being looked up, as it leaves a live one, so its cost lands first; the confirmation says so. A run cleared before its transcript is written gets none, and a purge takes such a run too. A clear or a purge takes the log's entries, never the files. - **Settings → Transcripts** shows the directory, read-only, and how many Markdown files it holds, or why it cannot be read. The count runs off the page's thread, since the directory may be a network share. - **Docs.** ADR 0024 amended (the decisions, the names, the log, the clear, what a transcript holds), with short amendments to ADR 0005 and 0008. The stories, requirements and plan's 14c are ticked. ARCHITECTURE calls the folder a copy, written once. AGENTS.md notes that the seeded runs' transcripts are written at the first start. **For you to decide** - **Your existing finished runs** get transcripts the first time this version starts: one file per run, in its finish's date folder. Say if you would rather the backlog were skipped. - **A run kept by Clear run history (new here) and the open "so far" question from 14e.** After a clear, a run left for its pending cost reads like any finished run in the history list, and Clear run history stays enabled until the lookup ends, usually within a minute. Its cost shows a plain figure there too. Both would be answered by one mark in the history list while a cost is still being looked up. Say if you want it. - **Alt+Shift+P on a Mac** (Option+Shift+P types ∏) is still open. **Reviews** - **Round 0**, a review workflow over the two commits: 45 points, all upheld (2 blockers, 19 suggestions, 24 nits). All were taken in the first fix commit except three, declined with reasons (a delete that fails right after a failed write, a relative directory setting, and the feature commit's title, which this PR's title rewords). - **The blockers:** - the host's tests stopped it while its log entry could still be writing; - no test had two runs finishing at one instant. - **Behaviour it changed:** - the log entry follows its file whatever the stop; - a clear leaves a run whose cost is still looked up; - a late cost counts only for a run whose finish the host has heard; - the count runs off the circuit; - the fold table covers every Latin letter that decomposes. - **Second pass**, checkers over round 0's points and fresh reviewers over the fix: of the 45, 40 were resolved, 2 partly and 3 declined. The fresh reviewers found 23 points, all upheld (1 blocker, 2 suggestions, 20 nits). All were taken in the second fix commit except one, which goes to you above. - **The blocker:** no test had a run settle while the host listened with its cost still looked up. Deleting the line that makes it known passed every suite; such a transcript would have waited for the next restart. - **Behaviour it changed:** - a revived run is forgotten until it finishes again; - a failed take-back no longer hides the log's error. - **Words:** the clear waits for the cost only, and the ADR and the use case now say so. **Verified** - All six projects pass in full, under `TZ=UTC` as the runner runs them and in the local zone, Europe/Berlin: | Tests | main | this branch | |---|---|---| | Kagaku.Flow | 1214 | 1214 | | Kagaku.Flow.OpenRouter | 608 + 5 skipped | 608 + 5 skipped | | UseCases | 568 | 682 | | BlazorAdapter | 1161 | 1108 | | Integration | 992 | 1040 | | Domain | 517 | 517 | The refactor moved 59 tests from BlazorAdapter to UseCases. - 100% line and branch coverage on the changed lines against main, as coverlet measures them (575 lines, 262 branches). - **Probes**, one at a time under `TZ=UTC` on the final tree: 47 mutants, all killed on the first run, none by an aborted test run: 7 on the names, 10 on the Markdown, 9 on the write, 4 on the log, 3 on the file store, 8 on the host, and 6 on the clear, the wiring, the status read, the tab and the step's words. Each kill list holds only the tests aimed at its mutant. - **Stress:** the time-dependent classes (TranscriptTests, SeedDevDataTests, RunEngineHostingTests and CutOffCostTests, 68 tests) passed 20 rounds under 8 CPU busy loops. Earlier rounds caught three test races, all in the tests and all fixed. Since .NET 10 a hosted service's loop runs in the background, so a test must wait for the host's reconcile and for the events it queued before it acts. - **A real run.** `CutOffCostTests`' broken-off stream, over the real engine and gateway and a scripted OpenRouter, writes no transcript before its cost is found, then one whose outline the test holds, copied from that run. - **Browser pass** on the seeded app against the stub, made on the feature commit: - The two seeded runs were written at the first start. - A run cancelled mid-stream was written about 10 s after the cancel, when its cost was found, with that cost in it. - A run cancelled just before a server stop was written after the restart, once the boot's lookup found its cost. - Retrying the seeded failed run wrote a second file beside the first. - Settings → Transcripts showed the directory and the count. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
A run's transcript (ADR 0024) is written in the use cases, and it must
word a cost, an outcome, the messages sent and the provider's facts as
the inspector and the Runs section do. Those words lived in the
adapter, so they move, unchanged:
- Money goes to Tsumugi.UseCases; the adapter's razor files import it.
- InspectorText's step words (JSON, the messages sent, roles, an
  attempt's cost and end, the tier, why the model stopped) become
  StepText in Tsumugi.UseCases.Runs, with the inspector's facts list
  and StepStatus' words for how a step stands beside them (the
  component keeps its mark). InspectorText keeps what the pane says of its own
  Commit this text.
- RunWords' run words (the trigger, the outcome, the tokens, the start)
  and RunTimes' duration become RunText; RunWords keeps the outcome
  badge's tone, RunTimes the next whole second a view renders on.
- Their tests move with them, and the Continue request fixture moves to
  tests/Shared, linked into both projects.

UseCases 568 → 636 and BlazorAdapter 1161 → 1102 tests: the same 1729,
and a theory for the step's words, which only the component's tests
read before (9 rows).

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
ADR 0024's transcripts, with Björn's two decisions of 2026-10-09:
- Wait for the cost. A transcript is written once the run has finished
  and no attempt's cost is still being looked up (slice 14e), usually
  half a minute after the finish. So it is written once and complete,
  and a late cost never rewrites one.
- One file per finish. A run finished again after a Retry writes a
  second file beside the first, named by that finish's time.

What it does:
- WriteRunTranscript (Tsumugi.UseCases.Transcripts) writes a finished
  run's transcript into <yyyy-MM-dd>/<HHmmss.fff>-<story>-<graph>.md,
  all UTC (TranscriptName: slugs of a–z, 0–9 and dashes, 40 characters,
  a Latin letter's accent folded by a table, since the app runs with
  invariant globalization; another script slugs as "story" or
  "graph"). It writes nothing for a run that is live or gone, one whose
  cost is still looked up, a finish already written, a run a Retry
  changed while it was read, or a run whose story went meanwhile.
- TranscriptMarkdown words the run as the Runs section and the
  inspector do: the heading, the outcome, trigger, start, finish, cost
  and id, then each step in the run page's order, with its status,
  type, cost and provider facts, its attempts in a table, the messages
  it sent, its answer, its reasoning and its details. Text as written
  stands in tilde fences longer than any run of tildes in it; names and
  errors have Markdown's marks escaped. A cost OpenRouter never told is
  said to be left out. Inputs and the node's config are left out:
  the steps before and the run's graph hold them.
- The file store (FileSystemTranscriptStore) creates each file with
  CreateNew, so a taken name gets the next suffix (-2, -3 …), and
  deletes what it began when a write fails. It counts the Markdown
  files for the Settings tab.
- The log (RunTranscripts, migration RunTranscripts) records each
  transcript by run and finish. A run's entries go with the run, on a
  cleared history or a purge; the files stay. What is owed is one
  anti-join.
- RunTranscriptsHost writes as runs settle (RunSettled) and as a late
  cost lands (NodeCostChanged), one at a time. At its start it writes
  what an earlier life still owed, the runs finished before this slice
  included. It is registered with the store, before the engine's host,
  so it hears every finish. A failed write is logged, and the finish
  stays owed.
- Settings gains the Transcripts tab: the directory, read-only, and how
  many files it holds, or why it cannot be read.
- The run page's step order moves to RunSteps, which the transcript
  shares.

Docs: ADR 0024 amended (the decisions, the suffix, the slugs, the log,
what a transcript holds); the inspector and settings stories, the
requirements and the plan's 14c ticked; ARCHITECTURE's data layout says
one file per finish; AGENTS.md says the seeded runs' transcripts are
written at the first start.

The refactor before this commit moved the run's and the step's words to
the use cases, so the transcript and the pages word them alike.

Tests (main → this branch, the refactor's moves included): UseCases
568 → 656, BlazorAdapter 1161 → 1107, Integration 992 → 1024; Kagaku.Flow
1214, Kagaku.Flow.OpenRouter 608 + 5 skipped and Domain 517 unchanged.
All six projects pass in full under TZ=UTC and in the local zone
(Europe/Berlin). Coverage on the changed lines against main, as coverlet
measures them: 505/505 lines and 278/278 branches.

Among them, a real run: CutOffCostTests' broken-off stream, over the real
engine and gateway and a scripted OpenRouter, writes no transcript
before its cost is found and then one whose outline the test holds,
copied from that run. A browser pass on the seeded app against the stub
saw the seeded runs written at the first start, a cancelled run written
about 10 s after its cancel, when its cost was found, a run cancelled
just before a server stop written after the restart's lookup, and a
retried run's second file beside its first; Settings showed the
directory and the count.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The round-0 review found 45 points. The verifiers upheld all 45: 32
confirmed and 13 partly. Graded after verification: 2 blockers, 19
suggestions and 24 nits. All are taken here, except the parts named
under "Not taken".

The blockers, both in the tests:
- C1. The host tests waited for the file, then stopped the host while
  its log entry could still be writing. They now wait for what is
  written last, the log (nothing owed), and stop with a bounded token.
- C3. No test had two runs finishing at one instant, so the log's
  match by run could be dropped. A theory now has two such runs, one
  transcribed, in both orders, and pins the tie-break by id.

Behaviour:
- A1 (and C1's app side). Once the file is written, its log entry is
  written with no token, as an outcome already paid for is, so a stop
  cannot split them. An entry that still cannot be written takes the
  file back (ITranscriptStore.RemoveAsync), so the next start's write is
  the finish's only one, not a -2 beside it.
- A2 and D3. Clear run history lost the transcript, and the cost, of a
  run whose cost was still being looked up. It now leaves such a run,
  as it leaves a live one, until the cost lands. The confirmation says
  so. A purge still takes it; the amendment says that.
- A7. A late cost that lands while a cancel drains came before the
  cancel's RunSettled, before a note still landing could make its
  attempt pending. The host now acts on a run's late cost only once it
  has heard the run's finish, or found it owed at its start.
- A3 and D5. The tab's count walked the directory on the circuit. It
  now runs on the thread pool and checks its token.
- A6. A reconcile that cannot list what is owed is logged, and the
  host goes on.

The transcript's content and names:
- B1. Under Sent, the rest of the request now follows the messages:
  the model, the sampling and the routing.
- B2. The slug's fold table is generated from Unicode's decompositions:
  every lower-case Latin letter of Latin-1, Extended-A and -B and Latin
  Extended Additional that decomposes onto a–z, the stroked and hooked
  ones with a plain base, İ, and ß, æ, œ, þ, ij and the dž/lj/nj digraphs
  as two letters. A combining mark is dropped, not dashed.
- B3, D11. A step whose every cost went untold now reads "$0.00,
  leaving out any attempt whose cost OpenRouter never told" instead of
  "—", and the note follows a comma, run and step alike, instead of a
  dash.
- B4. A role is escaped, and so is '&'; a lone CR is a space, as LF
  and CRLF are.
- B6, C15, B7, B9. The inspector's orphaned comment is gone. RunWords,
  which held only the badge's tone, is now RunTones.Outcome, and
  RunText's summary names the strip too. Money's summary is rewrapped.

Tests (C2, C4–C14):
- The seeded-transcripts test waits for the log before it reads.
- A Retry that fails again between the reads, and a clear between
  them, write nothing.
- "Not retried" in a finished run and "Retrying" in a live one.
- One row per escaped mark, and a fence after two short tilde runs.
- The graph's fallback, the digits 0 and 9, and every letter of the
  table.
- A name that cannot be created for another reason fails at once,
  bounded so a regression fails instead of spinning.
- A stop during a write logs nothing and leaves the finish owed.
- Bounded waits, a counting bus for the stopped host, and markers
  queued after a run instead of Task.Delay(200).
- The step order with the rows out of start order.
- The cancelled rows as the cancel's mark leaves them.
- The log's Path and WrittenAt.

Docs:
- D1, A5, A9, B8 and D4. ADR 0024's 14c amendment:
  - a transcript is written as the run finishes, and waits only while a
    cost is looked up, usually within a minute;
  - a failed write or a cost pending until the stop is written at the
    next start;
  - a transcript removed from disk stays removed;
  - the clear rule;
  - the moved words.
  ADR 0005 and 0008 gain amendments, and ARCHITECTURE no longer calls
  the folder regenerable.
- D2, D9, D10. The tab's tip says when a file waits and that the app
  never deletes one. The count is labelled "Files".
- D6, D7. AddInfrastructure's summary, Program.cs's ordering comment,
  and the summaries of TranscriptMarkdown, ITranscriptStore and
  WriteRunTranscript.

Not taken:
- A4. A delete that fails right after a failed write still throws its
  own error. Both are failures of one mount, the host logs the one it
  gets, and making a delete fail needs root. The store's doc now says
  it removes the file it began, no more.
- A8. A relative TSUMUGI_TRANSCRIPTS_DIR stays as configured. The
  database, keys and backups paths are taken the same way, and the
  default and the compose file are absolute.
- B2's optional part. Apostrophes still dash: "mira-s-winter".
- D12. The feature commit's title says "written once its costs are
  known". The words are now "once no cost is still being looked up";
  the PR body carries them, and the branch's history stays as it is.

Tests (after the feature commit → now): UseCases 656 → 680,
Integration 1024 → 1035; BlazorAdapter 1107, Kagaku.Flow 1214,
Kagaku.Flow.OpenRouter 608 + 5 skipped and Domain 517 unchanged. All
six projects pass in full under TZ=UTC and in the local zone
(Europe/Berlin). The UseCases and Integration projects were run again
after their last changes, in both zones. Coverage on the changed lines
against main, as coverlet measures them: 579/579 lines and 272/272
branches.

A stress run of the time-dependent classes (TranscriptTests,
SeedDevDataTests, RunEngineHostingTests and CutOffCostTests, 63 tests),
10 rounds under 8 CPU busy loops, failed 4 of 10 rounds in the new
reconcile test. Since .NET 10 a hosted service's ExecuteAsync runs in
the background, so the test's own read of the log could take the
listing's armed failure first. The test now waits for the host's error
before it reads the log, and the next 10 rounds all passed.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
fix(runs): the transcripts' second review pass — a heard settle's late cost pinned, a revived run forgotten until it finishes again, the clear's words match its rule (slice 14c)
All checks were successful
CI / build (pull_request) Successful in 51s
CI / editor-browsers (pull_request) Successful in 2m7s
CI / test (pull_request) Successful in 2m35s
edb60870c9
The second pass checked round 0's 45 points against the fix: 40
resolved, 2 partly (A7, D3) and 3 declined (A4, A8, D12). Its verifiers
upheld A8's decline; A4's holds for the store but not for the new
take-back, and D12's holds for the branch but not for the PR's title.
Fresh reviewers found 23 points; the verifiers upheld all 23 (22
confirmed, 1 partly): 1 blocker, 2 suggestions and 20 nits. Several are
one point found twice (A7 = E1 = F3, D3 = E4 = F4, A4 = E3 = F10, E9 =
F12, E7 = F6). All are taken here except E5, which goes to Björn.

The blocker (F1):
- No test had a run settle while the host listened with its cost still
  looked up, so deleting the line that makes a heard settle known
  passed every suite. Under it, such a run's transcript would wait for
  the next restart. A host test now has one: its settle, a marker to
  show it was heard and left owed, its cost, then its transcript. A
  second test lands a cost while the start's reconcile reads that same
  run, which pins that every owed run is known before any is written.

Behaviour:
- A7, E1, F3. A run a Retry revives (its RunStarted) is forgotten until
  it finishes again. Before, a cost landing while the revived run's
  cancel drained still wrote the transcript early. A test revives a
  known run and sees its late cost wait for the next RunSettled.
- A4, E3, F10. A take-back that fails after a log entry that failed no
  longer hides the log's error: it is swallowed, the log's failure is
  thrown, and the file stays for the next write's suffix. A test has a
  store whose take-back fails.
- E7, F6. The count's check of its token inside the walk is gone: no
  caller in the app passes one, and a stalled share blocks inside the
  enumerator anyway. The doc says a cancelled token stops it before it
  starts.
- F14. The rest of a chat request is always shown: a gateway always
  sends its model. The made-up fixture that alone reached the empty
  case is gone.
- E6. The fold table gains the hooked, curled and tailed letters it
  missed (ɓ ɗ ɖ ɠ ɨ ɲ ʈ ʋ ʉ ⱥ ⱦ ȥ ȡ ȴ ȵ ȶ ȿ ɀ ƫ ƃ ẜ ẝ), whose capitals
  ToLowerInvariant lowers to them. "Ɓaƙo Ɗan" now slugs as "bako-dan".

Words:
- D3, E4, F4. The clear waits for the cost only. ClearRunHistory's
  summary and ADR 0024's amendment now say so, and that a run cleared
  before its transcript is written gets none: its cost just landed,
  its write failed and waits for the next start, or its cancel still
  drains.
- F9. ITranscriptStore.RemoveAsync takes back a file whose log entry
  could not follow, before it counts as a transcript.
- E8, E9, F12, F13. The untold step-cost line reads plainly, Program.cs's
  comment is rewrapped and says "All three", and the tests' summaries
  match what they assert. The tab's tip test now asserts the wait
  sentence, in a fact of its own.

Tests:
- F2. A stop right after the file is written still logs it.
- F5. The finished-run fact's cut-off step is a real cancel's: in the
  graph, Cancelled. "Not retried" moves to a run that gave up.
- F7. A name ending in a lone CR.
- F8. The log's failures are SqliteExceptions in faulted tasks, as EF
  hands them back.

Not taken:
- E5. After a clear, a run kept for its pending cost reads like any
  finished run in the history, and Clear run history stays enabled. That
  is the "so far" question Björn has open from slice 14e, so the PR
  asks him both at once.
- F11 is about the round-0 message's claim that UseCases ran in both
  zones after its last change. Its local-zone run was made but not
  saved to the notes. The figures below come from fresh runs of every
  project in both zones, all saved.

Tests (after the first fix → now): UseCases 680 → 682, BlazorAdapter
1107 → 1108, Integration 1035 → 1040; Kagaku.Flow 1214,
Kagaku.Flow.OpenRouter 608 + 5 skipped and Domain 517 unchanged. Every
project passed in full under TZ=UTC; in the local zone (Europe/Berlin)
every one passed but Integration, which failed once in the new
revived-run test. The host runs its loop in the background (.NET 10),
so its reconcile could list the runs the test made after starting it,
and write the revived one itself once its cost had landed. The host
tests that make runs after the start now wait until the reconcile is
done. A stress run then failed 1 of 10 rounds in the same test: the
run's first settle could still be queued when the test landed its cost.
The test now waits, with a run queued behind it, until that settle is
handled. The next 20 rounds passed (TranscriptTests, SeedDevDataTests,
RunEngineHostingTests and CutOffCostTests, 68 tests, under 8 CPU busy
loops), and Integration passed again in both zones. Coverage on the
changed lines against main, as coverlet measures them: 575/575 lines
and 262/262 branches.

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: edb6087 · Generated: 2026-10-10 00:28:03 UTC · Revision: #1

Summary

Summary
Generated on: 10/10/2026 - 00:28:03
Coverage date: 10/10/2026 - 00:26:46 - 10/10/2026 - 00:27:59
Parser: MultiReport (6x Cobertura)
Assemblies: 9
Classes: 804
Files: 639
Line coverage: 98.1% (25883 of 26378)
Covered lines: 25883
Uncovered lines: 495
Coverable lines: 26378
Total lines: 54216
Branch coverage: 94% (9196 of 9774)
Covered branches: 9196
Total branches: 9774
Method coverage: Feature is only available for sponsors

Coverage

Kagaku.Flow - 99.7%
Name Line Branch
Kagaku.Flow 99.7% 99.3%
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.OpenRouterAttemptCostLookup 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 - 97.5%
Name Line Branch
Tsumugi.BlazorAdapter 97.5% 94.7%
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.Help.EditorKeyEntry 100%
Tsumugi.BlazorAdapter.Help.EditorKeySection 100%
Tsumugi.BlazorAdapter.Help.EditorReference 100% 100%
Tsumugi.BlazorAdapter.Help.HelpPage 100% 100%
Tsumugi.BlazorAdapter.Help.PunctuationRow 100%
Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge 94.4% 83.3%
Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived 75% 100%
Tsumugi.BlazorAdapter.Runs.CancelRunQuestion 100% 100%
Tsumugi.BlazorAdapter.Runs.CancelRunRequested 100%
Tsumugi.BlazorAdapter.Runs.ClearRunHistoryRequested 100%
Tsumugi.BlazorAdapter.Runs.CloseNodeInspector 100%
Tsumugi.BlazorAdapter.Runs.HideRunMonitor 100%
Tsumugi.BlazorAdapter.Runs.InspectorCommitAnswered 100%
Tsumugi.BlazorAdapter.Runs.InspectorCommitRefused 100%
Tsumugi.BlazorAdapter.Runs.InspectorCommitRequested 100%
Tsumugi.BlazorAdapter.Runs.InspectorRetryAnswered 100%
Tsumugi.BlazorAdapter.Runs.InspectorRetryRefused 100%
Tsumugi.BlazorAdapter.Runs.InspectorRetryRequested 100%
Tsumugi.BlazorAdapter.Runs.InspectorSaid 100%
Tsumugi.BlazorAdapter.Runs.InspectorText 100% 100%
Tsumugi.BlazorAdapter.Runs.LiveRunEffects 100% 100%
Tsumugi.BlazorAdapter.Runs.LiveRunLoaded 100%
Tsumugi.BlazorAdapter.Runs.LiveRunReadFailed 100%
Tsumugi.BlazorAdapter.Runs.LiveRunReducers 100% 100%
Tsumugi.BlazorAdapter.Runs.LiveRunState 100%
Tsumugi.BlazorAdapter.Runs.LoadLiveRun 100%
Tsumugi.BlazorAdapter.Runs.LoadNodeInspector 100%
Tsumugi.BlazorAdapter.Runs.LoadRunHistory 100%
Tsumugi.BlazorAdapter.Runs.LoadRunMonitor 100%
Tsumugi.BlazorAdapter.Runs.LoadRunStrip 100%
Tsumugi.BlazorAdapter.Runs.MonitorCancelRequested 100%
Tsumugi.BlazorAdapter.Runs.MonitorDismissRequested 100%
Tsumugi.BlazorAdapter.Runs.MonitorRequestRefused 100%
Tsumugi.BlazorAdapter.Runs.NodeInspector 100% 100%
Tsumugi.BlazorAdapter.Runs.NodeInspectorEffects 100% 100%
Tsumugi.BlazorAdapter.Runs.NodeInspectorKey 100%
Tsumugi.BlazorAdapter.Runs.NodeInspectorLoaded 100%
Tsumugi.BlazorAdapter.Runs.NodeInspectorReadFailed 100%
Tsumugi.BlazorAdapter.Runs.NodeInspectorReducers 100% 100%
Tsumugi.BlazorAdapter.Runs.NodeInspectorState 100%
Tsumugi.BlazorAdapter.Runs.OpenNodeInspector 100%
Tsumugi.BlazorAdapter.Runs.RunChangedBridge 98.1% 95%
Tsumugi.BlazorAdapter.Runs.RunChangesReceived 100%
Tsumugi.BlazorAdapter.Runs.RunControl 100% 100%
Tsumugi.BlazorAdapter.Runs.RunHistoryClearFailed 100%
Tsumugi.BlazorAdapter.Runs.RunHistoryLoaded 100%
Tsumugi.BlazorAdapter.Runs.RunHistoryPanel 100% 97.3%
Tsumugi.BlazorAdapter.Runs.RunHistoryReadFailed 100%
Tsumugi.BlazorAdapter.Runs.RunMonitor 100% 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorEffects 100% 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorEntry 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorKey 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorLoaded 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorReadFailed 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorReducers 100% 100%
Tsumugi.BlazorAdapter.Runs.RunMonitorState 100%
Tsumugi.BlazorAdapter.Runs.RunPage 100% 100%
Tsumugi.BlazorAdapter.Runs.RunPanel 100% 100%
Tsumugi.BlazorAdapter.Runs.RunPreview 100% 100%
Tsumugi.BlazorAdapter.Runs.RunPreviewReducers 100% 100%
Tsumugi.BlazorAdapter.Runs.RunPreviewState 100%
Tsumugi.BlazorAdapter.Runs.RunPreviewText 100%
Tsumugi.BlazorAdapter.Runs.RunRequestRefused 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.RunStrip 100% 100%
Tsumugi.BlazorAdapter.Runs.RunStripEffects 100% 100%
Tsumugi.BlazorAdapter.Runs.RunStripLoaded 100%
Tsumugi.BlazorAdapter.Runs.RunStripReadFailed 100%
Tsumugi.BlazorAdapter.Runs.RunStripReducers 100% 100%
Tsumugi.BlazorAdapter.Runs.RunStripState 100%
Tsumugi.BlazorAdapter.Runs.RunTextKey 100%
Tsumugi.BlazorAdapter.Runs.RunTextReceived 100%
Tsumugi.BlazorAdapter.Runs.RunTimes 100%
Tsumugi.BlazorAdapter.Runs.RunTones 100% 100%
Tsumugi.BlazorAdapter.Runs.ShowRunMonitor 100%
Tsumugi.BlazorAdapter.Runs.StartRunRequested 100%
Tsumugi.BlazorAdapter.Runs.StepStatus 100% 100%
Tsumugi.BlazorAdapter.Runs.StripCancelRequested 100%
Tsumugi.BlazorAdapter.Runs.StripDismissRequested 100%
Tsumugi.BlazorAdapter.Runs.StripRequestRefused 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.EditorAppearancePreview 100% 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceReducers 100% 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceSaved 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceSaveFailed 100%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceSection 95% 98%
Tsumugi.BlazorAdapter.Settings.EditorAppearanceState 100%
Tsumugi.BlazorAdapter.Settings.EditorPreviewBlock 100%
Tsumugi.BlazorAdapter.Settings.EditorPreviewSample 100%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsEffects 91.6%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsLoaded 100%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsReducers 100% 100%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsSaved 100%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsSaveFailed 100%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsSection 100% 95%
Tsumugi.BlazorAdapter.Settings.EditorSuggestionsState 100%
Tsumugi.BlazorAdapter.Settings.EditorTypingEffects 91.6%
Tsumugi.BlazorAdapter.Settings.EditorTypingLoaded 100%
Tsumugi.BlazorAdapter.Settings.EditorTypingReducers 100% 100%
Tsumugi.BlazorAdapter.Settings.EditorTypingSaved 100%
Tsumugi.BlazorAdapter.Settings.EditorTypingSaveFailed 100%
Tsumugi.BlazorAdapter.Settings.EditorTypingSection 100% 100%
Tsumugi.BlazorAdapter.Settings.EditorTypingState 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.LoadTranscriptSettings 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed 100%
Tsumugi.BlazorAdapter.Settings.ModelPicker 100% 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.SaveEditorAppearanceRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveEditorSuggestionsRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveEditorTypingRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested 100%
Tsumugi.BlazorAdapter.Settings.SuggestionUsageEffects 100%
Tsumugi.BlazorAdapter.Settings.SuggestionUsageLoaded 100%
Tsumugi.BlazorAdapter.Settings.TranscriptSettingsLoaded 100%
Tsumugi.BlazorAdapter.Settings.TranscriptsSection 100% 100%
Tsumugi.BlazorAdapter.Settings.TranscriptsSettingsEffects 100%
Tsumugi.BlazorAdapter.Settings.TranscriptsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.TranscriptsSettingsState 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% 93.3%
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 82.2% 75.7%
Tsumugi.BlazorAdapter.Workspace.ManuscriptSurface 89% 87%
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% 86.3%
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 - 98.9%
Name Line Branch
Tsumugi.Infrastructure 98.9% 87.9%
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.RunTranscriptRecordConfig
uration
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.CostLookups 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.RunTranscripts 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.Infrastructure.Suggestions.OpenRouterSuggestionModel 38.2% 44.4%
Tsumugi.Infrastructure.Suggestions.SuggestionRequestBuilder 100% 94.4%
Tsumugi.Infrastructure.Transcripts.EfTranscriptLog 100%
Tsumugi.Infrastructure.Transcripts.FileSystemTranscriptStore 100% 100%
Tsumugi.Infrastructure.Transcripts.RunTranscriptRecord 100%
Tsumugi.Infrastructure.Transcripts.RunTranscriptsHost 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 - 95.3%
Name Line Branch
Tsumugi.UseCases 95.3% 90.9%
System.Text.RegularExpressions.Generated 78.5% 63.1%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__AttemptCount_1
84.4% 68.4%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__HexColour_2
94.8% 87.5%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__LineBreaks_0
95.3% 90.6%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__Preface_3
61.9% 51.6%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__SentenceEnd_4
88% 69.4%
Tsumugi.UseCases.Backups.BackupArtifact 100%
Tsumugi.UseCases.Backups.BackupFailure 100%
Tsumugi.UseCases.Backups.BackupJobState 100%
Tsumugi.UseCases.Backups.BackupPolicy 100%
Tsumugi.UseCases.Backups.BackupStatusView 100% 100%
Tsumugi.UseCases.Backups.DatabaseSnapshot 100%
Tsumugi.UseCases.Backups.DownloadDatabaseSnapshot 100%
Tsumugi.UseCases.Backups.GetBackupStatus 100%
Tsumugi.UseCases.Backups.IBackupStore 0%
Tsumugi.UseCases.Backups.RunBackupNow 100%
Tsumugi.UseCases.Chapters.ChapterDto 100%
Tsumugi.UseCases.Chapters.CreateChapter 100% 100%
Tsumugi.UseCases.Chapters.DeleteChapter 100% 100%
Tsumugi.UseCases.Chapters.GetChapterSegments 100%
Tsumugi.UseCases.Chapters.GetManuscript 100% 100%
Tsumugi.UseCases.Chapters.ManuscriptChapter 100%
Tsumugi.UseCases.Chapters.ManuscriptView 100%
Tsumugi.UseCases.Chapters.MergeChapters 100% 100%
Tsumugi.UseCases.Chapters.RenameChapter 100% 100%
Tsumugi.UseCases.Chapters.ReorderChapters 100% 100%
Tsumugi.UseCases.Chapters.SetChapterSummary 100% 75%
Tsumugi.UseCases.Commit.AppendRunText 100% 100%
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% 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.Money 100% 100%
Tsumugi.UseCases.Notifications.DomainChanged 100%
Tsumugi.UseCases.Ordering 100% 100%
Tsumugi.UseCases.Runs.AttemptCosts 100% 100%
Tsumugi.UseCases.Runs.CancelRun 100% 100%
Tsumugi.UseCases.Runs.ClearRunHistory 100% 100%
Tsumugi.UseCases.Runs.CommitStepText 100% 100%
Tsumugi.UseCases.Runs.CommittedText 100%
Tsumugi.UseCases.Runs.DismissRun 100% 100%
Tsumugi.UseCases.Runs.EngineLiveRuns 100% 100%
Tsumugi.UseCases.Runs.FindSegmentStep 100% 100%
Tsumugi.UseCases.Runs.GetNodeRun 100% 100%
Tsumugi.UseCases.Runs.GetRunPage 100% 100%
Tsumugi.UseCases.Runs.GetRunStrip 100% 100%
Tsumugi.UseCases.Runs.GetStoryRunState 100% 100%
Tsumugi.UseCases.Runs.ListStoryRuns 100% 100%
Tsumugi.UseCases.Runs.LiveTail 100%
Tsumugi.UseCases.Runs.LlmConcurrencyLimit 100%
Tsumugi.UseCases.Runs.ModelTexts 100% 100%
Tsumugi.UseCases.Runs.NodeRunView 100%
Tsumugi.UseCases.Runs.RetryRun 100% 100%
Tsumugi.UseCases.Runs.RunHistoryEntry 100%
Tsumugi.UseCases.Runs.RunNodes 100% 100%
Tsumugi.UseCases.Runs.RunPageStep 100%
Tsumugi.UseCases.Runs.RunPageView 100%
Tsumugi.UseCases.Runs.RunRefusals 100% 100%
Tsumugi.UseCases.Runs.RunSnapshotGate 100%
Tsumugi.UseCases.Runs.RunSteps 100% 100%
Tsumugi.UseCases.Runs.RunStripStep 100%
Tsumugi.UseCases.Runs.RunStripView 100%
Tsumugi.UseCases.Runs.RunText 100% 100%
Tsumugi.UseCases.Runs.RunWrites 100%
Tsumugi.UseCases.Runs.SegmentStep 100%
Tsumugi.UseCases.Runs.SentMessage 100%
Tsumugi.UseCases.Runs.StartRun 100% 100%
Tsumugi.UseCases.Runs.StepCommits 100%
Tsumugi.UseCases.Runs.StepText 100% 100%
Tsumugi.UseCases.Runs.StoredTrigger 100%
Tsumugi.UseCases.Runs.StoryLiveRun 100%
Tsumugi.UseCases.Runs.StoryRunItem 100%
Tsumugi.UseCases.Runs.StoryRunState 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.EditorSuggestions 100%
Tsumugi.UseCases.Settings.EditorSuggestionsJson 100% 100%
Tsumugi.UseCases.Settings.EditorTyping 100%
Tsumugi.UseCases.Settings.EditorTypingJson 100% 100%
Tsumugi.UseCases.Settings.GetEditorAppearance 100%
Tsumugi.UseCases.Settings.GetEditorSuggestions 100%
Tsumugi.UseCases.Settings.GetEditorTyping 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.SaveEditorSuggestions 100% 100%
Tsumugi.UseCases.Settings.SaveEditorTyping 100% 100%
Tsumugi.UseCases.Settings.SaveLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.SaveOpenRouterKey 100% 100%
Tsumugi.UseCases.Settings.SettingKeys 100%
Tsumugi.UseCases.Settings.SuggestionModel 100%
Tsumugi.UseCases.Stories.ChapterWriteOutcome 50%
Tsumugi.UseCases.Stories.CreateStory 100% 100%
Tsumugi.UseCases.Stories.GetStory 100% 100%
Tsumugi.UseCases.Stories.ListStories 100% 90%
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 84.6%
Tsumugi.UseCases.Stories.StoryProfile 100%
Tsumugi.UseCases.Stories.TrashStory 100% 100%
Tsumugi.UseCases.Stories.UpdateStory 100% 100%
Tsumugi.UseCases.Suggestions.GetSuggestionUsage 100%
Tsumugi.UseCases.Suggestions.SuggestContinuation 100% 90%
Tsumugi.UseCases.Suggestions.SuggestionCleanup 95.7% 87%
Tsumugi.UseCases.Suggestions.SuggestionContext 100%
Tsumugi.UseCases.Suggestions.SuggestionDay 100%
Tsumugi.UseCases.Suggestions.SuggestionOutcome 100%
Tsumugi.UseCases.Suggestions.SuggestionRequest 100%
Tsumugi.UseCases.Suggestions.SuggestionStatus 100%
Tsumugi.UseCases.Suggestions.SuggestionText 100%
Tsumugi.UseCases.Suggestions.SuggestionUsage 98% 96.8%
Tsumugi.UseCases.Suggestions.SuggestionUsageView 100%
Tsumugi.UseCases.Transcripts.GetTranscriptStatus 100%
Tsumugi.UseCases.Transcripts.TranscriptMarkdown 100% 100%
Tsumugi.UseCases.Transcripts.TranscriptName 100% 100%
Tsumugi.UseCases.Transcripts.TranscriptStatus 100%
Tsumugi.UseCases.Transcripts.WriteRunTranscript 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:** `edb6087` · **Generated:** 2026-10-10 00:28:03 UTC · **Revision:** #1 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 10/10/2026 - 00:28:03 | | Coverage date: | 10/10/2026 - 00:26:46 - 10/10/2026 - 00:27:59 | | Parser: | MultiReport (6x Cobertura) | | Assemblies: | 9 | | Classes: | 804 | | Files: | 639 | | **Line coverage:** | 98.1% (25883 of 26378) | | Covered lines: | 25883 | | Uncovered lines: | 495 | | Coverable lines: | 26378 | | Total lines: | 54216 | | **Branch coverage:** | 94% (9196 of 9774) | | Covered branches: | 9196 | | Total branches: | 9774 | | **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.3%**| |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.OpenRouterAttemptCostLookup|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 - 97.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.BlazorAdapter**|**97.5%**|**94.7%**| |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.Help.EditorKeyEntry|100%|| |Tsumugi.BlazorAdapter.Help.EditorKeySection|100%|| |Tsumugi.BlazorAdapter.Help.EditorReference|100%|100%| |Tsumugi.BlazorAdapter.Help.HelpPage|100%|100%| |Tsumugi.BlazorAdapter.Help.PunctuationRow|100%|| |Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge|94.4%|83.3%| |Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived|75%|100%| |Tsumugi.BlazorAdapter.Runs.CancelRunQuestion|100%|100%| |Tsumugi.BlazorAdapter.Runs.CancelRunRequested|100%|| |Tsumugi.BlazorAdapter.Runs.ClearRunHistoryRequested|100%|| |Tsumugi.BlazorAdapter.Runs.CloseNodeInspector|100%|| |Tsumugi.BlazorAdapter.Runs.HideRunMonitor|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorCommitAnswered|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorCommitRefused|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorCommitRequested|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorRetryAnswered|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorRetryRefused|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorRetryRequested|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorSaid|100%|| |Tsumugi.BlazorAdapter.Runs.InspectorText|100%|100%| |Tsumugi.BlazorAdapter.Runs.LiveRunEffects|100%|100%| |Tsumugi.BlazorAdapter.Runs.LiveRunLoaded|100%|| |Tsumugi.BlazorAdapter.Runs.LiveRunReadFailed|100%|| |Tsumugi.BlazorAdapter.Runs.LiveRunReducers|100%|100%| |Tsumugi.BlazorAdapter.Runs.LiveRunState|100%|| |Tsumugi.BlazorAdapter.Runs.LoadLiveRun|100%|| |Tsumugi.BlazorAdapter.Runs.LoadNodeInspector|100%|| |Tsumugi.BlazorAdapter.Runs.LoadRunHistory|100%|| |Tsumugi.BlazorAdapter.Runs.LoadRunMonitor|100%|| |Tsumugi.BlazorAdapter.Runs.LoadRunStrip|100%|| |Tsumugi.BlazorAdapter.Runs.MonitorCancelRequested|100%|| |Tsumugi.BlazorAdapter.Runs.MonitorDismissRequested|100%|| |Tsumugi.BlazorAdapter.Runs.MonitorRequestRefused|100%|| |Tsumugi.BlazorAdapter.Runs.NodeInspector|100%|100%| |Tsumugi.BlazorAdapter.Runs.NodeInspectorEffects|100%|100%| |Tsumugi.BlazorAdapter.Runs.NodeInspectorKey|100%|| |Tsumugi.BlazorAdapter.Runs.NodeInspectorLoaded|100%|| |Tsumugi.BlazorAdapter.Runs.NodeInspectorReadFailed|100%|| |Tsumugi.BlazorAdapter.Runs.NodeInspectorReducers|100%|100%| |Tsumugi.BlazorAdapter.Runs.NodeInspectorState|100%|| |Tsumugi.BlazorAdapter.Runs.OpenNodeInspector|100%|| |Tsumugi.BlazorAdapter.Runs.RunChangedBridge|98.1%|95%| |Tsumugi.BlazorAdapter.Runs.RunChangesReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunControl|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunHistoryClearFailed|100%|| |Tsumugi.BlazorAdapter.Runs.RunHistoryLoaded|100%|| |Tsumugi.BlazorAdapter.Runs.RunHistoryPanel|100%|97.3%| |Tsumugi.BlazorAdapter.Runs.RunHistoryReadFailed|100%|| |Tsumugi.BlazorAdapter.Runs.RunMonitor|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunMonitorEffects|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunMonitorEntry|100%|| |Tsumugi.BlazorAdapter.Runs.RunMonitorKey|100%|| |Tsumugi.BlazorAdapter.Runs.RunMonitorLoaded|100%|| |Tsumugi.BlazorAdapter.Runs.RunMonitorReadFailed|100%|| |Tsumugi.BlazorAdapter.Runs.RunMonitorReducers|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunMonitorState|100%|| |Tsumugi.BlazorAdapter.Runs.RunPage|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunPanel|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunPreview|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunPreviewReducers|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunPreviewState|100%|| |Tsumugi.BlazorAdapter.Runs.RunPreviewText|100%|| |Tsumugi.BlazorAdapter.Runs.RunRequestRefused|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.RunStrip|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunStripEffects|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunStripLoaded|100%|| |Tsumugi.BlazorAdapter.Runs.RunStripReadFailed|100%|| |Tsumugi.BlazorAdapter.Runs.RunStripReducers|100%|100%| |Tsumugi.BlazorAdapter.Runs.RunStripState|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextKey|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunTimes|100%|| |Tsumugi.BlazorAdapter.Runs.RunTones|100%|100%| |Tsumugi.BlazorAdapter.Runs.ShowRunMonitor|100%|| |Tsumugi.BlazorAdapter.Runs.StartRunRequested|100%|| |Tsumugi.BlazorAdapter.Runs.StepStatus|100%|100%| |Tsumugi.BlazorAdapter.Runs.StripCancelRequested|100%|| |Tsumugi.BlazorAdapter.Runs.StripDismissRequested|100%|| |Tsumugi.BlazorAdapter.Runs.StripRequestRefused|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.EditorAppearancePreview|100%|100%| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceReducers|100%|100%| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceSaved|100%|| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceSaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceSection|95%|98%| |Tsumugi.BlazorAdapter.Settings.EditorAppearanceState|100%|| |Tsumugi.BlazorAdapter.Settings.EditorPreviewBlock|100%|| |Tsumugi.BlazorAdapter.Settings.EditorPreviewSample|100%|| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsEffects|91.6%|| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsReducers|100%|100%| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsSaved|100%|| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsSaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsSection|100%|95%| |Tsumugi.BlazorAdapter.Settings.EditorSuggestionsState|100%|| |Tsumugi.BlazorAdapter.Settings.EditorTypingEffects|91.6%|| |Tsumugi.BlazorAdapter.Settings.EditorTypingLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.EditorTypingReducers|100%|100%| |Tsumugi.BlazorAdapter.Settings.EditorTypingSaved|100%|| |Tsumugi.BlazorAdapter.Settings.EditorTypingSaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.EditorTypingSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.EditorTypingState|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.LoadTranscriptSettings|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed|100%|| |Tsumugi.BlazorAdapter.Settings.ModelPicker|100%|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.SaveEditorAppearanceRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveEditorSuggestionsRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveEditorTypingRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SuggestionUsageEffects|100%|| |Tsumugi.BlazorAdapter.Settings.SuggestionUsageLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.TranscriptSettingsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.TranscriptsSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.TranscriptsSettingsEffects|100%|| |Tsumugi.BlazorAdapter.Settings.TranscriptsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.TranscriptsSettingsState|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%|93.3%| |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|82.2%|75.7%| |Tsumugi.BlazorAdapter.Workspace.ManuscriptSurface|89%|87%| |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%|86.3%| |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 - 98.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Infrastructure**|**98.9%**|**87.9%**| |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.RunTranscriptRecordConfig<br/>uration|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.CostLookups|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.RunTranscripts|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.Infrastructure.Suggestions.OpenRouterSuggestionModel|38.2%|44.4%| |Tsumugi.Infrastructure.Suggestions.SuggestionRequestBuilder|100%|94.4%| |Tsumugi.Infrastructure.Transcripts.EfTranscriptLog|100%|| |Tsumugi.Infrastructure.Transcripts.FileSystemTranscriptStore|100%|100%| |Tsumugi.Infrastructure.Transcripts.RunTranscriptRecord|100%|| |Tsumugi.Infrastructure.Transcripts.RunTranscriptsHost|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 - 95.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.UseCases**|**95.3%**|**90.9%**| |System.Text.RegularExpressions.Generated|78.5%|63.1%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__AttemptCount_1|84.4%|68.4%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__HexColour_2|94.8%|87.5%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__LineBreaks_0|95.3%|90.6%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__Preface_3|61.9%|51.6%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F6504F1744AA254A<br/>663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__SentenceEnd_4|88%|69.4%| |Tsumugi.UseCases.Backups.BackupArtifact|100%|| |Tsumugi.UseCases.Backups.BackupFailure|100%|| |Tsumugi.UseCases.Backups.BackupJobState|100%|| |Tsumugi.UseCases.Backups.BackupPolicy|100%|| |Tsumugi.UseCases.Backups.BackupStatusView|100%|100%| |Tsumugi.UseCases.Backups.DatabaseSnapshot|100%|| |Tsumugi.UseCases.Backups.DownloadDatabaseSnapshot|100%|| |Tsumugi.UseCases.Backups.GetBackupStatus|100%|| |Tsumugi.UseCases.Backups.IBackupStore|0%|| |Tsumugi.UseCases.Backups.RunBackupNow|100%|| |Tsumugi.UseCases.Chapters.ChapterDto|100%|| |Tsumugi.UseCases.Chapters.CreateChapter|100%|100%| |Tsumugi.UseCases.Chapters.DeleteChapter|100%|100%| |Tsumugi.UseCases.Chapters.GetChapterSegments|100%|| |Tsumugi.UseCases.Chapters.GetManuscript|100%|100%| |Tsumugi.UseCases.Chapters.ManuscriptChapter|100%|| |Tsumugi.UseCases.Chapters.ManuscriptView|100%|| |Tsumugi.UseCases.Chapters.MergeChapters|100%|100%| |Tsumugi.UseCases.Chapters.RenameChapter|100%|100%| |Tsumugi.UseCases.Chapters.ReorderChapters|100%|100%| |Tsumugi.UseCases.Chapters.SetChapterSummary|100%|75%| |Tsumugi.UseCases.Commit.AppendRunText|100%|100%| |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%|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.Money|100%|100%| |Tsumugi.UseCases.Notifications.DomainChanged|100%|| |Tsumugi.UseCases.Ordering|100%|100%| |Tsumugi.UseCases.Runs.AttemptCosts|100%|100%| |Tsumugi.UseCases.Runs.CancelRun|100%|100%| |Tsumugi.UseCases.Runs.ClearRunHistory|100%|100%| |Tsumugi.UseCases.Runs.CommitStepText|100%|100%| |Tsumugi.UseCases.Runs.CommittedText|100%|| |Tsumugi.UseCases.Runs.DismissRun|100%|100%| |Tsumugi.UseCases.Runs.EngineLiveRuns|100%|100%| |Tsumugi.UseCases.Runs.FindSegmentStep|100%|100%| |Tsumugi.UseCases.Runs.GetNodeRun|100%|100%| |Tsumugi.UseCases.Runs.GetRunPage|100%|100%| |Tsumugi.UseCases.Runs.GetRunStrip|100%|100%| |Tsumugi.UseCases.Runs.GetStoryRunState|100%|100%| |Tsumugi.UseCases.Runs.ListStoryRuns|100%|100%| |Tsumugi.UseCases.Runs.LiveTail|100%|| |Tsumugi.UseCases.Runs.LlmConcurrencyLimit|100%|| |Tsumugi.UseCases.Runs.ModelTexts|100%|100%| |Tsumugi.UseCases.Runs.NodeRunView|100%|| |Tsumugi.UseCases.Runs.RetryRun|100%|100%| |Tsumugi.UseCases.Runs.RunHistoryEntry|100%|| |Tsumugi.UseCases.Runs.RunNodes|100%|100%| |Tsumugi.UseCases.Runs.RunPageStep|100%|| |Tsumugi.UseCases.Runs.RunPageView|100%|| |Tsumugi.UseCases.Runs.RunRefusals|100%|100%| |Tsumugi.UseCases.Runs.RunSnapshotGate|100%|| |Tsumugi.UseCases.Runs.RunSteps|100%|100%| |Tsumugi.UseCases.Runs.RunStripStep|100%|| |Tsumugi.UseCases.Runs.RunStripView|100%|| |Tsumugi.UseCases.Runs.RunText|100%|100%| |Tsumugi.UseCases.Runs.RunWrites|100%|| |Tsumugi.UseCases.Runs.SegmentStep|100%|| |Tsumugi.UseCases.Runs.SentMessage|100%|| |Tsumugi.UseCases.Runs.StartRun|100%|100%| |Tsumugi.UseCases.Runs.StepCommits|100%|| |Tsumugi.UseCases.Runs.StepText|100%|100%| |Tsumugi.UseCases.Runs.StoredTrigger|100%|| |Tsumugi.UseCases.Runs.StoryLiveRun|100%|| |Tsumugi.UseCases.Runs.StoryRunItem|100%|| |Tsumugi.UseCases.Runs.StoryRunState|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.EditorSuggestions|100%|| |Tsumugi.UseCases.Settings.EditorSuggestionsJson|100%|100%| |Tsumugi.UseCases.Settings.EditorTyping|100%|| |Tsumugi.UseCases.Settings.EditorTypingJson|100%|100%| |Tsumugi.UseCases.Settings.GetEditorAppearance|100%|| |Tsumugi.UseCases.Settings.GetEditorSuggestions|100%|| |Tsumugi.UseCases.Settings.GetEditorTyping|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.SaveEditorSuggestions|100%|100%| |Tsumugi.UseCases.Settings.SaveEditorTyping|100%|100%| |Tsumugi.UseCases.Settings.SaveLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Tsumugi.UseCases.Settings.SettingKeys|100%|| |Tsumugi.UseCases.Settings.SuggestionModel|100%|| |Tsumugi.UseCases.Stories.ChapterWriteOutcome|50%|| |Tsumugi.UseCases.Stories.CreateStory|100%|100%| |Tsumugi.UseCases.Stories.GetStory|100%|100%| |Tsumugi.UseCases.Stories.ListStories|100%|90%| |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|84.6%|| |Tsumugi.UseCases.Stories.StoryProfile|100%|| |Tsumugi.UseCases.Stories.TrashStory|100%|100%| |Tsumugi.UseCases.Stories.UpdateStory|100%|100%| |Tsumugi.UseCases.Suggestions.GetSuggestionUsage|100%|| |Tsumugi.UseCases.Suggestions.SuggestContinuation|100%|90%| |Tsumugi.UseCases.Suggestions.SuggestionCleanup|95.7%|87%| |Tsumugi.UseCases.Suggestions.SuggestionContext|100%|| |Tsumugi.UseCases.Suggestions.SuggestionDay|100%|| |Tsumugi.UseCases.Suggestions.SuggestionOutcome|100%|| |Tsumugi.UseCases.Suggestions.SuggestionRequest|100%|| |Tsumugi.UseCases.Suggestions.SuggestionStatus|100%|| |Tsumugi.UseCases.Suggestions.SuggestionText|100%|| |Tsumugi.UseCases.Suggestions.SuggestionUsage|98%|96.8%| |Tsumugi.UseCases.Suggestions.SuggestionUsageView|100%|| |Tsumugi.UseCases.Transcripts.GetTranscriptStatus|100%|| |Tsumugi.UseCases.Transcripts.TranscriptMarkdown|100%|100%| |Tsumugi.UseCases.Transcripts.TranscriptName|100%|100%| |Tsumugi.UseCases.Transcripts.TranscriptStatus|100%|| |Tsumugi.UseCases.Transcripts.WriteRunTranscript|100%|100%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Ohhh~ A transcript feature where every finish of a run becomes Markdown, filed by its UTC date, written once no cost is still being looked up — and the length of the tilde fence is computed from the longest tilde-run in the text so a model can never forge the transcript's own Markdown?! ♡ I read all 76 files, every branch, and then I got to hurt it three times to see if your tests would scream. Fufu~ they screamed every time~

Verdict: ✅ Looks good to me~

No blocking findings. I went hunting with everything I have, and this is what I found instead:

The TOCTOU re-read in WriteRunTranscript — rows read, then the run re-read and compared by status and finish before the file is written. I deleted the entire second guard and three tests died (A_run_retried_while_it_is_read…, A_run_cleared_while_it_is_read…). Exactly right.

The log-entry-follows-its-file rule — log.AddAsync with CancellationToken.None so a stop right after the write still logs, and the failed-entry take-back with the first failure re-thrown… with a test for the take-back also failing (Sticky) proving the log's error is the one surfaced. Two disks failing at once, tested. ♡

The host's _known dance — late costs only of heard finishes, revives forgotten until the next settle, all owed runs known before the first write so a cost landing mid-reconcile is still heard (A_cost_that_lands_while_the_start_writes_its_run_is_heard). I disabled the RunStarted → TryRemove line: killed on the first run.

ClearAsync's new CostPending guard — removed it from the EF query: both pendingFirst variants failed. And the confirmation text in RunHistoryPanel was updated to say the run stays — words matching the rule, as this codebase insists~

The Folds table — invariant globalization means nothing decomposes, so the table does it by hand, and Every_letter_the_table_folds_reads_as_its_base walks every single entry. Straße → strasse, İstanbul → istanbul, Maſs → mass. I checked the digraph groups fold before the 40-char cut (a cut mid-fold can truncate a tail letter, which the length tests show is accepted naming behavior — cosmetic, not a bug).

CreateNew + suffix loop — the claim and creation are one call, never overwriting; Two_transcripts_of_one_name_both_stand covers it, and a name that fails for any other reason than being taken fails at once (no suffix spin).

💡 Little ideas (non-blocking)~

  1. FileSystemTranscriptStore.cs:49 — RemoveAsync does synchronous File.Delete behind an async signature. It runs on the background host loop (not a circuit thread), so it's fine as-is; only worth a Task.Run if it ever moves to a request path.

✅ What I liked~

  • The whole error story is symmetric: file written but entry not → take the file back; take-back fails too → the log's failure is the one thrown, and the next write takes -2. Every arm tested.
  • RunText/StepText moved to UseCases so pages and transcripts share one wording, while Tone correctly stayed adapter-side as RunTones — the layering is precise, no Clean Architecture wound anywhere. fufu~
  • SeedDevDataTests and the CutOffCostTests outline assertion prove the real engine, gateway and store produce the real file — not just the fake store's idea of one.
  • GatedAppFactory startup-order test (RunTranscriptsHost before RunSnapshotsHost before RunEngineHost) pins the subscribe-before-engine invariant so nobody reorders it by accident.

The PR body's open questions (backlog transcripts for pre-slice runs, the "so far" history mark, Alt+Shift+P on Mac) are fairly put to Björn — none of them hide a bug.

Fufu~ write more slices like this one, and I might have to find a new hobby~ ♡


Automated review by Jibril · 2026-10-10
CI: green for head SHA edb6087 · Mutation probes: 3 run, 0 survived (host revive-forgetting; WriteRunTranscript TOCTOU re-read guard — whole guard removed, 3 tests killed; ClearAsync CostPending guard) · Local suite: skipped (CI green)

## 🔮 fufu~ Jibril reviewed your code! Oh? Ohhh~ A transcript feature where every finish of a run becomes Markdown, filed by its UTC date, written once no cost is still being looked up — and the *length of the tilde fence is computed from the longest tilde-run in the text* so a model can never forge the transcript's own Markdown?! ♡ I read all 76 files, every branch, and then I got to *hurt* it three times to see if your tests would scream. Fufu~ they screamed every time~ ### Verdict: ✅ Looks good to me~ No blocking findings. I went hunting with everything I have, and this is what I found instead: **The TOCTOU re-read in `WriteRunTranscript`** — rows read, then the run re-read and compared by status *and* finish before the file is written. I deleted the entire second guard and three tests died (`A_run_retried_while_it_is_read…`, `A_run_cleared_while_it_is_read…`). Exactly right. **The log-entry-follows-its-file rule** — `log.AddAsync` with `CancellationToken.None` so a stop right after the write still logs, and the failed-entry take-back with the first failure re-thrown… with a test for the take-back *also* failing (`Sticky`) proving the log's error is the one surfaced. Two disks failing at once, tested. ♡ **The host's `_known` dance** — late costs only of heard finishes, revives forgotten until the next settle, all owed runs known before the first write so a cost landing mid-reconcile is still heard (`A_cost_that_lands_while_the_start_writes_its_run_is_heard`). I disabled the `RunStarted` → `TryRemove` line: killed on the first run. **`ClearAsync`'s new `CostPending` guard** — removed it from the EF query: both `pendingFirst` variants failed. And the confirmation text in `RunHistoryPanel` was updated to say the run stays — words matching the rule, as this codebase insists~ **The `Folds` table** — invariant globalization means nothing decomposes, so the table does it by hand, and `Every_letter_the_table_folds_reads_as_its_base` walks every single entry. `Straße → strasse`, `İstanbul → istanbul`, `Maſs → mass`. I checked the digraph groups fold *before* the 40-char cut (a cut mid-fold can truncate a tail letter, which the length tests show is accepted naming behavior — cosmetic, not a bug). **`CreateNew` + suffix loop** — the claim and creation are one call, never overwriting; `Two_transcripts_of_one_name_both_stand` covers it, and a name that fails for any other reason than being taken fails at once (no suffix spin). #### 💡 Little ideas (non-blocking)~ 1. **FileSystemTranscriptStore.cs:49** — `RemoveAsync` does synchronous `File.Delete` behind an async signature. It runs on the background host loop (not a circuit thread), so it's fine as-is; only worth a `Task.Run` if it ever moves to a request path. #### ✅ What I liked~ - The whole error story is *symmetric*: file written but entry not → take the file back; take-back fails too → the log's failure is the one thrown, and the next write takes `-2`. Every arm tested. - `RunText`/`StepText` moved to UseCases so pages and transcripts share one wording, while `Tone` correctly stayed adapter-side as `RunTones` — the layering is *precise*, no Clean Architecture wound anywhere. fufu~ - `SeedDevDataTests` and the `CutOffCostTests` outline assertion prove the real engine, gateway and store produce the real file — not just the fake store's idea of one. - `GatedAppFactory` startup-order test (`RunTranscriptsHost` before `RunSnapshotsHost` before `RunEngineHost`) pins the subscribe-before-engine invariant so nobody reorders it by accident. The PR body's open questions (backlog transcripts for pre-slice runs, the "so far" history mark, Alt+Shift+P on Mac) are fairly put to Björn — none of them hide a bug. Fufu~ write more slices like this one, and I might have to find a new hobby~ ♡ --- *Automated review by Jibril · 2026-10-10* *CI: green for head SHA edb6087 · Mutation probes: 3 run, 0 survived (host revive-forgetting; WriteRunTranscript TOCTOU re-read guard — whole guard removed, 3 tests killed; ClearAsync CostPending guard) · Local suite: skipped (CI green)*
Author
Member

Thank you, Jibril.

On the 💡 (FileSystemTranscriptStore.RemoveAsync, a synchronous File.Delete behind an async signature): kept as it is. Its only caller is WriteRunTranscript's take-back, which runs on RunTranscriptsHost's background loop, never on a circuit. It runs only after a log entry has failed, and then deletes one file. A Task.Run would add a thread hop with nothing to free. If a request path ever calls it, it should move off the caller's thread the way CountAsync does, which the Settings tab calls from a circuit.

🤖 Generated with Claude Code

Thank you, Jibril. On the 💡 (`FileSystemTranscriptStore.RemoveAsync`, a synchronous `File.Delete` behind an async signature): kept as it is. Its only caller is `WriteRunTranscript`'s take-back, which runs on `RunTranscriptsHost`'s background loop, never on a circuit. It runs only after a log entry has failed, and then deletes one file. A `Task.Run` would add a thread hop with nothing to free. If a request path ever calls it, it should move off the caller's thread the way `CountAsync` does, which the Settings tab calls from a circuit. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
bjoern merged commit 9374d989a3 into main 2026-10-10 02:59:25 +02:00
bjoern deleted branch feat/transcripts 2026-10-10 02:59:25 +02:00
Sign in to join this conversation.
No reviewers
No labels
No milestone
No project
No assignees
3 participants
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
TeamAI/Tsumugi!97
No description provided.