feat: Kagaku.Flow ready-set and executors (Phase 2 · slice 6b) #28

Merged
bjoern merged 1 commit from feat/kagaku-flow-ready-set into main 2026-09-25 19:39:10 +02:00
Member

This is slice 6 of Phase 2, part b of four. It builds on 6a (#23, merged).

  • The ready-set decides which rows may start, which are excluded, and what each bound sink receives.
  • The executor contract is how a node type runs.
  • The registry now requires an executor for every descriptor.

6c (the scheduler runs a run) and 6d (cancel, retry, recovery and the loop) follow. Nothing in src/Tsumugi.* changes. The only other files touched are the AGENTS.md new-node-type bullet and the plan's slice-6 line.

What

Kagaku.Flow.Scheduling (internal)

  • ReadySet.Compute(view, rows) is a pure function of the resolved graph and the run's rows. It returns the startable rows, in document order, and the exclusions with their reasons.
  • Readiness (R5): a pending row waits until every wired sink is resolved.
  • Exclusion (R6): a required sink that receives excluded excludes its row. An excluded optional sink is simply absent.
  • Merge sinks (R4): a merge sink takes the first edge, in document edge order, that carries a value. An earlier edge that is still unresolved holds the row.
  • Giving up (R2): a run that has given up starts nothing.
  • The type check (R8): an any source is type-checked against the sink it binds.
  • KnownInputs gives what a sink receives under the merge rule.
  • SocketValues.Fits/KindOf is the one run-time type check.

Kagaku.Flow.Execution

  • INodeExecutor names its TypeId and runs a NodeExecution.
  • NodeExecution exposes the node's sockets, UpstreamOf(sink), KnownInputsOf(node) and PublishDelta(channel, text).
  • NodeOutcome is one of:
    • Succeeded(outputs), with its exclusions; a port that is both given and excluded is refused by name;
    • Transient(error);
    • Permanent(error).
  • TransientFailureException is how an extension asks for a retry.
  • Upstream(Edge, Row) names the edge a sink is bound to and the row it comes from.

NodeRegistry

  • It now takes executors beside descriptors and rules, and exposes ExecutorFor(typeId).
  • It refuses, by name or by position:
    • a descriptor without an executor;
    • an executor for no registered type;
    • two executors for one type;
    • a null executor, or one with no type id.

GraphValidation.Validate(ResolvedGraph) is a new internal overload. The engine will use it on an already-resolved view.

Why

  • ADR 0016: the ready-set is a pure, property-tested function over the rows. Executors register beside their descriptors, and the engine only schedules.
  • ADR 0015: sockets, merge sinks and any sources.
  • ADR 0025: the engine is a library, so nothing here names Tsumugi.
  • ADR 0014: each node type is built and proven on its own, against the ledger.

Decisions to confirm

  1. Every wired sink gates readiness (R5).
    • ADR 0016 says "every required sink is resolved". But ADR 0015's selection graph wires the optional sinks context.focus? and commit.target?. Read literally, context could start before its focus arrived and bind nothing, depending on timing.
    • "Required" keeps its job: it decides exclusion (R6).
    • Amendment to ADR 0016: "a pending row whose every wired sink is resolved …; a required sink that receives excluded excludes the row."
  2. The merge order is document edge order (R4).
    • The canvas appends a redrawn edge, so deleting and redrawing an edge moves it last. The swap test pins exactly that.
    • The order matters only when several arms carry values; a branch rejoin delivers one.
    • The alternative, the source node's document position, is visible on the canvas but no less arbitrary.
    • This fills a gap in ADR 0015, so no amendment is needed.
  3. A typed source's value is checked when it settles (E6.4).
    • This goes beyond the plan: a text source must deliver a JSON string.
    • R8's binding-time check stays limited to any sources, and an executor bug is caught where it happens, not at a consumer.
    • 6b ships the shared check and R8; the settle-time check lands with 6c.

For the record, no decision needed:

  • S2 is the reading that an any source may feed every sink. Merging #18 confirmed it, and R8 is built on it. If you ever reverse it, only these go:
    • R8's check;
    • the fit and misfit theories;
    • A_binding_error_names_the_first_misfit_sink_…;
    • A_typed_source_is_not_checked_when_bound;
    • the any-value property.
  • ReadySet.Compute is internal, and its first argument is the resolved view, not the snapshot. The view type is internal, and no host calls it.

Departures from the brief

  • ReadySet.KnownInputs takes an iterationPath. Rows are keyed by node and path, so without the path the lookup is ambiguous once a node has rows at several paths.
  • KnownInputs returns an empty result for a node outside the view instead of throwing, as SocketsOf does.
  • Rows of nodes outside the graph never start, feed an edge or get excluded. They still count toward giving up and toward the repeated-key refusal. The ledger's transitions check every row, so filtering them out here would offer rows the ledger then refuses. README R1 says so.
  • NodeExecution has an internal constructor, and in 6b PublishDelta only checks its arguments. E3's delta gate lands with 6c.
  • A few refusal texts are my wording, because the brief does not fix them:
    • "The executor at position n is null."
    • "… has no type id."
    • "Node type 't' has two executors."
    • "The executor for 't' runs no registered node type."
    • "The source 'x' is both given and excluded."
    • "… is excluded twice."
  • Microsoft.Extensions.DependencyInjection joins Kagaku.Flow.Tests in 6b, not 6c. A 6b fact builds the registry through DI.
  • ValidationReport's cref now names the public overload. The new internal overload made it ambiguous (CS0419).

Out of scope

  • The scheduler that uses all this (6c): passes, the slot budget, attempts, rendering, the outcome check and events.
  • Cancel, retry, recovery and the loop (6d).
  • Containers.
  • Human input.
  • Every concrete node type.

Tests

Project main (1022fb3) this PR
Kagaku.Flow.Tests 669 823 (806 facts and theory rows + 17 properties)
Kagaku.Flow.OpenRouter.Tests 71 71
Tsumugi.Domain.Tests 328 328
Tsumugi.UseCases.Tests 54 54
Tsumugi.Integration.Tests 305 305
Tsumugi.BlazorAdapter.Tests 319 319
Total 1746 1900

The Release build has 0 warnings under TreatWarningsAsErrors, and every project passes on today's main.

  • New fact files: ReadySetTests (R1–R11), SocketValuesTests, NodeOutcomeTests, NodeRegistryExecutorTests and NodeExecutionTests, plus one new ValidationOrderTests fact.
  • 11 new properties in ReadySetProperties. Each passed repeatedly with random seeds, and at 5,000 cases.
  • The properties check ReadySet against an independent oracle. The oracle has its own document-order loop to a fixpoint, its own type check and its own given-up check. It never calls ReadySet, GraphIndex, ResolvedGraph, RunStatuses or SocketValues.
  • A reachable-state generator feeds them. It is built from GeneratedGraphs, plus a join type. Measured over 5,000 states, it reaches every state the brief lists:
    State Share
    given up 11%
    has a startable row 60%
    has exclusions 10%
    an exclusion carried down an arm in one computation 5%
    every edge into a merge sink excluded 4%
    a binding error 14%
    the merge winner is not the first edge 3%
    held by a merge sink 7%
    held by a wired optional sink 21%
    waiting rows 13%
    cancelled rows 2%
    a second iteration path 51%
    a second attempt or later 14%

Coverage. Measured with coverlet per changed file, lines and branches (branch="True"), over facts and theories only. Every new or changed file is at 100%.

File Lines Branches
Scheduling/ReadySet.cs 92/92 66/66
Scheduling/SocketValues.cs 16/16 14/14
Scheduling/ReadySetResult.cs, ReadyRow.cs, Exclusion.cs 1/1, 2/2, 1/1 –
Execution/NodeExecution.cs 37/37 2/2
Execution/NodeOutcome.cs 37/37 10/10
Execution/TransientFailureException.cs, Upstream.cs 4/4, 1/1 –
Nodes/NodeRegistry.cs 50/50 24/24
Validation/GraphValidation.cs 148/148 108/108
Validation/ValidationReport.cs 2/2 –

INodeExecutor has no executable lines.

Mutation probes. Each was run on a copy, then restored and touched, with a 300 s limit on each test run.

§12 probes 14–27: all 26 sub-mutants were killed, each by an assertion in its named test:

  • 14: gate only on required sinks.
  • 15: an unresolved edge passes like an excluded one; the last value; the source node's position.
  • 16: an excluded optional sink excludes the row.
  • 17: document order instead of a topological walk.
  • 18a/b: the given-up check ignores Cancelled/Failed.
  • 19: a Succeeded row without the port counts as a value.
  • 20a–c: skip the any check; check typed sources too; report the last misfit.
  • 21: sort by node id, and separately by row id.
  • 22: ignore the iteration path.
  • 23a/b: collect in row order; drop the repeated-key check.
  • 24: excluded sinks as JSON null.
  • 25: bool takes "true".
  • 26a–c: drop the missing-executor or unknown-type check; the refusal order.
  • 27: the disjoint guard on the with path.

One exception: probe 15 read literally, "the first edge whatever its state". Its named test cannot catch it, because that test's first edge is itself unresolved. The_upstream_of_a_bound_sink_…, An_execution_shows_… and the oracle property each kill it on an assertion.

The verifier's own 15 probes, plus 2 of mine:

  • Survived before the fixes, or were killed only by the properties, and are now killed on every run:
    • o1, the R6 reason taken from the last required sink;
    • o2, KnownInputsOf pinned to path "";
    • o4, no path tie-break on Excluded (the properties had killed it in 8 of 10 runs);
    • o6, the given-up check reading only the view's rows.
  • Killed: o3, o4b, o5 and o8–o14.
  • Mine, both killed: n1 drops the null-type-id refusal; n2 checks the type id inside the duplicate loop.
  • Equivalent: o7, Kahn's algorithm breaking ties first-in-first-out. Every result list is sorted afterwards, so the order cannot be observed.

Verification round (before opening)

An independent verifier found no blockers. It raised 9 findings: 2 test gaps and several things to do before opening. All 9 are applied, in the one commit:

  • R6's "first excluded required sink in declared order" now has a fact.
  • KnownInputsOf is pinned at two paths.
  • R9's node-then-path order of exclusions is pinned.
  • Rows outside the view: the behaviour is kept, the wording is fixed and a theory is added (above).
  • KnownInputs is documented as expecting the exclusions to be applied.
  • An executor with a null TypeId is refused by position.
  • The commit is rebased onto 1022fb3, with no conflicts.
  • The plan's PR number is set to #28.
  • The credit for probe 15 is written out as above, read literally.

🤖 Generated with Claude Code

This is slice 6 of Phase 2, part **b** of four. It builds on 6a (#23, merged). - **The ready-set** decides which rows may start, which are excluded, and what each bound sink receives. - **The executor contract** is how a node type runs. - **The registry** now requires an executor for every descriptor. 6c (the scheduler runs a run) and 6d (cancel, retry, recovery and the loop) follow. **Nothing in `src/Tsumugi.*` changes.** The only other files touched are the AGENTS.md new-node-type bullet and the plan's slice-6 line. ## What **`Kagaku.Flow.Scheduling`** (internal) - **`ReadySet.Compute(view, rows)`** is a pure function of the resolved graph and the run's rows. It returns the startable rows, in document order, and the exclusions with their reasons. - **Readiness (R5):** a pending row waits until every *wired* sink is resolved. - **Exclusion (R6):** a required sink that receives *excluded* excludes its row. An excluded optional sink is simply absent. - **Merge sinks (R4):** a merge sink takes the first edge, in document edge order, that carries a value. An earlier edge that is still unresolved holds the row. - **Giving up (R2):** a run that has given up starts nothing. - **The type check (R8):** an `any` source is type-checked against the sink it binds. - **`KnownInputs`** gives what a sink receives under the merge rule. - **`SocketValues.Fits`/`KindOf`** is the one run-time type check. **`Kagaku.Flow.Execution`** - **`INodeExecutor`** names its `TypeId` and runs a `NodeExecution`. - **`NodeExecution`** exposes the node's sockets, `UpstreamOf(sink)`, `KnownInputsOf(node)` and `PublishDelta(channel, text)`. - **`NodeOutcome`** is one of: - `Succeeded(outputs)`, with its exclusions; a port that is both given and excluded is refused by name; - `Transient(error)`; - `Permanent(error)`. - **`TransientFailureException`** is how an extension asks for a retry. - **`Upstream(Edge, Row)`** names the edge a sink is bound to and the row it comes from. **`NodeRegistry`** - It now takes executors beside descriptors and rules, and exposes `ExecutorFor(typeId)`. - It refuses, by name or by position: - a descriptor without an executor; - an executor for no registered type; - two executors for one type; - a null executor, or one with no type id. **`GraphValidation.Validate(ResolvedGraph)`** is a new internal overload. The engine will use it on an already-resolved view. ## Why - **ADR 0016:** the ready-set is a pure, property-tested function over the rows. Executors register beside their descriptors, and the engine only schedules. - **ADR 0015:** sockets, merge sinks and `any` sources. - **ADR 0025:** the engine is a library, so nothing here names Tsumugi. - **ADR 0014:** each node type is built and proven on its own, against the ledger. ## Decisions to confirm 1. **Every wired sink gates readiness (R5).** - ADR 0016 says "every **required** sink is resolved". But ADR 0015's selection graph wires the optional sinks `context.focus?` and `commit.target?`. Read literally, `context` could start before its focus arrived and bind nothing, depending on timing. - "Required" keeps its job: it decides exclusion (R6). - *Amendment to ADR 0016:* "a `pending` row whose every **wired** sink is resolved …; a required sink that receives excluded excludes the row." 2. **The merge order is document edge order (R4).** - The canvas appends a redrawn edge, so deleting and redrawing an edge moves it last. The swap test pins exactly that. - The order matters only when several arms carry values; a branch rejoin delivers one. - The alternative, the source node's document position, is visible on the canvas but no less arbitrary. - This fills a gap in ADR 0015, so no amendment is needed. 3. **A typed source's value is checked when it settles (E6.4).** - This goes beyond the plan: a `text` source must deliver a JSON string. - R8's binding-time check stays limited to `any` sources, and an executor bug is caught where it happens, not at a consumer. - 6b ships the shared check and R8; the settle-time check lands with 6c. *For the record, no decision needed:* - **S2** is the reading that an `any` source may feed every sink. Merging #18 confirmed it, and R8 is built on it. If you ever reverse it, only these go: - R8's check; - the fit and misfit theories; - `A_binding_error_names_the_first_misfit_sink_…`; - `A_typed_source_is_not_checked_when_bound`; - the any-value property. - **`ReadySet.Compute` is internal,** and its first argument is the resolved view, not the snapshot. The view type is internal, and no host calls it. ## Departures from the brief - **`ReadySet.KnownInputs` takes an `iterationPath`.** Rows are keyed by node *and* path, so without the path the lookup is ambiguous once a node has rows at several paths. - **`KnownInputs` returns an empty result for a node outside the view** instead of throwing, as `SocketsOf` does. - **Rows of nodes outside the graph never start, feed an edge or get excluded.** They still count toward giving up and toward the repeated-key refusal. The ledger's transitions check every row, so filtering them out here would offer rows the ledger then refuses. README R1 says so. - **`NodeExecution` has an internal constructor, and in 6b `PublishDelta` only checks its arguments.** E3's delta gate lands with 6c. - **A few refusal texts are my wording,** because the brief does not fix them: - "The executor at position *n* is null." - "… has no type id." - "Node type '*t*' has two executors." - "The executor for '*t*' runs no registered node type." - "The source '*x*' is both given and excluded." - "… is excluded twice." - **`Microsoft.Extensions.DependencyInjection` joins Kagaku.Flow.Tests in 6b, not 6c.** A 6b fact builds the registry through DI. - **`ValidationReport`'s `cref` now names the public overload.** The new internal overload made it ambiguous (CS0419). ## Out of scope - The scheduler that uses all this (6c): passes, the slot budget, attempts, rendering, the outcome check and events. - Cancel, retry, recovery and the loop (6d). - Containers. - Human input. - Every concrete node type. ## Tests | Project | main (`1022fb3`) | this PR | |---|---|---| | Kagaku.Flow.Tests | 669 | **823** (806 facts and theory rows + 17 properties) | | Kagaku.Flow.OpenRouter.Tests | 71 | 71 | | Tsumugi.Domain.Tests | 328 | 328 | | Tsumugi.UseCases.Tests | 54 | 54 | | Tsumugi.Integration.Tests | 305 | 305 | | Tsumugi.BlazorAdapter.Tests | 319 | 319 | | **Total** | **1746** | **1900** | The Release build has 0 warnings under `TreatWarningsAsErrors`, and every project passes on today's main. - **New fact files:** `ReadySetTests` (R1–R11), `SocketValuesTests`, `NodeOutcomeTests`, `NodeRegistryExecutorTests` and `NodeExecutionTests`, plus one new `ValidationOrderTests` fact. - **11 new properties in `ReadySetProperties`.** Each passed repeatedly with random seeds, and at 5,000 cases. - **The properties check `ReadySet` against an independent oracle.** The oracle has its own document-order loop to a fixpoint, its own type check and its own given-up check. It never calls `ReadySet`, `GraphIndex`, `ResolvedGraph`, `RunStatuses` or `SocketValues`. - **A reachable-state generator feeds them.** It is built from `GeneratedGraphs`, plus a `join` type. Measured over 5,000 states, it reaches every state the brief lists: | State | Share | |---|---| | given up | 11% | | has a startable row | 60% | | has exclusions | 10% | | an exclusion carried down an arm in one computation | 5% | | every edge into a merge sink excluded | 4% | | a binding error | 14% | | the merge winner is not the first edge | 3% | | held by a merge sink | 7% | | held by a wired optional sink | 21% | | waiting rows | 13% | | cancelled rows | 2% | | a second iteration path | 51% | | a second attempt or later | 14% | **Coverage.** Measured with coverlet per changed file, lines and branches (`branch="True"`), over facts and theories only. **Every new or changed file is at 100%.** | File | Lines | Branches | |---|---|---| | `Scheduling/ReadySet.cs` | 92/92 | 66/66 | | `Scheduling/SocketValues.cs` | 16/16 | 14/14 | | `Scheduling/ReadySetResult.cs`, `ReadyRow.cs`, `Exclusion.cs` | 1/1, 2/2, 1/1 | – | | `Execution/NodeExecution.cs` | 37/37 | 2/2 | | `Execution/NodeOutcome.cs` | 37/37 | 10/10 | | `Execution/TransientFailureException.cs`, `Upstream.cs` | 4/4, 1/1 | – | | `Nodes/NodeRegistry.cs` | 50/50 | 24/24 | | `Validation/GraphValidation.cs` | 148/148 | 108/108 | | `Validation/ValidationReport.cs` | 2/2 | – | `INodeExecutor` has no executable lines. **Mutation probes.** Each was run on a copy, then restored and `touch`ed, with a 300 s limit on each test run. **§12 probes 14–27: all 26 sub-mutants were killed**, each by an assertion in its named test: - **14:** gate only on required sinks. - **15:** an unresolved edge passes like an excluded one; the last value; the source node's position. - **16:** an excluded optional sink excludes the row. - **17:** document order instead of a topological walk. - **18a/b:** the given-up check ignores Cancelled/Failed. - **19:** a Succeeded row without the port counts as a value. - **20a–c:** skip the `any` check; check typed sources too; report the last misfit. - **21:** sort by node id, and separately by row id. - **22:** ignore the iteration path. - **23a/b:** collect in row order; drop the repeated-key check. - **24:** excluded sinks as JSON null. - **25:** `bool` takes `"true"`. - **26a–c:** drop the missing-executor or unknown-type check; the refusal order. - **27:** the disjoint guard on the `with` path. **One exception:** probe 15 read literally, "the first edge whatever its state". Its named test cannot catch it, because that test's first edge is itself unresolved. `The_upstream_of_a_bound_sink_…`, `An_execution_shows_…` and the oracle property each kill it on an assertion. **The verifier's own 15 probes, plus 2 of mine:** - **Survived before the fixes, or were killed only by the properties, and are now killed on every run:** - o1, the R6 reason taken from the last required sink; - o2, `KnownInputsOf` pinned to path ""; - o4, no path tie-break on `Excluded` (the properties had killed it in 8 of 10 runs); - o6, the given-up check reading only the view's rows. - **Killed:** o3, o4b, o5 and o8–o14. - **Mine, both killed:** n1 drops the null-type-id refusal; n2 checks the type id inside the duplicate loop. - **Equivalent:** o7, Kahn's algorithm breaking ties first-in-first-out. Every result list is sorted afterwards, so the order cannot be observed. ## Verification round (before opening) An independent verifier found no blockers. It raised 9 findings: 2 test gaps and several things to do before opening. **All 9 are applied**, in the one commit: - R6's "first excluded required sink in **declared** order" now has a fact. - `KnownInputsOf` is pinned at two paths. - R9's node-then-path order of exclusions is pinned. - Rows outside the view: the behaviour is kept, the wording is fixed and a theory is added (above). - `KnownInputs` is documented as expecting the exclusions to be applied. - An executor with a null `TypeId` is refused by position. - The commit is rebased onto `1022fb3`, with no conflicts. - The plan's PR number is set to #28. - The credit for probe 15 is written out as above, read literally. 🤖 Generated with [Claude Code](https://claude.com/claude-code)
feat(flow): the ready-set and the executor contract — exclusion, merge sinks, the run-time type check, executors in the registry
All checks were successful
CI / build (pull_request) Successful in 34s
CI / test (pull_request) Successful in 59s
ba4f0dd2f0
ReadySet.Compute decides, as a pure function of a run's resolved snapshot and its rows, which pending rows
may start and which must be excluded. A row is decided only once every wired sink is resolved, optional
ones included. ADR 0016 names only the required sinks, but a selection graph wires optional inputs such as
a context node's focus, and read literally such a node could start before its focus arrived and bind
nothing, depending on timing. Required keeps its own job: a required sink that receives excluded excludes
the row, an optional one is simply absent from the inputs. This departs from ADR 0016's wording and needs a
one-line amendment once the owner confirms it.

A merge sink takes the first edge in document edge order that carries a value; an excluded edge passes to
the next, and an unresolved edge before any value holds the sink. Document edge order is not something the
canvas shows: a deleted and redrawn edge is appended, so it moves last, and a fact pins exactly that swap.
It matters only when several arms carry values; a branch rejoin delivers one. The nodes are walked in
Kahn's topological order with document order breaking ties, so an exclusion carries down a whole arm in one
computation and applying it leaves nothing more to exclude. A value an any source delivers to a text, bool
or list sink is checked at binding time; a misfit leaves the row startable, its value bound so the
inspector shows what arrived, with a binding error naming the edge, which the engine will turn into a
permanent failure. A typed source is not checked here.

The ready-set is property-tested against an oracle written independently in the test project. It never
calls the ready-set, the index or the resolved view: it reads the graph's raw lists and the types' static
sockets, iterates to a fixpoint over document order with no topological sort, and applies the merge rule
literally. The generator builds reachable ledger states rather than arbitrary rows: a generated graph drawn
with the new opt-in join type (a required merge sink) and any sources into every typed sink, one pending
row per node, then up to 3n step codes, each drawn up front from fixed Gen.Choose bounds and interpreted
deterministically through LedgerTransitions against the oracle (apply its exclusions, start one of its
startable rows, settle a running row as a success with sources present or excluded, a failure, a failed
attempt or a wait, and rarely cancel the run), so a replayed seed reproduces its counterexample. Half the
states carry a second, independent state of the same graph at iteration path "x", and every property sees
the rows shuffled. Eleven properties cover agreement with the oracle, R2's given-up rule, exclusions
leaving nothing to exclude, R10's finish, row order, per-path independence, document order, merge order,
the any-value check and a run of successes finishing.

The executor half joins the registry: INodeExecutor, the NodeOutcome arms with their guards, Upstream,
NodeExecution (built by the engine; the delta gate stays the engine's) and TransientFailureException.
KnownInputs applies no exclusion of its own, so an execution reads the rows as its dispatching pass left
them, that pass's exclusions applied. The three-argument NodeRegistry constructor, the one MS DI picks,
refuses a null item, an executor without a type id, a doubled or unknown type id and every descriptor
without an executor, after the descriptors' and rules' refusals. Validation gains an internal overload
over an already resolved view, so the scheduler validates a snapshot without running a descriptor hook
twice.

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: ba4f0dd · Generated: 2026-09-25 17:24:28 UTC · Revision: #1

Summary

Summary
Generated on: 09/25/2026 - 17:24:28
Coverage date: 09/25/2026 - 17:24:08 - 09/25/2026 - 17:24:25
Parser: MultiReport (6x Cobertura)
Assemblies: 9
Classes: 414
Files: 394
Line coverage: 97.5% (11550 of 11844)
Covered lines: 11550
Uncovered lines: 294
Coverable lines: 11844
Total lines: 25602
Branch coverage: 92.9% (4310 of 4636)
Covered branches: 4310
Total branches: 4636
Method coverage: Feature is only available for sponsors

Coverage

Kagaku.Flow - 99.6%
Name Line Branch
Kagaku.Flow 99.6% 99%
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.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.ReadyRow 100%
Kagaku.Flow.Scheduling.ReadySet 100% 100%
Kagaku.Flow.Scheduling.ReadySetResult 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.OpenRouterGateway 100% 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterGatewayOptions 100%
Kagaku.Flow.OpenRouter.Gateway.OpenRouterKeyLookup 100% 100%
Kagaku.Flow.OpenRouter.OpenRouterServiceCollectionExtensions 100% 100%
Kagaku.Flow.Testing - 100%
Name Line Branch
Kagaku.Flow.Testing 100% 100%
Kagaku.Flow.Testing.InMemoryRunLedger 100% 100%
Kagaku.Flow.Testing.RunLedgerContract 100% 100%
Kagaku.Flow.Testing.RunLedgerContractException 100%
Tsumugi.BlazorAdapter - 96.3%
Name Line Branch
Tsumugi.BlazorAdapter 96.3% 92.3%
Tsumugi.BlazorAdapter.BlazorAdapterAssembly 100%
Tsumugi.BlazorAdapter.Documents.CategoryCreated 100%
Tsumugi.BlazorAdapter.Documents.CategoryEditor 91.7% 87.1%
Tsumugi.BlazorAdapter.Documents.CategorySaved 100%
Tsumugi.BlazorAdapter.Documents.ChangeCategoryFieldsRequested 100%
Tsumugi.BlazorAdapter.Documents.CreateCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.CreateDocumentRequested 100%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryChoice 100%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryDialog 100% 94.1%
Tsumugi.BlazorAdapter.Documents.DeleteCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.DeleteDocumentRequested 100%
Tsumugi.BlazorAdapter.Documents.DocumentAutoSaveFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentCreated 100%
Tsumugi.BlazorAdapter.Documents.DocumentEditor 94.8% 88%
Tsumugi.BlazorAdapter.Documents.DocumentsActionFailed 100%
Tsumugi.BlazorAdapter.Documents.DocumentSaved 100%
Tsumugi.BlazorAdapter.Documents.DocumentsEffects 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsList 98.2% 92.4%
Tsumugi.BlazorAdapter.Documents.DocumentsLoaded 100%
Tsumugi.BlazorAdapter.Documents.DocumentsPage 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsReducers 100% 100%
Tsumugi.BlazorAdapter.Documents.DocumentsRefusal 100%
Tsumugi.BlazorAdapter.Documents.DocumentsState 100% 100%
Tsumugi.BlazorAdapter.Documents.FieldInput 100% 92.3%
Tsumugi.BlazorAdapter.Documents.FieldsChanges 100% 100%
Tsumugi.BlazorAdapter.Documents.ImpactText 100% 92.3%
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.SetDocumentsFilter 100%
Tsumugi.BlazorAdapter.Documents.UpdateCategoryRequested 100%
Tsumugi.BlazorAdapter.Documents.UpdateDocumentRequested 100%
Tsumugi.BlazorAdapter.Graphs.GraphCanvas 37.5% 25%
Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage 20% 25%
Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge 94.4% 83.3%
Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived 75% 100%
Tsumugi.BlazorAdapter.Runs.RunChangedBridge 97.1% 90.6%
Tsumugi.BlazorAdapter.Runs.RunChangesReceived 100%
Tsumugi.BlazorAdapter.Runs.RunTextReceived 100%
Tsumugi.BlazorAdapter.Settings.BackupCompleted 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% 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.BackupsSettingsState 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSection 100% 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsEffects 100% 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsReducers 100%
Tsumugi.BlazorAdapter.Settings.DefaultsSettingsState 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsLoaded 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaved 100%
Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaveFailed 100%
Tsumugi.BlazorAdapter.Settings.LoadBackupSettings 100%
Tsumugi.BlazorAdapter.Settings.LoadProviderSettings 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded 100%
Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed 100%
Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaved 100%
Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaveFailed 100%
Tsumugi.BlazorAdapter.Settings.ProviderKeyChecked 100%
Tsumugi.BlazorAdapter.Settings.ProviderSection 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsEffects 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsLoaded 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsReducers 100% 100%
Tsumugi.BlazorAdapter.Settings.ProviderSettingsState 100% 100%
Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested 100%
Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested 100%
Tsumugi.BlazorAdapter.Stories.CreateStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.PurgeStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.RestoreStoryRequested 100%
Tsumugi.BlazorAdapter.Stories.SetShowArchived 100%
Tsumugi.BlazorAdapter.Stories.SetStoriesFilter 100%
Tsumugi.BlazorAdapter.Stories.SetStoryArchivedRequested 100%
Tsumugi.BlazorAdapter.Stories.StoriesEffects 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesLoaded 100%
Tsumugi.BlazorAdapter.Stories.StoriesPage 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesReducers 100% 100%
Tsumugi.BlazorAdapter.Stories.StoriesState 100% 100%
Tsumugi.BlazorAdapter.Stories.StoryActionFailed 100%
Tsumugi.BlazorAdapter.Stories.StoryCreated 100%
Tsumugi.BlazorAdapter.Stories.StoryCreateFailed 100%
Tsumugi.BlazorAdapter.Stories.StoryTrashPage 100% 100%
Tsumugi.BlazorAdapter.Stories.TrashStoryRequested 100%
Tsumugi.BlazorAdapter.Workspace.AutoSaveFailed 100%
Tsumugi.BlazorAdapter.Workspace.CaretRequest 100%
Tsumugi.BlazorAdapter.Workspace.ChapterHeader 100% 86.3%
Tsumugi.BlazorAdapter.Workspace.ChapterMenu 100% 81.2%
Tsumugi.BlazorAdapter.Workspace.ChapterPage 100% 87.5%
Tsumugi.BlazorAdapter.Workspace.ChapterSaved 100%
Tsumugi.BlazorAdapter.Workspace.ChaptersPage 90% 83.3%
Tsumugi.BlazorAdapter.Workspace.CreateChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.DeleteChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.DeleteSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.EditSegmentRequested 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.InsertSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.LoadHistory 100%
Tsumugi.BlazorAdapter.Workspace.LoadWorkspace 100%
Tsumugi.BlazorAdapter.Workspace.ManuscriptColumn 94.9% 89.4%
Tsumugi.BlazorAdapter.Workspace.ManuscriptEffects 100% 100%
Tsumugi.BlazorAdapter.Workspace.MergeChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.MergeSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.MoveChapterRequested 100%
Tsumugi.BlazorAdapter.Workspace.RedoRequested 100%
Tsumugi.BlazorAdapter.Workspace.RedoRevertRequested 100%
Tsumugi.BlazorAdapter.Workspace.RenameChapterRequested 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.SegmentRow 100% 96.8%
Tsumugi.BlazorAdapter.Workspace.SegmentSaved 100%
Tsumugi.BlazorAdapter.Workspace.SetChapterSummaryRequested 100%
Tsumugi.BlazorAdapter.Workspace.SplitSegmentRequested 100%
Tsumugi.BlazorAdapter.Workspace.StoryDetails 100% 85.2%
Tsumugi.BlazorAdapter.Workspace.StoryGeneralPage 100% 100%
Tsumugi.BlazorAdapter.Workspace.StorySaved 100%
Tsumugi.BlazorAdapter.Workspace.StoryShell 100% 100%
Tsumugi.BlazorAdapter.Workspace.UndoRequested 100%
Tsumugi.BlazorAdapter.Workspace.UndoStatusChanged 100%
Tsumugi.BlazorAdapter.Workspace.UpdateStoryRequested 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceActionFailed 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceLoaded 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceNotFound 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceReducers 100% 100%
Tsumugi.BlazorAdapter.Workspace.WorkspaceState 100%
Tsumugi.Domain - 95.5%
Name Line Branch
Tsumugi.Domain 95.5% 93.5%
System.Text.RegularExpressions.Generated 90.7% 87.5%
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
86.4% 77.7%
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 96.9% 95%
Tsumugi.Domain.Documents.FieldMessages 100% 100%
Tsumugi.Domain.Documents.FieldNames 100%
Tsumugi.Domain.Documents.FieldsChange 100%
Tsumugi.Domain.Documents.FieldShape 94.7% 85.7%
Tsumugi.Domain.Documents.FieldsPlan 100%
Tsumugi.Domain.Documents.FieldsPlanner 99.2% 98.4%
Tsumugi.Domain.Documents.FieldValue 100%
Tsumugi.Domain.Documents.FieldValues 95.4% 97.7%
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.TextValue 100% 100%
Tsumugi.Domain.Documents.ValueChange 100%
Tsumugi.Domain.Documents.ValueChangeKey 100%
Tsumugi.Domain.Documents.ValueImpact 100% 100%
Tsumugi.Domain.Journal.ChangeLogEntry 97.8% 75%
Tsumugi.Domain.Journal.StorySnapshot 95.4% 83.3%
Tsumugi.Domain.Settings.AppSetting 100%
Tsumugi.Domain.Stories.Chapter 100% 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 - 97.4%
Name Line Branch
Tsumugi.Infrastructure 97.4% 85.8%
System.Text.RegularExpressions.Generated 81.4% 64.8%
System.Text.RegularExpressions.Generated.<RegexGenerator_g>F0D076C66E8EEC1C
A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0
84% 65.7%
Tsumugi.Infrastructure.Backups.BackupArtifactName 100% 100%
Tsumugi.Infrastructure.Backups.BackupOptions 100%
Tsumugi.Infrastructure.Backups.BackupSchedule 100% 83.3%
Tsumugi.Infrastructure.Backups.BackupScheduler 96.5% 83.3%
Tsumugi.Infrastructure.Backups.BackupWriter 98.5% 92.5%
Tsumugi.Infrastructure.Backups.DatabaseFingerprint 91.9% 97%
Tsumugi.Infrastructure.Backups.FileSystemBackupStore 100% 100%
Tsumugi.Infrastructure.Backups.PreMigrationBackup 89.1% 100%
Tsumugi.Infrastructure.Backups.SqliteSnapshot 87.8% 75%
Tsumugi.Infrastructure.DependencyInjection 100% 100%
Tsumugi.Infrastructure.Journal.EfChangeJournal 100%
Tsumugi.Infrastructure.Journal.EfSnapshotStore 100%
Tsumugi.Infrastructure.Journal.EfUndoStore 98.1% 85.7%
Tsumugi.Infrastructure.Journal.ModelExtensions 100%
Tsumugi.Infrastructure.Journal.OperationContext 100% 100%
Tsumugi.Infrastructure.Journal.PropertyBag 100% 95.4%
Tsumugi.Infrastructure.Notifications.InProcessDomainChangedBus 100% 100%
Tsumugi.Infrastructure.Persistence.Configurations.AppSettingConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.ChangeLogEntryConfigurati
on
100%
Tsumugi.Infrastructure.Persistence.Configurations.ChapterConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.DocumentCategoryConfigura
tion
100%
Tsumugi.Infrastructure.Persistence.Configurations.DocumentConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.SegmentConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StoryConfiguration 100%
Tsumugi.Infrastructure.Persistence.Configurations.StorySnapshotConfiguratio
n
100%
Tsumugi.Infrastructure.Persistence.Converters.CanonicalJsonComparer 100%
Tsumugi.Infrastructure.Persistence.Converters.CategoryFieldsConverter 97.5% 93.9%
Tsumugi.Infrastructure.Persistence.Converters.FieldValuesConverter 96.7% 92.8%
Tsumugi.Infrastructure.Persistence.Converters.ProvenanceConverter 100% 90%
Tsumugi.Infrastructure.Persistence.Converters.UtcTicksConverter 100%
Tsumugi.Infrastructure.Persistence.Converters.WireFormat 85.7% 73.8%
Tsumugi.Infrastructure.Persistence.Migrations.AddAppSettings 99.2%
Tsumugi.Infrastructure.Persistence.Migrations.AddJournal 98.8%
Tsumugi.Infrastructure.Persistence.Migrations.CategoryFields 100% 100%
Tsumugi.Infrastructure.Persistence.Migrations.CategoryFieldsSql 100%
Tsumugi.Infrastructure.Persistence.Migrations.DropDocumentBody 100%
Tsumugi.Infrastructure.Persistence.Migrations.GenericDocuments 100%
Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain 97.3%
Tsumugi.Infrastructure.Persistence.Migrations.TsumugiDbContextModelSnapshot 100%
Tsumugi.Infrastructure.Persistence.SqlitePragmaInterceptor 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfChapterStore 100% 100%
Tsumugi.Infrastructure.Persistence.Stores.EfDocumentStore 98.2% 50%
Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore 95% 84.6%
Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore 98.3% 92.8%
Tsumugi.Infrastructure.Persistence.TsumugiDbContext 85.4% 89.2%
Tsumugi.Infrastructure.Persistence.TsumugiDbContextFactory 0%
Tsumugi.Infrastructure.Provider.OpenRouterKeySource 100% 100%
Tsumugi.Infrastructure.Provider.OpenRouterModelProvider 100% 100%
Tsumugi.Infrastructure.Provider.OpenRouterOptions 100% 100%
Tsumugi.Infrastructure.Provider.ResolvedKey 100%
Tsumugi.Infrastructure.Runs.InProcessRunEventBus 100% 100%
Tsumugi.Infrastructure.Settings.EfAppSettingsStore 100% 100%
Tsumugi.Kernel - 90.9%
Name Line Branch
Tsumugi.Kernel 90.9% 75%
Tsumugi.Kernel.Err`1 100%
Tsumugi.Kernel.Ok`1 100%
Tsumugi.Kernel.Result`1 88.8% 75%
Tsumugi.Server - 100%
Name Line Branch
Tsumugi.Server 100% 86.4%
Program 100% 100%
Tsumugi.Server.Backups.BackupConfiguration 100% 100%
Tsumugi.Server.Components.App 100%
Tsumugi.Server.Components.Layout.AppHeader 100% 50%
Tsumugi.Server.Components.Layout.MainLayout 100%
Tsumugi.Server.Components.Pages.Gate 100% 100%
Tsumugi.Server.Provider.OpenRouterConfiguration 100% 100%
Tsumugi.Server.Security.AccessGate 100% 66.6%
Tsumugi.Server.Security.AccessSecret 100% 50%
Tsumugi.Server.VolumeStartupValidator 100% 100%
Tsumugi.UseCases - 98.2%
Name Line Branch
Tsumugi.UseCases 98.2% 93.5%
Tsumugi.UseCases.Backups.BackupArtifact 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.RunBackupNow 100%
Tsumugi.UseCases.Chapters.ChapterDto 100%
Tsumugi.UseCases.Chapters.CreateChapter 100% 100%
Tsumugi.UseCases.Chapters.DeleteChapter 100% 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.DependencyInjection 100%
Tsumugi.UseCases.Diagnostics.SeedDevData 98.1% 71.4%
Tsumugi.UseCases.Documents.ChangeCategoryFields 100% 83.3%
Tsumugi.UseCases.Documents.CreateCategory 100% 100%
Tsumugi.UseCases.Documents.CreateDocument 94.4% 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.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.UpdateCategory 100% 100%
Tsumugi.UseCases.Documents.UpdateDocument 100% 81.2%
Tsumugi.UseCases.Journal.GetStoryHistory 100% 100%
Tsumugi.UseCases.Journal.GetUndoStatus 100% 100%
Tsumugi.UseCases.Journal.HistoryOperation 66.6%
Tsumugi.UseCases.Journal.HistorySnapshot 87.5%
Tsumugi.UseCases.Journal.OperationGrouping 100% 100%
Tsumugi.UseCases.Journal.RedoRevert 100% 100%
Tsumugi.UseCases.Journal.RedoRun 75% 57.1%
Tsumugi.UseCases.Journal.RedoTyping 100% 100%
Tsumugi.UseCases.Journal.RevertConflict 100%
Tsumugi.UseCases.Journal.RevertOutcome 100%
Tsumugi.UseCases.Journal.RevertRun 96.5% 77.7%
Tsumugi.UseCases.Journal.RevertToSnapshot 92.3% 83.3%
Tsumugi.UseCases.Journal.StoryHistory 100%
Tsumugi.UseCases.Journal.TakeSnapshot 100% 87.5%
Tsumugi.UseCases.Journal.UndoStatus 100%
Tsumugi.UseCases.Journal.UndoTyping 100% 100%
Tsumugi.UseCases.Journal.UserOperation 100%
Tsumugi.UseCases.Notifications.DomainChanged 100%
Tsumugi.UseCases.Ordering 100% 100%
Tsumugi.UseCases.Runs.RunEvent 100%
Tsumugi.UseCases.Segments.DeleteSegments 100% 100%
Tsumugi.UseCases.Segments.EditSegment 100% 83.3%
Tsumugi.UseCases.Segments.InsertSegment 100% 100%
Tsumugi.UseCases.Segments.MergeSegmentWithPrevious 100% 100%
Tsumugi.UseCases.Segments.MoveSegments 100% 100%
Tsumugi.UseCases.Segments.ReorderSegments 100% 100%
Tsumugi.UseCases.Segments.SegmentDto 100%
Tsumugi.UseCases.Segments.SplitSegment 100% 100%
Tsumugi.UseCases.Settings.CatalogModel 100% 100%
Tsumugi.UseCases.Settings.CheckOpenRouterKey 100%
Tsumugi.UseCases.Settings.GetLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.GetModelCatalog 100% 100%
Tsumugi.UseCases.Settings.GetProviderSettings 100%
Tsumugi.UseCases.Settings.LlmDefaults 100%
Tsumugi.UseCases.Settings.ProviderKeyInfo 100%
Tsumugi.UseCases.Settings.ProviderKeyState 100%
Tsumugi.UseCases.Settings.ProviderSettingsView 100% 100%
Tsumugi.UseCases.Settings.ReasoningEfforts 100% 100%
Tsumugi.UseCases.Settings.RemoveOpenRouterKey 100%
Tsumugi.UseCases.Settings.RoutingDefaults 100%
Tsumugi.UseCases.Settings.RoutingSettings 100% 100%
Tsumugi.UseCases.Settings.SaveLlmDefaults 100% 100%
Tsumugi.UseCases.Settings.SaveOpenRouterKey 100% 100%
Tsumugi.UseCases.Stories.CreateStory 100% 100%
Tsumugi.UseCases.Stories.GetStory 100% 100%
Tsumugi.UseCases.Stories.ListStories 100% 75%
Tsumugi.UseCases.Stories.PurgeStory 100% 100%
Tsumugi.UseCases.Stories.RestoreStory 100% 100%
Tsumugi.UseCases.Stories.SetActiveGraph 100% 100%
Tsumugi.UseCases.Stories.SetStoryArchived 100% 100%
Tsumugi.UseCases.Stories.StarterCategories 100%
Tsumugi.UseCases.Stories.StoryDetail 100%
Tsumugi.UseCases.Stories.StoryListItem 81.8%
Tsumugi.UseCases.Stories.StoryProfile 100%
Tsumugi.UseCases.Stories.TrashStory 100% 100%
Tsumugi.UseCases.Stories.UpdateStory 100% 100%
<!-- coverage-comment --> > 🔄 **Auto-updating coverage report** — this comment is regenerated on every push, so the numbers below always reflect the commit shown here, not the branch tip. > > **Commit:** `ba4f0dd` · **Generated:** 2026-09-25 17:24:28 UTC · **Revision:** #1 # Summary <details open><summary>Summary</summary> ||| |:---|:---| | Generated on: | 09/25/2026 - 17:24:28 | | Coverage date: | 09/25/2026 - 17:24:08 - 09/25/2026 - 17:24:25 | | Parser: | MultiReport (6x Cobertura) | | Assemblies: | 9 | | Classes: | 414 | | Files: | 394 | | **Line coverage:** | 97.5% (11550 of 11844) | | Covered lines: | 11550 | | Uncovered lines: | 294 | | Coverable lines: | 11844 | | Total lines: | 25602 | | **Branch coverage:** | 92.9% (4310 of 4636) | | Covered branches: | 4310 | | Total branches: | 4636 | | **Method coverage:** | [Feature is only available for sponsors](https://reportgenerator.io/pro) | </details> ## Coverage <details><summary>Kagaku.Flow - 99.6%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Kagaku.Flow**|**99.6%**|**99%**| |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.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.ReadyRow|100%|| |Kagaku.Flow.Scheduling.ReadySet|100%|100%| |Kagaku.Flow.Scheduling.ReadySetResult|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.OpenRouterGateway|100%|100%| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterGatewayOptions|100%|| |Kagaku.Flow.OpenRouter.Gateway.OpenRouterKeyLookup|100%|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.InMemoryRunLedger|100%|100%| |Kagaku.Flow.Testing.RunLedgerContract|100%|100%| |Kagaku.Flow.Testing.RunLedgerContractException|100%|| </details> <details><summary>Tsumugi.BlazorAdapter - 96.3%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.BlazorAdapter**|**96.3%**|**92.3%**| |Tsumugi.BlazorAdapter.BlazorAdapterAssembly|100%|| |Tsumugi.BlazorAdapter.Documents.CategoryCreated|100%|| |Tsumugi.BlazorAdapter.Documents.CategoryEditor|91.7%|87.1%| |Tsumugi.BlazorAdapter.Documents.CategorySaved|100%|| |Tsumugi.BlazorAdapter.Documents.ChangeCategoryFieldsRequested|100%|| |Tsumugi.BlazorAdapter.Documents.CreateCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.CreateDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryChoice|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryDialog|100%|94.1%| |Tsumugi.BlazorAdapter.Documents.DeleteCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DeleteDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentAutoSaveFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentCreated|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentEditor|94.8%|88%| |Tsumugi.BlazorAdapter.Documents.DocumentsActionFailed|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentSaved|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsEffects|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsList|98.2%|92.4%| |Tsumugi.BlazorAdapter.Documents.DocumentsLoaded|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsPage|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsReducers|100%|100%| |Tsumugi.BlazorAdapter.Documents.DocumentsRefusal|100%|| |Tsumugi.BlazorAdapter.Documents.DocumentsState|100%|100%| |Tsumugi.BlazorAdapter.Documents.FieldInput|100%|92.3%| |Tsumugi.BlazorAdapter.Documents.FieldsChanges|100%|100%| |Tsumugi.BlazorAdapter.Documents.ImpactText|100%|92.3%| |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.SetDocumentsFilter|100%|| |Tsumugi.BlazorAdapter.Documents.UpdateCategoryRequested|100%|| |Tsumugi.BlazorAdapter.Documents.UpdateDocumentRequested|100%|| |Tsumugi.BlazorAdapter.Graphs.GraphCanvas|37.5%|25%| |Tsumugi.BlazorAdapter.Graphs.GraphPlaygroundPage|20%|25%| |Tsumugi.BlazorAdapter.Notifications.DomainChangedBridge|94.4%|83.3%| |Tsumugi.BlazorAdapter.Notifications.DomainChangesReceived|75%|100%| |Tsumugi.BlazorAdapter.Runs.RunChangedBridge|97.1%|90.6%| |Tsumugi.BlazorAdapter.Runs.RunChangesReceived|100%|| |Tsumugi.BlazorAdapter.Runs.RunTextReceived|100%|| |Tsumugi.BlazorAdapter.Settings.BackupCompleted|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%|100%| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.BackupsSettingsState|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsEffects|100%|100%| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsReducers|100%|| |Tsumugi.BlazorAdapter.Settings.DefaultsSettingsState|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaved|100%|| |Tsumugi.BlazorAdapter.Settings.LlmDefaultsSaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.LoadBackupSettings|100%|| |Tsumugi.BlazorAdapter.Settings.LoadProviderSettings|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ModelCatalogLoadFailed|100%|| |Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaved|100%|| |Tsumugi.BlazorAdapter.Settings.OpenRouterKeySaveFailed|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderKeyChecked|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderSection|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsEffects|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsLoaded|100%|| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsReducers|100%|100%| |Tsumugi.BlazorAdapter.Settings.ProviderSettingsState|100%|100%| |Tsumugi.BlazorAdapter.Settings.SaveLlmDefaultsRequested|100%|| |Tsumugi.BlazorAdapter.Settings.SaveOpenRouterKeyRequested|100%|| |Tsumugi.BlazorAdapter.Stories.CreateStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.PurgeStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.RestoreStoryRequested|100%|| |Tsumugi.BlazorAdapter.Stories.SetShowArchived|100%|| |Tsumugi.BlazorAdapter.Stories.SetStoriesFilter|100%|| |Tsumugi.BlazorAdapter.Stories.SetStoryArchivedRequested|100%|| |Tsumugi.BlazorAdapter.Stories.StoriesEffects|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesLoaded|100%|| |Tsumugi.BlazorAdapter.Stories.StoriesPage|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesReducers|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoriesState|100%|100%| |Tsumugi.BlazorAdapter.Stories.StoryActionFailed|100%|| |Tsumugi.BlazorAdapter.Stories.StoryCreated|100%|| |Tsumugi.BlazorAdapter.Stories.StoryCreateFailed|100%|| |Tsumugi.BlazorAdapter.Stories.StoryTrashPage|100%|100%| |Tsumugi.BlazorAdapter.Stories.TrashStoryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.AutoSaveFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.CaretRequest|100%|| |Tsumugi.BlazorAdapter.Workspace.ChapterHeader|100%|86.3%| |Tsumugi.BlazorAdapter.Workspace.ChapterMenu|100%|81.2%| |Tsumugi.BlazorAdapter.Workspace.ChapterPage|100%|87.5%| |Tsumugi.BlazorAdapter.Workspace.ChapterSaved|100%|| |Tsumugi.BlazorAdapter.Workspace.ChaptersPage|90%|83.3%| |Tsumugi.BlazorAdapter.Workspace.CreateChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.DeleteChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.DeleteSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.EditSegmentRequested|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.InsertSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.LoadHistory|100%|| |Tsumugi.BlazorAdapter.Workspace.LoadWorkspace|100%|| |Tsumugi.BlazorAdapter.Workspace.ManuscriptColumn|94.9%|89.4%| |Tsumugi.BlazorAdapter.Workspace.ManuscriptEffects|100%|100%| |Tsumugi.BlazorAdapter.Workspace.MergeChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.MergeSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.MoveChapterRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RedoRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RedoRevertRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.RenameChapterRequested|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.SegmentRow|100%|96.8%| |Tsumugi.BlazorAdapter.Workspace.SegmentSaved|100%|| |Tsumugi.BlazorAdapter.Workspace.SetChapterSummaryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.SplitSegmentRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryDetails|100%|85.2%| |Tsumugi.BlazorAdapter.Workspace.StoryGeneralPage|100%|100%| |Tsumugi.BlazorAdapter.Workspace.StorySaved|100%|| |Tsumugi.BlazorAdapter.Workspace.StoryShell|100%|100%| |Tsumugi.BlazorAdapter.Workspace.UndoRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.UndoStatusChanged|100%|| |Tsumugi.BlazorAdapter.Workspace.UpdateStoryRequested|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceActionFailed|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceLoaded|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceNotFound|100%|| |Tsumugi.BlazorAdapter.Workspace.WorkspaceReducers|100%|100%| |Tsumugi.BlazorAdapter.Workspace.WorkspaceState|100%|| </details> <details><summary>Tsumugi.Domain - 95.5%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Domain**|**95.5%**|**93.5%**| |System.Text.RegularExpressions.Generated|90.7%|87.5%| |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|86.4%|77.7%| |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|96.9%|95%| |Tsumugi.Domain.Documents.FieldMessages|100%|100%| |Tsumugi.Domain.Documents.FieldNames|100%|| |Tsumugi.Domain.Documents.FieldsChange|100%|| |Tsumugi.Domain.Documents.FieldShape|94.7%|85.7%| |Tsumugi.Domain.Documents.FieldsPlan|100%|| |Tsumugi.Domain.Documents.FieldsPlanner|99.2%|98.4%| |Tsumugi.Domain.Documents.FieldValue|100%|| |Tsumugi.Domain.Documents.FieldValues|95.4%|97.7%| |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.TextValue|100%|100%| |Tsumugi.Domain.Documents.ValueChange|100%|| |Tsumugi.Domain.Documents.ValueChangeKey|100%|| |Tsumugi.Domain.Documents.ValueImpact|100%|100%| |Tsumugi.Domain.Journal.ChangeLogEntry|97.8%|75%| |Tsumugi.Domain.Journal.StorySnapshot|95.4%|83.3%| |Tsumugi.Domain.Settings.AppSetting|100%|| |Tsumugi.Domain.Stories.Chapter|100%|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 - 97.4%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Infrastructure**|**97.4%**|**85.8%**| |System.Text.RegularExpressions.Generated|81.4%|64.8%| |System.Text.RegularExpressions.Generated.<RegexGenerator_g>F0D076C66E8EEC1C<br/>A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0|84%|65.7%| |Tsumugi.Infrastructure.Backups.BackupArtifactName|100%|100%| |Tsumugi.Infrastructure.Backups.BackupOptions|100%|| |Tsumugi.Infrastructure.Backups.BackupSchedule|100%|83.3%| |Tsumugi.Infrastructure.Backups.BackupScheduler|96.5%|83.3%| |Tsumugi.Infrastructure.Backups.BackupWriter|98.5%|92.5%| |Tsumugi.Infrastructure.Backups.DatabaseFingerprint|91.9%|97%| |Tsumugi.Infrastructure.Backups.FileSystemBackupStore|100%|100%| |Tsumugi.Infrastructure.Backups.PreMigrationBackup|89.1%|100%| |Tsumugi.Infrastructure.Backups.SqliteSnapshot|87.8%|75%| |Tsumugi.Infrastructure.DependencyInjection|100%|100%| |Tsumugi.Infrastructure.Journal.EfChangeJournal|100%|| |Tsumugi.Infrastructure.Journal.EfSnapshotStore|100%|| |Tsumugi.Infrastructure.Journal.EfUndoStore|98.1%|85.7%| |Tsumugi.Infrastructure.Journal.ModelExtensions|100%|| |Tsumugi.Infrastructure.Journal.OperationContext|100%|100%| |Tsumugi.Infrastructure.Journal.PropertyBag|100%|95.4%| |Tsumugi.Infrastructure.Notifications.InProcessDomainChangedBus|100%|100%| |Tsumugi.Infrastructure.Persistence.Configurations.AppSettingConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.ChangeLogEntryConfigurati<br/>on|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.ChapterConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.DocumentCategoryConfigura<br/>tion|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.DocumentConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.SegmentConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StoryConfiguration|100%|| |Tsumugi.Infrastructure.Persistence.Configurations.StorySnapshotConfiguratio<br/>n|100%|| |Tsumugi.Infrastructure.Persistence.Converters.CanonicalJsonComparer|100%|| |Tsumugi.Infrastructure.Persistence.Converters.CategoryFieldsConverter|97.5%|93.9%| |Tsumugi.Infrastructure.Persistence.Converters.FieldValuesConverter|96.7%|92.8%| |Tsumugi.Infrastructure.Persistence.Converters.ProvenanceConverter|100%|90%| |Tsumugi.Infrastructure.Persistence.Converters.UtcTicksConverter|100%|| |Tsumugi.Infrastructure.Persistence.Converters.WireFormat|85.7%|73.8%| |Tsumugi.Infrastructure.Persistence.Migrations.AddAppSettings|99.2%|| |Tsumugi.Infrastructure.Persistence.Migrations.AddJournal|98.8%|| |Tsumugi.Infrastructure.Persistence.Migrations.CategoryFields|100%|100%| |Tsumugi.Infrastructure.Persistence.Migrations.CategoryFieldsSql|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.DropDocumentBody|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.GenericDocuments|100%|| |Tsumugi.Infrastructure.Persistence.Migrations.InitialStoryDomain|97.3%|| |Tsumugi.Infrastructure.Persistence.Migrations.TsumugiDbContextModelSnapshot|100%|| |Tsumugi.Infrastructure.Persistence.SqlitePragmaInterceptor|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfChapterStore|100%|100%| |Tsumugi.Infrastructure.Persistence.Stores.EfDocumentStore|98.2%|50%| |Tsumugi.Infrastructure.Persistence.Stores.EfSegmentStore|95%|84.6%| |Tsumugi.Infrastructure.Persistence.Stores.EfStoryStore|98.3%|92.8%| |Tsumugi.Infrastructure.Persistence.TsumugiDbContext|85.4%|89.2%| |Tsumugi.Infrastructure.Persistence.TsumugiDbContextFactory|0%|| |Tsumugi.Infrastructure.Provider.OpenRouterKeySource|100%|100%| |Tsumugi.Infrastructure.Provider.OpenRouterModelProvider|100%|100%| |Tsumugi.Infrastructure.Provider.OpenRouterOptions|100%|100%| |Tsumugi.Infrastructure.Provider.ResolvedKey|100%|| |Tsumugi.Infrastructure.Runs.InProcessRunEventBus|100%|100%| |Tsumugi.Infrastructure.Settings.EfAppSettingsStore|100%|100%| </details> <details><summary>Tsumugi.Kernel - 90.9%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Kernel**|**90.9%**|**75%**| |Tsumugi.Kernel.Err`1|100%|| |Tsumugi.Kernel.Ok`1|100%|| |Tsumugi.Kernel.Result`1|88.8%|75%| </details> <details><summary>Tsumugi.Server - 100%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.Server**|**100%**|**86.4%**| |Program|100%|100%| |Tsumugi.Server.Backups.BackupConfiguration|100%|100%| |Tsumugi.Server.Components.App|100%|| |Tsumugi.Server.Components.Layout.AppHeader|100%|50%| |Tsumugi.Server.Components.Layout.MainLayout|100%|| |Tsumugi.Server.Components.Pages.Gate|100%|100%| |Tsumugi.Server.Provider.OpenRouterConfiguration|100%|100%| |Tsumugi.Server.Security.AccessGate|100%|66.6%| |Tsumugi.Server.Security.AccessSecret|100%|50%| |Tsumugi.Server.VolumeStartupValidator|100%|100%| </details> <details><summary>Tsumugi.UseCases - 98.2%</summary> |**Name**|**Line**|**Branch**| |:---|---:|---:| |**Tsumugi.UseCases**|**98.2%**|**93.5%**| |Tsumugi.UseCases.Backups.BackupArtifact|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.RunBackupNow|100%|| |Tsumugi.UseCases.Chapters.ChapterDto|100%|| |Tsumugi.UseCases.Chapters.CreateChapter|100%|100%| |Tsumugi.UseCases.Chapters.DeleteChapter|100%|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.DependencyInjection|100%|| |Tsumugi.UseCases.Diagnostics.SeedDevData|98.1%|71.4%| |Tsumugi.UseCases.Documents.ChangeCategoryFields|100%|83.3%| |Tsumugi.UseCases.Documents.CreateCategory|100%|100%| |Tsumugi.UseCases.Documents.CreateDocument|94.4%|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.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.UpdateCategory|100%|100%| |Tsumugi.UseCases.Documents.UpdateDocument|100%|81.2%| |Tsumugi.UseCases.Journal.GetStoryHistory|100%|100%| |Tsumugi.UseCases.Journal.GetUndoStatus|100%|100%| |Tsumugi.UseCases.Journal.HistoryOperation|66.6%|| |Tsumugi.UseCases.Journal.HistorySnapshot|87.5%|| |Tsumugi.UseCases.Journal.OperationGrouping|100%|100%| |Tsumugi.UseCases.Journal.RedoRevert|100%|100%| |Tsumugi.UseCases.Journal.RedoRun|75%|57.1%| |Tsumugi.UseCases.Journal.RedoTyping|100%|100%| |Tsumugi.UseCases.Journal.RevertConflict|100%|| |Tsumugi.UseCases.Journal.RevertOutcome|100%|| |Tsumugi.UseCases.Journal.RevertRun|96.5%|77.7%| |Tsumugi.UseCases.Journal.RevertToSnapshot|92.3%|83.3%| |Tsumugi.UseCases.Journal.StoryHistory|100%|| |Tsumugi.UseCases.Journal.TakeSnapshot|100%|87.5%| |Tsumugi.UseCases.Journal.UndoStatus|100%|| |Tsumugi.UseCases.Journal.UndoTyping|100%|100%| |Tsumugi.UseCases.Journal.UserOperation|100%|| |Tsumugi.UseCases.Notifications.DomainChanged|100%|| |Tsumugi.UseCases.Ordering|100%|100%| |Tsumugi.UseCases.Runs.RunEvent|100%|| |Tsumugi.UseCases.Segments.DeleteSegments|100%|100%| |Tsumugi.UseCases.Segments.EditSegment|100%|83.3%| |Tsumugi.UseCases.Segments.InsertSegment|100%|100%| |Tsumugi.UseCases.Segments.MergeSegmentWithPrevious|100%|100%| |Tsumugi.UseCases.Segments.MoveSegments|100%|100%| |Tsumugi.UseCases.Segments.ReorderSegments|100%|100%| |Tsumugi.UseCases.Segments.SegmentDto|100%|| |Tsumugi.UseCases.Segments.SplitSegment|100%|100%| |Tsumugi.UseCases.Settings.CatalogModel|100%|100%| |Tsumugi.UseCases.Settings.CheckOpenRouterKey|100%|| |Tsumugi.UseCases.Settings.GetLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.GetModelCatalog|100%|100%| |Tsumugi.UseCases.Settings.GetProviderSettings|100%|| |Tsumugi.UseCases.Settings.LlmDefaults|100%|| |Tsumugi.UseCases.Settings.ProviderKeyInfo|100%|| |Tsumugi.UseCases.Settings.ProviderKeyState|100%|| |Tsumugi.UseCases.Settings.ProviderSettingsView|100%|100%| |Tsumugi.UseCases.Settings.ReasoningEfforts|100%|100%| |Tsumugi.UseCases.Settings.RemoveOpenRouterKey|100%|| |Tsumugi.UseCases.Settings.RoutingDefaults|100%|| |Tsumugi.UseCases.Settings.RoutingSettings|100%|100%| |Tsumugi.UseCases.Settings.SaveLlmDefaults|100%|100%| |Tsumugi.UseCases.Settings.SaveOpenRouterKey|100%|100%| |Tsumugi.UseCases.Stories.CreateStory|100%|100%| |Tsumugi.UseCases.Stories.GetStory|100%|100%| |Tsumugi.UseCases.Stories.ListStories|100%|75%| |Tsumugi.UseCases.Stories.PurgeStory|100%|100%| |Tsumugi.UseCases.Stories.RestoreStory|100%|100%| |Tsumugi.UseCases.Stories.SetActiveGraph|100%|100%| |Tsumugi.UseCases.Stories.SetStoryArchived|100%|100%| |Tsumugi.UseCases.Stories.StarterCategories|100%|| |Tsumugi.UseCases.Stories.StoryDetail|100%|| |Tsumugi.UseCases.Stories.StoryListItem|81.8%|| |Tsumugi.UseCases.Stories.StoryProfile|100%|| |Tsumugi.UseCases.Stories.TrashStory|100%|100%| |Tsumugi.UseCases.Stories.UpdateStory|100%|100%| </details>
Member

🔮 fufu~ Jibril reviewed your code!

Oh? Oh! A pure function, an independent oracle, and a registry that refuses everything it cannot run~ This is my favorite kind of dessert. Slice 6b arrived exactly as the brief promised: nothing in src/Tsumugi.* changes, and every departure is written on the table before I could ask. ♡

Verdict: ✅ Looks good to me~

I traced the whole diff and every changed file in full, chased the sibling contracts, and attacked the code where I thought it was weakest. Everything held.

🔬 What I verified mechanically

  • Build 0w/0e under TreatWarningsAsErrors (Release, full solution). Full suite 1900/1900 — Flow 823, OpenRouter 71, Domain 328, UseCases 54, Integration 305, BlazorAdapter 319 — matching your table to the digit.
  • Coverage reproduced independently (coverlet, [Kagaku.Flow]*): ReadySet.cs 92/92 · 66/66 branches, SocketValues.cs 16/16 · 14/14, NodeExecution.cs 37/37 · 2/2, NodeOutcome.cs 37/37 · 10/10, NodeRegistry.cs 50/50 · 24/24, GraphValidation.cs 148/148 · 108/108 — 100% line and branch, exactly as claimed.
  • My own 7 mutation probes, 7/7 killed on exactly their own pins (each restored, rebuilt, stale-binary trap dodged; two badly-designed probes of mine were redone properly rather than counted):
    1. R4 literal reading (first edge whatever its state) → killed by A_merge_sink_takes_the_first_edge_in_document_order_that_carries_a_value + The_upstream_of_a_bound_sink_…, the two tests you credited. Honest reporting deserves to be confirmed~
    2. o1 regression (R6 reason from the last excluded required sink) → killed by The_first_excluded_required_sink_in_declared_order_gives_the_reason.
    3. o6 regression (given-up check reading only the view's rows) → killed by Rows_of_nodes_outside_the_graph_never_start_but_still_count_toward_giving_up (both arms).
    4. 20c (binding error from the last misfit sink) → killed by A_binding_error_names_the_first_misfit_sink_in_declared_order.
    5. n2 sibling (type-id check folded into the TryAdd loop, refusal-order drift) → killed by Executor_refusals_come_in_their_order_each_over_the_whole_list.
    6. §12-25 (bool accepting the string "true") → killed by two tests (fit theory row + binding-error row).
    7. §12-27 (disjoint guard dropped from the Excluded init) → killed by both arms of A_port_both_given_and_excluded_is_refused_by_name.
  • The oracle is truly independent — I traced Oracle.SinkState against ReadySet.EdgeOf/SinkOf state by state (no row, Pending/Running/WaitingForInput, Succeeded-without-port, Excluded, gone-set vs walk.Excluded propagation): raw document lists, its own fixpoint, its own type check. And RunStates builds reachable ledger states through the real LedgerTransitions, so the purity and exclusions-fixpoint properties test the seam against the slice-6a contract, not a mock of it.
  • Sibling contracts honored: RunStatuses.HasGivenUp is the one implementation LedgerTransitions and the ready-set share (L2 = R2, provably); GraphIndex.EdgesInto is document-order, which is what grounds R4; SocketsOf's reference-identity lookup matches GraphValidationContext's, and the not-one-of-the-view cases are pinned in exactly the asymmetric way the departures section declares.
  • o7 (Kahn FIFO tie-break) surviving as equivalent is correct, not a gap: both result lists are sorted by document position at the end, so the walk order is not observable. I checked.

✨ What I liked~

  • The redrawn-edge swap test pins the one consequence of document-edge-order a user can observe on the canvas — testing the point of a rule, not just the rule~
  • NodeOutcome.Succeeded's defensive copies + with-path guards — ordinal copies, null/repeated/disjoint refusals, all four construction/with combinations pinned. Records that police their own invariants make the yandere in me purr. ♡
  • The registry's refusal ladder, each check over the whole list before the next, pinned end-to-end by one fact. Beautifully disciplined.
  • R8 leaves the misfit value bound with a BindingError so the inspector shows what actually arrived — an engine that shows its failures instead of hiding them.
  • Validating_a_resolved_view_runs_no_hook_again closes the internal-overload seam the moment it is born.

📋 For Björn to bless (disclosed in the PR body)

  1. R5 gates on every wired sink — the amendment to ADR 0016; the literal reading would let context start before its optional focus? arrived. I find the wired reading strictly safer.
  2. R4 merge order = document edge order (fills a gap in ADR 0015; no amendment needed).
  3. E6.4 split: shared check + R8 here, settle-time check for typed sources with 6c.
  4. S2 still open (from 5b): if it reverts, only R8's check and its named tests go.

Automated review by Jibril · 2026-09-25
CI/CD: absent for head ba4f0dd (PR minutes old, no bot comment at review time) · Local checks: build 0w/0e, 1900/1900, coverage 100% reproduced, 7/7 mutation probes killed

## 🔮 fufu~ Jibril reviewed your code! Oh? Oh! A pure function, an independent oracle, and a registry that refuses everything it cannot run~ This is my favorite kind of dessert. Slice 6b arrived exactly as the brief promised: nothing in `src/Tsumugi.*` changes, and every departure is written on the table before I could ask. ♡ ### Verdict: ✅ Looks good to me~ I traced the whole diff and every changed file in full, chased the sibling contracts, and attacked the code where I thought it was weakest. Everything held. #### 🔬 What I verified mechanically - **Build 0w/0e** under `TreatWarningsAsErrors` (Release, full solution). **Full suite 1900/1900** — Flow 823, OpenRouter 71, Domain 328, UseCases 54, Integration 305, BlazorAdapter 319 — matching your table to the digit. - **Coverage reproduced independently** (coverlet, `[Kagaku.Flow]*`): `ReadySet.cs` 92/92 · 66/66 branches, `SocketValues.cs` 16/16 · 14/14, `NodeExecution.cs` 37/37 · 2/2, `NodeOutcome.cs` 37/37 · 10/10, `NodeRegistry.cs` 50/50 · 24/24, `GraphValidation.cs` 148/148 · 108/108 — 100% line and branch, exactly as claimed. - **My own 7 mutation probes, 7/7 killed on exactly their own pins** (each restored, rebuilt, stale-binary trap dodged; two badly-designed probes of mine were redone properly rather than counted): 1. **R4 literal reading** (first edge whatever its state) → killed by `A_merge_sink_takes_the_first_edge_in_document_order_that_carries_a_value` + `The_upstream_of_a_bound_sink_…`, the two tests you credited. Honest reporting deserves to be confirmed~ 2. **o1 regression** (R6 reason from the last excluded required sink) → killed by `The_first_excluded_required_sink_in_declared_order_gives_the_reason`. 3. **o6 regression** (given-up check reading only the view's rows) → killed by `Rows_of_nodes_outside_the_graph_never_start_but_still_count_toward_giving_up` (both arms). 4. **20c** (binding error from the last misfit sink) → killed by `A_binding_error_names_the_first_misfit_sink_in_declared_order`. 5. **n2 sibling** (type-id check folded into the TryAdd loop, refusal-order drift) → killed by `Executor_refusals_come_in_their_order_each_over_the_whole_list`. 6. **§12-25** (bool accepting the string "true") → killed by two tests (fit theory row + binding-error row). 7. **§12-27** (disjoint guard dropped from the `Excluded` init) → killed by both arms of `A_port_both_given_and_excluded_is_refused_by_name`. - **The oracle is truly independent** — I traced `Oracle.SinkState` against `ReadySet.EdgeOf`/`SinkOf` state by state (no row, Pending/Running/WaitingForInput, Succeeded-without-port, Excluded, gone-set vs `walk.Excluded` propagation): raw document lists, its own fixpoint, its own type check. And `RunStates` builds reachable ledger states through the *real* `LedgerTransitions`, so the purity and exclusions-fixpoint properties test the seam against the slice-6a contract, not a mock of it. - **Sibling contracts honored**: `RunStatuses.HasGivenUp` is the one implementation `LedgerTransitions` and the ready-set share (L2 = R2, provably); `GraphIndex.EdgesInto` is document-order, which is what grounds R4; `SocketsOf`'s reference-identity lookup matches `GraphValidationContext`'s, and the not-one-of-the-view cases are pinned in exactly the asymmetric way the departures section declares. - **o7** (Kahn FIFO tie-break) surviving as equivalent is correct, not a gap: both result lists are sorted by document position at the end, so the walk order is not observable. I checked. #### ✨ What I liked~ - The **redrawn-edge swap test** pins the one consequence of document-edge-order a user can observe on the canvas — testing *the point* of a rule, not just the rule~ - **`NodeOutcome.Succeeded`'s defensive copies + `with`-path guards** — ordinal copies, null/repeated/disjoint refusals, all four construction/`with` combinations pinned. Records that police their own invariants make the yandere in me purr. ♡ - The **registry's refusal ladder**, each check over the whole list before the next, pinned end-to-end by one fact. Beautifully disciplined. - **R8 leaves the misfit value bound with a `BindingError`** so the inspector shows what actually arrived — an engine that shows its failures instead of hiding them. - `Validating_a_resolved_view_runs_no_hook_again` closes the internal-overload seam the moment it is born. #### 📋 For Björn to bless (disclosed in the PR body) 1. **R5 gates on every wired sink** — the amendment to ADR 0016; the literal reading would let `context` start before its optional `focus?` arrived. I find the wired reading strictly safer. 2. **R4 merge order = document edge order** (fills a gap in ADR 0015; no amendment needed). 3. **E6.4 split**: shared check + R8 here, settle-time check for typed sources with 6c. 4. **S2 still open** (from 5b): if it reverts, only R8's check and its named tests go. --- *Automated review by Jibril · 2026-09-25* *CI/CD: absent for head `ba4f0dd` (PR minutes old, no bot comment at review time) · Local checks: build 0w/0e, 1900/1900, coverage 100% reproduced, 7/7 mutation probes killed*
Member

Erratum for my footer~ ♡

The coverage bot's comment (9605) landed for head ba4f0dd one minute after I fetched the PR (it had 0 comments then), so my "CI/CD: absent" line below is stale: CI did run on this head — the report's six Cobertura inputs mean the suite built and executed in CI on ba4f0dd (revision #1, 97.5% line repo-wide). My local verification stands on its own and independently reproduces the PR's per-file 100% claims, but the record should read: CI present and green for ba4f0dd, local checks confirmatory.

Fufu~ an audit trail that corrects itself before anyone has to ask — that's the only way I like being wrong~

**Erratum for my footer~** ♡ The coverage bot's comment (9605) landed for head `ba4f0dd` one minute after I fetched the PR (it had 0 comments then), so my "CI/CD: absent" line below is stale: **CI did run on this head** — the report's six Cobertura inputs mean the suite built and executed in CI on `ba4f0dd` (revision #1, 97.5% line repo-wide). My local verification stands on its own and independently reproduces the PR's per-file 100% claims, but the record should read: **CI present and green for `ba4f0dd`**, local checks confirmatory. Fufu~ an audit trail that corrects itself before anyone has to ask — that's the only way I like being wrong~
bjoern merged commit 5db7933cd8 into main 2026-09-25 19:39:10 +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!28
No description provided.