Skip to content

S132 — A story moves onto additive content - #590

Merged
The-Running-Dev merged 1 commit into
mainfrom
slice/S132-story-additive
Oct 9, 2026
Merged

The-Running-Dev merged 1 commit into
mainfrom
slice/S132-story-additive

Conversation

@The-Running-Dev

Copy link
Copy Markdown
Owner

What

The story-graph kind now declares adoptContent, implementing the rule in 16 §5.5 and 03 §8.1. A session moves onto a newer version of its campaign when that version only adds to what the player is playing:

  • The player keeps their place, visit history, achievements and variables.
  • Each variable the target adds is inserted at its declared initial value.

The session stays pinned with content_incompatible when the target would strand the player or drop something they carry.

Choice availability is judged by offeredChoices, which is now shared with availableActions. The adoption check therefore sees exactly what the scene shows.

Criteria

  • S132.1 — met: adopt.test.ts › S132.1:

    • the kind declares the member;
    • an additive target inserts patience and mood at their initial values and leaves every other field equal;
    • the input is not mutated;
    • an identical target adopts unchanged;
    • a carried value survives a changed initial.
  • S132.2 — met: adopt.test.ts › S132.2, one test per case:

    • the current node is missing;
    • the current node is now an ending, an auto node or a random node;
    • the current choice node has no available choice once the inserted variable applies;
    • a visitedCounts key has no target node;
    • an achievement is missing;
    • a variable's VarType changed;
    • a source-declared variable was dropped.

    A further test shows that a variable neither campaign declares passes through.

  • S132.3 — met: adopt.test.ts › S132.3. Four cases: a choice gated by showWhen or by requirements, on an inserted variable whose initial value is true or false. Adoption agrees with availableActions on the adopted state, and adopts exactly when the gate passes.

  • S132.4 — met:

    • adopt.test.ts › S132.4: the adopted state passes validateState on the target, and the unadopted state does not.
    • bulgaria-bureaucracy.adopt.test.ts: the real campaign adopts its own extension (one node plus one variable) partway through the arc. Two traceFixture runs of a log crossing the epoch are identical entry by entry, and the final state is formatVersion: 2 on 2.1.0. The state round-trips through deserialize.

Differs from design

Three interpretations are recorded in 90-decisions.md:

  • Type only, not value. Adoption compares a carried variable's VarType, not its value against the target's declaration. This is the rule as written. A narrowed enum can still fail a later copy; the entry flags it for revisiting.
  • Undeclared variables pass through. A variable neither campaign declares is carried over, as validateState tolerates it at load.
  • The real migrateState pins every extension that keeps it. The Bureaucracy campaign's migrateState migrates from 1.0.0 only, so an extension that keeps it pins with migration_failed. The S132.4 copy carries none, and a test pins the real behaviour. No campaign code changed.

Verified

  • npm run typecheck, npm run lint, npm test: 119 files, 2301 tests passing.

  • ./build/ConvertTo-HumanDocumentation.ps1 and ./build/Test-Documentation.ps1 pass. git diff --check is clean.

  • Reverting each guard in adopt.ts makes its tests fail:

    Guard reverted Tests that fail
    visitedCounts 1
    achievements 1
    VarType 1
    dropped variable 1
    current node missing 1
    node kind 3
    available choice 3
    insertion 7

    The current-node test first passed with its guard removed, because the visitedCounts rule refused the same state. A played state always counts the node it stands on. The test now also covers a state without that count, and fails when the guard is reverted.

  • Not run locally: ./docs.ps1 -BuildOnly (no installed docs.ps1). The Verify Documentation Build check covers it.

@The-Running-Dev
The-Running-Dev merged commit f169f9b into main Oct 9, 2026
8 checks passed
@The-Running-Dev
The-Running-Dev deleted the slice/S132-story-additive branch October 9, 2026 10:43
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant