Files
settled-reach/docs/workshops/body-map-viewer/round-1-notes.md
T
jpmschweitzerandClaude Fable 5 29c22cb728 docs(meta): body-map-viewer workshop — rounds, measurements, outcomes, as-built briefing
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>
2026-07-24 10:57:45 +02:00

315 lines
21 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
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.70.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 (190220 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 (330K8.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 (19) 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.