docs(spec): Duncarrow purge — decouple scaffolding from infrastructure
Delete the Duncarrow scaffolding while preserving the schema/disposition-gate infrastructure it carries: reparent rule.disposition-ladder into a new mechanics.md, stand up a synthetic status:candidate specimen (validated but never emitted), repoint the skill/tests/evals. Zero real game content; the in-flight NPC redesign and the hand-authored POC seed JSON stay out of scope. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01HuHRPE7VfppUJEaoGBEUqZ
This commit is contained in:
171
docs/superpowers/specs/2026-07-12-duncarrow-purge-design.md
Normal file
171
docs/superpowers/specs/2026-07-12-duncarrow-purge-design.md
Normal file
@@ -0,0 +1,171 @@
|
||||
# Duncarrow purge — decouple scaffolding from infrastructure
|
||||
|
||||
**Status:** approved design, ready for implementation plan
|
||||
**Date:** 2026-07-12
|
||||
**Follows:** `2026-07-12-cosmology-and-worldbuilding-theme-design.md` §6 (which flagged this
|
||||
purge) and the merged cosmology (dev `df5ed2b`).
|
||||
|
||||
**Scope:** Remove the Duncarrow scaffolding content, preserve the schema/disposition-gate
|
||||
*infrastructure* it currently carries via a synthetic non-canon specimen, and author
|
||||
**zero real game content**. Deliberately minimal blast radius: nothing this spec produces
|
||||
is rebuilt when the NPC model or Margreave lore is later reworked.
|
||||
|
||||
---
|
||||
|
||||
## 1. Why this is more than a deletion
|
||||
|
||||
`content/lore/duncarrow.md` was authored as scaffolding to build the content schema + the
|
||||
world-building skill (see the cosmology spec §6). It is **not game story** and is slated
|
||||
for removal. But it is currently **load-bearing infrastructure** in five places, so a naive
|
||||
delete breaks the build, the skill, the tests, and the evals:
|
||||
|
||||
1. **Hosts `rule.disposition-ladder`** — required *exactly once* across all bibles; the
|
||||
build hard-fails without it.
|
||||
2. **The world-building skill's teaching specimen** — `SKILL.md:100` ("match the voice and
|
||||
structure of `content/lore/duncarrow.md` — it is the reference specimen"); `schema.md`
|
||||
(organize-like-duncarrow; "the ladder already lives in `duncarrow.md`"; "mirror the
|
||||
Crell chain 1→2→2→3→4"; the Mera Fenn reachable-ceiling example); `tone.md` (the
|
||||
"prosperous and orderly" body quote; "Mera Fenn is the model"; Old Teague).
|
||||
3. **A dedicated build test** — `tools/content_build/tests/test_duncarrow.py`, plus
|
||||
Duncarrow references in `test_model.py`.
|
||||
4. **The eval suite** — 3 of the world-building skill's evals (`evals/evals.json`) are
|
||||
built on Duncarrow (add-an-NPC-to-Duncarrow; contradict-the-Crell-chain;
|
||||
elves-beyond-Duncarrow).
|
||||
5. **`schema.md`'s inline worked example** ties `person.old-teague` to `town.duncarrow`.
|
||||
|
||||
The design separates the two roles Duncarrow conflates — **game story** (delete) and
|
||||
**schema teaching example** (preserve, synthetically).
|
||||
|
||||
## 2. The deletion is self-contained (verified)
|
||||
|
||||
- The hand-authored POC seed JSON (`content/origins/`, `content/world/quests/`,
|
||||
`content/world/locations/`, `content/world/items/`) references **none** of Duncarrow's
|
||||
bible ids (grep clean). It is not touched (see §7).
|
||||
- The cosmology bibles (`cosmology.md`, `the-seven.md`) reference no Duncarrow id.
|
||||
- `content/world/npcs/` is a shared dir: `brannoc_thane`, `cadwyn_vell`, `fenn` are legacy
|
||||
hand-authored (bare ids); `mera-fenn`, `mayor-oswin-crell`, `harn-blackwood` are
|
||||
**generated** from `duncarrow.md`'s `npc.*` entries. Deleting the source + rebuilding
|
||||
triggers the build's orphan-cleanup to remove the three generated ones (client + server)
|
||||
while leaving the three legacy ones. (This is the exact "generated-npc orphan-in-shared-
|
||||
dir" path the build tool already covers.)
|
||||
|
||||
So deleting `duncarrow.md` dangles no bible reference; the only follow-through is the
|
||||
build's own orphan cleanup, which is already implemented and tested.
|
||||
|
||||
## 3. Reparent the disposition-ladder → `content/lore/mechanics.md`
|
||||
|
||||
Create `content/lore/mechanics.md` and move `rule.disposition-ladder` into it **verbatim**
|
||||
(same `id`, `type`, `secrecy: 0`, `rungs: [hostile, cold, neutral, warm, trusted]`, body).
|
||||
|
||||
- **Home choice rationale:** the ladder is a **dialogue mechanic**, not cosmological lore
|
||||
(so not `cosmology.md`, despite the cosmology spec's loose suggestion) and not the
|
||||
specimen (which must stay disposable). `mechanics.md` is the permanent neutral home for
|
||||
mechanical `rule.*` entries.
|
||||
- The required-once invariant is preserved (moved, not duplicated). The ladder must land in
|
||||
`mechanics.md` **before** `duncarrow.md` is deleted, or an intermediate build fails.
|
||||
|
||||
## 4. The synthetic specimen → `content/lore/specimen.md`
|
||||
|
||||
Create `content/lore/specimen.md` — the skill's schema/disposition-gate teaching example,
|
||||
lifted from `schema.md`'s already-written *Old Teague* and cut free of its Duncarrow tie.
|
||||
|
||||
- **Entries:** one generic `place`, one guarded `person`, its `npc.*` interactive layer
|
||||
(`start_disposition: cold`, warms up), and one personal `fact` (secrecy 2) gated at
|
||||
`warm`. The Teague shape: guarded-then-warm, one earned personal reveal, no plot weight.
|
||||
- **Obviously-synthetic, non-Margreave ids** — e.g. `place.specimen-wharf`,
|
||||
`person.specimen-teague`, `npc.specimen-teague`, `fact.specimen-foreign-coin` (final ids
|
||||
are the plan's call, but they MUST read as "format example," not real content, and MUST
|
||||
NOT collide with existing ids like the `greywater_docks` seed). A header comment states
|
||||
plainly: *this file is a format specimen, not game canon.*
|
||||
- **`status: candidate`** — the build **validates** it (`--check` resolves its `related`
|
||||
and checks its gate against the ladder) but **emits nothing** to `content/world/` or
|
||||
`content/server/`. No synthetic NPC ships in the game bundle. This is the key property:
|
||||
the specimen teaches humans and stays build-honest, without polluting real content.
|
||||
- The specimen's gate references a ladder rung, so it depends on `rule.disposition-ladder`
|
||||
(now in `mechanics.md`) — resolves because the build parses all `content/lore/*.md`
|
||||
together.
|
||||
|
||||
## 5. Repoint the world-building skill (and improve it)
|
||||
|
||||
Duncarrow played two skill roles; split them across two stable targets:
|
||||
|
||||
- **Schema / disposition-gate STRUCTURE** → the **specimen**:
|
||||
- `SKILL.md:100` "match the voice and structure of `content/lore/duncarrow.md`" →
|
||||
point at `content/lore/specimen.md` (structure) and note cosmology for voice.
|
||||
- `schema.md`: "organize a file … like `duncarrow.md`" → `specimen.md`; "the ladder
|
||||
already lives in `duncarrow.md`" → "in `mechanics.md`"; "mirror the Crell chain
|
||||
1→2→2→3→4" → describe the ascending-secrecy chain generically (the specimen only has a
|
||||
single fact, so the chain example becomes prose guidance, not a pointer to a deleted
|
||||
chain); the Mera Fenn reachable-ceiling paragraph → reframe generically or onto the
|
||||
specimen; the inline worked example's `related: [town.duncarrow]` → the specimen place.
|
||||
- **Narrator VOICE / tone** → the **cosmology bodies** (permanent canon, strong dry-voice
|
||||
exemplars):
|
||||
- `tone.md` "prosperous and orderly place…" quote → a cosmology body quote (e.g. the
|
||||
Warden's "the oldest argument there is," or the Seven's "Most of the Margreave believes
|
||||
the Seven are real. Most of the Margreave is right.").
|
||||
- `tone.md` "Mera Fenn is the model" (fear-as-prickliness, guarded-then-warm) → the
|
||||
**specimen's** npc as the guarded-then-warm model; keep the mechanic, swap the name.
|
||||
- `tone.md` "Old Teague's 'dryness turns to something almost fond'" → the specimen npc
|
||||
(which is Teague) — keep, just ensure it points at the specimen, not Duncarrow.
|
||||
|
||||
Net effect: the skill's **voice** examples now cite real permanent canon and its
|
||||
**structure** example is a build-validated fixture — both strictly better than pointing at
|
||||
scaffolding.
|
||||
|
||||
## 6. Tests and evals
|
||||
|
||||
- **Tests:** migrate `test_duncarrow.py` and the Duncarrow references in `test_model.py`
|
||||
onto the **specimen** and/or **synthetic in-test fixtures**. Preserve the *behaviors*
|
||||
that mattered — secrecy routing (a secret body never reaches the client), gate/rung
|
||||
resolution, generated-npc orphan cleanup — but assert them against content that still
|
||||
exists after the purge. No test may reference a deleted id. Because the specimen is
|
||||
`candidate` (unemitted), routing/emit assertions belong on synthetic `canon` fixtures
|
||||
constructed in-test, not on the specimen; the specimen backs validation/resolution
|
||||
assertions.
|
||||
- **Evals:** rewrite the 3 Duncarrow-based `evals/evals.json` entries so they target
|
||||
surviving content:
|
||||
- add-an-NPC eval → author against the specimen's place / a generic setting.
|
||||
- contradiction eval → *don't let an NPC reveal the Warden's name* (or otherwise
|
||||
contradict cosmology canon) — cosmology now provides real canon to reconcile against.
|
||||
- elves-beyond-Duncarrow eval → a generic "start a new storyline in its own file" prompt
|
||||
(no Duncarrow dependency).
|
||||
|
||||
## 7. Out of scope (stays intact)
|
||||
|
||||
- Any **real** Margreave town, region, faction, NPC, quest, item, or origin.
|
||||
- The **NPC-model redesign** the user has flagged as in-flight — this spec must not depend
|
||||
on or pre-empt it.
|
||||
- The **hand-authored POC seed JSON** (`content/origins/deserter.json`,
|
||||
`content/world/quests/find_the_ledger.json`, `content/world/locations/greywater_docks.json`,
|
||||
`content/world/items/*`): no coupling to Duncarrow bible ids, and editing it pulls in the
|
||||
runtime/new-game construction surface. Left untouched. (If a later cycle retires the POC
|
||||
seeds, that is its own spec.)
|
||||
- **`faction.elves` and `region.the-tallow-reach`** are deleted with the rest (clean slate,
|
||||
per the design decision) — re-authored as real content later, not preserved as stubs.
|
||||
|
||||
## 8. Acceptance criteria
|
||||
|
||||
- `rule.disposition-ladder` lives in `content/lore/mechanics.md` (verbatim), exactly once
|
||||
across all bibles; `content/lore/duncarrow.md` no longer exists.
|
||||
- `content/lore/specimen.md` exists, `status: candidate`, synthetic non-canon ids, one
|
||||
place + one guarded `person`/`npc.*` + one `warm`-gated `fact`; validated by `--check`
|
||||
and **emitted nowhere** (no specimen JSON under `content/world/` or `content/server/`).
|
||||
- The generated Duncarrow artifacts (`mera-fenn`, `mayor-oswin-crell`, `harn-blackwood`
|
||||
across canon/topics/npcs, client + server; the Crell topic chain) are gone; legacy
|
||||
`brannoc`/`cadwyn`/`fenn` npc JSON remain.
|
||||
- No skill file, test, or eval references a deleted id or `duncarrow.md`; the skill's
|
||||
structure pointers target the specimen and its voice pointers target cosmology.
|
||||
- `PYTHONPATH=tools python -m content_build` regenerates cleanly; `--check` exits 0 (fresh,
|
||||
valid, no orphans, no secrecy leaks); `pytest tools/content_build/tests -q` green.
|
||||
- Cosmology + the-seven content and the hand-authored POC seed JSON are unchanged.
|
||||
- `content/lore/canon-roadmap.md` updated (Duncarrow removed; ladder → mechanics.md;
|
||||
specimen established).
|
||||
|
||||
## 9. Blast-radius summary (why this scoping)
|
||||
|
||||
Everything authored here is either permanent infrastructure (`mechanics.md`, the ladder's
|
||||
home) or an explicitly disposable teaching fixture (`specimen.md`) — plus doc/test/eval
|
||||
pointer swaps. When the NPC model and real Margreave lore are reworked, **none of this is
|
||||
rebuilt**. The only thing that would force the specimen to change is a change to the `npc.*`
|
||||
**schema itself** (a new required field / a changed gate model) — which would ripple through
|
||||
*all* content regardless, so it is not a blast radius this spec can or should try to avoid.
|
||||
Reference in New Issue
Block a user