conformance/FLOWS.md defines setup, steps, captures and expectations, all observable at the contract boundary. flows.json carries setups (peer ids), fixed test keys, statute, scenario and explicit assign steps; scenarios.json holds the callback scenarios (the stub loads them). CONTRACT.md defines the case.assign response. Runner reads only the bundle and rejects undefined keys; new flow s-006 (held over cap). Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Assistant: claude-code Assistant-Model: opus Assistant-Process: 5787@bnt-lap001 Assistant-Session: 5db26b82-138b-40cc-9856-4d5eb0f752fd
81 lines
3.1 KiB
Markdown
81 lines
3.1 KiB
Markdown
---
|
|
id: MAS-WP-0013
|
|
type: workplan
|
|
title: "Mode contract flows independent of the Python harness"
|
|
domain: communication
|
|
repo: mail-address-semantics
|
|
status: finished
|
|
owner: claude
|
|
topic_slug: coulomb-social
|
|
created: "2026-10-19"
|
|
updated: "2026-10-19"
|
|
origin: residual
|
|
origin_ref: MAS-WP-0010
|
|
state_hub_workstream_id: "6d1d30c3-4373-59db-a6f6-d8a8ceb5fad9"
|
|
---
|
|
|
|
# Mode contract flows independent of the Python harness
|
|
|
|
Risk A in `history/2026-10-19T090725Z-scope-vs-intent.md`.
|
|
`mas-modes-v0.1-spec/conformance/flows.json` is language-neutral in
|
|
format, but it relies on harness details: the stub master assigns
|
|
`EXT-100`, `EXT-101`, ...; the role configuration is implied; and
|
|
expectation keys mirror `mas_modes.runner`. A second implementation could
|
|
not run the flows from the bundle alone.
|
|
|
|
## Make flows self-describing
|
|
|
|
```task
|
|
id: MAS-WP-0013-T01
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "95fe186c-d0af-5755-a78f-065e7da7afd1"
|
|
```
|
|
|
|
Write the inputs into each flow: role configuration, assigned ids, and
|
|
the stub scenarios. Define every expectation key in CONTRACT.md §7 or a
|
|
`conformance/FLOWS.md`, in terms of contract messages and sent mail only.
|
|
Remove any expectation that only the Python harness can observe.
|
|
|
|
## Runner follows the bundle
|
|
|
|
```task
|
|
id: MAS-WP-0013-T02
|
|
status: done
|
|
priority: medium
|
|
state_hub_task_id: "2e71569f-739a-513a-970f-0a0c867604d6"
|
|
```
|
|
|
|
Update `mas_modes.runner` and the stubs to read everything from the flow.
|
|
Keep `mas test` green. Add a fixture-level check that the bundle's flows
|
|
do not use undefined keys.
|
|
|
|
## Outcome
|
|
|
|
- **`conformance/FLOWS.md`** defines the format: how to set up a run (email
|
|
side, callback stub `callback-1`, master stub `cms-1`, controllable
|
|
clock, optional send cap), the five step types, captures and the 14
|
|
expectation keys. All of it is observable at the contract boundary:
|
|
messages the stubs receive, command responses, and sent mail.
|
|
- **`flows.json`** carries everything a run needs:
|
|
- `setups` with role configs by peer id (no URLs; `<mode:ID>` for a
|
|
primed webhook);
|
|
- fixed public test keys in `peers`, plus `statute`;
|
|
- per flow, a `scenario` and an optional `max_sent`;
|
|
- explicit `assign` steps with `EXT-100` instead of the stub's
|
|
auto-numbering.
|
|
- **Removed harness-only observables:** the ticket service's response
|
|
strings (now `event_accepted`, the 2xx) and `tick()`'s return value (now
|
|
`mode_received`, `mode_received_last` and `mails_sent`).
|
|
- **`conformance/scenarios.json`:** the callback scenarios as data. The
|
|
Python stub loads them from there.
|
|
- **CONTRACT.md §5** now defines the `case.assign` response, which flows
|
|
capture from.
|
|
- **New flow** `s-006` (a held send over the cap): 21 flows in all.
|
|
- **Runner** (`mas_modes.runner`) reads only the bundle and rejects
|
|
undefined keys. `tests/test_modes_conformance.py` checks that every flow
|
|
uses defined keys, existing setups and scenarios, and that every key is
|
|
documented in FLOWS.md. The drift test now also covers the vendored
|
|
FLOWS.md.
|
|
- **Checks.** A mutation check over 5 expectations, plus an undefined key,
|
|
was detected every time. `mas test`: mode corpus 195/195.
|