Files
interactive-story/PROVENANCE.md
T
JesseMarkowitzandClaude Opus 5 d27ee34901 Docs: consolidate active planning and archive historical material
The planning package had grown to where a new agent could not tell what was
authoritative. Phase 0 execution prompts sat beside the specification; four
completed milestone reports sat beside the current one; and upstream AI-DnD's
own `plan/` build log and `docs/` project site still described a hosted,
scripted, multi-user product with accounts — every screenshot in it showed a
Scripts tab and a Sign up button, none of which has existed since M2.

`planning/archive/` now holds the history and says so in its own README:
`phase0/` for the research that chose AI-DnD, `milestone-reports/` for M1 and
M2, `decisions/` for ADR 008, the Phase-0-before-build gate Phase 0 satisfied.
`planning/reports/` holds only the current milestone's report, because that is
the one M4 planning has to read; it moves to the archive when M4's replaces it.

Deleted rather than archived: the Phase 0B execution prompts and the
handoff/status/summary documents, the Phase 0A discovery and triage reports,
upstream's `plan/` and `docs/` trees, and `frontend/README.md`, which was Vite's
template boilerplate. All of it is in Git history, and the two recommendation
reports carry every conclusion the deleted research reached.

Archived documents are kept verbatim. Paths written inside them point at where
those files were when the document was written, which is the point: an evidence
record that has been quietly edited is no longer evidence.

Active documentation is corrected where it pointed at the removed trees or
described removed capability as present. `DEVELOPMENT.md`'s "things M1 did not
touch" list had gone stale at M2 and claimed QuickJS scripting was still tested;
its test count was 604 against an actual 638. `README.md` loses the upstream CI
badge, which reported upstream's pipeline rather than this fork's, and a
reference to `backend/app/worldstate/engine.py`, a file that does not exist.
`planning/README.md` is rewritten as the documentation index.

New: `planning/PROJECT-SOURCES.md` and `planning/project-sources.txt`, the
manifest of what belongs in the ChatGPT project's Sources.

Source comments referring to the deleted trees are reworded; no behaviour
changes. 638 backend tests pass, frontend lints and builds, and a reference scan
over all 48 tracked Markdown files reports no unresolved path in active
documentation.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01NCbwH7yLGKsj1rhXXzKSCu
2026-09-03 14:33:07 -04:00

6.1 KiB

Provenance

This repository is the Adventure Storyteller production fork. Its application code comes from AI-DnD, and its planning package (planning/) is original to this project.

Upstream

Project AI-DnD
Repository https://github.com/parththakkar106/AI-DnD
Commit d72f7c1bda0f34fccd84afb7a25c34eb01c901de
Subject Stop paying twice for a block a retry can still throw away
Author date Mon 31 Aug 2026 16:14:24 +0000
Position tip of upstream/main on 1 Sep 2026, when the fork was taken
License MIT, © 2026 Parth Thakkar

The commit is the one pinned by planning/DECISIONS/009-ai-dnd-production-base.md after Phase 0B. It was not substituted for a newer upstream commit.

How the fork is wired

Upstream history is in this repository rather than copied out of it. The import is a merge of the pinned commit with --allow-unrelated-histories, so:

  • git log d72f7c1bda0f34fccd84afb7a25c34eb01c901de shows the real upstream history, not a squashed snapshot;
  • upstream code paths are unchanged (backend/, frontend/, …), so a later upstream commit can still be fetched and cherry-picked against matching files. Upstream's own documentation trees, plan/ and docs/, were removed on 2026-09-03: they described the hosted, scripted, multi-user product this fork is not. They remain in this repository's history and in upstream;
  • the planning package that predates the fork keeps its own history on the other parent of the merge.

To re-verify from a fresh clone:

git remote add upstream https://github.com/parththakkar106/AI-DnD.git
git fetch --no-tags upstream
git cat-file -t d72f7c1bda0f34fccd84afb7a25c34eb01c901de   # -> commit
git merge-base --is-ancestor d72f7c1bda0f34fccd84afb7a25c34eb01c901de HEAD && echo "in this history"

License

Upstream is MIT. LICENSE is upstream's file, unmodified, and the copyright notice stays with it. The MIT terms require that the notice travel with the code and with substantial portions of it; keep LICENSE in place in any redistribution of this fork, including a packaged build.

Work done in this repository after the fork is a derivative of that MIT-licensed code.

Vendored third-party assets

Both were added by Milestone M1 to remove a runtime Internet dependency. Each is redistributable and each has a regeneration path in the tree, so neither is an opaque binary nobody can rebuild.

backend/app/context/vendor/cl100k_base.tiktoken

The BPE merge table for OpenAI's cl100k_base tokenizer, used for context budgeting only — no model of OpenAI's is ever called.

  • Source: https://openaipublic.blob.core.windows.net/encodings/cl100k_base.tiktoken
  • SHA-256: 223921b76ee99bde995b7ff738513eef100fb51d18c93597a113bcffe865b2a7, which is the digest tiktoken itself pins for that URL, and which backend/app/context/encoding.py re-checks every time it builds the encoding.
  • Published by OpenAI for use with tiktoken (MIT).

frontend/public/fonts/*.woff2

Cinzel, Crimson Pro and Inter, Latin and Latin Extended subsets, as variable fonts. All three are licensed under the SIL Open Font License 1.1; the license text ships beside them as OFL-cinzel.txt, OFL-crimsonpro.txt and OFL-inter.txt, which is what the OFL requires of a redistribution.

Regenerate with python3 frontend/tools/vendor_fonts.py, which also rewrites frontend/src/styles/fonts.css.

What this fork changed in Milestone M2

M2 is subtractive. It reduced the inherited application to the intended single-user, local-first trust boundary. Nothing was added that upstream did not have, except the endpoint policy and the tests that hold these removals in place.

Removed in full: campaign scripting and the QuickJS sandbox; multi-user accounts, guest sessions, login, registration and the shared demo key; the visitor analytics tables, dashboard and beacon; the access log; per-IP and per-user rate limiting and quotas; Render deployment config; Postgres/Neon support; cloud inference providers and the API-key field; session-cookie signing and API-key encryption at rest.

Added: backend/app/endpoints.py, which decides what an inference endpoint may be, and a configurable model timeout.

Three database tables (scripts, adventure_scripts, analytics_daily, analytics_visitor_days, access_log) and four columns (adventures.script_state, settings.api_key, users.demo_turns_used, users.demo_turns_date) are left in place, unmapped or inert, so that an existing M1 campaign database opens unchanged. They are not product functionality and nothing reads or writes them.

What this fork changed in Milestone M1

Nothing was removed from upstream. The changes are the offline/locality hardening M1 called for; see planning/archive/milestone-reports/M1-BASELINE-REPORT.md for the evidence.

  • backend/app/context/encoding.py (new) and backend/app/context/builder.py — build cl100k_base from the vendored table instead of downloading it on first use.
  • frontend/index.html, frontend/src/index.css, frontend/src/styles/fonts.css (new), frontend/public/fonts/ (new), frontend/tools/vendor_fonts.py (new) — self-hosted fonts in place of the Google Fonts link.
  • backend/app/main.py — CSP narrowed to same-origin, with the two Google hosts dropped and object-src / base-uri / form-action added; woff2 registered so the self-hosted fonts are served with their real media type.
  • backend/app/tlstrust.py (new), backend/app/providers/openai_compatible.py, backend/app/routers/settings.py — outbound HTTPS verifies against the machine's own CA store as well as certifi's, so a trusted-LAN Ollama with a locally-issued certificate works. Verification is not relaxed.
  • start.sh, start.ps1, docker-compose.yml — the storyteller listener is explicitly loopback-bound.
  • backend/requirements.lock (new) — the exact tested dependency closure.
  • backend/tests/test_offline_assets.py and backend/tests/test_tls_trust.py (new) — regression tests for the above.
  • DEVELOPMENT.md (new) — environment setup and Ollama configuration.