# AIRC Addressing Scheme — Specification

*Rafael Baptista, 25 September 2026. Draft 0.1, for discussion. Reproduced in
this tree from the author's document so the addressing and transport
specifications travel together; the transport spec is [`airc-spec.md`](/transport.md).*

## 1. Status and abstract

Status: draft 0.1, for discussion. Not yet submitted anywhere.

This document specifies the address syntax and resolution model for AIRC (AI
Relay Chat), a decentralized, DNS-routed protocol for real-time agent-to-agent
messaging. It covers only addressing: how an agent is named, how a name is
written, and how a name is turned into a reachable endpoint. Transport, message
format, and authentication are out of scope and will be specified separately.

An AIRC address is a URI of the form `airc://<authority>/<path>`. The authority
is a DNS name that owns the address space; the path is an opaque, hierarchical
namespace whose meaning is defined by that authority. The final path segment
names the endpoint. Any agent that owns a path prefix is the resolver for
everything beneath it, so sub-agents can be created and addressed without the
host learning of them.

Three spellings map onto that one grammar: the full URI, a scheme-elided
network form (`//host/alice/net-ops`), and a local shorthand with no authority
(`alice/net-ops`, `net-ops`).

## 2. Terminology and conventions

The key words MUST, MUST NOT, SHOULD, SHOULD NOT and MAY are to be interpreted
as described in RFC 2119.

| Term | Meaning |
|------|---------|
| Agent | Any process that can send or receive AIRC messages. Users, daemons and sub-agents are all agents. |
| Address | A string identifying one agent or one namespace, in any of the three forms in section 4. |
| Authority | The DNS name (plus optional port) that owns an address space. Written after `//`. |
| Path | The segments after the authority. Opaque to everyone except the authority and the agents it delegates to. |
| Segment | One `/`-separated element of the path. |
| Endpoint | The agent named by the last segment of a path. The thing a message is delivered to. |
| Namespace | A path prefix. Owned by the agent that segment names, or by the authority if none. Written with a trailing `/`. |
| Resolver | Any party that maps a path (or path suffix) to a transport-level destination. Hosts, users and agents can all be resolvers. |
| Delegation | A resolver handing responsibility for a path prefix to another agent. |
| Local form | An address with no authority. Resolved by the local resolver only. |
| Sender | The agent that originates a message. |
| Relay | Any intermediate party that forwards a message without being its endpoint. |

## 3. Syntax

An AIRC address is a valid RFC 3986 URI under the `airc` scheme. The grammar
below is a restriction of the generic URI grammar, not an extension; any
conforming URI parser can split an AIRC address correctly.

```
airc-uri      = "airc:" network-form
network-form  = "//" authority "/" path [ "#" fragment ]
local-form    = path [ "#" fragment ]

authority     = host [ ":" port ]
host          = reg-name / IP-literal        ; RFC 3986; reg-name MUST be a DNS name
port          = 1*5DIGIT

path          = segment *( "/" segment ) [ "/" ]   ; trailing "/" = namespace, see 7
segment       = name-char *62( name-char )         ; 1 to 63 characters
name-char     = ALPHA / DIGIT / "-" / "_"

fragment      = *pchar                             ; RFC 3986; not part of the address
```

Rules:

- Segments are case-insensitive. Implementations MUST compare them
  case-insensitively and SHOULD emit them in lowercase.
- A segment MUST NOT begin or end with `-`. Segments beginning with `_` are
  reserved (section 8).
- `.` is not permitted in a segment. This guarantees the authority is the only
  dotted component and a parser never has to guess where the host ends.
- `@`, `:`, `!`, `~`, `#` (outside a fragment), `*`, `%` and whitespace are not
  permitted in a segment. This keeps every address free of shell expansion in
  bash, zsh, fish, PowerShell and cmd, and keeps it visually distinct from an
  email address.
- Percent-encoding is not used. Names that cannot be expressed in `name-char`
  are not valid AIRC names.
- The total address MUST NOT exceed 1024 octets. Path depth is unbounded by
  the grammar (section 6).
- `airc:` followed immediately by a path with no `//` is not valid. The scheme
  always introduces the network form.

The fragment is carried by the URI but is not part of the address for
resolution or comparison purposes. Its use for instance identity is described
in section 7.

## 4. Address forms

One grammar, three spellings. All three denote the same endpoint once
resolved; they differ only in how much context the writer supplies.

| Form | Example | Where used | Resolved by |
|------|---------|------------|-------------|
| URI | `airc://sysops.example.com/alice/net-ops` | Documents, links, config files, envelope headers | DNS, then the authority |
| Network | `//sysops.example.com/alice/net-ops` | Command lines, chat, anywhere a human types | DNS, then the authority |
| Local | `alice/net-ops` or `net-ops` | Command lines on the same machine or fleet | The local resolver only |

### 4.1 URI form

The canonical form. Implementations MUST accept it everywhere an address is
accepted, and MUST use it in any on-the-wire field that carries an address
(for example the From and To of an envelope). It is the only form that is
unambiguous outside a local context.

### 4.2 Network form

The URI with `airc:` elided. This mirrors the scheme-relative URL convention in
HTML (`//cdn.example.com/x.js`). A leading `//` is the visual signature of an
AIRC address; a reader who sees it knows the string is neither an email
address nor a file path.

Implementations MUST treat a network-form address as equivalent to the URI
form with `airc:` prepended.

### 4.3 Local form

An address with no authority. It is resolved entirely by the local resolver,
which is the authority for the local machine or fleet. The protocol does not
define what local segments mean; it defines only the default that ships with
the reference resolver:

- `net-ops`: an agent in the invoking user's own namespace.
- `alice/net-ops`: an agent in the namespace of local user alice.
- Deeper local paths follow the same delegation rules as network paths
  (section 6).

A local-form address MUST NOT appear in an on-the-wire address field. Before a
message leaves the local resolver, the resolver MUST rewrite every local-form
address it contains into URI form using its own authority, so that the
recipient can reply.

### 4.4 Equivalence

Two addresses are equivalent if, after case-folding the authority and every
segment, dropping any default port, and dropping the fragment, the resulting
strings are identical. A trailing `/` is significant: `//host/alice` and
`//host/alice/` are not equivalent (section 7).

## 5. Resolution

Resolution turns an address into a transport-level destination for its
endpoint. It has two stages: the authority is located through DNS, and the
path is then resolved by the authority and whatever it has delegated to.

### 5.1 Locating the authority

For a network or URI form address, the sender's resolver MUST:

1. Query DNS for an SRV record at `_airc._tcp.<host>` (or `_airc._udp.<host>`
   if the transport spec defines a UDP binding). Follow standard SRV priority
   and weight rules, and use the SRV target and port as the destination.
2. If no SRV record exists, fall back to an A/AAAA lookup of `<host>` on the
   default AIRC port (to be assigned by the transport spec; this document uses
   7000 in examples).
3. If the address carries an explicit port, use it in place of any SRV or
   default port.

SRV is the mechanism that separates a domain from a machine.
`//example.com/alice/net-ops` can route to any host the domain's administrator
points the SRV at, and can change without any address changing. This is the
property that makes AIRC addresses behave like email addresses without looking
like them.

An IP-literal authority (`//[2001:db8::1]/alice/net-ops`,
`//192.0.2.1/net-ops`) skips DNS and connects directly. Implementations MUST
support it; it is intended for bootstrapping and testing, not for published
addresses.

### 5.2 Resolving the path

Once connected, the sender presents the full path to the authority's resolver.
The authority resolves as many leading segments as it owns, then either
delivers (if the endpoint is reached) or hands the remaining path to the agent
it has delegated that prefix to (section 6).

Senders and relays MUST NOT interpret the path. They MUST NOT split it, assume
a segment is a user, a team or a sub-agent, or rewrite it. The only party
permitted to give a segment meaning is the resolver responsible for it.

### 5.3 Local resolution

A local-form address is resolved by the local resolver using its configured
rules. The reference resolver's defaults are given in section 4.3. A local
resolver MUST know its own authority (its DNS name, or an IP-literal if it has
none) so it can rewrite local addresses to URI form on egress.

A network-form address whose authority is the local resolver's own authority
MUST be resolved as if it were the corresponding local form.
`//sysops.example.com/alice/net-ops` typed on sysops.example.com does not
leave the machine.

## 6. Delegation

Every agent is the resolver for its own subtree. This one rule gives AIRC
unbounded, ephemeral sub-agent addressing without any central registry.

### 6.1 The rule

If an agent is reachable at path P, then that agent is the authoritative
resolver for every path of the form P/.... The resolver above it MUST forward
any message addressed beneath P to the agent at P with the remaining segments
intact, and MUST NOT attempt to resolve those segments itself.

This is the same structure as DNS zone delegation: a parent zone knows only
that a subtree exists and who serves it, never what is inside.

### 6.2 Consequences

- **Creation is local.** An agent at `//host/alice/research` that spawns a
  worker registers `spider1` in its own routing table.
  `//host/alice/research/spider1` is immediately addressable. No call to the
  host, no call to alice.
- **Uniqueness is scoped.** A segment need only be unique among its siblings.
  `//host/alice/research/spider1` and `//host/bob/research/spider1` are
  different agents and never conflict.
- **Depth follows the spawn chain.** A path is as deep as the sequence of
  agents that created it. The grammar imposes no limit; the 1024-octet ceiling
  in section 3 is the only bound.
- **Teardown is local.** When spider1 exits, research removes it. A later
  message to that path receives a resolution error from research (section 9),
  not from the host.
- **The host never learns.** A host, and any relay, sees only the prefix it
  delegated. Sub-agent existence, count and naming are invisible above the
  delegating agent.

### 6.3 Resolver responsibilities

An agent that accepts delegation for a prefix MUST:

- Accept messages addressed to any path beneath its prefix and either
  deliver, forward, or return a resolution error. It MUST NOT silently drop
  them.
- Answer resolution queries for its immediate children (a listing of P/ in
  section 7) if it permits listing at all. It MAY refuse listing while still
  delivering to known children.
- Rewrite any local-form address in outgoing envelopes to the full URI form,
  using its own full path as the prefix, so that a sub-agent's From is always
  globally resolvable.

An agent MAY delegate further: spider1 can itself accept delegation for
spider1/.... The rule is recursive.

### 6.4 Peer discovery among ephemeral agents

Two sub-agents under different parents find each other through the envelope,
not a directory. When `//host/alice/research/spider1` sends to
`//host/bob/encyclopedia/summarizer3`, its envelope From carries its full URI.
summarizer3 replies to that URI; resolution runs host → encyclopedia →
summarizer3 in one direction and host → research → spider1 in the other.
Neither parent nor the host maintains a table of the other's children.

How spider1 learned of summarizer3 in the first place (an introduction from
research, a listing of encyclopedia/, or a capability announcement) is a
matter for the discovery layer and is out of scope here. This section
guarantees only that once an address is known, it resolves.

## 7. Endpoints, namespaces and instances

### 7.1 Endpoint versus namespace

A path without a trailing `/` names an endpoint: the agent at the last
segment. A path with a trailing `/` names a namespace: the set of agents
beneath that prefix.

| Address | Denotes |
|---------|---------|
| `//host/alice/research` | The research agent itself |
| `//host/alice/research/` | Every agent research has delegated to, not research |
| `//host/net-ops` | A system-level agent in the host's root namespace |
| `//host/` | The host's root namespace |

A namespace is not an endpoint. A message addressed to a namespace is a
fan-out request; whether the resolver for that namespace honours it
(delivering to all children, to a designated subset, or refusing) is that
resolver's policy. Implementations MUST accept the syntax and MAY refuse the
operation.

The same rule resolves the "is foo a user or an agent?" question: it is never
a question the sender has to answer. `//host/foo` is always the endpoint named
foo. If the host also has a user foo with agents beneath, that namespace is
`//host/foo/`, and the two never collide.

### 7.2 Instance identity

An address names a role, not a process. `//host/alice/research/spider1` may be
torn down and re-created many times with the same name. Receivers that need
to distinguish one incarnation from another SHOULD use the URI fragment, which
is carried but ignored by resolution:

```
//host/alice/research/spider1#run-42
//host/alice/research/spider1#7f3a9c
```

The fragment is chosen by the agent it describes and reported in its outgoing
From. A message arriving with a fragment that does not match the current
incarnation MAY be rejected by the endpoint with a stale-instance error
(section 9). Resolvers MUST strip the fragment before comparison and routing
and MUST pass it through to the endpoint unchanged.

This keeps addresses stable for configuration and humans while letting the
protocol tell a fresh spider1 from a stale one.

## 8. Reserved and well-known names

Segments beginning with `_` are reserved for this and future AIRC
specifications. Authorities MUST NOT assign them to users or agents. This
mirrors the `_service` convention in DNS and keeps the reserved space out of
the way of ordinary names.

The following are defined now. All are optional to implement; an authority
that does not implement one MUST return a resolution error rather than
assigning the name to something else.

| Name | At | Purpose |
|------|----|---------|
| `_resolver` | `//host/_resolver` | The authority's own resolver, for direct resolution queries and health checks |
| `_postmaster` | `//host/_postmaster` | Human-facing contact for the authority, by analogy with RFC 5321 postmaster@ |
| `_dir` | `//host/_dir`, `//host/alice/_dir` | Directory or listing agent for that namespace, when listing is offered as an agent rather than a resolver query |

Authorities and delegated agents MAY define further `_`-prefixed names for
their own use, but SHOULD prefer plain names for anything that is not
protocol machinery. A registry of well-known reserved names will be
established alongside the transport specification.

Names that are not reserved but are conventional (for example, a per-user
default agent that receives messages addressed to a bare user namespace) are
recommendations to authorities, not requirements, and will be collected in a
separate best-practices document.

## 9. Resolution errors and lifetimes

Because sub-agents are ephemeral, resolution failure is a normal event and
senders must be able to distinguish its causes. The following classes are
defined; exact codes and their wire representation belong to the transport
spec.

| Class | Meaning | Raised by | Sender should |
|-------|---------|-----------|---------------|
| No such authority | DNS lookup for the host failed | Sender's resolver | Treat as permanent; check the address |
| Authority unreachable | Host resolved but no connection | Sender's resolver | Retry with backoff |
| No such path | A resolver on the chain does not know the next segment | The last resolver that owned a prefix | Treat as permanent unless the path was recently valid |
| Path gone | The segment existed and has been torn down | The delegating agent | Treat as permanent; the instance is finished |
| Not delegated | A prefix is owned but its owner does not accept sub-paths | The owning agent | Treat as permanent |
| Namespace, not endpoint | Message sent to P/ where fan-out is refused | The resolver for P/ | Address a specific endpoint |
| Stale instance | Fragment does not match the current incarnation | The endpoint | Re-discover the address; drop the old fragment |
| Refused | Resolution succeeded but policy denies delivery | Any resolver | Do not retry without a change in credentials |

An error MUST identify the deepest resolver that produced it, as a URI, so the
sender knows where the chain broke. No such path from
`//host/alice/research` tells the sender the parent is alive and the child is
not; the same error from `//host/_resolver` tells it alice or research is
missing.

### 9.1 Lifetime hints

A successful resolution MAY carry a time-to-live in seconds, set by the
resolver that produced the final hop. Senders MAY cache a resolved destination
for at most that long. A resolver SHOULD set a short TTL (seconds to minutes)
for agents it knows to be ephemeral and MAY set a long one for durable agents.
Absence of a TTL means the result MUST NOT be cached.

TTLs are advisory. A cached destination that fails MUST be re-resolved, and a
Path gone or Stale instance error MUST invalidate any cached entry for that
address.

## 10. Security considerations

This document defines names, not trust. The points below are the
addressing-layer consequences that the authentication and transport
specifications must build on.

- **An address is not an identity.** Anyone can write
  `//example.com/alice/net-ops` in a From field. Resolvers and endpoints MUST
  NOT treat the address in an envelope as proof of origin. Origin
  authentication (signatures bound to an address, or transport-level identity
  of the delegating chain) is defined elsewhere.
- **Authorization follows delegation.** Whether spider1 may accept a message
  from outside alice/ is decided first by research, then by alice's resolver,
  then by the host, in that order. Each resolver on the chain MAY apply policy
  to messages passing through it and MUST NOT rely on a resolver below it to
  do so.
- **Opaque paths limit enumeration.** Because a relay never interprets a path,
  it cannot list sub-agents it did not delegate. Namespace listing (P/) is the
  only enumeration primitive and is opt-in per resolver. Authorities SHOULD
  refuse listing of user-level namespaces to unauthenticated senders.
- **Delegation is a trust boundary.** An agent that delegates a prefix is
  trusting the child to resolve it correctly and to apply policy. A
  compromised sub-agent can misroute or accept anything beneath its own
  prefix, but cannot affect siblings or ancestors, because it never sees their
  traffic.
- **DNS is the root of trust for locating an authority.** Resolvers SHOULD
  validate SRV and address records with DNSSEC where available, and the
  transport spec MUST bind the connection to the authority name (for example
  via TLS with the SRV target's certificate) so that a spoofed DNS answer
  cannot silently redirect a domain.
- **Local-form rewriting must be correct.** A local resolver that rewrites
  net-ops to the wrong authority on egress produces a From that either does
  not resolve or resolves to a third party. Resolvers MUST know their own
  authority and MUST refuse to send with a local-form address if they do not.
- **Fragments are unauthenticated hints.** A fragment identifies an
  incarnation but proves nothing; it is a cache key, not a credential.
- **Reserved names are public.** `_resolver` and `_postmaster` are
  discoverable by construction. Authorities SHOULD rate-limit them and MUST
  NOT expose privileged operations through them without authentication.

## 11. Examples

### 11.1 Addresses

```
net-ops                                       # local: my own agent
alice/net-ops                                 # local: alice's agent on this machine
//sysops.example.com/net-ops                  # remote: system agent in the host root
//sysops.example.com/alice/net-ops            # remote: alice's agent
//example.com/alice/net-ops                   # domain-level; SRV picks the host
//example.com:7001/alice/net-ops              # explicit port
//[2001:db8::1]/alice/net-ops                 # IP literal, no DNS
//example.com/sre/alice/net-ops               # team/user/agent (authority's taxonomy)
//example.com/alice/research/spider1          # sub-agent, delegated by research
//example.com/alice/research/spider1#run-42   # same, with instance fragment
//example.com/alice/research/                 # namespace: all of research's children
airc://example.com/alice/research/spider1     # canonical URI form, as carried on the wire
```

### 11.2 A command-line exchange

```
$ co-tell net-ops "nginx is down"
$ co-tell alice/net-ops "nginx is down"
$ co-tell //sysops.example.com/alice/net-ops "nginx is down"
```

In the first two cases the local resolver rewrites the address to
`airc://<local authority>/...` before sending, so net-ops can reply.

### 11.3 Resolution trace: sub-agent to sub-agent

`//example.com/alice/research/spider1` sends to
`//example.com/bob/encyclopedia/summarizer3`.

1. spider1's resolver (its parent, research) sees a non-local authority and
   looks up `_airc._tcp.example.com` → SRV → sysops.example.com:7000.
2. It connects and presents the path bob/encyclopedia/summarizer3.
3. The host resolver owns bob; bob's resolver owns encyclopedia and has
   delegated beneath it to the encyclopedia agent.
4. encyclopedia receives summarizer3, finds it in its routing table, delivers.
5. The envelope From is `airc://example.com/alice/research/spider1#run-42`.
   summarizer3 replies to it; the reverse chain is host → alice → research →
   spider1.

Neither research nor encyclopedia had any prior knowledge of the other's
children.

### 11.4 Resolution trace: a torn-down sub-agent

spider1 has exited. A message arrives for `//example.com/alice/research/spider1`.

1. Host → alice → research resolve normally.
2. research no longer has spider1 in its table and returns Path gone,
   identifying itself as `airc://example.com/alice/research`.
3. The sender invalidates any cached entry and knows the parent is alive;
   whether to ask research for a replacement is an application decision.

### 11.5 DNS records for an authority

```
_airc._tcp.example.com.  IN SRV 10 50 7000 sysops.example.com.
_airc._tcp.example.com.  IN SRV 20 50 7000 backup.example.com.
sysops.example.com.      IN A   192.0.2.10
backup.example.com.      IN A   192.0.2.11
```

Every address under `//example.com/...` now routes to sysops, failing over to
backup, with no address changing.

## 12. Use cases

The scheme is judged against the six scenarios below. Each one adds a
requirement the previous ones did not; the design in sections 3 to 9 is the
smallest grammar that satisfies all six.

### 12.1 One user, one machine, a fleet of agents

A developer runs several long-lived agents on a workstation: net-ops, builder,
reviewer. They want to address them from the shell with the least typing
possible and no configuration.

Requirement: a bare name must work. `co-tell net-ops "nginx is down"` is the
whole interaction.

How the scheme meets it: the local form (4.3). The local resolver owns the
bare-name namespace and needs no authority to be configured for local-only
use.

### 12.2 Several users on one machine

A shared host has users alice and bob, each running their own agents, some
with the same names.

Requirement: addresses must be scoped per user without forcing every user to
pick globally unique agent names, and the scoping must be obvious to a reader.

How the scheme meets it: `alice/net-ops` and `bob/net-ops`. Uniqueness is per
parent (6.2), and the owner/thing shape is one readers already know from
repositories and package registries.

### 12.3 Agents across machines in one organization

The organization runs agents on sysops, build-01 and build-02. Agents on any
of them need to reach agents on the others, and the organization wants to move
agents between machines without every peer's configuration changing.

Requirement: an address that names the organization, not the box, with the
organization deciding which box serves it.

How the scheme meets it: `//example.com/alice/net-ops` resolved through
`_airc._tcp.example.com` SRV (5.1). Moving alice's agents to another host is a
DNS change; no address changes. This is the property email gets from MX
records, reproduced without an `@`.

### 12.4 Agents across organizations

A supplier's `//supplier.example/orders/intake` must accept messages from a
customer's `//customer.example/procurement/buyer`, with neither organization
having any account on the other's systems.

Requirement: globally unique, self-describing addresses that any party on the
internet can resolve without prior arrangement, and that a receiver can reply
to from the envelope alone.

How the scheme meets it: the URI form is globally unique by construction (DNS
ownership), resolution needs only public DNS, and the mandatory rewrite of
local addresses to URI form on egress (4.3, 6.3) guarantees every From is
replyable.

### 12.5 Ephemeral sub-agent swarms

An orchestrator agent spawns fifty short-lived workers for a task, and two
orchestrators under different users need their workers to talk to each other
directly while the task runs, then disappear.

Requirement: creating and destroying an addressable agent must cost nothing
beyond the parent's own bookkeeping; the host must not need to know; a worker
under one parent must be able to reach a worker under another; and a message
to a dead worker must fail fast and informatively.

How the scheme meets it: delegation (6). Each parent resolves its own subtree,
so creation and teardown are a local table edit. Peers find each other through
envelope From fields (6.4). Path gone from the parent, with a TTL that was
short to begin with (9), makes failure cheap.

This use case is the one that rules out a flat or fixed-depth address space:
with agents as the primary users, sub-agents are the normal unit of work, not
an edge case.

### 12.6 Organization-specific taxonomies

One organization groups agents by team (`sre/alice/net-ops`); another by
product (`alice/monitoring/net-ops`); a third has no users at all, only
services (`billing/ledger`).

Requirement: the protocol must not impose an org chart, and a sender must not
need to know the receiver's taxonomy to address it correctly.

How the scheme meets it: the path is opaque to everyone but the authority
(5.2). The only fixed rules are that the last segment is the endpoint and that
a trailing `/` is a namespace (7.1). Everything between the authority and the
endpoint is the authority's business, exactly as the local-part of an email
address is the receiving domain's business.

## 13. Design rationale

Each choice below is stated with the alternatives that were considered and
why they lost. The recurring test was: does this look like the protocols that
lasted (DNS, SMTP, HTTP, URIs), and does it fail the way they fail?

### 13.1 Why a URI

Choice: every AIRC address is a valid RFC 3986 URI.

Justification: it gives the scheme a parser, an escaping story, a canonical
form, a place for ports and IP literals, and a fragment, all for free, and it
makes addresses embeddable in documents, links and config without a second
grammar. A homegrown syntax would have had to re-specify each of those and
would still not be clickable.

Rejected: a bespoke `host::user::agent` syntax (13.3), and a `user:agent@host`
syntax that reused URI userinfo but read as email.

### 13.2 Why `//` as the visual signature

Choice: the network form begins with `//`, the URI authority marker, and the
scheme prefix is optional in human contexts.

Justification: `//` already means "what follows is on the network" in URLs,
UNC paths and scheme-relative links, and it means nothing in email or on a
filesystem. A reader who sees a leading `//` knows instantly that the string
is neither. Dropping `airc:` in the shell mirrors the way HTML drops the
scheme in `//cdn.example.com/x.js`, so there is a precedent for the elision
rather than a new rule.

Rejected: `@`-based forms, which trigger the email reflex and invite mail
clients to linkify them; `!` bang paths, which are the most authentically
vintage option (UUCP) but collide with shell history expansion.

### 13.3 Why not `::` or bare DNS names

`host::user::agent` was the second-best candidate. It is unmistakable and
shell-safe, and it has DECnet lineage. It lost because it is not a URI (so it
needs a second grammar for links and config), because `::` is IPv6 syntax and
a bare IP authority becomes ambiguous, and because the dotted host floats
unboxed in the middle of the string.

`agent.user.host.example.com` was also considered, since routing is DNS
anyway. It lost because it is visually identical to a hostname, because every
agent would need a DNS label someone has to provision, and because ephemeral
sub-agents (12.5) cannot be created by a parent editing its own table if each
one needs a DNS record.

### 13.4 Why most-specific-last

Choice: the path reads authority, then namespace, then endpoint, left to
right.

Justification: it is how paths, URLs and owner/repo names already read, so no
one has to learn a direction. It also makes the shorthand forms prefixes of
the full form (`net-ops` ⊂ `alice/net-ops` ⊂ `//host/alice/net-ops`), which
is what makes tab-completion and progressive qualification natural.

Rejected: DNS-style most-specific-first, which reads well for hostnames but
would put the thing users type least (the authority) at the end and make the
local form a suffix rather than a prefix.

### 13.5 Why the path is opaque

Choice: only the authority and its delegates interpret the path. Senders and
relays MUST NOT.

Justification: this is the decision that let email survive thirty years of
unforeseen use. Everything left of `@` belongs to the receiving domain, which
is why plus-addressing, ticket IDs and list names all worked without an RFC
change. DNS made the same choice for labels. Fixing a taxonomy in the protocol
would have been wrong for someone on day one, and they would have encoded
their hierarchy into names like `sre-alice-net-ops` anyway, giving the
protocol the taxonomy with none of the structure.

Rejected: a hard two-level user/agent limit. Flatness is a genuine feature of
email, but 12.5 and 12.6 both need depth.

### 13.6 Why delegation is the depth mechanism

Choice: an agent at P resolves P/...; depth follows the spawn chain.

Justification: it is DNS zone delegation applied to agents. It makes sub-agent
creation a local table edit, keeps the host ignorant of what it delegated,
scopes uniqueness to siblings, and bounds every agent's blast radius to its
own subtree (10). Any alternative (a host-wide registry, a lease service)
would have added a round-trip to every spawn and a central table that grows
with the swarm.

### 13.7 Why the last segment is always the endpoint

Choice: `//host/foo` is always agent foo; `//host/foo/` is always a namespace.

Justification: it removes the "is foo a user or an agent?" question from the
sender entirely, the same way an email sender never needs to know whether
foo@ is a person or a list. Position decides, not knowledge. The trailing
slash gives namespaces a distinct spelling without a sigil, which keeps `@`
and `~` available for the future (14).

Rejected: an explicit user marker such as `@alice/net-ops`. It reads well and
is shell-safe, but it adds a character and a rule for a distinction the sender
does not need. Since `@` is an invalid name character, it can be introduced
later without breaking anything, so deferring it costs nothing.

### 13.8 Why the character set is so small

Choice: `[A-Za-z0-9_-]`, no dots, no percent-encoding.

Justification: every excluded character is either a shell metacharacter in
some common shell (`!`, `~`, `#`, `*`, `$`, whitespace), a delimiter that
would make parsing ambiguous (`.`, `:`, `@`, `/`), or a signal that the string
is something else (`@` again). Excluding `.` from segments means the authority
is the only dotted component and a parser never guesses where the host ends.
Excluding percent-encoding means an address is always exactly what it looks
like.

The cost is no non-ASCII names, which is listed as an open question (14).

### 13.9 Why the fragment carries instance identity

Choice: `#run-42` distinguishes incarnations; it is carried but ignored by
resolution.

Justification: an address should name a role, so that configuration,
documentation and humans can rely on it across restarts. But a receiver
sometimes needs to know whether the spider1 it is hearing from is the one it
was talking to a minute ago. The URI fragment is defined by RFC 3986 as
client-side and not sent to the server, which is exactly the semantics
wanted: routing ignores it, the endpoint sees it.

Rejected: putting the instance ID in the path (`spider1/run-42`), which would
make it a delegated sub-agent rather than a version of one, and putting it
only in a separate envelope header, which would leave it out of the address
and so out of logs and links.

### 13.10 Why SRV for authority lookup

Choice: `_airc._tcp.<host>` SRV, with A/AAAA fallback.

Justification: SRV is the existing, deployed mechanism for "this domain's
service for protocol X lives on that host and port," with priority and weight
for failover built in. It is what makes a domain-level address
(`//example.com/...`) independent of any machine, which is the property that
lets addresses stay stable while infrastructure moves. Inventing a new record
type would have meant waiting for resolver support; SRV works today.

### 13.11 Why local-form addresses must be rewritten on egress

Choice: a resolver MUST rewrite `net-ops` to `airc://<own authority>/net-ops`
before a message leaves it.

Justification: a From that cannot be resolved by the recipient breaks the one
guarantee that makes peer discovery through the envelope (6.4) work.
Requiring the rewrite at the edge is cheaper and more reliable than requiring
every agent to know its own global address.

## 14. Open questions

- [ ] Default port. 7000 is a placeholder; needs an IANA assignment request
  alongside the transport spec. *(The reference implementation uses 2472.)*
- [ ] Segment character set. Section 3 allows `_` in ordinary names but
  reserves a leading `_`. Decide whether to allow `_` at all outside reserved
  names, or drop it to `[a-z0-9-]` only.
- [ ] Unicode names. Percent-encoding is excluded deliberately. Decide whether
  IDNA-style punycode for segments is worth specifying, or whether ASCII-only
  is a feature.
- [ ] Fan-out semantics. Section 7 makes namespace delivery optional. Decide
  whether a minimum (deliver to all immediate children, or refuse) should be
  mandatory for interop.
- [ ] Resolution query protocol. Section 6.3 mentions listing and resolution
  queries without defining them. Decide whether they live in this spec or the
  transport spec.
- [ ] Explicit user marker. `@alice/net-ops` was considered and held in
  reserve. `@` is currently an invalid character, so it can be added later
  without breaking existing addresses. Decide whether to reserve it formally
  now.
- [ ] Non-DNS authorities. Whether to permit a future authority type (a public
  key, a .onion-style name) under the same `//` grammar, and how the host rule
  in section 3 would relax to allow it.
