Files
code_of_conquest_dnd/tools/content_build/rungs.py
Phillip Tarrant f84e55ab4b fix(content-build): --check orphan detection; canon secrecy-0 + value-type guards
- --check now detects orphaned/stale build artifacts in build-owned dirs
  (client canon/ + topics/ fully owned; client npcs/ shared with legacy
  hand-authored files, only npc.* ids are treated as build-owned)
- resolve() enforces the schema rule that canon entities must be secrecy 0
- resolve() and ladder_rungs() guard against malformed value TYPES (non-int
  secrecy, non-list related/rungs) raising BuildError instead of crashing

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01HuHRPE7VfppUJEaoGBEUqZ
2026-07-11 19:01:28 -05:00

24 lines
870 B
Python

"""The rung vocabulary, sourced from the bible's disposition-ladder entry. The
bible owns rung names/order; band NUMBERS live in client code and never here."""
from .errors import BuildError
from .model import Entry
LADDER_ID = "rule.disposition-ladder"
NEVER = "never"
def ladder_rungs(entries: list[Entry]) -> list[str]:
ladders = [e for e in entries if e.id == LADDER_ID]
if len(ladders) != 1:
raise BuildError(
f"exactly one '{LADDER_ID}' entry required, found {len(ladders)}")
if not isinstance(ladders[0].rungs, list) or not ladders[0].rungs:
raise BuildError("disposition-ladder needs a non-empty 'rungs:' list",
source=ladders[0].source, entry_id=LADDER_ID)
return list(ladders[0].rungs)
def legal_gates(entries: list[Entry]) -> set[str]:
return set(ladder_rungs(entries)) | {NEVER}