Story 1361: Sync the Broker to the Flat Atlas Proposal Contract
Atlas (the brain, pramaan-agents Story-1359) changed the shape of the matter-frame proposal it emits โ from nested to flat. The broker (this repo) and the brain share one golden fixture that must be byte-identical in both repos. When only the brain flips, the broker's copy is a lie: it documents a wire that no longer exists. This Story re-syncs the broker copy and pins the new shape so the lie cannot recur silently.
Why this matters (the catastrophe avoided)
The golden-parity fixture is the cross-repo handshake (pramaan-docs ADR-110 ยง12 amendment 1): if the brain emits one shape and the broker tests another, the contract is broken and nobody notices until a real Atlas run reaches a confused consumer. A stale fixture is worse than no fixture โ it actively asserts a false contract is healthy. This Story makes the two copies agree again and adds an assertion so a future drift back to the old nested shape fails CI instead of passing through.
๐ฐ๏ธ Satellite: where the proposal lives on the rail
Atlas (brain) Broker (this repo) App
pramaan-agents pramaan-functions
โโโโโโโโโโโโโ โโโโโโโโโโโโโโโโโโ โโโ
emits turn.completed โ parse_event_line() โ run.proposal
with flat proposal assigns seq, stamps (flat shape,
run/firm truth on DB row, intact)
FORWARDS turn untouched
The proposal is born in Atlas and consumed by the app. The broker sits in the middle as the contract-enforcement point โ but only for the envelope, not the proposal body.
โ๏ธ Airplane: what the broker actually does to the proposal โ nothing
The first question the ticket asked: does the broker re-validate the proposal shape, or just forward it? The answer is in src/shared/agent_contracts/events.py:
| Payload field | Type | Meaning |
|---|---|---|
TurnCompletedPayload.turn | dict[str, Any] | Opaque agent-typed turn (proposal lives inside). |
TurnDeltaPayload.partial | dict[str, Any] | Opaque ephemeral partial turn. |
Both are opaque dictionaries. There is no MatterFrameProposal model in the broker โ a repo-wide search finds zero definitions. The broker assigns seq, stamps run/firm truth on the DB row, and forwards the turn โ proposal and all โ to the app verbatim. So acceptance criterion 1 resolves to: no schema change; document that the broker forwards and never re-validates. That documentation now lives in the test module docstring.
๐ฌ Microscopic: the one line that changed in the fixture
The entire desync was the turn.completed proposal on line 4 of tests/unit/agent_contracts/fixtures/agent_event_stream_golden.jsonl.
| Old (nested โ stale) | New (flat โ Atlas Story-1359) |
|---|---|
"refined": {"core_dispute": "Breach of the SPA."} โ and no relief/proceeding/value fields |
"core_dispute", "proceeding_type", "prayers": [...], "value_amount_minor", "value_currency" โ all inline, no refined wrapper, no relief, no value.basis |
The new fixture copy was taken byte-identical from the brain's committed source of truth (pramaan-agents agents/atlas/tests/fixtures/agent_event_stream_golden.jsonl), so the two repos agree exactly โ a diff on either side now fails CI on the side that drifted.
The new pin: drift can no longer pass silently
Because turn is dict[str, Any], the existing parse test accepted any proposal shape โ which is precisely how the desync slipped in unnoticed. A new test, test_turn_completed_proposal_is_flat_atlas_shape, reaches into the forwarded turn and asserts:
proposal["core_dispute"] == "Breach of the SPA."
proposal["proceeding_type"] == "SIAC arbitration"
proposal["prayers"] == ["Damages of SGD 12.5M"]
proposal["value_amount_minor"] == 1250000000
proposal["value_currency"] == "SGD"
"refined" not in proposal # dropped nested coercions
"relief" not in proposal # never reappear (pre-revenue, no back-compat)
This proves acceptance criterion 3 โ the proposal survives the opaque-dict passthrough with its flat fields intact โ and converts a silent-drift hole into a loud test failure.
Scope discipline
No route, DTO, or router signature changed, so make openapi snapshots are untouched. The proposal contract is owned by Atlas, not the broker; this Story changes only the broker's fixture copy and its parity test. Pre-revenue: the old nested shape was deleted outright with no back-compat path.