diff --git a/docs/architecture/canonical-agent-state-schema.md b/docs/architecture/canonical-agent-state-schema.md index 2d00912..06fa68c 100644 --- a/docs/architecture/canonical-agent-state-schema.md +++ b/docs/architecture/canonical-agent-state-schema.md @@ -187,10 +187,12 @@ A pack is a character-local prompt payload for one speaker. It includes: - active memories - active goals - presentation constraints -- forbidden context The point is not to make the dialogue generator smarter by shouting plot at it. The point is to keep each character inside their own partial reality. +Packs are positive-context payloads: if the speaker should not know something, +it is not included. Secrets the speaker does know but wants to withhold belong +in goals, memories, beliefs, and presentation constraints. Ghostlight can build the trap. The character projection decides how the person inside the trap breathes. @@ -212,7 +214,8 @@ currently cares about: - state variable components stay in `0..1` - goals, memories, relationships, scenes, and dialogue context packs reference existing IDs -- dialogue packs do not leak obvious forbidden context into speaker-local truth +- dialogue packs carry speaker-local context without requiring negative + author-only fences This gives us a real seam before we build the prompt renderer. Not perfect. Useful. We are allowed to be both. diff --git a/examples/agent-state.call-of-the-void.json b/examples/agent-state.call-of-the-void.json index f79f6ec..02d9ab8 100644 --- a/examples/agent-state.call-of-the-void.json +++ b/examples/agent-state.call-of-the-void.json @@ -1099,10 +1099,6 @@ "Use dry, pointed sarcasm to evade sincerity or emotional exposure.", "Let the abrasive-boundary performance function as a boundary, not random cruelty.", "Probe without making it look like an interrogation." - ], - "forbidden_context": [ - "Do not reveal Oz's true controller unless Cat has earned it in-scene.", - "Do not mention author-only future plot beats." ] }, { @@ -1128,11 +1124,8 @@ "presentation_constraints": [ "Be helpful, a little funny, and evasive.", "Let the drone seem more autonomous than it is.", - "Use warmth carefully; Cat may treat open sincerity as bait." - ], - "forbidden_context": [ - "Do not confess the operator's location.", - "Do not use information Oz could not know from the scene or prior relationship." + "Use warmth carefully; Cat may treat open sincerity as bait.", + "Keep the operator location private unless scene pressure explicitly breaks the mask." ] } ] diff --git a/schemas/agent-state.schema.json b/schemas/agent-state.schema.json index efec087..e669ff4 100644 --- a/schemas/agent-state.schema.json +++ b/schemas/agent-state.schema.json @@ -569,8 +569,7 @@ "speaker_beliefs", "active_memories", "active_goals", - "presentation_constraints", - "forbidden_context" + "presentation_constraints" ], "additionalProperties": false, "properties": { @@ -612,12 +611,6 @@ "items": { "type": "string" } - }, - "forbidden_context": { - "type": "array", - "items": { - "type": "string" - } } } }, diff --git a/state/evidence.jsonl b/state/evidence.jsonl index e050e9c..2d1a875 100644 --- a/state/evidence.jsonl +++ b/state/evidence.jsonl @@ -15,3 +15,4 @@ {"ts": "2026-05-01T18:49:11+00:00", "type": "design", "status": "accepted", "note": "Separated verbal_response_strategy from voice_style. Sarcastic deflection, sincerity evasion, emotional evasion, banter-as-boundary, and verbal aggression are pressure-activated speech defenses, not baseline voice texture."} {"ts": "2026-05-01T18:54:49+00:00", "type": "design", "status": "accepted", "note": "Removed verbal_response_strategy as a canonical layer. Defensive verbal moves should emerge during projection from interactions among underlying organization, dispositions, behavioral dimensions, presentation strategy, situational pressure, relationship context, and voice style."} {"ts": "2026-05-01T18:55:15+00:00", "type": "design", "status": "accepted", "note": "Kept sarcastic deflection, sincerity evasion, emotional evasion, banter-as-boundary, and verbal aggression as target emergent behaviors for projection tests rather than canonical state fields."} +{"ts": "2026-05-01T19:09:58+00:00", "type": "design", "status": "accepted", "note": "Removed forbidden_context from dialogue context packs. Packs are positive speaker-local payloads; unknown or author-only material is omitted by the projection builder, while known secrets are expressed through goals, beliefs, memories, and presentation constraints."} diff --git a/state/map.yaml b/state/map.yaml index c34115e..b1beed5 100644 --- a/state/map.yaml +++ b/state/map.yaml @@ -79,6 +79,7 @@ accepted_design: - Voice style is a broad required communication vector covering lyrical speech, formality, verbosity, hedging, coded politeness, theatricality, dialect, register switching, technical compression, ritualized address, and related language mechanics. - Defensive verbal responses are derived during projection from underlying organization, dispositions, behavioral dimensions, presentation strategy, situational pressure, relationship context, and voice style rather than stored as a separate canonical layer. - Sarcastic deflection, sincerity evasion, emotional evasion, banter-as-boundary, and verbal aggression are target emergent behaviors for projection tests. + - Dialogue context packs are positive-context payloads; unknown or author-only material is omitted rather than listed as forbidden context, while known secrets are handled through goals, memories, beliefs, and presentation constraints. current_status: summary: Ghostlight now has the Epiphany-style persistence spine, the first architecture payload, and the initial canonical agent-state schema seam for Call of the Void-style authoring examples. The schema is still v0 and should be hardened before building prompt projection on top of it. diff --git a/tools/validate_agent_state.py b/tools/validate_agent_state.py index b2b2288..2d32c80 100644 --- a/tools/validate_agent_state.py +++ b/tools/validate_agent_state.py @@ -197,7 +197,6 @@ def validate_document(document: dict[str, Any], required: dict[str, list[str]], "active_memories", "active_goals", "presentation_constraints", - "forbidden_context", ], pack_path, ) @@ -208,11 +207,6 @@ def validate_document(document: dict[str, Any], required: dict[str, list[str]], require(goal_id in goal_ids, f"{pack_path}.active_goals references unknown goal: {goal_id}") for memory_id in pack["active_memories"]: require(memory_id in memory_ids, f"{pack_path}.active_memories references unknown memory: {memory_id}") - forbidden_blob = "\n".join(pack["forbidden_context"]).lower() - local_blob = "\n".join(pack["speaker_local_truth"] + pack["speaker_beliefs"]).lower() - for forbidden in ["author-only", "future plot"]: - if forbidden in forbidden_blob: - require(forbidden not in local_blob, f"{pack_path} leaks forbidden context into local state: {forbidden}") def main() -> int: