Files
settled-reach/governance
jpmschweitzerandClaude Opus 5 284ce847c3 docs(governance): Q-124 — one door, domain split, and failures that teach
Jeroen's shape for the tooling CLI: move the Python into a package with a
proper domain split, one door that answers everything with help, and errors
that hand back instructions rather than a status.

The domain split turns out to be discoverable rather than invented. tooling/ is
85 top-level entries — 37 loose .py, ~36 extensionless executables, 11 dirs of
which only 6 hold anything — across four coexisting naming conventions. But the
domains are already encoded as filename prefixes: blender x14, atlas x8,
generate x7, check x7, then visual/validate/test x3 and
godot/garment/pql/install x2. Those prefixes are the subcommand groups, which
is what makes the consolidation mechanical enough to be safe.

Two constraints recorded against "a new prompt not an error code", because
taken literally each would break something:

- Exit codes stay. Four of these run in the pre-push hook, which fails a push
  ONLY by non-zero exit; a tool that explains itself and exits 0 silently
  disables its own gate. That exact failure was observed in clide today, where
  unsupported-format, no-such-file and unknown-subsystem all returned 0.
  So: code AND message, never either/or.
- It must not become literally interactive. Agents and git hooks have no TTY,
  and the tea scar is already written down — its prompts "crash in Claude Code
  (no TTY)", which is why every tea call passes all flags explicitly. Any
  prompt must be TTY-gated and suppressible.

pql was cited as the precedent and measured rather than assumed. The principle
holds there for unknown subcommands (full usage dump) and not for invalid
values: `ticket status <id> nonsense` says invalid without naming the six legal
values it knows, `ticket new` says "accepts 2 arg(s)" without naming which two.
The gap is the closed sets, and it is the more common failure. Logged upstream
as pql T-112 rather than worked around here — the bar for our CLI is the
stronger one: whenever the accepted set is known, print it.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-20 02:06:25 +02:00
..

Governance — Decisions, Questions, Rejected

Structured planning records for The Settled Reach. pql decisions sync parses these into .pql/pql.db; query them with pql decisions ….

Layout

Records live in three per-type subdirectories, split by domain:

governance/
  decisions/<domain>.md   # D-NNN — confirmed design decisions
  questions/<domain>.md    # Q-NNN — open questions (may resolve into a D or R)
  rejected/<domain>.md     # R-NNN — rejected alternatives (kept for the audit trail)

The parser infers record type from the parent subdirectory and domain from the filename stem. A ### D-NNN: Title (or Q-/R-) heading begins each record; - **Field:** value lines and inline [D-NNN](…#anchor) links carry the metadata and cross-references pql indexes.

Current domains: architecture, content, economics, perception, process, scope. Create a new <domain>.md in the relevant subdir when records land in a new domain.

Domain guide

When in doubt where a record belongs:

  • architecture — constrains how we build (engine, protocols, data structures, performance).
  • scope — defines what we build (game concept, feature scope, prototype shape).
  • perception — defines what the player observes or knows (camera, fog, LOS, audio).
  • content — defines narrative, NPCs, dialogue, setting, templates.
  • economics — the economics layer (currencies, commodities, corporations, simulation).
  • process — defines how the team works (workflow, commits, branches, reviews).

Cross-domain records live in one file with [D-NNN](../<subdir>/<domain>.md#…) links to the related domain.

Querying

pql decisions list                              # every record
pql decisions list --type confirmed --domain architecture
pql decisions show D-010 --with-tickets         # a record + its implementing tickets
pql decisions read D-238                         # full markdown body
pql decisions refs D-010                          # cross-references in/out
pql decisions coverage                            # decisions ↔ ticket coverage

Adding a record

  1. Claim an ID (no side effects): pql decisions claim D <domain> "title" (use Q for a question, R for a rejected alternative).
  2. Edit the appropriate file (decisions/<domain>.md, questions/<domain>.md, or rejected/<domain>.md). Follow the existing ### D-NNN: Title format.
  3. Commit. The pre-commit hook runs pql decisions validate (malformed-record gate) and stages the planning changelog.
  4. Update relevant agent briefings if needed.

When a question resolves, set its - **Status:** Resolved → [D-NNN](../decisions/<domain>.md#…) line in place — keep the Q-record for the audit trail rather than deleting it.

Maintained by Qatux.

Decisions

Open questions

Resolved questions

Rejected