Separate institution posture from pressure
This commit is contained in:
parent
13959c7c09
commit
1c63ee5272
6 changed files with 59 additions and 5 deletions
|
|
@ -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]
|
||||
|
|
|
|||
|
|
@ -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::*;
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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.
|
||||
|
|
|
|||
Loading…
Reference in a new issue