From 585fa806173f4f99a67d3df541db64e16fbb4e99 Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Tue, 18 Aug 2026 00:29:30 +0200 Subject: [PATCH] Preserve chosen member migration in interpretation --- crates/ghostlight-dungeon/src/persona.rs | 28 +++++++++++++------ .../ghostlight-multiresolution-agency.md | 8 ++++++ notes/fresh-workspace-handoff.md | 6 ++++ notes/ghostlight-current-system-map.md | 6 ++++ state/map.yaml | 2 +- 5 files changed, 41 insertions(+), 9 deletions(-) diff --git a/crates/ghostlight-dungeon/src/persona.rs b/crates/ghostlight-dungeon/src/persona.rs index ed886c0..e5f244d 100644 --- a/crates/ghostlight-dungeon/src/persona.rs +++ b/crates/ghostlight-dungeon/src/persona.rs @@ -507,7 +507,7 @@ impl CellProjectionEngine { constrain_cell_proposal_schema(&mut schema, &slice)?; let interpreter_context = serde_json::to_string(&cell_interpreter_context(&slice))?; let permission_guidance = format!( - "Emit at most {} exact constituent- or named-member-attributed attempts. Priority is an urgency score from 0 to 100 where higher numbers resolve first; never use ordinal list rank where 1 means first. Copy each subject's allowed_effect_type: institution -> institution, gestalt -> either gestalt pressure transition or gestalt_activity, actor -> actor_move, named member -> either member_migration or member_activity. Use gestalt_activity or member_activity for a concrete attempt that does not itself change pressure. Map the natural attempt narrowly: communicate means speak, send, offer, ask, or notify; coordinate means arrange a joint attempt, not merely offer one; prepare means the subject's own concrete work such as loading, gathering, fortifying, or rehearsing; investigate means seek information; recruit means invite someone to join; trade means offer an exchange; obstruct means attempt interference. target_subject_ids must come from that exact subject's activity_target_ids and location_ids from its exact location scope. A member_activity must copy the raw member_id and use exactly the member's source_location_id. Internal work by the subject alone is prepare with an empty target_subject_ids list. Coordinate, communicate, trade, recruit, investigate, or obstruct a target only when the Persona explicitly attempts to engage that exact target; permission is not evidence that contact occurred. Write intended_effect as the attempted act itself, not its hoped-for success: 'offer work to X' is valid, while 'integrate X', 'ensure departure', 'build goodwill', acceptance, and any target response are not. Institution posture must be a specific new commitment or withholding, never the current posture or a generic label. Gestalt pressure_resolutions must copy exact current_pressures that the attempted action resolves; pressure_additions are only new unresolved constraints, threats, obligations, or conditions, never completed actions. A pressure transition requires one to four total changes. Use only that subject's permitted_state_references and allowed_public_channels; facet labels are not public channels. A named member migration uses one supplied destination; a population or arena cannot migrate a person. The runtime binds cell identity, revisions, membership, and effective state. The cell id is not an actor id. Use an empty actions array plus a concrete inaction_reason when nobody acts.", + "Emit at most {} exact constituent- or named-member-attributed attempts. Priority is an urgency score from 0 to 100 where higher numbers resolve first; never use ordinal list rank where 1 means first. Copy each subject's allowed_effect_type: institution -> institution, gestalt -> either gestalt pressure transition or gestalt_activity, actor -> actor_move, named member -> either member_migration or member_activity. Use gestalt_activity or member_activity for a concrete attempt that does not itself change pressure. Map the natural attempt narrowly: communicate means speak, send, offer, ask, or notify; coordinate means arrange a joint attempt, not merely offer one; prepare means the subject's own concrete work such as loading, gathering, fortifying, or rehearsing; investigate means seek information; recruit means invite someone to join; trade means offer an exchange; obstruct means attempt interference. target_subject_ids must come from that exact subject's activity_target_ids and location_ids from its exact location scope. A member_activity must copy the raw member_id and use exactly the member's source_location_id. Internal work by the subject alone is prepare with an empty target_subject_ids list. Coordinate, communicate, trade, recruit, investigate, or obstruct a target only when the Persona explicitly attempts to engage that exact target; permission is not evidence that contact occurred. Write intended_effect as the attempted act itself, not its hoped-for success: 'offer work to X' is valid, while 'integrate X', 'ensure departure', 'build goodwill', acceptance, and any target response are not. Institution posture must be a specific new commitment or withholding, never the current posture or a generic label. Gestalt pressure_resolutions must copy exact current_pressures that the attempted action resolves; pressure_additions are only new unresolved constraints, threats, obligations, or conditions, never completed actions. A pressure transition requires one to four total changes. Use only that subject's permitted_state_references and allowed_public_channels; facet labels are not public channels. A named member who chooses to board, depart, travel, or join one supplied destination within this strategic horizon emits member_migration; do not reduce that commitment to member_activity prepare merely because boarding or approach is the first physical step. Use prepare only when the member undertakes local preparation while departure remains unchosen. A population or arena cannot migrate a person. The runtime binds cell identity, revisions, membership, and effective state. The cell id is not an actor id. Use an empty actions array plus a concrete inaction_reason when nobody acts.", slice.max_actions ); let mut request = ModelStageRequest { @@ -572,7 +572,7 @@ impl CellProjectionEngine { model: self.interpreter_model.clone(), snapshot_binding: verifier_binding, lived_stream: format!( - "You are the private semantic verifier between an Interpreter and the world kernel. Decide whether every candidate typed effect and its intended_effect faithfully represent the exact attributed subject's own attempted consequence in the Persona turn. Structural permissions were already checked. A member_migration means that named member personally chooses to travel to the destination; giving away a berth, sending somebody else, waiting, or merely considering travel does not entail it. A member_activity belongs only to that exact named person's stated attempt; it cannot be reassigned to their population. An institution posture must express its stated commitment or withholding. A gestalt pressure resolution must be causally supported by its stated attempt, and an added pressure must be a resulting unresolved condition rather than completed-action prose. An activity records only the exact attempt—never successful preparation, coordination, discovery, recruitment, obstruction, exchange, delivery, persuasion, acceptance, or target response. Reject omissions, reversals, subject swaps, wishful outcomes, and effects that the Persona did not choose. Be concise. Return exactly one JSON object with this shape and no other fields: {{\"supported\":true or false,\"rejected_action_indices\":[zero-based integer indices],\"rationale\":\"one concise reason\"}}. When supported is true, rejected_action_indices must be empty. When false, list every rejected action index.\n\nCONTEXT:\n{}", + "You are the private semantic verifier between an Interpreter and the world kernel. Decide whether every candidate typed effect and its intended_effect faithfully represent the exact attributed subject's own attempted consequence in the Persona turn. Structural permissions were already checked. A member_migration means that named member personally chooses to travel to the destination within the strategic horizon; giving away a berth, sending somebody else, waiting, or merely considering travel does not entail it. Conversely, when the member chooses to board, depart, travel, or join the supplied destination, reject any member_activity that reduces that commitment to preparing, queuing, or approaching. A member_activity belongs only to that exact named person's stated attempt; it cannot be reassigned to their population. An institution posture must express its stated commitment or withholding. A gestalt pressure resolution must be causally supported by its stated attempt, and an added pressure must be a resulting unresolved condition rather than completed-action prose. An activity records only the exact attempt—never successful preparation, coordination, discovery, recruitment, obstruction, exchange, delivery, persuasion, acceptance, or target response. Reject omissions, reversals, subject swaps, wishful outcomes, and effects that the Persona did not choose. Be concise. Return exactly one JSON object with this shape and no other fields: {{\"supported\":true or false,\"rejected_action_indices\":[zero-based integer indices],\"rationale\":\"one concise reason\"}}. When supported is true, rejected_action_indices must be empty. When false, list every rejected action index.\n\nCONTEXT:\n{}", serde_json::to_string(&verifier_context)? ), output_schema: Some(serde_json::to_value(schema_for!( @@ -1123,6 +1123,11 @@ mod tests { ), "cell_interpreter" => { let call = self.interpreter_calls.fetch_add(1, Ordering::SeqCst); + assert!( + request + .lived_stream + .contains("chooses to board, depart, travel, or join") + ); if call == 0 { return Ok(serde_json::json!({ "actions":[{ @@ -1156,12 +1161,19 @@ mod tests { "inaction_reason":null }).to_string()) } - "cell_effect_verifier" => Ok(serde_json::json!({ - "supported":true, - "rejected_action_indices":[], - "rationale":"The institution's typed posture matches its stated commitment." - }) - .to_string()), + "cell_effect_verifier" => { + assert!( + request + .lived_stream + .contains("reject any member_activity that reduces that commitment") + ); + Ok(serde_json::json!({ + "supported":true, + "rejected_action_indices":[], + "rationale":"The institution's typed posture matches its stated commitment." + }) + .to_string()) + } stage => Err(anyhow!("unexpected fixture stage {stage}")), } } diff --git a/docs/architecture/ghostlight-multiresolution-agency.md b/docs/architecture/ghostlight-multiresolution-agency.md index dc8c2e0..ad55cdc 100644 --- a/docs/architecture/ghostlight-multiresolution-agency.md +++ b/docs/architecture/ghostlight-multiresolution-agency.md @@ -105,6 +105,14 @@ a crisis choose to travel, offer work after settling, and later rematerialize as the same person without forcing every refugee to consume an active Persona cell or giving their agency to the destination Gestalt. +The membrane distinguishes a chosen journey from preparation for one. When a +member commits to board, depart, travel, or join a supplied destination within +the strategic horizon, the Interpreter must emit `member_migration`; approaching +the queue is not allowed to erase that commitment into `member_activity`. +Preparing applies only while departure remains unchosen. The semantic verifier +checks both directions so neither consideration becomes travel nor chosen +travel disappears into local activity. + Presence projection is location- and lineage-bounded. The planner sees only active gestalt leaves at the player's location, dormant members whose exact current location is there, and materialized members that might be eligible to diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index b8288de..faf95c6 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -115,6 +115,12 @@ explicit `current_posture`; institution pressure is no longer smuggled through `pressures[0]`. Projector, Interpreter, and local validation share the same unambiguous baseline. +A subsequent strict preflight revealed a lossy Interpreter mapping: Mira chose +to board for South Harbor, but the typed effect recorded only local preparation +and the semantic verifier accepted it. The migration contract now states both +directions explicitly. Chosen travel within the strategic horizon is +`member_migration`; preparation is reserved for a still-unchosen departure. + 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 diff --git a/notes/ghostlight-current-system-map.md b/notes/ghostlight-current-system-map.md index 165ccea..49fa5c3 100644 --- a/notes/ghostlight-current-system-map.md +++ b/notes/ghostlight-current-system-map.md @@ -102,6 +102,12 @@ activity conflict on one member key. A destination population cannot inherit the person's offer, speech, or decision merely because the cover placed them in the same arena. +A named member's explicit commitment to board, depart, travel, or join a +supplied destination maps to `member_migration`, even when the first narrated +motion is only entering a queue. `member_activity: prepare` is valid only while +departure remains unchosen. The Interpreter and semantic verifier share this +distinction. + Population scale uses reversible individuation: ```text diff --git a/state/map.yaml b/state/map.yaml index 4c0f862..1277a43 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -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, 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. + next_action: Run the strict multiresolution refugee-return live fire after the perspective-ownership, explicit institution-posture, and chosen-travel translation 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.