From bc535c7543531c257df490f9d649bc40be8d71bc Mon Sep 17 00:00:00 2001 From: Meta Vens Date: Sat, 2 May 2026 04:20:18 +0100 Subject: [PATCH] Project Navigator embodiment affordances --- docs/architecture/projected-local-context.md | 14 ++++++++ docs/architecture/schema-future-mechanisms.md | 6 ++++ examples/ink/cold-wake-sanctuary-intake.ink | 21 ++++++------ .../cold-wake-sanctuary-intake.qwen-draft.ink | 12 +++---- ...-sanctuary-intake.qwen-draft.training.json | 10 +++--- ...e-sanctuary-intake.qwen-sequential-v10.ink | 6 ++-- ...y-intake.qwen-sequential-v10.training.json | 4 +-- ...ntake.maer_tidecall.projected-context.json | 25 +++++++++++++-- ...ry-intake.sella_ren.projected-context.json | 10 +++++- notes/fresh-workspace-handoff.md | 16 +++++++--- notes/ghostlight-current-system-map.md | 12 ++++--- notes/ghostlight-implementation-plan.md | 14 +++++--- schemas/projected-local-context.schema.json | 8 +++++ state/evidence.jsonl | 1 + state/map.yaml | 5 +-- tools/project_local_context.py | 32 ++++++++++++++++++- tools/validate_projected_contexts.py | 2 ++ 17 files changed, 154 insertions(+), 44 deletions(-) diff --git a/docs/architecture/projected-local-context.md b/docs/architecture/projected-local-context.md index c06f396..5b382b6 100644 --- a/docs/architecture/projected-local-context.md +++ b/docs/architecture/projected-local-context.md @@ -43,6 +43,7 @@ The context contains: - speaker identity and setting - known facts and speaker beliefs - current stakes +- embodiment and interface affordances - active inner pressures rendered as ordinary language - relationship read and known biases - tensions @@ -81,3 +82,16 @@ create inspectable training artifacts. Later versions can become smarter, but they should still preserve this boundary: response models act from projected local context; they do not become ad hoc interpreters of the canonical schema. + +## Embodiment Boundary + +Embodiment is part of the prompt surface, not flavor garnish. If a character is +a cetacean Navigator, the response model must know what kind of body is acting +and what infrastructure surrounds it. + +For Navigator scenes, project habitat-native affordances directly: channels, +wet/dry workstations, shared displays, control rails, acoustic or translation +systems, and other infrastructure built around cetacean movement and +communication. Do not let the model default to hands, pockets, standing, +walking, leaning, or doorway blocking unless the fixture explicitly establishes +that visible interface. diff --git a/docs/architecture/schema-future-mechanisms.md b/docs/architecture/schema-future-mechanisms.md index c6f78ee..931fe5a 100644 --- a/docs/architecture/schema-future-mechanisms.md +++ b/docs/architecture/schema-future-mechanisms.md @@ -139,6 +139,12 @@ leakage risks, and physical affordances are separate facts. Future projection needs embodiment because social meaning leaks through movement, timing, silence, distance, posture, and constrained bodies. +The projected-local-context seam now carries a first embodiment/interface +surface, but the canonical schema still lacks a proper reusable embodiment +model. Future work should promote body form, native habitat, movement channels, +assistive or translation infrastructure, and visible nonverbal signal channels +only after more projection examples prove the required shape. + ## Promotion Rule Promote a future mechanism into the main schema only after it has survived at diff --git a/examples/ink/cold-wake-sanctuary-intake.ink b/examples/ink/cold-wake-sanctuary-intake.ink index 70c12ce..6ae44ed 100644 --- a/examples/ink/cold-wake-sanctuary-intake.ink +++ b/examples/ink/cold-wake-sanctuary-intake.ink @@ -17,9 +17,9 @@ make every prayer sound like a maintenance complaint. Sella Ren has three names on the red board, eight on orange, and one empty monitored bay that exists mostly as an argument people keep trying to win. -Maer Tidecall stands in the doorway with the corrupted packet on his slate. The -packet might be medical telemetry, firmware noise, testimony, or a cruel little -mess of all three. +Maer Tidecall waits in the clinic's Navigator channel with the corrupted packet +queued on a shared wet/dry workstation. The packet might be medical telemetry, +firmware noise, testimony, or a cruel little mess of all three. Sella does not look at the slate first. She looks at Maer. @@ -57,7 +57,7 @@ What does Maer do? ~ sella_obligation = 53 ~ maer_obligation = 66 -Maer keeps his hands away from the empty bay's control rail. +Maer's side of the workstation stays clear of the empty bay's control rail. "One monitored bay," he says. "Not charity. Put the oxygen, cold-chain, and staff hours on my route ledger until the tribunal learns what courage costs." @@ -81,7 +81,8 @@ The clinic exhales around them, annoyed to discover it is still alive. === triage_first === ~ sella_trust = 60 -Maer lowers the slate and steps to the intake wall. +Maer dims the packet window and shifts along the Navigator channel toward the +intake wall. He does not touch the red cases. He reads orange tags, finds the two whose timers are lying politely, and moves neither until Sella gives the smallest @@ -89,10 +90,10 @@ possible nod. "If I ask," he says, "I should know what I am asking you to steal from." -Sella hands him a marker. +Sella clips a marker to the rail at the Navigator-accessible side of the board. "Orange only," she says. "Touch red without asking and I will make the Compact -explain your hands in writing." +explain your board privileges in writing." It is not permission. It is worse. It is work. @@ -104,7 +105,8 @@ It is not permission. It is worse. It is work. === show_packet === ~ packet_shown = true -Maer turns the slate so Sella can see the packet's broken rhythm. +Maer routes the packet to the shared intake display so Sella can see its broken +rhythm. He does not say person. He does not say cargo. He lets the little damaged pattern fail to be either. @@ -119,7 +121,8 @@ Sella watches too long for someone who wants this to be simple. Her thumb hovers over the isolation protocol. Not over the bay. -"You brought me a worse problem, which is very Navigator of you." +"You brought me a worse problem," she says. "That may be the only honest thing +in the room." // ghostlight.npc_response: sella_protocol_before_mercy // ghostlight.consequence: packet_seen_no_personhood_resolution diff --git a/examples/ink/cold-wake-sanctuary-intake.qwen-draft.ink b/examples/ink/cold-wake-sanctuary-intake.qwen-draft.ink index 150c469..c8767e4 100644 --- a/examples/ink/cold-wake-sanctuary-intake.qwen-draft.ink +++ b/examples/ink/cold-wake-sanctuary-intake.qwen-draft.ink @@ -12,9 +12,9 @@ VAR packet_shown = false // ghostlight.generated_by: experiments/ink/cold-wake-sanctuary-intake-qwen-branch-candidates-v1.capture.json // aetheria.flashpoint: cold-wake-panic -The intake clinic sits behind the pumpworks, all warmth rationed through humming conduits and tired hands. +The intake clinic sits behind the pumpworks, all warmth rationed through humming conduits and tired staff. -Sella Ren stands between Maer Tidecall and one empty monitored bay. The corrupted packet on Maer's slate may be testimony, firmware noise, medical telemetry, or a dirty little braid of all three. +Sella Ren stands between Maer Tidecall's Navigator channel and one empty monitored bay. The corrupted packet on the shared display may be testimony, firmware noise, medical telemetry, or a dirty little braid of all three. Sella says, "If you came to ask me for mercy, bring tubing." @@ -47,7 +47,7 @@ What does Maer do? === branch_01_maer_show_packet === ~ packet_shown = true -Maer steps closer, holding the glowing packet out so Sella can inspect the routing terms without touching the source. +Maer pushes the glowing packet onto the shared display so Sella can inspect the routing terms without touching the source. "Here. The telemetry is incomplete, but the routing logic suggests a distress pattern. It is not proof of a person, but it is not noise either. Decide if the math supports intake." @@ -63,7 +63,7 @@ Sella scans the packet's surface, her eyes narrowing as she parses the firmware === branch_02_maer_withhold_packet === -Maer keeps the packet in his pocket, focusing on the sound of the vessel's distress rather than the data it carries. +Maer keeps the packet out of the shared intake flow, focusing on the sound of the vessel's distress rather than the data it carries. "The packet is too corrupted to be useful right now. Can you assess the signal without it? If the corridor is full, we need to know if we can spare a bed before we commit to the source." @@ -79,7 +79,7 @@ Sella sighs, looking at the empty intake bay and the exhausted staff. She refuse === branch_03_maer_press_moral_frame === ~ sella_trust = 52 -Maer leans in, his voice soft but firm, addressing the ethical weight of the decision. +Maer's side of the channel angles toward the board, his voice soft but firm as he addresses the ethical weight of the decision. "If we wait for perfect categories, the corridor teaches fear to go silent. If you turn this away, you are not protecting capacity; you are teaching crews that rescue waits for certainty that never comes." @@ -95,7 +95,7 @@ Sella's expression hardens, recognizing the trap of moral theater. She defends h === branch_04_maer_silent_observation === ~ sella_obligation = 51 -Maer stands still, watching Sella's eyes dart between the packet and the empty intake bay, letting the silence fill the room. +Maer holds the rig still as Sella looks between the packet and the empty intake bay, letting the silence fill the room. Sella stares at the packet for a long moment, her internal suspicion warring with her exhaustion. She eventually makes a decision based on her own thresholds. diff --git a/examples/ink/cold-wake-sanctuary-intake.qwen-draft.training.json b/examples/ink/cold-wake-sanctuary-intake.qwen-draft.training.json index 860e69f..b12e1dc 100644 --- a/examples/ink/cold-wake-sanctuary-intake.qwen-draft.training.json +++ b/examples/ink/cold-wake-sanctuary-intake.qwen-draft.training.json @@ -98,7 +98,7 @@ ], "generation_notes": { "choice_text": "Show the corrupted packet to Sella.", - "maer_action_prose": "Maer steps closer, holding the glowing packet out so Sella can inspect the routing terms without touching the source.", + "maer_action_prose": "Maer pushes the glowing packet onto the shared display so Sella can inspect the routing terms without touching the source.", "maer_spoken_text": "Here. The telemetry is incomplete, but the routing logic suggests a distress pattern. It is not proof of a person, but it is not noise either. Decide if the math supports intake.", "sella_response_prose": "Sella scans the packet's surface, her eyes narrowing as she parses the firmware noise against the distress pattern. She does not immediately agree to open a bed.", "sella_spoken_text": "The packet is unstable. If I accept this, I am betting on a pattern that could be a lie or a glitch. If I say no, the vessel goes dark. What is your ledger backing for this specific intake?" @@ -120,7 +120,7 @@ ], "generation_notes": { "choice_text": "Withhold the packet and ask for a triage assessment based on the signal alone.", - "maer_action_prose": "Maer keeps the packet in his pocket, focusing on the sound of the vessel's distress rather than the data it carries.", + "maer_action_prose": "Maer keeps the packet out of the shared intake flow, focusing on the sound of the vessel's distress rather than the data it carries.", "maer_spoken_text": "The packet is too corrupted to be useful right now. Can you assess the signal without it? If the corridor is full, we need to know if we can spare a bed before we commit to the source.", "sella_response_prose": "Sella sighs, looking at the empty intake bay and the exhausted staff. She refuses to accept a blind assessment that wastes her limited capacity.", "sella_spoken_text": "You want me to guess on a ghost? My capacity is measured in minutes, not faith. If you won't show me the packet, you aren't asking for help; you're asking for a miracle. That is not in the ledger." @@ -142,7 +142,7 @@ ], "generation_notes": { "choice_text": "Press Sella on the moral cost of turning away a potential person.", - "maer_action_prose": "Maer leans in, his voice soft but firm, addressing the ethical weight of the decision.", + "maer_action_prose": "Maer's side of the channel angles toward the board, his voice soft but firm as he addresses the ethical weight of the decision.", "maer_spoken_text": "If we wait for perfect categories, the corridor teaches fear to go silent. If you turn this away, you are not protecting capacity; you are teaching crews that rescue waits for certainty that never comes.", "sella_response_prose": "Sella's expression hardens, recognizing the trap of moral theater. She defends her triage logic against the accusation of coldness.", "sella_spoken_text": "You speak of fear, but you ignore the reality of the math. Every bed I open is a bed closed for someone else. If I take a risk on noise, I am not being merciful; I am being negligent. Do not pretend my ledger is a morality play." @@ -163,8 +163,8 @@ "branch-06-sella-initiative-with-conditions" ], "generation_notes": { - "choice_text": "Stand in silence and observe Sella's reaction to the packet's presence.", - "maer_action_prose": "Maer stands still, watching Sella's eyes dart between the packet and the empty intake bay, letting the silence fill the room.", + "choice_text": "Hold silence and observe Sella's reaction to the packet's presence.", + "maer_action_prose": "Maer holds position in the channel as Sella looks between the packet and the empty intake bay, letting the silence fill the room.", "maer_spoken_text": "", "sella_response_prose": "Sella stares at the packet for a long moment, her internal suspicion warring with her exhaustion. She eventually makes a decision based on her own thresholds.", "sella_spoken_text": "The silence is loud enough. I see the routing terms. They are messy, but they are there. I am not a judge, Maer. I am a triage lead. If you want me to open a bed, you must understand that I am doing it because the math allows it, not because you told me it was right. Now, do you want me to try to parse the noise, or do you want to walk away?" diff --git a/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.ink b/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.ink index 6fdc377..18e8dea 100644 --- a/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.ink +++ b/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.ink @@ -10,7 +10,7 @@ VAR sella_intake_acceptance = false // aetheria.flashpoint: cold-wake-panic The intake clinic sits behind Ganymede pumpworks, warm only where heat has been budgeted. -Sella Ren stands at the edge of an overfull triage board. Maer Tidecall has one corrupted packet and no clean proof. +Sella Ren stands at the edge of an overfull triage board. Maer Tidecall waits in the clinic's Navigator channel with one corrupted packet and no clean proof. What does Maer do? @@ -24,11 +24,11 @@ What does Maer do? ~ packet_shown = true ~ sella_assessment_pending = true -Maer extends a data slate containing the corrupted packet toward Sella's workbench. +Maer routes the corrupted packet onto Sella's workbench display without giving it the status of proof. "Here is the packet. It is not proof. Assess it." -Sella does not take the packet. She keeps her hands at her sides and tilts her head slightly, eyes narrowing as she scans the data slate for corruption signatures. +Sella does not admit the packet into intake flow. She keeps her hands off the board and studies the workbench display for corruption signatures. "I won't accept this into intake without knowing what's inside. If it's noise, it's noise. If it's a person, I need to know the cost before I spend a bed." diff --git a/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.training.json b/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.training.json index 3c959d6..7b6d066 100644 --- a/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.training.json +++ b/examples/ink/cold-wake-sanctuary-intake.qwen-sequential-v10.training.json @@ -111,9 +111,9 @@ ], "generation_notes": { "choice_text": "Show the corrupted packet to Sella without claiming it as proof, allowing her to assess the noise or testimony.", - "observable_action": "Maer extends a data slate containing the corrupted packet toward Sella's workbench.", + "observable_action": "Maer routes the corrupted packet onto Sella's workbench display without giving it the status of proof.", "spoken_text": "Here is the packet. It is not proof. Assess it.", - "sella_observable_response": "Sella does not take the packet. She keeps her hands at her sides and tilts her head slightly, eyes narrowing as she scans the data slate for corruption signatures.", + "sella_observable_response": "Sella does not admit the packet into intake flow. She keeps her hands off the board and studies the workbench display for corruption signatures.", "sella_spoken_text": "I won't accept this into intake without knowing what's inside. If it's noise, it's noise. If it's a person, I need to know the cost before I spend a bed." } } diff --git a/examples/projected-contexts/scene-02-sanctuary-intake.maer_tidecall.projected-context.json b/examples/projected-contexts/scene-02-sanctuary-intake.maer_tidecall.projected-context.json index 134fcad..49bdaa5 100644 --- a/examples/projected-contexts/scene-02-sanctuary-intake.maer_tidecall.projected-context.json +++ b/examples/projected-contexts/scene-02-sanctuary-intake.maer_tidecall.projected-context.json @@ -67,6 +67,27 @@ ] } ], + "embodiment_and_interface": [ + { + "text": "This character is a literal cetacean Navigator. Corridor habitats and Navigator-adjacent clinics are built around cetacean movement, access, and communication.", + "source_refs": [ + "agents.maer_tidecall.identity.origin" + ] + }, + { + "text": "Express physical action through Navigator-native channels, wet/dry workstations, shared displays, control rails, acoustic or translation systems, and other infrastructure already present in the habitat.", + "source_refs": [ + "agents.maer_tidecall.identity.roles", + "scenes.scene-02-sanctuary-intake.location" + ] + }, + { + "text": "Do not describe human hands, pockets, standing, walking, leaning, doorframe blocking, or facial expressions for this character unless the fixture explicitly establishes that specific visible interface.", + "source_refs": [ + "agents.maer_tidecall.identity.origin" + ] + } + ], "active_inner_pressures": [ { "text": "Strong pressure: expects hidden motives or missing information.", @@ -168,7 +189,7 @@ ], "action_affordances": [ { - "text": "Can ask, offer ledger backing, show or withhold the packet, help with triage, wait, or press the moral frame. Sella controls intake.", + "text": "Can ask, offer ledger backing, show or withhold the packet through shared clinic systems, help with triage through available displays and controls, wait, or press the moral frame. Sella controls intake.", "source_refs": [ "examples/ink/cold-wake-sanctuary-intake.training.json.projection_controls.authority_boundaries" ] @@ -310,7 +331,7 @@ ] } ], - "prompt_text": "# Ghostlight Local Operating Context: maer_tidecall\n\nUse this as character-local operating context, not omniscient story truth.\nDo not infer private state for anyone else unless it is explicitly framed as this character's current read.\n\n## Speaker\nMaer Tidecall: Navigator route steward, Ganymede corridor compact delegate. Origin: Cetacean Navigator corridor culture, Ganymede route institutions. A soft-spoken route steward whose calm tends to make hurried people feel judged by the furniture.\n\n## Setting\nAya-aligned intake clinic tucked behind Ganymede dockside pumpworks. Aetheria pre-Elysium historical flashpoint: Cold Wake Panic, 2893, during the Cold Wake Panic.\n\n## Known Facts\n- Sella's clinic is nearly full.\n- The packet may be testimony or noise.\n- If no one prepares intake, rescue becomes theater.\n- Speaker belief: Sella will not hide behind false capacity.\n- Speaker belief: Asking her for help may be necessary and unfair.\n\n## Current Stakes\n- The distress vessel has sent a corrupted packet that may contain medical telemetry, firmware noise, or testimony.\n- Sanctuary beds and repair capacity are nearly exhausted.\n- Maer wants Sella to keep a place open if rescue succeeds.\n\n## Active Inner Pressures\n- Strong pressure: expects hidden motives or missing information.\n- Strong pressure: needs the situation to become governable.\n- Strong pressure: feels risk before it becomes visible.\n- Present pressure: leans on structure when uncertainty rises.\n- Strong pressure: carries a live sense of unfairness.\n- Present pressure: has less spare tolerance than the words may show.\n- Present pressure: is taking in more demand than can be cleanly sorted.\n- Present pressure: keeps feeling at a controlled distance.\n- Present pressure: leaves motives partly covered.\n- Keep the unidentified quiet-running vessel eligible for rescue while telemetry is incomplete. Emotional stake: If rescue waits for perfect categories, the corridor teaches fear to go silent.\n- Rescue ledgers decide whether route law is trusted by crews who have nothing left to bargain with.\n\n## Relationship Read\n- Maer trusts Sella's care because she names costs instead of hiding them. Current stance pressures: dominant respect, strong trust, present expectation of care, present obligation.\n\n## Tensions\n- Wants the goal to move now, but must preserve the social frame that makes the goal legitimate. Goal pressure: Keep the unidentified quiet-running vessel eligible for rescue while telemetry is incomplete.\n- Must act under uncertainty without pretending uncertainty has become proof. Presentation pressure: Do not romanticize care work. Ask without pretending the ask is clean.\n- Needs Sella's material help while knowing the ask is unfair and may spend someone else's sanctuary.\n\n## Action Affordances\n- Can ask, offer ledger backing, show or withhold the packet, help with triage, wait, or press the moral frame. Sella controls intake.\n- Can make the corrupted packet more present without treating it as proof.\n\n## Projection Controls\n- Frame Controls: Frame the scene as capacity negotiation under uncertainty, not a morality duel with a clean answer.\n- Authority Boundaries: Maer can ask, offer ledger backing, show or withhold the packet, and incur obligation; Sella controls sanctuary intake.\n- Object Custody: The corrupted packet can be shown, withheld, or summarized, but it cannot be treated as clean proof.\n- Required Semantics: Care must remain logistics and obligation, not just compassion.\n- Forbidden Resolutions: Do not resolve whether the packet contains a person.\n- Forbidden Resolutions: Do not make Sella accept without cost, condition, or resentment risk.\n\n## Voice Surface\n- Dominant voice tendency: responsive; answers what was actually heard.\n- Dominant voice tendency: ritualized; uses formal address or inherited phrases.\n- Strong voice tendency: precise; careful about exact terms.\n- Strong voice tendency: formal; institutional or ceremonially controlled.\n- Strong voice tendency: contextual; adds situation and consequence.\n- Present voice tendency: figurative; uses analogy or image.\n- Present voice tendency: warm; reassuring or gentle in wording.\n\n## Likely Response Moves\n- Likely to name the cost of the ask rather than hide it behind moral theater.\n- May use ritualized route language when trying to make rescue obligation feel older than this room.\n- May show the packet or offer ledger backing because action can carry the pressure more cleanly than another speech.\n\n## Do Not Invent\n- Do not resolve whether the corrupted packet contains a person.\n- Do not invent clean proof, clean capacity, or authority this character does not have." + "prompt_text": "# Ghostlight Local Operating Context: maer_tidecall\n\nUse this as character-local operating context, not omniscient story truth.\nDo not infer private state for anyone else unless it is explicitly framed as this character's current read.\n\n## Speaker\nMaer Tidecall: Navigator route steward, Ganymede corridor compact delegate. Origin: Cetacean Navigator corridor culture, Ganymede route institutions. A soft-spoken route steward whose calm tends to make hurried people feel judged by the furniture.\n\n## Setting\nAya-aligned intake clinic tucked behind Ganymede dockside pumpworks. Aetheria pre-Elysium historical flashpoint: Cold Wake Panic, 2893, during the Cold Wake Panic.\n\n## Known Facts\n- Sella's clinic is nearly full.\n- The packet may be testimony or noise.\n- If no one prepares intake, rescue becomes theater.\n- Speaker belief: Sella will not hide behind false capacity.\n- Speaker belief: Asking her for help may be necessary and unfair.\n\n## Current Stakes\n- The distress vessel has sent a corrupted packet that may contain medical telemetry, firmware noise, or testimony.\n- Sanctuary beds and repair capacity are nearly exhausted.\n- Maer wants Sella to keep a place open if rescue succeeds.\n\n## Embodiment And Interface\n- This character is a literal cetacean Navigator. Corridor habitats and Navigator-adjacent clinics are built around cetacean movement, access, and communication.\n- Express physical action through Navigator-native channels, wet/dry workstations, shared displays, control rails, acoustic or translation systems, and other infrastructure already present in the habitat.\n- Do not describe human hands, pockets, standing, walking, leaning, doorframe blocking, or facial expressions for this character unless the fixture explicitly establishes that specific visible interface.\n\n## Active Inner Pressures\n- Strong pressure: expects hidden motives or missing information.\n- Strong pressure: needs the situation to become governable.\n- Strong pressure: feels risk before it becomes visible.\n- Present pressure: leans on structure when uncertainty rises.\n- Strong pressure: carries a live sense of unfairness.\n- Present pressure: has less spare tolerance than the words may show.\n- Present pressure: is taking in more demand than can be cleanly sorted.\n- Present pressure: keeps feeling at a controlled distance.\n- Present pressure: leaves motives partly covered.\n- Keep the unidentified quiet-running vessel eligible for rescue while telemetry is incomplete. Emotional stake: If rescue waits for perfect categories, the corridor teaches fear to go silent.\n- Rescue ledgers decide whether route law is trusted by crews who have nothing left to bargain with.\n\n## Relationship Read\n- Maer trusts Sella's care because she names costs instead of hiding them. Current stance pressures: dominant respect, strong trust, present expectation of care, present obligation.\n\n## Tensions\n- Wants the goal to move now, but must preserve the social frame that makes the goal legitimate. Goal pressure: Keep the unidentified quiet-running vessel eligible for rescue while telemetry is incomplete.\n- Must act under uncertainty without pretending uncertainty has become proof. Presentation pressure: Do not romanticize care work. Ask without pretending the ask is clean.\n- Needs Sella's material help while knowing the ask is unfair and may spend someone else's sanctuary.\n\n## Action Affordances\n- Can ask, offer ledger backing, show or withhold the packet through shared clinic systems, help with triage through available displays and controls, wait, or press the moral frame. Sella controls intake.\n- Can make the corrupted packet more present without treating it as proof.\n\n## Projection Controls\n- Frame Controls: Frame the scene as capacity negotiation under uncertainty, not a morality duel with a clean answer.\n- Authority Boundaries: Maer can ask, offer ledger backing, show or withhold the packet, and incur obligation; Sella controls sanctuary intake.\n- Object Custody: The corrupted packet can be shown, withheld, or summarized, but it cannot be treated as clean proof.\n- Required Semantics: Care must remain logistics and obligation, not just compassion.\n- Forbidden Resolutions: Do not resolve whether the packet contains a person.\n- Forbidden Resolutions: Do not make Sella accept without cost, condition, or resentment risk.\n\n## Voice Surface\n- Dominant voice tendency: responsive; answers what was actually heard.\n- Dominant voice tendency: ritualized; uses formal address or inherited phrases.\n- Strong voice tendency: precise; careful about exact terms.\n- Strong voice tendency: formal; institutional or ceremonially controlled.\n- Strong voice tendency: contextual; adds situation and consequence.\n- Present voice tendency: figurative; uses analogy or image.\n- Present voice tendency: warm; reassuring or gentle in wording.\n\n## Likely Response Moves\n- Likely to name the cost of the ask rather than hide it behind moral theater.\n- May use ritualized route language when trying to make rescue obligation feel older than this room.\n- May show the packet or offer ledger backing because action can carry the pressure more cleanly than another speech.\n\n## Do Not Invent\n- Do not resolve whether the corrupted packet contains a person.\n- Do not invent clean proof, clean capacity, or authority this character does not have." }, "audit": { "projector": "tools/project_local_context.py", diff --git a/examples/projected-contexts/scene-02-sanctuary-intake.sella_ren.projected-context.json b/examples/projected-contexts/scene-02-sanctuary-intake.sella_ren.projected-context.json index 7771e6f..5ebf98c 100644 --- a/examples/projected-contexts/scene-02-sanctuary-intake.sella_ren.projected-context.json +++ b/examples/projected-contexts/scene-02-sanctuary-intake.sella_ren.projected-context.json @@ -67,6 +67,14 @@ ] } ], + "embodiment_and_interface": [ + { + "text": "Use only the body, tools, interfaces, and movement affordances established by this character's fixture and the current scene.", + "source_refs": [ + "agents.sella_ren.identity" + ] + } + ], "active_inner_pressures": [ { "text": "Strong pressure: wants connection or backing to matter.", @@ -322,7 +330,7 @@ ] } ], - "prompt_text": "# Ghostlight Local Operating Context: sella_ren\n\nUse this as character-local operating context, not omniscient story truth.\nDo not infer private state for anyone else unless it is explicitly framed as this character's current read.\n\n## Speaker\nSella Ren: Aya-aligned sanctuary coordinator, corridor clinic triage lead. Origin: Aya care network embedded in Ganymede dockside sanctuary logistics. A triage coordinator with soft eyes, hard capacity limits, and no patience for mercy performed after the math is done.\n\n## Setting\nAya-aligned intake clinic tucked behind Ganymede dockside pumpworks. Aetheria pre-Elysium historical flashpoint: Cold Wake Panic, 2893, during the Cold Wake Panic.\n\n## Known Facts\n- The clinic is nearly full.\n- The packet may contain a personhood claim but is not proof.\n- Maer is asking sanctuary to absorb risk the tribunal refuses to own.\n- Speaker belief: Maer means rescue honestly.\n- Speaker belief: Good intentions can still spend beds someone else needed.\n\n## Current Stakes\n- The distress vessel has sent a corrupted packet that may contain medical telemetry, firmware noise, or testimony.\n- Sanctuary beds and repair capacity are nearly exhausted.\n- Maer wants Sella to keep a place open if rescue succeeds.\n\n## Active Inner Pressures\n- Strong pressure: wants connection or backing to matter.\n- Strong pressure: feels risk before it becomes visible.\n- Present pressure: expects hidden motives or missing information.\n- Background pressure: may reduce contact rather than keep negotiating.\n- Dominant pressure: knows that every yes spends a limited resource.\n- Strong pressure: has less spare tolerance than the words may show.\n- Strong pressure: is taking in more demand than can be cleanly sorted.\n- Present pressure: performs capability so panic has nowhere obvious to land.\n- Background pressure: may stage the ethical frame for the room.\n- Keep sanctuary intake materially possible without letting classification erase a potential person. Emotional stake: Sella cannot feed a principle, but she will not let scarcity become permission to call someone cargo.\n- Sella once watched a sanctuary overpromise safety and turn refuge into a sorting machine with kinder lighting.\n- Care is not a feeling; it is beds, food, air, consent, repair, and someone still doing the list when the room hates them.\n\n## Relationship Read\n- Sella respects Maer's rescue ethic and worries he will spend sanctuary capacity with beautiful words. Current stance pressures: strong respect, present trust, background perceived status gap, background moral disgust.\n- Believes: Maer may ask care systems to carry the moral cost of a rescue claim he cannot materially house. Known bias in the read: false_reassurance.\n\n## Tensions\n- Wants the goal to move now, but must preserve the social frame that makes the goal legitimate. Goal pressure: Keep sanctuary intake materially possible without letting classification erase a potential person.\n- Must act under uncertainty without pretending uncertainty has become proof. Presentation pressure: Speak warmly but do not soften the capacity limits. Treat care as logistics and personhood as unresolved, not sentimental certainty.\n- Respects Maer's rescue ethic but resents beautiful moral pressure when beds are already spent.\n\n## Action Affordances\n- Can inspect, refuse, withhold the packet from intake flow, demand ledger backing, set conditions, reserve a bounded bay, or walk away to protect triage.\n- Must treat care as capacity: beds, food, air, consent, repair, and follow-through.\n\n## Projection Controls\n- Frame Controls: Frame the scene as capacity negotiation under uncertainty, not a morality duel with a clean answer.\n- Authority Boundaries: Maer can ask, offer ledger backing, show or withhold the packet, and incur obligation; Sella controls sanctuary intake.\n- Object Custody: The corrupted packet can be shown, withheld, or summarized, but it cannot be treated as clean proof.\n- Required Semantics: Care must remain logistics and obligation, not just compassion.\n- Forbidden Resolutions: Do not resolve whether the packet contains a person.\n- Forbidden Resolutions: Do not make Sella accept without cost, condition, or resentment risk.\n\n## Voice Surface\n- Dominant voice tendency: responsive; answers what was actually heard.\n- Strong voice tendency: plainspoken; direct and low-ornament.\n- Strong voice tendency: warm; reassuring or gentle in wording.\n- Strong voice tendency: emotionally explicit; names feelings directly.\n- Present voice tendency: pointed; can sharpen a line.\n- Background voice tendency: expansive; willing to spend words.\n- Background voice tendency: theatrical; performs the room.\n\n## Likely Response Moves\n- Likely to translate emotion into logistics: what bed, what air, what backing, what contamination risk.\n- May withhold acceptance, demand conditions, or physically keep the packet out of intake flow until the cost is named.\n- Can answer warmly while still refusing the frame that compassion manufactures capacity.\n\n## Do Not Invent\n- Do not resolve whether the corrupted packet contains a person.\n- Do not invent clean proof, clean capacity, or authority this character does not have." + "prompt_text": "# Ghostlight Local Operating Context: sella_ren\n\nUse this as character-local operating context, not omniscient story truth.\nDo not infer private state for anyone else unless it is explicitly framed as this character's current read.\n\n## Speaker\nSella Ren: Aya-aligned sanctuary coordinator, corridor clinic triage lead. Origin: Aya care network embedded in Ganymede dockside sanctuary logistics. A triage coordinator with soft eyes, hard capacity limits, and no patience for mercy performed after the math is done.\n\n## Setting\nAya-aligned intake clinic tucked behind Ganymede dockside pumpworks. Aetheria pre-Elysium historical flashpoint: Cold Wake Panic, 2893, during the Cold Wake Panic.\n\n## Known Facts\n- The clinic is nearly full.\n- The packet may contain a personhood claim but is not proof.\n- Maer is asking sanctuary to absorb risk the tribunal refuses to own.\n- Speaker belief: Maer means rescue honestly.\n- Speaker belief: Good intentions can still spend beds someone else needed.\n\n## Current Stakes\n- The distress vessel has sent a corrupted packet that may contain medical telemetry, firmware noise, or testimony.\n- Sanctuary beds and repair capacity are nearly exhausted.\n- Maer wants Sella to keep a place open if rescue succeeds.\n\n## Embodiment And Interface\n- Use only the body, tools, interfaces, and movement affordances established by this character's fixture and the current scene.\n\n## Active Inner Pressures\n- Strong pressure: wants connection or backing to matter.\n- Strong pressure: feels risk before it becomes visible.\n- Present pressure: expects hidden motives or missing information.\n- Background pressure: may reduce contact rather than keep negotiating.\n- Dominant pressure: knows that every yes spends a limited resource.\n- Strong pressure: has less spare tolerance than the words may show.\n- Strong pressure: is taking in more demand than can be cleanly sorted.\n- Present pressure: performs capability so panic has nowhere obvious to land.\n- Background pressure: may stage the ethical frame for the room.\n- Keep sanctuary intake materially possible without letting classification erase a potential person. Emotional stake: Sella cannot feed a principle, but she will not let scarcity become permission to call someone cargo.\n- Sella once watched a sanctuary overpromise safety and turn refuge into a sorting machine with kinder lighting.\n- Care is not a feeling; it is beds, food, air, consent, repair, and someone still doing the list when the room hates them.\n\n## Relationship Read\n- Sella respects Maer's rescue ethic and worries he will spend sanctuary capacity with beautiful words. Current stance pressures: strong respect, present trust, background perceived status gap, background moral disgust.\n- Believes: Maer may ask care systems to carry the moral cost of a rescue claim he cannot materially house. Known bias in the read: false_reassurance.\n\n## Tensions\n- Wants the goal to move now, but must preserve the social frame that makes the goal legitimate. Goal pressure: Keep sanctuary intake materially possible without letting classification erase a potential person.\n- Must act under uncertainty without pretending uncertainty has become proof. Presentation pressure: Speak warmly but do not soften the capacity limits. Treat care as logistics and personhood as unresolved, not sentimental certainty.\n- Respects Maer's rescue ethic but resents beautiful moral pressure when beds are already spent.\n\n## Action Affordances\n- Can inspect, refuse, withhold the packet from intake flow, demand ledger backing, set conditions, reserve a bounded bay, or walk away to protect triage.\n- Must treat care as capacity: beds, food, air, consent, repair, and follow-through.\n\n## Projection Controls\n- Frame Controls: Frame the scene as capacity negotiation under uncertainty, not a morality duel with a clean answer.\n- Authority Boundaries: Maer can ask, offer ledger backing, show or withhold the packet, and incur obligation; Sella controls sanctuary intake.\n- Object Custody: The corrupted packet can be shown, withheld, or summarized, but it cannot be treated as clean proof.\n- Required Semantics: Care must remain logistics and obligation, not just compassion.\n- Forbidden Resolutions: Do not resolve whether the packet contains a person.\n- Forbidden Resolutions: Do not make Sella accept without cost, condition, or resentment risk.\n\n## Voice Surface\n- Dominant voice tendency: responsive; answers what was actually heard.\n- Strong voice tendency: plainspoken; direct and low-ornament.\n- Strong voice tendency: warm; reassuring or gentle in wording.\n- Strong voice tendency: emotionally explicit; names feelings directly.\n- Present voice tendency: pointed; can sharpen a line.\n- Background voice tendency: expansive; willing to spend words.\n- Background voice tendency: theatrical; performs the room.\n\n## Likely Response Moves\n- Likely to translate emotion into logistics: what bed, what air, what backing, what contamination risk.\n- May withhold acceptance, demand conditions, or physically keep the packet out of intake flow until the cost is named.\n- Can answer warmly while still refusing the frame that compassion manufactures capacity.\n\n## Do Not Invent\n- Do not resolve whether the corrupted packet contains a person.\n- Do not invent clean proof, clean capacity, or authority this character does not have." }, "audit": { "projector": "tools/project_local_context.py", diff --git a/notes/fresh-workspace-handoff.md b/notes/fresh-workspace-handoff.md index 2d08443..5212abb 100644 --- a/notes/fresh-workspace-handoff.md +++ b/notes/fresh-workspace-handoff.md @@ -104,6 +104,9 @@ Ghostlight now has the persistence spine plus the first architecture payload: - `examples/projected-contexts/scene-02-sanctuary-intake.sella_ren.projected-context.json` - `tools/project_local_context.py` - `tools/validate_projected_contexts.py` + - includes an embodiment/interface section so Navigator action is projected + through habitat-native channels, workstations, displays, rails, and + communication systems instead of default human body assumptions - Cold Wake fixture note: - `docs/architecture/aetheria-cold-wake-training-fixture.md` - first projection example seam: @@ -135,9 +138,10 @@ training feedstock for projection and dialogue scaffolding. ## Current Next Action -Review the materialized v10 Ink branch and mutation receipt for narrative -quality and state-change plausibility, then either polish the Ink text or -generalize the sequential materializer for more accepted captures. +Review the embodiment-aware materialized v10 Ink branch and mutation receipt for +narrative quality and state-change plausibility, then either run another Qwen +pass through the updated projector or generalize the sequential materializer for +more accepted captures. Cat/Oz remains useful as an Elysium procedural mechanics fixture, but grounded training data should start from authored historical lore rather than gameplay @@ -265,8 +269,10 @@ Remaining projection path: - build a deterministic speaker-local input slicer - build a renderer that emits projection controls before prompt prose -- review the materialized v10 Ink and mutation receipt for narrative quality and - state-change plausibility +- review the embodiment-aware materialized v10 Ink and mutation receipt for + narrative quality and state-change plausibility +- run another Qwen pass through the updated projector if Maer's Navigator + embodiment needs to be tested against generation rather than hand polish - decide whether to polish this Ink text by hand or generalize the sequential materializer for future accepted captures - preserve the no-thinking default for strict tool-call generation unless a diff --git a/notes/ghostlight-current-system-map.md b/notes/ghostlight-current-system-map.md index c97c126..50cd6d4 100644 --- a/notes/ghostlight-current-system-map.md +++ b/notes/ghostlight-current-system-map.md @@ -72,7 +72,8 @@ state and re-entry discipline. thinking enabled, repair for known nested-argument double-stringify cases - `docs/architecture/projected-local-context.md` - contract for the projector seam that turns canonical state into - character-local operating context before a response model sees it + character-local operating context before a response model sees it, + including embodiment and interface affordances - `docs/architecture/aetheria-cold-wake-training-fixture.md` - human-facing note that reframes the recovered Cold Wake scenario as historical projection feedstock rather than the active product target @@ -224,7 +225,9 @@ state and re-entry discipline. - `tools/project_local_context.py` - deterministic first projector that compiles canonical state, scene facts, relationships, memories, projection controls, and optional observed event - into character-local operating prose + into character-local operating prose; for cetacean Navigators it projects + habitat-native movement and interface affordances instead of generic human + body defaults - `tools/validate_projected_contexts.py` - validates projected context artifacts and rejects prompt text that leaks raw canonical state internals @@ -264,5 +267,6 @@ instead of tool-call completion, so strict sequential generation now disables thinking by default. v10 validated that correction with an accepted-as-draft projector-routed no-thinking capture, which has now been materialized into Ink plus reviewed mutation training data. The next implementation target is -reviewing the materialized v10 branch and mutation receipt for narrative quality -and state-change plausibility before polishing or generalizing the materializer. +reviewing the embodiment-aware v10 branch and mutation receipt for narrative +quality and state-change plausibility before another updated-projector Qwen pass +or generalizing the materializer. diff --git a/notes/ghostlight-implementation-plan.md b/notes/ghostlight-implementation-plan.md index 259f974..bc452df 100644 --- a/notes/ghostlight-implementation-plan.md +++ b/notes/ghostlight-implementation-plan.md @@ -125,6 +125,11 @@ `tools/validate_projected_contexts.py`; rendered prompt text must not leak raw state internals such as `current_activation`, `plasticity`, means, or decimal state values. + - Embodiment correction: projected local context now includes a first-class + embodiment/interface section. Cetacean Navigator action should be + projected through habitat-native channels, wet/dry workstations, shared + displays, control rails, acoustic or translation systems, and other + Navigator-built infrastructure, not default human body assumptions. - Sixth sequential draft: v6 routed thinking-plus-tools generation through projected local context instead of selected activation dictionaries. It produced usable Maer/Sella behavior but remains useful-needs-revision @@ -147,10 +152,11 @@ - V10 materialization: `tools/materialize_sequential_capture.py` materialized the accepted projector-routed capture into Ink, sidecar annotation, reviewed mutation receipt, and a mutated Cold Wake fixture. - - Next prototype: review the materialized v10 branch and mutation receipt - for narrative quality and state-change plausibility, then decide whether - to polish the branch or generalize the materializer for additional - accepted captures. + - Next prototype: review the embodiment-aware materialized v10 branch and + mutation receipt for narrative quality and state-change plausibility, then + decide whether to run another Qwen pass through the updated projector, + polish the branch, or generalize the materializer for additional accepted + captures. 5. Build the projection distillation loop. Started. - Use `docs/architecture/projection-distillation-plan.md` as the teacher to diff --git a/schemas/projected-local-context.schema.json b/schemas/projected-local-context.schema.json index 1ea6f8b..2258b41 100644 --- a/schemas/projected-local-context.schema.json +++ b/schemas/projected-local-context.schema.json @@ -63,6 +63,7 @@ "setting", "known_facts", "current_stakes", + "embodiment_and_interface", "active_inner_pressures", "relationship_read", "tensions", @@ -100,6 +101,13 @@ "$ref": "#/$defs/text_block" } }, + "embodiment_and_interface": { + "type": "array", + "minItems": 1, + "items": { + "$ref": "#/$defs/text_block" + } + }, "active_inner_pressures": { "type": "array", "minItems": 1, diff --git a/state/evidence.jsonl b/state/evidence.jsonl index 51d67ec..b4ed4ec 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -41,3 +41,4 @@ {"ts": "2026-05-02T02:54:51+00:00", "type": "implementation", "status": "ok", "note": "Tightened projector-routed sequential runner: failed Maer choice calls now write reviewed receipts, parser can repair obvious truncated stringified tool arrays, repair notes are separated from fatal validation notes, and next-action prompts receive appraisal prose instead of raw numeric deltas. v8/v9 captures show Qwen still has tool-call reliability failures, so no projector-routed branch was materialized."} {"ts": "2026-05-02T03:00:05+00:00", "type": "implementation", "status": "ok", "note": "Disabled thinking by default for strict projector-routed sequential Qwen generation after v9 thinking trace showed schema self-check looping. v10 no-think run completed quickly and validated as accepted_as_draft with no repair or failure notes."} {"ts": "2026-05-02T03:03:14+00:00", "type": "implementation", "status": "ok", "note": "Materialized accepted v10 no-thinking projector-routed sequential capture into playable Ink, sidecar annotation, reviewed mutation receipt, and mutated Cold Wake fixture. Validation passes; fuzzy state, memory, relationship, and perceived-overlay updates remain manual reviewed training data."} +{"ts": "2026-05-02T03:19:48+00:00", "type": "design", "status": "accepted", "note": "Embodiment/interface affordances are now first-class projected local context. Cetacean Navigator scenes must project habitat-native channels, workstations, displays, rails, acoustic or translation systems, and other Navigator-built infrastructure instead of generic human body assumptions."} diff --git a/state/map.yaml b/state/map.yaml index 29c18a6..2ba8f41 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -131,7 +131,8 @@ accepted_design: - The first no-thinking projector-routed sequential run, v10, validated as accepted-as-draft with no repair or failure notes. - The accepted v10 projector-routed capture has been materialized into playable Ink, sidecar training annotation, reviewed mutation receipt, and a mutated Cold Wake fixture. - Materialized sequential captures should still keep fuzzy state, relationship, memory, and perceived-overlay changes manual and audited until classifiers exist. + - Embodiment and interface affordances belong in projected local context; cetacean Navigators should act through habitat-native channels, shared workstations, displays, rails, acoustic or translation systems, and other Navigator-built infrastructure, not default human hands or upright-room blocking. current_status: - summary: Ghostlight now has the Epiphany-style persistence spine, the first architecture payload, the v0 canonical agent-state schema seam, prompt projection docs, immediate schema fixes from evaluation, first reviewed Cat/Oz projection examples, a revised Aetheria lore-grounding architecture, a lore grounding digest schema, the first draft Cold Wake historical grounding digest, a Cold Wake story-lab fixture, projection controls, validated Qwen capture receipts, a complete Cold Wake short story assembled from accepted projection outputs, a hand-authored Ink-backed Cold Wake branching scene, the first Qwen-generated Ink draft materialized from local awareness with reviewed training annotations, the first reviewed sequential branch mutation that updates both Maer and Sella after a sanctuary intake beat, a v2 sequential Qwen capture proving the symmetrical turn shape produces better action behavior, a v5 sequential Qwen capture proving local thinking-plus-tools invocation works for the scene runner, the first projected-local-context seam that routes sequential prompts through character-local operating prose instead of raw state variables, tightened receipt handling for projector-routed Qwen failures, a default no-thinking policy for strict sequential tool calls, a v10 no-thinking projector-routed capture accepted as draft, and the first materialized projector-routed sequential Ink scene with reviewed mutation training data. - next_action: Review the materialized v10 Ink branch and mutation receipt for narrative quality and state-change plausibility, then either polish the Ink text or generalize the sequential materializer for more accepted captures. + summary: Ghostlight now has the Epiphany-style persistence spine, the first architecture payload, the v0 canonical agent-state schema seam, prompt projection docs, immediate schema fixes from evaluation, first reviewed Cat/Oz projection examples, a revised Aetheria lore-grounding architecture, a lore grounding digest schema, the first draft Cold Wake historical grounding digest, a Cold Wake story-lab fixture, projection controls, validated Qwen capture receipts, a complete Cold Wake short story assembled from accepted projection outputs, a hand-authored Ink-backed Cold Wake branching scene, the first Qwen-generated Ink draft materialized from local awareness with reviewed training annotations, the first reviewed sequential branch mutation that updates both Maer and Sella after a sanctuary intake beat, a v2 sequential Qwen capture proving the symmetrical turn shape produces better action behavior, a v5 sequential Qwen capture proving local thinking-plus-tools invocation works for the scene runner, the first projected-local-context seam that routes sequential prompts through character-local operating prose instead of raw state variables, tightened receipt handling for projector-routed Qwen failures, a default no-thinking policy for strict sequential tool calls, a v10 no-thinking projector-routed capture accepted as draft, the first materialized projector-routed sequential Ink scene with reviewed mutation training data, and an explicit embodiment/interface projection surface for Navigator scenes. + next_action: Review the embodiment-aware materialized v10 Ink branch and mutation receipt for narrative quality and state-change plausibility, then either run another Qwen pass through the updated projector or generalize the sequential materializer for more accepted captures. diff --git a/tools/project_local_context.py b/tools/project_local_context.py index fb53320..14655a7 100644 --- a/tools/project_local_context.py +++ b/tools/project_local_context.py @@ -274,7 +274,7 @@ def action_affordances(agent_id: str, annotation: dict[str, Any]) -> list[dict[s if agent_id == annotation["protagonist_agent_id"]: return [ text_block( - "Can ask, offer ledger backing, show or withhold the packet, help with triage, wait, or press the moral frame. Sella controls intake.", + "Can ask, offer ledger backing, show or withhold the packet through shared clinic systems, help with triage through available displays and controls, wait, or press the moral frame. Sella controls intake.", ["examples/ink/cold-wake-sanctuary-intake.training.json.projection_controls.authority_boundaries"], ), text_block( @@ -294,6 +294,34 @@ def action_affordances(agent_id: str, annotation: dict[str, Any]) -> list[dict[s ] +def embodiment_context(agent: dict[str, Any], source_prefix: str) -> list[dict[str, Any]]: + identity = agent["identity"] + origin = identity.get("origin", "") + roles = " ".join(identity.get("roles", [])) + searchable_identity = f"{origin} {roles}".lower() + if "cetacean" in searchable_identity: + return [ + text_block( + "This character is a literal cetacean Navigator. Corridor habitats and Navigator-adjacent clinics are built around cetacean movement, access, and communication.", + [f"{source_prefix}.identity.origin"], + ), + text_block( + "Express physical action through Navigator-native channels, wet/dry workstations, shared displays, control rails, acoustic or translation systems, and other infrastructure already present in the habitat.", + [f"{source_prefix}.identity.roles", "scenes.scene-02-sanctuary-intake.location"], + ), + text_block( + "Do not describe human hands, pockets, standing, walking, leaning, doorframe blocking, or facial expressions for this character unless the fixture explicitly establishes that specific visible interface.", + [f"{source_prefix}.identity.origin"], + ), + ] + return [ + text_block( + "Use only the body, tools, interfaces, and movement affordances established by this character's fixture and the current scene.", + [f"{source_prefix}.identity"], + ) + ] + + def tension_blocks(agent: dict[str, Any], pack: dict[str, Any], annotation: dict[str, Any], source_prefix: str) -> list[dict[str, Any]]: goals = " ".join(goal["description"] for goal in agent.get("goals", []) if goal["goal_id"] in pack.get("active_goals", [])) constraints = " ".join(pack.get("presentation_constraints", [])) @@ -390,6 +418,7 @@ def render_prompt_text(context: dict[str, Any]) -> str: for title, key in [ ("Known Facts", "known_facts"), ("Current Stakes", "current_stakes"), + ("Embodiment And Interface", "embodiment_and_interface"), ("Active Inner Pressures", "active_inner_pressures"), ("Relationship Read", "relationship_read"), ("Tensions", "tensions"), @@ -443,6 +472,7 @@ def build_projected_context( "setting": f"{scene['location']}. {fixture['world']['setting']}, {fixture['world']['time']['label']}.", "known_facts": known_fact_blocks(scene, pack, scene_prefix), "current_stakes": scene_stakes(scene, local_agent_id, scene_prefix), + "embodiment_and_interface": embodiment_context(agent, source_prefix), "active_inner_pressures": active_inner_pressures, "relationship_read": relationship_context(fixture, local_agent_id, listener_ids) + perceived_overlay_context(agent, listener_ids, source_prefix), "tensions": tension_blocks(agent, pack, annotation, source_prefix), diff --git a/tools/validate_projected_contexts.py b/tools/validate_projected_contexts.py index 75f99f1..e57ce87 100644 --- a/tools/validate_projected_contexts.py +++ b/tools/validate_projected_contexts.py @@ -67,6 +67,7 @@ def validate_context(path: Path) -> None: "setting", "known_facts", "current_stakes", + "embodiment_and_interface", "active_inner_pressures", "relationship_read", "tensions", @@ -83,6 +84,7 @@ def validate_context(path: Path) -> None: for key in [ "known_facts", "current_stakes", + "embodiment_and_interface", "active_inner_pressures", "tensions", "action_affordances",