From eb81a9090fdf49eef027392433f26393d6a20e3f Mon Sep 17 00:00:00 2001 From: Christopher <131207452+PetrefiedThunder@users.noreply.github.com> Date: Thu, 22 Oct 2026 14:51:39 -0700 Subject: [PATCH 1/2] site: hero receipt copy, example output, single install block, drop curl text, tab border contrast, demo key click event --- site/analytics.js | 1 + site/home-key.js | 22 +----- site/index.html | 43 +++++------ site/styles.css | 110 ++++++++++------------------- site/test_analytics.mjs | 55 +++++++++++++++ site/test_home_contrast.mjs | 3 +- site/test_home_key.mjs | 47 ++++-------- tests/test_site_agent_interface.py | 27 ++++--- 8 files changed, 146 insertions(+), 162 deletions(-) create mode 100644 site/test_analytics.mjs diff --git a/site/analytics.js b/site/analytics.js index a1b890c1..eb40eda4 100644 --- a/site/analytics.js +++ b/site/analytics.js @@ -5,6 +5,7 @@ // configured at build time; email_click is the primary intake path. const allowedEvents = new Set([ "booking_click", + "demo_key_click", "email_click", "proof_click", ]); diff --git a/site/home-key.js b/site/home-key.js index c22c487e..44233eba 100644 --- a/site/home-key.js +++ b/site/home-key.js @@ -13,10 +13,6 @@ const budget = byId("home-key-budget"); const retry = byId("home-key-retry"); const email = byId("home-key-email"); - const quickstart = byId("home-quickstart-code"); - const copyQuickstart = byId("home-copy-quickstart"); - const copyStatus = byId("home-copy-status"); - const quickstartTemplate = quickstart.textContent; const heroQuickstart = byId("home-hero-python"); const heroQuickstartTemplate = heroQuickstart.textContent; const copyHeroQuickstart = byId("home-hero-python-copy"); @@ -82,9 +78,7 @@ key.type = "password"; wallet.type = "password"; budget.textContent = String(data.budget_credits); - quickstart.textContent = fillQuickstart(quickstartTemplate, data); heroQuickstart.textContent = fillQuickstart(heroQuickstartTemplate, data); - copyQuickstart.disabled = false; copyHeroQuickstart.disabled = false; title.textContent = "Your demo key is ready"; status.textContent = "Your demo key is ready"; @@ -188,17 +182,7 @@ copy(`export AMW_API_KEY=${shellQuote(key.value)}\nexport AMW_WALLET_ID=${shellQuote(wallet.value)}`, "Key and wallet commands copied.", key, status, "Copy was unavailable. Copy Key and Wallet separately.")); - copyQuickstart.addEventListener("click", () => - copy(quickstart.textContent, "Quickstart copied.", quickstart, copyStatus)); - for (const [buttonId, codeId] of [ - ["home-hero-python-copy", "home-hero-python"], - ["home-hero-curl-copy", "home-hero-curl"], - ]) { - const button = byId(buttonId); - const code = byId(codeId); - if (button && code) { - button.addEventListener("click", () => - copy(code.textContent, "Commands copied.", code, byId("home-hero-copy-status"))); - } - } + copyHeroQuickstart.addEventListener("click", () => + copy(heroQuickstart.textContent, "Commands copied.", heroQuickstart, + byId("home-hero-copy-status"))); })(); diff --git a/site/index.html b/site/index.html index 41a373e0..978da42f 100644 --- a/site/index.html +++ b/site/index.html @@ -171,7 +171,7 @@ - + @@ -196,9 +196,10 @@

Let agents retry safely.

-

One accepted request key permits at most one gateway dispatch to the configured upstream tool and at most one debit. Each finalized or reconciled path has a receipt.

+

Each action runs once and leaves a receipt.

+

One accepted request key permits at most one gateway dispatch to the configured upstream tool and at most one debit. Each finalized or reconciled path has a receipt.

- + Run the quickstart: amw-demo
@@ -219,11 +220,12 @@

Let agents retry safely.

python examples/permit_echo_retry.py
-
-
curl -s -X POST https://api.thisisatest.tech/v1/demo/keys
- +
+

Example output

+
receipt_id: rcpt_7Kq2mX9
+Same receipt. The tool did not run again.
-

The button above fills these Python commands with a demo key. With curl, replace both export placeholders using api_key and wallet_id from the response.

+

Get a demo key to fill the Python commands with your key and wallet ID.

@@ -292,26 +294,13 @@

Get your demo key

How it works

From demo key to checked receipt

-
-
1

Get a demo key

Use the button above. Save both api_key and wallet_id for the demo call.

-
2

Set up

Run the Python example with your demo key and wallet. It needs Python 3.10 or newer.

-
-
Python
-
git clone https://github.com/agentmiddleware/amw-demo.git
-cd amw-demo
-python3 -m venv .venv
-source .venv/bin/activate
-pip install -e .
-export AMW_API_KEY='YOUR_DEMO_KEY'
-export AMW_WALLET_ID='YOUR_WALLET_ID'
-python examples/permit_echo_retry.py
-

Get a demo key to fill in the two export lines.

-
-
-
3

First call returns a receipt

The example creates a permit and calls partner.echo through the gateway. It prints a receipt ID for the result.

-
4

Retry with the same request key

For an accepted request key on the configured upstream tool, a retry with the same key returns the original receipt instead of dispatching again. The receipt does not prove what happened inside the tool.

- -
+
    +
  • Get a demo key and save the API key and wallet ID.
  • +
  • Set the key and wallet ID in the Python commands above, then run the example.
  • +
  • The first call creates a permit and prints the receipt ID.
  • +
  • For an accepted request key on the configured upstream tool, a retry with the same key returns the original receipt instead of dispatching again.
  • +
  • Check the receipt signature offline. See a published sample and verifier.
  • +
diff --git a/site/styles.css b/site/styles.css index 04283b60..8ca24d98 100644 --- a/site/styles.css +++ b/site/styles.css @@ -2669,6 +2669,12 @@ body.home-light .hero-v2-intro > p { font-size: 1.1875rem; letter-spacing: -0.018em; } +body.home-light .hero-v2-intro > .hero-v2-boundary { + margin-top: 5px; + font-size: 0.875rem; + line-height: 1.5; + letter-spacing: 0; +} body.home-light .hero-v2-actions { display: flex; flex-wrap: wrap; @@ -2744,7 +2750,7 @@ body.home-light .hero-v2-tab-disabled { } body.home-light .hero-v2-tab-disabled span { padding: 3px 6px; - border: 1px solid var(--home-line); + border: 1px solid #6b7280; border-radius: 4px; font-size: 0.625rem; } @@ -2771,12 +2777,20 @@ body.home-light .hero-v2-command-row button { cursor: pointer; } body.home-light .hero-v2-command-row button:disabled { cursor: not-allowed; opacity: 0.55; } -body.home-light .hero-v2-curl-row { - margin: 18px 23px 0; +body.home-light .hero-v2-output { + margin: 16px 23px 0; border-top: 1px solid var(--home-line); } -body.home-light .hero-v2-curl-row pre { padding: 14px 64px 0 0; line-height: 1.375rem; } -body.home-light .hero-v2-curl-row button { top: 6px; right: -8px; } +body.home-light .hero-v2-output p { + margin: 12px 0 0; + color: var(--home-muted); + font-size: 0.75rem; +} +body.home-light .hero-v2-command-row.hero-v2-output pre { + padding: 8px 0 0; + line-height: 1.5; + white-space: pre-wrap; +} body.home-light .hero-v2-code-note { margin: 16px 23px 0; max-width: none; @@ -2784,10 +2798,8 @@ body.home-light .hero-v2-code-note { font-size: 0.75rem; } body.home-light .hero-v2-copy-status { - position: absolute; - right: 23px; - bottom: 7px; - margin: 0; + margin: 6px 23px 0; + min-height: 1rem; color: var(--home-muted); font-size: 0.6875rem; } @@ -3031,26 +3043,26 @@ body.home-light .home-v2-section-heading > p { font-weight: 600; } body.home-light .home-v2-section-heading h2 { margin: 0 0 30px; font-size: 2.375rem; } -body.home-light .home-v2-guide-step { - display: grid; - grid-template-columns: 34px minmax(0, 1fr); - gap: 18px; - padding: 20px 0; - border-top: 1px solid var(--home-line); +body.home-light .home-v2-steps { + margin: 0; + padding: 0; + list-style: none; } -body.home-light .home-v2-guide-number { +body.home-light .home-v2-steps li { display: grid; - place-items: center; - width: 32px; - height: 32px; - border: 1px solid var(--home-line); - border-radius: 6px; + grid-template-columns: 24px minmax(0, 1fr); + gap: 12px; + padding: 16px 0; + border-top: 1px solid var(--home-line); color: var(--home-muted); - font-size: 0.75rem; - font-weight: 600; + font-size: 0.9375rem; + line-height: 1.6; +} +body.home-light .home-v2-steps li::before { + content: "✓"; + color: var(--home-blue); + font-weight: 700; } -body.home-light .home-v2-guide-step h3 { margin: 2px 0 8px; font-size: 1.125rem; } -body.home-light .home-v2-guide-step p, body.home-light .home-v2-limits > p, body.home-light .home-v2-source > p { max-width: 76ch; @@ -3058,51 +3070,6 @@ body.home-light .home-v2-source > p { font-size: 0.9375rem; line-height: 1.6; } -body.home-light .home-code-panel { - max-width: 850px; - margin-top: 18px; - overflow: hidden; - border: 1px solid var(--home-line); - border-radius: 10px; - background: var(--home-soft); - box-shadow: none; -} -body.home-light .home-code-toolbar { - display: flex; - align-items: center; - justify-content: space-between; - gap: 1rem; - min-height: 46px; - padding: 0 18px; - border-bottom: 1px solid var(--home-line); - font-size: 0.75rem; - font-weight: 600; -} -body.home-light .home-code-toolbar button { - padding: 5px 9px; - border: 1px solid var(--home-line); - border-radius: 5px; - background: var(--home-bg); - color: var(--home-muted); - font: 600 0.6875rem "Public Sans", sans-serif; - cursor: pointer; -} -body.home-light .home-code-toolbar button:disabled { cursor: not-allowed; opacity: 0.55; } -body.home-light .home-code-scroll { - margin: 0; - overflow-x: auto; - padding: 18px 23px; - color: var(--home-text); - font-size: 0.8125rem; - line-height: 1.55; -} -body.home-light .home-code-help { - margin: 0; - padding: 0.55rem 1.4rem; - border-top: 1px solid var(--home-line); - color: var(--home-muted); - font-size: 0.75rem; -} body.home-light .home-v2-section a { text-decoration: underline; } body.home-light .home-v2-source { padding-bottom: 90px; } body.home-light .home-v2-source a { overflow-wrap: anywhere; } @@ -3130,15 +3097,12 @@ body.home-light .home-v2-source a { overflow-wrap: anywhere; } align-self: flex-end; margin: 8px 14px 0; } - body.home-light .hero-v2-curl-row { margin-top: 12px; } body.home-light .hero-v2-code-note { margin-top: 12px; } - body.home-light .hero-v2-copy-status { position: static; margin: 6px 23px 0; } body.home-light .hero-v2-flow { grid-template-columns: minmax(0, 1fr); } body.home-light .hero-v2-step { min-height: 0; } body.home-light .home-v2-glossary { grid-template-columns: minmax(0, 1fr); min-height: 0; } body.home-light .home-v2-glossary article { min-height: 0; } body.home-light .home-v2-section { padding-top: 50px; padding-bottom: 50px; } - body.home-light .home-v2-guide-step { gap: 12px; } body.home-light .home-key-drawer { padding: 84px 24px 24px; } } diff --git a/site/test_analytics.mjs b/site/test_analytics.mjs new file mode 100644 index 00000000..60d306f7 --- /dev/null +++ b/site/test_analytics.mjs @@ -0,0 +1,55 @@ +import assert from "node:assert/strict"; +import { readFileSync } from "node:fs"; +import test from "node:test"; +import { createContext, runInContext } from "node:vm"; + +const script = readFileSync(new URL("./analytics.js", import.meta.url), "utf8"); +const homeHtml = readFileSync(new URL("./index.html", import.meta.url), "utf8"); + +function analyticsPage(analyticsEnabled) { + const sent = []; + let click; + const context = createContext({ + document: { + addEventListener(name, listener) { + assert.equal(name, "click"); + click = listener; + }, + }, + window: analyticsEnabled ? { + va(...args) { sent.push(JSON.parse(JSON.stringify(args))); }, + } : {}, + }); + runInContext(script, context, { filename: "analytics.js" }); + return { + sent, + click(eventName) { + click({ + target: { + closest(selector) { + assert.equal(selector, "[data-analytics-event]"); + return eventName ? { dataset: { analyticsEvent: eventName } } : null; + }, + }, + }); + }, + }; +} + +test("homepage demo key button emits one existing analytics event per click", () => { + assert.match(homeHtml, /]*id="home-key-trigger"[^>]*data-analytics-event="demo_key_click"[^>]*>/); + const page = analyticsPage(true); + page.click("demo_key_click"); + assert.deepEqual(page.sent, [["event", { name: "demo_key_click" }]]); +}); + +test("analytics stays silent without opt in and rejects unknown event names", () => { + const disabled = analyticsPage(false); + disabled.click("demo_key_click"); + assert.deepEqual(disabled.sent, []); + + const enabled = analyticsPage(true); + enabled.click("receipt_verified"); + enabled.click(""); + assert.deepEqual(enabled.sent, []); +}); diff --git a/site/test_home_contrast.mjs b/site/test_home_contrast.mjs index 98764b0b..605b4679 100644 --- a/site/test_home_contrast.mjs +++ b/site/test_home_contrast.mjs @@ -56,13 +56,14 @@ test("homepage surfaces and controls use the contrast aware palette", () => { ["body.home-light .hero-v2-action-primary,\nbody.home-light #main .hero-v2-action-primary", "color", "var(--home-primary-text)"], ["body.home-light .hero-v2-code", "background", "var(--home-soft)"], ["body.home-light .hero-v2-command-row button", "border", "1px solid var(--home-line)"], + ["body.home-light .hero-v2-tab-disabled span", "border", "1px solid #6b7280"], ["body.home-light .hero-v2-step", "background", "var(--home-bg)"], ["body.home-light .hero-v2-intro > p", "color", "var(--home-muted)"], + ["body.home-light .hero-v2-intro > .hero-v2-boundary", "font-size", "0.875rem"], ["body.home-light .home-key-drawer", "background", "var(--home-bg)"], ["body.home-light .home-key-field-row", "border", "1px solid var(--home-line)"], ["body.home-light .home-key-field-row button", "color", "var(--home-muted)"], ["body.home-light .home-v2-glossary", "background", "var(--home-soft)"], - ["body.home-light .home-code-toolbar button", "background", "var(--home-bg)"], ]) { assert.equal(rule(selector)[property], value, `${selector} ${property}`); } diff --git a/site/test_home_key.mjs b/site/test_home_key.mjs index db68d65a..3fcf400a 100644 --- a/site/test_home_key.mjs +++ b/site/test_home_key.mjs @@ -9,14 +9,6 @@ const homeHtml = readFileSync(new URL("./index.html", import.meta.url), "utf8"); const heroCode = homeHtml.match(/
]*>([\s\S]*?)<\/code><\/pre>/);
 assert.ok(heroCode, "hero Python command block must exist");
 const heroTemplate = heroCode[1].replaceAll("&", "&");
-const template = `git clone https://github.com/agentmiddleware/amw-demo.git
-cd amw-demo
-python3 -m venv .venv
-source .venv/bin/activate
-pip install -e .
-export AMW_API_KEY='YOUR_DEMO_KEY'
-export AMW_WALLET_ID='YOUR_WALLET_ID'
-python examples/permit_echo_retry.py`;
 
 function makePage(fetchResponse, { copyFails = false, capture = true, search = "", referrer = "", session: stored = {} } = {}) {
   const ids = [
@@ -24,19 +16,15 @@ function makePage(fetchResponse, { copyFails = false, capture = true, search = "
     "home-key-title", "home-key-result", "home-key-error", "home-key-error-message",
     "home-key-value", "home-wallet-value", "home-key-reveal", "home-wallet-reveal",
     "home-key-copy", "home-wallet-copy", "home-key-copy-both", "home-key-budget",
-    "home-key-retry", "home-key-email", "home-quickstart-code",
-    "home-copy-quickstart", "home-copy-status",
-    "home-hero-python-copy", "home-hero-curl-copy", "home-hero-python",
-    "home-hero-curl", "home-hero-copy-status",
+    "home-key-retry", "home-key-email", "home-hero-python-copy",
+    "home-hero-python", "home-hero-copy-status",
   ];
   const elements = new Map(ids.map((id) => [id, {
     id,
     hidden: ["home-key-trigger", "home-key-panel", "home-key-result", "home-key-error",
       "home-key-retry", "home-key-email"].includes(id),
-    disabled: id === "home-copy-quickstart" || id === "home-hero-python-copy",
-    textContent: id === "home-quickstart-code" ? template :
-      id === "home-hero-python" ? heroTemplate :
-      id === "home-hero-curl" ? "curl -s -X POST https://api.thisisatest.tech/v1/demo/keys" :
+    disabled: id === "home-hero-python-copy",
+    textContent: id === "home-hero-python" ? heroTemplate :
       id === "home-key-trigger" ? "Get a free demo key" : "",
     value: "",
     type: id === "home-key-value" || id === "home-wallet-value" ? "password" : "button",
@@ -50,7 +38,6 @@ function makePage(fetchResponse, { copyFails = false, capture = true, search = "
     select() { this.selectCount += 1; },
     set innerHTML(_) { throw new Error("API data must not be inserted as HTML"); },
   }]));
-  elements.get("home-quickstart-code").select = undefined;
   const requests = [];
   const copies = [];
   const session = new Map(Object.entries(stored));
@@ -111,13 +98,13 @@ function issuedResponse(apiKey = "b2a_" + "test", walletId = "agt-test", credits
 test("hero Python copy requires an issued demo key and wallet", async () => {
   assert.match(heroTemplate, /export AMW_API_KEY='YOUR_DEMO_KEY'\nexport AMW_WALLET_ID='YOUR_WALLET_ID'\npython examples\/permit_echo_retry\.py$/);
   assert.match(homeHtml, /id="home-hero-python-copy"[^>]*disabled/);
+  assert.equal(homeHtml.match(/git clone https:\/\/github.com\/agentmiddleware\/amw-demo\.git/g)?.length, 1);
+  assert.match(homeHtml, /hero-v2-tab-disabled">curl<\/code>coming soon<\/span>/);
+  assert.doesNotMatch(homeHtml, /id="home-hero-curl(?:-copy)?"|curl -s -X POST/);
+  assert.doesNotMatch(homeHtml, /id="home-quickstart-code"|id="home-copy-quickstart"/);
   const page = makePage(() => { throw new Error("unexpected key request"); });
   await page.click("home-hero-python-copy");
-  await page.click("home-hero-curl-copy");
-  assert.deepEqual(page.copies, [
-    "curl -s -X POST https://api.thisisatest.tech/v1/demo/keys",
-  ]);
-  assert.equal(page.elements.get("home-hero-copy-status").textContent, "Commands copied.");
+  assert.deepEqual(page.copies, []);
   assert.equal(page.requests.length, 0);
 });
 
@@ -127,7 +114,6 @@ test("idle, loading, and success issue one empty POST and fill the live quicksta
   const get = (id) => page.elements.get(id);
   assert.equal(get("home-key-trigger").hidden, false);
   assert.equal(get("home-key-panel").hidden, true);
-  assert.equal(get("home-copy-quickstart").disabled, true);
   assert.equal(get("home-hero-python-copy").disabled, true);
   assert.equal(page.requests.length, 0);
 
@@ -157,16 +143,13 @@ test("idle, loading, and success issue one empty POST and fill the live quicksta
   assert.equal(get("home-key-value").value, key);
   assert.equal(get("home-wallet-value").value, "agt-test");
   assert.equal(get("home-key-budget").textContent, "1000");
-  assert.equal(get("home-copy-quickstart").disabled, false);
   assert.equal(get("home-hero-python-copy").disabled, false);
-  assert.equal(get("home-quickstart-code").textContent,
-    template.replace("export AMW_API_KEY='YOUR_DEMO_KEY'", () => "export AMW_API_KEY='b2a_test_'\"'\"'$&'")
-      .replace("export AMW_WALLET_ID='YOUR_WALLET_ID'", "export AMW_WALLET_ID='agt-test'"));
   assert.equal(get("home-hero-python").textContent,
     heroTemplate.replace("export AMW_API_KEY='YOUR_DEMO_KEY'", () => "export AMW_API_KEY='b2a_test_'\"'\"'$&'")
       .replace("export AMW_WALLET_ID='YOUR_WALLET_ID'", "export AMW_WALLET_ID='agt-test'"));
   await page.click("home-hero-python-copy");
   assert.equal(page.copies[0], get("home-hero-python").textContent);
+  assert.equal(get("home-hero-copy-status").textContent, "Commands copied.");
   assert.match(page.copies[0], /export AMW_WALLET_ID='agt-test'\npython examples\/permit_echo_retry\.py$/);
   assert.equal(page.copies[0].includes("YOUR_DEMO_KEY"), false);
   assert.equal(get("home-key-trigger").disabled, false);
@@ -238,14 +221,11 @@ test("reveal and copy controls use full values and quote shell commands", async
   await page.click("home-key-copy");
   await page.click("home-wallet-copy");
   await page.click("home-key-copy-both");
-  await page.click("home-copy-quickstart");
   assert.deepEqual(page.copies, [
     "b2a_a'b",
     "agt-w",
     "export AMW_API_KEY='b2a_a'\"'\"'b'\nexport AMW_WALLET_ID='agt-w'",
-    get("home-quickstart-code").textContent,
   ]);
-  assert.equal(get("home-copy-status").textContent, "Quickstart copied.");
 });
 
 test("network and service failures show retry and a later request can succeed", async () => {
@@ -319,7 +299,6 @@ test("malformed success fails closed and unavailable clipboard focuses a manual
     await invalid.click("home-key-trigger");
     assert.equal(invalid.elements.get("home-key-result").hidden, true);
     assert.equal(invalid.elements.get("home-key-retry").hidden, false);
-    assert.equal(invalid.elements.get("home-copy-quickstart").disabled, true);
     assert.equal(invalid.elements.get("home-hero-python-copy").disabled, true);
   }
 
@@ -331,9 +310,9 @@ test("malformed success fails closed and unavailable clipboard focuses a manual
   await page.click("home-key-copy-both");
   assert.equal(page.elements.get("home-key-status").textContent,
     "Copy was unavailable. Copy Key and Wallet separately.");
-  await page.click("home-copy-quickstart");
-  assert.equal(page.elements.get("home-quickstart-code").focusCount, 1);
-  assert.equal(page.elements.get("home-copy-status").textContent,
+  await page.click("home-hero-python-copy");
+  assert.equal(page.elements.get("home-hero-python").focusCount, 1);
+  assert.equal(page.elements.get("home-hero-copy-status").textContent,
     "Copy was unavailable. Select the text and copy it manually.");
 });
 
diff --git a/tests/test_site_agent_interface.py b/tests/test_site_agent_interface.py
index f8093966..953ef701 100644
--- a/tests/test_site_agent_interface.py
+++ b/tests/test_site_agent_interface.py
@@ -237,24 +237,35 @@ def test_rendered_landing_is_human_first_and_has_a_working_funnel(tmp_path) -> N
         "configured upstream tool and at most one debit. Each finalized or "
         "reconciled path has a receipt."
     ) in text
-    assert "Each action runs once" not in text
+    assert "Each action runs once and leaves a receipt." in text
+    assert re.search(
+        r"

Each action runs once and leaves a receipt\.

\s*" + r'

One accepted request key', + page, + ) assert "Get a demo key" in text assert "Run the quickstart: amw-demo" in text assert re.search(r']*id="home-key-trigger"[^>]*>', page) - assert '' in page + assert '' in page assert re.search(r'', page, re.S) assert 'href="https://github.com/agentmiddleware/amw-demo"' in page assert 'id="quickstart"' in page - assert page.count("rcpt_7Kq2mX9") == 2 + assert page.count("rcpt_7Kq2mX9") == 3 + assert "receipt_id: rcpt_7Kq2mX9\nSame receipt. The tool did not run again." in page assert "rcpt_7Kq2mX9." not in page assert page.index('class="home-v2-glossary"') < page.index('id="how-it-works"') - assert page.count('class="home-v2-guide-step"') == 5 - assert "git clone https://github.com/agentmiddleware/amw-demo.git" in page + checklist = page.split('

    ', 1)[1].split("
", 1)[0] + assert checklist.count("curlcoming soon' in page + assert "curl -s -X POST https://api.thisisatest.tech/v1/demo/keys" not in page + assert 'id="home-hero-curl-copy"' not in page assert "The gateway does not dispatch again." in text - assert "The tool did not run again." not in text + assert "Same receipt. The tool did not run again." in text assert 'id="how-it-works"' in page for heading in ("Permit", "Request key", "Receipt"): assert heading in text @@ -3435,7 +3446,7 @@ def test_landing_keeps_one_illustrative_retry_without_recording(tmp_path) -> Non assert result.returncode == 0, result.stderr page = (output / "index.html").read_text(encoding="utf-8") - assert page.count("rcpt_7Kq2mX9") == 2 + assert page.count("rcpt_7Kq2mX9") == 3 assert '
Date: Thu, 22 Oct 2026 15:05:25 -0700 Subject: [PATCH 2/2] style: ruff format site interface test --- tests/test_site_agent_interface.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_site_agent_interface.py b/tests/test_site_agent_interface.py index 953ef701..c8875765 100644 --- a/tests/test_site_agent_interface.py +++ b/tests/test_site_agent_interface.py @@ -261,7 +261,10 @@ def test_rendered_landing_is_human_first_and_has_a_working_funnel(tmp_path) -> N assert page.count("git clone https://github.com/agentmiddleware/amw-demo.git") == 1 assert "python examples/permit_echo_retry.py" in page assert "coming soon" in text - assert 'class="hero-v2-tab hero-v2-tab-disabled">curlcoming soon' in page + assert ( + 'class="hero-v2-tab hero-v2-tab-disabled">curlcoming soon' + in page + ) assert "curl -s -X POST https://api.thisisatest.tech/v1/demo/keys" not in page assert 'id="home-hero-curl-copy"' not in page assert "The gateway does not dispatch again." in text