Repository navigation
Content epochs Revision 2 — resolve red-team F1–F3 - #584
Merged
Merged
Conversation
F1: a migration that changes campaignVersion appends a LoggedMigration entry, so a migrated content-bearing save stays inside C26; the entry ends replay (branch, capture, harness refuse it). F2: story-graph adoption requires the current node to stay a ChoiceNode with an available choice, since adoption runs no settle. F3: getStrings returns the union of the session's live epochs, newest winning per key (new C27), rather than a Scene epoch stamp plus a getStrings version parameter.
A migration appends a LoggedMigration only when the log already carries an epoch entry, so a host that migrates but never adopts keeps formatVersion 1 and byte-identical saves (engine rollback stays safe). Capture now refuses every replayCompatible: false session, since a migrated log without epoch entries carries no entry to refuse on.
Refusing every replayCompatible: false session fixes a capture gap that predates content epochs, so it is a separate unit, not part of F1. 08 is back to refusing a session whose log carries a migration entry, and the gap is in the open register.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Resolves the three defects in
design/redteam/2026-10-08-10-design.md(target22af559). Each has a dated 2026-10-08 entry indesign/90-decisions.mdthat cites its finding ID.Changes
F1, BLOCKING. When a save that already carries an epoch entry migrates to a different
campaignVersion, it now also gets aLoggedMigration { seq, system: "migration", from, to }entry.deserializerefuse.formatVersion: 1. A host that migrates but never adopts writes the same saves it writes today.branchSessionrefuses it, capture records none, and the §14 harness fails a fixture that carries one.16-content-epochs§3.5.F2, LOCAL. Story-graph
adoptContentnow also requires two things after the new content is applied:currentNodeIdmust still be aChoiceNode;Adoption runs no settle, so without this check a player could be left on a node with no possible action. Contract: story-graph §8.1. Design: 16 §5.5.
F3, STRUCTURAL.
getStrings(sessionId)now returns the union of the string tables of every epoch the session is still using. Where two epochs define the same key, the newer one wins.Generated pages are regenerated, and the guide's content-epochs subsection is updated and stamped.
Decisions signed off in review
Not in this PR
replayCompatible, so a migrated session with no migration entry can be captured. It is recorded in90-decisions.md's open register under Found by the content-epochs red-team revision.Verified
./build/Test-Documentation.ps1: drift check passed across 19 generated pages and the guide, and link and terminology checks passed across 135 Markdown files.git diff --check: clean.docs.ps1is not installed. Rely on this PR's Verify Documentation Build check.src/engine/changed.