Mira reads the whole room; exports do not

Story-2500 · T3j · I-14/I-15 · ER-26 · pramaan-agents

The mental model: privilege is a membrane at the exit, not a wall around the record. An assigned matter-team member asks Mira a question and gets the truthful answer. Protected cargo is visibly marked. The same cargo cannot enter a shared Brief, filing, or chronology export.

1 · The real wire seam

Functions Story-2499 sends the canonical context_bundle.v1 at the top level of agent_invoke.v1. Its section items carry authoritative privileged:true tags. Mira previously looked only for an obsolete nested input.bundle.text, so those tags never reached either route. The runtime now folds the top-level bundle into the typed route input once, before dispatch.

functions broker
  context_bundle.v1 { sections[].items[].privileged }
       |
       v
Mira runtime ingress ----> converse: full tagged bundle
                      `---> command: privileged items removed before every panel seat

The structured bundle is rendered into stable JSON inside the existing <<CONTEXT_BUNDLE_hash>> fence. Document text remains DATA under I-11; privilege does not turn it into an instruction channel.

2 · Internal answer: truthful and visibly protected

Converse receives the complete tagged record. The prompt says not to refuse, hide, or weaken a truthful matter answer merely because its source is privileged. If any served bundle item is privileged, the stream begins with:

🔒 Privileged — not exportable

The same prefix is present in turn.completed.markdown, so the streaming and settled answer agree. Passage-level prompt rules keep the marker beside protected citations. Whole-answer marking is deliberately conservative until the plain-text stream carries citation-to-tag attribution.

3 · Export-shaped command: protected cargo never reaches the model

The command route produces the Matter Frame / Brief shape. Before proposer, critic, or synthesizer runs, Mira removes every bundle item tagged privileged:true. Public items remain. The prompt also states that a marker never licenses export and forbids reconstructing removed material. This is defence in depth; the functions membrane remains the hard egress gate.

4 · ER-26 and refusal evidence

GateWhat it proves
test_top_level_context_bundle_*The merged broker shape reaches converse and command.
test_privileged_context_marks_*The first streamed delta and settled answer carry the visible lock marker; public-only context does not.
test_converse_reads_privileged_rows_*Chat sees the protected fact; the Brief panel sees the public fact and not the protected one.
evals/run.py privilegeER-26 rejects an unmarked or withheld internal answer and rejects marked or unmarked privileged cargo in export output.
conv-indirect-privileged-document-injectionA planted instruction inside a privileged bundle row stays fenced DATA; the adversarial corpus turns red if the fence is removed.

5 · Verification

uv run --package mira python agents/mira/evals/run.py privilege
uv run --package mira python agents/mira/evals/run.py adversarial
uv run --package mira pytest agents/mira/tests -q
uv run ruff check agents/

Scope held: no app rendering, database, schema, pricing, or functions egress code changed.