Commit Graph
100 Commits
Author SHA1 Message Date
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 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
jpmschweitzerandClaude Fable 5 dec5b0bc43 feat(simulation): lake_margin_q depth band — lake shorelines gain gradient vocabulary (T-1188)
Lake edges rendered as hard step-edges while ocean coasts got multi-tone
transition bands: every coastal-transition morphology gate keys on
ocean_fraction_q, definitionally 0 inside a lake basin (hypothesis (b)
of the ticket; (a) disproven first — a shoreline-crossing sweep at
2048/512/128m plus a 10m fine sweep all land on the same continuous
crossing, so positional refinement was never broken). New
DistrictProfile.lake_margin_q (0-100 settled-hydrology depth band, from
the same bilinear filled/elevation pair the lake test already samples;
ceiling calibrated just above the observed p90 depth on GJ338Bd's 5,043
flooded cells), threaded through both derive paths onto
EncodedStepCanvas (serde-default for shape tolerance) and down the
client: protocol decode, terrain-layer plane, colorize shades Lake cells
by depth band instead of elev_q (bedrock-under-water, the wrong signal).
project.yaml 0.4.0 -> 0.4.1: the new wire field must invalidate the
client disk cache via its version tag (T-1183's D-192 mechanism).
Acceptance gates green with the new field (lossless round-trip,
cache-hit==cache-miss, every rung).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:08:44 +02:00
jpmschweitzerandClaude Fable 5 07f0fa307f fix(simulation): region baseline latitude — equator-anchored signed rows (T-1186)
region_centre_latitude_deg mapped row 0 to the north pole with lat_frac
clamped [0,1] while the derive core floor-divides equator-anchored signed
world metres — every northern-hemisphere region clamped to +90 (polar
everywhere) and the southern hemisphere read as compressed northern
tropics. Now mirrors the derive core's exact inverse mapping (lat_frac =
centre_y/meridian clamped [-0.5,0.5], lat = -frac*180). The ticket's
in-the-wild datapoint flips as predicted: GJ338Bd region (136,43), old
baseline +13.94N/26.8C -> new -76.06S/10.3C; the 76S district cell now
derives Lake/2.07C/Light glaciation. Goldens regenerated (believability +
window derivation, stable on rerun); two region_profile unit tests
repositioned — their probe coordinates meant different places under the
old convention. step_canvas rung-0 already used the correct signed
convention; layer_proxy's pole-anchored pseudo-grid stays deferred to
T-1181's rung-0 rebuild per D-256(f).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 13:08:26 +02:00
jpmschweitzerandClaude Fable 5 915a6790f0 chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 12:52:28 +02:00
jpmschweitzerandClaude Fable 5 c1a97166c5 feat(ui): cap rung extents to the body + fit/center the Global canvas (T-1189, T-1192)
The two client fixes for the Atlas frames Jeroen flagged. Region rung no
longer requests more planet than exists: cap_extent_to_body() caps the
viewport-fit extent at the body's own region grid (the Global canvas
extent echo — cols=regions_per_equator, rows=cols/2), matched by gridunit
SPACING not rung name, applied before the request/cache key is built;
cold-start scroll-before-Global-echo requests uncapped and lets the
server clamp (documented). Kills both the side-by-side continent repeat
and the past-the-pole stripe smear.

Global opener now fit-scales and centers through one shared letterbox
mechanism (center_offset/integer_fit_scale/fit_scale, 75%-coverage
integer-vs-fractional decision, NEAREST already forced on orbital rungs
per D-255's escape hatch) also used for the Region cap's letterbox
remainder. Legend column reserved before fitting — pinned to the legend's
own width by a cross-constant test, never overlapping the canvas.

Also fixes a latent crash: NOTIFICATION_RESIZED fires mid-_ready() before
children exist; null guard in the resize path.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 12:52:06 +02:00
jpmschweitzerandClaude Fable 5 7ab15baed5 chore(meta): pql changelog — T-1183 done, T-1191/T-1192 filed, T-1189 escalated
T-1191: atlas edge-scroll pans on unfocused mouse motion (eyeball nit).
T-1192: Global rung canvas fit/center presentation.
T-1189: raised to high — Region-rung extent exceeds body on both axes at
standard viewports (continent repeats + south-pole stripe smear), per the
T-1183 eyeball captures Jeroen flagged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 12:18:55 +02:00
jpmschweitzer 2fffec866c Merge remote-tracking branch 'origin/t1183-client-cache' 2026-07-25 12:12:37 +02:00
jpmschweitzerandClaude Fable 5 4d43a41acd chore(meta): pql changelog — T-1190 filed, T-1183 to review
T-1190: step-canvas wire staleness signal + client sim_ttl threading
(the D-253 clock seam raised in PR #204 review, adjudicated future-seam).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 11:37:40 +02:00
jpmschweitzerandClaude Fable 5 51fe35d00d fix(ui): harden step-canvas disk cache — PR #204 review round (T-1183)
Atomic index writes (tmp+rename), orphan-payload reconciliation sweep
folded into the background sweep, payload shape guard mirroring the
protocol's own width/height discriminator, size_bytes via get_position()
instead of a full payload re-read, and a 64-bit SHA-256 payload filename
(String.hash()'s 31-bit space made a silent wrong-map filename collision
a ~1-in-16k event per cap-full body; migration self-heals via the orphan
sweep). Tier-3 class doc rewritten to name the real D-253 seam — the
glaciation/flooded_q wire fields exist but carry static values and no
staleness signal crosses the wire; T-1190 tracks threading a wire TTL
into put(sim_ttl_sec) when the driving clock lands — replacing the false
'no sim-state wire field exists' premise. Four new tests plus a
_stub_canvas fixture helper centralizing the canvas shape contract.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 11:36:21 +02:00
jpmschweitzerandClaude Fable 5 6702e6c725 chore(meta): update changelog
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 11:09:18 +02:00
jpmschweitzerandClaude Fable 5 6b76e365bb feat(ui): client disk cache — FileAccess tiers beneath the LRU (D-255, T-1183)
step_canvas_disk_cache.gd: the Tier 2/3 store per D-255(d) and the
round-2 three-tier spec. Payload is the WIRE, pre-decode — store_var/
get_var round-trips the PNG-encoded PackedByteArrays natively, and
Image.load_png_from_buffer never runs in this file. One composite key
shared verbatim with Tier 1 (hash filenames for filesystem safety);
per-body index.json with malformed-index recovery (rebuild-or-discard,
never crash).

Three independent eviction mechanisms, exactly as ruled: rung-0 Global
carries a retention floor no sweep touches (now also threaded into
Tier 1 per the T-1182 handoff); Tier 2 geometry is byte-valid forever
and evicts only by time-since-last-visit (14d starting tunable, on
body-open) and LRU byte budget (256 MiB/body, 5-min coarse timer) —
two separate sweeps; Tier 3 sim-state TTL is wired and tested but has
no production caller yet (no sim-state field exists on
EncodedStepCanvas — the D-253 stub inheritance, documented).

Hardening per D-255(d), both mandatory: per-body deep-rung cap
(512 Block+Chunk entries, enforced synchronously in put(), floor- and
budget-independent — the ticket sanctions count-or-quota; count chosen
as the direct D-226(d) information-content proxy) and a schema/version
tag on every entry (project.yaml version via the existing
loading_screen line-scan idiom — D-192 co-ship makes the client
version the wire-schema version; exact-inequality mismatch = miss +
drop, NEVER decode, checked in both has() and get_canvas()).

Integration: request_now() checks Tier 2 on a Tier-1 miss (synchronous
promote), Ready responses write through to both tiers, Pending never
writes; viewer runs the visit sweep on body-open + the background
sweep on a 5-min timer.

30 new disk-cache tests + 7 request-integration + 3 sweep-wiring tests
(restart persistence, sweep independence both directions, cap
semantics, version-mismatch never-decode, corrupt-index recovery).
Full client suite 3,440/3,440, 0 orphans; cold-parse clean.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 11:08:48 +02:00
jpmschweitzer 83986dbb90 Merge remote-tracking branch 'origin/t1182-client-map'
# Conflicts:
#	CHANGELOG.md
2026-07-25 10:31:03 +02:00
jpmschweitzer b2d2128b92 Merge remote-tracking branch 'origin/t1185-outlet-wiring' 2026-07-25 10:30:24 +02:00
jpmschweitzerandClaude Fable 5 9a296de797 chore(meta): pql changelog — T-1182/T-1185 cycle (T-1188/T-1189 filed, T-1157 inventory)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-25 10:30:12 +02:00