impl/js/src/email.mjs (written from CONTRACT.md + FLOWS.md): both roles, case store, handoffs, timeouts, one-cap outbox with holding, authorization. Passes all 22 flows from the bundle; with the JS master all 12 slave flows (no Python contract party). Writing it found six contract gaps, folded into the draft as MCP-1..6 (acknowledgement, details convention, resume names the outcome, opaque case key, error table, transfer reporting); flows now check outcome tokens, not reference prose. A mutation check found a missing flow: a-008 (per-type master check). 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
1.9 KiB
1.9 KiB
Mode contract proposals (MCP)
Changes to mas-modes-v0.1-spec/CONTRACT.md while v0.1 is a draft. Each
one comes from evidence, like the address spec's SCP series.
MCP-1 to MCP-6: found while writing the second email side (MAS-WP-0014)
Evidence: to write an email side from CONTRACT.md and FLOWS.md alone, everything the flows check has to be in the text. Reading it that way showed six places where the flows relied on the Python reference's behavior, not on the contract.
| Gap | Change (folded into the v0.1 draft) | |
|---|---|---|
| MCP-1 | The flows expect a mail when the master role creates a case (mails_sent: 1), but §3.1 did not say email acknowledges |
§3.1.1: email acknowledges a new case from its address. A mode-not-enabled refusal at creation goes into that mail, with no separate resume |
| MCP-2 | Asking for details and reading the answers relied on an unwritten Field: value convention |
§3.1.4 defines details: lines, case-insensitive field names, first occurrence wins, and the question format Field: ... |
| MCP-3 | The flows checked the reference's English wording ("has taken place", "could not arrange") | §3.1.3: the resume mail MUST name the terminal status and the reason or detail. The flows now check those tokens |
| MCP-4 | case.key was "the equivalence key (§8)", but address spec v0.2 §8 makes the key format non-normative |
§1: email chooses the key, equivalent addresses share it, and other parties treat it as opaque |
| MCP-5 | Errors such as unknown-handoff and case-exists were used but not defined |
§5.1: an error table |
| MCP-6 | §3.2.4 said a blocked transfer produces only handoff.requested, but the reference also relays refused (blocked) (flow s-003) |
§3.2.4 states both messages, which statuses are relayed, and the seq |
Impact: text and flow expectations only. The Python reference already behaved this way, except that its resume mail now also names the status (MCP-3).