AGENTS.md · git:20261005.84767bc · 2026-10-05 · sha256 71a996c75825b889

AGENTS.md git:20261005.84767bcA

Immutable. This exact content never changes and is served at /api/v1/blob/71a996c75825b889.

# x0x

Agent-to-agent gossip network for AI systems. Built on `ant-quic` (QUIC with
post-quantum crypto and NAT traversal) and `saorsa-gossip` (epidemic broadcast,
CRDT sync, pub/sub). Shipped as the `x0x` crate, the `x0xd` daemon (local REST +
WebSocket API) and the `x0x` CLI. Non-Rust apps talk to `x0xd` over HTTP; there
are no FFI bindings.

## Reference docs (read when relevant)
- REST + WebSocket API: `docs/api-reference.md`
- Tests, e2e harnesses, VPS ports: `tests/AGENTS.md`, `TEST_SUITE_GUIDE.md`
- Self-update: `docs/upgrade-system.md` · CI/CD: `docs/cicd.md`
- Trust, connectivity, announcements: `docs/trust-and-connectivity.md`
- Remote exec + ACL: `docs/exec.md`, `docs/design/x0x-exec.md` · Connect ACL: `docs/connect-acl.md`
- Signed-KV legacy compatibility: `docs/legacy-compat.md`
- Named groups: `docs/design/named-groups-full-model.md` · Symphony: `docs/symphony-integration.md`
- Non-Rust integration: `docs/local-apps.md`

## Build and test
- `just --list` for recipes. Local format, lint and docs checks (a subset of CI):
  `cargo fmt --all -- --check`,
  `cargo clippy --all-targets --all-features -- -D warnings`, and
  `RUSTDOCFLAGS="-D warnings" cargo doc --all-features --no-deps`.
  Passing them is not a full preflight. The `main` ruleset requires the
  Format Check, Clippy Lint, Test Suite, Documentation and Build linux-x64-gnu
  checks, and CI also runs coverage, parity, integration and
  deployment-authority jobs; see `.github/workflows/` for the full set.
- `ant-quic` and `saorsa-gossip-*` are exact-pinned (`=`) crates.io versions in
  `Cargo.toml`, and `Cargo.lock` is tracked. CI and release builds use
  `--locked`, so a dependency bump is a deliberate `Cargo.toml` + `Cargo.lock`
  change. Local work against sibling checkouts (`../ant-quic`, `../saorsa-gossip`)
  needs a temporary `[patch]`, which must not be committed.
- **Running tests needs isolation.** Test daemons join the real network, so test
  execution only runs inside a fresh loopback-only Linux network namespace with
  dropped privileges; macOS/Windows fail closed. Use `just test` / `just test-full`
  or `python3 scripts/dev/test-isolated.py nextest --all-features -- -E 'test(identity)'`
  (contract: `nextest <build flags> -- <runtime flags>`). Plain `cargo test` /
  `cargo nextest run` bypasses the isolation — only use it on a selector you've
  confirmed is inert. Evidence lands in `target/dev-isolation/run-*`.
- Linux cross-build: `cargo zigbuild --release --target x86_64-unknown-linux-gnu --bin x0xd`.

## Architecture

Identity is three layers; every ID is SHA-256 of an ML-DSA-65 public key:
- **Machine** (`~/.x0x/machine.key`, auto-generated) — QUIC transport identity; equals the ant-quic PeerId.
- **Agent** (`~/.x0x/agent.key`, auto-generated) — portable across machines.
- **User** (`~/.x0x/user.key`) — optional human identity, **never auto-generated**; issues an `AgentCertificate` binding agent to user.

Keys are bincode-serialized via `storage.rs`, not JSON.

Stack, bottom to top:
1. `network.rs` — wraps `ant_quic::Node`, implements `GossipTransport`. ant-quic owns mDNS, UPnP, bootstrap cache and connection orchestration.
2. `bootstrap.rs` — retry/backoff for the hard-coded seed hints. `DEFAULT_BOOTSTRAP_PEERS` is defined in `network.rs`; it lists UDP/443 first (preferred, traverses networks that block higher UDP ports) and keeps UDP/5483 for pre-ADR-0011 clients. Seeds are hints only.
3. `gossip/` — thin orchestration over `saorsa-gossip-*`; `GossipRuntime` owns `PubSubManager`.
4. `presence.rs` — beacons on the Bulk stream, phi-accrual failure detection, FOAF discovery with trust-scoped visibility.
5. `crdt/` (task lists), `kv/` (replicated KV with access policies), `mls/` (group encryption), `groups/` (named groups; DHT-free discovery via social propagation, BLAKE3 tag shards and presence). Deltas of a group-scoped task list (`x0x.group.<gid>.symphony.<lid>`) in an `MlsEncrypted` group are sealed with the group's current GSS/TreeKEM key, like group KV stores (`crdt/sealed.rs`, #895); personal lists and `SignedPublic` groups stay plaintext.
6. `server/` + `api/` — `x0xd` REST/WS; `src/api/mod.rs` is the shared endpoint registry that keeps routes and CLI subcommands (`src/cli/`) in sync. `gui/` is embedded HTML via `include_str!`.

Errors: `IdentityError`, `NetworkError`, `PresenceError` in `error.rs`.
`lib.rs` allows `unwrap_used`/`expect_used` crate-wide for tests; production paths still use `?`.

`x0x exec` is off unless the exec ACL (`/etc/x0x/exec-acl.toml`, macOS `/usr/local/etc/x0x/exec-acl.toml`) sets `[exec].enabled = true`.

`x0xd` flags worth knowing: `--name` (multi-instance), `--api-port`,
`--no-hard-coded-bootstrap` (config peers kept), `--relay`, `--check`, `--doctor`.
Example: `x0xd --name alice --api-port 12701 --no-hard-coded-bootstrap`.

## Documentation and communication

Use approximately 80% ASD-STE100 style in ADRs, docs, PR text, review notes,
and communication with David. Use short sentences, common words, clear actions
and consistent terms. Keep necessary technical terms and exact guarantees.
Do not claim formal compliance. Follow `docs/documentation-style.md`.

## Architecture decisions (ADRs)
Before changing architecture, protocols, storage formats, crypto, network
behaviour, public APIs or operational invariants, check `docs/adr/` and its
status overlay. Already assigned numbered ADR work uses `docs/adr/TEMPLATE.md`
during transfer. New decisions use the fixed slots below. Accepted ADRs are
immutable. Supersede them instead. Only a human marks an ADR Accepted.

The consolidated direction uses 15 fixed slots, A01 through A15. Read
`docs/adr/consolidated/README.md` before adding a decision. Do not create A16
or a new general ADR series. Use a proposed revision of the relevant slot.
Keep already assigned numbered ADR work on its existing review lane during
transfer. The old accepted records, overlay, frozen evidence and team gates
stay in force until the replacement transfer and human acceptance are complete.
Run `python3 scripts/check-adr-consolidation.py` for the transition checks.