M9: a campaign you can actually get back
A campaign could already be exported and imported. What could not survive the trip was everything that explains it: the state events behind the authoritative document, the prompt each turn was actually given, the passages it was shown, the summaries that carry long-story continuity, and which take belonged to which turn. An imported campaign could be read and could no longer say why it was what it was — and a manual correction, the one state change no narration explains, was indistinguishable from something the story had established. The bundle is now `ai-dnd-adventure-v3`, and the version is the design rather than a side effect. Everything added here could have been another optional key, the way persona, Save Points, narrative state and imported knowledge each were. That mechanism stops working at exactly this addition: a v2 file with no prompt provenance is ambiguous between "written before M9" and "written by M9 from a campaign that has none", and those are different facts about a campaign. A version number is how a recovery file states what it was capable of recording. v1 and v2 still import, and every seam from pre-active-head onward is tested for the rule that an older file is never reinterpreted under a newer assumption. Two categories became three. "Chosen travels, derived is recomputed" was enough until stored prompts had to be decided: they are derived, and they must travel anyway. The test that separates evidence from cache is not "could this be recomputed" but "would a recomputation answer the same question" — a rebuilt search index answers the same question, a rebuilt prompt says what the turn would be told *now*, which is the opposite of what the inspector is for. Also here: a real SQLite backup, through the online backup API rather than a file copy, taken while the application is running and verified before it is kept; story cards settled as compatibility-only legacy data and taken out of the narrator's prompt, because they were the untracked path around knowledge authority that IMPORTED-KNOWLEDGE-DESIGN §73 already forbade; and no schema change at all, proved against a database M8's own code wrote. Three defects, found by running the milestone's own tests rather than by reading them. Deleting a campaign leaked its FTS index rows, and SQLite then handed the freed ids to the next source imported into any campaign, which failed with an integrity error that Reindex could not repair — both ends are closed, and a database already carrying the damage now repairs itself. An imported node with no state snapshot was being stamped with the campaign's head state, so an Undo to turn 2 showed what the story knew at turn 20. And the snapshot relink did not persist at all, because it mutated a dict in place on a column SQLAlchemy tracks by assignment: it looked correct in memory and wrote the wrong ids to disk. Carrying per-turn prompts looked like it would halve the length of campaign that can be restored. Measured — and after compressing them inside the file — everything M9 added costs 12% of it: the import ceiling moves from about 318 turns to about 279, against a 100-turn certification target. The dominant cost is not M9's at all. The per-position narrative state document is 74% of a bundle, and v2 already carried it. Backend 1,102 passed / 14 skipped / 0 failed. Frontend 145 passed. Lint, production build and Docker build clean. Verified across two server processes with two data directories, and in a real browser against a real narrator. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Qyn3oRd4D6pi72nKBG725B
This commit is contained in:
co-authored by
Claude Opus 5
parent
1ce9972760
commit
44edece67e
+48
-36
@@ -3,7 +3,8 @@
|
||||
**This file is the index. Start here.**
|
||||
|
||||
**Current state:** Phase 0 complete; AI-DnD forked as the production base;
|
||||
milestones **M1 through M6 implemented and accepted** (M3 and M4: 2026-09-03;
|
||||
milestones **M1 through M8 implemented and accepted**, and **M9 implemented and
|
||||
awaiting review**. M1-M6 were accepted on the dates below (M3 and M4: 2026-09-03;
|
||||
M5: 2026-09-04; M6: 2026-09-06). M5 and M6 were each accepted only after an
|
||||
independent review found a real defect and a corrective pass fixed it.
|
||||
|
||||
@@ -19,8 +20,15 @@ carries the closeout: the build-evidence classification in its §P, finding 14's
|
||||
operational resolution, and the acceptance record in its §V. The M8 tree is
|
||||
staged and awaits the repository owner's signed commit.
|
||||
|
||||
**Next: M9 — Export, Backup, Recovery, and Migration Hardening.** It has not
|
||||
been started.
|
||||
**M9 — Export, Backup, Recovery, and Migration Hardening — is implemented and
|
||||
awaiting independent review** (2026-09-07).
|
||||
`reports/M9-IMPLEMENTATION-REPORT.md` is the implementer's account, written for
|
||||
a reviewer: a set of claims with the measurements attached, not yet a record of
|
||||
acceptance. M8's report has moved to `archive/milestone-reports/`, which is
|
||||
where a milestone report goes once the next milestone's report replaces it.
|
||||
|
||||
**Next: M10 — Future Media Extension Hooks Only.** It has not been started, and
|
||||
no brief for it exists.
|
||||
|
||||
**Package version:** see `VERSION.md`, which records what each revision changed
|
||||
and why.
|
||||
@@ -82,8 +90,8 @@ Two standing qualifications:
|
||||
| Document | What it is for |
|
||||
| --- | --- |
|
||||
| `SPECIFICATION.md` | What the product must do. The top of the authority order. |
|
||||
| `TECHNICAL-DESIGN.md` | The selected architecture, including what M1-M7 built, recorded as fact. |
|
||||
| `DATA-MODEL.md` | Entities, the stored head, branch disposition, and the export shape. |
|
||||
| `TECHNICAL-DESIGN.md` | The selected architecture, including what M1-M9 built, recorded as fact. |
|
||||
| `DATA-MODEL.md` | Entities, the stored head, branch disposition, and the v3 export contract. |
|
||||
| `STORY-BRANCH-SEMANTICS.md` | Undo/Redo/Retry/branch/take behavior, including the M3 ratifications. |
|
||||
| `CONTEXT-AND-MEMORY.md` | Prompt assembly, summarization, branch-safe memory. |
|
||||
| `IMPORTED-KNOWLEDGE-DESIGN.md` | Canon / Reference / Inspiration knowledge as a first-class subsystem. |
|
||||
@@ -110,7 +118,7 @@ Two standing qualifications:
|
||||
10. `BROWSER-UX-SPEC.md`
|
||||
11. `V1-ACCEPTANCE-TESTS.md`
|
||||
12. `DECISIONS/` — all of them; they are short.
|
||||
13. `reports/M8-IMPLEMENTATION-REPORT.md`, for what the most recent milestone
|
||||
13. `reports/M9-IMPLEMENTATION-REPORT.md`, for what the most recent milestone
|
||||
actually left behind — reading it as a claim to check, not a record, until
|
||||
it is reviewed. Nothing in `planning/archive/` unless sent there.
|
||||
|
||||
@@ -143,20 +151,18 @@ work until Phase 0 closes — which Phase 0 satisfied on 2026-09-01. It is in
|
||||
`reports/` holds the report for the milestone most recently completed, because
|
||||
that is the one the next milestone's planning has to consult:
|
||||
|
||||
- `reports/M8-IMPLEMENTATION-REPORT.md` — the M8 implementation, its baseline
|
||||
UX measurement, and the browser evidence for every acceptance test it claims.
|
||||
Written by the implementer for an independent reviewer, and completed at
|
||||
closeout after that review accepted the milestone: it is a set of claims with
|
||||
the measurements attached **and** the record of the acceptance. Its §U carries
|
||||
the M9 handoff — the four questions the next brief has to decide.
|
||||
- `reports/M9-IMPLEMENTATION-REPORT.md` — the M9 implementation: the measured M8
|
||||
portability baseline it started from, the final bundle contract, and the
|
||||
evidence for every acceptance test it claims. Written by the implementer for
|
||||
an independent reviewer, so it is a set of claims with the measurements
|
||||
attached and **not** a record of acceptance. Its §W carries the M10-M11
|
||||
handoff.
|
||||
|
||||
**It stays here until M9's report replaces it.** A milestone report is useful
|
||||
during the immediately following milestone; M8's is not archived merely
|
||||
because M8 is accepted.
|
||||
**It stays here until M10's report replaces it.**
|
||||
|
||||
Completed earlier milestones are in `archive/milestone-reports/`, which M7's
|
||||
report joined when M8's was written: a milestone report is useful during the
|
||||
immediate next milestone and historical afterwards. M1-M7 are all there,
|
||||
Completed earlier milestones are in `archive/milestone-reports/`, which M8's
|
||||
report joined when M9's was written: a milestone report is useful during the
|
||||
immediate next milestone and historical afterwards. M1-M8 are all there,
|
||||
unedited.
|
||||
|
||||
## The decision this package rests on
|
||||
@@ -282,33 +288,39 @@ Milestone M8 COMPLETE / ACCEPTED (2026-09-06)
|
||||
story operations review + closeout, in sequence
|
||||
|
|
||||
v
|
||||
Milestone M9 NEXT — not started
|
||||
export, backup, recovery, see BUILD-MILESTONES.md
|
||||
migration hardening
|
||||
Milestone M9 COMPLETE — awaiting review (2026-09-07)
|
||||
export, backup, recovery, reports/M9-IMPLEMENTATION-REPORT.md
|
||||
migration hardening bundle format v3; SQLite online backup
|
||||
|
|
||||
v
|
||||
M10-M11, one at a time see BUILD-MILESTONES.md
|
||||
Milestone M10 NEXT — not started
|
||||
future media extension hooks see BUILD-MILESTONES.md
|
||||
|
|
||||
v
|
||||
Milestone M11 see BUILD-MILESTONES.md
|
||||
```
|
||||
|
||||
## Stop Rule
|
||||
|
||||
**One milestone at a time. Do not begin a milestone before its brief exists.**
|
||||
|
||||
**No M9 brief has been prepared.** Writing one is the current action, informed
|
||||
by the M8 report and by the debt `BUILD-MILESTONES.md` records against M8 — in
|
||||
particular that the campaign bundle still carries no context snapshots, so an
|
||||
imported campaign has no historical prompt provenance; that story cards survive
|
||||
in the backend and the bundle with no browser surface, and M9 should decide
|
||||
deliberately whether the bundle keeps carrying them; and that a deployment whose
|
||||
Ollama enforces a small context window truncates an imported long campaign
|
||||
immediately unless the `DEVELOPMENT.md` procedure or a matching
|
||||
`context_token_budget` is applied.
|
||||
**No M10 brief has been prepared**, and M9 is not accepted — it is implemented
|
||||
and awaiting an independent review. Writing the M10 brief is the action after
|
||||
that review closes, informed by the M9 report's §W.
|
||||
|
||||
**M8's own carried debt** is recorded under M8 in `BUILD-MILESTONES.md`: story
|
||||
cards have no browser editor, the RPG world state is read-only, copy is
|
||||
per-message only, there is no discarded-history recovery screen, and the tablet
|
||||
layout is usable but untuned. Each names the milestone that owns it; none is an
|
||||
open M8 condition.
|
||||
All three questions the M8 debt raised against M9 are settled and recorded:
|
||||
the bundle carries historical context snapshots (`DATA-MODEL.md` §29); story
|
||||
cards are compatibility-only legacy data and no longer reach the narrator
|
||||
(`IMPORTED-KNOWLEDGE-DESIGN.md` §73); and the deployment context ceiling is
|
||||
documented in `DEVELOPMENT.md` with the note that an imported long campaign
|
||||
meets it on its first turn rather than gradually. The window itself stays M11's.
|
||||
|
||||
**M8's own carried debt** is recorded under M8 in `BUILD-MILESTONES.md`. Two of
|
||||
its five items are now closed by M9 — story cards have a settled policy, and the
|
||||
bundle carries the provenance. The RPG world state is still read-only, copy is
|
||||
still per-message only, there is still no discarded-history recovery screen, and
|
||||
the tablet layout is still untuned. Each names the milestone that owns it; none
|
||||
is an open M8 condition.
|
||||
|
||||
The M6 retrieval debt this milestone was warned about is partly addressed and
|
||||
partly still open. Imported material does **not** compete with story memory for
|
||||
|
||||
Reference in New Issue
Block a user