A Save Point is a name for a story position, and restoring one is head movement. That is the whole architecture, and it is what ADR 012 and BUILD-MILESTONES' note on M4 asked for: M3 made the head a stored (branch, depth) and made arriving at one a row lookup plus a state restore, so a Save Point needs no restore machinery of its own. What the user gets: - Name the moment they are reading, keep playing, restart the app, and come back to it. Restoring moves the story back and deletes nothing: the later turns stay, Redo still walks forward into them, and writing something different is what starts a new line while the old one is kept. - Rename, delete, and a list, in a Save Points panel beside the branch panel, with a Save Point button next to Undo and Redo. Both confirmations say what is *not* destroyed, because that is the part the screen cannot show. - Save Points survive export and import. What was deliberately not built: - No second restore path. `head.move_to_node` is the only new movement: its depth half is M3's `head.move_to` unchanged, and its branch half is the single assignment `switch_branch` already makes. No head field is written in the checkpoint router, nothing reconstructs state, nothing prunes a memory, nothing copies or deletes a turn, and restore never forks — the first write below the restored head does, through `fork_if_behind_head`. - No automatic cleanup. A Save Point behind the head, or naming a line the story left, is doing its job (STORY-BRANCH-SEMANTICS §19). The one removal is a cascade: deleting a branch takes its Save Points, as it takes its memories, because the story they named went with it. - No new ADR. ADR 012 already decides the architecture, and a table is not a decision. The one call the planning package did not already make: restore moves the branch half of the head only when the coordinate is off the path being read. Doing it unconditionally would quietly hand back an abandoned continuation whenever a Save Point in a shared prefix was restored; never doing it would make a Save Point on a departed line unrestorable, which contradicts §19. TECHNICAL-DESIGN §8.8 records it. Schema: a `checkpoints` table holding a name, an optional note and a (branch, depth) coordinate — no copy of any story. `create_all` builds it as it did `memories` and `branches`; migration 80 adds the index. No backfill, because nobody had named a position before M4. The coordinate is deliberately not an action id: one coordinate holds every attempt at a turn and exactly one is live, so a coordinate follows a retry where a row id would pin a take the story no longer tells. Tests: 680 pass (638 before). 42 new in tests/test_save_points.py covering D11-D14, I04, L03, E-series lineage and memory isolation after restore and divergence, the edge cases, and an M3-database migration. One pre-existing fixture in test_tree_migration.py needed `checkpoints` added to its drop list — SQLite refuses to drop a table another table references. Not verified: the browser. No session has had a usable one, so the Save Point panel's DOM behaviour is unobserved — as M3's Redo control still is. The twenty-step sequence was driven over HTTP against a live server with a real process restart instead, and all seventeen checks pass. M4 is implemented, not accepted: no review has been written. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01PWU4gTfLYY6Qq9U7aa9Qw2
196 lines
11 KiB
Markdown
196 lines
11 KiB
Markdown
# Planning Package Version
|
|
|
|
- **Package:** Adventure Storyteller Planning Package v2.5
|
|
- **Revision date:** 2026-09-03
|
|
- **Status:** Phase 0 complete; architecture selected; **Milestones M1, M2 and M3 implemented and accepted**; **M4 implemented 2026-09-03 and awaiting review.**
|
|
|
|
## v2.5 — M4 Implementation (2026-09-03)
|
|
|
|
M4 added durable named Save Points. This revision records only what the
|
|
implementation established as fact; **no product requirement changed**, and the
|
|
milestone is **not** marked accepted — its review has not been written.
|
|
|
|
- `TECHNICAL-DESIGN.md` gains **§8.8** and **§9.2**: the Save Point as a name
|
|
plus a coordinate holding no story, restore as head movement with a bounds
|
|
check, the rule that the branch half of the head moves only when the
|
|
coordinate is off the path being read, restore never forking, and the bundle
|
|
carrying Save Points independently of the head.
|
|
- `DATA-MODEL.md` **§8** records the pointer as implemented — `(branch, depth)`
|
|
rather than a turn id, with the reason: one coordinate holds every attempt at
|
|
a turn and exactly one is live, so a coordinate follows a retry where a row id
|
|
would pin a superseded take. **§29** records the checkpoints in the export.
|
|
- `BUILD-MILESTONES.md` **M4** gains a status block: what shipped, the one
|
|
architectural decision the milestone had to make and why it needed no new ADR,
|
|
the test count, and the outstanding browser condition.
|
|
- `README.md` describes Save Points as a user-facing capability.
|
|
|
|
**No ADR was created.** ADR 012 already decides the architecture M4 needed —
|
|
restore reuses active-head movement — and a table is not a decision. The one
|
|
question ADR 012 does not answer, whether restore moves the branch half of the
|
|
head, is that same mechanism applied to a coordinate ADR 012 already defines;
|
|
`TECHNICAL-DESIGN.md` §8.8 records the answer rather than a new ADR asserting it.
|
|
|
|
`SPECIFICATION.md`, `SECURITY-THREAT-MODEL.md`, `STORY-BRANCH-SEMANTICS.md` and
|
|
`V1-ACCEPTANCE-TESTS.md` are unchanged. M4 altered no product requirement, added
|
|
no outbound path, and implemented the checkpoint semantics
|
|
`STORY-BRANCH-SEMANTICS.md` §18-25 already specified rather than amending them.
|
|
|
|
**The browser smoke test remains unperformed, now for both M3 and M4.** No
|
|
session has had a usable browser. See `BUILD-MILESTONES.md` M3 and M4.
|
|
|
|
## v2.4 — Documentation Consolidation (2026-09-03)
|
|
|
|
No product requirement, architecture decision or milestone status changed in
|
|
this revision. It reorganises the documentation so that a new coding agent can
|
|
tell authoritative material from evidence at a glance.
|
|
|
|
- `planning/archive/` is created and is **non-authoritative by declaration**
|
|
(`archive/README.md`). It holds `phase0/` — the research that chose AI-DnD —
|
|
`milestone-reports/` — the completed M1 and M2 reports — and `decisions/`,
|
|
which now holds ADR **008**, the Phase-0-before-build process gate that Phase 0
|
|
satisfied. ADR numbering continues from 012; 008 is not reused.
|
|
- `planning/reports/` now holds **only the current milestone's report**,
|
|
`M3-IMPLEMENTATION-REPORT.md`, because M4 planning has to consult it. It moves
|
|
to the archive when M4's report replaces it.
|
|
- The Phase 0B execution prompts and handoff/status/summary documents
|
|
(`CODEX-HANDOFF-NOTE.md`, `PHASE-0B-CODEX-BRIEF.md`,
|
|
`PHASE-0B-CODEX-HANDOFF.md`, `PLANNING-UPDATE-SUMMARY.md`) and the Phase 0A
|
|
discovery and triage reports were **deleted**: intermediate working documents
|
|
whose conclusions all reached the two recommendation reports, and which remain
|
|
in Git history.
|
|
- Upstream AI-DnD's inherited `plan/` build log and `docs/` project site
|
|
(guides, generated HTML, screenshots) were **deleted**. They documented a
|
|
hosted, scripted, multi-user product with accounts — every screenshot showed a
|
|
Scripts tab and a Sign up button — which M2 removed. Both trees remain in Git
|
|
history and in upstream.
|
|
- `README.md`, `DEVELOPMENT.md` and `PROVENANCE.md` are corrected where they
|
|
pointed at the removed trees or described removed capability as present.
|
|
`DEVELOPMENT.md`'s "things M1 did not touch" section had gone stale at M2 and
|
|
now says what is actually still inherited.
|
|
- `planning/README.md` is rewritten as **the documentation index**: current
|
|
milestone, the three-way active/ADR/archive split, the authority order,
|
|
reading order, where reports live, and what comes next. The milestone
|
|
correction tables are preserved unchanged.
|
|
- New: `planning/PROJECT-SOURCES.md` and `planning/project-sources.txt`, the
|
|
manifest of files to upload as ChatGPT Project Sources.
|
|
|
|
## v2.3 — Post-M3 Closeout (2026-09-03)
|
|
|
|
M3 replaced destructive Undo with a stored active head. Its review is
|
|
`reports/M3-IMPLEMENTATION-REPORT.md`, which is also M3's primary evidence
|
|
record — no separate baseline report was produced — and whose §W records this
|
|
closeout.
|
|
|
|
In summary:
|
|
|
|
- the architecture is recorded as **ADR 012 — Active-Head Non-Destructive
|
|
History**: the head is stored rather than derived, every read of the story is
|
|
capped at it in one place, one mechanism moves it, state comes from the node
|
|
rather than from a replay, the first write below a moved-back head is the
|
|
divergence, and Redo is decided by the lineage rather than by a flag. ADR 005
|
|
is unchanged: it states the product requirement, and ADR 012 states the
|
|
architecture chosen to implement it,
|
|
- two history semantics are **ratified** in `STORY-BRANCH-SEMANTICS.md`: Undo
|
|
crosses fork points to the campaign opening (§5), and the system refuses to
|
|
switch which take is live while a later story is off screen (§10),
|
|
- a **new §14A** records the interim in-place-editing rule — refuse when story
|
|
descends from the turn and is not on screen — and states explicitly that
|
|
§14-15's full narrator-edit requirement stands and is completed in M5,
|
|
- `TECHNICAL-DESIGN.md` gains **§8.7** and **§9.1** recording the implemented
|
|
model and bundle behaviour as fact, and a constraint on §10.4: the snapshot
|
|
half of the hybrid state model is a requirement, because head movement must
|
|
not become proportional to campaign length,
|
|
- `DATA-MODEL.md` records the head as campaign-stored, the branch disposition as
|
|
implemented and deliberately advisory, and the export as carrying a chosen
|
|
position rather than a derived one,
|
|
- `BUILD-MILESTONES.md` marks **M3 complete**, states the one outstanding
|
|
condition (the browser smoke test), tells **M4** to reuse M3's head movement
|
|
rather than build a second restore path, and gives **M5** three constraints,
|
|
- `V1-ACCEPTANCE-TESTS.md` records D03's full pass, states **D10's milestone
|
|
ownership without weakening any pass condition**, adds I07's pre-M3 bundle
|
|
clause, and resolves the apparent L01/A05 conflict,
|
|
- `README.md` is corrected to describe the current local-only single-user
|
|
application rather than the upstream hosted one.
|
|
|
|
`SPECIFICATION.md` and `SECURITY-THREAT-MODEL.md` are unchanged: M3 altered no
|
|
product requirement and touched no path in the threat model.
|
|
|
|
## v2.2 — Post-M2 Closeout (2026-09-03)
|
|
|
|
M2 removed the hosted, cloud, account and scripting surface and added the
|
|
inference endpoint policy. Its review recommended six planning changes and
|
|
reported rather than applied them; all six are applied in this revision, listed
|
|
in `README.md` § *Post-M2 corrections applied*, with the evidence in
|
|
`archive/milestone-reports/M2-BASELINE-REPORT.md` and `archive/milestone-reports/M2-IMPLEMENTATION-REPORT.md`.
|
|
|
|
In summary:
|
|
|
|
- the **inference endpoint policy is recorded as implemented** — an address
|
|
allowlist of explicit local-network CIDRs, every resolved address checked,
|
|
enforced when settings are saved and again before every outbound request, with
|
|
TLS verification never traded against it (new **ADR 011**,
|
|
`SECURITY-THREAT-MODEL.md` §10A),
|
|
- its two **residual limits are stated rather than mitigated**: a hostile host
|
|
already on the trusted LAN, and the DNS-rebinding interval between the
|
|
policy's resolution and the client's connection,
|
|
- `TECHNICAL-DESIGN.md` §5.1 items 3 and 4 are **resolved**, and a new §5.2
|
|
records the M1/M2 production architecture as fact,
|
|
- a **wiring rule** is added (§18.1): removing a setting requires testing a real
|
|
consumer path, and adding one requires proving it reaches its component — M2
|
|
shipped two defects behind a 604-test green suite because the tests at that
|
|
boundary were mocks,
|
|
- `BUILD-MILESTONES.md` records **M2 complete**, warns M5 that eight rollback
|
|
tests use the world-state engine as instrumentation rather than as
|
|
architecture, and requires M6 to make background memory failure observable,
|
|
- the security acceptance contract is strengthened: **H10** now names the
|
|
wildcard-origin and `/api` 404 conditions, and new **H12** covers inference
|
|
endpoint enforcement including the database-edited-behind-the-API case.
|
|
|
|
`SPECIFICATION.md` is unchanged: M2 altered no product requirement. Nothing in
|
|
the architecture selected in v2 was reversed.
|
|
|
|
## v2.1 — Post-M1 Corrections (2026-09-02)
|
|
|
|
M1 implementation evidence contradicted or under-specified parts of v2. The
|
|
corrections are recorded in the documents themselves and listed in
|
|
`README.md` § *Post-M1 corrections applied*; the evidence behind them is in
|
|
`archive/milestone-reports/M1-BASELINE-REPORT.md` and `archive/milestone-reports/M1-IMPLEMENTATION-REPORT.md`.
|
|
|
|
In summary:
|
|
|
|
- a trusted-LAN Ollama may be **HTTPS with a privately issued certificate**;
|
|
clients verify against the operating system's CA store, with full certificate
|
|
and hostname verification and no bypass option (ADR 002,
|
|
`TECHNICAL-DESIGN.md` §5, A06),
|
|
- offline claims require a **fresh cache and no route out** to be evidence at
|
|
all, and vendored runtime artifacts should be integrity-verifiable
|
|
(ADR 004),
|
|
- A05's invariant is about **accepted** history; the user's submitted text is
|
|
deliberately retained on a failed turn,
|
|
- A06 requires a **real second machine and an HTTPS endpoint**; a plain-HTTP
|
|
LAN test is no longer sufficient evidence,
|
|
- the standard test environment records **CPU/GPU/RAM**, because cold model
|
|
load on a CPU-only host exceeded the inherited 120 s client timeout,
|
|
- `BUILD-MILESTONES.md` records M1 as complete and reframes M2's endpoint work
|
|
as **narrowing** an existing capability rather than inventing it,
|
|
- `SECURITY-THREAT-MODEL.md` §53 distinguishes **inbound** TLS (still deferred)
|
|
from **outbound** certificate verification (required, done in M1).
|
|
|
|
Nothing in the architecture selected in v2 was reversed.
|
|
|
|
## v2 — Post Phase 0B Revision (2026-09-01)
|
|
|
|
This v2 package supersedes the earlier planning package produced before the final Phase 0B review and the trusted-LAN Ollama deployment clarification.
|
|
|
|
Key v2 changes include:
|
|
|
|
- AI-DnD selected as the production base at the pinned Phase 0B commit.
|
|
- Non-destructive head-cursor Undo/Redo design selected.
|
|
- Explicit typed/absolute narrative-state events selected for production state handling.
|
|
- Imported knowledge separated from AI-DnD Story Cards.
|
|
- Trusted-LAN Ollama inference supported in v1 while the storyteller UI/API remains loopback-bound by default.
|
|
- Offline first-use dependencies and runtime remote assets identified as M1 hardening work.
|
|
- Production implementation divided into milestones M1-M11.
|
|
|
|
Historical Phase 0 prompts/reports are retained as evidence and should not be treated as current implementation instructions unless a current milestone prompt explicitly refers to them.
|