# Design: Axiom Resolution Protocol

**Status:** Draft for review
**Author:** Benjamin Booth (with Claude Code)
**Date:** 2026-04-16
**Context:** Exploratory design — evolving Axiom federation toward a DNS/HTTP-native resolution layer for capabilities, knowledge, and trust.

---

## Table of Contents

- [1) Thesis](#1-thesis)
- [2) Substrate TAP Review — What to Adopt, What to Skip](#2-substrate-tap-review--what-to-adopt-what-to-skip)
- [3) Design Principles](#3-design-principles)
- [4) Resolution Model — Mapping to DNS + HTTP](#4-resolution-model--mapping-to-dns--http)
- [5) The Nine Gaps (and How to Close Them)](#5-the-nine-gaps-and-how-to-close-them)
- [6) Integration with Existing Axiom Architecture](#6-integration-with-existing-axiom-architecture)
- [7) What Changes, What Stays](#7-what-changes-what-stays)
- [8) Phased Implementation](#8-phased-implementation)
- [9) Open Questions](#9-open-questions)

---

## 1) Thesis

Axiom federation currently works as a **peer directory** — nodes discover
each other, exchange keys, share resources. This is like an `/etc/hosts`
file: it works at small scale but requires every node to know about every
other node, with no delegation, no caching semantics, no structured
resolution.

DNS succeeded not because it's clever, but because it solved three
problems cleanly:

1. **Delegation** — "I don't own this name, but I know who does"
2. **Caching with staleness** — "This answer is good for N seconds"
3. **Recursive resolution** — "I don't know, but I'll find out for you"

HTTP succeeded because it added:

4. **Content negotiation** — "Give me what I can handle"
5. **Status semantics** — "Here's exactly what happened and why"
6. **Cacheability** — "This response can be reused under these conditions"

Axiom should build its resolution protocol **on top of actual DNS and
HTTP**, adding agent-specific semantics only where the base protocols
genuinely can't express what's needed. The goal is a system where:

- A node resolving a capability (`reactor_physics.fuel_cycle`) walks a
  delegation chain the way a DNS resolver walks NS records
- The answer comes back with HTTP-style cache headers (`max-age`,
  `stale-while-revalidate`, `vary`)
- Federation topology maps to DNS zone delegation
- Agent Cards are served at well-known HTTP endpoints (already true)
- New concepts (capability records, trust attestations, knowledge
  authority) are expressed as extensions to these protocols, not
  replacements

---

## 2) Substrate TAP Review — What to Adopt, What to Skip

Substrate (github.com/Substrate-App/substrate) was an earlier attempt at
this same problem space. TAP (The Agent Protocol) introduced nine novel
components. Four months of industry evolution and Axiom's specific
constraints (academic federation, nuclear domain, classification
boundaries, offline-first) change the calculus on each.

### Adopt (with adaptation)

| TAP Component | What It Does | Why It's Helpful for Axiom | Adaptation Needed |
|---|---|---|---|
| **DADP** (Distributed Agent Discovery) | DNS-like federated agent/capability discovery with semantic search | Directly solves the "resolution layer" gap. Axiom's mDNS + manual registration doesn't scale past ~20 nodes. | Strip the commercial marketplace framing. Use actual DNS SRV + TXT for the base layer, DADP-style semantic overlay only where DNS can't express it. |
| **CPAC** (Confidentiality Policies as Code) | Machine-readable data sharing policies with runtime enforcement | Axiom has classification stamps (content-level) and trust profiles (approval-level) but no formalized **data-flow policy** that travels with content across federation boundaries. CPAC fills that gap. | Rename to avoid acronym collision. Simplify: Axiom's three-tier access model + classification stamps are the floor; CPAC-style policies extend them for cross-federation scenarios. No need for the full CPAC spec — just the "policy travels with content" principle. |
| **CBAC** (Capability-Based Access Control) | Cryptographic, field-level, time-bounded, use-limited tokens | For cross-federation resource access, OpenFGA alone is insufficient — the authorizing node and the consuming node don't share an authz service. Capability tokens solve this: the data owner issues a scoped, signed, expiring token that the consumer presents. Self-contained proof of authorization. | Axiom already uses Ed25519 extensively. CBAC tokens should be Ed25519-signed JWTs with Axiom-specific claims (access_tier, classification_ceiling, maturity_floor, federation_scope). Not a new cryptographic system — just a signed claim format. |

### Skip (with reasoning)

| TAP Component | What It Does | Why It's Not Helpful for Axiom |
|---|---|---|
| **MASR** (Model-Agnostic State) | Cross-model state portability, mid-conversation model switching | Axiom nodes run specific LLM providers (llamafile, Ollama, cloud). Model switching is a provider configuration concern, not a protocol concern. The gateway already handles LLM routing. Solving a problem Axiom doesn't have. |
| **MAMA** (Multi-Agent Memory Architecture) | Six-tier memory management (core, episodic, semantic, procedural, resource, vault) | Axiom's knowledge maturity model (Data → Patterns → Facts → Frameworks → Application → Wisdom) already covers this more pragmatically and with domain-appropriate semantics. MAMA is generic; Axiom's model is tuned for knowledge evolution in research/education contexts. Over-engineering for Axiom's use case. |
| **BAAT** (Blockchain-Anchored Audit Trail) | Tamper-evident audit via blockchain anchoring | Ed25519-signed, append-only JSONL audit chains (which Axiom already uses) provide tamper evidence without blockchain complexity, cost, or infrastructure dependencies. Blockchain adds value in adversarial multi-party commercial scenarios (healthcare billing disputes, financial compliance). In academic/gov federation with institutional trust anchors (InCommon, PIV/CAC), the threat model doesn't justify blockchain. If a nation-state can forge your Ed25519 chain, they can also compromise your blockchain node. |
| **VITAL** (Trust Lineage via Blockchain) | Agent provenance tracking with trust inheritance | The trust *inheritance* concept is valid — a derived agent should inherit some trust from its parent. But Axiom already has this via signed attestation chains (ADR-022 identity roots, ADR-024 intermediate keys). Blockchain anchoring adds nothing over signed attestations in Axiom's trust model. The useful part (inheritance semantics) can be adopted as an extension to existing attestations, not a new system. |
| **OASIS** (Organization Identity) | KYC/AML-style org verification for agent identity | Axiom's ADR-020 (identity layers) + ADR-022 (multi-sector anchoring via InCommon, PIV/CAC, consortium PKI) already solve this more pragmatically for academic/gov contexts. InCommon IS the "org verification" for universities. PIV/CAC IS the "org verification" for gov. OASIS reinvents what these existing systems already provide. |
| **SubCert** (Certification Framework) | Bronze/Silver/Gold/Platinum agent certification marketplace | Commercial marketplace framing doesn't fit academic federation. Axiom's trust profiles + validated classification pattern + CURIO quality gates already provide graduated trust without a certification marketplace. |

### Concepts to Extract (the useful kernel, not the full system)

| TAP Concept | Useful Kernel | How It Maps to Axiom |
|---|---|---|
| **Trust inheritance** (from VITAL) | Derived agents/extensions inherit trust from their parent, with decay based on derivation type (wrapper > extension > fork > composition) | Extension trust: a domain pack from a trusted institution inherits institutional trust. A fork of an agent inherits partial trust. Express as a claim in the capability token, not a separate blockchain system. |
| **Coordination patterns** (from agent protocol) | Sequential handoff, parallel fan-out, collaborative refinement, dynamic delegation, proactive assistance | Axiom agents (AXI, SCAN, CURIO, PRESS) already use some of these implicitly. Formalizing them as A2A task patterns (not a new protocol) helps cross-node agent collaboration. |
| **Portable context** (from MASR, stripped down) | When an agent delegates to a peer agent across federation, the relevant context travels with the request — but only what's authorized | Express as A2A task context with CPAC-style data-flow policy attached. Not a new state format — just structured A2A task metadata. |

---

## 3) Design Principles

### 3.1 Use real DNS. Use real HTTP. Add only what they can't express.

DNS SRV records already support service discovery. HTTP already supports
content negotiation, caching, and conditional requests. TLS already
supports mutual authentication. Don't invent parallel systems for things
these protocols already do.

**Axiom-specific extensions** are expressed as:
- DNS TXT records (for metadata that fits)
- HTTP headers (for per-request context)
- JSON payloads at well-known endpoints (for structured data)
- A2A Agent Cards (for capability advertisement)

### 3.2 Resolution is deterministic. Intent classification is model-mediated.

Consistent with `spec-security.md §2`: The resolution protocol itself
(delegation, caching, authority lookup) is deterministic code. Intent
classification ("is this a lookup or a synthesis query?") can be
model-mediated — it shapes which resolution path to take, but the
resolution path itself is deterministic.

### 3.3 Self-sufficient by default. Resolution is additive.

A node with no federation resolves everything locally. Federation adds
delegation and remote authorities but never creates a dependency.
If the resolution chain breaks, the node falls back to local resources
with a degradation notice — it doesn't fail.

### 3.4 Every response carries provenance and staleness.

Every resolved result includes:
- **Authority**: who provided this answer (node identity, institution)
- **Freshness**: when it was produced, how long it's valid
- **Trust path**: the chain of delegation that led to this authority
- **Classification**: access tier + classification stamp of the content

### 3.5 The federation IS the resolution network.

Federation topology (flat mesh, hub-and-spoke, hierarchical) maps
directly to DNS zone structure. A coordinator is an authoritative
nameserver. A leaf node is a stub resolver. The same infrastructure
that manages membership also manages resolution.

---

## 4) Resolution Model — Mapping to DNS + HTTP

### 4.1 What Gets Resolved

DNS resolves names to addresses. Axiom resolves **four things**:

| Resolution Type | Question | Answer | DNS Analog |
|---|---|---|---|
| **Capability** | "Who can run MCNP simulations?" | Node endpoints + parameters + cost + trust | SRV + TXT |
| **Knowledge** | "Who is authoritative for TRISO fuel data?" | Node endpoint + domain pack version + maturity tier + access tier | NS + SOA |
| **Identity** | "Is `@ben.booth:ut-austin` a real principal with valid affiliation?" | Signed attestation chain | DNSSEC chain |
| **Policy** | "What data-flow rules apply when sharing with this peer?" | Policy document (classification ceiling, field restrictions, audit requirements) | TXT (but richer) |

### 4.2 Actual DNS Usage (not analogy — real DNS records)

Axiom nodes register actual DNS records where the institution controls
its DNS zone. This is not a parallel naming system — it IS DNS.

```
; Zone file for physics.utexas.edu (maintained by IT, requested by axiom operator)

; SRV: "axiom federation endpoint lives here"
_axiom._tcp.physics.utexas.edu.  IN SRV 10 100 8443 rascal.physics.utexas.edu.

; TXT: node metadata (parseable by axiom, ignorable by everything else)
_axiom._tcp.physics.utexas.edu.  IN TXT "v=axiom1" "node_id=ax-7f3a2b9e" "profile=server" "ver=0.5.0"

; SRV: capability advertisement
_axiom-cap._tcp.physics.utexas.edu. IN SRV 10 100 8443 rascal.physics.utexas.edu.

; TXT: capability metadata
_axiom-cap._tcp.physics.utexas.edu. IN TXT "cap=llm:70b,rag:reactor_physics,rag:fuel_cycle,run:mcnp"

; SRV: knowledge authority advertisement
_axiom-ka._tcp.physics.utexas.edu.  IN SRV 10 100 8443 rascal.physics.utexas.edu.

; TXT: knowledge domains this node is authoritative for
_axiom-ka._tcp.physics.utexas.edu.  IN TXT "auth=reactor_physics.msr,fuel_cycle.msr" "gen=5" "tier=restricted"
```

**Why real DNS:**
- Institutions already manage DNS. Adding SRV + TXT records is a
  standard IT request, not a new system.
- DNS caching, TTL, and delegation work out of the box.
- DNS-SD (RFC 6763) provides automatic service browsing.
- mDNS (already implemented in Axiom) handles LAN discovery.
- No new infrastructure to deploy, maintain, or secure.

**Limitations of DNS (where we extend):**
- DNS TXT records are limited to 255 bytes per string (can chain, but
  awkward for rich metadata).
- DNS doesn't support semantic queries ("find an agent that can help
  with fuel cycle analysis").
- DNS doesn't carry trust attestations or classification stamps.
- DNS updates are slow (zone file changes, DNSSEC re-signing).

These limitations are handled by the HTTP layer (§4.3).

### 4.3 Actual HTTP Usage (not analogy — real HTTP endpoints)

Every axiom node already serves `/.well-known/agent-card.json` and
`/.well-known/axiom-manifest.json`. The resolution protocol extends
this with additional well-known endpoints that use standard HTTP
semantics:

#### Capability Resolution Endpoint

```http
GET /.well-known/axiom-capabilities HTTP/2
Accept: application/json
Authorization: Bearer <federation-capability-token>
X-Axiom-Intent: synthesis
X-Axiom-Classification-Ceiling: restricted
X-Axiom-Maturity-Floor: facts

HTTP/2 200 OK
Content-Type: application/json
Cache-Control: max-age=300, stale-while-revalidate=60
ETag: "gen5-cap-a3f2"
Vary: X-Axiom-Classification-Ceiling, Authorization
X-Axiom-Authority: @rascal:ut-austin
X-Axiom-Trust-Path: @rascal:ut-austin (self)

{
  "capabilities": [
    {
      "type": "rag",
      "domain": "reactor_physics.msr",
      "generation": 5,
      "maturity_tiers": ["data", "patterns", "facts", "frameworks"],
      "access_tier": "restricted",
      "chunk_count": 42000,
      "last_updated": "2026-04-10T14:30:00Z"
    },
    {
      "type": "llm",
      "model": "llama-3.3-70b",
      "context_window": 131072,
      "rate_limit": "10 req/min per peer"
    },
    {
      "type": "run",
      "codes": ["mcnp", "openmc"],
      "queue_depth": 3,
      "max_wall_time": "4h"
    }
  ],
  "delegations": [
    {
      "domain": "reactor_physics.htgr",
      "delegate_to": "https://axiom.inl.gov",
      "relationship": "partner",
      "trust_level": "bilateral"
    }
  ]
}
```

**Key HTTP patterns used:**
- `Cache-Control` + `ETag` — standard HTTP caching. Resolvers cache
  capability responses and use conditional requests (`If-None-Match`)
  to revalidate. No custom TTL system needed.
- `Vary` — responses vary by classification ceiling and auth context.
  A public query gets different capabilities than a restricted query.
  Standard HTTP content negotiation.
- `Authorization` — federation capability tokens (Ed25519-signed JWTs).
  Standard bearer token pattern.
- Custom `X-Axiom-*` headers — the agent-specific extensions. Intent,
  classification ceiling, maturity floor, authority, trust path.

#### Knowledge Authority Endpoint

```http
GET /.well-known/axiom-authority?domain=reactor_physics.fuel_cycle.triso HTTP/2
Authorization: Bearer <token>

HTTP/2 200 OK
Cache-Control: max-age=3600
X-Axiom-Authority: @rascal:ut-austin
X-Axiom-Delegation: true

{
  "authoritative": false,
  "delegation": {
    "domain": "reactor_physics.fuel_cycle.triso",
    "authority": "https://axiom.inl.gov",
    "authority_identity": "@triso-lab:inl",
    "relationship": "partner",
    "trust_path": ["@rascal:ut-austin", "@axiom:inl"],
    "cached_at": "2026-04-16T10:00:00Z",
    "cache_ttl": 3600
  }
}
```

This IS recursive resolution: "I'm not authoritative for
`fuel_cycle.triso`, but INL is, and here's how to reach them." The
requesting node can then query INL directly, or ask the delegating
node to proxy (like a recursive DNS resolver).

#### Negative Response (Authoritative "Not Found")

```http
GET /.well-known/axiom-authority?domain=reactor_physics.fusion HTTP/2

HTTP/2 404 Not Found
Cache-Control: max-age=86400
X-Axiom-Authority: @rascal:ut-austin
X-Axiom-Authoritative-Negative: true

{
  "domain": "reactor_physics.fusion",
  "status": "not_found",
  "authoritative": true,
  "message": "This node is authoritative for reactor_physics.* and confirms no fusion domain exists in this federation.",
  "cached_until": "2026-04-17T10:00:00Z"
}
```

Standard HTTP 404 + cache headers. The `X-Axiom-Authoritative-Negative`
header signals this is a signed negative response (like DNS NXDOMAIN
with NSEC), not a connectivity failure. Resolvers cache this to avoid
repeated queries for nonexistent domains.

### 4.4 The Delegation Chain (DNS zone delegation, but for capabilities)

```
                    Federation Root
                    (consortium authority)
                         |
             +-----------+-----------+
             |                       |
        ut-austin                   inl
     (authoritative for          (authoritative for
      reactor_physics.msr,       reactor_physics.htgr,
      education.*)               fuel_cycle.triso.*)
             |                       |
      +------+------+               |
      |             |               |
  rascal         classroom      triso-lab
  (server,       (ephemeral,    (server,
   restricted)    public)        restricted)
```

Each level in this tree maps to:
- A DNS zone with SRV + TXT records (for the base discovery layer)
- An HTTP endpoint serving `/.well-known/axiom-authority` (for the
  rich resolution layer)
- A signed membership manifest (for the trust layer)

Resolution walks this tree:
1. Query arrives at leaf node: "Who has TRISO fuel performance data?"
2. Leaf checks local capabilities → not authoritative
3. Leaf queries its coordinator (ut-austin) → not authoritative, but
   knows INL is (delegation record, cached)
4. Response: delegate to `https://axiom.inl.gov` with trust path
5. Requesting node queries INL directly (or asks ut-austin to proxy)
6. INL responds with capability details + access requirements
7. All intermediate responses cached with appropriate TTL

### 4.5 Intent-Aware Resolution (the model-mediated layer)

DNS resolution is pure name→address. Axiom resolution adds an
**intent** dimension: the same domain resolves differently depending
on what the requester is trying to do.

This is where the RAG retrieval policy (from the prior design
session) connects to the resolution protocol:

| Intent | Resolution Behavior | HTTP Expression |
|---|---|---|
| `lookup` | Resolve to nearest node with exact-match capability. Short-circuit, no fan-out. | `X-Axiom-Intent: lookup` → response includes single best source |
| `synthesis` | Resolve to ALL nodes with relevant capability. Fan-out. | `X-Axiom-Intent: synthesis` → response includes all sources + weights |
| `diagnosis` | Resolve to nodes with graph-capable RAG + operational data. | `X-Axiom-Intent: diagnosis` → response filtered to graph + facility sources |
| `teaching` | Resolve to nodes with education-tier content, maturity ≥ frameworks. | `X-Axiom-Intent: teaching` → response filtered by maturity + pedagogy flag |
| `operations` | Resolve to local facility RAG only. No federation fan-out. | `X-Axiom-Intent: operations` → response restricted to local |
| `research` | Resolve to all federated peers + all packs. Broadest scope. | `X-Axiom-Intent: research` → response includes all reachable sources |

Intent classification is model-mediated (Bonsai classifies the query).
The resolution protocol itself is deterministic — given an intent, the
delegation, filtering, and caching behavior is fully specified.

### 4.6 Classification-Aware Resolution (the security layer)

Every resolution request carries a classification ceiling (from the
principal's clearance and the federation domain). Every resolution
response carries a classification stamp (from the content).

```
Request:  X-Axiom-Classification-Ceiling: restricted
Response: X-Axiom-Classification-Stamp: restricted
          X-Axiom-Export-Control: EAR-99

→ Allowed (stamp ≤ ceiling, EAR-99 is unrestricted)

Request:  X-Axiom-Classification-Ceiling: public
Response: X-Axiom-Classification-Stamp: restricted

→ Filtered out (stamp > ceiling). The capability exists but is not
  visible to this principal at this classification level.
```

This is standard HTTP content negotiation extended to classification.
The `Vary: X-Axiom-Classification-Ceiling` header tells caches that
responses differ by classification context — a cache serving a public
query must not return a cached restricted response.

---

## 5) The Nine Gaps (and How to Close Them)

### Gap 1: Hierarchical Capability Naming

**Solution:** Use DNS-compatible hierarchical naming for knowledge
domains. Axiom's existing domain pack names become a namespace:

```
reactor_physics                    (top-level domain)
reactor_physics.msr                (subdomain)
reactor_physics.msr.fuel_salt      (sub-subdomain)
reactor_physics.fuel_cycle         (sibling subdomain)
reactor_physics.fuel_cycle.triso   (sub-subdomain)
education                          (separate top-level)
education.ne_fundamentals          (subdomain)
```

These names are used in:
- DNS TXT records (`auth=reactor_physics.msr`)
- HTTP authority queries (`?domain=reactor_physics.fuel_cycle.triso`)
- Domain pack manifests (`domain: reactor_physics.msr`)
- Resolution delegation records

The naming is **descriptive, not administrative**. It describes what
knowledge is about, not who owns it. Ownership is expressed through
authority delegation (which node is authoritative for which domain),
exactly like DNS NS records.

**What changes:** Domain pack names become dot-separated hierarchical
names. Current flat names (`reactor_physics`, `fuel_cycle`) gain
structure. Existing packs are updated.

### Gap 2: Recursive Resolution

**Solution:** Nodes operate in one of two resolution modes (like DNS):

- **Stub resolver** (leaf/edge nodes): Forwards unresolvable queries
  to its configured coordinator. Does not cache delegation records.
  Simplest possible implementation.

- **Recursive resolver** (standard/server/coordinator nodes): Walks
  the delegation chain itself, caches intermediate results, returns
  the final answer to the requester. Caches follow HTTP
  `Cache-Control` semantics.

The resolution algorithm:

```python
def resolve(query: ResolutionQuery) -> ResolutionResponse:
    # 1. Check local capabilities
    local = self.local_capabilities.match(query)
    if local:
        return ResolutionResponse(
            authoritative=True,
            source=self.identity,
            results=local,
            cache_control=CacheControl(max_age=300),
        )

    # 2. Check cache
    cached = self.cache.get(query)
    if cached and not cached.is_stale():
        return cached.with_header("X-Axiom-Cache: HIT")

    # 3. Check delegation records
    delegation = self.delegations.match(query.domain)
    if delegation:
        if self.mode == ResolverMode.STUB:
            # Return delegation, let requester follow it
            return ResolutionResponse(
                authoritative=False,
                delegation=delegation,
            )
        else:
            # Recursive: follow the delegation ourselves
            response = self.fetch(delegation.authority_url, query)
            self.cache.store(query, response)
            return response

    # 4. If coordinator exists, forward to coordinator
    if self.coordinator:
        return self.forward(self.coordinator, query)

    # 5. Authoritative negative (we're the end of the chain)
    if self.is_authoritative_for(query.domain_parent()):
        return ResolutionResponse(
            authoritative=True,
            status=404,
            negative=True,
            cache_control=CacheControl(max_age=86400),
        )

    # 6. Genuine unknown
    return ResolutionResponse(status=502, message="No resolution path")
```

**What changes:** `NodeRegistry` gains a delegation table.
`resource_selection.py` gains resolution logic. The coordinator role
(ADR-023) gains resolver responsibilities.

### Gap 3: Record Types for Agents

**Solution:** Multiple well-known endpoints, each serving a different
"record type." All are standard HTTP JSON responses.

| Endpoint | Record Type | DNS Analog | Content |
|---|---|---|---|
| `/.well-known/agent-card.json` | Identity | A/AAAA | Who this agent is (A2A standard, already exists) |
| `/.well-known/axiom-manifest.json` | Manifest | SOA | Node metadata (already exists) |
| `/.well-known/axiom-capabilities` | Capability | SRV | What this node can do, with parameters |
| `/.well-known/axiom-authority` | Authority | NS | What knowledge domains this node is authoritative for |
| `/.well-known/axiom-delegations` | Delegation | NS referral | "For domain X, ask node Y instead" |
| `/.well-known/axiom-trust` | Trust | DNSSEC chain | Signed attestation chain for this node's identity |
| `/.well-known/axiom-policy` | Policy | (no analog) | Data-flow policies for cross-federation sharing |

**What changes:** Three new well-known endpoints (capabilities,
authority, delegations). Trust and policy endpoints are Phase 2.

### Gap 4: TTL on Federated Knowledge

**Solution:** Use HTTP `Cache-Control` headers. No custom TTL system.

| Content Type | Cache-Control | Rationale |
|---|---|---|
| Capability advertisement | `max-age=300, stale-while-revalidate=60` | Capabilities change slowly; 5-minute cache is fine |
| Knowledge authority | `max-age=3600` | Authority delegation changes rarely |
| Delegation records | `max-age=86400` | Delegation topology is very stable |
| Negative responses | `max-age=86400` | "This doesn't exist" is stable |
| Operational data (facility status) | `max-age=60` | Changes frequently |
| Domain pack generation | `max-age=604800, must-revalidate` | Changes on pack rebuild only |
| Trust attestations | `max-age=86400` | Matches membership manifest TTL (ADR-024 §3) |

Nodes use standard HTTP conditional requests (`If-None-Match` with
ETags, `If-Modified-Since`) to revalidate cached responses. No new
caching infrastructure — HTTP libraries handle this.

**What changes:** All federation HTTP responses gain `Cache-Control`
and `ETag` headers. Existing heartbeat (10s) and manifest sync remain
for operational state; HTTP caching applies to resolution queries.

### Gap 5: Negative Caching

**Solution:** HTTP 404 + `X-Axiom-Authoritative-Negative: true` header
+ `Cache-Control: max-age=86400`.

Resolvers distinguish three failure modes:

| HTTP Status | Meaning | Cacheable? | Action |
|---|---|---|---|
| 404 + `Authoritative-Negative: true` | "I am authoritative and this doesn't exist" (NXDOMAIN) | Yes, long TTL | Cache negative, don't retry |
| 404 (no authoritative header) | "I don't have this but I'm not authoritative" | No | Try delegation chain |
| 403 | "This exists but you're not authorized" (NODATA) | Yes, per-principal | Different from "not found" — content exists at higher tier |
| 502/504 | "I can't reach the authority" (SERVFAIL) | No | Retry later, use stale cache if available |

**What changes:** Resolution responses gain the
`X-Axiom-Authoritative-Negative` header. Resolver cache stores
negative entries.

### Gap 6: Anycast / Locality-Aware Resolution

**Solution:** Weighted capability responses with preference signals.
Maps to DNS SRV priority/weight fields.

When multiple nodes serve the same knowledge domain, the authority
response includes all of them with routing hints:

```json
{
  "domain": "reactor_physics.msr",
  "providers": [
    {
      "node": "@rascal:ut-austin",
      "priority": 10,
      "weight": 100,
      "generation": 5,
      "latency_hint_ms": 20,
      "relationship": "cluster"
    },
    {
      "node": "@msr-node:ornl",
      "priority": 20,
      "weight": 50,
      "generation": 4,
      "latency_hint_ms": 85,
      "relationship": "partner"
    }
  ]
}
```

The requesting node selects based on `resource_selection.py`'s
existing weighted scoring (capability, proximity, availability,
affinity, cost). This is the same selection algorithm, fed by
resolution responses instead of the flat `KnownNode` registry.

**What changes:** Resolution responses include priority/weight fields
matching DNS SRV semantics. `resource_selection.py` consumes these.

### Gap 7: Reverse Lookup ("Who provides this capability?")

**Solution:** Query parameter on the capabilities endpoint.

```http
GET /.well-known/axiom-capabilities?reverse=true&type=run&code=mcnp HTTP/2

HTTP/2 200 OK
{
  "query": {"type": "run", "code": "mcnp"},
  "providers": [
    {"node": "@rascal:ut-austin", "queue_depth": 3},
    {"node": "@hpc:inl", "queue_depth": 0}
  ]
}
```

Only coordinator nodes serve reverse lookups (they aggregate
capability advertisements from their zone). Leaf nodes forward
reverse queries to their coordinator.

**What changes:** Coordinator role gains reverse-lookup aggregation.
Capabilities endpoint gains `?reverse=true` query parameter.

### Gap 8: Root of Trust

**Solution:** Leverage ADR-022 and ADR-024. The federation root
(threshold-signed, FROST) IS the resolution root. The root's public
key is the trust anchor for the entire delegation chain, just as the
DNS root key is the DNSSEC trust anchor.

For different federation types:

| Federation Type | Root Authority | Bootstrap |
|---|---|---|
| Academic consortium | Founding members (TRIGA: UT, OSU, INL) with k-of-n threshold signing | Hardcoded root public key in first invitation |
| Institutional | IT department's existing PKI | Root key derived from institutional CA |
| Classroom (ephemeral) | Instructor's node | Instructor key is root; students join via invitation |
| Gov/industry | DOE/agency PKI | Root key from agency certificate chain |
| Cross-sector bridge | Bilateral: each side's root signs the bridge | Bridge key pair signed by both roots |

**What changes:** Nothing new — ADR-022 and ADR-024 already design
this. The resolution protocol explicitly uses the federation root as
its trust anchor. Resolution responses include the trust path back
to the root (like DNSSEC's chain of signatures).

### Gap 9: Glue Records (Bootstrap Without Circular Dependencies)

**Solution:** The federation invitation token (already implemented in
`trust.py`) IS the glue record. It contains everything needed to
bootstrap resolution without depending on resolution:

```python
@dataclass
class InvitationToken:
    token: str                    # CSPRNG, single-use
    issuer_node_id: str          # Who issued this
    issuer_display_name: str     # Human-readable
    # --- glue fields (new) ---
    issuer_endpoint: str         # Direct URL (no resolution needed)
    issuer_public_key: str       # Ed25519 pubkey (no trust chain needed)
    federation_root_key: str     # Root public key (trust anchor)
    created_at: datetime
    expires_at: datetime
```

The invitation carries the issuer's endpoint and public key directly
(glue), plus the federation root key (trust anchor). The joining node
can verify the issuer's identity and reach them without any prior
resolution infrastructure. After joining, normal resolution takes over.

**What changes:** `InvitationToken` gains three fields (endpoint,
public key, root key). These are the DNS glue records equivalent.

---

## 6) Integration with Existing Axiom Architecture

### 6.1 What This Replaces

| Current Component | Becomes | Why |
|---|---|---|
| Flat `KnownNode` registry (nodes.yaml) | Resolution cache + delegation table | Resolution is richer than a flat peer list |
| Manual `axi federation add <url>` | Still works, but now registers a delegation hint | Explicit registration becomes one of several discovery paths |
| Resource selection fan-out to all peers | Resolution-guided selection (query the delegation chain first, then select from resolved providers) | Don't query every peer for every request |

### 6.2 What This Extends

| Current Component | Extension | Why |
|---|---|---|
| `/.well-known/axiom-manifest.json` | Gains link to capabilities + authority endpoints | Manifest is the "glue" that points to richer resolution endpoints |
| `/.well-known/agent-card.json` | Unchanged (A2A standard) | Agent Cards remain the identity layer; resolution is the capability layer |
| mDNS discovery | Remains for LAN discovery (Phase 0). DNS SRV for WAN. | mDNS is the right tool for local; DNS SRV for institutional |
| Domain pack manifests | Gain hierarchical domain names + authority claims | Pack names become resolution-compatible names |
| Trust profiles | Extend to resolution context (trust profile determines classification ceiling, maturity floor, federation scope for resolution queries) | Same profiles govern RACI approvals AND resolution filtering |
| `resource_selection.py` | Consumes resolution responses instead of flat peer list | Selection algorithm stays; input source changes |

### 6.3 What This Enables (the RAG connection)

The retrieval policy engine (from the prior design session) becomes a
consumer of the resolution protocol:

```
User query
  → Bonsai classifies intent (model-mediated)
  → Trust profile provides constraints (classification ceiling,
    maturity floor, federation scope)
  → Principal provides identity (clearance, affiliation)

Resolution query = (intent, domain, constraints, principal)
  → Resolution protocol walks delegation chain
  → Returns: list of (source, capability, priority, weight,
    trust_path, cache_control)

Retrieval policy engine selects from resolved sources:
  → Which sources to query (based on intent + resolution results)
  → Which strategy per source (vector, graph, hybrid)
  → Which parameters (top-k, reranking weights, maturity filter)

Retrieval executes against selected sources
  → Results aggregated with provenance
  → Classification gate filters results post-retrieval
  → Bonsai generates grounded response with per-source citations
```

The resolution protocol is the bridge between "I have a query" and
"here are the right sources to answer it." Without it, the retrieval
policy has to maintain its own registry of available sources — which
is just reinventing resolution.

---

## 7) What Changes, What Stays

### Stays Unchanged

- Ed25519 identity model (ADR-020, ADR-022)
- A2A Agent Cards for agent identity
- Invitation-based trust bootstrap (enhanced with glue fields)
- Heartbeat daemon for operational state
- mDNS for LAN discovery
- Membership manifests with monotonic sequence + TTL (ADR-024)
- Trust profiles and RACI model
- Classification boundary spec (all 13 scenarios, 10 invariants)
- TRIAGE security service
- Node profiles (edge/workstation/server/platform)

### Changes

| Component | Current | New |
|---|---|---|
| Node discovery | Flat registry (KnownNode list) | Delegation-aware resolution cache |
| Capability advertisement | Implicit in manifest | Explicit endpoints with HTTP caching |
| Knowledge authority | Not formalized | Authority endpoint + delegation chain |
| Domain pack naming | Flat (`reactor_physics`) | Hierarchical (`reactor_physics.msr.fuel_salt`) |
| Cross-node queries | Fan-out to all known peers | Resolution-guided: resolve authority first, then query |
| Coordinator role | Election + gossip (spec'd, not built) | Adds: authoritative resolver for its zone |
| Federation join | Invitation token | Invitation token + glue fields (endpoint, pubkeys, root key) |
| Resource selection | Scores all known peers | Scores resolved providers (subset of all peers) |

### New Components

| Component | Description | Size |
|---|---|---|
| `resolution.py` | Core resolver: local lookup, cache check, delegation follow, recursive resolution | ~300 lines |
| `delegation.py` | Delegation table: domain → authority mapping, loaded from authority endpoint responses | ~100 lines |
| `resolution_cache.py` | HTTP-semantics cache: respects Cache-Control, ETag, Vary | ~200 lines |
| Capabilities endpoint | `/.well-known/axiom-capabilities` handler | ~150 lines |
| Authority endpoint | `/.well-known/axiom-authority` handler | ~100 lines |
| DNS SRV registration | Helper to generate SRV + TXT records for institutional DNS | ~50 lines (utility) |

Total new code: ~900 lines. This is a thin layer — the complexity
lives in the existing federation infrastructure.

---

## 8) Phased Implementation

Each phase is independently valuable (per standing rule).

### Phase 1: Local Resolution + Capability Endpoints

**Delivers:** Nodes advertise capabilities via HTTP. Resolution works
locally (no delegation yet). Retrieval policy engine can query local
capabilities programmatically instead of hardcoded knowledge.

- [ ] `/.well-known/axiom-capabilities` endpoint (serves local capabilities)
- [ ] `resolution.py` with local-only resolution (steps 1-2 of algorithm)
- [ ] `resolution_cache.py` with HTTP Cache-Control semantics
- [ ] Domain pack names become hierarchical
- [ ] `resource_selection.py` consumes resolution responses
- [ ] Tests: 20+ covering local resolution, caching, capability matching

**Why this is valuable alone:** Even without federation, a single node
can resolve its own capabilities programmatically. The retrieval
policy engine has a clean API to discover what's available locally.
Bonsai can answer "what can this node do?" from the capabilities
endpoint rather than hardcoded knowledge.

### Phase 2: Delegation + Recursive Resolution

**Delivers:** Nodes can delegate knowledge domains to peers.
Resolution walks the delegation chain. Cross-federation capability
queries resolve through intermediaries instead of fan-out.

- [ ] `/.well-known/axiom-authority` endpoint (serves authority + delegations)
- [ ] `delegation.py` delegation table
- [ ] Recursive resolution (steps 3-6 of algorithm)
- [ ] Negative caching (authoritative 404)
- [ ] Invitation token gains glue fields
- [ ] Coordinator gains resolver role (serves zone-level authority)
- [ ] Tests: 30+ covering delegation chains, negative caching, recursive resolution

**Why this is valuable alone:** Cross-node queries become targeted
instead of broadcast. A node asking "who has TRISO data?" gets a
delegation to INL rather than querying every peer. Scales from
O(n) fan-out to O(log n) delegation walks.

### Phase 3: DNS SRV Integration + Anycast

**Delivers:** Institutional DNS zones advertise axiom capabilities.
Multiple providers for the same domain get priority/weight routing.

- [ ] DNS SRV + TXT record generation utility
- [ ] DNS-SD integration for institutional WANs
- [ ] Priority/weight fields in resolution responses
- [ ] Locality-aware provider selection
- [ ] Reverse lookup on coordinator nodes
- [ ] Tests: 15+ covering DNS integration, multi-provider routing

**Why this is valuable alone:** Nodes on institutional networks
discover federation peers via standard DNS, with no manual
configuration. IT departments can manage axiom service discovery
alongside all their other DNS records.

### Phase 4: Cross-Federation Data Flow Policies

**Delivers:** When content crosses federation boundaries, data-flow
policies travel with it. The receiving node enforces the policy
deterministically.

- [ ] `/.well-known/axiom-policy` endpoint
- [ ] Policy document format (inspired by Substrate CPAC, simplified)
- [ ] Policy enforcement at federation ingestion boundary
- [ ] Ed25519-signed capability tokens for cross-federation access
- [ ] Tests: 20+ covering policy enforcement, token validation

**Why this is valuable alone:** Cross-federation data sharing gets
formalized access controls beyond the current three-tier model.
Essential for the classified/export-control scenarios (S4-S7 in
spec-classification-boundary.md).

---

## 9) Open Questions

### 9.1 Domain Namespace Governance

Who decides that `reactor_physics.msr` is a valid domain name? Options:
- **Convention-based** (like early DNS): founding members agree on
  top-level domains, sub-domains are per-institution
- **Registry-based** (like ICANN): a consortium maintains the
  namespace registry
- **Emergent** (like hashtags): anyone can claim a domain, authority
  is established by usage and trust

Recommendation: Convention-based for Phase 1. The TRIGA founding
members define the initial namespace. Extensions can register
sub-domains. Governance formalizes later if needed.

### 9.2 Resolution vs. A2A Tasks

A2A already has a task model (create task, get status, cancel).
Should resolution be expressed as A2A tasks, or as a separate
protocol? Arguments:

- **As A2A tasks:** Consistent with existing agent communication
  patterns. Resolution is "just another task type." But A2A tasks
  are heavyweight for what is essentially a lookup.
- **As HTTP endpoints:** Lightweight, cacheable, stateless. Fits
  the DNS analogy better. But introduces a second communication
  channel alongside A2A.

Recommendation: HTTP endpoints for resolution (stateless lookups),
A2A tasks for operations that result from resolution (e.g., "run
this MCNP simulation on the node I just resolved"). Resolution is
infrastructure; tasks are application-level.

### 9.3 How Deep Does the Hierarchy Go?

`reactor_physics.msr.fuel_salt.fluoride.flibe` — how many levels?
DNS allows 127 levels but practically uses 3-5. For knowledge
domains:

Recommendation: Limit to 4 levels. Top-level (discipline) → domain
→ sub-domain → specific. Deeper specificity is expressed through
content metadata, not domain naming.

### 9.4 Compatibility with Substrate TAP

If Substrate evolves independently, should Axiom maintain
compatibility? TAP agents ARE A2A agents, and Axiom agents ARE A2A
agents, so the base interop layer exists. The question is whether
Axiom should implement DADP or the HTTP-native approach described
here.

Recommendation: Axiom implements the HTTP-native approach (this
document). If DADP matures and gains adoption, Axiom can add a
DADP adapter that translates between DADP queries and Axiom's
HTTP endpoints. Don't couple to DADP's evolution — but don't
preclude it either.

### 9.5 Classroom as Resolution Micro-Federation

A classroom is an ephemeral federation where the instructor's node
is the root authority. How does resolution work at this scale?

Recommendation: The instructor node is both root and sole
coordinator. Students are stub resolvers. All resolution queries
go to the instructor node. No delegation, no recursion — just
direct lookup. The resolution protocol degenerates gracefully
to a simple client-server pattern at small scale. The same code
handles both, which means students graduating to research
federation don't learn a new system.

---

## Appendix: Substrate TAP Decision Log

For each TAP component, the adopt/skip decision and full reasoning.
Preserved for future reference if TAP evolves.

| Component | Decision | Reasoning | Revisit If... |
|---|---|---|---|
| DADP | Adapt (as HTTP-native resolution) | The *need* is real (distributed capability discovery). The *implementation* should use DNS + HTTP, not a parallel protocol. | DADP gains significant adoption and tooling |
| CPAC | Adopt (simplified as data-flow policies) | Policy-travels-with-content is a genuine gap in Axiom. But the full CPAC spec is over-engineered for Axiom's context. | Cross-industry federation scenarios emerge |
| CBAC | Adopt (as Ed25519-signed capability tokens) | Cross-federation authz tokens are needed. Existing OAuth/OpenFGA doesn't span federation boundaries. | A standard emerges for cross-org capability tokens |
| MASR | Skip | Axiom doesn't need model switching. Gateway handles LLM routing. | Axiom supports user-facing model choice |
| MAMA | Skip | Knowledge maturity model is superior for this domain. | Axiom's agent memory needs outgrow the maturity model |
| BAAT | Skip | Ed25519 signed chains are sufficient. Blockchain adds cost without proportional trust benefit in academic/gov context. | Regulatory requirements demand blockchain-grade immutability |
| VITAL | Extract kernel only (trust inheritance semantics) | Trust inheritance is useful. Blockchain anchoring is not. Express as signed attestation claims. | Agent ecosystem grows to need formal provenance tracking |
| OASIS | Skip | ADR-020 + ADR-022 solve this with InCommon/PIV/CAC. | Axiom fedrates with commercial entities outside academic/gov |
| SubCert | Skip | Trust profiles + validated classification replace commercial certification. | Marketplace/ecosystem model emerges for axiom extensions |
_Copyright (c) 2026 The University of Texas at Austin and B-Tree Labs. Apache-2.0 licensed._
