chore(meta): pql changelog — T-1181 wire-shape report + review status

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-25 03:35:34 +02:00
co-authored by Claude Fable 5
parent 08b85bf233
commit 2f45292563
2 changed files with 26 additions and 0 deletions
+12
View File
@@ -1864,3 +1864,15 @@ INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, chang
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FSCXX7E3BXT7WG0BYDB6PJA0', 'description', 'Found during the PR #199 (T-1174/D-256) review fix round, PRE-EXISTING on the window path since the region climate stack (T-1078/T-1113) was wired into derive_at_metres. region_profile::region_centre_latitude_deg (region_profile.rs ~270-280) maps region row 0 to the north pole (+90) with lat_frac clamped to [0,1] — a pole-anchored, non-negative row convention. But the derive core (derive_at_metres_with_riparian, district_profile.rs ~1788) keys regions by floor-dividing EQUATOR-anchored world metres (negative wy = north), producing signed region rows (Earth-class: -49..+49). Consequence: every northern-hemisphere region has negative row -> region_centre_y_m negative -> lat_frac clamps to 0 -> baseline latitude +90 (polar) regardless of true latitude; southern-hemisphere rows 0..~48 read as compressed NORTHERN latitudes ~89..~0.7 (south pole reads as equator). Affects the region temperature baseline (and glaciation/moisture components derived from it) for the window path at every rung, and post-D-256 the batch/survey path inherits the same keys (still an improvement over the pre-D-256 body-wide region-(0,0) baseline, which read ~+89 everywhere). NOT touched in PR #199 to keep the review round scoped; goldens currently pin the wrong-latitude values. FIX SHAPE: make region_centre_latitude_deg mirror the derive core''s inverse mapping (equator-anchored signed rows: lat = -((ry+0.5)*REGION_M/meridian_m clamped to [-0.5,0.5])*180), audit the OTHER convention''s callers (the D-255 rung-0 canvas row space and the collapsed LayerRegionOutput builder use non-negative pole-anchored rows - decide ONE convention per D-256''s one-inverse-mapping principle, likely at the T-1181 rung-0 rebuild), regen affected goldens, and re-run the believability direction check. Related: D-256, D-243, T-1181, T-1078.', 'Found during the PR #199 (T-1174/D-256) review fix round, PRE-EXISTING on the window path since the region climate stack (T-1078/T-1113) was wired into derive_at_metres. region_profile::region_centre_latitude_deg (region_profile.rs ~270-280) maps region row 0 to the north pole (+90) with lat_frac clamped to [0,1] — a pole-anchored, non-negative row convention. But the derive core (derive_at_metres_with_riparian, district_profile.rs ~1788) keys regions by floor-dividing EQUATOR-anchored world metres (negative wy = north), producing signed region rows (Earth-class: -49..+49). Consequence: every northern-hemisphere region has negative row -> region_centre_y_m negative -> lat_frac clamps to 0 -> baseline latitude +90 (polar) regardless of true latitude; southern-hemisphere rows 0..~48 read as compressed NORTHERN latitudes ~89..~0.7 (south pole reads as equator). Affects the region temperature baseline (and glaciation/moisture components derived from it) for the window path at every rung, and post-D-256 the batch/survey path inherits the same keys (still an improvement over the pre-D-256 body-wide region-(0,0) baseline, which read ~+89 everywhere). NOT touched in PR #199 to keep the review round scoped; goldens currently pin the wrong-latitude values. FIX SHAPE: make region_centre_latitude_deg mirror the derive core''s inverse mapping (equator-anchored signed rows: lat = -((ry+0.5)*REGION_M/meridian_m clamped to [-0.5,0.5])*180), audit the OTHER convention''s callers (the D-255 rung-0 canvas row space and the collapsed LayerRegionOutput builder use non-negative pole-anchored rows - decide ONE convention per D-256''s one-inverse-mapping principle, likely at the T-1181 rung-0 rebuild), regen affected goldens, and re-run the believability direction check. Related: D-256, D-243, T-1181, T-1078.
In-the-wild datapoint (2026-07-25, T-1184 eyeball session): GJ338Bd (Arbour, R=6711km) survey cell (42,29) true position latitude -76.2S (wy=8,929,367m, region row 43) derives with the pole-anchored baseline latitude +13.9N, producing an 18C temperate, glaciation-free lake district near the antarctic circle. Concrete demonstration of the southern-hemisphere-reads-as-northern-tropics half of the bug (the northern half clamps to +90). Conversion math used: scratchpad survey_to_district.py, the D-256 bridge formula.', NULL, '2026-07-25 01:01:37', '2026-07-25 01:01:37.348', '2026-07-25 01:01:37.348', NULL, '5aa76c70a4a81e6e66391bbfaea9b85e', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XXY5GNCQEXYAYQEQD0CHM', 'status', 'review', 'done', NULL, '2026-07-25 01:11:56', '2026-07-25 01:11:56.813', '2026-07-25 01:11:56.813', NULL, '16cb46543b844f102adbecb905977b41', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XQW73B1P8WKR2BCZBFXZW', 'description', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.
IMPLEMENTATION REPORT wire shapes for T-1182 (2026-07-25, PR #201): StepCanvasRung = Global (rung 0, variable, one gridunit per region, whole-body, always-kept) | Region 204.8km | District 2048m | Quarter 512m | Block 128m | Chunk 64m (deepest). Global/Region derive via derive_orbital_at_metres; District..Chunk via derive_at_metres. StepCanvasRequest { step_canvas: bool (marker), body_id, rung, center: (i64,i64), extent: (u32,u32), min_wl_m: u32 } sixth Inbound variant. StepCanvasResponse { body_id, rung, center, min_wl_m, status: StepCanvasStatus, canvas: Option<EncodedStepCanvas> } dedicated outbound, NOT on AtlasLayerResponse. EncodedStepCanvas: width, height + 6 static fields (morphology, elev_q, moisture_q, vegetation as PNG-per-field; temp_dc raw Vec<i16> msgpack, settlement_id raw Vec<u32> msgpack too wide for 8-bit PNG) + 2 sim-state (glaciation PNG, flooded_q PNG always-0 stub) + 2 sparse (courses: Vec<RiverCourse>, cliffs: Vec<CliffSegment> always empty today, zero carved cells in the population). settlement_id: 0=none else city_id, a 1500m proximity radius around the settlement anchor point (honest approximation no footprint polygons exist; revisit when quarter-skeleton geometry lands); Global rung reports zero coverage. Rung-0 row space: SIGNED equator-anchored rows (wy=(row-rows/2)*REGION_M, negative=north) per the D-256 canonical core T-1186 interaction documented at build_step_canvas. Caches: GlobalTierCache (BTreeMap by body_id, no eviction API structurally keep-always, lazy D-206 populate) + StepCanvasCache keyed (body_id, rung, center, extent, min_wl_m), dual-axis eviction on get() (storage TTL per rung, Region ~1h..Chunk ~2min; SIM_STATE_TTL seasonal ~1h / tidal ~15min moon-bearing note BodyDrivingClockClass::classify always returns Moonless today, no moon signal on BodyParams). Station-spacing cap adopted: course_station_spacing_m(rung) = rung.spacing_m().max(DISTRICT_M) (COURSE_STATION_SPACING_FLOOR_M). Known stubs: flooded_q always 0, glaciation static (D-253 not built); both wire-shape-ready.', NULL, '2026-07-25 01:21:11', '2026-07-25 01:21:11.774', '2026-07-25 01:21:11.774', NULL, '51c8c51fb6b6509b0ef3de5b63773161', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XQW73B1P8WKR2BCZBFXZW', 'status', 'in_progress', 'review', NULL, '2026-07-25 01:21:19', '2026-07-25 01:21:19.771', '2026-07-25 01:21:19.771', NULL, 'd1db4f86c70195def949676db0f78b20', 2) ON CONFLICT(hash) DO NOTHING;
INSERT INTO ticket_history (ticket_record_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XQW73B1P8WKR2BCZBFXZW', 'description', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.
IMPLEMENTATION REPORT wire shapes for T-1182 (2026-07-25, PR #201): StepCanvasRung = Global (rung 0, variable, one gridunit per region, whole-body, always-kept) | Region 204.8km | District 2048m | Quarter 512m | Block 128m | Chunk 64m (deepest). Global/Region derive via derive_orbital_at_metres; District..Chunk via derive_at_metres. StepCanvasRequest { step_canvas: bool (marker), body_id, rung, center: (i64,i64), extent: (u32,u32), min_wl_m: u32 } sixth Inbound variant. StepCanvasResponse { body_id, rung, center, min_wl_m, status: StepCanvasStatus, canvas: Option<EncodedStepCanvas> } dedicated outbound, NOT on AtlasLayerResponse. EncodedStepCanvas: width, height + 6 static fields (morphology, elev_q, moisture_q, vegetation as PNG-per-field; temp_dc raw Vec<i16> msgpack, settlement_id raw Vec<u32> msgpack too wide for 8-bit PNG) + 2 sim-state (glaciation PNG, flooded_q PNG always-0 stub) + 2 sparse (courses: Vec<RiverCourse>, cliffs: Vec<CliffSegment> always empty today, zero carved cells in the population). settlement_id: 0=none else city_id, a 1500m proximity radius around the settlement anchor point (honest approximation no footprint polygons exist; revisit when quarter-skeleton geometry lands); Global rung reports zero coverage. Rung-0 row space: SIGNED equator-anchored rows (wy=(row-rows/2)*REGION_M, negative=north) per the D-256 canonical core T-1186 interaction documented at build_step_canvas. Caches: GlobalTierCache (BTreeMap by body_id, no eviction API structurally keep-always, lazy D-206 populate) + StepCanvasCache keyed (body_id, rung, center, extent, min_wl_m), dual-axis eviction on get() (storage TTL per rung, Region ~1h..Chunk ~2min; SIM_STATE_TTL seasonal ~1h / tidal ~15min moon-bearing note BodyDrivingClockClass::classify always returns Moonless today, no moon signal on BodyParams). Station-spacing cap adopted: course_station_spacing_m(rung) = rung.spacing_m().max(DISTRICT_M) (COURSE_STATION_SPACING_FLOOR_M). Known stubs: flooded_q always 0, glaciation static (D-253 not built); both wire-shape-ready.', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.
IMPLEMENTATION REPORT wire shapes for T-1182 (2026-07-25, PR #201): StepCanvasRung = Global (rung 0, variable, one gridunit per region, whole-body, always-kept) | Region 204.8km | District 2048m | Quarter 512m | Block 128m | Chunk 64m (deepest). Global/Region derive via derive_orbital_at_metres; District..Chunk via derive_at_metres. StepCanvasRequest { step_canvas: bool (marker), body_id, rung, center: (i64,i64), extent: (u32,u32), min_wl_m: u32 } sixth Inbound variant. StepCanvasResponse { body_id, rung, center, min_wl_m, status: StepCanvasStatus, canvas: Option<EncodedStepCanvas> } dedicated outbound, NOT on AtlasLayerResponse. EncodedStepCanvas: width, height + 6 static fields (morphology, elev_q, moisture_q, vegetation as PNG-per-field; temp_dc raw Vec<i16> msgpack, settlement_id raw Vec<u32> msgpack too wide for 8-bit PNG) + 2 sim-state (glaciation PNG, flooded_q PNG always-0 stub) + 2 sparse (courses: Vec<RiverCourse>, cliffs: Vec<CliffSegment> always empty today, zero carved cells in the population). settlement_id: 0=none else city_id, a 1500m proximity radius around the settlement anchor point (honest approximation no footprint polygons exist; revisit when quarter-skeleton geometry lands); Global rung reports zero coverage. Rung-0 row space: SIGNED equator-anchored rows (wy=(row-rows/2)*REGION_M, negative=north) per the D-256 canonical core T-1186 interaction documented at build_step_canvas. Caches: GlobalTierCache (BTreeMap by body_id, no eviction API structurally keep-always, lazy D-206 populate) + StepCanvasCache keyed (body_id, rung, center, extent, min_wl_m), dual-axis eviction on get() (storage TTL per rung, Region ~1h..Chunk ~2min; SIM_STATE_TTL seasonal ~1h / tidal ~15min moon-bearing note BodyDrivingClockClass::classify always returns Moonless today, no moon signal on BodyParams). Station-spacing cap adopted: course_station_spacing_m(rung) = rung.spacing_m().max(DISTRICT_M) (COURSE_STATION_SPACING_FLOOR_M). Known stubs: flooded_q always 0, glaciation static (D-253 not built); both wire-shape-ready.
WIRE SHAPE ADDENDUM (PR #201 review round): StepCanvasResponse gained an extent: (u32,u32) ECHO field the server-clamped canvas extent, so the client can detect a clamp (mirrors DistrictWindowLayer.n precedent). Wire extent is clamped server-side per D-255(b): STEP_CANVAS_MAX_EXTENT_AXIS=3840 per axis, STEP_CANVAS_MAX_EXTENT_CELLS=8294400 total (aspect-preserving scale-down); Global rung ignores wire extent entirely. T-1182 client must read the echoed extent, never assume its requested one.', NULL, '2026-07-25 01:33:48', '2026-07-25 01:33:48.224', '2026-07-25 01:33:48.224', NULL, '38229b5ea0a6985ce97bc8ce697063b4', 2) ON CONFLICT(hash) DO NOTHING;
+14
View File
@@ -2708,3 +2708,17 @@ INSERT INTO tickets (record_id, type, parent_record_id, title, description, stat
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FSCXX7E3BXT7WG0BYDB6PJA0', 'bug', '06FBPPMZNNEV052DBYYY3A897C', 'Region-baseline latitude is pole-anchored while the derive core keys equator-anchored signed regions — northern hemisphere clamps to +90', 'Found during the PR #199 (T-1174/D-256) review fix round, PRE-EXISTING on the window path since the region climate stack (T-1078/T-1113) was wired into derive_at_metres. region_profile::region_centre_latitude_deg (region_profile.rs ~270-280) maps region row 0 to the north pole (+90) with lat_frac clamped to [0,1] — a pole-anchored, non-negative row convention. But the derive core (derive_at_metres_with_riparian, district_profile.rs ~1788) keys regions by floor-dividing EQUATOR-anchored world metres (negative wy = north), producing signed region rows (Earth-class: -49..+49). Consequence: every northern-hemisphere region has negative row -> region_centre_y_m negative -> lat_frac clamps to 0 -> baseline latitude +90 (polar) regardless of true latitude; southern-hemisphere rows 0..~48 read as compressed NORTHERN latitudes ~89..~0.7 (south pole reads as equator). Affects the region temperature baseline (and glaciation/moisture components derived from it) for the window path at every rung, and post-D-256 the batch/survey path inherits the same keys (still an improvement over the pre-D-256 body-wide region-(0,0) baseline, which read ~+89 everywhere). NOT touched in PR #199 to keep the review round scoped; goldens currently pin the wrong-latitude values. FIX SHAPE: make region_centre_latitude_deg mirror the derive core''s inverse mapping (equator-anchored signed rows: lat = -((ry+0.5)*REGION_M/meridian_m clamped to [-0.5,0.5])*180), audit the OTHER convention''s callers (the D-255 rung-0 canvas row space and the collapsed LayerRegionOutput builder use non-negative pole-anchored rows - decide ONE convention per D-256''s one-inverse-mapping principle, likely at the T-1181 rung-0 rebuild), regen affected goldens, and re-run the believability direction check. Related: D-256, D-243, T-1181, T-1078.
In-the-wild datapoint (2026-07-25, T-1184 eyeball session): GJ338Bd (Arbour, R=6711km) survey cell (42,29) true position latitude -76.2S (wy=8,929,367m, region row 43) derives with the pole-anchored baseline latitude +13.9N, producing an 18C temperate, glaciation-free lake district near the antarctic circle. Concrete demonstration of the southern-hemisphere-reads-as-northern-tropics half of the bug (the northern half clamps to +90). Conversion math used: scratchpad survey_to_district.py, the D-256 bridge formula.', 'backlog', 'high', NULL, 'server', NULL, '2026-07-24 23:30:51.889', '2026-07-25 01:01:37.348', NULL, 'e21a79e29bd911e28ff64a26cd517c0e', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XXY5GNCQEXYAYQEQD0CHM', 'task', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Hydrology into the pipeline: productionize the T-1177 solver + lake morphology sourcing (D-255)', 'Two halves, one ticket (the D-227 lakes amendment''s implementation; converged in araminta-round2.md §(e) + dudley-interview2-response.md CORRECTED section). HALF 1 — productionize: wire server/src/atlas/hydrology_equilibrium.rs (currently an inert workshop prototype, zero non-test callers) into the derive pipeline: solve once per body at rung-0 Global populate (measured ~24ms/body at 512x256; population survey: all 267 bodies ~0.86s), result held with the global tier (D-203-shaped, keep-always). HALF 2 — lake sourcing: MorphologyZone::Lake (discriminant 1 — ALREADY in the frozen D-239 17-zone vocabulary, no widening) becomes sourced from the settled solver: at derive time a gridunit is Lake when bilinear-sampled HydrologyResult.filled_scaled exceeds bilinear-sampled original elevation (the continuous filled-surface comparison — lake edges refine with rung like coastlines, per D-166; NEVER project basin-cell membership as a discrete lookup, which gives blocky non-refining edges), with today''s ocean_fraction_q>=60 heuristic as fallback where no solve exists. This is seed-chaining mechanism B (coarse continuous primitive sampled fresh per rung — D-255(f)). STATIC classification — distinct from the sim-state flooded plane; a lake''s existence must never flicker on a TTL. NO endorheic bit anywhere (ruled: the cue is outflow-course presence, delivered by the separate outlet-wiring ticket; until that lands the map shows lakes without the drains-vs-closed distinction — honest sequencing per D-227 amendment (4)). Byte cost: zero new wire bytes (existing field). Uniform moisture_q=55 scope limit from the survey noted: affects endorheic/overflow split only, never lake extent.
IMPLEMENTATION NOTE (2026-07-25, lead-accepted deviation): the ticket''s ''result held with the global tier (D-203-shaped, keep-always)'' clause could not be satisfied literally no keep-always rung-0 resident tier exists in the codebase yet (BodyWorldStateCache is the D-203 50-body LRU and drops TerrainAnalysis per T-1048). Implemented instead: hydrology solves once per TerrainAnalysis build inside run_layer1/run_layer1_with_moisture (~24ms, mirrors drainage::analyze), carried as TerrainAnalysis.hydrology: Option<HydrologySample> (~1MB), resident wherever TA is resident (TerrainAnalysisCache in gen_queue). When T-1181 builds the actual resident global tier, hydrology rides TA into it with no further wiring. Also: TerrainAnalysisCache::get_or_derive gained a body_params param to thread the real moisture ceiling a known merge seam with the concurrent T-1181 branch (second-to-land rebases). Basin-id/outcome sampling deliberately NOT wired (T-1185 will need its own nearest-sample basin-id lookup if it needs identity beyond outlet-path presence); HydrologyResult.basins spill points computed but currently discarded after filled/elevation extraction cheap to extend at the same call site.', 'done', 'medium', NULL, 'server', 'D-227', '2026-07-24 07:12:17.452', '2026-07-25 01:11:56.813', NULL, 'b3af895faf92eaa19ef7ab581ee45c2f', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XQW73B1P8WKR2BCZBFXZW', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Step-canvas serving: StepCanvasRequest/Response tagged envelope (D-255 wire migration)', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.
IMPLEMENTATION REPORT wire shapes for T-1182 (2026-07-25, PR #201): StepCanvasRung = Global (rung 0, variable, one gridunit per region, whole-body, always-kept) | Region 204.8km | District 2048m | Quarter 512m | Block 128m | Chunk 64m (deepest). Global/Region derive via derive_orbital_at_metres; District..Chunk via derive_at_metres. StepCanvasRequest { step_canvas: bool (marker), body_id, rung, center: (i64,i64), extent: (u32,u32), min_wl_m: u32 } sixth Inbound variant. StepCanvasResponse { body_id, rung, center, min_wl_m, status: StepCanvasStatus, canvas: Option<EncodedStepCanvas> } dedicated outbound, NOT on AtlasLayerResponse. EncodedStepCanvas: width, height + 6 static fields (morphology, elev_q, moisture_q, vegetation as PNG-per-field; temp_dc raw Vec<i16> msgpack, settlement_id raw Vec<u32> msgpack too wide for 8-bit PNG) + 2 sim-state (glaciation PNG, flooded_q PNG always-0 stub) + 2 sparse (courses: Vec<RiverCourse>, cliffs: Vec<CliffSegment> always empty today, zero carved cells in the population). settlement_id: 0=none else city_id, a 1500m proximity radius around the settlement anchor point (honest approximation no footprint polygons exist; revisit when quarter-skeleton geometry lands); Global rung reports zero coverage. Rung-0 row space: SIGNED equator-anchored rows (wy=(row-rows/2)*REGION_M, negative=north) per the D-256 canonical core T-1186 interaction documented at build_step_canvas. Caches: GlobalTierCache (BTreeMap by body_id, no eviction API structurally keep-always, lazy D-206 populate) + StepCanvasCache keyed (body_id, rung, center, extent, min_wl_m), dual-axis eviction on get() (storage TTL per rung, Region ~1h..Chunk ~2min; SIM_STATE_TTL seasonal ~1h / tidal ~15min moon-bearing note BodyDrivingClockClass::classify always returns Moonless today, no moon signal on BodyParams). Station-spacing cap adopted: course_station_spacing_m(rung) = rung.spacing_m().max(DISTRICT_M) (COURSE_STATION_SPACING_FLOOR_M). Known stubs: flooded_q always 0, glaciation static (D-253 not built); both wire-shape-ready.', 'in_progress', 'high', NULL, 'server', 'D-255', '2026-07-24 07:11:27.800', '2026-07-25 01:21:11.774', NULL, 'aadff35baf50abdbc76b9d6ff95bc6b8', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XQW73B1P8WKR2BCZBFXZW', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Step-canvas serving: StepCanvasRequest/Response tagged envelope (D-255 wire migration)', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.
IMPLEMENTATION REPORT wire shapes for T-1182 (2026-07-25, PR #201): StepCanvasRung = Global (rung 0, variable, one gridunit per region, whole-body, always-kept) | Region 204.8km | District 2048m | Quarter 512m | Block 128m | Chunk 64m (deepest). Global/Region derive via derive_orbital_at_metres; District..Chunk via derive_at_metres. StepCanvasRequest { step_canvas: bool (marker), body_id, rung, center: (i64,i64), extent: (u32,u32), min_wl_m: u32 } sixth Inbound variant. StepCanvasResponse { body_id, rung, center, min_wl_m, status: StepCanvasStatus, canvas: Option<EncodedStepCanvas> } dedicated outbound, NOT on AtlasLayerResponse. EncodedStepCanvas: width, height + 6 static fields (morphology, elev_q, moisture_q, vegetation as PNG-per-field; temp_dc raw Vec<i16> msgpack, settlement_id raw Vec<u32> msgpack too wide for 8-bit PNG) + 2 sim-state (glaciation PNG, flooded_q PNG always-0 stub) + 2 sparse (courses: Vec<RiverCourse>, cliffs: Vec<CliffSegment> always empty today, zero carved cells in the population). settlement_id: 0=none else city_id, a 1500m proximity radius around the settlement anchor point (honest approximation no footprint polygons exist; revisit when quarter-skeleton geometry lands); Global rung reports zero coverage. Rung-0 row space: SIGNED equator-anchored rows (wy=(row-rows/2)*REGION_M, negative=north) per the D-256 canonical core T-1186 interaction documented at build_step_canvas. Caches: GlobalTierCache (BTreeMap by body_id, no eviction API structurally keep-always, lazy D-206 populate) + StepCanvasCache keyed (body_id, rung, center, extent, min_wl_m), dual-axis eviction on get() (storage TTL per rung, Region ~1h..Chunk ~2min; SIM_STATE_TTL seasonal ~1h / tidal ~15min moon-bearing note BodyDrivingClockClass::classify always returns Moonless today, no moon signal on BodyParams). Station-spacing cap adopted: course_station_spacing_m(rung) = rung.spacing_m().max(DISTRICT_M) (COURSE_STATION_SPACING_FLOOR_M). Known stubs: flooded_q always 0, glaciation static (D-253 not built); both wire-shape-ready.', 'review', 'high', NULL, 'server', 'D-255', '2026-07-24 07:11:27.800', '2026-07-25 01:21:19.766', NULL, '3e5eca9aa98c0cfa1ef832cf09cc5f70', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);
INSERT INTO tickets (record_id, type, parent_record_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('06FS5XQW73B1P8WKR2BCZBFXZW', 'story', '06FB0TNSRZXCHGS16BFHSSGSV4', 'Step-canvas serving: StepCanvasRequest/Response tagged envelope (D-255 wire migration)', 'The D-225-discharging migration per D-255(c): one new Inbound variant (StepCanvasRequest, required marker field step_canvas, extending the proven star_map/city_names/browse ShapeProbe pattern in server/src/bridge/mod.rs) + a dedicated StepCanvasResponse (NOT a field on AtlasLayerResponse — the D-226 §2 ceiling is re-scoped to the legacy carrier). Serves all six rungs of the D-255(a) ladder — rung-0 Global variable-extent is a field value, not a different shape; fixed rungs viewport-sized per D-255(b). Encoding: PNG-per-field dense (8 fields: 6 static + glaciation/flooded sim-state L8 planes) + MessagePack-native sparse (courses, cliffs) per the T-1179 measured table. SERVER CACHE TIERS ARE THIS TICKET''S SCOPE TOO (SI gap 3): the D-203-shaped resident global tier (~8.85MB population-wide, measured) + TTL(detail, time, distance) for finer rungs + SIM_STATE_TTL[field] = 1x the field''s own fastest driving clock-bucket per body class (flooded: tidal bucket moon-bearing / seasonal moonless; glaciation: seasonal — D-227 amendment (1), Dudley+Araminta joint formula). ACCEPTANCE GATE (SI gap 2, mandatory per D-227 amendment (3)): byte-identical output test — cache-hit derive path == cache-miss derive path for every rung; the seed-chaining cache-accelerated-pure-function correctness gate, same shape as T-1170''s window-independence invariant. Implementation note carried from measurement S2: courses cost +38-87% at chunk/block spacing (station count scales inversely with rung spacing — 1,732 vs 867 points/course measured); a station-spacing cap independent of rung spacing is a named candidate optimization, decision at implementation. Design sources: dudley-round2.md §(a), tyre-round2.md §(b), D-255(c)(d)(f). Legacy district_window survives byte-unchanged until its consumer is replaced.
IMPLEMENTATION REPORT wire shapes for T-1182 (2026-07-25, PR #201): StepCanvasRung = Global (rung 0, variable, one gridunit per region, whole-body, always-kept) | Region 204.8km | District 2048m | Quarter 512m | Block 128m | Chunk 64m (deepest). Global/Region derive via derive_orbital_at_metres; District..Chunk via derive_at_metres. StepCanvasRequest { step_canvas: bool (marker), body_id, rung, center: (i64,i64), extent: (u32,u32), min_wl_m: u32 } sixth Inbound variant. StepCanvasResponse { body_id, rung, center, min_wl_m, status: StepCanvasStatus, canvas: Option<EncodedStepCanvas> } dedicated outbound, NOT on AtlasLayerResponse. EncodedStepCanvas: width, height + 6 static fields (morphology, elev_q, moisture_q, vegetation as PNG-per-field; temp_dc raw Vec<i16> msgpack, settlement_id raw Vec<u32> msgpack too wide for 8-bit PNG) + 2 sim-state (glaciation PNG, flooded_q PNG always-0 stub) + 2 sparse (courses: Vec<RiverCourse>, cliffs: Vec<CliffSegment> always empty today, zero carved cells in the population). settlement_id: 0=none else city_id, a 1500m proximity radius around the settlement anchor point (honest approximation no footprint polygons exist; revisit when quarter-skeleton geometry lands); Global rung reports zero coverage. Rung-0 row space: SIGNED equator-anchored rows (wy=(row-rows/2)*REGION_M, negative=north) per the D-256 canonical core T-1186 interaction documented at build_step_canvas. Caches: GlobalTierCache (BTreeMap by body_id, no eviction API structurally keep-always, lazy D-206 populate) + StepCanvasCache keyed (body_id, rung, center, extent, min_wl_m), dual-axis eviction on get() (storage TTL per rung, Region ~1h..Chunk ~2min; SIM_STATE_TTL seasonal ~1h / tidal ~15min moon-bearing note BodyDrivingClockClass::classify always returns Moonless today, no moon signal on BodyParams). Station-spacing cap adopted: course_station_spacing_m(rung) = rung.spacing_m().max(DISTRICT_M) (COURSE_STATION_SPACING_FLOOR_M). Known stubs: flooded_q always 0, glaciation static (D-253 not built); both wire-shape-ready.
WIRE SHAPE ADDENDUM (PR #201 review round): StepCanvasResponse gained an extent: (u32,u32) ECHO field the server-clamped canvas extent, so the client can detect a clamp (mirrors DistrictWindowLayer.n precedent). Wire extent is clamped server-side per D-255(b): STEP_CANVAS_MAX_EXTENT_AXIS=3840 per axis, STEP_CANVAS_MAX_EXTENT_CELLS=8294400 total (aspect-preserving scale-down); Global rung ignores wire extent entirely. T-1182 client must read the echoed extent, never assume its requested one.', 'review', 'high', NULL, 'server', 'D-255', '2026-07-24 07:11:27.800', '2026-07-25 01:33:48.224', NULL, 'd92ef3d03c1e05c6f17604ee0423f8dd', 2) ON CONFLICT(record_id) DO UPDATE SET type=excluded.type, parent_record_id=excluded.parent_record_id, title=excluded.title, description=excluded.description, status=excluded.status, priority=excluded.priority, assigned_to=excluded.assigned_to, team=excluded.team, decision_ref=excluded.decision_ref, updated_at=excluded.updated_at, deleted_at=excluded.deleted_at, hash=excluded.hash, canonical_version=excluded.canonical_version WHERE excluded.updated_at > tickets.updated_at OR (excluded.updated_at = tickets.updated_at AND excluded.hash > tickets.hash);