From bd88f68dcda40406d0cbbdbdd0d50c1c1cc3f81b Mon Sep 17 00:00:00 2001 From: Claude Date: Thu, 23 Apr 2026 21:36:52 +0000 Subject: [PATCH] docs: point README / DEVELOPMENT / amy-expert at cli/tests/ MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit After the harness move from tools/marmot-interop/ to cli/tests/, three doc locations were still describing the old layout: - cli/DEVELOPMENT.md § Testing — the "round-trip" row pointed at a non-existent `cli/src/test/resources/scripts/`, and the "interop with other clients" row claimed it was out of scope. Both now name `cli/tests/marmot/` and `cli/tests/dm/` with what each covers, and the interop-script template points at the concrete test files rather than re-inventing a smaller example. - cli/README.md — the "For an interop-test script template" pointer now links to `cli/tests/README.md` alongside the DEVELOPMENT.md section. - .claude/skills/amy-expert/SKILL.md — the "Where things live" tree omitted the new `tests/` subtree entirely. Added it with a one-line description per suite. Also extended the wire-up checklist with a step 7: add a harness case when a new verb changes observable wire behaviour. No content changes elsewhere; just path corrections. --- .claude/skills/amy-expert/SKILL.md | 13 ++++++++++++- cli/DEVELOPMENT.md | 9 +++++++-- cli/README.md | 5 ++++- 3 files changed, 23 insertions(+), 4 deletions(-) diff --git a/.claude/skills/amy-expert/SKILL.md b/.claude/skills/amy-expert/SKILL.md index bf423a0250..1677296d17 100644 --- a/.claude/skills/amy-expert/SKILL.md +++ b/.claude/skills/amy-expert/SKILL.md @@ -104,9 +104,15 @@ Wire-up checklist: 4. Extend `printUsage()` in `Main.kt`. 5. Add the row to `cli/README.md`'s command table. 6. Update `cli/ROADMAP.md` — move the row from 🆕 / 📦 to ✅. +7. If the verb changes observable wire behaviour (a new event kind, + a new relay-routing rule, a new JSON discriminator), add a case + in the appropriate harness under `cli/tests/` — `cli/tests/marmot/` + for MLS flows, `cli/tests/dm/` for NIP-17, or a new sibling suite + if it's neither. If you change output shape: note it in the commit message, bump the -example in `README.md`, update any interop fixtures. +example in `README.md`, update any interop fixtures under +`cli/tests/`. ## Where things live @@ -116,6 +122,11 @@ cli/ ├── DEVELOPMENT.md # touch-the-code: architecture, conventions, testing ├── ROADMAP.md # parity matrix + ordered milestones ├── plans/ # dated design docs (use for new subsystems) +├── tests/ # end-to-end shell harnesses against a local relay +│ ├── lib.sh # shared logging + result tracking +│ ├── headless/ # shared amy wrappers + assertions +│ ├── marmot/ # MLS group-messaging interop (vs whitenoise-rs) +│ └── dm/ # NIP-17 DM interop (two amy clients) └── src/main/kotlin/…/cli/ ├── Main.kt # argv dispatch ├── Args.kt # flag parser diff --git a/cli/DEVELOPMENT.md b/cli/DEVELOPMENT.md index 2d5b990c2a..6b855761aa 100644 --- a/cli/DEVELOPMENT.md +++ b/cli/DEVELOPMENT.md @@ -197,8 +197,8 @@ Amy-specific layer still needs its own coverage: | Error / exit-code contract (bad args → 2, await timeout → 124, runtime → 1) | Table-driven tests invoking `main(argv)` with captured stdout/stderr. | | JSON output shape (each command's keys and types) | Snapshot tests: run a command against a throwaway data-dir, assert the JSON matches a golden file. | | File layout on disk (`identity.json`, `relays.json`, `groups/*.mls`, `keypackages.bundle`) | Structural assertions after a command sequence. | -| Round-trip between two data-dirs on a local relay | End-to-end shell scripts under `cli/src/test/resources/scripts/`. Spin up `nostr-rs-relay`, run Alice + Bob, assert await verbs resolve. | -| Interop with other clients | External harness consumes Amy as a binary; out of scope here but the JSON contract is what keeps it stable. | +| Round-trip between two data-dirs on a local relay | End-to-end shell harnesses under `cli/tests/`. Each harness spins up a local `nostr-rs-relay`, bootstraps two or more fresh identities in their own `--data-dir`s, and drives a scenario via `amy` (+ `wn` for Marmot interop against whitenoise-rs). Today there are two suites: `cli/tests/marmot/` (13 MLS scenarios vs whitenoise-rs) and `cli/tests/dm/` (NIP-17 DM round-trips between two `amy` clients). | +| Interop with other clients | Covered by `cli/tests/marmot/marmot-interop-headless.sh` (drives Amy against whitenoise-rs `wn`/`wnd`). Add new scenarios there or start a new sibling under `cli/tests/`. | **What not to test here:** event signing, filter assembly, MLS correctness, NIP-44 encryption. Those belong in `quartz`/`commons`. @@ -207,6 +207,11 @@ If an Amy bug can only be caught here, it's a contract violation **Interop-test script template:** +The canonical examples live under `cli/tests/` — read +[`cli/tests/README.md`](./tests/README.md) for the layout, then +crib from `cli/tests/dm/tests-dm.sh` or `cli/tests/marmot/tests-create.sh`. +At the byte-banging level, a minimal round-trip looks like: + ```bash set -euo pipefail TMP=$(mktemp -d) diff --git a/cli/README.md b/cli/README.md index a1077f37e3..abc2141470 100644 --- a/cli/README.md +++ b/cli/README.md @@ -98,7 +98,10 @@ GID=$(amy --data-dir ./alice marmot group create --name "Test" | jq -r .group_id ``` For an interop-test script template, see -[DEVELOPMENT.md § Testing](./DEVELOPMENT.md#testing). +[DEVELOPMENT.md § Testing](./DEVELOPMENT.md#testing). The runnable +harnesses live under [`cli/tests/`](./tests/README.md) — +`cli/tests/marmot/` for MLS group messaging vs whitenoise-rs, +`cli/tests/dm/` for NIP-17 DMs between two `amy` clients. ---