Files
settled-reach/governance
jpmschweitzerandClaude Opus 5 4b75be5975 fix(simulation): PR #218 review round — real-body evidence, D-211, derived bound
Three findings from Hoshe (QA) and Tyre (architecture), plus a bug the first
of them uncovered.

HOSHE — the headline evidence lived only in a deleted scratch scan. All nine
tests used synthetic fixtures, so nothing committed held the "46 of 109
synthetic placements in water" claim on real data. Two tests now do. The
T-1206 verification scan itself is committed as an #[ignore]d full-corpus
test (267 bodies, run with --ignored), which also makes the recalibration
instruction on the search bound executable rather than aspirational; a fast
test pins the bodies it identifies.

That scan promptly caught a bug in its own first draft, and it is the reason
this commit is worth reading. `CascadeSnapshot::terrain_analysis` is
transient — the cascade nulls it the moment DistrictProfile and RoadGraph are
done (D-203/T-1048, ~2 MB a body) — so it is ALWAYS None on a returned
snapshot, whatever cascade_snapshot_for_body's doc-comment implies. Reading
the ocean mask off the snapshot and skipping when absent therefore skipped
every body while reporting success: 267 bodies "scanned", 0 findings, a green
assert over an empty set, in 697 seconds. Terrain is now re-derived through
the same run_layer1_with_moisture call the cascade used, reproducing the grid
the placements were computed against.

Two habits caught it, both prompted by Hoshe's finding: a vacuity guard that
refuses to pass when no synthetic placement was seen, and counters that stop
"none found" and "never got that far" from looking identical. Corrected
figures at seed 42: 267 bodies, all reaching Layer 3, 344 placements, 109
synthetic, 0 in water — the synthetic count matching the original scan, so
the claim is reproducible now rather than anecdotal.

TYRE 1 — MAX_LAND_SEARCH_RING was justified as grid_h/2 but written as a
literal 128, leaving the 512x256 coupling implicit. It is now derived from
the grid in scope, so the value cannot drift from its own rationale. On the
current working grid it evaluates to exactly 128: no behaviour change, and
the byte-identical-placement guarantee is untouched. Recalibration owner
recorded.

That derivation does change one test. nearest_land_cell_clamps_rows_no_wrap
uses a 16x16 fixture, so its bound drops 128 -> 8, which now sits BETWEEN the
clamped distance to the far pole (15) and the wrapped one (1). The assertion
moves from position to absence and gets sharper for it: previously both
implementations returned Some((15,0)) and only the position could be pinned;
now any Some at all proves rows wrapped.

TYRE 2 — D-211 carried no note though its behaviour changed. Dated amendment
added: step 4's outcome set is no longer total (synthetic overflow may now
resolve to a defined SKIP), and step 5's warning fires for a new legitimate
reason. No re-decision needed — position remains a pure function of seed and
terrain — and the dead-end cross-reference to D-210's closure is now a live
anchor.

Full cargo test green (30 binaries).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-06 17:55:23 +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