The D-225-discharging wire migration per D-255(c): a new step_canvas.rs subsystem serving all six D-255(a) rungs (Global variable-extent opener through 64m Chunk) via a dedicated StepCanvasRequest/StepCanvasResponse tagged envelope on the proven ShapeProbe pattern. Dense fields ship PNG-per-field, sparse courses/cliffs MessagePack-native — the T-1179 measured encoding. Server cache tiers per D-255(d): the structurally keep-always GlobalTierCache plus the dual-axis StepCanvasCache (per-rung storage TTLs; SIM_STATE_TTL clock buckets per the D-227 amendment (1) formula).
The headline deliverable
tests/step_canvas_acceptance_gate.rs — byte-identical cache-hit == cache-miss on every rung (the D-255(f)/D-166 walkable-world protector), plus lossless encode round-trips and cache-vs-fresh-derive equality. 5/5.
Decisions made at implementation discretion
Station-spacing cap ADOPTED: course stations floored to District spacing at finer rungs — kills the S2-measured +38-87% chunk/block course cost with no display loss (COURSE_STATION_SPACING_FLOOR_M).
Rung-0 row space: signed equator-anchored rows per the canonical D-256 core — deliberately NOT replicating either pre-existing pole-anchored convention (which would have made T-1186 a three-way bug). T-1186 itself remains open and unfixed here by instruction; the interaction is documented at build_step_canvas.
Honest gaps, documented not hidden
settlement_id is a 1,500m proximity approximation (no footprint polygons exist yet — named revisit); glaciation/flooded_q sim-state planes are wire-shape-ready D-253 stubs; Global/Region rungs never invent courses (mirrors the legacy path).
Merged main in-branch; the known gen_queue seam resolved (body_params threaded into the shared TerrainAnalysisCache derive so step canvases get the same hydrology-carrying TerrainAnalysis the legacy path does). Acceptance gate + window goldens re-verified green post-merge.
Verification
Legacy district_window byte-unchanged (window_derivation_golden 6/6 incl. the T-1184 lake_bowl rows; all district_window suites unmodified). Full gate green: fmt, clippy -D warnings, 1920 lib + every integration binary, deny. Server-side only — no client consumer exists yet (T-1182 draws these canvases), so no rendered-path change by construction.
Wire-shape reference for T-1182 lives in the implementation report on the ticket.
## Summary
The D-225-discharging wire migration per D-255(c): a new step_canvas.rs subsystem serving all six D-255(a) rungs (Global variable-extent opener through 64m Chunk) via a dedicated StepCanvasRequest/StepCanvasResponse tagged envelope on the proven ShapeProbe pattern. Dense fields ship PNG-per-field, sparse courses/cliffs MessagePack-native — the T-1179 measured encoding. Server cache tiers per D-255(d): the structurally keep-always GlobalTierCache plus the dual-axis StepCanvasCache (per-rung storage TTLs; SIM_STATE_TTL clock buckets per the D-227 amendment (1) formula).
## The headline deliverable
tests/step_canvas_acceptance_gate.rs — byte-identical cache-hit == cache-miss on every rung (the D-255(f)/D-166 walkable-world protector), plus lossless encode round-trips and cache-vs-fresh-derive equality. 5/5.
## Decisions made at implementation discretion
- Station-spacing cap ADOPTED: course stations floored to District spacing at finer rungs — kills the S2-measured +38-87% chunk/block course cost with no display loss (COURSE_STATION_SPACING_FLOOR_M).
- Rung-0 row space: signed equator-anchored rows per the canonical D-256 core — deliberately NOT replicating either pre-existing pole-anchored convention (which would have made T-1186 a three-way bug). T-1186 itself remains open and unfixed here by instruction; the interaction is documented at build_step_canvas.
## Honest gaps, documented not hidden
settlement_id is a 1,500m proximity approximation (no footprint polygons exist yet — named revisit); glaciation/flooded_q sim-state planes are wire-shape-ready D-253 stubs; Global/Region rungs never invent courses (mirrors the legacy path).
## Post-merge integration (T-1184 lakes landed first)
Merged main in-branch; the known gen_queue seam resolved (body_params threaded into the shared TerrainAnalysisCache derive so step canvases get the same hydrology-carrying TerrainAnalysis the legacy path does). Acceptance gate + window goldens re-verified green post-merge.
## Verification
Legacy district_window byte-unchanged (window_derivation_golden 6/6 incl. the T-1184 lake_bowl rows; all district_window suites unmodified). Full gate green: fmt, clippy -D warnings, 1920 lib + every integration binary, deny. Server-side only — no client consumer exists yet (T-1182 draws these canvases), so no rendered-path change by construction.
Wire-shape reference for T-1182 lives in the implementation report on the ticket.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
The D-225-discharging wire migration per D-255(c): a new
server/src/atlas/step_canvas.rs subsystem (six-rung StepCanvasRung
ladder — Global variable-extent rung 0 through Chunk 64m — the
StepCanvasRequest/StepCanvasResponse tagged envelope extending the
proven ShapeProbe discriminated-shape pattern, PNG-per-field dense +
MessagePack-native sparse encoding per the T-1179 measured table, and
both server cache tiers: the structurally keep-always GlobalTierCache
and the dual-axis StepCanvasCache with storage TTLs per rung and
SIM_STATE_TTL clock-bucket staleness per the D-227 amendment (1)
formula). Wired through bridge/{mod,tcp,local}.rs (sixth demux shape,
send_step_canvas_response mirroring the five existing senders),
gen_queue.rs (DeriveStepCanvas work item with per-connection-per-rung
coalescing, reusing the shared TerrainAnalysisCache), and plugin.rs
(serve/complete systems, lazy D-206 rung-0 population).
Acceptance gate (mandatory per D-227 amendment (3)):
tests/step_canvas_acceptance_gate.rs — cache-hit == cache-miss
byte-identical for every rung, lossless encode round-trips, cache
round-trips vs fresh derive, distinct-center sanity. 5/5 pass.
Station-spacing cap ADOPTED: course stations floored to District
spacing (2,048 m) at finer rungs — the S2-measured +38-87% chunk/block
course cost had zero display benefit at the same station density
(COURSE_STATION_SPACING_FLOOR_M).
Documented honest gaps, not shortcuts: settlement_id is a proximity
approximation (no footprint polygons exist yet); glaciation/flooded_q
sim-state planes are wire-shape-ready D-253 stubs; rung-0 uses signed
equator-anchored rows (the canonical D-256 core convention — T-1186's
wrong-latitude behavior applies unchanged and unfixed here, by
instruction).
Legacy district_window carrier byte-unchanged: window_derivation_golden
6/6 byte-identical, all district_window suites pass unmodified. Full
suite at implementation time: 2127 passed across 45 binaries.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The T-1184 merge seam: TerrainAnalysisCache::get_or_derive gained a
body_params parameter (real moisture ceiling for the hydrology solve);
the DeriveStepCanvas arm now passes its own body_params so step-canvas
requests get the same hydrology-carrying TerrainAnalysis the legacy
DeriveWindow path does. Acceptance gate + window goldens green
post-merge.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Two needless mutable borrows in the serve system, one spurious
markdown list marker from a doc-comment line wrap (a leading '- '
turned the whole T-1186 convention note into a lazy continuation), and
a named row/col pair replacing the identity-op grid index in the
settlement-id tie test.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Hoshe finding 1: StepCanvasRequest.extent is no longer wire-trusted —
clamp_step_canvas_extent enforces the D-255(b) canvas budget at the
request boundary (per-axis cap 3840 defeating u32::MAX before any
multiplication, then an aspect-preserving total-cell ceiling at the
measured 3840x2160 = 8,294,400-cell workshop budget), mirroring the
legacy carrier's clamp_window_n_v2 discipline; the Global rung ignores
the wire extent entirely. StepCanvasResponse gains the extent echo
field so a client can detect the clamp (the DistrictWindowLayer.n
precedent — a pre-existing gap closed in passing, recorded on the
ticket for T-1182). Seven new tests including an end-to-end u32::MAX
request proving actual allocation respects the cap.
Hoshe finding 2: submit_step_canvas coalescing now has the same two
regression tests its submit_window sibling always had (same-key
collapses to one pending item, different-key does not), exercising
step_canvas_supersede_key.
Targeted suites green: 1928 lib, acceptance gate 5/5, bridge_tcp 22/22,
window_derivation_golden 6/6 byte-green.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Clause-by-clause D-255 conformance verified against the record: dedicated StepCanvasResponse (never a field on AtlasLayerResponse), the ShapeProbe marker extension matches the proven pattern incl. union-rejection, rung 0's variable extent is a field value not a second shape, and the legacy district_window carrier is genuinely byte-unchanged (two pub(crate) visibility widenings only, confirmed via diff). Cache tiers match D-255(d) precisely — GlobalTierCache structurally keep-always (no eviction API exists on the type), dual-axis staleness/storage eviction per the D-227 amendment, SIM_STATE_TTL formula fidelity confirmed against the workshop source, and the Moonless-classifier stub honestly documented. The acceptance gate is the correct D-255(f) gate, checked at three levels across all six rungs; mechanism-A prohibition holds by construction (no seed-chaining acceleration exists yet — stated plainly in the test's own docs). Both implementation-discretion calls ruled sound and unusually well-documented: the station-spacing cap does not touch T-1170's global arc-length parametrization, and the signed equator-anchored rung-0 rows are the D-256-consistent choice with the T-1186 interaction documented in exhaustive, accurate detail. D-010 discipline intact (BTreeMap, ordered indexed par_iter, no float structural gates). ShapeProbe still the right seam at six shapes. No comments.
Hoshe (Code Quality): REQUEST_CHANGES (2 findings — both fixed, see author response)
Core subsystem verified well-executed: the row-chunked derive genuinely mirrors build_district_window_layer's cell-placement math, antimeridian/pole handling correctly delegates to the shared D-256 core, the temp_dc sentinel clamp is byte-identical to existing call sites, the acceptance gate is non-vacuous, and the sixth demux shape correctly guards mutual exclusivity.
Unclamped wire extent — a real DoS surface: width*height allocations + rayon derive reachable with (u32::MAX, u32::MAX); no analogue of the legacy carrier's documented "never trust window_n from the wire" clamp.
Finding 1: clamp_step_canvas_extent now enforces the D-255(b) canvas budget at the request boundary — per-axis cap of 3,840 (defeating u32::MAX before any multiplication), then an aspect-preserving total-cell ceiling at the measured 3840x2160 = 8,294,400-cell workshop budget, mirroring clamp_window_n_v2's two-stage discipline; the Global rung ignores the wire extent entirely. In passing, a real pre-existing gap closed: StepCanvasResponse now echoes the (clamped) extent so a client can detect the clamp (the DistrictWindowLayer.n precedent) — recorded on the ticket as a T-1182 contract note ("read the echoed extent, never assume your requested one"). Seven new tests, including an end-to-end u32::MAX request proving actual allocation respects the cap.
Finding 2: submit_step_canvas now has the same two regression tests as its sibling (same-key collapses to one pending item; different-key does not), exercising step_canvas_supersede_key.
Round confined to step_canvas.rs / gen_queue.rs / plugin.rs; no touch to hydrology or legacy-carrier code. Targeted suites green: 1928 lib, acceptance gate 5/5, bridge_tcp 22/22, window_derivation_golden 6/6 byte-green. Gate re-run on push.
Verdict: CHANGES REQUESTED -> resolved; merging on gate green
No screenshot eyeball for this PR by construction: the envelope has zero client consumers until T-1182 (server-side only, legacy carrier byte-unchanged and golden-pinned).
## Review: t1181-step-canvas -> main (type: code)
### Tyre (Architecture): APPROVE
Clause-by-clause D-255 conformance verified against the record: dedicated StepCanvasResponse (never a field on AtlasLayerResponse), the ShapeProbe marker extension matches the proven pattern incl. union-rejection, rung 0's variable extent is a field value not a second shape, and the legacy district_window carrier is genuinely byte-unchanged (two pub(crate) visibility widenings only, confirmed via diff). Cache tiers match D-255(d) precisely — GlobalTierCache structurally keep-always (no eviction API exists on the type), dual-axis staleness/storage eviction per the D-227 amendment, SIM_STATE_TTL formula fidelity confirmed against the workshop source, and the Moonless-classifier stub honestly documented. The acceptance gate is the correct D-255(f) gate, checked at three levels across all six rungs; mechanism-A prohibition holds by construction (no seed-chaining acceleration exists yet — stated plainly in the test's own docs). Both implementation-discretion calls ruled sound and unusually well-documented: the station-spacing cap does not touch T-1170's global arc-length parametrization, and the signed equator-anchored rung-0 rows are the D-256-consistent choice with the T-1186 interaction documented in exhaustive, accurate detail. D-010 discipline intact (BTreeMap, ordered indexed par_iter, no float structural gates). ShapeProbe still the right seam at six shapes. No comments.
### Hoshe (Code Quality): REQUEST_CHANGES (2 findings — both fixed, see author response)
Core subsystem verified well-executed: the row-chunked derive genuinely mirrors build_district_window_layer's cell-placement math, antimeridian/pole handling correctly delegates to the shared D-256 core, the temp_dc sentinel clamp is byte-identical to existing call sites, the acceptance gate is non-vacuous, and the sixth demux shape correctly guards mutual exclusivity.
| # | File | Issue |
|---|------|-------|
| 1 | step_canvas.rs (resolve_canvas_extent / StepCanvasRequest.extent) | Unclamped wire extent — a real DoS surface: width*height allocations + rayon derive reachable with (u32::MAX, u32::MAX); no analogue of the legacy carrier's documented "never trust window_n from the wire" clamp. |
| 2 | gen_queue.rs (submit_step_canvas / step_canvas_supersede_key) | Near-verbatim sibling of submit_window shipped with zero test coverage, while the sibling has two dedicated coalescing regression tests. |
## Author response — both fixed in 8af28f317
**Finding 1**: clamp_step_canvas_extent now enforces the D-255(b) canvas budget at the request boundary — per-axis cap of 3,840 (defeating u32::MAX before any multiplication), then an aspect-preserving total-cell ceiling at the measured 3840x2160 = 8,294,400-cell workshop budget, mirroring clamp_window_n_v2's two-stage discipline; the Global rung ignores the wire extent entirely. In passing, a real pre-existing gap closed: StepCanvasResponse now echoes the (clamped) extent so a client can detect the clamp (the DistrictWindowLayer.n precedent) — recorded on the ticket as a T-1182 contract note ("read the echoed extent, never assume your requested one"). Seven new tests, including an end-to-end u32::MAX request proving actual allocation respects the cap.
**Finding 2**: submit_step_canvas now has the same two regression tests as its sibling (same-key collapses to one pending item; different-key does not), exercising step_canvas_supersede_key.
Round confined to step_canvas.rs / gen_queue.rs / plugin.rs; no touch to hydrology or legacy-carrier code. Targeted suites green: 1928 lib, acceptance gate 5/5, bridge_tcp 22/22, window_derivation_golden 6/6 byte-green. Gate re-run on push.
### Verdict: CHANGES REQUESTED -> resolved; merging on gate green
*No screenshot eyeball for this PR by construction: the envelope has zero client consumers until T-1182 (server-side only, legacy carrier byte-unchanged and golden-pinned).*
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
Summary
The D-225-discharging wire migration per D-255(c): a new step_canvas.rs subsystem serving all six D-255(a) rungs (Global variable-extent opener through 64m Chunk) via a dedicated StepCanvasRequest/StepCanvasResponse tagged envelope on the proven ShapeProbe pattern. Dense fields ship PNG-per-field, sparse courses/cliffs MessagePack-native — the T-1179 measured encoding. Server cache tiers per D-255(d): the structurally keep-always GlobalTierCache plus the dual-axis StepCanvasCache (per-rung storage TTLs; SIM_STATE_TTL clock buckets per the D-227 amendment (1) formula).
The headline deliverable
tests/step_canvas_acceptance_gate.rs — byte-identical cache-hit == cache-miss on every rung (the D-255(f)/D-166 walkable-world protector), plus lossless encode round-trips and cache-vs-fresh-derive equality. 5/5.
Decisions made at implementation discretion
Honest gaps, documented not hidden
settlement_id is a 1,500m proximity approximation (no footprint polygons exist yet — named revisit); glaciation/flooded_q sim-state planes are wire-shape-ready D-253 stubs; Global/Region rungs never invent courses (mirrors the legacy path).
Post-merge integration (T-1184 lakes landed first)
Merged main in-branch; the known gen_queue seam resolved (body_params threaded into the shared TerrainAnalysisCache derive so step canvases get the same hydrology-carrying TerrainAnalysis the legacy path does). Acceptance gate + window goldens re-verified green post-merge.
Verification
Legacy district_window byte-unchanged (window_derivation_golden 6/6 incl. the T-1184 lake_bowl rows; all district_window suites unmodified). Full gate green: fmt, clippy -D warnings, 1920 lib + every integration binary, deny. Server-side only — no client consumer exists yet (T-1182 draws these canvases), so no rendered-path change by construction.
Wire-shape reference for T-1182 lives in the implementation report on the ticket.
🤖 Generated with Claude Code
The D-225-discharging wire migration per D-255(c): a new server/src/atlas/step_canvas.rs subsystem (six-rung StepCanvasRung ladder — Global variable-extent rung 0 through Chunk 64m — the StepCanvasRequest/StepCanvasResponse tagged envelope extending the proven ShapeProbe discriminated-shape pattern, PNG-per-field dense + MessagePack-native sparse encoding per the T-1179 measured table, and both server cache tiers: the structurally keep-always GlobalTierCache and the dual-axis StepCanvasCache with storage TTLs per rung and SIM_STATE_TTL clock-bucket staleness per the D-227 amendment (1) formula). Wired through bridge/{mod,tcp,local}.rs (sixth demux shape, send_step_canvas_response mirroring the five existing senders), gen_queue.rs (DeriveStepCanvas work item with per-connection-per-rung coalescing, reusing the shared TerrainAnalysisCache), and plugin.rs (serve/complete systems, lazy D-206 rung-0 population). Acceptance gate (mandatory per D-227 amendment (3)): tests/step_canvas_acceptance_gate.rs — cache-hit == cache-miss byte-identical for every rung, lossless encode round-trips, cache round-trips vs fresh derive, distinct-center sanity. 5/5 pass. Station-spacing cap ADOPTED: course stations floored to District spacing (2,048 m) at finer rungs — the S2-measured +38-87% chunk/block course cost had zero display benefit at the same station density (COURSE_STATION_SPACING_FLOOR_M). Documented honest gaps, not shortcuts: settlement_id is a proximity approximation (no footprint polygons exist yet); glaciation/flooded_q sim-state planes are wire-shape-ready D-253 stubs; rung-0 uses signed equator-anchored rows (the canonical D-256 core convention — T-1186's wrong-latitude behavior applies unchanged and unfixed here, by instruction). Legacy district_window carrier byte-unchanged: window_derivation_golden 6/6 byte-identical, all district_window suites pass unmodified. Full suite at implementation time: 2127 passed across 45 binaries. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>Review: t1181-step-canvas -> main (type: code)
Tyre (Architecture): APPROVE
Clause-by-clause D-255 conformance verified against the record: dedicated StepCanvasResponse (never a field on AtlasLayerResponse), the ShapeProbe marker extension matches the proven pattern incl. union-rejection, rung 0's variable extent is a field value not a second shape, and the legacy district_window carrier is genuinely byte-unchanged (two pub(crate) visibility widenings only, confirmed via diff). Cache tiers match D-255(d) precisely — GlobalTierCache structurally keep-always (no eviction API exists on the type), dual-axis staleness/storage eviction per the D-227 amendment, SIM_STATE_TTL formula fidelity confirmed against the workshop source, and the Moonless-classifier stub honestly documented. The acceptance gate is the correct D-255(f) gate, checked at three levels across all six rungs; mechanism-A prohibition holds by construction (no seed-chaining acceleration exists yet — stated plainly in the test's own docs). Both implementation-discretion calls ruled sound and unusually well-documented: the station-spacing cap does not touch T-1170's global arc-length parametrization, and the signed equator-anchored rung-0 rows are the D-256-consistent choice with the T-1186 interaction documented in exhaustive, accurate detail. D-010 discipline intact (BTreeMap, ordered indexed par_iter, no float structural gates). ShapeProbe still the right seam at six shapes. No comments.
Hoshe (Code Quality): REQUEST_CHANGES (2 findings — both fixed, see author response)
Core subsystem verified well-executed: the row-chunked derive genuinely mirrors build_district_window_layer's cell-placement math, antimeridian/pole handling correctly delegates to the shared D-256 core, the temp_dc sentinel clamp is byte-identical to existing call sites, the acceptance gate is non-vacuous, and the sixth demux shape correctly guards mutual exclusivity.
Author response — both fixed in
8af28f317Finding 1: clamp_step_canvas_extent now enforces the D-255(b) canvas budget at the request boundary — per-axis cap of 3,840 (defeating u32::MAX before any multiplication), then an aspect-preserving total-cell ceiling at the measured 3840x2160 = 8,294,400-cell workshop budget, mirroring clamp_window_n_v2's two-stage discipline; the Global rung ignores the wire extent entirely. In passing, a real pre-existing gap closed: StepCanvasResponse now echoes the (clamped) extent so a client can detect the clamp (the DistrictWindowLayer.n precedent) — recorded on the ticket as a T-1182 contract note ("read the echoed extent, never assume your requested one"). Seven new tests, including an end-to-end u32::MAX request proving actual allocation respects the cap.
Finding 2: submit_step_canvas now has the same two regression tests as its sibling (same-key collapses to one pending item; different-key does not), exercising step_canvas_supersede_key.
Round confined to step_canvas.rs / gen_queue.rs / plugin.rs; no touch to hydrology or legacy-carrier code. Targeted suites green: 1928 lib, acceptance gate 5/5, bridge_tcp 22/22, window_derivation_golden 6/6 byte-green. Gate re-run on push.
Verdict: CHANGES REQUESTED -> resolved; merging on gate green
No screenshot eyeball for this PR by construction: the envelope has zero client consumers until T-1182 (server-side only, legacy carrier byte-unchanged and golden-pinned).
Pull request closed