Apply post-M1 corrections to the planning package

This commit is contained in:
JesseMarkowitz
2026-09-02 06:03:10 -04:00
parent 645f07f06d
commit 1a28a9a708
8 changed files with 304 additions and 35 deletions
+36 -3
View File
@@ -1,6 +1,6 @@
# Adventure Storyteller — Production Build Milestones # Adventure Storyteller — Production Build Milestones
**Status:** Planning-ready; implementation not yet authorized **Status:** In implementation. M1 complete (2026-09-02); M2 next
**Base:** AI-DnD `d72f7c1bda0f34fccd84afb7a25c34eb01c901de` **Base:** AI-DnD `d72f7c1bda0f34fccd84afb7a25c34eb01c901de`
## 1. Purpose ## 1. Purpose
@@ -63,6 +63,15 @@ Create the production fork from the pinned AI-DnD commit and make ordinary local
- verify explicitly configured trusted-LAN Ollama story generation while the storyteller UI/API remains loopback-bound, - verify explicitly configured trusted-LAN Ollama story generation while the storyteller UI/API remains loopback-bound,
- establish baseline regression/test report. - establish baseline regression/test report.
**Added during implementation:** outbound TLS trust. A trusted-LAN Ollama may be
served over HTTPS with a privately issued certificate, which the inherited HTTP
client refused because it verified against a bundled public-CA list only. M1
made outbound HTTPS verify against the operating system's CA store as well,
with verification and hostname checking fully intact and no bypass option
(ADR 002; `backend/app/tlstrust.py`). This was not in the scope list above but
was on M1's critical path: without it the trusted-LAN Definition of Done below
is unreachable against a realistic host.
## Explicit Non-Scope ## Explicit Non-Scope
- no history rewrite yet, - no history rewrite yet,
@@ -86,6 +95,22 @@ Must demonstrate:
A clean production build can start, open the browser UI, generate and persist story turns through either same-host Ollama or an explicitly configured trusted-LAN Ollama host, restart, and resume with outbound Internet blocked. The storyteller UI/API remains loopback-bound by default. A clean production build can start, open the browser UI, generate and persist story turns through either same-host Ollama or an explicitly configured trusted-LAN Ollama host, restart, and resume with outbound Internet blocked. The storyteller UI/API remains loopback-bound by default.
## Status: COMPLETE
Accepted 2026-09-02. Evidence: `planning/reports/M1-BASELINE-REPORT.md` (run
logs and packet captures) and `planning/reports/M1-IMPLEMENTATION-REPORT.md`
(review report). A01-A06, H01-H03 and H11 all pass on runtime evidence; 648
backend tests pass, including with no route to the Internet.
**Capabilities M1 delivered, which later milestones inherit rather than build:**
- offline first turn — the tokenizer table is vendored and digest-checked,
- no remote runtime assets — fonts self-hosted, CSP names no remote origin,
- loopback-bound storyteller in every run path, including the published Docker port,
- **working trusted-LAN inference, plain HTTP and HTTPS with a private CA**,
demonstrated against a second physical machine,
- a reproducible environment (`backend/requirements.lock`) and an offline-capable test suite.
--- ---
# M2 — Remove Hosted, Cloud, Scripting, and Unneeded Deployment Surface # M2 — Remove Hosted, Cloud, Scripting, and Unneeded Deployment Surface
@@ -111,7 +136,15 @@ Remove or isolate as appropriate:
Add: Add:
- explicit Ollama endpoint policy: same-host loopback default plus user-configured trusted-LAN inference, - explicit Ollama endpoint policy. **Trusted-LAN inference already works as of
M1** — same-host loopback default, user-configured LAN endpoint, HTTP or
HTTPS with a privately issued certificate, verified against the machine's CA
store. M2's job is not to invent that capability but to **formalize and
narrow** it: decide and enforce what an endpoint may be in normal v1
configuration, reject or remove what it may not, and keep the endpoint's
configuration from affecting the storyteller's own loopback bind. Do not
regress the TLS behavior while narrowing the surface — the shared
verification context must follow any client the removal work rewrites,
- clear local-model connection diagnostics, - clear local-model connection diagnostics,
- migration/test instrumentation replacements for any tests that depended on JS hooks or removed hosted paths. - migration/test instrumentation replacements for any tests that depended on JS hooks or removed hosted paths.
@@ -126,7 +159,7 @@ Add:
- local story play still works, - local story play still works,
- existing tree/retry/memory/context behavior remains intact, - existing tree/retry/memory/context behavior remains intact,
- application requires no cloud API keys, - application requires no cloud API keys,
- approved trusted-LAN Ollama endpoints work while arbitrary public/Internet provider endpoints are rejected or absent from normal production configuration, - approved trusted-LAN Ollama endpoints work — including an HTTPS endpoint with a privately issued certificate, per A06 — while arbitrary public/Internet provider endpoints are rejected or absent from normal production configuration,
- removed provider/auth/analytics/scripting paths are no longer reachable from normal production configuration. - removed provider/auth/analytics/scripting paths are no longer reachable from normal production configuration.
## Definition of Done ## Definition of Done
+29 -1
View File
@@ -1,6 +1,6 @@
# ADR 002 — Ollama Is the v1 Model Backend # ADR 002 — Ollama Is the v1 Model Backend
**Status:** Accepted **Status:** Accepted; transport/TLS consequence added after M1
## Decision ## Decision
@@ -30,3 +30,31 @@ Ollama is already available locally, provides a simple local API, supports both
- LAN inference does not imply LAN exposure of the storyteller UI/API; the storyteller should still bind to loopback by default, - LAN inference does not imply LAN exposure of the storyteller UI/API; the storyteller should still bind to loopback by default,
- arbitrary public Internet/cloud model endpoints remain outside normal v1 configuration, - arbitrary public Internet/cloud model endpoints remain outside normal v1 configuration,
- future backend abstraction may be added, but v1 should not be delayed to support it. - future backend abstraction may be added, but v1 should not be delayed to support it.
## Transport for a Trusted-LAN Endpoint
Added after M1. Same-host Ollama speaks plain HTTP over loopback, and it was
assumed a LAN endpoint would look the same. It does not have to.
A trusted-LAN Ollama may be served over **HTTPS with a certificate issued by a
private or local CA** rather than a public one — a self-hosted server that
terminates TLS for everything it exposes is the ordinary case, not an exotic
one, and it may offer no cleartext port at all. A v1 client that trusts only a
bundled public-CA list cannot talk to such a host, while `curl` and the user's
browser on the same machine can.
Therefore:
- production clients must verify against the **operating system's trusted CA
store** in addition to any bundled certificate list, so a CA the user has
installed on their own machine is honoured by this application too;
- certificate **and hostname** verification remain fully enabled;
- there must be **no "ignore TLS errors" / "insecure" option**, in the UI,
in configuration, or as an environment variable. A LAN endpoint the machine
does not trust is a configuration problem to fix at the OS level, not a check
to switch off;
- the endpoint URL must therefore accept `https://` on any port, not only
`http://…:11434`.
M1 implemented this (`backend/app/tlstrust.py`); see
`planning/reports/M1-IMPLEMENTATION-REPORT.md` §G.
@@ -1,6 +1,6 @@
# ADR 004 — Local-Only Production Default # ADR 004 — Local-Only Production Default
**Status:** Accepted; Phase 0B hardening requirements identified **Status:** Accepted; Phase 0B hardening requirements identified; testing consequence strengthened after M1
## Decision ## Decision
@@ -31,6 +31,27 @@ The selected AI-DnD base does **not** satisfy this requirement unchanged:
These are bounded production-hardening tasks rather than reasons to reject the fork. These are bounded production-hardening tasks rather than reasons to reject the fork.
## Testing Consequence
Strengthened after M1, which confirmed the failure mode this rule exists to catch.
**Offline behavior must be tested with a fresh cache/data state on a machine
with no route to the Internet.** Both inherited violations above were *first-use*
downloads: `tiktoken` caches its encoding to a temp directory, and the browser
caches Google's fonts. On any machine that had been online once, both were
invisible — the application appeared to work offline while depending on an
artifact an earlier online run had left behind. Neither was findable by static
analysis; each took an actually isolated run to surface.
Therefore an offline claim is only evidence when the test:
- runs on a network with **no route out and no external DNS**, verified before
the test rather than assumed,
- starts from a **fresh application data directory and a fresh cache**, so
nothing warmed by a previous run is available,
- exercises the **first** story turn, which is when a first-use download fires,
- observes actual network destinations rather than only the absence of an error.
## Consequences ## Consequences
The production application must avoid or remove: The production application must avoid or remove:
@@ -48,4 +69,11 @@ The production application must avoid or remove:
Production packaging must contain all runtime assets required for ordinary story use after the user has installed the intended local Ollama models. Production packaging must contain all runtime assets required for ordinary story use after the user has installed the intended local Ollama models.
Vendored runtime artifacts should be **integrity-verifiable where practical**: a
recorded source and a digest the application checks when it loads them, rather
than an opaque blob nobody can re-derive. A substituted or truncated artifact
should then fail loudly instead of silently changing behavior — a corrupted
tokenizer table, for instance, would quietly change every token count the
context budget is computed from.
The storyteller application should bind to loopback by default. Ollama should default to same-host loopback but may be explicitly configured to an approved trusted-LAN endpoint for v1. This LAN inference path does not authorize LAN exposure of the storyteller UI/API. Arbitrary public/Internet inference endpoints remain prohibited in normal v1 configuration. The storyteller application should bind to loopback by default. Ollama should default to same-host loopback but may be explicitly configured to an approved trusted-LAN endpoint for v1. This LAN inference path does not authorize LAN exposure of the storyteller UI/API. Arbitrary public/Internet inference endpoints remain prohibited in normal v1 configuration.
+29 -8
View File
@@ -1,7 +1,7 @@
# Adventure Storyteller Planning Package # Adventure Storyteller Planning Package
**Status:** Phase 0 complete; architecture selected; planning revision ready for review. **Status:** Phase 0 complete; architecture selected; **Milestone M1 implemented and accepted (2026-09-02)**.
**Production coding:** Not yet authorized. Review this package before preparing the first implementation prompt. **Production coding:** Underway, milestone by milestone. M1 is done; M2 is the next milestone to brief.
This package contains the current product requirements, final Phase 0 architecture decisions, detailed subsystem designs, acceptance tests, research evidence, and the production milestone plan for the local-only interactive-story project. This package contains the current product requirements, final Phase 0 architecture decisions, detailed subsystem designs, acceptance tests, research evidence, and the production milestone plan for the local-only interactive-story project.
@@ -153,14 +153,17 @@ Phase 0 research and spikes COMPLETE
Architecture/fork decision COMPLETE Architecture/fork decision COMPLETE
| |
v v
Planning package revision CURRENT REVIEW Planning package revision COMPLETE
| |
v v
Approve planning package Approve planning package COMPLETE
| |
v v
Prepare one implementation prompt Milestone M1 COMPLETE (2026-09-02)
for Production Milestone 1 fork + offline baseline see planning/reports/M1-*.md
|
v
Milestone M2 NEXT — brief not yet prepared
| |
v v
Implement and review milestone-by-milestone Implement and review milestone-by-milestone
@@ -168,6 +171,24 @@ Implement and review milestone-by-milestone
## Stop Rule ## Stop Rule
**Do not begin production coding from this package yet.** **One milestone at a time. Do not begin a milestone before its brief exists.**
The current action is to review the planning changes. No replacement Codex prompt has been prepared in this revision. M1 is complete and accepted; its evidence is in `reports/M1-BASELINE-REPORT.md`
and `reports/M1-IMPLEMENTATION-REPORT.md`. **No M2 brief has been prepared.**
The current action is to review the post-M1 planning corrections below before
writing one.
### Post-M1 corrections applied (2026-09-02)
Implementation evidence contradicted or under-specified six places in this
package, and a seventh was added on review. All seven are now corrected:
| Document | Correction |
| --- | --- |
| `DECISIONS/002-ollama-only-v1.md` | New section: a trusted-LAN Ollama may be HTTPS with a private CA; verify against the OS trust store; full certificate and hostname checking; no bypass option. |
| `DECISIONS/004-local-only-production.md` | New *Testing Consequence*: offline tests need a fresh cache and no route out. Vendored runtime artifacts should be integrity-verifiable. |
| `V1-ACCEPTANCE-TESTS.md` A05 | Pass conditions reworded around *accepted* history; explicit note that the user's submitted text is deliberately retained. |
| `V1-ACCEPTANCE-TESTS.md` A06 | Now requires a real second machine and an HTTPS endpoint with a locally issued certificate; a plain-HTTP LAN test is no longer sufficient evidence. |
| `V1-ACCEPTANCE-TESTS.md` §3 | Record CPU/GPU/RAM: cold model load on a CPU-only host exceeded the inherited 120 s timeout. |
| `BUILD-MILESTONES.md` | M1 marked COMPLETE with the capabilities it delivered; M2's endpoint-policy line reframed from inventing trusted-LAN support to narrowing it. |
| `TECHNICAL-DESIGN.md` §5 | Runtime boundary restated: the storyteller is loopback-only, inference may be same-host *or* trusted-LAN, and the two are independent. Adds the TLS/private-CA rule. |
+23 -1
View File
@@ -783,6 +783,26 @@ LAN access to the **storyteller browser UI/API** is different and remains a futu
Do not accidentally inherit storyteller LAN exposure because a candidate project binds to all interfaces. Do not accidentally inherit storyteller LAN exposure because a candidate project binds to all interfaces.
### Two different TLS questions — do not conflate them
Clarified after M1, which implemented one of these and not the other.
**Inbound TLS — serving the storyteller over HTTPS.** Deferred, and still
deferred. It only becomes a question if storyteller LAN access is ever added.
This is what "local certificate support" refers to in the deferred list further
down.
**Outbound TLS — verifying the certificate of a trusted-LAN inference host.**
**Implemented in M1 and required for v1.** A LAN Ollama is often served over
HTTPS with a privately issued certificate, so the storyteller must verify
against the machine's own CA store as well as any bundled list, with
certificate and hostname checking fully enabled and no bypass option
(ADR 002; `TECHNICAL-DESIGN.md` §5).
The storyteller remaining loopback-bound is unaffected by either. Outbound
verification is about who the storyteller is willing to *talk to*; inbound TLS
would be about who may talk to *it*.
## 54. Tailscale / VPN Access ## 54. Tailscale / VPN Access
Treat remote access to the storyteller UI/API like storyteller LAN access. Treat remote access to the storyteller UI/API like storyteller LAN access.
@@ -1167,7 +1187,9 @@ Potential later improvements:
- signed release builds, - signed release builds,
- dependency SBOM, - dependency SBOM,
- LAN authentication, - LAN authentication,
- local certificate support, - local certificate support **for serving the storyteller over HTTPS** — note
that *outbound* verification of a trusted-LAN inference host's certificate is
a separate matter, is required for v1, and was implemented in M1 (see §53),
- optional AppArmor/container confinement. - optional AppArmor/container confinement.
These are not required for initial v1 unless Phase 0B reveals a specific need. These are not required for initial v1 unless Phase 0B reveals a specific need.
+65 -12
View File
@@ -132,19 +132,59 @@ Accepted Story / Scene State
`Local-only` means user-controlled local infrastructure with no required Internet/cloud dependency; it does not require every process to share one host. `Local-only` means user-controlled local infrastructure with no required Internet/cloud dependency; it does not require every process to share one host.
Default same-host runtime path: The architecture has **two boundaries, and they are not the same boundary**. The
storyteller is loopback-only, always. Inference may be same-host or on a
specifically configured trusted-LAN machine. Wording that describes Ollama as
simply "loopback/local" collapses the two and understates the intended
deployment:
```text ```text
Browser -> local FastAPI application -> 127.0.0.1 Ollama Browser ──loopback──> storyteller (FastAPI + SPA), bound to 127.0.0.1
│
├── same-host Ollama on 127.0.0.1:11434 (default)
│
└── OR an explicitly configured trusted-LAN Ollama
on another user-controlled machine
http://<host>:11434/v1 or https://<host>/v1
``` ```
Supported v1 trusted-LAN inference path: Read that as three separate rules:
```text 1. **The storyteller's own listener is loopback, in every run path.** Dev
Browser -> local FastAPI application -> explicitly approved LAN Ollama host server, production server, and container alike. Nothing about the inference
``` choice changes it. Where a container must listen on `0.0.0.0` because a
published port cannot reach anything else, the port is published to the
host's loopback only.
2. **The inference endpoint is an outbound connection, chosen by the user.**
Same-host loopback is the default. A trusted-LAN host is a first-class,
supported v1 configuration — not a workaround and not a development-only
convenience.
3. **The two are independent.** Reaching a LAN Ollama never requires, and must
never cause, LAN exposure of the storyteller UI/API. There is no supported
v1 configuration in which the storyteller itself is reachable from the LAN.
The browser and storyteller API still remain loopback-bound by default. Supporting LAN inference does **not** expose the storyteller web application to the LAN. ### Transport to a trusted-LAN endpoint
A LAN inference host is often reached over **HTTPS with a certificate issued by
a private or local CA**, and may offer no cleartext port at all. This is
ordinary for a self-hosted server, so v1 must handle it rather than assume the
same plain HTTP that same-host loopback uses:
- outbound HTTPS verifies against the **operating system's trusted CA store** in
addition to any bundled certificate list, so a CA the user installed on their
own machine is honoured here as it is by `curl` and their browser;
- certificate **and hostname** verification stay fully enabled;
- there is **no "ignore TLS errors" option** anywhere — not in the UI, not in
configuration, not as an environment variable;
- the endpoint field therefore accepts `https://` on any port.
Prompts, story text, retrieved knowledge and embedding inputs all travel to
whichever inference host is configured, which is why it must be one the user
controls on a network they trust — and why the endpoint is always explicitly
configured, never discovered.
See ADR 002 (*Transport for a Trusted-LAN Endpoint*) and, for the demonstrated
deployment, `planning/reports/M1-IMPLEMENTATION-REPORT.md` §F.
Allowed future local paths may also include explicitly configured local media services. Allowed future local paths may also include explicitly configured local media services.
@@ -161,17 +201,30 @@ Production defaults must not require:
### 5.1 Known AI-DnD hardening work ### 5.1 Known AI-DnD hardening work
Phase 0B identified concrete inherited violations: Phase 0B identified concrete inherited violations, and M1 added a fifth. Items
1, 2 and 5 are **resolved**; items 3 and 4 remain open and belong to M2.
1. `tiktoken` attempts to download the `cl100k_base` encoding on first use. 1. ~~`tiktoken` attempts to download the `cl100k_base` encoding on first use.~~
- production packaging must include/cache the required encoding or replace the dependency path so first story use is offline. **Done in M1.** The encoding table is vendored in the tree and loaded
2. the SPA requests Google Fonts at runtime. directly, with its SHA-256 verified against the digest `tiktoken` pins, so no
- fonts must be self-hosted or replaced with local/system fonts and CSP tightened. code path in the tokenizer can reach the network.
2. ~~the SPA requests Google Fonts at runtime.~~
**Done in M1.** All three families are self-hosted, and the CSP names no
remote origin at all.
3. hosted/multi-user/auth/demo/analytics/Postgres/cloud-provider/QuickJS paths are unnecessary. 3. hosted/multi-user/auth/demo/analytics/Postgres/cloud-provider/QuickJS paths are unnecessary.
- remove them rather than merely hide them where practical. - remove them rather than merely hide them where practical.
- **Open — M2.** M1 removed nothing, so this surface is unchanged from the
fork point.
4. endpoint validation must reflect this product's threat model. 4. endpoint validation must reflect this product's threat model.
- same-host loopback Ollama is the default; an explicitly configured trusted-LAN Ollama endpoint is supported; arbitrary public/Internet model endpoints must be rejected or kept outside normal v1 configuration. - same-host loopback Ollama is the default; an explicitly configured trusted-LAN Ollama endpoint is supported; arbitrary public/Internet model endpoints must be rejected or kept outside normal v1 configuration.
- inference endpoint configuration must not change the storyteller's own loopback bind behavior. - inference endpoint configuration must not change the storyteller's own loopback bind behavior.
- **Open — M2.** The trusted-LAN path itself works as of M1; what remains is
deciding and enforcing which endpoints normal v1 configuration may name.
5. ~~outbound TLS verified only against a bundled public-CA list, so a LAN host
with a privately issued certificate was refused.~~
**Found and fixed in M1.** Not visible to Phase 0B: every run up to that
point used plain HTTP over loopback, where certificate verification never
happens. See *Transport to a trusted-LAN endpoint* above.
## 6. Browser UI Boundary ## 6. Browser UI Boundary
+59 -6
View File
@@ -64,10 +64,13 @@ Recommended environment:
- one installed narrator model, - one installed narrator model,
- one installed embedding model if semantic retrieval is enabled, - one installed embedding model if semantic retrieval is enabled,
- outbound Internet blocked after setup, - outbound Internet blocked after setup,
- fresh test data directory. - fresh test data directory,
- for A06, a second user-controlled machine on the trusted LAN serving HTTPS
with a locally issued certificate.
Record: Record:
- OS, - OS,
- **CPU (core count), GPU (or explicitly none), and RAM**,
- application commit/version, - application commit/version,
- Ollama version, - Ollama version,
- narrator model, - narrator model,
@@ -75,6 +78,14 @@ Record:
- browser, - browser,
- test date. - test date.
Hardware is not bookkeeping. A model's **cold load** time depends on it, and
M1 measured a cold `qwen2.5:3b-instruct` load on a GPU-less four-core host
exceeding the inherited 120-second client timeout — three times — while the
same turn completed in 6 to 9 seconds once the model was resident. A timeout
result is therefore uninterpretable unless the hardware and the warm/cold state
are recorded with it, and a pass on a GPU machine does not predict a pass on a
CPU-only one.
## 4. Standard Test Campaign ## 4. Standard Test Campaign
Create a campaign named: Create a campaign named:
@@ -284,9 +295,29 @@ Transcript and authoritative current state are restored.
5. Reopen campaign. 5. Reopen campaign.
### Pass ### Pass
- prior story remains intact, - **previously accepted history and state are unchanged** — every earlier turn,
- failed turn is not partially committed as accepted, its text and the authoritative state remain exactly as they were,
- user can retry. - **no AI response is accepted for the failed turn**: no partial or truncated
narration is committed, and the count of accepted AI turns does not move,
- the failure is reported to the user rather than swallowed,
- the user can retry and continue.
### Note on wording
"Nothing was committed" would be misleading, and this test should not be read
that way. The user's **submitted text is deliberately retained**: it is
committed before the model is called, so a model failure never discards what
the player typed. A failed turn therefore leaves the player's input at the head
of the story with no reply, and the total row count grows by one.
The invariant is about *accepted* history, not about row counts. What must
never happen is a partially generated AI response entering the story as though
it were accepted, or an earlier turn being altered or lost.
A test that asserts the story is byte-identical before and after will fail for
the wrong reason. Assert instead on the accepted prefix — for example, a digest
over every action up to the pre-failure head — and on the number of accepted AI
turns.
--- ---
@@ -296,13 +327,18 @@ Transcript and authoritative current state are restored.
### Preconditions ### Preconditions
- storyteller and browser run on machine A, - storyteller and browser run on machine A,
- Ollama runs on a separate user-controlled machine B on the trusted LAN, - Ollama runs on a separate user-controlled machine B on the trusted LAN —
**a genuinely separate machine**, not another container or namespace on
machine A,
- **machine B serves HTTPS with a certificate issued by a private/local CA**,
and that CA is installed in machine A's operating-system trust store,
- required models are already installed, - required models are already installed,
- outbound Internet access is blocked. - outbound Internet access is blocked.
### Steps ### Steps
1. Keep the storyteller UI/API bound to loopback on machine A. 1. Keep the storyteller UI/API bound to loopback on machine A.
2. Configure the storyteller's Ollama endpoint to machine B. 2. Configure the storyteller's Ollama endpoint to machine B, as an `https://`
URL using the hostname the certificate is issued for.
3. Verify model discovery/connection diagnostics. 3. Verify model discovery/connection diagnostics.
4. Generate at least three story turns. 4. Generate at least three story turns.
5. Trigger state extraction and embeddings/memory retrieval if enabled. 5. Trigger state extraction and embeddings/memory retrieval if enabled.
@@ -311,11 +347,28 @@ Transcript and authoritative current state are restored.
### Pass ### Pass
- story operation succeeds through the explicitly configured LAN Ollama host, - story operation succeeds through the explicitly configured LAN Ollama host,
- **TLS is verified, not bypassed**: the certificate chains to the CA installed
on machine A and the hostname is checked; no "insecure" option was used,
because none exists,
- no cloud API key or Internet access is required, - no cloud API key or Internet access is required,
- inference/model traffic goes only to the approved LAN host, - inference/model traffic goes only to the approved LAN host,
- storyteller UI/API remains loopback-bound, - storyteller UI/API remains loopback-bound,
- prompts, state, retrieved knowledge, and embedding inputs do not go to any unapproved destination. - prompts, state, retrieved knowledge, and embedding inputs do not go to any unapproved destination.
### Note on sufficient evidence
Added after M1. **A plain-HTTP LAN test is no longer sufficient evidence for
this test.** Certificate verification never happens over cleartext, so an
HTTP-only run cannot exercise the path that actually broke: against a real
HTTPS LAN host, the application refused an endpoint that `curl` and the browser
on the same machine accepted, because it verified against a bundled public-CA
list instead of the machine's own trust store (ADR 002, *Transport for a
Trusted-LAN Endpoint*).
A container or network namespace standing in for machine B is likewise not
sufficient on its own. It exercises the non-loopback address but typically
speaks plain HTTP, and it will hide exactly this class of defect.
--- ---
# B. Basic Story Interaction # B. Basic Story Interaction
+34 -3
View File
@@ -1,8 +1,39 @@
# Planning Package Version # Planning Package Version
**Package:** Adventure Storyteller Planning Package v2 **Package:** Adventure Storyteller Planning Package v2.1
**Revision date:** 2026-09-01 **Revision date:** 2026-09-02
**Status:** Phase 0 complete; architecture selected; production milestone plan approved for milestone-by-milestone implementation. **Status:** Phase 0 complete; architecture selected; **Milestone M1 implemented and accepted**; M2 not yet briefed.
## 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
`reports/M1-BASELINE-REPORT.md` and `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. This v2 package supersedes the earlier planning package produced before the final Phase 0B review and the trusted-LAN Ollama deployment clarification.