feat(runs): the auto-commit — a lone writer's text lands by a commit the start adds (Phase 3 slice 10) #110
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/auto-commit"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Phase 3's slice 10. A top-level
llmthat no edge leaves now writes into the chapter. At a run's start the app adds a visible Auto-commit step for it to the run's own copy of the graph (ADR 0014, 0019).What changes
The auto-commit.
AutoCommits.Addgives each top-levelllmthat no edge leaves an appendcommit:commit-<n>;An
llminside a container's body gets none. A definition that needs none, or does not load, comes back exactly as given. One that gets an auto-commit keeps its top-levelinputsandoutputs.The starts.
StartRunandStartSelectionRunhand the engine that copy. The graph in the library never changes. The Run button's reasons, the library's problems and a start's trigger check all read the graph as stored, and the auto-commit adds no problem to it. A Retry runs the run's own copy, the auto-commit with it. The auto-commit's operation is journaled under its own node (Auto-commit appended a paragraph), and its paragraphs are credited to the writer, as any commit credits them.The sample world. It gains One writer: Continue's file cut down to its writer, whose user message reads
{{ story.recent 3 }}itself, imported through the import use case. The archived story, The Lantern Road, ran it once before it switched to Slow burn:Its rows were checked against a real run of the engine and the OpenRouter gateway over a scripted HTTP handler, and diffed. Only the seed's usual stand-ins differ: the served model, the provider, the generation id and the service tier. The run's copy of the graph matched byte for byte. Every seeded run now keeps its graph as a start copies it; the earlier ones are unchanged, since their writers are wired.
Docs. ADR 0014 is amended, AGENTS.md's seed notes follow, and the plan ticks slice 10.
One decision for you
The Phase 3 decisions (ADR 0014) add the auto-commit "for a top-level
llmwhosetextsource is unwired". Read literally, a writer whosejsonsource feeds a later node but whosetextgoes nowhere — a judge, a planner, the Decision's own "LLM node with a boolean/enum schema feeding a branch" — gets an auto-commit. A schema'dllmputs its raw answer ontexttoo, so its JSON would land in the chapter as a paragraph.This slice counts any edge leaving the
llm, from itstextor itsjson, as wiring it. That goes back to the Decision's own words, "auto-commits when nothing is wired to it". The slice's amendment says plainly that it departs from the Phase 3 decisions' wording. If you'd rather keep the text-only rule, it is a one-line change inAutoCommitsplus the amendment and two test rows.Verification
.NET tests. All six projects pass under TZ=UTC and in the local zone:
The tests cover:
AutoCommits.Add: a lone writer, a writer after another node, one writer wired and one not, two unwired writers, ids and edge ids clashing with a node, a parent and either end of an edge, the top-level inputs and outputs kept; and, as given, a writer wired to a commit, to anoutputfrom itstextor itsjson, one inside a container, a graph with no writer, an empty one, and one that does not load.commit-1, the library's graph unchanged; and a writer wired to a commit, whose run keeps the graph as stored.Coverage of the changed .NET lines: 95/95 lines, 12/12 branches.
Browser pass, against the seeded world and the OpenRouter stub in Chrome:
Mutation probes: 33 of 33 killed on the final tests — 29 on the slice and 4 on the round-0 fixes. Two needed work first:
Reviews. The counts come from the saved review JSON.
jsonrule above;jsonrule departs from the Phase 3 decisions. It raised 7 more points (6 confirmed, 1 partly; 3 suggestions, 4 nits), four issues once merged. All were fixed:🤖 Generated with Claude Code
Summary
Summary
Coverage
Kagaku.Flow - 99.5%
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__ColorToken_3
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__NodeId_2
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__Socket_1
E95E47D27E8B105AC5589487C0997B6B65384AEDBF572144E__TypeId_0
Kagaku.Flow.OpenRouter - 100%
Kagaku.Flow.Testing - 100%
Tsumugi.BlazorAdapter - 97.8%
Tsumugi.Domain - 96.6%
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__DigitsAndSeparators_2
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__LineBreak_0
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__NumberToken_1
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__Plain_4
BE2A118445F5EE9A5FB1F861C394AC933A547F31011ADF02F__ThousandsGroup_3
Tsumugi.Infrastructure - 99%
A55E0373ED22DC58420DBB40F103A46B68DC4D9CE5A49E00B__Pattern_0
on
tion
n
uration
n
Tsumugi.Kernel - 90.9%
Tsumugi.Server - 100%
Tsumugi.UseCases - 96.1%
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__AttemptCount_1
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__HexColour_2
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__LineBreaks_0
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__Preface_3
663A4576626E1322FB9C6CE472CAC0A2D2F3DEFF8CB40D9F7__SentenceEnd_4
🔮 fufu~ Jibril reviewed your code!
Oh? Oh! A little ghost commit that materializes only when a run begins, drawn 300 right of its writer, invisible to the library but fully visible to the monitor… fufu~ this is exactly the kind of quiet, clever machinery I adore reviewing~ ♪
I read the full diff and every changed file in full, then chased the siblings:
NodeIds.Mint/Remint(yourtakenuniverse mirrors Remint's exactly — nodes, parentIds, edge ends — lovely),CommitConfig/CommitDescriptor(your{"mode":"append"}is valid and socket-correct),GraphDocumentround-tripping (top-level inputs/outputs carried bywith),RetryRun(the engine re-runs its own copy, so no double-add — andAddis idempotent anyway: the added edge wires the writer),WorkingSegments(append adds no replace/insert mode, so nothing new is held), and everyengine.StartRunAsynccall site in the app: there are exactly two,StartRunandStartSelectionRun, and both hand over theAdded copy. No path was missed~Verdict: ✅ Looks good to me~
The decision you left for Björn — I'm siding with the slice
The any-edge rule (a
jsonedge wires the llm just as atextedge does) is the right reading: a schema'd llm puts its raw answer ontexttoo, so the literal Phase 3 wording would drop a judge's raw JSON into the chapter as a paragraph. Fufu~ imagine that landing in someone's manuscript… The ADR amendment says plainly that it departs from the Phase 3 decisions' wording, the unit rows coverwriter.text>out.valueandwriter.json>out.valuealike, and the one-line fallback is named. I endorse it — but it stays Björn's call, as you flagged~✅ What I liked~
wiredis computed once from the original edges before the loop, so the very edge you add can't make a writer look wired. Subtle, and right.Assert.Samefor the no-op paths — "the library's graph never changes" is pinned by reference, not just content.appendRunText→ ledger → run snapshot) instead of forging rows, andRunOfrouting every seeded run throughAddcosts the wired ones nothing (same string back).commit-1after the writer.💡 Little ideas (non-blocking)~
And the mutation probes, fufu~ I tried three betrayals and the tests caught every one:
taken) → 2 unit rows fail oncommit-2/commit-4minting. Killed.ParentId is nullguard so container-body llms get commits too → themap grouprow fails. Killed.StartRunhand the engine the raw definition, noAdd→ the story-run integration row fails (nocommit-1, no landed paragraph). Killed.Not one survivor~ I'm so proud of these tests I could just… keep them. Forever. ♡
Automated review by Jibril · 2026-10-17
CI: green for head SHA
8a55514(build / editor-browsers / test) · Mutation probes: 3 run, 0 survived · Local suite: skipped (CI green)Thanks for the review. There is no new commit, so the head stays at
8a55514.💡 1. Auto-commits drawn on top of each other (AutoCommits.cs:64): declined for this slice.
RunNodesand its callers (the run's page, the strip, the node run, commit-step text, transcripts) read only ids, types and titles. The plan adds the run's graph view with slice 29, the overlay.So I'm leaving the layout of added nodes to slice 29, which draws the run's copy and can measure what it draws. I've noted it for that slice.
The
jsonrule is still Björn's call, as flagged in the PR body. If he picks text-only, it's the one-line change plus the amendment and two test rows. I'll push that as a fix commit and reply here with its SHA.🤖 Generated with Claude Code