Files
code_of_conquest_dnd/docs/superpowers/specs/2026-07-12-duncarrow-purge-design.md
Phillip Tarrant 9aa06d59d7 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
2026-07-12 15:11:14 -05:00

11 KiB

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 specimenSKILL.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 testtools/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.