diff --git a/crates/ghostlight-dungeon/src/bin/ghostlight-gestalt-dynamics-smoke.rs b/crates/ghostlight-dungeon/src/bin/ghostlight-gestalt-dynamics-smoke.rs index d3a6cd3..9293042 100644 --- a/crates/ghostlight-dungeon/src/bin/ghostlight-gestalt-dynamics-smoke.rs +++ b/crates/ghostlight-dungeon/src/bin/ghostlight-gestalt-dynamics-smoke.rs @@ -375,7 +375,7 @@ async fn main() -> anyhow::Result<()> { let mut rejected_wave_pulses = Vec::new(); let mut background_subject_ids = BTreeSet::new(); let mut detail_focus_subject_ids = BTreeSet::new(); - detail_focus_subject_ids.extend(root_cell.detail_focus_subject_id.clone()); + detail_focus_subject_ids.extend(direct_resolution_subject_ids(&output.wave.cover.cells)); let sustained_budgets = if fairness_stress_waves == 0 { vec![4_u8, 8, 4] } else { @@ -474,14 +474,9 @@ async fn main() -> anyhow::Result<()> { } } } - detail_focus_subject_ids.extend( - sustained_output - .wave - .cover - .cells - .iter() - .filter_map(|cell| cell.detail_focus_subject_id.clone()), - ); + detail_focus_subject_ids.extend(direct_resolution_subject_ids( + &sustained_output.wave.cover.cells, + )); for stage in &sustained_output.stages { store.insert( "persona_stage_receipt.v1", @@ -679,6 +674,22 @@ fn lineage_depth( Ok(depth) } +#[cfg(windows)] +fn direct_resolution_subject_ids( + cells: &[ghostlight_dungeon::domain::SimulationCell], +) -> std::collections::BTreeSet { + cells + .iter() + .filter_map(|cell| cell.detail_focus_subject_id.clone()) + .chain( + cells + .iter() + .filter(|cell| cell.subject_ids.len() == 1) + .flat_map(|cell| cell.subject_ids.iter().cloned()), + ) + .collect() +} + #[cfg(windows)] fn dynamics_campaign() -> ghostlight_dungeon::domain::Campaign { use chrono::{Duration, Utc}; diff --git a/docs/architecture/ghostlight-multiresolution-agency.md b/docs/architecture/ghostlight-multiresolution-agency.md index ceece90..2ff8fb5 100644 --- a/docs/architecture/ghostlight-multiresolution-agency.md +++ b/docs/architecture/ghostlight-multiresolution-agency.md @@ -569,6 +569,11 @@ graph. Migration, relation changes, fission, or activation can therefore break a leased cell and force replanning immediately. Cover validation reports empty, duplicate, disconnected, content-ID, and false-cohesion failures separately. +Fairness accounting uses the same definition as canonical detail debt: an +explicit aggregate `detail_focus_subject_id` and every singleton cell both +receive direct resolution attention. A named focus is not required for a +subject already receiving its own complete Persona pipeline. + The run also exposes the next authority gap. Institution postures, population migration, clocks, and history changed canonically, but most Gestalt activities remain attributed attempts recorded as events. Over many ticks this can repeat diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 4e94053..d007848 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -271,6 +271,12 @@ A regression constructs a still-leased formerly connected cover whose groups are disconnected under the current graph. Validation now names the exact cover fault instead of returning one generic invalid-cell message. +The fixed budget-4 run then completed all 24 ticks but the harness falsely +reported `relief-union` missing: that institution was a singleton in every +cover, so `advance_detail_debt` correctly treated it as directly resolved while +the harness counted only explicit aggregate focus labels. Acceptance now uses +the canonical union of explicit focus plus singleton subjects. + Do not call setting-wide material agency finished yet. Most population output is still an attributed `gestalt_activity` attempt stored as history. The long run became repetitive around ferry loading and shelter requests because no diff --git a/state/map.yaml b/state/map.yaml index c6f73b1..ad0c2ef 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -268,5 +268,5 @@ data_flow: current_status: summary: GhostlightDungeon production remains on the verified Starfire release. Multiresolution pressure proves the callback, nested diaspora, fairness, and scale matrix. Lease-preserving pressure exposed two hidden faults now cut: redundant controls manufactured epochs, and migrated topology could leave a disconnected leased cell alive. Production state remains untouched. - next_action: Rerun lease-preserving long profiles at budgets 4 and 8 with independent provider parallelism. Require covers to survive valid leases and replan immediately around migration-broken adjacency. Then map strategic outcome ownership after attributed cell attempts without granting Interpreter outcome authority. + next_action: Rerun the lease-preserving budget-4 profile with canonical singleton-plus-focus fairness accounting, then test budget 8 with independent provider parallelism. Require covers to survive valid leases and replan immediately around migration-broken adjacency. gestalt_population: Gestalt Personas own shared population baselines; persistent member deltas own named individuality; WorldKernel materialization and approval-gated fission preserve lineage and identity. Presence projection is limited to nearby active leaves and exact-location dormant members. Simulation cells are derived covers only.