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
132 lines
6.1 KiB
Markdown
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.
|