Outcome: Vani now reads counsel-authored personalisation from the
broker's top-level memory_pack.v1 and places it in the CORE instruction
prefix before matter-specific material. Counsel's text reaches the model byte-for-byte;
an absent or empty personalisation adds no marker, header, or prompt byte.
MiraConverseInput wire type.| Before | After |
|---|---|
The broker sent memory_pack beside input, but Vani only
validated the nested input, so MiraConverseInput.memory_pack was
None. |
runtime.handle_request copies the authoritative top-level pack into the
converse input at the single ingress seam. Command and map-command contracts are
unchanged. |
The local pack's text field was treated as a matter/session fold and
rendered after the frame as SESSION_MEMORY. |
text is counsel's cross-matter CORE personalisation.
session_fold remains the matter-specific fold after the frame. The two
meanings are explicit and independently tested. |
ModelRequest
instructions:
Vani static instructions
CORE PERSONALISATION — counsel-authored standing instructions.
[CORE_PERSONALISATION_BEGIN]
{counsel text exactly as stored}
[CORE_PERSONALISATION_END]
user material:
matter metadata
<<MATTER_FRAME_…>>
<<SESSION_MEMORY_…>> (only the matter/session fold)
<<CONTEXT_BUNDLE_…>>
history, tool results, counsel message
The implementation uses Pydantic AI's native per-run
Agent.iter(..., instructions=...) seam. CORE therefore precedes the user
prompt structurally; no custom message machinery is introduced. The prompt version moves
from mira.converse.v6 to mira.converse.v7.
| Requirement | Executable proof |
|---|---|
| Top-level store output reaches Vani | test_top_level_memory_pack_reaches_the_converse_input_verbatim feeds a
producer-shaped top-level pack through handle_request and inspects the
typed converse input. |
| CORE is first | test_personalisation_is_core_first_and_verbatim_in_the_model_request
captures the real Pydantic AI ModelRequest, proves CORE is in
instructions, and proves frame/fold ordering in user material. |
| Verbatim counsel text | The same model-request test uses leading/trailing spaces, a newline, an em dash, and Devanagari text, then extracts the delimited payload and asserts exact equality. |
| No personalisation changes zero bytes | test_empty_personalisation_is_byte_identical_to_no_memory_pack fixes the
nonce, compares the assembled prompts byte-for-byte, and proves both runs add no
per-run instructions. |
uv run ruff check . → All checks passed uv run pytest -q → 444 passed Focused Vani suite → 264 passed Decision-number gate → 6 passed