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
713 lines
No EOL
20 KiB
Markdown
713 lines
No EOL
20 KiB
Markdown
# MAS — Mail Address Semantics
|
|
|
|
## Status
|
|
|
|
**Phase 1 (reference experiment) passed** its decision gate on 2026-10-18
|
|
(MAS-WP-0002, `docs/experiment-review.md`). All ten success criteria were
|
|
met, including the live run through Gmail, Microsoft 365 and Postfix.
|
|
**Phase 2** is described in *Phase 2 intent* below. The phase-1 sections
|
|
are kept as the record of what was tested; where phase 2 changes them, it
|
|
says so.
|
|
|
|
## Intent (phase 1)
|
|
|
|
Build the smallest practical implementation of **Mail Address Semantics (MAS) v0.1** that can prove whether the specification is useful in real email workflows.
|
|
|
|
The project should demonstrate that ordinary email addresses can carry limited, human-readable and machine-parseable semantics for:
|
|
|
|
- opaque organizational targets,
|
|
- resource addressing,
|
|
- facets,
|
|
- optional interaction preferences,
|
|
|
|
without modifying SMTP and without turning addresses into credentials, commands, contracts, or payment instructions.
|
|
|
|
The implementation must preserve the core architectural boundary of MAS:
|
|
|
|
> **Parsing is local and deterministic. Discovery is networked. Policy is pure. Delivery remains external.**
|
|
|
|
The first implementation should be deliberately narrow. Its purpose is not to build a full MAS ecosystem, but to test the convention against real messages, real routing, resource lifecycle, malformed input, and namespace metadata.
|
|
|
|
---
|
|
|
|
## Core hypothesis
|
|
|
|
MAS is valuable if the following can be made both simple and reliable:
|
|
|
|
```text
|
|
ticket!callback@great-service.example
|
|
```
|
|
|
|
can express:
|
|
|
|
> initiate a ticket interaction with callback as the preferred continuation mode
|
|
|
|
and result in a stable resource address:
|
|
|
|
```text
|
|
ticket=GS-41872@great-service.example
|
|
```
|
|
|
|
that can subsequently be used to correlate email with that ticket without embedding application identifiers in subject lines.
|
|
|
|
If this lifecycle works cleanly through ordinary email infrastructure, MAS has demonstrated its core value.
|
|
|
|
---
|
|
|
|
## Design principles
|
|
|
|
### 1. The parser does not use the network
|
|
|
|
Parsing operates only on the address syntax.
|
|
|
|
It must:
|
|
|
|
- validate canonical MAS syntax,
|
|
- produce an explicit parse tree,
|
|
- identify which MAS profile the syntax requires,
|
|
- never perform statute discovery,
|
|
- never infer person, actor, or function kind from `.`, `-`, or `_`.
|
|
|
|
Example:
|
|
|
|
```text
|
|
ticket!callback
|
|
```
|
|
|
|
parses structurally as an interaction-bearing target and records:
|
|
|
|
```text
|
|
required_profile = P2
|
|
```
|
|
|
|
Whether the addressed namespace supports P2 is decided later.
|
|
|
|
---
|
|
|
|
### 2. Discovery returns facts or typed failure
|
|
|
|
MAS discovery is responsible only for retrieving and validating the exact-host statute.
|
|
|
|
Given:
|
|
|
|
```text
|
|
anna.mueller@acme.coulomb.social
|
|
```
|
|
|
|
discovery targets:
|
|
|
|
```text
|
|
https://acme.coulomb.social/.well-known/mas
|
|
```
|
|
|
|
It must not walk parent domains implicitly.
|
|
|
|
Discovery should return either:
|
|
|
|
```text
|
|
ValidatedStatute
|
|
```
|
|
|
|
or a typed failure such as:
|
|
|
|
```text
|
|
NotFound
|
|
HttpFailure
|
|
CrossHostRedirect
|
|
SchemaInvalid
|
|
NamespaceMismatch
|
|
InheritanceCycle
|
|
UnsupportedVersion
|
|
```
|
|
|
|
Failure to discover MAS metadata does not invalidate the email address.
|
|
|
|
---
|
|
|
|
### 3. Policy is pure
|
|
|
|
Policy evaluation takes:
|
|
|
|
```text
|
|
parse tree
|
|
+
|
|
validated statute
|
|
+
|
|
optional local registry
|
|
```
|
|
|
|
and produces semantic interpretation.
|
|
|
|
Policy performs no network access.
|
|
|
|
This allows the same policy implementation to be exercised entirely through the conformance corpus.
|
|
|
|
---
|
|
|
|
### 4. No semantic inference from naming punctuation
|
|
|
|
The following remain naming hints only:
|
|
|
|
```text
|
|
.
|
|
-
|
|
_
|
|
```
|
|
|
|
Therefore:
|
|
|
|
```text
|
|
bernd.worsch@
|
|
research-companion@
|
|
invoice_ingest@
|
|
```
|
|
|
|
may visually suggest person, actor, and function, but machine classification requires statute or registry metadata.
|
|
|
|
No statute means:
|
|
|
|
```text
|
|
kind = opaque
|
|
```
|
|
|
|
not:
|
|
|
|
```text
|
|
kind = person-like
|
|
```
|
|
|
|
---
|
|
|
|
### 5. Resource semantics are the primary proof
|
|
|
|
The initial implementation should strongly support:
|
|
|
|
```text
|
|
type=id@
|
|
```
|
|
|
|
Resource addresses must remain usable as correlation identifiers while remaining independent of authorization.
|
|
|
|
Example:
|
|
|
|
```text
|
|
ticket=GS-41872@
|
|
```
|
|
|
|
identifies the ticket communication endpoint.
|
|
|
|
It does not grant permission to inspect or mutate ticket GS-41872.
|
|
|
|
---
|
|
|
|
### 6. Resource addressability outlives mutability
|
|
|
|
Closed resources remain addressable.
|
|
|
|
A closed ticket may:
|
|
|
|
- archive later email,
|
|
- reject mutation,
|
|
- return lifecycle information,
|
|
- create a linked follow-up ticket.
|
|
|
|
It must not become mutable merely because mail can still reach its address.
|
|
|
|
---
|
|
|
|
### 7. Facets degrade safely
|
|
|
|
A facet:
|
|
|
|
```text
|
|
ticket=GS-41872+comments@
|
|
```
|
|
|
|
may be stripped by existing email infrastructure.
|
|
|
|
If so, the remaining address:
|
|
|
|
```text
|
|
ticket=GS-41872@
|
|
```
|
|
|
|
still identifies the base resource.
|
|
|
|
Facet preservation is desirable but never assumed.
|
|
|
|
---
|
|
|
|
### 8. Interaction remains a preference
|
|
|
|
The P2 syntax:
|
|
|
|
```text
|
|
ticket!callback@
|
|
```
|
|
|
|
requests that the addressed endpoint continue through `callback`.
|
|
|
|
It does not imply:
|
|
|
|
- who initiates the callback,
|
|
- that callback is available,
|
|
- that callback has been accepted,
|
|
- an SLA,
|
|
- a command.
|
|
|
|
The application decides whether and how to satisfy the request.
|
|
|
|
*(Phase 2: `!MODE` is a requested **handoff** from email to another mode.
|
|
The mode contract defines what can happen to it, including refusal. It
|
|
stays a request, never a command. See Mode reference implementation.)*
|
|
|
|
---
|
|
|
|
### 9. Economic syntax remains closed
|
|
|
|
The characters:
|
|
|
|
```text
|
|
$
|
|
^
|
|
```
|
|
|
|
remain reserved only.
|
|
|
|
No implementation work on price, reward, conditions, offers, contracts, or settlement belongs in this phase.
|
|
|
|
---
|
|
|
|
### 10. Auto-reply endpoints are gated and capped
|
|
|
|
*(Added in phase 2, from the live run.)*
|
|
|
|
An address that answers automatically, such as `ticket!callback@`, turns
|
|
any forged `From:` into outbound mail to a third party. Any endpoint that
|
|
replies automatically therefore:
|
|
|
|
- replies only when the sender is authenticated (DMARC pass, read from
|
|
trusted `Authentication-Results`);
|
|
- never replies to automated mail or to the null sender;
|
|
- caps how much it can send in total.
|
|
|
|
This is application policy, not MAS syntax. But a MAS deployment that
|
|
leaves it out reflects mail at third parties, and the reference
|
|
implementation must show how to avoid that.
|
|
|
|
---
|
|
|
|
## Initial architecture
|
|
|
|
The first repository should contain only the pieces needed for the experiment.
|
|
|
|
```text
|
|
mas/
|
|
├── mas_core/
|
|
│ ├── parser
|
|
│ ├── model
|
|
│ ├── discovery
|
|
│ ├── policy
|
|
│ └── lint
|
|
├── cli/
|
|
│ └── mas
|
|
├── conformance/
|
|
│ ├── addresses
|
|
│ ├── statutes
|
|
│ └── properties
|
|
├── examples/
|
|
│ ├── statute/
|
|
│ └── ticket_service/
|
|
├── gateway/
|
|
│ └── smtp_or_webhook_to_http/
|
|
└── docs/
|
|
```
|
|
|
|
The existing MAS v0.1 specification bundle is the normative basis.
|
|
|
|
---
|
|
|
|
## Initial components
|
|
|
|
### `mas-core`
|
|
|
|
Python reference implementation.
|
|
|
|
Responsibilities:
|
|
|
|
- parse canonical MAS syntax,
|
|
- expose structured parse objects,
|
|
- identify required profile,
|
|
- validate statutes,
|
|
- discover exact-host statutes,
|
|
- apply equivalence rules,
|
|
- evaluate semantics from parse tree plus statute,
|
|
- lint statutes.
|
|
|
|
The first implementation should be clear and auditable rather than clever.
|
|
|
|
---
|
|
|
|
### `mas-cli`
|
|
|
|
Primary human interface.
|
|
|
|
Initial commands:
|
|
|
|
```text
|
|
mas parse ADDRESS
|
|
mas explain ADDRESS
|
|
mas discover HOST
|
|
mas lint-statute FILE
|
|
mas test
|
|
```
|
|
|
|
`mas explain` should clearly distinguish:
|
|
|
|
```text
|
|
syntactic facts
|
|
discovered namespace facts
|
|
policy-derived semantics
|
|
unknowns
|
|
```
|
|
|
|
A discovery failure must remain visible.
|
|
|
|
---
|
|
|
|
### `mas-conformance`
|
|
|
|
The conformance corpus should become a first-class package rather than an incidental test directory.
|
|
|
|
It should contain:
|
|
|
|
- positive syntax cases,
|
|
- negative syntax cases,
|
|
- parser expectations,
|
|
- generator expectations,
|
|
- statute validation cases,
|
|
- discovery policy cases,
|
|
- property and boundary cases.
|
|
|
|
Every future language implementation should consume this corpus unchanged.
|
|
|
|
---
|
|
|
|
### Static statute
|
|
|
|
The first service does not need a statute server framework.
|
|
|
|
A static file served at:
|
|
|
|
```text
|
|
/.well-known/mas
|
|
```
|
|
|
|
is sufficient.
|
|
|
|
The point is to test discovery semantics, not middleware.
|
|
|
|
---
|
|
|
|
### Generic mail gateway
|
|
|
|
The first mail integration should translate inbound mail into a simple HTTP request.
|
|
|
|
It may receive mail via:
|
|
|
|
- a local SMTP listener, or
|
|
- a provider-style inbound webhook.
|
|
|
|
Its responsibility should be minimal:
|
|
|
|
```text
|
|
email recipient
|
|
→ MAS parse
|
|
→ statute/policy resolution
|
|
→ normalized HTTP event
|
|
```
|
|
|
|
It should not contain ticket-specific business logic.
|
|
|
|
---
|
|
|
|
### Reference ticket service
|
|
|
|
A deliberately small example application proving the canonical lifecycle.
|
|
|
|
Required behavior:
|
|
|
|
#### Initial interaction
|
|
|
|
Mail to:
|
|
|
|
```text
|
|
ticket!callback@great-service.example
|
|
```
|
|
|
|
creates a ticket.
|
|
|
|
The service generates:
|
|
|
|
```text
|
|
ticket=GS-41872@great-service.example
|
|
```
|
|
|
|
#### Subsequent correlation
|
|
|
|
Mail sent to:
|
|
|
|
```text
|
|
ticket=GS-41872@great-service.example
|
|
```
|
|
|
|
is associated with that ticket without depending on the subject line.
|
|
|
|
#### Closed lifecycle
|
|
|
|
After the ticket is closed, its address remains routable.
|
|
|
|
Later mail must not silently reopen or mutate the resource unless application policy explicitly allows it.
|
|
|
|
---
|
|
|
|
## Explicit non-goals (phase 1)
|
|
|
|
*Phase 2 removes the address composer and the MTA integration profile
|
|
from this list (see Phase 2 intent). The rest still applies.*
|
|
|
|
The initial implementation does not include:
|
|
|
|
- TypeScript reference library,
|
|
- Go implementation,
|
|
- Postfix policy daemon,
|
|
- central MAS registry,
|
|
- mail client plugin,
|
|
- browser extension,
|
|
- address composer,
|
|
- payment semantics,
|
|
- electronic signatures,
|
|
- generalized service marketplace,
|
|
- production identity federation,
|
|
- automatic DNS-parent inheritance.
|
|
|
|
These should be considered only after the reference experiment succeeds.
|
|
|
|
---
|
|
|
|
## Success criteria
|
|
|
|
The first experiment succeeds if:
|
|
|
|
1. the parser conforms to the shared fixture corpus;
|
|
2. parser behavior requires no network access;
|
|
3. discovery produces validated statute or typed failure;
|
|
4. policy evaluation is deterministic and offline;
|
|
5. `mas explain` never invents semantics on discovery failure;
|
|
6. the ticket lifecycle works end to end;
|
|
7. ticket identifiers no longer need to be encoded in subject lines;
|
|
8. closed resources remain addressable without becoming mutable;
|
|
9. facet loss degrades safely;
|
|
10. the experiment exposes no need to change SMTP itself.
|
|
|
|
---
|
|
|
|
## Phase 2 intent
|
|
|
|
Phase 1 showed that the convention works through ordinary infrastructure
|
|
once the MTA is configured correctly, and that resource addressing is the
|
|
strongest part of MAS. Phase 2 turns the experiment into a usable
|
|
reference. It still stays narrow.
|
|
|
|
### Role of this repository
|
|
|
|
This repository is the **spec workbench** as well as the reference
|
|
implementation. It maintains the normative bundles (`mas-v0.1-spec/` as
|
|
v0.1.1 errata, and the `mas-v0.2-spec/` draft) and records every change as
|
|
a proposal in `docs/spec-change-proposals.md`. Every spec change needs:
|
|
|
|
- evidence from a test or a live run;
|
|
- conformance fixtures in the bundle;
|
|
- an implementation in `mas_core`.
|
|
|
|
Implementation and spec move together. A version is declared final only
|
|
after a second implementation or deployment has passed its corpus
|
|
unchanged.
|
|
|
|
### Goals
|
|
|
|
1. **Adoptable integration.** A documented, tested MTA profile, so that
|
|
P2 addresses survive. Default Postfix drops them. Postfix is done; Exim
|
|
only on demand.
|
|
2. **Forwarder-safe generation.** Provider forms refuse `=` and fold case.
|
|
The generator and `mas compose` emit the canonical form and, where the
|
|
statute allows it, a forwarder-safe form. When that form would be
|
|
misread, they refuse to emit it.
|
|
3. **v0.2 to final.** Settle stand-ins, destination transforms and
|
|
`resource_id_case`. Finalize once an independent implementation
|
|
validates the corpus.
|
|
4. **Safe reference behavior.** The reference service demonstrates
|
|
principle 10.
|
|
5. **Email as a building block.** A mode reference implementation makes
|
|
MAS email a capable, reusable component of a larger multimodal
|
|
communication framework. That framework is yet to be designed and is not
|
|
built here. See below.
|
|
|
|
### Decided: interaction modes are handoffs (P2)
|
|
|
|
*Decided by the founder on 2026-10-19. This replaces the open question
|
|
from the first phase-2 draft.*
|
|
|
|
Phase 1 proved resource addressing strongly, and interaction only partly:
|
|
`!callback` states the intent, but the service still has to ask for a
|
|
number and a time. The decision gives `!MODE` defined semantics, but at
|
|
the **mode-contract** layer, not in address syntax:
|
|
|
|
- `!MODE` requests a handoff of the conversation from email to `MODE`.
|
|
The address grammar and statute fields stay as they are. `intake_for`
|
|
still links an intake target such as `ticket` to its resource type.
|
|
- What a handoff does is defined in the mode contract (below): negotiate,
|
|
run, time out, complete, fail or be refused. These are statuses reported
|
|
back to email, not side effects of parsing.
|
|
- The P2 work is narrowed accordingly. No new address mechanism is added
|
|
for modes (beyond the existing `---` stand-in) unless the contract needs
|
|
it.
|
|
|
|
## Mode reference implementation
|
|
|
|
### Purpose
|
|
|
|
Make MAS email a **capable building block** for a multimodal
|
|
communication framework, which is yet to be designed. The framework will
|
|
combine email with other modes (callback, chat, video, SMS, web forms, and
|
|
so on). This repository supplies the email part, plus enough of an
|
|
interface landscape around it that the framework can be designed against
|
|
something that runs.
|
|
|
|
### Boundary
|
|
|
|
- **Email is the only real communication channel.** The repository sends
|
|
and receives real mail. It does not place calls, run chats, send SMS or
|
|
integrate with telephony or messaging providers.
|
|
- **Other modes exist only as test stubs.** A stub speaks the mode contract
|
|
and simulates how a mode develops. It never contacts a person or an
|
|
outside service.
|
|
- **Callback first.** One fully worked stub, callback. The contract is
|
|
generic, so other modes plug in the same way. A second, trivial stub may
|
|
exist only to prove that.
|
|
- The framework itself, orchestration beyond what email-as-master needs,
|
|
and connectors to real CMS, ticketing or support products are out of
|
|
scope.
|
|
|
|
### Two roles for email
|
|
|
|
Email takes one of two roles, **configured per resource type** and fixed
|
|
for the life of a case. One deployment can do both, for example `ticket`
|
|
mastered by email and `case` slaved to an external CMS.
|
|
|
|
**Email as master.** Email is the reference for the communication. It owns
|
|
the case and its durable thread. When a handoff is requested
|
|
(`ticket!callback@`), email negotiates the missing details by email,
|
|
hands off to the mode, and records every mode status in the thread. When
|
|
the other mode times out, fails or ends, email **picks the conversation
|
|
back up**. Email owns the timeouts in this role.
|
|
|
|
**Email as slave.** Email is one element in a control flow owned
|
|
elsewhere: a CMS, a ticketing or support system, or the future framework.
|
|
The email side provides case-based communication for that master:
|
|
|
|
- **The master issues the case identifier; email adopts it.** The case is
|
|
exposed as a resource address (for example `case=EXT-123@`) under the
|
|
statute. Email maps the identifier but never invents it. Intake mail
|
|
without a case is reported to the master, which answers with the
|
|
identifier to use.
|
|
- Inbound mail becomes events for the master.
|
|
- **The master configures whether email may send on its own,** per case:
|
|
for example acknowledgements, or negotiation questions. Otherwise email
|
|
sends only when the master instructs it.
|
|
- Mode transfers are **controlled from outside**. The master may block
|
|
them, or prime them with a mode webhook that email calls when a
|
|
`!MODE` request arrives.
|
|
- **Timeouts belong to the master.** Email reports, but does not
|
|
escalate on its own.
|
|
- Principle 10 holds in both roles. A send the master requests can still
|
|
be refused (unauthenticated sender, automated mail, cap reached). The
|
|
refusal is reported back to the master.
|
|
|
|
### Callback stub
|
|
|
|
The callback stub simulates the relevant ways a callback can develop. Its
|
|
scenarios are **scripted and deterministic**: chosen by a fixture or a
|
|
test header, and reproducible in pytest and as contract fixtures.
|
|
|
|
- **Negotiation over email.** The number or time is missing, so the service
|
|
asks by email. The customer replies, and the request becomes
|
|
schedulable. This is the gap phase 1 found.
|
|
- **Outcome lifecycle.** Scheduled; attempted with no answer; retried;
|
|
completed; failed; expired. Every status reaches the email thread
|
|
(master) or the outside master (slave).
|
|
- **Refusal paths.** The mode is unavailable or not enabled, the request
|
|
is declined, or it is out of hours. Email falls back and says why.
|
|
|
|
## Current scope and reuse surface
|
|
|
|
What the larger framework can build on. Each item is versioned and tested
|
|
on its own.
|
|
|
|
| Reuse surface | What it is | Status |
|
|
|---|---|---|
|
|
| MAS address spec | `mas-v0.1-spec/` (v0.1.1), `mas-v0.2-spec/` (draft): grammar, statute schema, conformance corpora | exists |
|
|
| `mas_core` | parse (no I/O), discover (exact host), resolve (pure), generate / `for_destination` | exists |
|
|
| Gateway event | `mas-gateway` pipe/webhook → normalized JSON event with parse, semantics and trusted sender authentication | exists; to be versioned with a schema |
|
|
| Postfix profile | `integrations/postfix/`: receiving setup that keeps MAS syntax intact | exists |
|
|
| **Mode contract** | Language-neutral, versioned, separate from the address spec. It defines handoff requests, mode statuses, timeouts, roles (master/slave), outside-master commands (send, block, prime webhook, assign case id) and refusals. Comes with JSON schemas and conformance fixtures | new |
|
|
| **Email mode reference** | Email side of the contract in both roles, built from the gateway and the reference ticket service | new |
|
|
| **Stub mode server** | Scriptable stub that speaks the contract, callback first | new |
|
|
| **Stub outside master** | Minimal fake CMS/ticketing master that drives email in slave mode end to end | new |
|
|
|
|
The reference ticket service and the stubs are **examples and test
|
|
fixtures, not products**. The contract and schemas, `mas_core` and the
|
|
address spec are the parts meant to be reused unchanged.
|
|
|
|
## Not in phase 2
|
|
|
|
Other language implementations (except one used to validate v0.2), a
|
|
policy daemon, a central registry, mail-client plugins, signed statutes,
|
|
implicit parent inheritance, and economic semantics. A web composer is out
|
|
until something asks for one. Real non-email modes, telephony or messaging
|
|
integrations, connectors to real CMS or ticketing products, and the
|
|
multimodal framework itself are out too.
|
|
|
|
## Phase 2 is done when
|
|
|
|
1. a fresh Postfix install, using only `integrations/postfix/`, delivers
|
|
the full corpus unchanged and refuses relaying;
|
|
2. `mas compose` produces correct forms for every destination observed so
|
|
far, and refuses the rest;
|
|
3. v0.2 is declared final, or is withdrawn with recorded reasons;
|
|
4. the handoff reading of P2 is recorded in the v0.2 spec text, and the
|
|
address spec points to the mode contract;
|
|
5. the live test environment is retired, with its evidence archived;
|
|
6. mode contract v0.1 is published with JSON schemas and fixtures;
|
|
7. the email mode reference passes them in both roles: as master against
|
|
the callback stub, and as slave under the stub outside master;
|
|
8. every callback scenario (negotiation, outcome lifecycle, refusals) runs
|
|
deterministically in the test suite.
|
|
|
|
---
|
|
|
|
## Longer-term direction
|
|
|
|
If the experiment validates the concept, MAS may later grow into:
|
|
|
|
- additional language libraries,
|
|
- infrastructure gateways,
|
|
- mail client affordances,
|
|
- signed semantic metadata,
|
|
- richer interaction discovery,
|
|
- economic profiles,
|
|
- service-market coordination.
|
|
|
|
Those extensions should remain subordinate to the core principle:
|
|
|
|
> **MAS should add useful semantics to email without making ordinary email depend on MAS.** |