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

132 lines
6.1 KiB
Markdown

# 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:
```bash
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.