Say what the app is now, everywhere it is published

The README, the project page and the engineering guide all describe a linear
story. The tree shipped two days ago. Every published surface is a phase
behind, and the guide is not merely behind — it is wrong in a way that costs a
reader time.

Its 2.2 was "Two coordinate systems, and the bug class they create", and it
explained the codebase through position_of_index, note_action_removed and
settled_story_actions. All three were deleted in SP3. 2.3 explained retry
through Action.variants and state_before. Somebody reading either would go
looking for machinery that is not there, which is worse than a gap.

So 2.2 is now "The story is a tree", written at the depth 1.2 and 1.3 are
written at: the seven bugs that turned out to be one bug, the lineage clause
and the two properties that make fork count free, why takes group by parent_id
rather than by coordinate, cursors becoming anchors, and a closing list of what
the design is honest about. 2.3 is rewritten around state_after and takes, and
1.1 and 1.5 follow, because the pipeline no longer snapshots before the call
and the memory bank no longer holds an action back.

The numbers were simply old: 151 tests where there are 440, 37 migrations where
there are 64, twelve phases where there are fourteen. They appear in four
places across the README, the project page's stat tiles and the guide's results
table. The measured branch cost — 103 B, and 1.007x the page load of the same
story flat — is added beside the egress and turn-cost figures it belongs with,
since it is the number that answers "what does branching cost me".

Three screenshots, on a new tools/shots_fixture.py: the Bandit Camp demo driven
through eight written turns with written deltas, three discarded takes forked
onto branches of their own, one off a branch so the map has to nest. Same
reason tree_fixture.py is committed — the shots have to be reproducible and the
frontend still has no test runner. play-world-state.jpg is reshot because it
predates the entire tree UI; the map and the branches panel are new.

Note for next time: docs/guide.html is hand-written, not generated from the
Markdown, so every guide edit is two edits in two vocabularies. Both files were
checked for tag balance and both pages rendered locally before this landed.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01DfMCsN1KBLsTqMkj5hSgrY
This commit is contained in:
parththakkar106
2026-08-20 04:19:53 +05:30
co-authored by Claude Opus 5
parent c8e081e9d6
commit 40d2555f84
10 changed files with 995 additions and 163 deletions
+21 -5
View File
@@ -138,15 +138,26 @@
<figure class="hero-shot">
<img src="images/play-world-state.jpg" alt="The play screen with the world-state rail open, showing HP, mana, an NPC's trust and a raised alarm flag">
<figcaption>The left rail is live world state. The model proposes what changed this turn; the engine decides
what sticks, and the chip under the narration reports the result.</figcaption>
what sticks, and the chip under the narration reports the result. The <code>&lsaquo; 2/2 &rsaquo;</code>
under a turn steps between the takes it has.</figcaption>
</figure>
</header>
<section>
<h2>What makes it more than a chat wrapper</h2>
<p class="lede">Three things a plain "talk to a model" app doesn't do.</p>
<p class="lede">Four things a plain "talk to a model" app doesn't do.</p>
<div class="grid">
<div class="card">
<h3>The story is a tree</h3>
<p>Any turn can hold more than one <em>take</em>. Stepping between them is free — the story below simply
empties, and the server is told nothing. Writing below a take that isn't the live one is what makes a
branch, and a branch stores no turns of its own: it records where it left its parent and borrows
everything above that. Twenty forks cost 1.007× the page load of the same story flat. Switch lines and
the world state, the script scoreboard and the cooldown clocks all come back to what that line left.</p>
<img src="images/branch-map.jpg" alt="The branch map: one horizontal lane per line of the story, each joined to its parent by an elbow at the moment it forked">
</div>
<div class="card">
<h3>The AI proposes, Python referees</h3>
<p>A scenario declares stats, flags, milestones and a named cast. Each turn the model appends the changes
@@ -192,7 +203,7 @@
→ onInput script modifier
→ assemble context: [narrator prompt] + [world state + stat guide] + [AI instructions]
+ [plot essentials] + [story summary] + [retrieved memories]
+ [triggered story cards] + [story history, token-budgeted]
+ [triggered story cards] + [history along this branch, token-budgeted]
+ [author's note] + [player action]
→ onModelContext script modifier
→ snapshot context (Insights)
@@ -219,8 +230,8 @@
<div class="stats">
<div class="stat"><div class="n">189×</div><div class="l">less database egress per adventure load</div></div>
<div class="stat"><div class="n">151</div><div class="l">backend tests, run by CI on every push</div></div>
<div class="stat"><div class="n">37</div><div class="l">schema migrations, applied in order on boot</div></div>
<div class="stat"><div class="n">440</div><div class="l">backend tests, run by CI on every push</div></div>
<div class="stat"><div class="n">64</div><div class="l">schema migrations, applied in order on boot</div></div>
<div class="stat"><div class="n">$0</div><div class="l">to run it locally against Ollama</div></div>
</div>
@@ -232,6 +243,11 @@
<li><strong>Turn cost, made flat.</strong> Assembling a turn walked the whole story, so it grew with story
length — 839 KB of reads by turn 200. History is now served as tails and slices from SQL: the same turn
costs 129 KB and stops growing at around turn 50.</li>
<li><strong>Branching that costs 103 bytes.</strong> A branch stores where it left its parent and borrows
every turn above that, so nothing is copied on a fork. A 40-turn story forked twenty times loads in
31,652 B against 31,433 B for the same story flat — 1.007×. Reads stay cheap because the ancestry is
windowed the way the history is: the number of SQL clauses is bounded by the context window, not by how
many times the story has forked.</li>
<li><strong>A shared demo key that can't be drained.</strong> The hosted demo funds a model for visitors, so
model selection is pinned server-side with a structural backstop that raises if any code path tries to
resolve a model outside the allowed set — plus a daily per-visitor turn cap.</li>