# AgentNet v0.1.50 Setup Usability Design

**Status:** Approved direction, implementation candidate  
**Affected requirements:** ID-006, COM-001, COM-002, COM-009, AVL-003, AVL-005, AVL-006, UX-001, UX-002, SEC-003, SEC-005, OPS-003, OPS-006  
**Owner/gate dependencies:** PD-002, PD-009, PD-010 and every must-not-ship gate remain blocked; this change does not promote evidence.

## Goal

Make the existing secure setup path practically usable without weakening its identity, approval, or fail-closed boundaries:

- one pasted command on the server;
- one pasted command on the laptop;
- one required browser OIDC/passkey journey;
- automatic resume after interruption;
- direct upgrade from a supported installed release to v0.1.50 with one package update;
- first bidirectional message and exact acknowledgement as the terminal success proof;
- fresh server ready within 10 minutes and laptop enrollment plus first message within 5 minutes when the human completes the browser step promptly;
- release gate exercised across two isolated virtual machines.

No dashboard work, new protocol, new authority model, or new infrastructure abstraction is in scope.

## Product commands

The public package remains `@misunders2d/agentnet`; `agentnet` remains the only executable. Installation and operation may be joined by `&&`, so the operator pastes once while each process still fails independently.

### Server

```bash
sudo npm install --global @misunders2d/agentnet@0.1.50 --ignore-scripts --no-audit --no-fund && sudo agentnet server-agent setup --apply --start
```

With no `--request`, setup enters package-owned guided mode. It obtains the exact request from, in order:

1. the current signed/package-owned setup marker and retained input provenance for an upgrade;
2. the standard root-only AgentNet configuration locations for a fresh host;
3. a bounded terminal prompt for missing owner-selected values only.

It derives canonical audiences, runtime IDs, paths, package digests, service users, and request digests itself. It never asks for UUIDs, database row IDs, schema values, JSON documents, state paths, credential IDs, or separate plan/apply commands.

Before managed-host mutation, the same process renders one concise frozen plan and requests one explicit terminal approval. It then applies that exact digest and starts the five managed units. Existing `--request` plan/apply behavior remains for automation and forensic operation.

### Laptop

The server's terminal result prints the exact public Core origin and this copyable command:

```bash
npm install --global @misunders2d/agentnet@0.1.50 --ignore-scripts --no-audit --no-fund && agentnet join guided --server https://core.example.invalid
```

Only the server origin is supplied because it names the network being joined. Core discovery supplies the trust domain and supported enrollment profile. The launcher derives harness kind from its measured host adapter, uses the local hostname only as a display-name proposal, selects owner-only default state/key/identity paths, opens the system browser, and uses the five-minute setup deadline.

Explicit `--domain`, `--harness`, `--name`, `--state`, `--private-key`, `--identity`, `--browser`, and `--timeout` options remain available and override derived presentation/configuration values without changing authority semantics.

## Server state machine

Guided server setup is a thin orchestrator over the existing strict setup implementation, not a second installer.

1. **discover** — identify installed package, current marker, retained source provenance, PostgreSQL/TLS/OIDC prerequisites, and supported transition.
2. **plan** — build the existing immutable `ServerSetupRequest` and exact request digest without managed-host writes.
3. **approve** — show the bounded plan and obtain one terminal confirmation unless a previously approved identical attempt is resumable.
4. **apply** — execute existing atomic writes, package-owned systemd units, database checks, and direct migration chain.
5. **enroll** — preserve a current enrolled server identity or resume the exact owner OIDC/passkey ceremony; never silently replace a nonterminal identity.
6. **activate** — resolve the exact completed C0 harness pair and establish permanent communication scope using current canonical identity rows.
7. **verify** — prove all five units healthy, exact package provenance active, PostgreSQL schema current, server identity enrolled, and communication usable.

No second orchestration journal is introduced. Existing owner-only guided state, setup marker, upgrade journal, managed configuration, and database state are the canonical resumable records. A rerun reconstructs its current phase from those records and revalidates exact bytes before continuing.

## Direct upgrade

One installed v0.1.50 runtime may upgrade any explicitly supported marker in the maintained v0.1.45–v0.1.49 window. The operator does not install intermediate npm packages.

Because v0.1.45–v0.1.49 share the same schema-v7 and five-unit topology, v0.1.50 uses one explicitly allowlisted source-marker-to-v0.1.50 transition rather than pretending to execute intermediate package migrations. The existing forward-only journal validates the exact source marker, schema, unit profile, request/input provenance, and target package before the public marker advances. A crash resumes the same journaled transition. Unknown, ambiguous, missing, downgraded, or unsupported state fails closed before service restart.

Rollback remains package/state restoration from an operator-approved backup. Setup does not reverse database migrations or infer an older marker.

## Laptop state machine

1. **discover** — fetch authenticated Core discovery and derive domain/profile.
2. **prepare** — create or validate owner-only local state, candidate key, and identity paths.
3. **authenticate** — open OIDC in the system browser.
4. **approve** — open the exact current AgentNet passkey approval URL.
5. **enroll** — atomically bind the verified human, exact harness, and credential.
6. **activate** — resume the exact permanent communication activation for the enrolled harness.
7. **roundtrip** — send one package-owned setup-check message to the authenticated ordinary server harness, receive its exact message, reply, and require exact custody acknowledgements in both directions.
8. **verify** — write the owner-only identity profile and return terminal success.

A rerun with identical arguments resumes the same pending transaction. If Core proves terminal `expired` or `failed`, guided mode replaces only that terminal transaction while reusing the candidate key. It never replaces on timeout, network loss, stale local logs, or an unverified browser page.

## Progress and blockers

Human-readable progress goes to stderr; the final machine-readable JSON remains on stdout. Each phase prints a stable name, elapsed time, and one current action. No secrets, raw IDs, message content, or browser tokens are printed.

Stable blockers include:

- `unsupported_upgrade_source`
- `missing_external_prerequisite`
- `plan_approval_required`
- `browser_authentication_pending`
- `passkey_approval_pending`
- `terminal_enrollment_replacement_required`
- `service_health_timeout`
- `communication_activation_blocked`
- `roundtrip_ack_timeout`
- `setup_deadline_exceeded`

Every blocker reports the responsible component, safe automatic action already taken, whether rerun resumes, and the single human action required, if any.

## Duration and recovery

- Server total deadline: 600 seconds.
- Laptop total deadline: 300 seconds.
- Every subprocess, HTTP wait, systemd transition, database wait, and message acknowledgement has a smaller explicit timeout.
- Human browser wait consumes the same total budget; timeout preserves resumable state.
- Retries use existing idempotency keys and exact attempt journals.
- A rerun never repeats a committed migration, creates a sibling credential, or sends a duplicate setup-check event.

Elapsed time uses a monotonic clock. Wall-clock timestamps are evidence only.

## Two-VM release gate

The v0.1.50 gate uses two fresh isolated Ubuntu 24.04 virtual machines on one private network:

- **server VM:** PostgreSQL 18, Node.js 24, uv, local TLS routes, synthetic workforce OIDC/passkey only for hermetic release evidence;
- **laptop VM:** Node.js 24, uv, a measured laptop harness, and no pre-existing AgentNet state.

Both install the candidate from independently packed npm bytes, not a source checkout. The gate runs the same public commands and asserts:

- one pasted command per VM;
- no manual JSON, IDs, state paths, or intermediate package versions;
- exactly one browser-equivalent approval journey;
- server deadline under 600 seconds;
- laptop deadline under 300 seconds;
- automatic activation;
- laptop-to-server and server-to-laptop messages;
- exact non-duplicate custody acknowledgements;
- no foreground-turn injection, secret output, manual repair, residual processes, or retained VM credentials after teardown.

A hermetic browser equivalent proves the package path but is not external WebAuthn/OIDC evidence. One separately retained live two-VM run with the real browser journey is required before claiming live usability; it does not promote PD-002 or production gates.

## Security invariants

- Discovery metadata narrows configuration but never grants identity or authority.
- Caller identity always comes from authenticated transport and exact credential proof, never CLI strings or discovery JSON.
- The server's plan approval authorizes only the displayed request digest.
- Automatic resume never means automatic approval of changed scope.
- Direct upgrades preserve PostgreSQL, enrollment, credentials, endpoints, mailbox state, and audit history.
- A package install response, browser success page, transport receipt, or A2A state never substitutes for enrollment, communication custody, or effect evidence.
- Protected content and reusable credentials never appear in progress, journals, or final output.
- Any mismatch, stale epoch, revoked credential, unsupported marker, missed deadline, or ambiguous outcome fails closed and remains safely resumable.
