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
24 lines
1.9 KiB
Markdown
24 lines
1.9 KiB
Markdown
# 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).
|