diff --git a/.pql/changelog/ticket_history/2026-06.sql b/.pql/changelog/ticket_history/2026-06.sql index d6c006e9f..3bd08dde4 100644 --- a/.pql/changelog/ticket_history/2026-06.sql +++ b/.pql/changelog/ticket_history/2026-06.sql @@ -74,3 +74,28 @@ Refinement (2026-05-23, /whats-next): Design (D-226, Araminta, 2026-05-24) — human-visual layer of the inspection harness. Extend OVERLAY_DEFS / AtlasOverlayBar with a generation overlay group (second row) + a left-side legend panel; do NOT build a separate viewer. Encoding: relief base; rivers as blue polylines (mouths = double-circle markers, confluences where in-degree >= 3); basin fills very translucent + thin boundary polylines; attractors as markers where SHAPE encodes the 7 AttractorTypes (circle/half-circle/diamond/down-tri/up-tri/hollow-circle/square) and COLOR encodes sub-biome (shape carries identity in headless/monochrome; color is additive); size scales with strength, skip strength < 0.15. Stable button ids gen_l0_heightmap / gen_l1_rivers / gen_l1_basins / gen_l1_attractors; start pending/locked, unlock+activate via notify_gen_layer_ready(id) as data arrives (grows as layers land, D-166). Consumes the live proxy (#969); the agent channel (#971) drives this same UI. Remaining to close (Si sweep 2026-06-07): add the gen_l0_heightmap overlay to OVERLAY_DEFS + render path in atlas_viewer.gd / atlas_marker_overlay.gd — required by the D-226/T-960 acceptance criteria but currently absent. Layer-1 overlays (rivers/basins/attractors) + proxy wire + pending indicator are already implemented; this Layer-0 overlay is the sole remaining piece.', NULL, '2026-06-07 08:40:15', '2026-06-07 08:40:15', '2026-06-07 08:40:15', NULL, 'f7e6ccc4036a83f06ec6301b6bfe738b', 1) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'description', 'Wire Layer-3 settlement placement to Layer-4 quarter generation so the already-implemented Layer-4 geometry runs in production with real per-settlement orientation. Today there is NO production call site that dispatches GenerateSkeleton from a placement: city_context_reader.rs:484 stubs founding_orientation=Cardinal, so the implemented D-234b waterfront rule (and morphology-correct streets) stay dormant. + +Scope: on GenCompletion::BodyAnalyzed, iterate state.placements and submit one GenerateSkeleton work item per placed settlement, building CityGenerationContext from each CityPlacement (context_from_read_set, city_context_reader.rs:~462) and overriding founding_orientation with the attractor-matched CityPlacement.founding_orientation (already computed in attractor_matching.rs:~535, carried on CityPlacement:~63). + +Call sites: plugin.rs BodyAnalyzed handler (~84), gen_queue.rs GenerateSkeleton arm, city_context_reader.rs (stub at 484), attractor_matching.rs. Q-109 (multi-source/station dispatch) is adjacent but non-blocking for the planetary path. Surfaced by Si vetting (2026-06-07): T-976/989/990/991 geometry is done+tested but dormant without this dispatch.', 'Wire Layer-3 settlement placement to Layer-4 quarter generation so the already-implemented Layer-4 geometry runs in production with real per-settlement orientation. Today there is NO production call site that dispatches GenerateSkeleton from a placement: city_context_reader.rs:484 stubs founding_orientation=Cardinal, so the implemented D-234b waterfront rule (and morphology-correct streets) stay dormant. + +Scope: on GenCompletion::BodyAnalyzed, iterate state.placements and submit one GenerateSkeleton work item per placed settlement, building CityGenerationContext from each CityPlacement (context_from_read_set, city_context_reader.rs:~462) and overriding founding_orientation with the attractor-matched CityPlacement.founding_orientation (already computed in attractor_matching.rs:~535, carried on CityPlacement:~63). + +Call sites: plugin.rs BodyAnalyzed handler (~84), gen_queue.rs GenerateSkeleton arm, city_context_reader.rs (stub at 484), attractor_matching.rs. Q-109 (multi-source/station dispatch) is adjacent but non-blocking for the planetary path. Surfaced by Si vetting (2026-06-07): T-976/989/990/991 geometry is done+tested but dormant without this dispatch. + +--- +Refinement (Si, 2026-06-07) — READY: + +Wiring point: drain_generation_completions in server/src/atlas/plugin.rs:78. The BodyAnalyzed arm (line 84) currently calls cache.insert(state) and discards placements. Expand it: after cache insert, iterate state.placements (Vec, body_world_state.rs:85) and submit one GenWorkItem::GenerateSkeleton per placement. System signature grows by Option> + Option> (world_seed), mirroring serve_atlas_requests; both already imported. + +Per placement: ctx = reader.build_context(placement.city_id, world_seed) (city_context_reader.rs:221) -> read_set -> context_from_read_set -> CityGenerationContext. Override the stub: ctx.founding_orientation = placement.founding_orientation.clone() (the one field stubbed Cardinal at city_context_reader.rs:484; value computed by founding_orientation() at attractor_matching.rs:535, carried on CityPlacement:63 from attractor.water_bearing + territorial_status). + +GenerateSkeleton other fields: economic_role/population/founding_age_years from reader.read_set() CityEconomicReadSet (call read_set directly to capture them; carried separately per gen_queue.rs:93-108). body_id = state.body_id.clone(). chain = SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id) (Layer4Quarter at seed.rs:92; mirrors Layer3Settlement use at city_context_reader.rs:389). + +DECISION for implementer (no open Q, one-liner): quarter_id has no canonical derivation yet (test placeholder city_id*10). Use SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id).seed() — deterministic, namespace-isolated; add a comment referencing D-194/D-230. + +Edge cases: empty state.placements -> loop submits nothing, returns normally (no special case). Q-109 (station/multi-source dispatch) non-blocking — BodyAnalyzed only fires on the planetary AnalyzeBody path; stations have no AnalyzeBody enqueue site yet. + +Verified: Layer-4 geometry (D-234a/b) fully implemented in server/src/atlas/skeleton_gen.rs (derive_corridors reads morphology_zone, derive_access_points reads road_entry_directions, waterfront rule ~108-113 reads founding_orientation). Only the dispatch is dormant.', NULL, '2026-06-07 10:42:27', '2026-06-07 10:42:27', '2026-06-07 10:42:27', NULL, 'aa1911b38c699f46e21fed37aacde669', 1) ON CONFLICT(hash) DO NOTHING; +INSERT INTO ticket_history (ticket_id, field, old_value, new_value, changed_by, changed_at, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'status', 'backlog', 'in_progress', NULL, '2026-06-07 10:44:24', '2026-06-07 10:44:24', '2026-06-07 10:44:24', NULL, 'bae44ce724f650962ff7d1d27aafd2bc', 1) ON CONFLICT(hash) DO NOTHING; diff --git a/.pql/changelog/tickets/2026-06.sql b/.pql/changelog/tickets/2026-06.sql index 94a7cbb65..a21b82cf1 100644 --- a/.pql/changelog/tickets/2026-06.sql +++ b/.pql/changelog/tickets/2026-06.sql @@ -241,3 +241,43 @@ INSERT INTO tickets (id, type, parent_id, title, description, status, priority, INSERT INTO tickets (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1029', 'task', 'T-974', 'Specialized morphology geometry generators (7 families)', 'D-239 sections 5,8. Implement LavaField, FjordWall, CliffCoast, BraidedDelta, DuneStrand, IncisedGorge, MeanderReach geometry on the F1 VoxelColumn pipeline. Each honours the binding believability laws (drainage monotonicity / D8 thalweg; lithology->landform; glaciation->form U-valleys/moraines/cirques) and game-feel chokepoint widths (river crossings 3-15m, gorge floors 2-8m). Validate per-family <5ms/chunk (FjordWall/IncisedGorge are far costlier than the AlluvialPlain fallback). May split per-family during refinement. Blocked by the F1 pipeline.', 'backlog', 'high', NULL, 'server', 'D-239', '2026-06-07 10:34:11', '2026-06-07 10:34:11', NULL, 'e3525f555af182a432047c3672537d14', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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 (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1030', 'task', 'T-974', 'Scattered transient freeze/snow model', 'D-239 section 3. Phase transition as a band with deterministic spatially-coherent scatter (clustered patches, never per-tile dice): freshwater (lakes/rivers) +5 to -10 C district mean (the +5 is night-frost reaching the coldest tiles); sea ice own lower/wider band (~-2 onset, pack-ice sheets+leads pattern); snow (land) moisture-gated. TRANSIENT in the marginal band — forms in the cold phase, melts in the warm phase (day/night, season) -> time-of-day passability shifts. The transient/clock-bound portion is a forward contract to Q-105 (region seasonal/clock state); the static scattered model is buildable now. Blocked by climate-derived fields.', 'backlog', 'medium', NULL, 'server', 'D-239', '2026-06-07 10:34:11', '2026-06-07 10:34:11', NULL, 'cbde57e8b0c344ac6503725a091cccd9', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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 (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1031', 'task', 'T-974', 'Believability + determinism + <5ms budget verification harness', 'D-239 sections 1,8,9. Golden-seed regression for the binding laws (drainage monotonicity, lithology->landform, glaciation->form with no glacial-U on GlaciationGrade 0, climate->vegetation no-skip + riparian band), per-family <5ms/chunk budget assertion, and the validation-case bodies: Kallast=alluvial plain/Soil, Velen=tidal-flat/dune coast (VERIFY it has a moon param for the tidal term first), Cygni B=volcanic immature drainage, Ross 128=ocean island terrain, Gruenfeld=marginal Gravel/Scrub. If a body reads wrong, fix its params — never patch the derivation (D-239 section 1). Blocked by the family generators.', 'backlog', 'high', NULL, 'server', 'D-239', '2026-06-07 10:34:11', '2026-06-07 10:34:11', NULL, '0cbe7fe1f7c2bfcdf36a62f709fa68b7', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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 (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'story', 'T-750', 'Layer-3 -> Layer-4 GenerateSkeleton dispatch (founding_orientation wiring)', 'Wire Layer-3 settlement placement to Layer-4 quarter generation so the already-implemented Layer-4 geometry runs in production with real per-settlement orientation. Today there is NO production call site that dispatches GenerateSkeleton from a placement: city_context_reader.rs:484 stubs founding_orientation=Cardinal, so the implemented D-234b waterfront rule (and morphology-correct streets) stay dormant. + +Scope: on GenCompletion::BodyAnalyzed, iterate state.placements and submit one GenerateSkeleton work item per placed settlement, building CityGenerationContext from each CityPlacement (context_from_read_set, city_context_reader.rs:~462) and overriding founding_orientation with the attractor-matched CityPlacement.founding_orientation (already computed in attractor_matching.rs:~535, carried on CityPlacement:~63). + +Call sites: plugin.rs BodyAnalyzed handler (~84), gen_queue.rs GenerateSkeleton arm, city_context_reader.rs (stub at 484), attractor_matching.rs. Q-109 (multi-source/station dispatch) is adjacent but non-blocking for the planetary path. Surfaced by Si vetting (2026-06-07): T-976/989/990/991 geometry is done+tested but dormant without this dispatch. + +--- +Refinement (Si, 2026-06-07) — READY: + +Wiring point: drain_generation_completions in server/src/atlas/plugin.rs:78. The BodyAnalyzed arm (line 84) currently calls cache.insert(state) and discards placements. Expand it: after cache insert, iterate state.placements (Vec, body_world_state.rs:85) and submit one GenWorkItem::GenerateSkeleton per placement. System signature grows by Option> + Option> (world_seed), mirroring serve_atlas_requests; both already imported. + +Per placement: ctx = reader.build_context(placement.city_id, world_seed) (city_context_reader.rs:221) -> read_set -> context_from_read_set -> CityGenerationContext. Override the stub: ctx.founding_orientation = placement.founding_orientation.clone() (the one field stubbed Cardinal at city_context_reader.rs:484; value computed by founding_orientation() at attractor_matching.rs:535, carried on CityPlacement:63 from attractor.water_bearing + territorial_status). + +GenerateSkeleton other fields: economic_role/population/founding_age_years from reader.read_set() CityEconomicReadSet (call read_set directly to capture them; carried separately per gen_queue.rs:93-108). body_id = state.body_id.clone(). chain = SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id) (Layer4Quarter at seed.rs:92; mirrors Layer3Settlement use at city_context_reader.rs:389). + +DECISION for implementer (no open Q, one-liner): quarter_id has no canonical derivation yet (test placeholder city_id*10). Use SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id).seed() — deterministic, namespace-isolated; add a comment referencing D-194/D-230. + +Edge cases: empty state.placements -> loop submits nothing, returns normally (no special case). Q-109 (station/multi-source dispatch) non-blocking — BodyAnalyzed only fires on the planetary AnalyzeBody path; stations have no AnalyzeBody enqueue site yet. + +Verified: Layer-4 geometry (D-234a/b) fully implemented in server/src/atlas/skeleton_gen.rs (derive_corridors reads morphology_zone, derive_access_points reads road_entry_directions, waterfront rule ~108-113 reads founding_orientation). Only the dispatch is dormant.', 'backlog', 'high', NULL, 'server', 'D-234', '2026-06-07 08:10:17', '2026-06-07 10:42:27', NULL, '1b00995a914a6e77a530bc449b71d0d5', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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 (id, type, parent_id, title, description, status, priority, assigned_to, team, decision_ref, created_at, updated_at, deleted_at, hash, canonical_version) VALUES ('T-1022', 'story', 'T-750', 'Layer-3 -> Layer-4 GenerateSkeleton dispatch (founding_orientation wiring)', 'Wire Layer-3 settlement placement to Layer-4 quarter generation so the already-implemented Layer-4 geometry runs in production with real per-settlement orientation. Today there is NO production call site that dispatches GenerateSkeleton from a placement: city_context_reader.rs:484 stubs founding_orientation=Cardinal, so the implemented D-234b waterfront rule (and morphology-correct streets) stay dormant. + +Scope: on GenCompletion::BodyAnalyzed, iterate state.placements and submit one GenerateSkeleton work item per placed settlement, building CityGenerationContext from each CityPlacement (context_from_read_set, city_context_reader.rs:~462) and overriding founding_orientation with the attractor-matched CityPlacement.founding_orientation (already computed in attractor_matching.rs:~535, carried on CityPlacement:~63). + +Call sites: plugin.rs BodyAnalyzed handler (~84), gen_queue.rs GenerateSkeleton arm, city_context_reader.rs (stub at 484), attractor_matching.rs. Q-109 (multi-source/station dispatch) is adjacent but non-blocking for the planetary path. Surfaced by Si vetting (2026-06-07): T-976/989/990/991 geometry is done+tested but dormant without this dispatch. + +--- +Refinement (Si, 2026-06-07) — READY: + +Wiring point: drain_generation_completions in server/src/atlas/plugin.rs:78. The BodyAnalyzed arm (line 84) currently calls cache.insert(state) and discards placements. Expand it: after cache insert, iterate state.placements (Vec, body_world_state.rs:85) and submit one GenWorkItem::GenerateSkeleton per placement. System signature grows by Option> + Option> (world_seed), mirroring serve_atlas_requests; both already imported. + +Per placement: ctx = reader.build_context(placement.city_id, world_seed) (city_context_reader.rs:221) -> read_set -> context_from_read_set -> CityGenerationContext. Override the stub: ctx.founding_orientation = placement.founding_orientation.clone() (the one field stubbed Cardinal at city_context_reader.rs:484; value computed by founding_orientation() at attractor_matching.rs:535, carried on CityPlacement:63 from attractor.water_bearing + territorial_status). + +GenerateSkeleton other fields: economic_role/population/founding_age_years from reader.read_set() CityEconomicReadSet (call read_set directly to capture them; carried separately per gen_queue.rs:93-108). body_id = state.body_id.clone(). chain = SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id) (Layer4Quarter at seed.rs:92; mirrors Layer3Settlement use at city_context_reader.rs:389). + +DECISION for implementer (no open Q, one-liner): quarter_id has no canonical derivation yet (test placeholder city_id*10). Use SeedChain::for_body(world_seed,&body_id).derive(SeedDomain::Layer4Quarter, placement.city_id).seed() — deterministic, namespace-isolated; add a comment referencing D-194/D-230. + +Edge cases: empty state.placements -> loop submits nothing, returns normally (no special case). Q-109 (station/multi-source dispatch) non-blocking — BodyAnalyzed only fires on the planetary AnalyzeBody path; stations have no AnalyzeBody enqueue site yet. + +Verified: Layer-4 geometry (D-234a/b) fully implemented in server/src/atlas/skeleton_gen.rs (derive_corridors reads morphology_zone, derive_access_points reads road_entry_directions, waterfront rule ~108-113 reads founding_orientation). Only the dispatch is dormant.', 'in_progress', 'high', NULL, 'server', 'D-234', '2026-06-07 08:10:17', '2026-06-07 10:44:24', NULL, '31b663a2d5dbb8ad823ff3d54f8a4f1f', 1) ON CONFLICT(id) DO UPDATE SET type=excluded.type, parent_id=excluded.parent_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); diff --git a/docs/briefings/clide-team-mode-friction.md b/docs/briefings/clide-team-mode-friction.md index 7e30f01d3..a79909659 100644 --- a/docs/briefings/clide-team-mode-friction.md +++ b/docs/briefings/clide-team-mode-friction.md @@ -83,3 +83,29 @@ earlier is unrelated background sessions, not this teammate.) This sharpens the **Workaround taken this session.** Kept Tyre's delivered round-1; ran the rest of the Q-101 workshop as **background Agent subagents** (the Si/reviewer pattern), which DO surface in clide's normal Claude activity flow — i.e. avoid `teammateMode` teammates until the team-chat view is wired to the mailbox. + +### FINDING T2 — background agent + out-of-root worktree is a sandbox dead-end — 2026-06-07 + +**What.** Spawned a background Agent (not a `teammateMode` teammate) to implement a server ticket in +an isolated git worktree at `/var/mnt/data/projects/settled-reach/.worktrees/` — a *sibling* +of the session root `/var/mnt/data/projects/settled-reach/main`. The agent could Read/Grep/cargo fine +and produced a complete design, but **every `Edit`/`Write` was denied**: sandboxed file writes are +confined to the session's project root, so the sibling `.worktrees/` path is unwritable — by the +agent *and* by the lead. It is not a clide permission toggle; there is nothing to "grant." + +**Impact.** The whole background-agent-in-worktree isolation pattern is unusable under the current +sandbox: the agent burns a full run designing, then blocks at the first write. The user (reasonably) +looked for a permission to grant and found none. Fallback was to drop the worktree and implement in +the main checkout on the branch. + +**Suggested fixes (for the clide team).** +1. Create agent/teammate worktrees *inside* the writable root (e.g. `main/.worktrees/`), or +2. Extend the sandbox's writable root to cover the repo's sibling worktrees, or +3. At minimum, fail fast with one clear up-front error ("worktree path is outside the writable root") + instead of per-`Edit` denials that read as a grantable permission. + +### Positive — `clide image show` works well — 2026-06-07 + +`clide image show --caption "..."` rendered and displayed a generated diagram first try, with a +clean `{shown:true}` return. A solid parity data point alongside the team-mode gaps — the observe/drive +surface (D-6) is sound where it's wired; the gap is specifically team-mode rendering, not the CLI model.