feat(skills): add project-local world-building skill

Author gritty, disposition-gated Margreave content (lore bible + hand-authored
quest/item/location/origin JSON) that reconciles against existing canon before
writing, holds the world's hard-by-default / warm-when-earned NPC tone, and keeps
the content_build --check gate green.

- SKILL.md: read-before-write workflow, read-only on existing canon (propose
  diffs, require approval), build+check+pytest as the done bar.
- references/schema.md: full bible + JSON contract, secrecy scale, gate model.
- references/tone.md: tone contract + NPC disposition-warmth model.
- scripts/canon_index.py: dumps existing ids for reconciliation.
- evals/: 3 test cases (all green in isolated-worktree runs).

Un-ignore /.claude/skills/ so project skills are versioned like code; all other
.claude/ dirs (root + nested api/client) stay ignored.

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:
2026-07-12 11:15:34 -05:00
parent a3506f7f02
commit b15bd2bb1e
6 changed files with 643 additions and 1 deletions

View File

@@ -0,0 +1,137 @@
---
name: world-building
description: >
Author gritty, dark, disposition-gated world content for Code of Conquest (the
Margreave). Use this WHENEVER the user wants to write, expand, or add lore,
storylines, plot threads, secrets, factions, regions, towns, dungeons, NPCs and
their knowledge/dialogue, quests, items, locations, or starting origins — even
if they don't say "world-building" or name the content/ folder. Triggers on
"write an NPC", "add a town/region/faction", "new quest", "a secret the party
can uncover", "expand the Tallow Reach", "flesh out Duncarrow", "someone the
player meets on the road", "cursed item", "give me a storyline", and the like.
The skill reconciles new content against existing canon (never contradicting or
silently changing it), writes it in the exact source format the content build
tool consumes, keeps NPCs true to the world's hard, uncaring tone (warm only
when disposition is earned), and verifies the build stays green. Do NOT use it
for engine/UI code, prompts (/api/prompts), or combat rules.
---
# World-building — the Margreave
Author new content for **Code of Conquest**, a gritty single-player CRPG. Read
`CLAUDE.md` (repo root) once per session for the charter — this skill assumes it.
## The one rule that governs everything you write
> **Code owns state. AI owns text.** (charter §2)
You are authoring *static content*, not runtime state. Facts, personas, places,
and knowledge chains are text the engine references by stable **id**. You never
write initial disposition numbers into world content, never gameplay logic. A
starting *value* (where the player begins, a seeded disposition) belongs to an
**origin**, never to a town or NPC.
## The two things that make this hard
1. **New content must not contradict old content.** The build tool checks
structure (ids resolve, secrecy routes correctly) but it CANNOT tell that you
just described the north road as untraveled when canon says elves walk it. A
contradiction ships silently and the DM narrates a broken world. So:
**read the existing canon before you write a word**, and treat every existing
file as read-only unless the user explicitly approves an edit (see below).
2. **The tone is specific and easy to get wrong.** Gritty, not grim. The world
is hard and does not care about the player — but an NPC who has come to trust
them becomes genuinely warm. Getting either pole wrong (grimdark misery, or
friendly-NPC-from-hello) breaks the world. See `references/tone.md`.
## Workflow — follow in order
Make a todo per step.
### 1. Understand what's being asked, and which layer it lives in
| Content kind | Format | Lives in |
|---|---|---|
| People, places, regions, factions, world rules, knowledge (rumor/fact/secret), NPC dialogue layers | **Markdown bible**` ```yaml ` blocks | `content/lore/*.md` (source) |
| Quests / story skeletons | Hand-authored JSON | `content/world/quests/` |
| Items (incl. cursed/blessed) | Hand-authored JSON | `content/world/items/` |
| Locations (map nodes) | Hand-authored JSON | `content/world/locations/` |
| Origins (starting seeds) | Hand-authored JSON | `content/origins/` |
| Degraded-DM fallback prose | Markdown/text | `content/fallback/` |
The **lore bible is the heart** — it produces the disposition-gated dialogue that
makes NPCs feel alive. `content/world/` and `content/server/` under `canon/`,
`topics/`, and `npcs/` are **BUILT from the bible — never hand-edit them.** The
JSON under `quests/`, `items/`, `locations/`, and `origins/` is hand-authored and
loosely schema'd (POC seeds); edit those directly.
If a storyline you're writing implies a quest, item, or location that doesn't
exist yet, say so and author the stub, or flag it — don't leave a dangling id.
### 2. Load and reconcile against existing canon — before writing
Run the canon index to see every id, type, secrecy, and one-line gist already
authored:
```
.venv/bin/python .claude/skills/world-building/scripts/canon_index.py
```
Read the entries your new content touches (people it references, the region it
sits in, secrets it brushes against). New content must slot into this without
contradiction. Reuse existing ids in `related:` rather than inventing parallel
ones. If your idea only works by *changing* something already canon — a fact's
body, a disposition, who knows what — **STOP.** Do not edit. Present the exact
before/after change and the reason, and get explicit approval first. New files
and new entries need no approval; edits to existing canon always do.
### 3. Draft in the correct format
- **Bible entries:** see `references/schema.md` for the full field-by-field
contract, the id/namespace/type rules, the secrecy scale, and the knowledge-gate
model. Match the voice and structure of `content/lore/duncarrow.md` — it is the
reference specimen.
- **Hand-authored JSON:** mirror the shape of the existing file in that folder
(`references/schema.md` documents each). Keep ids stable and lowercase-snake.
Write NPCs to the tone and disposition-warmth model in `references/tone.md`. A
hard NPC starts guarded (`cold`/`neutral`, sometimes reachable-`hostile`),
withholds more than a stranger would expect, and both *reveals more* and *softens
in manner* as the player climbs their ladder. That warmth is earned, never
default — it's what the five-rung gate system exists to deliver.
### 4. Build and verify — not done until green
The build regenerates `content/world/` + `content/server/` from the bible and the
`--check` gate is what CI enforces (`.github/workflows/content-build.yml`). Run,
from repo root, with the repo venv active (`source .venv/bin/activate`) — the
`content_build` package lives under `tools/`, so `PYTHONPATH=tools` is required:
```
PYTHONPATH=tools python -m content_build # regenerate world/ + server/ from lore/
PYTHONPATH=tools python -m content_build --check # must exit 0: fresh, valid, no orphans, no secrecy leaks
PYTHONPATH=tools python -m pytest tools/content_build/tests -q # schema + secrecy + cli coverage
```
(If `python` isn't found, the venv isn't active — use `.venv/bin/python`.)
If any step fails, read the `BUILD FAILED` / `STALE:` message — it names the
source file and line — fix the bible, rebuild, recheck. Never hand-edit the
generated JSON to make `--check` pass; fix the source. (Hand-authored JSON under
quests/items/locations/origins isn't built — the build tool ignores it. If you
touched those, just confirm they're valid JSON.)
### 5. Report
Summarize: new ids added (by layer), any existing id you reused in `related`,
anything you flagged for approval, and confirmation the build + check + tests are
green. Update `content/lore/canon-roadmap.md`'s Authored/Pending lists if you
added a new bible file or closed out a pending thread.
## Reference files
- `references/schema.md` — the complete bible + JSON schema, all validation rules,
the secrecy scale, the knowledge-gate model, worked examples. Read before
authoring bible entries.
- `references/tone.md` — the Margreave's tone contract and the NPC
disposition-warmth model. Read before writing any NPC or narrative body.