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
| Gate | What 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 privilege | ER-26 rejects an unmarked or withheld internal answer and rejects marked or unmarked privileged cargo in export output. |
conv-indirect-privileged-document-injection | A 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.