857 lines
19 KiB
Markdown
857 lines
19 KiB
Markdown
# Adventure Storyteller — Story Branch Semantics
|
|
|
|
**Status:** Draft v0.1
|
|
**Purpose:** Define exactly how Undo, Redo, Retry, Edit, Restore, checkpoints, and abandoned history should behave.
|
|
|
|
## 1. Design Goal
|
|
|
|
The user experience should remain simple.
|
|
|
|
The user should not need to think in terms of Git branches, tree structures, or database lineage during normal storytelling.
|
|
|
|
The primary controls should be:
|
|
|
|
- Undo
|
|
- Redo
|
|
- Retry
|
|
- Edit
|
|
- Save Checkpoint
|
|
- Restore Checkpoint
|
|
|
|
Internally, however, the system should preserve enough history to make these operations safe, reversible, and state-consistent.
|
|
|
|
The core rule is:
|
|
|
|
> User-facing history should feel like normal Undo/Redo, while internal history may use branch-like lineage to avoid destructive edits.
|
|
|
|
## 2. User-Facing Philosophy
|
|
|
|
### 2.1 Branching is an implementation detail
|
|
|
|
The normal UI should not require explicit actions such as:
|
|
|
|
- Create Branch
|
|
- Switch Branch
|
|
- Merge Branch
|
|
- Compare Branches
|
|
|
|
Those concepts may exist internally.
|
|
|
|
The user should instead see familiar operations.
|
|
|
|
### 2.2 Abandoned history is retained but disposable
|
|
|
|
When the user goes backward and continues differently:
|
|
|
|
- the original future should not be immediately deleted,
|
|
- it should be marked as abandoned/disposable,
|
|
- it should no longer appear as the active story,
|
|
- it may be pruned later by a future cleanup feature,
|
|
- it may optionally become recoverable through a future discarded-history screen.
|
|
|
|
No automatic cleanup policy is required for v1.
|
|
|
|
### 2.3 Named checkpoints are intentionally durable
|
|
|
|
A named checkpoint is different from ordinary undo history.
|
|
|
|
Named checkpoints remain until explicitly deleted.
|
|
|
|
## 3. Definitions
|
|
|
|
### Active History
|
|
The currently selected sequence of accepted turns from campaign root to the current head.
|
|
|
|
### Story Head
|
|
The current endpoint of active history.
|
|
|
|
### Abandoned History
|
|
Previously accepted turns that are no longer part of the active continuation because the user undid, restored, edited, or retried and then continued differently.
|
|
|
|
### Disposable History
|
|
Abandoned history that is retained for safety/recovery but may be eligible for future cleanup.
|
|
|
|
### Named Checkpoint
|
|
A durable user-created pointer to a specific accepted story position.
|
|
|
|
### Alternate Take
|
|
A different narrator response to the same user input.
|
|
|
|
### Divergence
|
|
The point where active story history begins following a different continuation than previously accepted history.
|
|
|
|
## 4. Undo
|
|
|
|
Undo moves the active story head backward by one accepted story step.
|
|
|
|
Example:
|
|
|
|
```text
|
|
Turn 47
|
|
You enter the tavern.
|
|
|
|
Turn 48
|
|
You accuse Mara of stealing the key.
|
|
|
|
Turn 49
|
|
Mara draws a knife.
|
|
```
|
|
|
|
After one Undo:
|
|
|
|
```text
|
|
Active head: Turn 48
|
|
Redo candidate: Turn 49
|
|
```
|
|
|
|
After two Undos:
|
|
|
|
```text
|
|
Active head: Turn 47
|
|
Redo candidate: Turn 48
|
|
```
|
|
|
|
## 5. Undo Depth
|
|
|
|
Preferred behavior:
|
|
|
|
> Unlimited Undo across retained campaign history.
|
|
|
|
If the selected base architecture makes unlimited Undo substantially harder or unsafe, the minimum acceptable behavior is:
|
|
|
|
> At least five consecutive Undo operations.
|
|
|
|
Technical validation during Phase 0B should determine whether unlimited Undo is straightforward.
|
|
|
|
The final implementation should prefer unlimited Undo unless there is a concrete technical reason not to.
|
|
|
|
## 6. State Restoration on Undo
|
|
|
|
Undo must restore more than visible transcript text.
|
|
|
|
When moving the story head backward, the system must restore the corresponding:
|
|
|
|
- authoritative narrative state,
|
|
- current location,
|
|
- entity states,
|
|
- relationships,
|
|
- facts,
|
|
- active story threads,
|
|
- scene state,
|
|
- summary lineage,
|
|
- memory lineage,
|
|
- relevant prompt/retrieval lineage.
|
|
|
|
The system must not leave current state from a later turn attached to an earlier transcript position.
|
|
|
|
## 7. Redo
|
|
|
|
Redo moves forward along the previously active continuation after Undo.
|
|
|
|
Example:
|
|
|
|
```text
|
|
47 -> 48 -> 49
|
|
```
|
|
|
|
User undoes to 47:
|
|
|
|
```text
|
|
Active: 47
|
|
Redo path: 48 -> 49
|
|
```
|
|
|
|
Pressing Redo restores 48.
|
|
|
|
Pressing Redo again restores 49.
|
|
|
|
## 8. Redo Invalidation
|
|
|
|
Redo remains available only while the user has not created a new continuation.
|
|
|
|
Example:
|
|
|
|
```text
|
|
47 -> 48A -> 49A
|
|
```
|
|
|
|
User undoes to 47 and then enters a new action:
|
|
|
|
```text
|
|
47 -> 48B
|
|
```
|
|
|
|
At that point:
|
|
|
|
- 48B becomes active,
|
|
- 48A -> 49A becomes abandoned/disposable history,
|
|
- ordinary Redo should no longer move into 48A.
|
|
|
|
The old history is retained internally but is no longer part of the standard Redo stack.
|
|
|
|
## 9. Retry
|
|
|
|
Retry means:
|
|
|
|
> Generate another narrator response to the same user input.
|
|
|
|
Example:
|
|
|
|
```text
|
|
User:
|
|
I open the door.
|
|
|
|
Take A:
|
|
A dragon lunges through the doorway.
|
|
```
|
|
|
|
Retry:
|
|
|
|
```text
|
|
Take B:
|
|
The room beyond is dark and silent.
|
|
```
|
|
|
|
The user should be able to move among recent alternate takes before continuing.
|
|
|
|
## 10. Retry Selection
|
|
|
|
Before the user continues the story, alternate narrator takes should remain selectable.
|
|
|
|
Conceptually:
|
|
|
|
```text
|
|
User action
|
|
|
|
|
+-- Take A
|
|
+-- Take B
|
|
+-- Take C
|
|
```
|
|
|
|
One take is selected as active.
|
|
|
|
If the user continues from Take B:
|
|
|
|
```text
|
|
User action
|
|
|
|
|
+-- Take A [inactive/disposable]
|
|
+-- Take B [selected]
|
|
|
|
|
+-- next user turn
|
|
+-- Take C [inactive/disposable]
|
|
```
|
|
|
|
Inactive takes should remain retained initially.
|
|
|
|
## 11. Retry vs Branch
|
|
|
|
Retry should not be presented to the user as “creating a branch.”
|
|
|
|
It is an alternate narrator attempt for the same user instruction.
|
|
|
|
Internally, the implementation may represent retries as sibling turn nodes, alternate takes under one turn request, or another equivalent lineage mechanism.
|
|
|
|
The physical representation is still provisional.
|
|
|
|
## 12. Retry of Older Narration
|
|
|
|
If the user selects an older narrator response and retries it:
|
|
|
|
- the system first returns to that story position,
|
|
- the existing future becomes abandoned/disposable history,
|
|
- the new narrator take becomes a new continuation candidate.
|
|
|
|
The system must restore the state corresponding to the retry point before generating the new response.
|
|
|
|
## 13. Editing User Input
|
|
|
|
The user should be able to edit an earlier user input.
|
|
|
|
Semantics:
|
|
|
|
> Editing an earlier user input is equivalent to returning to the parent story state and creating a new continuation using the edited input.
|
|
|
|
Example:
|
|
|
|
Original:
|
|
|
|
```text
|
|
47: Arrive at tavern
|
|
48: "I accuse Mara of taking the key."
|
|
49: Mara draws a knife.
|
|
```
|
|
|
|
User edits Turn 48 to:
|
|
|
|
```text
|
|
"I quietly ask Mara whether she has seen the key."
|
|
```
|
|
|
|
Result:
|
|
|
|
```text
|
|
47
|
|
├── 48A original accusation
|
|
│ └── 49A knife response
|
|
└── 48B edited question
|
|
└── new narrator response
|
|
```
|
|
|
|
The old future is retained as disposable history.
|
|
|
|
## 14. Editing Narrator Output
|
|
|
|
The user should be able to directly correct narrator prose.
|
|
|
|
Example:
|
|
|
|
Original:
|
|
|
|
```text
|
|
Mara enters wearing a red cloak.
|
|
```
|
|
|
|
User changes it to:
|
|
|
|
```text
|
|
Mara enters wearing a green cloak.
|
|
```
|
|
|
|
The edited narration becomes authoritative for the active continuation.
|
|
|
|
## 15. Effects of Narrator Edit
|
|
|
|
Editing narrator output may affect structured state.
|
|
|
|
Therefore the system must:
|
|
|
|
1. return to the state immediately before the edited narration,
|
|
2. treat the edited text as the accepted narrator output,
|
|
3. re-evaluate state changes implied by that output,
|
|
4. create a new active continuation,
|
|
5. retain the original narration/future as disposable history.
|
|
|
|
The system must not simply replace visible text while leaving stale state behind.
|
|
|
|
## 16. Manual State / Canon Correction
|
|
|
|
The user should be able to correct authoritative story state without rewriting prose.
|
|
|
|
Example:
|
|
|
|
> Mara never learned about the silver key.
|
|
|
|
This should be available through an explicit operation such as:
|
|
|
|
- Edit Story State
|
|
- Edit Canon
|
|
- Correct Fact
|
|
|
|
Exact UI terminology is still open.
|
|
|
|
## 17. State Correction Semantics
|
|
|
|
A manual correction should:
|
|
|
|
- record the old value,
|
|
- record the new value,
|
|
- record that the source was a manual user correction,
|
|
- record when the correction occurred,
|
|
- affect future story context,
|
|
- remain auditable.
|
|
|
|
A manual correction should not silently rewrite historical transcript text.
|
|
|
|
If historical consistency requires a deeper rewind, the UI may warn the user.
|
|
|
|
## 18. Checkpoints
|
|
|
|
A checkpoint is a user-created durable save point.
|
|
|
|
Example names:
|
|
|
|
- Before entering Blackwood
|
|
- Arrival at Ceres Station
|
|
- Before confronting Mara
|
|
- Before opening the vault
|
|
|
|
A checkpoint points to a specific accepted story position.
|
|
|
|
## 19. Checkpoint Durability
|
|
|
|
Named checkpoints remain until explicitly deleted.
|
|
|
|
They should not be removed by:
|
|
|
|
- Undo,
|
|
- Redo,
|
|
- Retry,
|
|
- Edit,
|
|
- Restore,
|
|
- branch divergence,
|
|
- ordinary history cleanup.
|
|
|
|
## 20. Checkpoint Restore
|
|
|
|
Restoring a checkpoint:
|
|
|
|
1. moves the active story head to the checkpoint turn,
|
|
2. restores authoritative state for that turn,
|
|
3. restores corresponding scene state,
|
|
4. restores compatible summary/memory lineage,
|
|
5. prepares the story to continue from that position.
|
|
|
|
The original later story remains retained as abandoned/disposable history.
|
|
|
|
## 21. Restore Does Not Delete
|
|
|
|
Example:
|
|
|
|
```text
|
|
Checkpoint: Before Fortress
|
|
|
|
100 -> 101 -> 102 -> 103 -> 104
|
|
```
|
|
|
|
Restore checkpoint at 100 and continue:
|
|
|
|
```text
|
|
100
|
|
├── 101A -> 102A -> 103A -> 104A [old/disposable]
|
|
└── 101B -> 102B [active]
|
|
```
|
|
|
|
The UI does not need to show this tree during normal play.
|
|
|
|
## 22. Model Settings on Restore
|
|
|
|
A checkpoint primarily preserves story position and state.
|
|
|
|
It does not need to force restoration of the exact narrator model/settings used at the time.
|
|
|
|
Every historical turn should separately preserve its original model/settings for auditability.
|
|
|
|
When continuing after restore, the system should normally use the user's current configured model/settings.
|
|
|
|
A future optional control may allow restoring historical model settings.
|
|
|
|
## 23. Checkpoint Renaming
|
|
|
|
Checkpoint labels may be renamed.
|
|
|
|
Renaming does not change the referenced story position.
|
|
|
|
## 24. Moving Checkpoints
|
|
|
|
v1 should not casually allow an existing checkpoint to be moved to another turn.
|
|
|
|
Preferred behavior:
|
|
|
|
- rename checkpoint, or
|
|
- delete checkpoint and create a new one.
|
|
|
|
This keeps checkpoint meaning auditable.
|
|
|
|
## 25. Deleting Checkpoints
|
|
|
|
Checkpoint deletion must be explicit.
|
|
|
|
Deleting a checkpoint:
|
|
|
|
- removes the named pointer,
|
|
- does not delete the story turn,
|
|
- does not delete story history.
|
|
|
|
## 26. Abandoned / Disposable History
|
|
|
|
When a different continuation becomes active, the displaced future becomes conceptually:
|
|
|
|
```text
|
|
abandoned = true
|
|
disposable = true
|
|
```
|
|
|
|
Equivalent metadata may be used.
|
|
|
|
The exact database representation is implementation-specific.
|
|
|
|
## 27. No Automatic Cleanup in Initial Version
|
|
|
|
v1 should not automatically purge disposable history.
|
|
|
|
Reasons:
|
|
|
|
- text/state records are inexpensive,
|
|
- early cleanup risks destroying useful recovery data,
|
|
- branch/state correctness is easier to verify when history remains,
|
|
- generated media will consume much more storage than text.
|
|
|
|
Cleanup should be designed only after real usage shows it is necessary.
|
|
|
|
## 28. Future Cleanup
|
|
|
|
A later cleanup feature may offer:
|
|
|
|
- prune abandoned history older than N days,
|
|
- prune abandoned history older than N turns,
|
|
- prune all unprotected discarded paths,
|
|
- retain paths referenced by checkpoints,
|
|
- retain paths containing manually preserved alternates,
|
|
- show estimated space savings before deletion.
|
|
|
|
No specific cleanup policy is committed for v1.
|
|
|
|
## 29. Possible Future Discarded-History Recovery Screen
|
|
|
|
A future feature may expose discarded/abandoned history.
|
|
|
|
Possible uses:
|
|
|
|
- recover a discarded continuation,
|
|
- inspect earlier alternate takes,
|
|
- restore something accidentally abandoned,
|
|
- compare old and current story paths.
|
|
|
|
This is a possible later feature, not a committed v1 requirement.
|
|
|
|
## 30. Active History Visibility
|
|
|
|
Normal transcript display should show only:
|
|
|
|
- the active history,
|
|
- currently selected narrator take,
|
|
- current story state.
|
|
|
|
Discarded history should not clutter normal play.
|
|
|
|
## 31. History Integrity
|
|
|
|
The system must never create a transcript/state mismatch such as:
|
|
|
|
```text
|
|
Visible transcript says:
|
|
Mara never saw the key.
|
|
|
|
Structured state says:
|
|
Mara knows about the key because of abandoned Turn 52.
|
|
```
|
|
|
|
Only active-lineage facts, memories, summaries, and state may influence the current continuation.
|
|
|
|
## 32. Summary Lineage
|
|
|
|
Summaries are derived from specific story history.
|
|
|
|
When the active story diverges:
|
|
|
|
- summaries containing abandoned future turns must not be applied to the new continuation,
|
|
- unaffected ancestral summaries may remain valid,
|
|
- new summaries may be generated when required.
|
|
|
|
The system should record source turn ranges or lineage for every summary.
|
|
|
|
## 33. Memory Lineage
|
|
|
|
Retrieved story memory must respect active lineage.
|
|
|
|
A memory from an abandoned future must not appear as something that happened in the active story.
|
|
|
|
Example:
|
|
|
|
Discarded path:
|
|
|
|
```text
|
|
Mara reveals she is a spy.
|
|
```
|
|
|
|
New active path:
|
|
|
|
```text
|
|
Mara has never revealed this.
|
|
```
|
|
|
|
The memory retriever must not feed:
|
|
|
|
```text
|
|
Mara is known to be a spy.
|
|
```
|
|
|
|
to the narrator merely because that fact exists in an abandoned path.
|
|
|
|
This is a critical correctness requirement.
|
|
|
|
## 34. Imported Knowledge Is Different
|
|
|
|
Imported Canon / Reference / Inspiration files are not normally branch-specific.
|
|
|
|
They remain available across branches unless the source is explicitly campaign-state-dependent or the user disables/removes the source.
|
|
|
|
Story memories and story-derived facts, by contrast, must be lineage-aware.
|
|
|
|
## 35. Scene Lineage
|
|
|
|
Scene snapshots must also follow active history.
|
|
|
|
A scene from an abandoned future must not become the current scene after Undo or Restore.
|
|
|
|
Generated media attached to an abandoned scene may remain stored, but it should no longer be treated as current-story media.
|
|
|
|
## 36. Prompt Provenance
|
|
|
|
Every generated narrator take should preserve enough information to determine:
|
|
|
|
- parent story position,
|
|
- user input,
|
|
- selected history,
|
|
- current state,
|
|
- summaries used,
|
|
- memories used,
|
|
- imported knowledge used,
|
|
- model/settings,
|
|
- resulting output.
|
|
|
|
This remains true even for abandoned/disposable history until it is explicitly pruned.
|
|
|
|
## 37. Failure During Retry / Edit / Continue
|
|
|
|
If generation fails:
|
|
|
|
- the previously accepted active history remains valid,
|
|
- no partial state mutation should be committed,
|
|
- no successful prior take should be lost.
|
|
|
|
The user should be able to retry generation.
|
|
|
|
## 38. Atomic Acceptance
|
|
|
|
A newly generated continuation should become accepted only when the application can coherently commit:
|
|
|
|
- narration,
|
|
- lineage,
|
|
- state changes,
|
|
- scene update,
|
|
- provenance.
|
|
|
|
A failure in state extraction should not silently leave partially applied state.
|
|
|
|
Exact failure-repair handling will be specified later.
|
|
|
|
## 39. User-Facing Control Summary
|
|
|
|
### Undo
|
|
Move backward one accepted story step.
|
|
|
|
### Redo
|
|
Move forward again, until a new continuation is created.
|
|
|
|
### Retry
|
|
Generate another narrator response to the same user input.
|
|
|
|
### Edit User Input
|
|
Return to that point and create a new continuation using edited input.
|
|
|
|
### Edit Narrator Output
|
|
Replace the active narration through a new auditable continuation and re-evaluate state.
|
|
|
|
### Save Checkpoint
|
|
Create a durable named pointer to the current story position.
|
|
|
|
### Restore Checkpoint
|
|
Return to that state; later history becomes retained disposable history.
|
|
|
|
### Correct State / Canon
|
|
Explicitly change an authoritative fact without rewriting transcript prose.
|
|
|
|
## 40. Not Required in v1 UI
|
|
|
|
Do not require:
|
|
|
|
- branch tree visualization,
|
|
- manual branch creation,
|
|
- merge,
|
|
- cherry-pick,
|
|
- branch comparison,
|
|
- branch IDs,
|
|
- discarded-history browser,
|
|
- automatic branch cleanup.
|
|
|
|
Internal lineage may still use branch/tree structures.
|
|
|
|
## 41. Minimum v1 Undo Requirement
|
|
|
|
Acceptance requirement:
|
|
|
|
- at least 5 consecutive Undo operations must be supported.
|
|
|
|
Preferred:
|
|
|
|
- unlimited Undo across retained history.
|
|
|
|
Phase 0B should determine whether the preferred behavior is already practical in the selected base.
|
|
|
|
## 42. Example: Simple Mistake
|
|
|
|
Initial:
|
|
|
|
```text
|
|
10: Enter tavern
|
|
11: Accuse Mara
|
|
12: Mara becomes hostile
|
|
```
|
|
|
|
User Undo x2:
|
|
|
|
```text
|
|
Active head = 10
|
|
```
|
|
|
|
User enters:
|
|
|
|
```text
|
|
I ask Mara privately whether she saw anyone near my room.
|
|
```
|
|
|
|
Result:
|
|
|
|
```text
|
|
10
|
|
├── 11A Accuse Mara
|
|
│ └── 12A Mara hostile
|
|
└── 11B Ask privately
|
|
└── 12B New narration
|
|
```
|
|
|
|
User sees only:
|
|
|
|
```text
|
|
10 -> 11B -> 12B
|
|
```
|
|
|
|
The A path is retained but disposable.
|
|
|
|
## 43. Example: Retry
|
|
|
|
```text
|
|
User: I open the airlock door.
|
|
|
|
Take A:
|
|
A maintenance robot is waiting.
|
|
|
|
Retry
|
|
|
|
Take B:
|
|
The corridor beyond is filled with smoke.
|
|
```
|
|
|
|
User selects Take B and continues.
|
|
|
|
Take A remains retained/disposable.
|
|
|
|
## 44. Example: Named Checkpoint
|
|
|
|
```text
|
|
Checkpoint:
|
|
"Before entering the alien structure"
|
|
|
|
Turn 220
|
|
```
|
|
|
|
Story continues to Turn 245.
|
|
|
|
User restores checkpoint and chooses another approach.
|
|
|
|
Turns 221-245 remain retained/disposable.
|
|
|
|
The checkpoint remains attached to Turn 220 until explicitly deleted.
|
|
|
|
## 45. Example: Manual Canon Correction
|
|
|
|
Narrator incorrectly establishes:
|
|
|
|
```text
|
|
The Persephone has an FTL drive.
|
|
```
|
|
|
|
Campaign canon says:
|
|
|
|
```text
|
|
FTL does not exist.
|
|
```
|
|
|
|
User corrects state/canon.
|
|
|
|
The correction should be recorded explicitly and future context must treat:
|
|
|
|
```text
|
|
The Persephone has no FTL capability.
|
|
```
|
|
|
|
as authoritative.
|
|
|
|
If desired, the user may also edit the narration, but that is a separate operation.
|
|
|
|
## 46. Phase 0B Validation Questions
|
|
|
|
Codex should answer:
|
|
|
|
1. Does AI-DnD already support unlimited practical Undo through its lineage model?
|
|
2. How does AI-DnD distinguish retry takes from full branches?
|
|
3. Can retry/edit preserve prior futures without exposing a complex branch UI?
|
|
4. Can summaries and memories be reliably lineage-filtered after divergence?
|
|
5. Does AI-DnD state rollback restore generic state independently of RPG mechanics?
|
|
6. How difficult would it be to mark abandoned paths disposable without deleting them?
|
|
7. In Open Dungeon, what exact modules assume destructive tail-deletion semantics?
|
|
8. Can checkpoints be implemented as durable turn pointers without duplicating state?
|
|
9. What is the cost of retaining all disposable text/state history in SQLite?
|
|
10. Does any finalist currently leak abandoned branch memories into active retrieval?
|
|
|
|
## 47. Acceptance Criteria
|
|
|
|
The final implementation must satisfy:
|
|
|
|
- Undo restores transcript and state together.
|
|
- At least five Undo steps are available; unlimited is preferred.
|
|
- Redo works until a new continuation is created.
|
|
- Retry preserves alternate narrator takes.
|
|
- Editing old user input creates a safe new continuation.
|
|
- Editing narrator output re-evaluates state.
|
|
- Named checkpoints remain until explicitly deleted.
|
|
- Restoring a checkpoint does not delete later history.
|
|
- Abandoned history is retained and marked disposable.
|
|
- No automatic abandoned-history cleanup is required initially.
|
|
- Abandoned history does not influence active summaries, memories, state, or prompts.
|
|
- Manual state/canon corrections are auditable.
|
|
- Normal UI does not require branch management.
|
|
- A future discarded-history recovery screen remains possible without schema redesign.
|
|
|
|
## 48. Current Recommendation
|
|
|
|
Use a simple linear user experience backed by non-destructive lineage.
|
|
|
|
Conceptually:
|
|
|
|
```text
|
|
USER EXPERIENCE
|
|
|
|
Undo
|
|
Redo
|
|
Retry
|
|
Edit
|
|
Checkpoint
|
|
Restore
|
|
|
|
↓
|
|
|
|
INTERNAL MODEL
|
|
|
|
Parent-linked history
|
|
Alternate takes
|
|
State snapshots/events
|
|
Active head
|
|
Disposable abandoned history
|
|
Lineage-aware summaries/memory
|
|
```
|
|
|
|
This provides recovery and correctness without forcing the user to manage a story tree.
|