MAS-WP-0003-T04: IONOS forward results (rejects '=', lower-cases; SRS safe); SCP-6/7

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 252470@bnt-lap001
Assistant-Session: ad628c8f-4be2-4979-94c9-76c7ed6f8241
This commit is contained in:
tegwick 2026-10-18 13:53:13 +02:00
parent 401dc69522
commit 2d8ebf4fa7
3 changed files with 108 additions and 8 deletions

View file

@ -149,8 +149,30 @@ four sender setups:
- **Outbound port 25 was blocked** at the hosting provider (and on a
second host). Replies need an authenticated submission relay.
**Still untested (T04):** overlap with SRS (`SRS0=...`) and VERP when
forwarding, and facet stripping by forwarders and lists.
**Forwarding (T04, IONOS mail forward, 2026-10-18):** this is the first
real failure in the run.
- **The IONOS forwarding form refuses `=`** in the destination address.
`+` is accepted. A resource address cannot be configured as a forward
target at all.
- **The form also forces lower case.** It only accepts lower-case
destinations and "corrects" input. The operator entered
`ticket--GS-85QJ8WC09P+comments@` (with `--` standing in for `=`), and
`ticket--gs-85qj8wc09p+comments@` arrived. Under the spec's default
exact comparison, a lower-cased identifier no longer matches its
resource, even if the `=` had been allowed.
- **SRS does not collide with `=`.** IONOS rewrote the *envelope sender*
to `SRS0=ppc5=II=gmail.com=bernd.worsch@srs2.kundenserver.de`. SRS never
touches the recipient, so `=` in recipients is safe from it.
- The facet `+comments` survived forwarding.
- The header `To:` showed the forwarding address (`mas-fwd@coulomb.social`),
so MAS receivers must classify the **envelope recipient**, as
`mas-gateway` does.
- Result: the gateway classified the mail as an opaque target with a facet.
The ticket service correctly declined it (404, not handled), because
nothing in the statute gives `ticket--…` resource meaning. See SCP-6
(declared alternate separator) and SCP-7 (identifier case).
**Still untested (T04):** a mailing list (VERP).
### Resource addressing: did it improve correlation?
Yes. The service replies *from* `ticket=GS-…@great-service.example`, so an
@ -205,8 +227,8 @@ This is a recommendation; the decision is the founder's.
| Candidate | Demonstrated need? | Recommendation |
|---|---|---|
| Postfix/Exim integration | **Yes.** Default Postfix drops every P2 address, and the correct relay config is non-obvious | Build first: a documented, tested Postfix profile (later Exim) based on `deploy/railiance/entrypoint.sh` |
| Spec v0.1.1 errata | **Yes**, SCP-1 to SCP-5 | Do alongside the integration |
| Address composer | Weak. Providers accepted hand-typed addresses; the 64-octet budget and facet/interaction exclusivity are the only traps | Defer; `mas generate` in the CLI covers it |
| Spec v0.1.1 errata | **Yes**, SCP-1 to SCP-7 (SCP-6 is an additive feature and could go to v0.2) | Do alongside the integration |
| Address composer | Partly. Mail clients accepted hand-typed addresses, but the IONOS forwarding form refused `=` and lower-cased input | Defer the tool; first settle SCP-6/SCP-7, then `mas generate` emits the forwarder-safe form |
| Mail-client inspector | Not shown; nothing was rewritten that a user would need to see | Defer |
| TypeScript / Go implementations | Not shown; no consumer outside Python yet | Defer until a second consumer exists |
| Signed statutes | Not shown; pinned local statutes covered the operator case (see Discovery) | Defer |

View file

@ -6,8 +6,9 @@ because `mas_conformance/` and `mas_core/schema/` are vendored copies and
the tests check them for drift. Evidence references point to
`docs/experiment-review.md`.
Proposed target: a v0.1.1 errata release for SCP-1 to SCP-3 and SCP-5,
which clarify or tighten without changing what canonical addresses mean.
Proposed target: a v0.1.1 errata release for SCP-1 to SCP-3, SCP-5 and the
recommendation part of SCP-7, with SCP-6 targeted at v0.2. Errata here are changes that clarify or
tighten without changing what canonical addresses mean.
SCP-4 is informative only.
---
@ -98,8 +99,12 @@ an `=` From address. Postfix 3.7 never applied the legacy `!`/`%` rewrites
to MAS addresses carrying an `@domain`. Pending: SRS and VERP (MAS-WP-0003
T04).
**Counter-evidence (T04):** the IONOS forwarding form refused `=` and
forced lower case (SCP-6, SCP-7). Mail *clients* preserved MAS syntax;
provider *configuration forms* did not.
**Proposal:** keep the normative text. Add an informative note recording
the tested paths, and an implementation note that a default Postfix relay
the tested paths, including the IONOS refusal, and an implementation note that a default Postfix relay
configuration rejects every local-part containing `!` (see SCP-5 and the
review's operational findings). The "cooperating environments" wording for
`!` stays until T04 has covered forwarding.
@ -133,6 +138,65 @@ event-schema addition.
---
## SCP-6: statute-declared alternate resource separator (`--` for `=`)
**Sections:** §6 Resource semantics, §11 Statute document, §12.
**Evidence:** the IONOS forwarding form refuses `=` in a destination
address. The operator compensated with `ticket--GS-…`, and it was
delivered, but under v0.1 it is only an opaque target. The service
correctly could not attach it to the ticket.
**Proposal:** a statute MAY declare an alternate separator for resource
targets, for example:
```json
"resource_syntax": { "alternate_separator": "--" }
```
When it is declared, a target `TYPE--ID`, where `TYPE` is a declared
resource type, is equivalent to `TYPE=ID` in that namespace. The policy
resolver reports `target_syntax: "resource-alternate"` and the canonical
equivalence key `TYPE=ID`. Without the declaration, `--` has no meaning
(§6.1 still applies). Generators SHOULD offer the alternate form when the
statute declares one and the destination is known to reject `=`.
**Open points:** the first `--` after a declared type is the split point,
so IDs may still contain `--`. The separator must be a dot-atom-safe string
and may not contain `.`. A namespace whose existing opaque names start with
`TYPE--` must not declare it.
**Impact:** additive, optional schema field, policy change, new fixtures.
A candidate for v0.2 rather than errata.
---
## SCP-7: resource identifiers must survive lower-casing
**Sections:** §6.2 Resource identifiers, §8 Address equivalence, §13.
**Evidence:** the IONOS forwarding form forces destination addresses to
lower case: `GS-85QJ8WC09P` became `gs-85qj8wc09p`. With the spec default
(exact comparison) and a statute declaring `case: exact`, the identifier
no longer matches. Many systems treat local-parts as case-insensitive in
practice, despite RFC 5321.
**Proposal:**
- §6.2: "Generators SHOULD use resource identifiers whose meaning does not
depend on letter case (for example lower-case only, or a case-insensitive
alphabet such as Crockford base32), because forwarders and web forms may
change the case of local-parts."
- Statute: allow `equivalence.resource_id_case: "insensitive"` independently
of the local-part `case` setting. Receivers then fold the identifier for
lookup but must not fold anything else.
- Together with SCP-2, the resource type is already lower-case.
**Impact:** recommendation plus an optional statute field. The reference
service could switch to lower-case IDs today. Crockford base32 decoding is
case-insensitive by design.
---
## Lower-priority gaps (no proposal yet)
Recorded in the review, not urgent:

View file

@ -167,7 +167,7 @@ address and what envelope recipient arrives.
```task
id: MAS-WP-0003-T04
status: todo
status: progress
priority: medium
state_hub_task_id: "97c88b4f-14c3-5f6c-8f31-6b9fc3afd236"
```
@ -176,6 +176,20 @@ Send via one forwarding service (SRS) and one mailing list (VERP). Check
whether `=` collides with SRS0/VERP encoding, and whether facets survive
or are stripped.
- 2026-10-18, IONOS mail forward (`mas-fwd@coulomb.social`): the IONOS form
refuses `=` in the destination and forces lower case. The operator used
`ticket--GS-85QJ8WC09P+comments@`, and `ticket--gs-85qj8wc09p+comments@`
arrived at 11:47:06Z from mout.kundenserver.de. The envelope sender was
SRS-rewritten (`SRS0=ppc5=II=gmail.com=bernd.worsch@srs2.kundenserver.de`).
SRS only touches the sender, so there is no collision with `=` in
recipients. The facet survived, and the header To kept the forward
address. The gateway saw an opaque target with a facet, and the app
correctly declined it (404). This led to SCP-6 (statute-declared `--`
separator; the operator endorses the mapping) and SCP-7 (case-robust
identifiers).
Gmail forwarding: skipped (optional; would only add a second forwarder
that accepts `=`). Still open: one mailing list (VERP).
## Cap total outbound mail
```task