mail-address-semantics/workplans/MAS-WP-0002-reference-experiment.md
tegwick 52140cee9b Register with State Hub; add MAS v0.1 spec bundle, intent and reference-experiment workplan
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

Assistant: claude-code
Assistant-Model: opus
Assistant-Process: 623586@bnt-lap001
Assistant-Session: 10b30928-5b3b-4c11-9934-5ecca07367d8
2026-10-08 00:14:14 +02:00

12 KiB

id type title domain repo status owner topic_slug created updated
MAS-WP-0002 workplan MAS v0.1 reference experiment communication mail-address-semantics ready claude coulomb-social 2026-10-08 2026-10-08

MAS v0.1 reference experiment

Objective

Build one runnable reference experiment for MAS v0.1.

The experiment should validate the full path:

address
→ parse
→ discovery
→ policy
→ mail gateway
→ ticket resource
→ subsequent resource-addressed mail

The plan deliberately avoids parallel language implementations and infrastructure-specific integrations until the model has survived one complete implementation.


Milestone 0 — Establish the implementation baseline

id: MAS-WP-0002-T01
status: todo
priority: high

Goal

Turn the specification bundle into executable project inputs.

Work

Import or vendor:

SPECIFICATION.md
grammar/mas-v0.1.abnf
schema/mas-statute-v0.1.schema.json
conformance/addresses.json

Establish the repository structure.

Define Python package boundaries:

mas_core.model
mas_core.parser
mas_core.discovery
mas_core.policy
mas_core.statute
mas_core.lint

Define an explicit version:

MAS 0.1
implementation 0.1.0-dev

Deliverable

A repository where:

pytest

runs the existing fixture corpus.


Milestone 1 — Core parser and model

id: MAS-WP-0002-T02
status: todo
priority: high

Goal

Implement the specification without network or namespace policy.

Core model

Define immutable objects such as:

MasAddress
Target
OpaqueTarget
ResourceTarget
Facet
Interaction
RequiredProfile

Example:

ticket=PR42+comments!callback

should parse to approximately:

MasAddress
  target:
    ResourceTarget
      type = ticket
      id = PR42
  facet = comments
  interaction = callback
  required_profile = P2

Critically:

ticket!callback

must parse successfully in the maximal parser and report:

required_profile = P2

The parser must not require knowledge of whether a particular namespace enables P2.

Parser APIs

Recommended:

parse_local_part(value) -> ParsedLocalPart
parse_address(value) -> ParsedAddress
validate_profile(parsed, profile) -> ValidationResult

Avoid coupling syntax parsing to statute policy.

Property cases to add

Extend beyond the existing fixtures.

Length boundaries

Test:

63 octets
64 octets
65 octets

The transport limit applies after encoding.

Additional =

Validate:

ticket==PR42

as:

resource_type = ticket
resource_id = =PR42

because only the first = is structural.

Reserved operators

Ensure:

$
^

always fail canonical v0.1 parsing.

Registry independence

Ensure a registry key such as:

support

is legal while:

support+foo

is not interpreted as a registry key lookup for the full faceted address.

Registry lookup should operate on the base target.

Exit criteria

  • all existing fixtures pass;
  • new property cases pass;
  • parser performs zero I/O;
  • parser does not infer person/actor/function kind.

Milestone 2 — Statute model and linting

id: MAS-WP-0002-T03
status: todo
priority: high

Goal

Make namespace semantics explicit and verifiable.

Work

Implement statute loading and JSON Schema validation.

Add semantic validation beyond the schema.

Checks should include:

Namespace consistency

A statute fetched for:

acme.coulomb.social

must declare:

namespace = acme.coulomb.social

or fail with:

NamespaceMismatch

P2 consistency

Reject or lint:

profiles.p2 = false

together with enabled interaction modes.

Resource type validity

Resource type names must themselves satisfy MAS resource-type syntax.

Registry key validity

Explicit address registry keys must refer to base opaque targets only.

For v0.1, registry keys should not contain:

+
!
$
^

Inheritance cycles

Detect:

A → B → A

and longer cycles.

Child precedence

Where inheritance is supported:

child overrides inherited defaults

Explicit address registry entries must not inherit.

CLI

Implement:

mas lint-statute FILE

Output should distinguish:

schema error
semantic error
warning

Exit criteria

A malformed but schema-valid statute can still be rejected by semantic linting.


Milestone 3 — Exact-host discovery

id: MAS-WP-0002-T04
status: todo
priority: high

Goal

Resolve namespace metadata without contaminating parsing or policy.

API

Recommended:

discover(host) -> DiscoveryResult

with successful result:

ValidatedStatute

and typed failures such as:

NotFound
TransportFailure
InvalidContentType
SchemaInvalid
NamespaceMismatch
CrossHostRedirect
InheritanceCycle
UnsupportedVersion

Redirect rule

Before adding caching, define redirect semantics precisely.

Initial rule:

Follow same-host HTTPS redirects only. Reject cross-host redirects.

A redirect must not transfer MAS authority to another hostname.

Scheme downgrade to HTTP must be rejected.

Parent domains

Never perform implicit lookup such as:

acme.coulomb.social
→ coulomb.social

Inheritance occurs only through an explicit statute declaration.

Caching

Add only minimal caching after behavior is correct.

Cache successful statutes separately from failures.

Do not let cache behavior hide typed discovery failures.

Exit criteria

Discovery is deterministic enough to test against a local HTTP fixture server.


Milestone 4 — Policy resolver

id: MAS-WP-0002-T05
status: todo
priority: high

Goal

Combine syntax and validated metadata without network access.

API

Conceptually:

resolve(
    parsed_address,
    statute,
    local_registry=None,
) -> AddressSemantics

Policy must remain pure.

Resolution examples

With no statute:

bernd.worsch@example.org

resolves only to syntactic information:

target = bernd.worsch
kind = opaque

It must not become:

kind = person

from punctuation.

With statute registry:

addresses:
  bernd.worsch:
    kind: person

the resolver may produce:

kind = person

For:

ticket=PR42

and a statute declaring ticket:

kind = resource
resource_type = ticket
resource_id = PR42

Profile validation

For:

ticket!callback

if statute says:

p2 = false

policy should return a typed semantic failure such as:

ProfileNotEnabled

The syntax remains valid.

Exit criteria

The complete policy test suite runs with network disabled.


Milestone 5 — mas CLI

id: MAS-WP-0002-T06
status: todo
priority: high

Goal

Provide the main inspection surface for developers and operators.

Commands

Parse

mas parse ADDRESS

Shows syntax only.

Discover

mas discover HOST

Shows validated statute or typed failure.

Explain

mas explain ADDRESS

Shows three distinct layers:

Syntax
Namespace discovery
Semantic resolution

Example failure:

Address:
  bernd.worsch@example.org

Syntax:
  target: bernd.worsch
  required profile: P1

Discovery:
  no valid MAS statute found

Semantics:
  kind: opaque

This is preferable to displaying a guessed “person”.

Lint statute

mas lint-statute FILE

Run conformance suite

mas test

Exit criteria

A human can understand exactly why an address received its interpretation.


Milestone 6 — Static statute deployment

id: MAS-WP-0002-T07
status: todo
priority: medium

Goal

Test real exact-host discovery.

Serve one validated static statute at:

/.well-known/mas

No framework-specific statute server should be built yet.

The deployment should advertise only the features needed by the reference service.

Example:

P1 = enabled
P2 = enabled

resource_types:
  ticket

interaction_modes:
  callback

Exit criteria

mas discover retrieves the live/local test statute and validates namespace consistency.


Milestone 7 — Generic mail-to-HTTP gateway

id: MAS-WP-0002-T08
status: todo
priority: medium

Goal

Bridge ordinary inbound mail into an application-neutral MAS event.

Input

Either:

SMTP

or:

provider inbound webhook

Choose whichever produces the smallest reliable prototype.

Gateway behavior

For each inbound recipient:

  1. parse address;
  2. discover statute;
  3. resolve policy;
  4. produce normalized event;
  5. POST event to configured HTTP application endpoint.

Example event:

{
  "recipient": "ticket=GS-41872@example.org",
  "mas": {
    "profile": "P1",
    "kind": "resource",
    "resource_type": "ticket",
    "resource_id": "GS-41872"
  },
  "message": {
    "from": "customer@example.net",
    "subject": "The problem happened again"
  }
}

The gateway must not contain ticket-specific logic.

Exit criteria

The same gateway could theoretically route another MAS resource type without code changes.


Milestone 8 — Reference ticket service

id: MAS-WP-0002-T09
status: todo
priority: medium

Goal

Prove the canonical lifecycle.

Flow A — create

Customer sends:

ticket!callback@great-service.example

The service:

  1. receives a normalized MAS event;
  2. verifies P2 is enabled;
  3. creates ticket;
  4. records callback as requested interaction mode;
  5. generates resource address:
ticket=GS-41872@great-service.example
  1. replies using that resource address.

The subject does not require a ticket prefix.


Flow B — correlate

Customer later sends or replies to:

ticket=GS-41872@great-service.example

The service:

  1. resolves resource type and id;
  2. locates GS-41872;
  3. associates the new message with that resource.

No subject-line parsing is required.


Flow C — closed resource

Ticket GS-41872 is closed.

Mail later arrives at:

ticket=GS-41872@great-service.example

The address remains valid.

The service must apply explicit lifecycle policy.

For the prototype, choose one behavior such as:

archive message
+
return "ticket closed" response

It must not silently mutate or reopen the ticket.


Flow D — unknown resource

Mail arrives at:

ticket=DOES-NOT-EXIST@great-service.example

The service must handle this deliberately and without generating abusive backscatter.


Milestone 9 — Experiment review

id: MAS-WP-0002-T10
status: todo
priority: medium

Goal

Decide whether MAS v0.1 survives contact with implementation.

Review:

Syntax

Did the parser remain simple?

Discovery

Was exact-host metadata sufficient?

Policy

Could all inference remain explicit?

Email infrastructure

Which characters or address forms were rewritten or rejected?

Resource addressing

Did resource addresses actually improve correlation?

Subject lines

Could application identifiers genuinely disappear from subjects?

Lifecycle

Did closed resources remain understandable?

Interaction

Was !callback useful or did it require more negotiation semantics?

Security

Did any address accidentally start behaving like a capability?


Decision gate

Only after the reference experiment should the project decide whether to build:

TypeScript implementation
Go implementation
Postfix/Exim integration
mail-client inspector
address composer
signed statutes
P3 economic profile

Each addition should answer a demonstrated need from the experiment.


Initial execution order

The shortest path is:

1. mas-core parser/model
2. expanded conformance corpus
3. statute validator/linter
4. exact-host discovery
5. pure policy resolver
6. mas CLI
7. static statute
8. generic inbound gateway
9. reference ticket service
10. experiment review

The governing rule for this phase is:

One implementation, one lifecycle, one real email path.