Commit Graph
100 Commits
Author SHA1 Message Date
jpmschweitzerandClaude Opus 5 d5e617eff6 docs(simulation): PR #218 round 3 — the round-2 fix outran its own documentation
Three findings, all doc-accuracy, and all the same root cause: folding the
spacing predicate into the ring walk changed what three comments describe, and
two of those comments were written by this same PR one round earlier.

TYRE 1 — road_graph.rs's T-1206 gap-closure comment cited `nearest_land_cell`,
which round 2 made `#[cfg(test)]`. A reader chasing that name lands on a
test-only function and reasonably wonders whether they are looking at dead
code. Repointed to `nearest_cell_matching`, and the paragraph's closing claim
that "T-1206 guarantees the placement pixel is land" is corrected: it has been
land-AND-spacing-or-skip since round 2.

TYRE 2 — `max_land_search_ring`'s doc named the same test-only wrapper as the
thing that walks the bound. It now names the production consumer and both
callers.

TYRE 3 — the D-211 amendment was written in round 1, before round 2 existed,
and still described a land-only correction. It now carries a dated refinement
recording what the code actually does: the walk satisfies BOTH of step 4's
promises in one search, and SKIP therefore also fires where land exists but
none of it clears spacing within the bound. The no-re-decision conclusion is
unaffected — position remains a deterministic, non-fabricated function of seed
and terrain — and the refinement notes the spacing promise is step 4's alone,
since Tier A/B/C placements sit on their matched attractor and were never
subject to it.

HOSHE's three findings were the same three hunks, observed uncommitted while
the review ran: accurate content, but not in the branch tip, so the PR would
have merged a governance record that misdescribes its own commit. That is this
commit.

Both reviewers independently confirmed what the round-2 fix claims. Tyre traced
the ring geometry and tie-break order by hand against the spacing predicate;
Hoshe re-ran the full 267-body corpus scan live (850s) and reproduced the
figures exactly — 267 bodies, 267 reaching Layer 3, 344 placements, 109
synthetic, 0 in water, 0 spacing violations.

The shared-ring-search-helper retraction is confirmed and settled, with NEW
grounds rather than a restatement: round 2 strengthened the case for keeping
them separate, since this walk is now parameterized by an arbitrary predicate
over native u16 terrain coordinates while road_graph's is a RouteGrid method
over downsampled routing cells with a fixed cost test and an unrelated bound.

22 module tests green; clippy and fmt clean.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-08 10:53:33 +02:00
jpmschweitzerandClaude Opus 5 fc55bd897f fix(simulation): PR #218 round 2 — the guard was spending D-211's spacing promise
Hoshe and Tyre independently found the same defect, neither having seen the
other's review. They were right.

THE SPACING REGRESSION. synthetic_attractor's walk picks a candidate that
satisfies MIN_SPACING against every already-placed city, and the ocean
correction then moves that candidate up to h/2 = 128 cells with no
re-validation. D-211 step 4 promises the synthetic attractor is placed "at a
position that respects minimum city spacing" — the fix was buying the land
half of that promise with the spacing half. road_graph::collapse_colocated is
no safety net either: it dedupes by name, not position.

The spacing predicate now goes INTO the ring walk (nearest_cell_matching)
rather than running before it, so the search returns the nearest cell
satisfying land AND spacing, with the same tie-break order and the same
degrade-to-skip. A predicate on the existing walk, not a second walk.

Unmeasured, and stated rather than implied: whether this was ever a LIVE
violation or only a latent one. The old behaviour was replaced before it was
measured. What the corpus does say is that 12 of the 13 bodies showing any
sub-MIN_SPACING pair carry no synthetic placement at all.

AND THE FIRST VERSION OF THAT FIX OVER-ASSERTED. Checking MIN_SPACING across
ALL placement pairs found 13 violations corpus-wide, none of them the guard's
doing: the promise is step 4's alone, and matched placements (Tier A greedy,
Tier B/C Hungarian) sit on their terrain attractor, never subject to it. Two
real river mouths 12 cells apart is geography. Shipping that assertion would
have failed the gate and blamed this guard for pre-existing placements. Both
checks are now scoped to pairs involving a synthetic placement, with the 13
matched-pair proximities recorded in-code so they are not re-litigated.

Corpus, both invariants: 267 bodies, 267 reaching Layer 3, 344 placements,
109 synthetic, 0 in water, 0 spacing violations.

ALSO FIXED:
- t1206_verification_scan could still pass vacuously (Hoshe). The fast test
  got bodies_loaded>0 / synthetic_seen>0 guards last round; the scan — the one
  test whose entire purpose is being the re-runnable evidence — did not, and
  !bodies.is_empty() only proves the directory listing worked. Both added.
- cascade_snapshot_for_body's doc-comment claimed the snapshot "still carries
  the transient TerrainAnalysis" (Tyre). It is always None for a full-cascade
  call. Corrected in place, with the re-derivation recipe and a note that this
  sentence cost a false-clean 267-body scan.
- The passthrough test's comment described a land-island fixture and claimed
  (0,0) is not returned; the fixture is ta_all_land and the test asserts (0,0)
  IS returned (both reviewers). Rewritten to match reality.
- max_land_search_ring's cost note said ~(h/2)^2 = 16k candidates (Hoshe).
  That is one quadrant's area, not cumulative ring cost: sum of 8r over
  1..=128 is 66,048. Conclusion unchanged; the arithmetic is the executable
  recalibration rationale, so it has to be right.
- The fast test ran 25.8s, close to the long pole of the whole --lib suite
  (Hoshe). Trimmed 6 bodies to 3: 13.0s. Not to one — synthetic_seen>0 needs
  only one body, but resting on one is how the first draft ended up depending
  on GJ903c alone.

RETRACTED: the shared-ring-search-helper finding. Round 1 ruled duplicate-
over-share CORRECT for this walk and said so "stated so it isn't
re-litigated"; round 2 asks to factor it with no new evidence and no change to
either implementation. Fixing the spacing gap by predicate rather than by a
second walk moves that direction anyway.

Full cargo test green (40 binaries).

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-08-07 09:49:39 +02:00
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
jpmschweitzer e52aa027b3 Merge remote-tracking branch 'origin/main' into ocean-guard-synthetic 2026-07-26 15:28:34 +02:00
jpmschweitzerandClaude Fable 5 b58b02c98a chore(meta): pql changelog — idmap row (T-1206 flow)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:28:25 +02:00
jpmschweitzerandClaude Fable 5 dbd5c6c4f2 fix(simulation): synthetic-overflow placements get the ocean-mask guard (T-1206)
synthetic_attractor now takes the terrain analysis and land-corrects
its pure-arithmetic position via a bounded nearest-land ring walk
(T-1116's pattern: row-major tie-break, column wrap, row clamp,
MAX_LAND_SEARCH_RING=128 sized empirically — real polar ocean bands
push nearest land up to 125 cells). Land positions pass through
UNTOUCHED — verified by direct before/after scan of all 267 real
bodies: 63 land-arithmetic placements byte-identical, and every
golden/determinism harness passes unchanged. The gap was real and
widespread: 46 of 109 synthetic-overflow placements sat in open water
at seed 42 (e.g. GJ903c at a genuine polar ocean cell); post-fix zero,
with all 109 preserved (confirmed at a second seed). Degradation is
defined and pinned: no land within the bound -> the synthetic
attractor is skipped and Phase 5's existing not-placed warning
reports it — never a panic, never a fabricated water position (the
bound never triggers on any scanned real body). 9 new unit tests;
road_graph's anchor comment and the D-210 amendment record the gap
CLOSED (validated).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:27:43 +02:00
jpmschweitzerandClaude Fable 5 dc403d7f73 chore(meta): changelog + pql — T-1197 done (PR #217 merged, araminta re-accepted)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:24:26 +02:00
jpmschweitzer 3821e6718f Merge remote-tracking branch 'origin/main' into header-ghost-fix 2026-07-26 15:21:11 +02:00
jpmschweitzerandClaude Fable 5 c431780164 fix(client): fog perf test measures min-of-7, not median-of-5 (T-1210 done)
Three flakes in one day (0.549/0.503/0.638 vs the 0.5ms budget) proved
median-of-5 (T-1092's mitigation) insufficient when a concurrent cargo
build inflates all samples together. The assertion asks whether the
CODE meets the D-059 budget — load can only inflate wall time, never
deflate it, so the minimum is the least-noise estimator of code
capability, while a real regression shifts the minimum too. Budget
unchanged; regression-catching power preserved. 46/46 verified.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:17:51 +02:00
jpmschweitzerandClaude Fable 5 a4d9a4fa09 fix(ui): PR #217 review fixes — derived legend offset, 960x540 goldens, non-overlap tests
The legend's reposition() now derives its Y from the header panel's
MEASURED bottom plus a named 12px gap (new accessors on the viewer;
deferred recompute so it reads settled layout, refreshed on header
content change) — the old hardcoded 60.0 sat 17px inside the wrapped
header's real 77px bottom, fusing the panels. Pixel-proven at the
evidence center: bottom=77.0, legend top=89.0, gap=12.0 exact. All 13
goldens regenerated at the DOCUMENTED 960x540 (the 1280x720 rider was
my own CLI flag, not a config; PIL-verified) with two-run byte
stability. Two structural tests pin the header/legend relationship
(T-1192 precedent), proven failing-first against the old constant
(-17.0px reported), and the legacy test that pinned the literal 60.0
now asserts the derived relationship so it cannot re-enforce drift.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 15:13:11 +02:00
jpmschweitzer 34ecdad46f Merge remote-tracking branch 'origin/main' into header-ghost-fix 2026-07-26 14:47:21 +02:00
jpmschweitzerandClaude Fable 5 0a51f98666 chore(meta): pql changelog — T-1197 to review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:47:13 +02:00
jpmschweitzerandClaude Fable 5 41144f317f fix(ui): Atlas header gets its implant panel scrim — legible on any terrain (T-1197)
Root cause was not the suspected fade race — no animation exists
anywhere under client/ui/implant (grep-proven, and settle+2 vs
settle+90 captures were byte-identical). _build_screen_header() was
the single ImplantHeader call site in the codebase that added the
header bare instead of through ImplantPanel.add_component(), so its
fixed light-gray text washed out against pale terrain (Quarter upland
scatter, District olive) while reading fine on dark ocean. Wrapped in
an ImplantPanel like every sibling — the theme's panel_bg scrim makes
it legible everywhere. One committed golden (atlas_GJ820Bc_District)
already carried the ghosting baked in, confirming the bug was static;
all 13 goldens regenerated per the header change, two independent
live-server runs byte-identical (T-1157 stability discipline).
Verified live at the original evidence center: header crisp at
settle+2/+30/+90.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:46:55 +02:00
jpmschweitzerandClaude Fable 5 59d6ff57c3 chore(meta): pql changelog — batch 9 activated (T-1206/dudley, T-1197/stig)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:36:07 +02:00
jpmschweitzerandClaude Fable 5 47279184d2 chore(meta): changelog + pql — batch 8 closed (T-1098 done via PR #216)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:30:05 +02:00
jpmschweitzerandClaude Fable 5 9c5aa79852 fix(simulation): PR #216 review fixes — footprint-wins enforcement, discriminating tests
Finding 2 became a real code fix: interstitial_fill_into now enforces
the footprint-wins conflict rule (column_has_voxel range probe) — the
FilledChunk absence contract was previously a documented promise the
code didn't keep against conflicting inputs; pinned by a fully-
overlapping-leaf test asserting per-tile resolution. The tautological
overlap test replaced with a real rects_overlap() geometric helper
(itself sanity-tested) applied pairwise. The degenerate-setback fix is
now a standalone pure fn shrink_lot_or_interstitial with four boundary
tests — honestly documented as unreachable from live traffic today
(every min_lot exceeds every setback), a robustness guard for future
recalibration. Both sub-chunk clip tests now reconstruct the full
32-tile union across the seam (disjoint + complete), including the
pre-existing footprint clip test (leave-cleaner). Brief's ChunkLayout
claim tightened to the verified no-production-consumer statement.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:28:40 +02:00
jpmschweitzer 5b5cdc85a3 Merge remote-tracking branch 'origin/main' into interstitial-fill 2026-07-26 14:13:31 +02:00
jpmschweitzerandClaude Fable 5 d49871e22d chore(meta): pql changelog — T-1098 to review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:13:24 +02:00
jpmschweitzerandClaude Fable 5 1d676a91f8 feat(simulation): interstitial fill — ground-tile character between building footprints (T-1098)
The BSP leaves that lose the D-233 coverage roll in
subdivide_block_footprints were computed and discarded; they are now
surfaced as the interstitial rect set (BlockSubdivision), making the
ground-plane classification exhaustive by construction: footprint /
interstitial / street-margin-or-reserved. FillChunk carries the leaves
plus a minimal BlockFillContext (interstitial_character + setback_tier,
re-derived at block level via the existing pure fn); FilledChunk gains
a sparse interstitial map whose absence contract is stated on the
struct (missing key = footprint/street/reserved, never unknown). The
pure resolution maps OperationsSurface (D-233) first, else setback_tier
onto five of D-235's seven interstitial values — dock_slip/market_pad
have no specified trigger in the record and point at T-1209 rather
than an invented mapping. Design brief with the geometry model at
docs/architecture/interstitial-fill-t1098.md (lead-approved
checkpoint). Bonus fix: a degenerate setback shrink previously vanished
from BOTH lists silently; it now falls through to interstitial. 14 new
tests; full cargo test green incl. all golden harnesses; purity per
T-987 (plan-time compute, pre-resolved work items, no cache reads).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 14:13:08 +02:00
jpmschweitzerandClaude Fable 5 879c9dfb60 fix(briefings): correct five more f4c72e148 mis-citations in gestalt.md (T-1205 done)
D-130->D-131 (broad life-verb vocabulary, x3) and D-118->D-133 (skills
affect outcome, x2), each verified by full record-body match and lead
spot-check. The T-1205 audit body-matched all 66 unique decision ids
across the remaining 11 briefings — the other 10 are citation-clean.
Final f4c72e148 tally: 16 mis-citations across 6 of 18 briefings, all
fixed (T-1199 + T-1205). Follow-ups: T-1208 (eight wholesale-stale
briefings, rewrite backlog), and tiger.md confirmed deleted/off-roster.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:49:59 +02:00
jpmschweitzerandClaude Fable 5 447033857c chore(meta): pql changelog — batch 8 activated (T-1098/dudley, T-1205/clerk)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:44:16 +02:00
jpmschweitzerandClaude Fable 5 63ec09b089 chore(meta): changelog + pql — batch 7 closed (T-1116 done via PR #215; T-1207 Wave-2 overlays filed)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:40:28 +02:00
jpmschweitzer 8e82bcafd0 Merge remote-tracking branch 'origin/road-routing-coastal-fix' 2026-07-26 13:39:28 +02:00
jpmschweitzerandClaude Fable 5 a378ef862c chore(meta): pql changelog — T-1206 filed (synthetic-overflow ocean-guard gap, from PR #215 review)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:36:26 +02:00
jpmschweitzerandClaude Fable 5 de8bcf4ebb fix(simulation): PR #215 review fixes — hop-unit surcharge, D-210 amendment, citation + gap
The surcharge is now COASTAL_ACCESS_SURCHARGE_HOPS_PER_RING=1 added
directly to length_cells (a pure hop count) — the old cost-unit
constant div_ceil'd through MIN_CELL_COST silently produced 4 hops per
ring, worst-case +24 (double the waypoint threshold) for physically
short edges; worst case is now 6. A formula-pinning test asserts both
the arithmetic and the constant. GJ251c's repro tightened to the
documented 2 edges. The always-land citation now points at the real
guarantee (features.rs::extract_attractors, D-209) — and checking the
D-211 Phase-4 synthetic-overflow path exposed a real gap: it has no
ocean-mask guard at all (T-1206 filed); documented, not papered over.
D-210 gains a dated amendment recording the surrogate-anchor-at-cost
carve-out and the relaxation-over-nudge adjudication. The bare 100
dependency dissolved with the unit fix. Edge counts on both repro
bodies verified unchanged (reachability was never affected).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:34:43 +02:00
jpmschweitzerandClaude Fable 5 0039bda184 style(simulation): cargo fmt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:19:02 +02:00
jpmschweitzerandClaude Fable 5 1ec5cb4fd5 fix(simulation): clippy — erasing_op row-major literals, range-contains in T-1116 tests
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:16:54 +02:00
jpmschweitzer 5dd703ac6f Merge remote-tracking branch 'origin/main' into road-routing-coastal-fix 2026-07-26 13:13:52 +02:00
jpmschweitzerandClaude Fable 5 8247ba1ded fix(simulation): coastal-cell routing relaxation — roads return to water-heavy bodies (T-1116)
A routing cell folds up to 64 native pixels, so a coastal settlement's
own land pixel (placement always filters !ocean_mask) can sit inside a
water-majority cell that RouteGrid marks IMPASSABLE — and astar()
hard-returned None for every pair touching it, zeroing whole road
graphs (GJ251c: all 3 placements; GJ380c: Sethvale). The fix relaxes
only the start/goal anchor lookup: nearest_passable_cell (ring BFS,
deterministic row-major tie-break, bounded at COASTAL_ANCHOR_MAX_RING=3)
finds a surrogate anchor and prices it via COASTAL_ACCESS_COST_PER_RING
— a short, honestly-costed access road, never a free water crossing.
IMPASSABLE semantics untouched everywhere else (D-210 transit costs,
open-ocean). The placement-nudge alternative was rejected: it would
move Layer-3 state D-211 promises is seed-derived, for no gain.

Boundary semantics pinned by test: exactly-half-water cells stay
passable (strict-majority rule); a settlement with no passable cell
within the search ring degrades to an isolated 0-edge node, never a
panic or fabricated route. Failing-first repro on real bodies
(GJ251c 0->2 edges, GJ380c 0->1) via the real cascade entry point,
plus same-seed determinism. Full cargo test green; believability and
cascade goldens verified unaffected (Layer-2-only change).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:05:35 +02:00
jpmschweitzerandClaude Fable 5 f60cb1b3b9 chore(meta): changelog — T-1204 done (PR #214 merged, first production assets)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:04:55 +02:00
jpmschweitzer c9eefe9efe Merge remote-tracking branch 'origin/furniture-promotion' 2026-07-26 13:04:33 +02:00
jpmschweitzerandClaude Fable 5 82d44cf483 docs(assets): codify the authored-footprint rule (araminta ruling, PR #214)
footprint_tiles is an authored value, never derived from normalized
mesh geometry — [1,1] defaults only for plausibly-single-tile classes;
ordinarily-multi-tile classes require an explicitly stated footprint at
promotion. Her exact wording in furniture-props.md §3; conventions.md
§4 gains the authored-not-derived sentence pointing at the full rule
(and a pre-existing 'Single Sunday-tile' typo fixed in passing). The
[1,1] values shipped for the four promoted items stand as ruled.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 13:03:55 +02:00
jpmschweitzerandClaude Fable 5 d20ae38b74 chore(meta): pql changelog — T-1204 to review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 12:55:43 +02:00
jpmschweitzerandClaude Fable 5 2f87c1a65f data(assets): promote the four spike GLBs — first production environment assets (T-1204)
table_baroque, chair_modernist, desk_scifi (furniture, with mask
sidecars) and lion_statue (props, non-tintable) enter
client/assets/models/ under the category-first convention, byte-
identical to the spike sources (MD5-verified; spikes/ untouched,
vw_beetle excluded per the Q-067 deferral). Postprocess verified
already-applied by Blender node-graph inspection (mat_primary,
roughness=1.0/specular=0.0 shader inputs — the convenience properties
read stale defaults, the graph is authoritative), so not re-run. All
four registered in manifest.json at 'planned' with footprint_tiles
[1,1] (a flagged judgment call — normalized spike geometry erases
real-world scale; the brief ruling goes to araminta in review).
In-engine proof: clean headless import + ResourceLoader load +
instantiate for all four. Discovery documented in conventions.md §2 +
glb-gen SKILL.md: Godot externalizes the GLB's embedded texture as a
<model>_Image_0.png sidecar referenced by binary UID — it must be
committed or loading breaks with an undiscoverable dependency error.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 12:55:28 +02:00
jpmschweitzerandClaude Fable 5 1f199b9717 fix(briefings): correct eleven decision-id mis-citations from the f4c72e148 pass (T-1199)
The 2026-03-13 'update all 18 briefings' commit transcribed a family of
adjacent-id slips while summarizing the Where's the Fun? workshop batch,
copied forward by every later maintenance pass: D-126<->D-134 swapped,
D-136 written as D-131, D-137 as D-136, D-130 as D-131, D-120 as D-137.
Fixed in gore/mellanie/ozzie/stig/nigel briefings; every correction
verified against the record's actual body (D-130's emergent-moral-arc
and D-120's no-skill-ceiling were resolved beyond the clerk's audit by
body-matching — the nigel D-137 fix would otherwise have created
contradictory citations in one file). Governance records untouched
(they were always correct); sprint archives verified already-correct.
Remaining 13 briefings from the same commit: T-1205.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-26 12:50:56 +02:00
jpmschweitzerandClaude Fable 5 74e95148ae chore(meta): pql changelog — batch 7 activated (T-1116/dudley, T-1204/justine, T-1199/clerk; Q-119 narrow ruling on T-961)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:16:24 +02:00
jpmschweitzerandClaude Fable 5 3f63ccf8ce chore(meta): changelog + pql — batch 6 closed (T-1049/T-1051/T-1053 done; stories T-1200..T-1204 created under T-961)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:11:44 +02:00
jpmschweitzer 8db1d92733 Merge remote-tracking branch 'origin/asset-class-stories' 2026-07-25 23:10:38 +02:00
jpmschweitzerandClaude Fable 5 660f4a703f docs(assets): PR #213 review fixes — DoorSpec fields, spike inventory, axis honesty, D-154
doors.md now presents D-231's actual struct shape (initial_state
Open/Closed/Locked/Sealed; TemporalWindow lives in the independent
credential field) and attaches the Phase-5 runtime bridge to
initial_state only. furniture-props.md inventories all five spike GLBs
— acceptance is 4 promotable (3 furniture + lion_statue), vw_beetle
explicitly excluded to the Q-067 deferral. deferred.md + station-walls
gain the axis-completeness note: roof/facade/street textures ride the
wall-brief convention as a same-family follow-on, so the register
accounts for all four D-235 axes. The briefing's D-257 pointer
corrected to palette.md §2.1–2.2, and both the briefing and palette.md
(leave-cleaner, gap inherited from PR #211) now carry D-154's amendment
to D-033 — relationship colors display only in the insert/perception
overlay; normal gameplay is a uniform #1a1a1a outline (D-150).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:10:09 +02:00
jpmschweitzerandClaude Fable 5 18349d8619 chore(meta): pql changelog — T-1049/T-1053 to review
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:01:23 +02:00
jpmschweitzerandClaude Fable 5 2e9bbcaaf2 docs(briefings): rewrite araminta.md around the Phase-4 landscape (T-1053)
Replaces the 2026-03-13 v0.2-pivot briefing (sprite pipeline, dropped
scope framing, pre-Atlas) with the current shape: palette.md +
conventions.md as the live authorities the briefing points at rather
than restates, her standing rulings (category-first naming, D-257
toon/glazing) marked as hers to extend, D-235 co-maintenance with Miri,
the wardrobe pipeline as reference model, D-255 stepped Atlas as active
co-designed work, and her real open items (T-1049, D-257 shader,
Q-119, T-1198). Every v0.2-era decision citation verified before
dropping: D-114/D-117 superseded; D-119/D-122/D-128/D-135 live but not
hers; D-033/D-045 kept. D-126/D-131 found REPURPOSED to unrelated
content since the era docs cited them — the ID-drift sweep is T-1199.
Lead added the briefs/ + deferred.md pointers (araminta's cross-agent
note; her SendMessage to the author couldn't be delivered).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:01:09 +02:00
jpmschweitzerandClaude Fable 5 2bac820c77 docs(assets): per-class production briefs + template + formal deferral register (T-1049)
The asset-brief template (scope/visual-reference/naming/gen-path/
acceptance, one page) and five real briefs — station walls, rural walls,
doors, floors, furniture/props — each citing its D-235 axis tokens and
palette.md register rows (or the D-257 toon default), conventions.md
naming/mask/footprint rules, and the image-gen -> glb-gen -> promotion
path with concrete acceptance counts. Doors carry the negative
no-state-frame-files constraint (runtime mechanism stays Phase 5);
furniture/props' first acceptance is promoting the three unpromoted
spike GLBs. deferred.md is the formal register for the T-1051 four
(lamp posts, barns, TVs, billboards) + cars/Q-067, with rationale and
revisit triggers — satisfying T-1051's own 'or record formal deferral'
deliverable. Child stories under T-961 are created lead-side at merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 23:00:51 +02:00
jpmschweitzerandClaude Fable 5 e70c3efeee chore(meta): pql changelog — T-1199 filed (D-126/D-131 ID-drift sweep, from T-1053 finding)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:58:44 +02:00
jpmschweitzerandClaude Fable 5 9afcff0b54 chore(meta): pql changelog — batch 6 activated (T-1049/araminta, T-1053/qatux; T-1051 deferral ratified)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:55:21 +02:00
jpmschweitzerandClaude Fable 5 a223af66fb chore(meta): pql changelog — batch 5 closed (T-1196 PASS+done; T-1197/T-1198 filed from araminta observations)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:53:55 +02:00
jpmschweitzerandClaude Fable 5 5d00a1d2ee chore(meta): pql changelog — T-1196 active, capture center probed (GJ1002b massif)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:47:12 +02:00
jpmschweitzerandClaude Fable 5 4df5f132b9 chore(meta): pql changelog — T-1157 done (PR #212 merged)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:38:59 +02:00
jpmschweitzerandClaude Fable 5 72b15ab13c chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:38:49 +02:00
jpmschweitzer 19bfe811f8 Merge remote-tracking branch 'origin/capture-harness-redesign' 2026-07-25 22:38:21 +02:00
jpmschweitzerandClaude Fable 5 feef7aa1c5 fix(client): PR #212 review fixes — true on-screen footprint_px, self-describing shot coverage
Tyre finding 2: _log_atlas_view_transform's footprint_px now logs the
real on-screen pixel footprint (StepCanvasTransport.canvas_footprint_px
* canvas_scale — the same public pure function the terrain layer uses),
with the old cell-count field kept as canvas_cells. Live-verified the
divergence the fix exposes: Global logs footprint_px=(1528, 760) vs
canvas_cells=191x95 — the T-1192 fit-multiplier class the log exists to
root-cause, previously invisible under the mislabel.

Tyre finding 3: atlas_shots.json's one_shot_per_body note replaced by
rung_coverage stating the true distribution — 13 goldens across 7
bodies (per-rung coverage map, GJ380c's 3 shots as the invariance-proof
body, curated-subset rationale per T-1121). Corrects the prior commit
message's '12 new goldens' miscount: the true count everywhere is 13,
verified against shots array, visual.json entries, and PNGs on disk.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:36:03 +02:00
jpmschweitzerandClaude Fable 5 deeec94ec9 chore(meta): pql changelog — T-1157 review transition (write-through landed main-side via FR-4 vault resolution)
Tyre's PR #212 finding 1: the review-status row existed only in a live
DB, unrecorded in any git-tracked changelog — a rebuild reverted it.
Root cause: pql run from the capture worktree resolved the MAIN vault
(FR-4), so the write-through row landed here, uncommitted. Committing
it main-side makes the transition rebuild-safe; branch and main
changelog rows union at merge.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:22:30 +02:00
jpmschweitzer 28a0b3e2af Merge remote-tracking branch 'origin/main' into capture-harness-redesign 2026-07-25 22:13:49 +02:00
jpmschweitzerandClaude Fable 5 a45d4a5f58 feat(client): capture harness redesigned for the stepped Atlas — (body, rung) goldens (T-1157)
_setup_atlas_golden_shot and _run_atlas_matrix rebuilt on the real D-255
surface: nav.push('regional') through AtlasApp's own body-selection tail,
then StepCanvasViewer.jump_to at a fixed center (inventory item 5) — no
shim over the retired continuous-zoom API. is_pending()-aware bounded
settle (mirroring atlas_agent_driver.gd) and view-transform logging
(inventory item 3) wired into both capture paths. The 12 z2_0/z4_0/zfit
goldens are replaced by 12 (body, rung) goldens captured live against
fresh --test-mode servers; atlas_shots.json/visual.json re-keyed;
atlas_gen_open's stale gen_l1_* overlay ids fixed to gen_dw_temp.

Verification: two consecutive District runs byte-identical, and a
cold-vs-warm disk-cache invariance proof on both terrain draw branches
(Global/NEAREST, District/LINEAR) — byte-identical either way, so
capture output does not depend on the shared user://atlas_cache state.
DEVOPS.md's real-rendering exception note now records the fold-target
mapping for the smoke file T-1182 already deleted (Global + District
goldens exercise its two real-pixel draw branches). Old legacy-tracked
.import sidecars go with their PNGs; new goldens ship bare per
.gitignore's client/**/*.import rule.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 22:13:37 +02:00
jpmschweitzerandClaude Fable 5 ae45d5e21a chore(meta): pql changelog — batch-6 prep (T-1049 re-scoped, T-1053 refined, T-1196 body pool recorded)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 21:00:46 +02:00
jpmschweitzerandClaude Fable 5 7f704a08c7 chore(meta): pql changelog — visual track closed (T-1050, T-1052 done)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:55:15 +02:00
jpmschweitzerandClaude Fable 5 bea6c5fc4f chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:52:27 +02:00
jpmschweitzer 3351c595ab Merge remote-tracking branch 'origin/main' into visual-asset-catalog 2026-07-25 20:48:59 +02:00
jpmschweitzerandClaude Fable 5 08acbcb7df chore(meta): pql changelog — T-1193 first-slice incident record
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:46:07 +02:00
jpmschweitzerandClaude Fable 5 9ac98542d1 fix(client): isolate viewer tests from the machine-shared atlas disk cache
user://atlas_cache/ is one directory for every worktree gate run, live
capture driver, and real play session, and T-1183's Tier-2/3 lookup
short-circuits BEFORE test_mode's silent-no-op IPC — so a warm shared
cache delivers real canvases into tests written against 'nothing ever
arrives'. Caught live: a concurrent GJ380c Global capture flipped the
two before-any-canvas viewer tests in another worktree's push gate.

Adds disk_cache_root_override on StepCanvasViewer (threads into
StepCanvasRequest's existing test-injection-only seam; production
leaves it empty) and routes every direct viewer construction in the
viewer + legend suites through a _make_viewer() helper pinning an
isolated root. First slice of T-1193's viewer test seam; screen-built
viewers still share the default root (noted on T-1193).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:45:46 +02:00
jpmschweitzerandClaude Fable 5 2ca70d0228 docs(assets): PR #211 review fixes — ratified glazing tokens, D-257, manifest skip contract
Review round (Hoshe + Tyre, both REQUEST_CHANGES) fully addressed:
palette.md's glass carve-out re-keyed from retired never-shipped tokens
(precision_glass/smart_facade) to the ratified glass_curtain_wall (wall)
+ industrial_glazing (facade); the toon/PBR treatment promoted from a
docs-only ruling to D-257 (architecture, cross-refs D-235/D-244/D-043/
D-044/D-033) with palette.md §2 now citing it as authority; D-149 +
D-257 added to decision_refs; manifest.json _comment gains the explicit
underscore-prefix loader skip contract; master pipeline table Visual row
Stub -> Active; conventions.md mask pointer Section 3 -> 5; pre-existing
broken D-066 links in the mood-board transcript repaired (leave-cleaner).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:36:47 +02:00
jpmschweitzerandClaude Fable 5 7d5a774fa5 docs(assets): Phase-4 visual style bible in palette.md (T-1052)
Authors the full style bible: camera table separating D-148 gameplay from
D-019 offline-renderer use; the delegated toon-vs-PBR ruling (environment
props share the character toon treatment, with a minimal-PBR carve-out for
glass/polished metal so sightlines read truthfully under occlusion-based
perception); a color/material register for every D-235 ObjectTag (hue,
grain, D-217-keyed weathering); and explicit supersession notes both ways
with visual-grammar-v01.md and the mood-board workshop transcript.
Includes branch-side pql changelog rows (T-1050/T-1052 -> review); the
worktree pre-commit export step failed benignly (write-through had
already refreshed the files) so they are staged explicitly here.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:20:21 +02:00
jpmschweitzerandClaude Fable 5 f77e15d075 docs(assets): 3D-model+texture catalog, glb-gen production path, conventions (T-1050)
Instantiates the five D-244 catalog files (models/textures/artwork/icons/
effects — icons carries the 13 as-built SVGs, stance icons traced to their
consumer and marked final), creates client/assets/models/{furniture,props}
with a schema-documented manifest.json mirroring the character manifest,
fixes glb-gen SKILL.md's stale 'path does not exist' paragraph, and authors
docs/assets/visual/conventions.md: category-first model naming (araminta
ruling), mask sidecars per the character convention, D-235-token-keyed
texture naming, footprint_tiles as manifest metadata. Door-state and
TileSet conventions are recorded as explicit deferrals (Phase-5 owned).
visual/README.md carries both this ticket's count/link updates and
T-1052's palette-section rewrite (shared file, committed here).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:20:04 +02:00
jpmschweitzerandClaude Fable 5 3b3ef392c5 chore(meta): pql changelog — visual cluster re-scoped (T-1050/T-1052 refined+active, T-1051 deferred blocked-by T-1049)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:11:55 +02:00
jpmschweitzerandClaude Fable 5 0822390f7a chore(meta): pql changelog — batch 5 activation (T-1157 in_progress/hoshe, T-1196 ready, T-962 gate questions recorded, T-1050 held-note correction)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 20:04:19 +02:00
jpmschweitzerandClaude Fable 5 d14bead60a chore(meta): pql changelog — batch 4 closed (T-964, T-971 done)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:56:59 +02:00
jpmschweitzerandClaude Fable 5 493cd716b6 style(simulation): gate bounce — cargo fmt in fix-round fixture
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:49:56 +02:00
jpmschweitzerandClaude Fable 5 5d1935f8fc style(simulation): gate bounce — clippy identity_op in drainage fixtures
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:45:18 +02:00
jpmschweitzer e4b5c2bc9f Merge remote-tracking branch 'origin/main' into test-hardening 2026-07-25 19:36:39 +02:00
jpmschweitzerandClaude Fable 5 b165c8038d fix(simulation): PR #210 review round — guard boundary, live oasis pinning, unreachability proof (T-964)
Guard becomes land_districts <= 1 (both reviewers converged — a lone
island definitionally cannot show two distinct directions; same
nothing-to-vary condition one value short), with a lone-island vacuous-
pass fixture; golden confirmed untouched. Oasis scaling adjudicated as
LIVE, not future — GRID_W is already 1024 on main, so ring iterations
change 2/4 -> 4/8 today: extracted a pure oasis_ring_iterations()
helper pinned by tests at both 512 and 1024, and traced exactly why the
determinism hash stayed green (it reads only elevation; the rings touch
only biome — a genuinely different array, not a coincidence). The
drainage merge-logic question answered byte-precisely: zero logic
changed vs main (comment-only diff) — and the deeper dig PROVED the
'isolated basin with another basin to escape to' branch is
mathematically unreachable for any connected grid (contracting vertex
groups of a connected graph cannot disconnect it), so the comment now
states that instead of narrating a divergence that never fires; two
direct merge-target tests added regardless. Wrap test renamed to what
it actually pins (non-wrap-awareness). D-010 docstring softened to
same-process purity, naming the cascade golden as the cross-run layer.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:35:09 +02:00
jpmschweitzer c324875959 Merge remote-tracking branch 'origin/atlas-agent-channel' 2026-07-25 19:33:22 +02:00
jpmschweitzerandClaude Fable 5 6f63cb6f70 fix(ui): agent driver honors SR_PORT — the eyeball's own finding (T-971)
The channel eyeball caught the committed reference driver silently
relying on SimBridge's hardcoded default port, unlike every sibling
real-render driver — a caller starting the server on a chosen port got
20 silent connect retries against the wrong port and a hollow session
whose results had valid shapes but no data. Mirrors visual_capture.gd's
convention exactly: SR_LIVE=1 without SR_PORT is a hard error; SR_PORT
sets SimBridge.server_port before boot.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:30:29 +02:00
jpmschweitzerandClaude Fable 5 52304d3e37 fix(ui): PR #209 review round — current-screen guards, pending-aware settle, one body guard (T-971)
Every screen-targeted intent now routes through one
_require_current_screen() check and returns the structured error shape
instead of silently mutating an off-screen viewer (hoshe's finding:
scroll_rung from the reach screen fired real IPC and reported ok). The
reference driver's fixed 4-frame settle becomes is_pending()-aware with
a 600-frame bound, the keep-waiting decision extracted as a pure
testable function — restoring the proven eyeball-driver discipline. The
terrain_reference guard moves into AtlasApp._on_body_selected(), the
shared tail for double-click, Enter, AND the intent path — closing a
pre-existing click/Enter divergence hoshe caught this PR formalizing;
the intent layer pre-checks via the new SystemScreen.find_body() and
reports structured errors for unknown ids and terrain-less bodies.
after_test() resets AtlasAgentBridge.current_app (tyre's freed-pending
footgun). Suites 58/58 + 14/14; full suite 3,638.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:14:02 +02:00
jpmschweitzerandClaude Fable 5 d316c1274b chore(meta): pql changelog — batch-4 activation rows (T-948 closed as delivered, T-964/T-971 activation + appends)
Tyre's PR #209 review flagged T-971's re-scope appends as invisible to
the branch-side planning store — same bookkeeping-lag class as PR #208's
T-1195 finding: the write-through rows were awaiting this commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:05:08 +02:00
jpmschweitzerandClaude Fable 5 272d3781d8 style(simulation): gate bounce — clippy unnecessary_cast in test fixture
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:04:47 +02:00
jpmschweitzerandClaude Fable 5 80974dfe5a docs(governance): D-226 amendment — agent-channel vocabulary reconciled to the stepped Atlas (T-971)
Tyre's PR #209 finding: every prior D-226 re-scope carries a dated
amendment in the record, and this vocabulary change existed only in
code comments and ticket appends. Records the drops (select_city,
open_regional — no settlement hit-test affordance post-D-255; one
screen Region..Chunk), the additions (open_atlas, jump_to_center via
the constrained jump_to seam), the summary-field reconciliation, and
the in-process-only transport narrowing.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:04:00 +02:00
jpmschweitzerandClaude Fable 5 b929aa27b0 style(simulation): gate bounce — cargo fmt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 19:01:51 +02:00
jpmschweitzerandClaude Fable 5 e141a595b1 feat(simulation): believability gate learns basin-direction variety (T-964, D-245)
A real D-245 gate-shape strengthening, not just a test: the D-256/T-1174
finding proved the believability golden byte-identical under a total
all-North basin_direction collapse — every scalar contrast field is
structurally blind to the one field that regressed. ContrastMetrics
gains land_districts and basin_directions_distinct (both over ALL
districts, no new derive calls — the evidence-backed pick over the
voxel-transect proxy, which washes out at production sample density),
and evaluate_criteria gains 'basin direction variety': pass when
land_districts == 0 (the drained-body guard — an all-ocean body has no
cells that can cast a D8 vote per the aggregator's own exclusion rule,
so a uniform default is legitimate, mirroring the file's existing
nothing-to-vary idiom) or distinct >= 2. Negative test proves the
criterion catches the land-bearing all-North regression; vacuous-pass
test proves the waterworld guard. Golden regenerated and rerun-stable;
both validation bodies (Arbour, Edict) pass at distinct=2.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 18:59:13 +02:00
jpmschweitzerandClaude Fable 5 f81622bbf0 test(simulation): Phase-4 hardening — deferred #953/#963 review gaps (T-964)
The verified-still-open coverage list: per-type attractor reachability
fixtures (LakeShore via enclosed depression, PassEntrance via crafted
saddle, PlainCenter via flat terrain, RiverCrossing via confluence) plus
thin_by_spacing behavior (collision, strict-< boundary, equirectangular
column wrap); heightmap 8-bit decode, sea_level passthrough, downsample
identity and zero-target early-return; drainage area_pct bit-for-bit
determinism plus the isolated-basin-fallback divergence comment (Tyre
N1, citing the pre-#953 behavior it deliberately departs from); the
layer1 mountain-branch pairing test (investigated first — the cascade
test supplies a mountain pool but only ever asserted river counts, a
genuine gap); an importer idempotency test covering atlas_city_names
AND atlas_feature_names plus the Sol exemption, wired into
make test-tooling; and the oasis_water dilation radius scaled by
GRID_W/512 (Tyre N2, hash-stable). One stale item dropped per the
refinement trim (test_sim_determinism wiring — already done).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 18:58:53 +02:00
jpmschweitzerandClaude Fable 5 3689ad0466 chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 18:52:10 +02:00
jpmschweitzerandClaude Fable 5 34dbac9bf6 feat(ui): AtlasAgentInterface — observe/act named-intent control channel (D-226, T-971)
D-226 layer 4, rebuilt against the post-D-255 stepped Atlas after the
Phase-1 reconciliation (the original intent list targeted the retired
continuous-zoom viewer). Eleven intents, each backed by the exact
production handler a click calls — select/open for systems and bodies
(extracted shared by-id tails so click and intent paths are one code
path), scroll_rung, reset_view, back, open/close_atlas, set_overlay —
plus two new first-class capabilities: jump_to_center (the fixed-center
revisit pattern proven by five eyeball drivers, via a new
StepCanvasViewer.jump_to seam that reuses _scroll_rung's exact request
tail — same extent cap, same cache keys) and get_current_canvas_summary
(allocation-light reads off the raw wire dict, courses-by-class,
draw-matched settlement dedup — no PNG decode). Contract shape: dumb
AtlasAgentBridge autoload holding the app handle (untyped per the
parse-order rule), all logic in the static AtlasAgentInterface class.
observe() is side-effect-free: current state + a generic Control-walk
affordance tree. In-process consumers only this ticket (documented);
the committed reference driver (atlas_agent_driver.gd, InputSwallower +
settle-until-ready from the T-1157 inventory) replaces the scratch
eyeball drivers as the sanctioned headless-drive pattern.
select_city/open_regional dropped with recorded rationale (no
settlement hit-test affordance exists post-D-255) — diff on the ticket.
33 new tests across three suites.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 18:51:45 +02:00
jpmschweitzerandClaude Fable 5 e0d120e555 chore(meta): pql changelog — polish batch closed (T-1160/69/59/75 done, T-1196 filed)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 18:21:04 +02:00
jpmschweitzer aafce641db Merge remote-tracking branch 'origin/atlas-feature-names' 2026-07-25 18:15:08 +02:00
jpmschweitzerandClaude Fable 5 077d787c4a fix(simulation): one shared invent_coastal_position — PR #208 review round (T-1160)
Hoshe found the concrete residual: the hand-copied driver block called
derive_temperature_c unconditionally where invent_primitives prefers the
lapse-adjusted region baseline on non-airless bodies — driver_temp feeds
glaciation/moisture into the warp magnitude, so orbital displacement
could still differ from District at the same position (the ticket's
defect class, one step upstream); the copy structurally couldn't branch
right because region_baseline_at_district was computed after it. Tyre
demanded the structural cure: steps 1-3 now live in ONE shared helper
(invent_coastal_position -> warped position + CoastCharacter);
invent_primitives composes helper + detail-scatter; the orbital path
hoists the baseline and makes a single helper call. The audit test's own
'District-style' side turned out to be a THIRD copy carrying the same
bug — rewired to the real helper (raw pre-fix side untouched as the
historical baseline; refreshed: 5.01% disagreement, mean 5,957.9 m,
748.9 ns/cell). Golden verified byte-identical under forced regen, with
the reason traced: the wire temperature never flowed through the buggy
internal branch, and the fixture's probe positions cross no discrete
boundary — the 267-body audit is the instrument that sees the drift.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 17:22:16 +02:00
jpmschweitzerandClaude Fable 5 7a55685bf6 chore(meta): pql changelog — T-1194/T-1195 filed, polish batch transitions
T-1194 (biome/relief stipple layer, from T-1175's assessment) and T-1195
(river+mountain label positions, the T-1169 scope adjudication target)
now have their write-through rows in git — tyre's PR #208 review caught
the branch-side store unable to resolve the T-1195 reference because
these rows were awaiting this commit.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 17:05:47 +02:00
jpmschweitzerandClaude Fable 5 71f70f035e style(simulation): gate bounce — cargo fmt
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 16:53:41 +02:00
jpmschweitzer 497f9dc94d Merge remote-tracking branch 'origin/main' into atlas-feature-names
# Conflicts:
#	CHANGELOG.md
2026-07-25 16:44:51 +02:00
jpmschweitzerandClaude Fable 5 1eb596ec78 chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 16:11:12 +02:00
jpmschweitzerandClaude Fable 5 8da9670e0f feat(simulation): feature-name pipeline wired + legacy window_granularity u32 retired (T-1169, T-1159)
One commit for two tickets whose changes share the bridge/plugin
plumbing files. T-1169 connects the three dormant feature-name pieces:
atlas_feature_names populated at regen (17,891 rows — 15,190 mountain,
2,701 river — via populate_atlas_feature_names mirroring the city-names
importer; systems.db regenerated, stamp fresh), attach_feature_names
wired into the cascade's Topography block with name pools threaded
DB-free through AnalyzeBody (D-225 pattern) and assignments stored on
Layer1Output/BodyWorldState for future consumers, and a
FeatureNamesRequest/Response read proxy as the bridge's 7th tagged
envelope (D-236 pattern, both SimBridge impls). Client label DRAW is
deliberately NOT here — implementation proved both river and mountain
labels need a wire-carried position (the pool is position-free; course
polylines aren't correlated with the named attractors by construction) —
deferred to T-1195's single design pass. cascade_layer1 golden re-pinned
(additive feature_names field).

T-1159 retires the legacy u32 granularity field fully shadowed by
window_granularity_v2: AtlasLayerRequest.window_granularity,
DistrictWindowLayer.granularity echo, the u32::MAX sentinel, and
resolve_window_granularity are gone server-side; client encode paths and
the caller-less atlas_window_cache legacy key component dropped;
msgpack fixtures regenerated; the T-1150 aliasing regression test now
drives through the surviving enum field. The district_window carrier
itself survives byte-compatible per D-255(c).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 16:10:27 +02:00
jpmschweitzerandClaude Fable 5 befdb689c1 fix(simulation): orbital rung applies coast_warp_px — one coastline at every rung (T-1160)
The Global/Region rungs sampled the heightmap ocean mask raw while every
finer rung samples it at the coast-warped position — a structurally
different coastline at the orbital-to-district seam. Audited on all 267
real body heightmaps at region spacing, coastal band only: 5.01%
land/ocean classification disagreement (2,911 of 58,073 cells), mean
displacement ~6.0 km, max ~18.9 km. Fork taken: APPLY the warp —
derive_orbital_at_metres now runs invent_primitives' steps 1-3 (driver
climate -> coast character -> coast_warp_px) before sampling, still
skipping detail-scatter (its octave ceiling, 32.8 km, is below region
spacing; the WARP's octaves reach 262 km, which is why skipping it was
wrong). Cost measured: ~784 ns/cell added (~15 ms on an Earth-class
Global canvas; low hundreds of ms parallel at the 8.3M-cell ceiling).
The ignored audit test preserves the pre-fix baseline for the record.
Golden re-pinned — region rows only, district/quarter byte-identical.
project.yaml 0.4.2 -> 0.4.3: orbital canvas bytes changed, client disk
caches must miss. Awaiting Araminta's review-seat sign-off per ticket.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 16:09:46 +02:00
jpmschweitzerandClaude Fable 5 686021bee8 fix(ui): PR #207 review round — crop-gated taper, true mitres, hybrid AA (T-1175)
Five findings from the araminta+hoshe round. Tapering now fires only on
a TRUE upstream source: the course's first raw world point is tested
against the canvas's own world bounds (conservative 1m epsilon) —
exact detection because the server crop keeps one point beyond the
window (layer_proxy crop_course_to_window lo = first_in-1, contract
documented), so crop passthroughs draw the old flat full-width cut and
never a false headwater. The averaged-normal joint is replaced by a
real mitre (half_w/cos(theta/2) recovered trig-free via the bisector
normal), clamped by a 2x mitre limit AND 0.45x the shorter adjacent
segment — restoring true perpendicular width at bends (the 29% pinch at
confluences is gone) and preventing the hairpin bowtie; the winding doc
now states the actual bounded guarantee. Antialiasing restored via the
hybrid: only the varying-width taper head draws as a ribbon; the
constant-width ~85% of every course keeps the original antialiased
draw_polyline (byte-identical for untapered courses), split at an
interpolated arc-length point sharing position and width — junction
capture evidence in .cache/screenshots/t1175-fix-round/. Flat-fill
single-element color array. Suite 24 -> 48 tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 16:05:17 +02:00
jpmschweitzerandClaude Fable 5 28d2e6c80b chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 15:25:58 +02:00
jpmschweitzerandClaude Fable 5 40cf89c3cb feat(ui): river source tapering + width-grammar retune — map fluency pass (T-1175)
The single large polish pass Jeroen requested off the T-1170 captures,
benchmarked against RimWorld's world-map fluency. Courses now draw as
source-tapered ribbons: per-vertex width ramps from a hairline at the
upstream source to full class width over 15% of the course's arc length
(arc-length parameterized, not vertex-indexed, so point density doesn't
change the read), built as one draw_polygon ribbon with mitred joins.
Class width table retuned 0.9/1.4/2.2 -> 0.6/1.2/2.4: a clean ~2x
per-class ladder so a tributary-joins-trunk confluence reads as a join,
trunk held at its visually-proven weight, stream thinner per the
benchmark's thin/consistent/restrained grammar. Opacity untouched
(Araminta's T-1170 ruling stands). Coast-gradient item resolved as
already-correct (the coastal transition zones + elevation lightness
render the shoreline band; capture-verified) — no wire change. Stipple
assessment filed as T-1194. Eight new taper-geometry tests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 15:25:30 +02:00
jpmschweitzerandClaude Fable 5 0d8984fe53 chore(meta): pql changelog — visual-defect batch closed (T-1186/88/89/92 done, T-1193 filed)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 14:46:52 +02:00
jpmschweitzerandClaude Fable 5 4a9567c669 style(simulation): gate bounce — fmt wrap + clippy needless_range_loop
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 14:24:45 +02:00
jpmschweitzerandClaude Fable 5 39f0fd8c51 fix(simulation): lake_margin_q normalizes per basin — full-range depth gradient (T-1188)
The PR #206 eyeball caught what every numeric gate passed: the depth
signal was visually flat on both test lakes (GJ1c lmq=0 across the whole
basin; GJ338Bd 0-13 of 100). Two compounding causes: a fixed absolute
ceiling (one body's p90 cell depth) compressing skewed depth
distributions into single digits, and heightmap-pitch depth variation
being sub-texel-tiny within most basins. lake_margin_q is now
depth / the basin's own maximum settled depth: HydrologyResult grows
basin_max_depth_scaled (computed in solve() from existing basin_cells
membership, broadcast per basin), threaded through
HydrologySample.basin_max_depth, normalized in lake_from_hydrology_at
with a degenerate-basin epsilon guard (a genuinely uniform pond shades
flat — honest, not forced). Lake EXISTENCE (filled > original) is
untouched — only tone changes. Measured at district spacing:
GJ1c min=0 p50=33 max=84; GJ338Bd min=8 p50=38 max=70 — full-range
shore-to-deep ramps on both. No perceptual curve added: the linear
per-basin ramp is already well-quartiled. project.yaml 0.4.1 -> 0.4.2
(0.4.1-tagged canvases carrying flat-lmq semantics reached real disk
caches during eyeball runs and must miss). Acceptance gates green;
zero golden churn (lake_margin_q not captured by either golden shape).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 14:23:11 +02:00
jpmschweitzerandClaude Fable 5 b39dd49950 docs(simulation): update step_canvas row-space doc — T-1186 is fixed (PR #206 review)
Hoshe's review finding: the build_step_canvas row-space convention block
still described region_centre_latitude_deg as pole-anchored/bugged and
said 'T-1186 stays open' — both false after this PR's own first commit.
Rewritten to reflect the fixed state; the deliberate signed-convention
rationale and the layer_proxy deferral (still true, still T-1181's scope)
are preserved.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:44:35 +02:00
jpmschweitzer 324a318b17 Merge remote-tracking branch 'origin/main' into atlas-latitude-fix
# Conflicts:
#	CHANGELOG.md
2026-07-25 13:30:16 +02:00
jpmschweitzerandClaude Fable 5 4c44786f99 docs(governance): D-255 amendment — rung-0 integer viewport-fit display ratio
Records the T-1192 presentation ruling: the Global opener's display
ratio is viewport-fitted per body to the largest integer px/gridunit
that fits the legend-reserved viewport (floored at 1x1, letterbox
centred), texel-exact by construction; fixed rungs keep their tuned
constants. Explicitly notes that non-integer resting-state scaling
remains unsanctioned and that a PR #205 review finding removed a
fractional-fit branch which had cited this record for an exception it
does not contain — the mis-citation episode is part of the record so it
cannot recur silently.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:14:26 +02:00
jpmschweitzerandClaude Fable 5 374b195594 fix(ui): PR #205 review round — integer px-per-gridunit fit replaces fractional (T-1189, T-1192)
The fractional fit branch is deleted, resolving both review findings at
the root: tyre showed its comments cited D-255 for an exception the
record does not contain (the language came from the lead's ticket text,
not governance), and hoshe showed it returned sub-1x for a canvas
exceeding the viewport on one axis. Replacement: fit_scale_ratio()
chooses the largest integer pixels-per-gridunit R fitting both
legend-reserved axes, floored at 1 (over-viewport draws native and
crops like every fixed rung) — the fine-grained integer lattice (GJ1c
1080p -> 9px/gu = 1593x792, ~98% width; 4K -> 20) that makes the
fractional hatch unnecessary. center_offset() floors to whole pixels
(half-pixel centering would blur the texel grid). Doc comments cite the
real sanction (D-255 amendment 2026-07-25, this branch). Legend column
constant is now canonical in transport, read directly by the legend
(was an independently-typed literal); its test asserts real geometry.
New regression test proves _global_body_extent clears on body switch
and never caps another body's requests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:14:12 +02:00
jpmschweitzerandClaude Fable 5 562dbc5b21 chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:09:07 +02:00