Separate institution posture from pressure

This commit is contained in:
Meta Vens 2026-08-18 00:23:56 +02:00
commit 1c63ee5272
6 changed files with 59 additions and 5 deletions

View file

@ -67,6 +67,7 @@ pub struct CellConstituentSlice {
pub reachable_destination_ids: BTreeSet<String>,
pub activity_target_ids: BTreeSet<String>,
pub goals: Vec<String>,
pub current_posture: Option<String>,
pub pressures: Vec<String>,
}
@ -342,6 +343,7 @@ fn cell_projector_context(slice: &PermittedCellSlice) -> serde_json::Value {
"reachable_destination_ids": subject.reachable_destination_ids,
"activity_target_ids": subject.activity_target_ids,
"goals": subject.goals,
"current_posture": subject.current_posture,
"pressures": subject.pressures,
})).collect::<Vec<_>>(),
"member_exceptions": slice.member_exceptions.iter().map(|member| serde_json::json!({
@ -387,6 +389,7 @@ fn cell_interpreter_context(slice: &PermittedCellSlice) -> serde_json::Value {
"permitted_state_references": subject.permitted_state_references,
"reachable_destination_ids": subject.reachable_destination_ids,
"activity_target_ids": subject.activity_target_ids,
"current_posture": subject.current_posture,
"current_pressures": subject.pressures,
})).collect::<Vec<_>>(),
"member_permissions": slice.member_exceptions.iter().map(|member| serde_json::json!({
@ -880,7 +883,12 @@ fn validate_constituent_effect(
subject.location_ids
));
}
let current = subject.pressures.first().map(String::as_str).unwrap_or("");
let current = subject.current_posture.as_deref().ok_or_else(|| {
anyhow!(
"institution {} is missing its exact current posture",
subject.subject_id
)
})?;
if !crate::resolution::substantive_text_change(current, posture) {
return Err(anyhow!(
"institution {} proposed posture {:?}, but its exact current posture is {:?}; emit a specific different commitment or choose inaction",
@ -1184,6 +1192,7 @@ mod tests {
reachable_destination_ids: BTreeSet::new(),
activity_target_ids: BTreeSet::new(),
goals: vec!["publish a position".into()],
current_posture: Some("weighing whether to publish a position".into()),
pressures: vec!["the vote is near".into()],
}],
member_exceptions: vec![],
@ -1520,13 +1529,26 @@ mod tests {
&slice.constituents[0],
&StrategicCellEffect::Institution {
institution_id: "faction-06".into(),
posture: "the vote is near".into(),
posture: "weighing whether to publish a position".into(),
location_ids: vec!["forum".into()],
},
)
.unwrap_err();
assert!(error.to_string().contains("exact current posture"));
assert!(error.to_string().contains("the vote is near"));
assert!(
error
.to_string()
.contains("weighing whether to publish a position")
);
let projector_context = cell_projector_context(&slice);
assert_eq!(
projector_context["constituents"][0]["current_posture"],
"weighing whether to publish a position"
);
assert_eq!(
projector_context["constituents"][0]["pressures"][0],
"the vote is near"
);
}
#[tokio::test]

View file

@ -690,6 +690,7 @@ fn constituent_slice(campaign: &Campaign, id: &str) -> Result<CellConstituentSli
reachable_destination_ids: BTreeSet::new(),
activity_target_ids: crate::resolution::strategic_activity_targets(campaign, id),
goals: vec![],
current_posture: None,
pressures: vec![],
};
match profile.subject_kind {
@ -723,7 +724,7 @@ fn constituent_slice(campaign: &Campaign, id: &str) -> Result<CellConstituentSli
value.name = institution.name.clone();
value.resources = institution.resources.iter().cloned().collect();
value.goals = institution.goals.clone();
value.pressures = vec![institution.posture.clone()];
value.current_posture = Some(institution.posture.clone());
}
AgencySubjectKind::Gestalt => {
let gestalt = campaign.gestalts.get(id).context("cell gestalt vanished")?;
@ -1040,6 +1041,18 @@ mod tests {
);
}
#[test]
fn institution_slice_does_not_disguise_committed_posture_as_pressure() {
let campaign = crate::resolution::tests::campaign(1, 1);
let institution = &campaign.institutions["faction-0000"];
let slice = constituent_slice(&campaign, "faction-0000").unwrap();
assert_eq!(
slice.current_posture.as_deref(),
Some(institution.posture.as_str())
);
assert!(slice.pressures.is_empty());
}
#[test]
fn arena_event_projection_preserves_exact_viewers_including_named_members() {
use crate::domain::*;

View file

@ -284,6 +284,12 @@ knowledge is never treated as an information channel; while dematerialized,
the member can publish only through channels owned by their current leaf
gestalt's agency profile.
Institution rows distinguish `current_posture` from unresolved `pressures`.
The committed posture is projected as already true and is the exact baseline
against which a new institutional commitment is validated. It is never hidden
in a generic pressure list, where a Projector could mistake a completed choice
for a dilemma still awaiting action.
A committed strategic effect must produce an exact canonical consequence.
Institutions cannot re-adopt their current posture. Population pressure effects
carry an explicit lifecycle: `pressure_resolutions` must name exact current

View file

@ -107,6 +107,14 @@ internal perspective for actual cell constituents/member exceptions, Personas
cannot conjure absent entities into contact, and empty target errors explicitly
tell the correction stage that anonymous targets cannot be encoded.
The following run migrated Mira and completed two sustained waves before a
third safe abort. An institution's committed posture had been stored in the
generic cell `pressures` list; its Projector treated that already-made decision
as a live dilemma and the Persona repeated it. `CellConstituentSlice` now has an
explicit `current_posture`; institution pressure is no longer smuggled through
`pressures[0]`. Projector, Interpreter, and local validation share the same
unambiguous baseline.
The multiresolution body is deployed on Starfire. Typed health matched the
immutable release, DeepSeek was ready, and the disposable live strategic-cell
smoke committed three offscreen events plus three accessible news items without

View file

@ -79,6 +79,11 @@ perspective. Event mentions do not transfer a person into another cell, and an
unnamed or unsupplied entity cannot become an activity target merely because a
Persona found it plausible.
Institution slices carry committed `current_posture` separately from unresolved
pressure. Projectors present the posture as existing state; Interpreters and
validators compare any new commitment directly against it. The old overloaded
`pressures[0]` convention is not an authority path.
Gestalt background choices use two distinct typed paths. Pressure transitions
change exact unresolved markers. `gestalt_activity` records an attributed
preparation, coordination, investigation, recruitment, obstruction, trade, or

View file

@ -265,5 +265,5 @@ data_flow:
current_status:
summary: GhostlightDungeon production remains on the verified Starfire release. The acceptance candidate is pressuring multiresolution agency: exact Gestalt activity attempts, typed Gestalt event participation, nested lineage identity preservation, location-bounded presence projection, and automatic refugee callback rematerialization. Production state is untouched while the strict live-fire harness and receipts falsify the candidate.
next_action: Run the strict multiresolution refugee-return live fire after the shared-location, spatial-partition, and perspective-ownership membrane repairs. Require meaningful whole-setting background activity, exact rival-arena attribution, migration across unrelated nested lineage trees, and automatic presence-planner rematerialization of the same durable member. Profile stage receipts and repair only the owning context or typed effect seam.
next_action: Run the strict multiresolution refugee-return live fire after the shared-location, perspective-ownership, and explicit institution-posture repairs. Require meaningful whole-setting background activity, exact rival-arena attribution, migration across unrelated nested lineage trees, and automatic presence-planner rematerialization of the same durable member. Profile stage receipts and repair only the owning context or typed effect seam.
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.