diff --git a/AGENTS.md b/AGENTS.md
index 8c206de..38592fd 100644
--- a/AGENTS.md
+++ b/AGENTS.md
@@ -50,6 +50,6 @@
- Roles are not exclusive: a single node may issue queries and answer them concurrently (I5, §3 "any member"). Implement querier/responder as independent enable flags — never an exclusive mode enum or fixed deployment role.
- Matching floor: boundary tokenizer (`src/tokenizer.rs` — letter/digit splits so `5555` matches `DLEX5555`, lowercase, ASCII fold, English stopwords+stemmer) → coverage gate (`[match] min_coverage`, default 0.4; 1–2 term queries require all terms) → title boost 2.0 + phrase boost 3.0 + query-time snippets. Schema changes require a fresh index dir (`open_or_create` errors on mismatch).
- Engine seam: `src/engine.rs` `SearchEngine` trait (`search` → `EngineOutput { hits, total: Option }`, `doc_count`); `respond()` in `src/node.rs` is the conformance wrapper (budget clamp, truncation from engine total — unknown total forces `truncated = true`). Power users can implement the trait (HTTP adapter or subprocess to an external engine).
-- Onboarding: `frxd --onboarding` runs a wizard consuming a credential block (`id=.. token=.. registry=.. ma_key=..`) issued by the MA's signup endpoint (`registry serve --signup-code --registry-url`; HTML page at `/`, `POST /v1/signup` → one-time invite token, `POST /v1/enroll` binds keys and re-signs). Identity registration stays MA-side; the wizard never creates identities, only binds locally generated keys. Invites live in `/invites.json`; the form's organization/representative/contact/payment fields are stored privately in `/applications.json` (mode 600, MA contract data — never in the signed snapshot), and the two acknowledgement checkboxes are required by the endpoint. Prompts accept empty input as the default; scripted stdin works for tests.
+- Onboarding: `frxd --onboarding` runs a wizard consuming a credential block (`id=.. token=.. registry=.. ma_key=..`) issued by the MA's signup endpoint (`registry serve --signup-code --registry-url`; HTML page at `/`, `POST /v1/signup` → one-time invite token, `POST /v1/enroll` binds keys and re-signs). Identity registration stays MA-side; the wizard never creates identities, only binds locally generated keys. Signup without a code queues a pending application (`/applications.json`, mode 600, MA contract data — never in the signed snapshot); `frxd registry approve ` promotes it (member stub + invite + credential block). A valid `--signup-code` approves immediately. Invites live in `/invites.json`. Prompts accept empty input as the default; scripted stdin works for tests.
- Next matching steps: eval harness with a small golden set (precision@k + false-silence rate), then a dense recall leg (model2vec-rs 0.2.1 exists but needs `default-features = false, features = ["fancy-regex", "local-only"]` for musl/airgapped; verify crate + model licenses before bundling), then an optional cross-encoder reranker. Embeddings are for recall; reranking is the precision tier.
- Identity/registry (RFC Draft 0.5 §4/§6): MA-hosted FQDN identifiers first (`
1. Register with the membership authority
-
Registering here creates your identifier with the membership authority (MA); the
-onboarding wizard in step 4 then binds your node's keys to it. The public registry publishes only
-your identifier, class, keys, and the federation's relays. The organization details below are kept
-privately by the MA for the membership contract — they are never published and never travel on the
-wire.
+
This form requests membership from the membership authority (MA). The MA reviews
+your organization details and issues a credential block
+(id=... token=... registry=... ma_key=...); the onboarding wizard in step 4 then
+binds your node's keys to the identifier. The public registry publishes only your identifier,
+class, keys, and the federation's relays. The organization details below are kept privately by
+the MA for the membership contract — never published, never on the wire.