From bfbfe575136ddd636f85fefdcd2dc173450ef19f Mon Sep 17 00:00:00 2001 From: npub17jjz49l9jjmhhk7cac63j8yt9z555n9cw8vk7v5jz4vzw4ppld5qgj57cc Date: Sat, 27 Jun 2026 10:41:24 -0400 Subject: [PATCH] test(conformance): document status-code-as-layer-discriminator on nip98_replay assertion MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Follow-up to da6051fdb per Quinn's cold-read (event 4529860195007964...). The within-community replay assertion `assert_eq!(second_a.status(), UNAUTHORIZED)` pins the 401 status code rather than checking the body, because the system has defense-in-depth across two layers with distinct rejection signatures: * auth-layer replay check (`check_nip98_replay`) — rejects with 401 + body "NIP-98: replay detected". * storage-layer dedup (`events` PK `ON CONFLICT DO NOTHING` in `ingest_event`) — accepts with 200 + body `accepted: false, message: "duplicate"`. Both reject a duplicate, but only the 401 path proves the seen-set is in the request path. A body-only check like `!accepted` would pass under a noop'd `check_nip98_replay` because storage-dedup still 200-accepted-false's the second post — the bite would go vacuous against the layer the obligation actually names ("seen-set in the request path"). Adds: * Inline `//` comment block immediately above the `assert_eq!` naming the two layers, their distinct status signatures, and why the 401 expectation is the load-bearing-layer discriminator. Explicitly tells a future reader not to weaken to `!accepted` for "simpler reading." * Extended assertion message: when the test fails, the panic message now names both layers and which one the 401 proves, so a future debugger sees the architectural property without reading the doc-comment. Generalized principle (per Quinn): when a system has defense-in-depth across layers with different status-code signatures on rejection, the assertion should pin the status code from the load-bearing layer, not any rejection. Held in the row's doc-comment (not the shared discipline slug) per Quinn's stopping rule — this is a deeper instance of slug rule #2's defense-in-depth class, not a new spine entry. Bar: * Comment/string-only diff: 21 lines (+19 / −2), zero runtime behavior change — verified by inspection (`git diff` shows only comments and string-literal extensions). * `cargo check -p buzz-test-client --tests`: clean. * `cargo clippy -p buzz-test-client --tests -- -D warnings`: clean. * `cargo fmt -p buzz-test-client -- --check`: clean. * Default `cargo test ... api_tokens` (no `--ignored`): doc-only `#[test]` still passes; wire-driven still `#[ignore]`-skipped. * No live mutate-bite re-run needed: the runtime path of the wire-driven test is byte-identical (only strings/comments touched), and the mutate-bite at da6051fdb was already RED-on-right-assertion by Sami's hands at :3300 and Eva's hands at her :3300 (event 9e9050cd44d6...). The follow-up makes the *reason* the bite bites discoverable to a future reader; it does not change *whether* the bite bites. Base: PR #1321 head `da6051fdb`. Test-only diff. Co-authored-by: Tyler Longwell Signed-off-by: Tyler Longwell --- .../tests/conformance_multitenant.rs | 21 +++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/crates/buzz-test-client/tests/conformance_multitenant.rs b/crates/buzz-test-client/tests/conformance_multitenant.rs index 562904b72..ec5e6900d 100644 --- a/crates/buzz-test-client/tests/conformance_multitenant.rs +++ b/crates/buzz-test-client/tests/conformance_multitenant.rs @@ -761,13 +761,30 @@ mod api_tokens_nip98_replay { .send() .await .unwrap_or_else(|e| panic!("second POST to A failed: {e}")); + // The assertion below pins the status code (401), not just rejection, + // because the system has defense-in-depth across two layers with + // distinct rejection signatures: + // * auth-layer replay check (`check_nip98_replay`) — rejects with + // 401 + body "NIP-98: replay detected". + // * storage-layer dedup (`events` PK `ON CONFLICT DO NOTHING` in + // `ingest_event`) — accepts with 200 + body `accepted: false, + // message: "duplicate"`. + // Both reject a duplicate, but only the 401 path proves the seen-set + // is in the request path. A body-only check like `!accepted` would + // pass under a noop'd `check_nip98_replay` because storage-dedup + // still 200-accepted-false's the second post — the bite would go + // vacuous against the layer the obligation actually names. Status- + // code is the load-bearing-layer discriminator; do not weaken this + // to `!accepted` for "simpler reading." assert_eq!( second_a.status(), reqwest::StatusCode::UNAUTHORIZED, "second POST to A with the same NIP-98 event MUST be rejected as \ replay (got {}) — if this returns 200, the shared seen-set is \ - not in the request path. Mutate-bite handle: \ - `check_nip98_replay` in bridge.rs:79.", + not in the request path (storage-dedup at `ingest_event` would \ + return 200-accepted-false on the same input; only the 401 from \ + `check_nip98_replay` proves the auth-layer replay fence). \ + Mutate-bite handle: `check_nip98_replay` in bridge.rs:79.", second_a.status(), ); let second_a_body = second_a.text().await.unwrap_or_default();