Reconcile civic bindings across gestalt fission
This commit is contained in:
parent
74ea14db56
commit
8a81ea2c1d
9 changed files with 547 additions and 12 deletions
|
|
@ -228,6 +228,8 @@ fn main() -> Result<()> {
|
|||
},
|
||||
"subjectDirectory": subjects,
|
||||
"locations": campaign.locations,
|
||||
"civicSystems": campaign.civic_systems,
|
||||
"agencyRelations": campaign.agency_relations,
|
||||
"latestStrategicTick": latest_tick,
|
||||
"cover": cover,
|
||||
"appraisals": appraisals,
|
||||
|
|
|
|||
|
|
@ -1221,6 +1221,47 @@ async fn main() -> anyhow::Result<()> {
|
|||
}
|
||||
let player_before = campaign.actors[&campaign.player_actor_id].clone();
|
||||
let kernel = WorldKernel::start(store.clone());
|
||||
let civic_reconciliation_path = root.join("fission-civic-reconciliation.json");
|
||||
if resume
|
||||
&& ghostlight_dungeon::legacy_transition::fission_civic_reconciliation_required(&campaign)
|
||||
{
|
||||
if civic_reconciliation_path.is_file() {
|
||||
anyhow::bail!(
|
||||
"fission civic reconciliation checkpoint exists but canonical repair is absent"
|
||||
)
|
||||
}
|
||||
let committed = kernel
|
||||
.command(WorldCommand::ReconcileFissionCivicBindings {
|
||||
expected_revision: campaign.revision,
|
||||
})
|
||||
.await?;
|
||||
let CommandResult::Committed {
|
||||
campaign: advanced,
|
||||
receipt,
|
||||
} = committed
|
||||
else {
|
||||
anyhow::bail!("fission civic reconciliation did not commit")
|
||||
};
|
||||
publish_immutable_checkpoint(
|
||||
&civic_reconciliation_path,
|
||||
&serde_json::json!({
|
||||
"schema":"ghostlight.fission_civic_reconciliation_checkpoint.v1",
|
||||
"receipt":receipt,
|
||||
}),
|
||||
)?;
|
||||
campaign = advanced;
|
||||
} else if civic_reconciliation_path.is_file() {
|
||||
let checkpoint: serde_json::Value = read_checkpoint(&civic_reconciliation_path)?;
|
||||
let revision = checkpoint["receipt"]["revision"]
|
||||
.as_u64()
|
||||
.ok_or_else(|| anyhow::anyhow!("fission civic reconciliation receipt is malformed"))?;
|
||||
if checkpoint["schema"] != "ghostlight.fission_civic_reconciliation_checkpoint.v1"
|
||||
|| checkpoint["receipt"]["command_kind"] != "reconcile_fission_civic_bindings"
|
||||
|| revision > campaign.revision
|
||||
{
|
||||
anyhow::bail!("fission civic reconciliation checkpoint disagrees with campaign")
|
||||
}
|
||||
}
|
||||
let region_requests = std::env::var("GHOSTLIGHT_WORLD_REGION_REQUESTS")
|
||||
.ok()
|
||||
.map(|value| {
|
||||
|
|
|
|||
|
|
@ -1236,6 +1236,9 @@ pub enum WorldCommand {
|
|||
#[serde(default)]
|
||||
model_stage_receipts: Vec<crate::model::ModelStageReceipt>,
|
||||
},
|
||||
ReconcileFissionCivicBindings {
|
||||
expected_revision: u64,
|
||||
},
|
||||
ExpandRegion {
|
||||
expected_revision: u64,
|
||||
expansion: RegionExpansion,
|
||||
|
|
|
|||
|
|
@ -1144,6 +1144,35 @@ fn execute(
|
|||
Some((transition, mutation_receipt)),
|
||||
)
|
||||
}
|
||||
WorldCommand::ReconcileFissionCivicBindings { expected_revision } => {
|
||||
require_revision(&campaign, expected_revision)?;
|
||||
let transition = crate::legacy_transition::lower_fission_civic_reconciliation(
|
||||
&campaign,
|
||||
Utc::now() + Duration::minutes(5),
|
||||
)
|
||||
.map_err(|error| KernelError::Invalid(error.to_string()))?
|
||||
.ok_or_else(|| {
|
||||
KernelError::Invalid("campaign has no stale fission civic bindings".into())
|
||||
})?;
|
||||
let mutation_receipt =
|
||||
crate::legacy_transition::apply_lowered_fission_civic_reconciliation(
|
||||
&mut campaign,
|
||||
&transition,
|
||||
Utc::now(),
|
||||
)
|
||||
.map_err(|error| KernelError::Invalid(error.to_string()))?;
|
||||
commit_with_records(
|
||||
store,
|
||||
row,
|
||||
campaign,
|
||||
"reconcile_fission_civic_bindings",
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
Vec::new(),
|
||||
None,
|
||||
Some((transition, mutation_receipt)),
|
||||
)
|
||||
}
|
||||
WorldCommand::AdvanceStrategicTick {
|
||||
expected_revision,
|
||||
source,
|
||||
|
|
|
|||
|
|
@ -219,6 +219,14 @@ pub fn lower_fission(
|
|||
destination_population: Some(population_subject(destination)),
|
||||
});
|
||||
}
|
||||
for (jurisdiction, system) in
|
||||
fission_civic_system_rebindings(campaign, preview, &source_receipt_id)
|
||||
{
|
||||
mutations.push(WorldMutation::SetCivicSystem {
|
||||
jurisdiction,
|
||||
system,
|
||||
});
|
||||
}
|
||||
lower_exact_mutations(
|
||||
campaign,
|
||||
mutations,
|
||||
|
|
@ -238,6 +246,179 @@ pub fn lower_fission(
|
|||
)
|
||||
}
|
||||
|
||||
fn fission_civic_system_rebindings(
|
||||
campaign: &Campaign,
|
||||
preview: &GestaltFissionPreview,
|
||||
verification_receipt_id: &str,
|
||||
) -> Vec<(SubjectRef, crate::domain::CivicSystemManifest)> {
|
||||
let inherited_relation_ids = campaign
|
||||
.agency_relations
|
||||
.values()
|
||||
.filter(|relation| {
|
||||
relation.active
|
||||
&& (relation.from_subject_id == preview.parent_gestalt_id
|
||||
|| relation.to_subject_id == preview.parent_gestalt_id)
|
||||
})
|
||||
.map(|relation| relation.id.clone())
|
||||
.collect::<BTreeSet<_>>();
|
||||
campaign
|
||||
.civic_systems
|
||||
.values()
|
||||
.filter_map(|system| {
|
||||
let mut rebound = system.clone();
|
||||
if !apply_fission_civic_rebinding(
|
||||
&mut rebound,
|
||||
&preview.parent_gestalt_id,
|
||||
&preview
|
||||
.children
|
||||
.iter()
|
||||
.map(|child| child.id.clone())
|
||||
.collect::<Vec<_>>(),
|
||||
&inherited_relation_ids,
|
||||
) {
|
||||
return None;
|
||||
}
|
||||
rebound.version = rebound.version.saturating_add(1);
|
||||
rebound.semantic_verification_receipt_id = verification_receipt_id.into();
|
||||
Some((place_subject(&rebound.jurisdiction_location_id), rebound))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
fn apply_fission_civic_rebinding(
|
||||
system: &mut crate::domain::CivicSystemManifest,
|
||||
parent_id: &str,
|
||||
child_ids: &[String],
|
||||
inherited_relation_ids: &BTreeSet<String>,
|
||||
) -> bool {
|
||||
let mut changed = false;
|
||||
if system.resident_population_ids.remove(parent_id) {
|
||||
system
|
||||
.resident_population_ids
|
||||
.extend(child_ids.iter().cloned());
|
||||
changed = true;
|
||||
}
|
||||
let rebound_relation_ids = system
|
||||
.political_relation_ids
|
||||
.intersection(inherited_relation_ids)
|
||||
.cloned()
|
||||
.collect::<Vec<_>>();
|
||||
for relation_id in rebound_relation_ids {
|
||||
system.political_relation_ids.remove(&relation_id);
|
||||
system.political_relation_ids.extend(
|
||||
child_ids
|
||||
.iter()
|
||||
.map(|child_id| format!("{relation_id}:fission:{child_id}")),
|
||||
);
|
||||
changed = true;
|
||||
}
|
||||
changed
|
||||
}
|
||||
|
||||
fn fission_civic_reconciliation_rebindings(
|
||||
campaign: &Campaign,
|
||||
) -> Vec<(SubjectRef, crate::domain::CivicSystemManifest)> {
|
||||
campaign
|
||||
.civic_systems
|
||||
.values()
|
||||
.filter_map(|system| {
|
||||
let mut rebound = system.clone();
|
||||
let mut changed = false;
|
||||
for lineage in campaign.gestalt_lineages.values() {
|
||||
let inherited_relation_ids = rebound
|
||||
.political_relation_ids
|
||||
.iter()
|
||||
.filter(|relation_id| !campaign.agency_relations.contains_key(*relation_id))
|
||||
.filter(|relation_id| {
|
||||
lineage.child_gestalt_ids.iter().all(|child_id| {
|
||||
campaign
|
||||
.agency_relations
|
||||
.contains_key(&format!("{relation_id}:fission:{child_id}"))
|
||||
})
|
||||
})
|
||||
.cloned()
|
||||
.collect::<BTreeSet<_>>();
|
||||
changed |= apply_fission_civic_rebinding(
|
||||
&mut rebound,
|
||||
&lineage.parent_gestalt_id,
|
||||
&lineage.child_gestalt_ids,
|
||||
&inherited_relation_ids,
|
||||
);
|
||||
}
|
||||
if !changed {
|
||||
return None;
|
||||
}
|
||||
rebound.version = rebound.version.saturating_add(1);
|
||||
Some((place_subject(&rebound.jurisdiction_location_id), rebound))
|
||||
})
|
||||
.collect()
|
||||
}
|
||||
|
||||
pub fn fission_civic_reconciliation_required(campaign: &Campaign) -> bool {
|
||||
!fission_civic_reconciliation_rebindings(campaign).is_empty()
|
||||
}
|
||||
|
||||
pub fn lower_fission_civic_reconciliation(
|
||||
campaign: &Campaign,
|
||||
expires_at: DateTime<Utc>,
|
||||
) -> Result<Option<LoweredLegacyTransition>> {
|
||||
let mut rebindings = fission_civic_reconciliation_rebindings(campaign);
|
||||
if rebindings.is_empty() {
|
||||
return Ok(None);
|
||||
}
|
||||
let repair_digest = digest_serializable(&(campaign.id, campaign.revision, &rebindings))?;
|
||||
let source_receipt_id = format!(
|
||||
"fission-civic-reconciliation:{}",
|
||||
repair_digest.trim_start_matches("sha256:")
|
||||
);
|
||||
let mutations = rebindings
|
||||
.iter_mut()
|
||||
.map(|(jurisdiction, system)| {
|
||||
system.semantic_verification_receipt_id = source_receipt_id.clone();
|
||||
WorldMutation::SetCivicSystem {
|
||||
jurisdiction: jurisdiction.clone(),
|
||||
system: system.clone(),
|
||||
}
|
||||
})
|
||||
.collect();
|
||||
lower_exact_mutations(
|
||||
campaign,
|
||||
mutations,
|
||||
MutationProcedure::CompilerAdmission,
|
||||
None,
|
||||
MutationOutcomeBinding::Deterministic,
|
||||
Some(campaign.resolution_policy.resolution_epoch),
|
||||
"Replace only stale civic population and political-relation bindings whose exact fission lineage and complete child relation set already exist in canonical state.",
|
||||
&source_receipt_id,
|
||||
Some(repair_digest.clone()),
|
||||
Some(repair_digest),
|
||||
expires_at,
|
||||
)
|
||||
.map(Some)
|
||||
}
|
||||
|
||||
pub fn apply_lowered_fission_civic_reconciliation(
|
||||
campaign: &mut Campaign,
|
||||
transition: &LoweredLegacyTransition,
|
||||
now: DateTime<Utc>,
|
||||
) -> Result<WorldMutationReceipt> {
|
||||
let snapshot = component_snapshot_for_reconciliation(campaign)?;
|
||||
let application =
|
||||
apply_component_world_batch(&snapshot, &transition.authority, &transition.batch, now)?;
|
||||
for system in application.state.civic_systems.values() {
|
||||
if campaign
|
||||
.civic_systems
|
||||
.get(&system.jurisdiction_location_id)
|
||||
.is_some_and(|current| current != system)
|
||||
{
|
||||
campaign
|
||||
.civic_systems
|
||||
.insert(system.jurisdiction_location_id.clone(), system.clone());
|
||||
}
|
||||
}
|
||||
Ok(application.receipt)
|
||||
}
|
||||
|
||||
pub fn apply_lowered_fission(
|
||||
campaign: &mut Campaign,
|
||||
preview: &GestaltFissionPreview,
|
||||
|
|
@ -904,6 +1085,18 @@ fn project_accepted_fission(
|
|||
}
|
||||
campaign.agency_relations.insert(id, inherited);
|
||||
}
|
||||
campaign.agency_relations.remove(&relation.id);
|
||||
}
|
||||
for system in next.civic_systems.values() {
|
||||
if campaign
|
||||
.civic_systems
|
||||
.get(&system.jurisdiction_location_id)
|
||||
.is_some_and(|current| current != system)
|
||||
{
|
||||
campaign
|
||||
.civic_systems
|
||||
.insert(system.jurisdiction_location_id.clone(), system.clone());
|
||||
}
|
||||
}
|
||||
campaign.gestalt_lineages.insert(
|
||||
preview.parent_gestalt_id.clone(),
|
||||
|
|
@ -1780,6 +1973,17 @@ fn foreground_mutations(
|
|||
}
|
||||
|
||||
fn component_snapshot(campaign: &Campaign) -> Result<ComponentWorldState> {
|
||||
component_snapshot_with_validation(campaign, true)
|
||||
}
|
||||
|
||||
fn component_snapshot_for_reconciliation(campaign: &Campaign) -> Result<ComponentWorldState> {
|
||||
component_snapshot_with_validation(campaign, false)
|
||||
}
|
||||
|
||||
fn component_snapshot_with_validation(
|
||||
campaign: &Campaign,
|
||||
validate: bool,
|
||||
) -> Result<ComponentWorldState> {
|
||||
let version = campaign.revision;
|
||||
let mut state = ComponentWorldState {
|
||||
schema: "ghostlight.component_world_state.v1".into(),
|
||||
|
|
@ -2346,7 +2550,9 @@ fn component_snapshot(campaign: &Campaign) -> Result<ComponentWorldState> {
|
|||
},
|
||||
);
|
||||
}
|
||||
validate_component_world(&state)?;
|
||||
if validate {
|
||||
validate_component_world(&state)?;
|
||||
}
|
||||
Ok(state)
|
||||
}
|
||||
|
||||
|
|
@ -3480,6 +3686,195 @@ mod tests {
|
|||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn fission_rebinds_civic_residency_and_political_relations_atomically() {
|
||||
let mut campaign = campaign();
|
||||
let public_fact = campaign.facts["fact:route"].statement.clone();
|
||||
campaign.gestalts.insert(
|
||||
"residents".into(),
|
||||
GestaltPersonaState {
|
||||
schema: "ghostlight.gestalt_persona_state.v1".into(),
|
||||
id: "residents".into(),
|
||||
name: "Residents".into(),
|
||||
version: 0,
|
||||
home_location_id: "room".into(),
|
||||
shared_capabilities: BTreeSet::new(),
|
||||
shared_knowledge: BTreeSet::from([public_fact.clone()]),
|
||||
resources: BTreeSet::new(),
|
||||
goals: vec![],
|
||||
pressures: vec![],
|
||||
},
|
||||
);
|
||||
crate::resolution::ensure_agency_profiles(&mut campaign);
|
||||
campaign.agency_relations.insert(
|
||||
"relation:residents-watch".into(),
|
||||
AgencyRelation {
|
||||
schema: AgencyRelation::SCHEMA.into(),
|
||||
id: "relation:residents-watch".into(),
|
||||
from_subject_id: "residents".into(),
|
||||
to_subject_id: "watch".into(),
|
||||
kind: crate::domain::AgencyRelationKind::Membership,
|
||||
strength: 60,
|
||||
active: true,
|
||||
evidence_receipt_ids: vec!["evidence:civic".into()],
|
||||
},
|
||||
);
|
||||
campaign.civic_systems.insert(
|
||||
"room".into(),
|
||||
crate::domain::CivicSystemManifest {
|
||||
schema: "ghostlight.civic_system_manifest.v1".into(),
|
||||
version: 0,
|
||||
jurisdiction_location_id: "room".into(),
|
||||
governing_institution_ids: BTreeSet::from(["watch".into()]),
|
||||
resident_population_ids: BTreeSet::from(["residents".into()]),
|
||||
public_authority_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
public_selection_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
public_resource_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
public_redress_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
political_relation_ids: BTreeSet::from(["relation:residents-watch".into()]),
|
||||
semantic_verification_receipt_id: "semantic:civic".into(),
|
||||
},
|
||||
);
|
||||
let child = |id: &str, name: &str| GestaltPersonaState {
|
||||
schema: "ghostlight.gestalt_persona_state.v1".into(),
|
||||
id: id.into(),
|
||||
name: name.into(),
|
||||
version: 0,
|
||||
home_location_id: "room".into(),
|
||||
shared_capabilities: BTreeSet::new(),
|
||||
shared_knowledge: BTreeSet::from([public_fact.clone()]),
|
||||
resources: BTreeSet::new(),
|
||||
goals: vec![],
|
||||
pressures: vec![],
|
||||
};
|
||||
let preview = GestaltFissionPreview {
|
||||
schema: "ghostlight.gestalt_fission_preview.v1".into(),
|
||||
campaign_id: campaign.id,
|
||||
expected_world_revision: campaign.revision,
|
||||
parent_gestalt_id: "residents".into(),
|
||||
partition_axis: crate::domain::AgencyAxis::Ideology,
|
||||
children: vec![
|
||||
child("resident-majority", "Resident majority"),
|
||||
child("resident-dissenters", "Resident dissenters"),
|
||||
],
|
||||
child_partition_values: BTreeMap::from([
|
||||
("resident-majority".into(), "majority".into()),
|
||||
("resident-dissenters".into(), "other/unknown".into()),
|
||||
]),
|
||||
residual_child_id: "resident-dissenters".into(),
|
||||
member_child_assignments: BTreeMap::new(),
|
||||
resource_child_assignments: BTreeMap::new(),
|
||||
evidence_receipt_ids: vec![],
|
||||
gaps: vec![],
|
||||
canon_candidates: vec![],
|
||||
requires_approval: true,
|
||||
};
|
||||
|
||||
let transition =
|
||||
lower_fission(&campaign, &preview, Utc::now() + Duration::minutes(5)).unwrap();
|
||||
assert!(
|
||||
transition
|
||||
.batch
|
||||
.mutations
|
||||
.iter()
|
||||
.any(|mutation| matches!(mutation.mutation, WorldMutation::SetCivicSystem { .. }))
|
||||
);
|
||||
apply_lowered_fission(&mut campaign, &preview, &transition, Utc::now()).unwrap();
|
||||
|
||||
let civic = &campaign.civic_systems["room"];
|
||||
assert_eq!(
|
||||
civic.resident_population_ids,
|
||||
BTreeSet::from(["resident-majority".into(), "resident-dissenters".into()])
|
||||
);
|
||||
assert_eq!(
|
||||
civic.political_relation_ids,
|
||||
BTreeSet::from([
|
||||
"relation:residents-watch:fission:resident-majority".into(),
|
||||
"relation:residents-watch:fission:resident-dissenters".into(),
|
||||
])
|
||||
);
|
||||
assert_eq!(civic.version, 1);
|
||||
assert!(
|
||||
civic
|
||||
.semantic_verification_receipt_id
|
||||
.starts_with("fission-preview:")
|
||||
);
|
||||
assert!(
|
||||
!campaign
|
||||
.agency_relations
|
||||
.contains_key("relation:residents-watch")
|
||||
);
|
||||
for relation_id in &civic.political_relation_ids {
|
||||
assert!(campaign.agency_relations.contains_key(relation_id));
|
||||
}
|
||||
let snapshot = component_snapshot(&campaign).unwrap();
|
||||
crate::transition::validate_component_world(&snapshot).unwrap();
|
||||
|
||||
campaign.revision += 1;
|
||||
campaign.civic_systems.insert(
|
||||
"room".into(),
|
||||
crate::domain::CivicSystemManifest {
|
||||
schema: "ghostlight.civic_system_manifest.v1".into(),
|
||||
version: 0,
|
||||
jurisdiction_location_id: "room".into(),
|
||||
governing_institution_ids: BTreeSet::from(["watch".into()]),
|
||||
resident_population_ids: BTreeSet::from(["residents".into()]),
|
||||
public_authority_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
public_selection_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
public_resource_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
public_redress_fact_ids: BTreeSet::from(["fact:route".into()]),
|
||||
political_relation_ids: BTreeSet::from(["relation:residents-watch".into()]),
|
||||
semantic_verification_receipt_id: "semantic:stale".into(),
|
||||
},
|
||||
);
|
||||
assert!(fission_civic_reconciliation_required(&campaign));
|
||||
let reconciliation =
|
||||
lower_fission_civic_reconciliation(&campaign, Utc::now() + Duration::minutes(5))
|
||||
.unwrap()
|
||||
.unwrap();
|
||||
let repaired_system = reconciliation
|
||||
.batch
|
||||
.mutations
|
||||
.iter()
|
||||
.find_map(|mutation| match &mutation.mutation {
|
||||
WorldMutation::SetCivicSystem { system, .. } => Some(system),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap();
|
||||
assert_eq!(
|
||||
repaired_system.political_relation_ids,
|
||||
BTreeSet::from([
|
||||
"relation:residents-watch:fission:resident-majority".into(),
|
||||
"relation:residents-watch:fission:resident-dissenters".into(),
|
||||
])
|
||||
);
|
||||
let stale_snapshot = component_snapshot_for_reconciliation(&campaign).unwrap();
|
||||
for relation_id in &repaired_system.political_relation_ids {
|
||||
assert!(stale_snapshot.relationships.contains_key(relation_id));
|
||||
}
|
||||
apply_lowered_fission_civic_reconciliation(&mut campaign, &reconciliation, Utc::now())
|
||||
.unwrap();
|
||||
assert!(!fission_civic_reconciliation_required(&campaign));
|
||||
assert_eq!(
|
||||
campaign.civic_systems["room"].resident_population_ids,
|
||||
BTreeSet::from(["resident-majority".into(), "resident-dissenters".into()])
|
||||
);
|
||||
assert_eq!(
|
||||
campaign.civic_systems["room"].political_relation_ids,
|
||||
BTreeSet::from([
|
||||
"relation:residents-watch:fission:resident-majority".into(),
|
||||
"relation:residents-watch:fission:resident-dissenters".into(),
|
||||
])
|
||||
);
|
||||
assert!(
|
||||
campaign.civic_systems["room"]
|
||||
.semantic_verification_receipt_id
|
||||
.starts_with("fission-civic-reconciliation:")
|
||||
);
|
||||
crate::transition::validate_component_world(&component_snapshot(&campaign).unwrap())
|
||||
.unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn shared_learning_updates_the_materialized_member_projection() {
|
||||
let mut campaign = campaign();
|
||||
|
|
|
|||
|
|
@ -5504,6 +5504,7 @@ fn player_http_command_allowed(command: &WorldCommand, player_actor_id: &str) ->
|
|||
| WorldCommand::SetProviderParallelism { .. }
|
||||
| WorldCommand::ReplaceResolutionPins { .. }
|
||||
| WorldCommand::FissionGestalt { .. }
|
||||
| WorldCommand::ReconcileFissionCivicBindings { .. }
|
||||
| WorldCommand::BindClockConsequences { .. } => false,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1705,12 +1705,25 @@ materializing a `NewsIssue`.
|
|||
unchanged. The current uncommitted cut requires the exact frozen resource
|
||||
and dormant-member IDs as action-schema map keys, rejects extras, and leaves
|
||||
destination-child choice to the model. Full verification passes 495 library
|
||||
and 16 strategic tests. Commit and push, then clone Run 80 into Run 81 and
|
||||
resume only those same failed dispatches. Do not
|
||||
and 16 strategic tests. Pushed `e7ceb2c` owns that exact-key boundary.
|
||||
|
||||
Run 81's first accepted Hearthcoil fission exposed the next canonical defect:
|
||||
its civic manifest still named the removed parent's political relation. The
|
||||
current uncommitted transition cut atomically replaces parent civic residency
|
||||
with every child, replaces inherited parent relation IDs with child relation
|
||||
IDs, removes the obsolete parent relation, and validates the component world
|
||||
in the same fission transaction. Review and verify that future-fission cut
|
||||
plus the deterministic recovery command, run focused/full and strategic
|
||||
gates, then commit and push. Clone immutable Run 81 and invoke
|
||||
`ReconcileFissionCivicBindings` exactly once. It may repair only stale civic
|
||||
bindings proven by the admitted fission lineage and must persist its mutation
|
||||
proof and checkpoint. Then skip Patina `commit0001` and rebase Charter. Do not
|
||||
replay any model call, fission mutation, region/locality work, or unrelated
|
||||
dispatch. Do not
|
||||
assume a fixed batch yield or one model call per useful subject. Keep
|
||||
Resolution as cover owner. Nemesis receives
|
||||
that cover and assigns causal decision windows inside it; it does not choose
|
||||
cover membership. Preserve Runs 64 through 80 and both live services. This
|
||||
cover membership. Preserve Runs 64 through 81 and both live services. This
|
||||
work does not wait for the Delvehold adapter because the Greathold remains an
|
||||
external sovereign boundary observer.
|
||||
4. Build the Delvehold-owned adapter before any real Delvehold-owned player,
|
||||
|
|
|
|||
|
|
@ -2349,10 +2349,61 @@ shows every signed modifier with its exact references.
|
|||
|
||||
Population fission now composes admitted child entities, stable child
|
||||
identities, one lineage split, exact resource custody transfers, and exact
|
||||
named-member membership transfers. The old fission function that directly
|
||||
wrote campaign state has been removed. Its surviving projector updates only
|
||||
agency profiles, facets, cover invalidation, and `resolution_epoch` after the
|
||||
canonical mutation batch succeeds.
|
||||
named-member membership transfers. The same fission transaction owns every
|
||||
relation and civic consequence of retiring the parent: it creates one inherited
|
||||
child agency relation per child, retires the parent relation, replaces the
|
||||
parent resident ID with all child IDs in each affected civic manifest, rebinds
|
||||
each civic political-relation ID to the exact child relation IDs, advances the
|
||||
manifest version, and binds its semantic verification/source field to the exact
|
||||
`fission-preview:<digest>` receipt. These writes lower together with child
|
||||
admission, lineage, custody, and membership into one component-world batch;
|
||||
either the complete state validates and commits or none of it does.
|
||||
|
||||
The aggregate projector may copy the accepted child relations and civic
|
||||
manifests out of that component result, and `project_fission_resolution` owns
|
||||
the derived agency-profile, facet, cover-invalidation, and resolution-epoch
|
||||
projection. Later `ensure_agency_profiles` synchronization is not a cleanup
|
||||
owner and may not repair missing civic residents, replace stale political
|
||||
relation IDs, recreate retired parent relations, or make a partially applied
|
||||
fission appear valid. The old fission function that directly wrote campaign
|
||||
state has been removed.
|
||||
|
||||
Immutable Run 81 at exact source
|
||||
`e7ceb2c2807fabb2b0e68aeeeb0aab5948c582a5` and root
|
||||
`/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-e7ceb2c-81`
|
||||
is failure evidence for this ownership boundary. Patina commit 0001 advanced
|
||||
revision 15 to 16 and admitted the Hearthcoil children, but left the Hearthcoil
|
||||
civic manifest pointing at missing parent relation
|
||||
`rel:hearthcoil-houses-member-blackchalk` while the child relation clones
|
||||
existed. Charter's already accepted frozen proposal then failed admission with
|
||||
`invalid command: canonical civic system lost a political relation`. Preserve
|
||||
the run unchanged; unit `ghostlight-full-world-e7ceb2c-81.service`, invocation
|
||||
`069f3a5de05b4bd3a972ddf621e29d54`, is terminal with an exit code.
|
||||
|
||||
Run 81 recovery is an explicit one-boundary repair, not rollback or fission
|
||||
replay. `WorldCommand::ReconcileFissionCivicBindings` owns deterministic repair
|
||||
on a clone of Run 81. It may select only civic manifests whose stale parent
|
||||
resident or political-relation binding is proven by an existing canonical
|
||||
Gestalt lineage and, for each retired relation, the complete canonical child
|
||||
relation set. It lowers only the resulting `SetCivicSystem` mutations through
|
||||
the shared mutation kernel, increments the affected manifest version, and binds
|
||||
the repair to a deterministic `fission-civic-reconciliation:<digest>` source.
|
||||
|
||||
The repair uses an unchecked component snapshot only as the bounded workbench
|
||||
needed to represent the known invalid starting state. The mutation application
|
||||
must produce a normally validated next component world; WorldKernel then
|
||||
persists an ordinary world commit and mutation receipt under command kind
|
||||
`reconcile_fission_civic_bindings`. The acceptance driver publishes one
|
||||
immutable `ghostlight.fission_civic_reconciliation_checkpoint.v1` and refuses a
|
||||
checkpoint whose canonical repair is absent or whose command/revision binding
|
||||
disagrees with the campaign. The unchecked snapshot is not a general admission
|
||||
mode, migration authority, cleanup loop, or permission to repair unrelated
|
||||
state.
|
||||
|
||||
After that checkpoint, the complexity loop recognizes Patina commit 0001 as
|
||||
already admitted, skips it, and rebases the preserved Charter proposal against
|
||||
the repaired revision. The Run 81 frozen preview and model receipts remain the
|
||||
inference authority; recovery performs no model or elaboration replay.
|
||||
|
||||
Region expansion and in-place locality elaboration compose typed place,
|
||||
proposition, population, and institution admission plus exact topology and
|
||||
|
|
|
|||
|
|
@ -92,7 +92,7 @@ live_architecture:
|
|||
- The hosted player story is the chronological lowering of exact committed NarrativeTurn rows. No narrator or verifier model rewrites those turns; historical narration projections are inert and never enter Eve or CultMesh player surfaces.
|
||||
- Epiphany consumes the extracted Ghostlight projection crate at an exact Git revision while retaining her canonical Mind, effect admission, and consequence authority.
|
||||
- Gestalt Personas own shared population state; durable member deltas preserve specific people between appearances. WorldKernel owns one revision-bound individuation primitive that validates exact Gestalt lineage, location, version, and identity uniqueness before atomically materializing the member. Foreground presence may call it after exact player speech; strategic waves may call it for at most one selected Gestalt action through an action-bound selector receipt. Resolution owns the exact strategic-individuation validator. The scheduler calls that shared validator at proposal production, records semantic_invalid, and drops an invalid optional proposal before wave assembly; WorldKernel revalidates with the same owner at admission. The model proposes identity content only.
|
||||
- The multiresolution agency graph derives a connected cohesive/arena attention cover from canonical actors, institutions, and Gestalt-compressed latent subjects under a campaign-selected 1–240 active-cell entitlement; provider concurrency is independently capped at 32. Active cells do not state total world population or complexity. The current full-world target is approximately 2,400 potentially acting entities under a 240-cell cover, about ten percent simultaneous attention. A 1,000-subject, 200-cell fixture remains machinery proof of complete unique coverage and parallel membrane dispatch under a seven-call provider gate, not the product-scale target. Nemesis allocates causal attention; WorldKernel retains cover derivation and commit authority.
|
||||
- The multiresolution agency graph derives a connected cohesive/arena attention cover from canonical actors, institutions, and Gestalt-compressed latent subjects under a campaign-selected 1–240 active-cell entitlement; provider concurrency is independently capped at 32. Active cells do not state total world population or complexity. The current full-world target is approximately 2,400 potentially acting entities under a 240-cell cover, about ten percent simultaneous attention. A 1,000-subject, 200-cell fixture remains machinery proof of complete unique coverage and parallel membrane dispatch under a seven-call provider gate, not the product-scale target. Resolution owns cover derivation, Nemesis allocates causal decision windows inside that cover, and WorldKernel retains commit authority.
|
||||
- Model-driven strategic cell waves can change remote actors, institutions, gestalts, clocks, and exact-channel news while the absent player remains outside their write authority; the entire wave validates and commits atomically.
|
||||
- Population activity effects represent exact attributed attempts to prepare, coordinate, investigate, recruit, obstruct, trade, or communicate; graph scope, locations, channels, and semantics validate before the kernel derives an event, and the effect never claims its own success.
|
||||
- Population migration is a separate exact-leaf effect. WorldKernel atomically moves the Gestalt and its agency-profile location along an explicit reachable migration relation; destination populations remain distinct and named members never move by implication.
|
||||
|
|
@ -196,7 +196,7 @@ live_architecture:
|
|||
- Institution, faction, and consumer decision models
|
||||
|
||||
active_subgoals:
|
||||
- Complete the separate latent-world complexity and active-simulation budget cut before another full-world acceptance. Approximately 2,400 potentially acting entities under a 240-cell attention cover is a causal-complexity target, not a population-roster target. Iterative elaboration must raise admitted complexity by fissioning Gestalts and promoting causally meaningful individuals and institutions, then remeasure the remaining deficit; it may not assume one row or one model call equals one useful subject. Resolution owns cover selection, and Nemesis assigns causal decision windows inside an existing cover without gaining cover or commit authority. Preserve Runs 64 through 80 and treat the Greathold as an externally sovereign boundary observer.
|
||||
- Complete the separate latent-world complexity and active-simulation budget cut before another full-world acceptance. Approximately 2,400 potentially acting entities under a 240-cell attention cover is a causal-complexity target, not a population-roster target. Iterative elaboration must raise admitted complexity by fissioning Gestalts and promoting causally meaningful individuals and institutions, then remeasure the remaining deficit; it may not assume one row or one model call equals one useful subject. Resolution owns cover selection, and Nemesis assigns causal decision windows inside an existing cover without gaining cover or commit authority. Preserve Runs 64 through 81 and treat the Greathold as an externally sovereign boundary observer.
|
||||
- Connect a Delvehold-owned adapter to the admitted generic consumer contract: shared compiler/consumer WorldSeed admission, externally authoritative institution-or-Gestalt snapshots, attributed proposal acknowledgement, and committed-event newspaper composition over typed CultNet, without consumer-specific IDs or schemas in Ghostlight.
|
||||
- Extend strategic/offscreen named-person individuation beyond the proven emerge-then-act path so people plot across sustained political waves, acquire relationships, fold, and return without granting a cell, arena, or model commit authority.
|
||||
- Finish the semantic mutation migration: delete or demote remaining legacy model effect schemas and move aggregate campaign fields toward projection-only state. Seed publication and named-person presence now have explicit non-effect authority classifications.
|
||||
|
|
@ -329,8 +329,8 @@ current_status:
|
|||
provider_acceptance_checkpoint: Exact pushed commit `139b8a6` completed Run 60 under `character-newsroom.v10` without world or per-wave replay. Its acceptance witness and terminal status bind the completed page and exact resume lineage. The independently dispatched blind reviewer, shown only the reader-facing fantasy newspaper, read it as a real left-populist civic broadsheet and did not immediately identify procedural generation, so the narrative reverse-Turing criterion passes. The review's substantive criticism is that the three stories feel like three rewrites of one briefing; accepted Run 60 remains immutable. The run used 96,902 prompt tokens and reported zero cache hits. Its delivered typeset artifact is `output/pdf/canopy-ledger-run-60-front-page.pdf`; frozen-source and visual verification remain accepted. Exact pushed `bc2ca39` then produced frozen-fact newsroom-only Run 61 Issues 13, 15, 16, 17, and 18 without world or wave model replay. Provider output proves `special_issue` convergence in Issues 13 and 15, independent `general_issue` beats in Issues 16 through 18, and assignment-selector cache hits. Blind review of Issues 13, 15, 16, and 17 passes both distinct recurring voices and issue-shape diversity, recognizing Ossan, Mera, Corin, and Lysa's biases plus modest cross-issue evolution. Run 62 exercised v12 without world or wave replay and failed only because two lead articles proposed invalid datelines; recurring reporter calls still recorded zero cache hits. Run 63 used exact pushed v13 `a52d57b`; Issues 17 and 18 completed before root stopped the final weekly recomposition, both repeated bylines again recorded zero cache hits, and live services remained unchanged. Preserve Runs 61 through 63 as stopped or completed immutable evidence. Copy defects remain later deadline-correction work rather than a reason to reopen accepted issue artifacts.
|
||||
implementation_checkpoint: Exact pushed v13 `a52d57b` keeps one stable reporter action schema, places a common stable house charter before recurring identity and dynamic assignment, and projects deterministic `allowed_datelines` from cited records while retaining copy-desk factual authority and deterministic cited-place admission; 480 library tests and the all-target check pass. Run 63 falsifies reporter-cache pursuit as a useful acceptance target for sporadic independent filings. The proposed v14 cache-floor prompt growth was removed. Append-only agent contexts remain the natural cache beneficiary; accepted Run 60 remains immutable. The strategic cut extracts one shared `validate_strategic_individuation_proposals` owner used by resolution validation and by the scheduler before it returns an optional proposal. An invalid optional identity emits a semantic-invalid receipt and produces no individuation instead of aborting the recoverable wave. Focused valid and invalid regressions pass, and exact-source Run 68 exercises the corrected provider path through twelve committed waves; no further validator implementation is pending. The newsroom-only cut adds a navigation-only directory of completed public changes grouped by period and exact source timestamps to new v14 audit citations. The directory derives context from canonical records and gains no fact or world authority. Legacy empty source times are omitted from both rendering and serialization, preserving inherited v13 receipt bytes and digests; new v14 nonempty source times remain rendered and serialized. Exact-source Run 73 proves that compatibility path and final recomposition mechanically. Current source gives the assignment editor bounded full-ledger queries and explicitly asks it to search sideways for opposition and countermoves; Run 73 falsifies the stronger assumption that this access and instruction alone guarantee balanced selection. Exact pushed v15 source `b6787d909bd79b68ed3a4d143b7f6dd438e00fa2` binds accountability, opposition, and counter-narrative pitches to two distinct named parties and selected citations through a typed conflict axis, and preserves canonical ledger order. Run 74 falsifies the stronger v15 assumption: its lone accountability pitch used the same transfer citation for cultivators and a passive Tribunal, while four of five pitches avoided the adversarial axis through lead or consequence functions. Two cited names did not prove two moves. Exact pushed v16 `86fe6ed89d51da26b65ab6a031608075840b1527` binds each adversarial axis to two distinct cited public moves or positions and rejects one record presented as both sides; it adds no event writer, judge, process, dependency, or persistent authority. Formatting, 27 focused newspaper tests, 484 full library tests, and 16 strategic-smoke tests pass.
|
||||
full_world_acceptance_checkpoint: Run 68 at exact source `69c811a2669fc38f19f9199bf57088dc250bfc3e` is mechanically complete at world revision 27 with 12/12 strategic waves, 240 events, 514 public news rows, and a final newspaper. Independent editorial and grounding reviews both fail. Earlier per-wave papers prove the immutable record already contains dramatic completed facts, including an organ breaching the rail capital, a dead pump, and families crossing borders; the final paper failed to make that committed change legible. Preserve Run 68 unchanged. Run 69 at source `84b31e57a462710eb939c4559e0437eb5d6a7a28` failed before any model call when immutable recomposition verification encountered an empty rendered `Source time:` line in inherited v13 per-wave issues. Run 70 at source `ec45952b843e102dc2ebddda3a3bbb4058687175` also failed before any model call because v14 serialization changed the legacy recomposition digest. Exact-source Run 73 `b827d897b9579c2091a67c363d35b8695288ba2f` is terminal complete at `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-b827d89-73`: world revision 27, 12/12 waves, 240 events, 514 news rows, inherited artifacts byte-identical to Run 68, manifest valid, and archive SHA-256 `090d05f304c8f3d33c9dccd728bffbf3e5dc2969a7aeeffc2f9d7bafe701ac8a`. Exact-source Run 74 `b6787d909bd79b68ed3a4d143b7f6dd438e00fa2` is mechanically complete at `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-b6787d9-74`: revision 27, 12/12 waves, 240 events, 514 news rows, Run 68 inherited artifacts byte-identical, manifest valid, unchanged live services, and archive SHA-256 `957b11a5d584d27d23bf4d50ed1fbc8d067faf67953b03f80705bfb9587c496d`. Independent editorial review fails: the page has a coherent throughline and sharp prose but no sustained adversarial narrative; opposing decision-makers, motives, responses, and countermoves are largely absent, scandal and public reaction are missing, lived costs remain abstract, and the result reads as polished minutes with conclusions. Its post-press correction notice has two items: `The corridor had begun closing hours earlier` overstates a source that says the prolonged oath-route closure was diverting arrivals six hours before the breach; `no relief or assignment of liability has followed` must narrow to `no tribunal remedy is recorded yet`. Run 75 launched at exact source `86fe6ed89d51da26b65ab6a031608075840b1527` under the superseded 240-cell-only acceptance shape and was stopped cleanly at the operator's scale correction. Preserve `/var/lib/gamecult/ghostlight-dungeon/acceptance/full-world-delvehold-86fe6ed-75` as stopped non-acceptance evidence: preflight, world-region and titled-elaboration checkpoints, a wave-one cell terminal checkpoint, partial pulses 01/02, and two rejected pulse receipts exist. `ghostlight-full-world-run75.service` invocation `86bfe6a3ef504a7d99f579b3d67710ab` is inactive/dead after explicit stop; live services remain unchanged. Do not claim terminal success or failure. Preserve Runs 64 through 75. Mechanical completion of the earlier world is proven, but final newspaper acceptance under the corrected scale target is not.
|
||||
scale_checkpoint: The active 240-cell entitlement is an attention budget, not the world-size claim. The approximately 2,400 potentially acting entities are a target for causally meaningful latent complexity, not a raw population or roster count. Multiresolution Gestalts compress the unresolved population; repeated admitted elaboration must fission them and promote individuals and institutions whose agency, relationships, resources, pressures, or authority can actually participate in consequences, then remeasure the deficit. Exact pushed `df66ec989c1e44a7a8b21ed159e9589778426238` defines consumer-authored `WorldScaleIntent` and deterministic `WorldElaborationDemand`; at 240 cells and 1,000 cover basis points it derives a numeric 2,400-subject target, current-subject deficit, weighted per-realm shares, and bounded `round_mutation_budget`. Pushed `a017737` owns title-by-realm persistent logical elaborator sessions with agentic bounded compaction, compact mutation drafts, exact failed-dispatch-only resume, both Gestalt fission and grounded named-person promotion, WorldKernel-only commit, and post-round canonical remeasurement. Run 79 exposed opaque fission findings. Terminal Run 80 retried only Patina and Charter; the complete validator mismatch set proved both omitted every parent resource assignment and named the exact three missing resources for each parent. No mutation committed and live services remained unchanged. The current uncommitted cut structurally requires the exact frozen resource and dormant-member IDs as action-schema map keys, rejects extras, and leaves only destination-child choice to the model. Full verification passes 495 library and 16 strategic tests. Commit/push and provider resume remain pending. Resolution owns derived cover membership. Nemesis receives an existing cover and assigns bounded causal decision windows among eligible responders; it does not allocate that cover.
|
||||
scale_checkpoint: The active 240-cell entitlement is an attention budget, not the world-size claim. The approximately 2,400 potentially acting entities are a target for causally meaningful latent complexity, not a raw population or roster count. Multiresolution Gestalts compress the unresolved population; repeated admitted elaboration must fission them and promote individuals and institutions whose agency, relationships, resources, pressures, or authority can actually participate in consequences, then remeasure the deficit. Exact pushed `df66ec989c1e44a7a8b21ed159e9589778426238` defines consumer-authored `WorldScaleIntent` and deterministic `WorldElaborationDemand`; at 240 cells and 1,000 cover basis points it derives a numeric 2,400-subject target, current-subject deficit, weighted per-realm shares, and bounded `round_mutation_budget`. Pushed `a017737` owns title-by-realm persistent logical elaborator sessions with agentic bounded compaction, compact mutation drafts, exact failed-dispatch-only resume, both Gestalt fission and grounded named-person promotion, WorldKernel-only commit, and post-round canonical remeasurement. Run 80 proved exact resource custody, and pushed `e7ceb2c` requires exact frozen resource and dormant-member assignment keys. Run 81's first accepted Hearthcoil fission then reached the canonical transition with its civic manifest still naming the removed parent's political relation. The current uncommitted cut makes the same fission transaction rebind resident population IDs and inherited political-relation IDs from the parent to every admitted child, removes the parent relation, and validates the component world atomically. Verification, review, commit/push, and provider resume remain pending. Resolution owns derived cover membership. Nemesis receives an existing cover and assigns bounded causal decision windows among eligible responders; it does not allocate that cover.
|
||||
presentation_checkpoint: The historical press-layout and seed-ownership split are complete. `notes/historical-newspaper-layout-grammar.md` remains the durable grammar. Manifest v2 at `output/tex/canopy-ledger-run-61-style-1847-flow-723.manifest.toml` independently binds `style_seed=1847`, `flow_seed=723`, frozen source SHA-256 `8f195140f52a40ba705d6a66987146a1500ae89668e5d82b01d1792eb3afb882`, and the final artifact `output/pdf/canopy-ledger-run-61-style-1847-flow-723.pdf`, SHA-256 `a457f4b1702a7a52480e42fce0039f0dbe677ff32958e98f1c412b346237190c`. An identical seed pair produces byte-identical TeX and PDF; changing only flow preserves the exact style section while materially changing a plausible layout, and changing only style preserves flow topology. Cut-first and cut-midstory templates pass visual inspection; the failed split-card template is deleted. Frozen copy/assets, actual PDF `/BM /Multiply`, and economic-layer advertising authority remain invariant.
|
||||
public_reference_checkpoint: Public architecture reference is complete. Canonical Ghostlight commit `15ea0f0` owns five pages under `docs/public-architecture` covering overview, authority, pipelines, 43 named production stages, and eight titled elaborators. Site commit `ea0b026` publishes exact projections under `F:\Projects\GhostlightDungeon-site\content\Documentation`, adds the sync/check script, explorer and table-of-contents navigation, scoped documentation layout, and homepage Architecture link. Local Quartz build and visual browser QA pass. GitHub Pages workflow `33408004480` succeeded. `https://ghostlight.gamecult.org/Documentation/` and the extensionless `Documentation/Agents-and-model-stages` route are live; the stage page exposes seven tables and 51 rows. Ghostlight remains technical authority; the site repository owns public composition and deployment.
|
||||
next_action: Preserve Runs 75 through 80. Commit and push the verified exact-key fission action-schema cut. Clone immutable Run 80 into Run 81 and resume only the same failed Patina and Charter dispatches; do not replay admitted world work or other completed dispatches. Require the exact frozen resource and dormant-member keys, model-selected destination children, deterministic full-command materialization, complete validator findings, and eventual WorldKernel admission before claiming complexity progress. Preserve title-by-realm logical sessions, bounded agentic compaction, failed-dispatch-only resume, post-round remeasurement, the 2,400-complexity target under 240-cell attention, Resolution cover ownership, Nemesis's bounded causal-window role, both live services, the completed public reference, the two-seed press checkpoint, and the economic-layer advertising boundary.
|
||||
next_action: Preserve Runs 75 through 81. Review and verify both civic-fission paths, run focused/full-package/strategic gates, then commit and push. Future fissions must atomically replace parent civic residency and relations inside the fission transaction. For the admitted Run 81 lineage, clone immutable Run 81 and invoke `ReconcileFissionCivicBindings` exactly once; it must accept only lineage-proven stale civic bindings, commit the deterministic repair with mutation proof and checkpoint, skip Patina `commit0001`, and rebase Charter. Do not replay any model call, fission mutation, admitted region/locality work, or unrelated dispatch. Require the reconciled Hearthcoil civic manifest to contain no parent reference before claiming complexity progress. Preserve title-by-realm logical sessions, bounded agentic compaction, failed-dispatch-only resume, post-round remeasurement, the 2,400-complexity target under 240-cell attention, Resolution cover ownership, Nemesis's bounded causal-window role, both live services, the completed public reference, the two-seed press checkpoint, and the economic-layer advertising boundary.
|
||||
gestalt_population: Gestalt Personas own shared population baselines; persistent member deltas own named individuality; WorldKernel materialization and approval-gated fission preserve lineage and identity. Materialisation/folding changes only representation and the exact member delta, advances resolution epoch, and retires the old cover; it has no Gestalt-wide effect authority. Selected actionable member exceptions are mandatory Projector perspective owners, so aggregation cannot silently erase their decision. Presence projection is limited to nearby active leaves and exact-location dormant members, includes reciprocal player relationship evidence, and may propose an earned cast without committing it. Simulation cells are derived covers only.
|
||||
|
|
|
|||
Loading…
Reference in a new issue