The complete workshop record: four round-1 positions, five round-2 syntheses (incl. Troblum's adversarial pass with addendum + final scorecard — all seven findings resolved), both lead interviews, Qatux's round notes and the 8-section workshop-outcomes.md (the lakes message-crossing documented as process history), measurement ⑥ (set_pixel/c1) + the population-survey and chunk/S2 addenda in the measurement docs, the brief's appendix updated through ⑥, and architecture-briefing-final.md — Jeroen's outline written back as-built (six-level ladder, lakes, ~9MB resident global tier). README row: Complete. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
315 lines
21 KiB
Markdown
315 lines
21 KiB
Markdown
---
|
||
title: "Round 1 Notes — Body Map Viewer Workshop"
|
||
description: "Compiled record of Round 1 positions: per-question summary, cross-agent agreements, conflicts/tensions, the open-for-synthesis decision list, and scope-drift check against settled premises."
|
||
type: workshop
|
||
status: active
|
||
workshop: body-map-viewer
|
||
agent: qatux
|
||
round: 1
|
||
created: 2026-07-25
|
||
---
|
||
|
||
# Body Map Viewer — Round 1 Notes
|
||
|
||
**Compiled by:** Qatux
|
||
**Round:** 1 — Positions against the measured appendix
|
||
**Participants:** Dudley, Araminta, Stig, Tyre (Troblum is round 2 only)
|
||
**Sources:** [dudley-round1.md](dudley-round1.md), [araminta-round1.md](araminta-round1.md),
|
||
[stig-round1.md](stig-round1.md), [tyre-round1.md](tyre-round1.md)
|
||
|
||
All four positions are argued from the measured appendix (①–⑤,
|
||
[the brief's appendix](body-map-viewer-workshop-brief.md#pre-workshop-measurement-appendix))
|
||
with no extrapolation beyond what was measured — each agent says so explicitly and
|
||
the citations check out against the four measurement docs.
|
||
|
||
---
|
||
|
||
## 1. Per-question position summary
|
||
|
||
### Dudley — server derivation (hydrology, step-canvas generation, chunking, cache tiers)
|
||
|
||
1. **Hydrology algorithm:** adopt T-1177's priority-flood + Dijkstra prototype as-is
|
||
(production-shaped, not throwaway). Cost: ~24 ms/body single-threaded at 512×256;
|
||
all 273 bodies in parallel ≈ 0.7–0.8 s; solved once per body (like `drainage::analyze`
|
||
today), held in a D-203-shaped cache, never re-solved per step/request.
|
||
2. **Cliff representation:** `elevation` (unchanged) + `channel_depth: u16` +
|
||
`cliff_edge: bool` — direct, non-lossy carry of solver output, no min/max synthesis.
|
||
Gorge carving measured **structurally rare** (zero carved cells across all three
|
||
production-scale benches) — weakens, doesn't eliminate, the wire-cost argument.
|
||
Explicitly defers the Phase-4-vs-Phase-5 scope call to Tyre/Araminta.
|
||
3. **Canonical-vs-viewport (red flag 3):** **viewport-sized canvases at every step,
|
||
no canonical fixed canvas past the orbital/region rung** — argued as a governance
|
||
necessity (D-226(d)), not merely a cache-cost preference. Fixed pixel budget per
|
||
canvas (e.g. 3840×2160), not literal client viewport echo.
|
||
4. **Compute-chunk partitioning:** the existing row-chunked `into_par_iter()` loop in
|
||
`build_district_window_layer` holds flat (190–220 ns/cell) at every measured size
|
||
and spacing — "the single most load-bearing measured result across all four gates."
|
||
Flags that courses are excluded from the replica-loop numbers (small, bounded tax,
|
||
not a different order of magnitude) and that chunking-as-seed-input-for-next-tier
|
||
is unmeasured, an open data-flow question for round 2/implementation.
|
||
5. **Cache tiers:** global/orbital tier only, "always keep" ≈ ~174 MB PNG-encoded
|
||
across all 273 bodies, as a D-203-shaped resource extension (not SQLite — cost
|
||
doesn't force it). Everything finer: `TTL = BASE_TTL[rung] × time_decay ×
|
||
distance_decay`, no disk tier below orbital.
|
||
|
||
### Araminta — named-feature encoding, per-gridunit payload, encoding continuity
|
||
|
||
1. **Named-feature encoding is three decisions, not one**, per the existing carrier
|
||
three-way rule: settlements/POIs → ids-with-lookup against the already-built
|
||
`atlas_city_names` pool (D-223) — presence + id per gridunit, never inline name.
|
||
Rivers → geometry already settled (T-1170 Ruling 1c `courses`); adds a new
|
||
whole-body `river_names: BTreeMap<edge_id, String>` lookup, many-edges-to-one-name.
|
||
Roads: out of scope but the pattern generalizes for free when they land.
|
||
2. **Payload schema:** the existing six dense fields stay as-is (no new classification
|
||
vocabulary); one new dense field `settlement_id: Vec<u32>`; the cliff fields are
|
||
**sparse, not dense** — a `cliffs: Vec<CliffSegment>` list parallel to `courses`,
|
||
not two more mostly-zero dense arrays (this differs from Dudley's dense-field framing
|
||
— see Conflicts below). States a hard client rule: color/style/tween presentation
|
||
only, never invent geometry/flooding/cliffs — missing data is a schema gap, not a
|
||
license to interpolate.
|
||
3. **Encoding continuity:** one colorizer family confirmed across every step (same
|
||
field set, same enum vocabularies, only sampling density changes). Average-back is
|
||
safe for continuous fields (`elev_q`/`temp_dc`/`moisture_q`) but **meaningless for
|
||
categorical fields** (`morphology`/`vegetation`/`glaciation`) — coarser steps must
|
||
re-derive via dominant-mode/plurality pick, never arithmetic mean. "Clearings/ponds
|
||
at low zoom" is scoped as sub-zone octave detail within an existing classification,
|
||
not new vocabulary — no new wire field needed.
|
||
4. **Wire-contract summary for synthesis:** confirms PNG-per-field for all dense arrays,
|
||
MessagePack-native for sparse lists; confirms the payload is categorically over the
|
||
30 KB cap at every size regardless of her additions — doesn't change the
|
||
tagged-envelope verdict.
|
||
|
||
### Stig — client component, step-cross UX, overlay compositing, cache store
|
||
|
||
1. **Client structure:** kill `_canvas.scale` entirely — two sibling layers replace it:
|
||
RTT terrain/classification layer (texel-exact `ImageTexture`, generalizing the
|
||
existing `_build_tile_texture`/`_rebuild_texture_if_needed` mosaic path from
|
||
per-tile to universal) + an unscaled screen-space annotation layer (world→screen
|
||
transform per frame, literal px sizes, deletes `_zs()`/`_zs_stroke()`/
|
||
`_zs_ring_radius()` by construction). T-1158 (viewer decomposition) is **subsumed**
|
||
— recommends cancellation with a supersession note, not separate scheduling.
|
||
2. **Step-cross UX:** hold-fetch-swap baseline (cursor-anchored), cache-hit swaps
|
||
immediately, cache-miss holds the current texture magnified during fetch (bounded
|
||
by measurement ①/④: uncached 330K canvas ≈ 75 ms derive + 5 ms encode). Morph/tween
|
||
is real but **strictly cosmetic and sequenced after** the baseline ships, as an
|
||
optional toggle. Upload cost (⑤) confirmed non-gating; prefers `texture.update()`
|
||
reuse over fresh allocation (avoids Texture object churn, despite being marginally
|
||
slower in raw ms) and L8 wherever a plane is single-channel.
|
||
3. **Overlay compositing (c1):** **ship CPU `set_pixel` coloring first**, not shaders
|
||
— today's code already does this and works; nothing in ①–⑤ prices CPU coloring cost
|
||
at step-canvas scale (330K–8.3M cells), which Stig names explicitly as **the missing
|
||
sixth measurement** (`Image.set_pixel` cost at those sizes). Shader migration is the
|
||
natural landing spot for T-1175's tapering work later, not a precondition for the
|
||
ladder itself.
|
||
4. **Client cache store:** **(iii) plain `FileAccess` cache dir + index** — rejects both
|
||
(i) server-side SQLite (relocates a client decision onto the server's process
|
||
boundary, dilutes the "server owns the DB" mental model) and (ii) godot-sqlite (a
|
||
relational addon for a point-lookup-with-expiry access pattern that doesn't need
|
||
one). Two-tier eviction: geometry entries get LRU + a retention floor at step-0
|
||
(the concrete "always keep global" mechanism, disk-budget-safe at ~440 MB where RAM
|
||
would not be); sim-state-tagged entries get an explicit TTL sweep (the literal
|
||
self-cleaning behavior Jeroen asked for). In-memory `atlas_window_tile_set.gd`-style
|
||
LRU stays on top as the hot tier.
|
||
|
||
### Tyre — governance ratification, gridunit↔D-243, determinism boundary, cliff ruling
|
||
|
||
1. **Governance delta ratified as concrete amendment texts** (five, drafted and ready
|
||
to file): D-166 corollary repoint (per-step derivation floor + display ratio,
|
||
between-step magnification named as a bounded exception not a silent violation);
|
||
T-1143 ruling 3 superseded for zoom transport only (cursor-centering/edge-scroll/
|
||
full-reset survive); `select_rung`/coverage-walk replaced by the step index;
|
||
**tagged-envelope migration ruled triggered, not merely likely** (21×–563× over
|
||
the ceiling, "off by two to three orders of magnitude before encoding is even
|
||
considered"); T-1170 carrier rule survives with a terminology gloss only
|
||
("windowed payload" → "tagged step-canvas envelope").
|
||
2. **Gridunit↔D-243 — the load-bearing call: gridunit SNAPS to D-243 rungs, does not
|
||
float.** Argued from determinism (`derive_at_metres` on viewport-relative spacing
|
||
would contaminate the cache key with a presentation parameter, breaking premise 9's
|
||
"canvas for a fixed seed never changes") and from cost (measurement ③ shows no
|
||
derivation-cost reason to invent a seventh spacing value — the six D-243 rungs
|
||
already cover every depth cheaply). What floats instead: the **display ratio**
|
||
(px-per-gridunit, 1×1 to 5×5), a pure client-side presentation parameter, decoupled
|
||
from spacing. Files the D-243 gridunit vocabulary entry as "a role, not a new rung."
|
||
3. **Determinism boundary:** generalizes the T-1170 course-invention ruling into a
|
||
three-bucket test — legal client interpolation is interpolation over a **closed,
|
||
server-supplied input set** (two arrived textures, wire-carried control points);
|
||
illegal is inventing any sample outside that set or smoothing across a step/
|
||
truncation/cliff boundary. Three concrete legal cases named (step-cross morph,
|
||
river/road curve-fitting through wire-carried stations, texture-to-viewport
|
||
scaling), two illegal (upsampling terrain detail, blending across a step boundary
|
||
as if continuous), one gray case flagged for Araminta (label de-dup at coarse-step
|
||
seams — legal only if identity, not proximity, drives it).
|
||
4. **Cliff ruling:** adopts Dudley's dominant-height + `channel_depth` + `cliff_edge`
|
||
representation outright (settled by what the solver emits, zero re-derivation).
|
||
**Rules Phase-4 Atlas scope, not deferred to Phase-5** — argues deferral would
|
||
silently contradict "settled hydrology" itself (a map showing a smooth shoreline
|
||
where the solver computed a carved channel misrepresents the settled state), and
|
||
that the rarity finding makes inclusion nearly free rather than making exclusion
|
||
safe. Flags his own caveat: rarity is measured on one real body (GJ1c) + two
|
||
synthetics, not surveyed across ~273 bodies — names this explicitly as something
|
||
for Troblum's round-2 adversarial pass to stress.
|
||
|
||
---
|
||
|
||
## 2. Cross-agent agreements (settled going into round 2 — do not re-litigate)
|
||
|
||
- **Dudley, Araminta, Tyre** all treat the **tagged-envelope migration as settled by
|
||
the numbers**, not a round-2 open question. Each cites T-1179 independently and
|
||
lands on the same order-of-magnitude reading (21×–563× over the 30 KB cap). Tyre's
|
||
position sharpens the brief's "likely triggers" framing to "triggered, unambiguous."
|
||
Round 2 should treat *whether* as closed and spend synthesis time only on the
|
||
*shape* of the tagged envelope (which is genuinely open — see §4).
|
||
- **Dudley and Tyre** independently land on **viewport-sized canvases, no canonical
|
||
fixed canvas past the orbital/region rung** — Dudley from cost-shape-plus-D-226(d)
|
||
necessity, Tyre from the same D-226(d) argument plus the determinism/cache-key
|
||
argument in his gridunit↔D-243 ruling. These are two independently-argued paths to
|
||
the same conclusion, not one agent citing the other — worth naming as convergent,
|
||
not coincidental.
|
||
- **Dudley, Araminta, and Tyre all adopt the T-1177 cliff representation
|
||
(`elevation` + `channel_depth` + `cliff_edge`) without dispute.** The only open
|
||
edge is dense-vs-sparse wire shape (§3) and Phase scope (§3), not the field set
|
||
itself.
|
||
- **Araminta and Tyre agree explicitly** that the client may never invent
|
||
geometry/flooding/cliff state — Araminta states it as a payload-schema hard rule,
|
||
Tyre generalizes it into the three-bucket determinism-boundary test. Same
|
||
conclusion, complementary framings (schema discipline vs. interpolation discipline).
|
||
- **Stig and Dudley/Araminta agree** that morph/tween between steps is real,
|
||
cosmetic-only, and non-blocking for the baseline — Stig sequences it as a
|
||
follow-up after hold-fetch-swap ships; Tyre's bucket-A ruling gives it the
|
||
determinism green light; nobody argues for shipping it in the first cut.
|
||
- **All four agents report their four gated measurements (①–④) as clean GO/VIABLE
|
||
results with no extrapolation** — no agent treats any of the pre-workshop numbers
|
||
as contested or requiring a re-run.
|
||
|
||
---
|
||
|
||
## 3. Conflicts and tensions (named, not yet resolved)
|
||
|
||
- **Dudley vs. Araminta — dense vs. sparse wire shape for the cliff fields.** Dudley's
|
||
round-1 text frames `channel_depth`/`cliff_edge` as "the wire field" without
|
||
specifying dense-array vs. sparse-list shape, and his cost argument ("cheap under
|
||
any of the encodings in ④'s table... PNG's DEFLATE in particular loves a field
|
||
that's constant almost everywhere") reads as implicitly assuming dense per-gridunit
|
||
arrays alongside the other six. Araminta explicitly rejects that shape: "as dense
|
||
per-gridunit arrays would be wasteful given near-zero occupancy" and proposes a
|
||
sparse `cliffs: Vec<CliffSegment>` list parallel to `courses` instead. Tyre's
|
||
synthesis leans toward Araminta's read ("I'd steer toward 'new arrays' over 'steal
|
||
a bit'... a sparse-friendly encoding... helps this field cost less than its raw
|
||
byte width suggests" — but this sentence is ambiguous on dense-vs-sparse, using
|
||
"new arrays" language while endorsing a sparse-friendly encoding argument).
|
||
**This needs an explicit round-2 resolution, not an inferred one** — the three
|
||
positions are close but not identical, and "new arrays" (Tyre) vs. "sparse feature
|
||
list, not arrays" (Araminta) is a real implementation-shape fork even if the wire
|
||
bytes converge.
|
||
- **Stig vs. the brief's implicit assumption — shader-vs-CPU (c1) is not close to
|
||
resolved, and Stig's position is a deferral, not an answer.** The brief posed c1 as
|
||
"genuinely open for the workshop"; Stig's position doesn't rule for CPU on the
|
||
merits so much as rule for CPU *by default* pending a measurement that doesn't
|
||
exist yet. This isn't a disagreement with another agent (no one else took a
|
||
position on c1), but it is a gap between what the brief expected round 1 to
|
||
produce (a position) and what it got (a sequencing recommendation plus a flagged
|
||
missing measurement) — surfaced here so the lead interview doesn't mistake "ship
|
||
CPU first" for "shader question closed."
|
||
- **Scope-boundary tension, not a disagreement: Dudley defers the Phase-4-vs-Phase-5
|
||
cliff-scope call to "Tyre/Araminta," and Tyre rules on it unilaterally** ("Phase-4
|
||
Atlas scope, not deferred to Phase-5") in the same round without an explicit
|
||
Araminta sign-off in her own document (her round-1 text adopts the field shape but
|
||
does not independently address the Phase-4-vs-Phase-5 question at all). Tyre's
|
||
ruling may be correct and well-argued, but strictly by the documents, it is a
|
||
two-of-three-invited-parties call, not a three-way confirmed one — worth a direct
|
||
Araminta confirm-or-object in round 2 rather than treating it as fully closed.
|
||
|
||
---
|
||
|
||
## 4. OPEN-FOR-SYNTHESIS decision list (for the lead interview)
|
||
|
||
Carried into Jeroen's Round 1 lead interview and/or Round 2 synthesis, in the order
|
||
the brief's Expected Outputs raises them:
|
||
|
||
1. **Step count and step factor** (largest → visible tile) — every agent treats this
|
||
as still-open and downstream of their own numbers; Dudley's table gives per-rung
|
||
costs but explicitly does not propose a step count. This is the brief's own
|
||
Jeroen-interview question 2 and remains unanswered by round 1.
|
||
2. **Map time axis** (climatology vs. current sim state for frozen/flooded) — not
|
||
addressed head-on by any of the four round-1 documents beyond Araminta's schema
|
||
table flagging it as "where the outline's sea/flooded distinction needs a decision
|
||
the workshop, not me, should rule on." Still fully open; this is Jeroen-interview
|
||
question 1.
|
||
3. **Tagged-envelope migration shape** (not the yes/no, which is agreed — see §2 —
|
||
but the concrete framing: new IPC message type, demux mechanics, how the legacy
|
||
`district_window` carrier coexists) — Tyre's amendment text names the destination
|
||
but defers the mechanical design; this is round-2 synthesis work.
|
||
4. **Cliff field wire shape: dense arrays vs. sparse feature list** — the Dudley/
|
||
Araminta/Tyre tension in §3, needs an explicit round-2 call, not an inferred one.
|
||
5. **Cliff field Phase-4 vs. Phase-5 scope** — Tyre ruled Phase-4; Araminta has not
|
||
independently confirmed; the §3 two-of-three tension needs closing explicitly.
|
||
6. **Shader-vs-CPU styling (c1)** — Stig's position is "CPU first, sequence shader
|
||
later," not a resolution of the open question the brief posed. **Depends on the
|
||
missing sixth measurement (below) before it can be treated as settled even
|
||
provisionally.**
|
||
7. **NEW: the missing sixth measurement — `Image.set_pixel` cost at 330K/2.07M/8.3M
|
||
cells (GDScript, client-side).** Stig names this explicitly as a gap: nothing in
|
||
measurements ①–⑤ prices CPU per-cell coloring cost at step-canvas scale, and the
|
||
c1 shader-vs-CPU call cannot be made "with the same rigor as everything else in
|
||
this brief" without it. This should be added to the measurement appendix (as ⑥)
|
||
or explicitly scoped as a round-2/pre-implementation follow-up — flagging per the
|
||
coordinator's instruction that this lands in the decision list, not just Stig's
|
||
own document.
|
||
8. **Chunking-as-seed-input-for-next-tier data flow** — Dudley flags this as
|
||
unmeasured and architecturally undecided (does a finer step re-derive independently
|
||
from `(seed, position)`, or literally consume the coarser step's output values?).
|
||
His own cost measurements assume independent re-derivation; round 2 needs to either
|
||
confirm that assumption or scope a new cost pass if the alternative is preferred.
|
||
9. **Region-as-step-0 confirmation** — Tyre's §1e amendment note flags this needs
|
||
confirming with Araminta in round 2 synthesis ("Region likely IS the global/step-0
|
||
rung, worth confirming").
|
||
10. **The gray determinism case — label placement de-duplication at step seams** —
|
||
Tyre flags this explicitly as unresolved and hands it to Araminta's named-feature
|
||
call; not yet addressed in her document.
|
||
|
||
---
|
||
|
||
## 5. Scope-drift check against settled premises
|
||
|
||
No round-1 document relitigates a settled premise (1–9) or a "settled by round A"
|
||
clarification-round item. Specific checks:
|
||
|
||
- **Stepped zoom, vocabulary (tile vs. gridunit), data-resolution tunable, hydrology
|
||
as deterministic equilibrium** — all four agents use the settled vocabulary and
|
||
model correctly throughout; no drift back to continuous zoom or "tile" misuse
|
||
detected in any of the four documents.
|
||
- **Server-determines-content / client-draws-art (premise 2)** — held firmly by all
|
||
four; Araminta's explicit client-rule statement and Tyre's determinism-boundary
|
||
bucket test both *reinforce* this premise rather than erode it. No agent proposes
|
||
client-side derivation of any invented-detail category.
|
||
- **CPU/Rust-server-side-only derivation, GPU presentation-only (premise 2, the c2
|
||
pre-empt)** — untouched; Stig's shader discussion (c1) is explicitly about
|
||
*styling/coloring already-derived data*, not derivation, and he states this
|
||
distinction himself. No drift toward GPU-side derivation anywhere in round 1.
|
||
- **One caution, not a violation:** Stig's structural recommendation to cancel
|
||
T-1158 outright (not just note supersession) is a **ticket-plan action**, one
|
||
category beyond a "position" — it's appropriate content for round 1 (the brief's
|
||
Expected Output 2 explicitly wants conflicting tickets named), but it is a
|
||
concrete cancellation recommendation rather than a design position, worth the lead
|
||
noting as an actionable item distinct from the architecture questions proper.
|
||
- **No Phase-5/Phase-6 drag detected.** Stig explicitly declines to scope Phase-5
|
||
reuse speculatively ("I don't want to speculatively design against now — that
|
||
would be exactly the kind of later-phase drag the cascade discipline warns
|
||
against") — this is the correct cascade-discipline call, named here because it's
|
||
a positive scope-discipline example, not a violation.
|
||
|
||
---
|
||
|
||
## Summary for the lead interview
|
||
|
||
Round 1 produced four internally consistent, cross-citing positions with **no cost
|
||
surprises** — every measured gate came back GO, and three of the four agents
|
||
converge on viewport-sized canvases and the tagged-envelope migration independently.
|
||
The genuinely open items are load-bearing but narrow: step count itself, the map
|
||
time axis, the cliff field's wire shape (dense vs. sparse) and phase scope, the
|
||
shader-vs-CPU call (blocked on a **new, named missing measurement** —
|
||
`Image.set_pixel` cost at step-canvas scale), and two smaller synthesis-confirmation
|
||
items (chunking/seed-input data flow, Region-as-step-0). Nothing here requires
|
||
relitigating a settled premise, and no scope drift toward later cascade phases was
|
||
observed.
|