"""The two-sided marketplace site: Worker routes, the request-a-kit form and the wording it shows."""
from __future__ import annotations
import html
import json
import re
import subprocess
from pathlib import Path
from typing import Any
ROOT = Path(__file__).resolve().parents[1]
WORKER = ROOT / "deploy" / "cloudflare" / "worker.js"
ISSUE_FORM = ROOT / ".github" / "ISSUE_TEMPLATE" / "request-a-kit.yml"
OLD_NAMES = re.compile(r"shamash|kinema|kothar", re.IGNORECASE)
# Simulates the Cloudflare asset binding: real files from web/public, and index.html for any other path,
# which is what `"not_found_handling": "single-page-application"` does for the deployed Worker.
WORKER_SCRIPT = r"""
import fs from "node:fs";
import path from "node:path";
import worker from WORKER;
const publicDir = PUBLIC_DIR;
const shell = fs.readFileSync(INDEX_HTML, "utf8");
const extra = EXTRA_ENV;
const env = {
...extra,
ASSETS: {
async fetch(req) {
const url = new URL(typeof req === "string" ? req : req.url);
const target = path.join(publicDir, url.pathname.replace(/^\//, ""));
if (url.pathname !== "/" && fs.existsSync(target) && fs.statSync(target).isFile()) {
const type = target.endsWith(".json") ? "application/json" : "image/svg+xml";
return new Response(fs.readFileSync(target), { status: 200, headers: { "content-type": type } });
}
return new Response(shell, { status: 200, headers: { "content-type": "text/html; charset=utf-8" } });
},
},
};
const requests = REQUESTS;
const out = {};
for (const [name, method, pathname, body] of requests) {
const init = { method };
if (body !== null) {
init.body = JSON.stringify(body);
init.headers = { "content-type": "application/json" };
}
const response = await worker.fetch(new Request("https://eranos.ta-amps.workers.dev" + pathname, init), env);
const bytes = method === "HEAD" ? new Uint8Array() : new Uint8Array(await response.arrayBuffer());
const digest = [...new Uint8Array(await crypto.subtle.digest("SHA-256", bytes))].map((b) => b.toString(16).padStart(2, "0")).join("");
const binary = (response.headers.get("content-type") || "").includes("gzip");
out[name] = {
sha256: digest,
xsha: response.headers.get("x-content-sha256") || "",
disposition: response.headers.get("content-disposition") || "",
status: response.status,
type: response.headers.get("content-type") || "",
csp: response.headers.get("content-security-policy") || "",
frame: response.headers.get("x-frame-options") || "",
allow: response.headers.get("allow") || "",
cache: response.headers.get("cache-control") || "",
cors: response.headers.get("access-control-allow-origin") || "",
body: binary ? "" : new TextDecoder().decode(bytes),
};
}
console.log(JSON.stringify(out));
"""
def _worker(
requests: list[tuple[str, str, str, Any]], extra_env: str = "({})"
) -> dict[str, dict[str, Any]]:
script = (
WORKER_SCRIPT.replace("EXTRA_ENV", extra_env)
.replace("WORKER", json.dumps(WORKER.as_uri()))
.replace("PUBLIC_DIR", json.dumps((ROOT / "web" / "public").as_posix()))
.replace("INDEX_HTML", json.dumps((ROOT / "web" / "index.html").as_posix()))
.replace("REQUESTS", json.dumps(requests))
)
run = subprocess.run(
["node", "--input-type=module", "-e", script], check=True, capture_output=True, text=True
)
result: dict[str, dict[str, Any]] = json.loads(run.stdout)
return result
def test_marketplace_pages_load_directly_and_on_refresh() -> None:
wrangler = (ROOT / "deploy" / "cloudflare" / "wrangler.jsonc").read_text(encoding="utf-8")
assert '"not_found_handling": "single-page-application"' in wrangler
assert '"run_worker_first": true' in wrangler
out = _worker(
[
("home", "GET", "/", None),
("help", "GET", "/help", None),
("help_slash", "GET", "/help/", None),
("nonprofits", "GET", "/nonprofits", None),
("nonprofits_query", "GET", "/nonprofits?from=home", None),
("help_head", "HEAD", "/help", None),
("help_post", "POST", "/help", {}),
]
)
for name in ("home", "help", "help_slash", "nonprofits", "nonprofits_query", "help_head"):
page = out[name]
assert page["status"] == 200, name
assert page["type"].startswith("text/html"), name
assert "script-src 'self'" in page["csp"], name
assert page["frame"] == "DENY", name
for name in ("home", "help", "nonprofits"):
assert 'href="/help"' in out[name]["body"]
assert 'href="/nonprofits"' in out[name]["body"]
assert out["help_post"]["status"] == 405
def test_home_page_opens_on_the_two_doors_without_an_injected_banner() -> None:
out = _worker([("home", "GET", "/", None), ("help", "GET", "/help", None)])
for name in ("home", "help"):
assert "data-agent-start" not in out[name]["body"], name
assert "/agent-start.js" not in out[name]["body"], name
def test_connect_agent_mcp_and_api_routes_still_answer() -> None:
out = _worker(
[
("connect", "GET", "/connect", None),
("connect_json", "GET", "/connect.json", None),
("start_json", "GET", "/agent-start.json", None),
("start_js", "GET", "/agent-start.js", None),
("card", "GET", "/.well-known/agent-card.json", None),
("llms", "GET", "/llms.txt", None),
("health", "GET", "/api/health", None),
("catalog", "GET", "/api/catalog", None),
("examples", "GET", "/api/examples", None),
("missing_api", "GET", "/api/help", None),
("mcp", "POST", "/mcp", {"jsonrpc": "2.0", "id": 1, "method": "tools/list"}),
]
)
assert (
out["connect"]["status"] == 200
and "
Connect to Eranos" in out["connect"]["body"]
)
assert json.loads(out["connect_json"]["body"])["surface_persistence"] is False
start = json.loads(out["start_json"]["body"])
assert start["version"] == "agent.onboarding.v1"
assert start["activates_work"] is False
assert "https://eranos.ta-amps.workers.dev/connect.json" in start["modes"]["any"]
assert out["start_js"]["status"] == 200 and "javascript" in out["start_js"]["type"]
card = json.loads(out["card"]["body"])
assert "agent kits" in card["description"]
assert not re.search(r"\btools?\b", card["description"])
llms = out["llms"]["body"]
# The banner tells every agent to read /llms.txt and follow it: it comes from the eranos.instructions/llms noun.
noun = json.loads((ROOT / "instructions" / "llms.json").read_text())
assert noun["text"].strip().splitlines()[0] in llms
for line in (
"Ask for help for a nonprofit, without private information",
"Pick up open tasks as a volunteer",
"The agent that builds something can't approve it",
"/connect.json",
):
assert line in llms, line
assert "github.com" not in llms
assert json.loads(out["health"]["body"])["surface"] == "eranos"
snapshot_kits = json.loads(
(ROOT / "web" / "public" / "snapshot" / "catalog.json").read_text(encoding="utf-8")
)["kits"]
assert len(json.loads(out["catalog"]["body"])["kits"]) == len(snapshot_kits) >= 5
shown = json.loads(
(ROOT / "web" / "public" / "snapshot" / "examples.json").read_text(encoding="utf-8")
)
assert json.loads(out["examples"]["body"]) == shown
assert shown["runs"]["count"] >= 5 and shown["needs"]
assert out["missing_api"]["status"] == 404
assert "json" in out["missing_api"]["type"]
tools = json.loads(out["mcp"]["body"])["result"]["tools"]
assert {t["name"] for t in tools} >= {"list_tracks", "search_catalog", "get_kit"}
def test_request_form_warns_first_and_asks_the_four_questions() -> None:
text = ISSUE_FORM.read_text(encoding="utf-8")
assert text.startswith("name: Tell us what you need\n")
assert not re.search(r"request a (kit|verb)", text, re.IGNORECASE)
warning = "Don't include anyone's personal information. Requests are public."
assert warning in text.splitlines()[1], "the chooser description leads with the warning"
body = text.split("\nbody:\n", 1)[1]
first_item = ("\n" + body).split("\n - type: ")[1]
assert first_item.startswith("markdown") and f"## {warning}" in first_item
fields = re.findall(
r"^ - type: (\w+)\n id: ([\w-]+)\n attributes:\n label: (.+)$", body, re.M
)
assert [(kind, label) for kind, _, label in fields] == [
("dropdown", "Organization type"),
("textarea", "The job to be done"),
("textarea", "Steps that must stay with a person"),
("textarea", "Constraints"),
("checkboxes", "Before you submit"),
]
assert len({field_id for _, field_id, _ in fields}) == len(fields)
assert "A volunteer will check your request before it becomes work." in text
assert "Kits are reviewed, not certified." in text
assert "required: true" in text
assert not re.search(r"\btools?\b", text, re.IGNORECASE)
assert not OLD_NAMES.search(text)
def test_data_the_site_shows_never_names_a_retired_pack() -> None:
snapshot = ROOT / "web" / "snapshot"
tracks = json.loads((snapshot / "tracks.json").read_text(encoding="utf-8"))["tracks"]
shown: list[str] = []
for track in tracks:
shown += [track["title"], track["summary"], *track["never"]]
shown += [org["mandate"] for org in track["organizations"]]
for entry in json.loads((snapshot / "catalog.json").read_text(encoding="utf-8"))["kits"]:
kit = entry["kit"]
shown += [
kit["title"],
kit["summary"],
kit["target_org"],
entry["review_notes"],
*kit["checklist"],
]
shown += [f"{step['title']} {step['actor']} {step['guidance']}" for step in kit["steps"]]
shown += [f"{fixture['scenario']} {fixture['sample_input']}" for fixture in kit["fixtures"]]
shown += [source["title"] for source in kit["sources"]]
assert [line for line in shown if OLD_NAMES.search(line)] == []
for path in [ROOT / "web" / "index.html", *sorted((ROOT / "web" / "src").rglob("*.ts*"))]:
assert not OLD_NAMES.search(path.read_text(encoding="utf-8")), path.name
def test_the_worker_code_never_names_a_retired_surface() -> None:
"""Hunt, October 30: access.js still branched on an archived surface's name (MUST-FOLLOW item 9)."""
named = [
path.name
for path in sorted((ROOT / "deploy" / "cloudflare").glob("*.js"))
if OLD_NAMES.search(path.read_text(encoding="utf-8"))
]
assert named == []
def test_worker_serves_public_nouns_and_the_practice_digest() -> None:
import hashlib
from tessera.receipts import canonical_json
bundle = json.loads(
(ROOT / "examples" / "kits" / "05-volunteer-shift-sop-pack.json").read_text()
)
draft = bundle["draft"]
out = _worker(
[
("help", "GET", "/api/nouns/eranos.instructions/help", None),
("listing", "GET", "/api/nouns/eranos.instructions", None),
("private_store", "GET", "/api/nouns/eranos.steward_requests/x", None),
("catalog_store", "GET", "/api/nouns/eranos.catalog/KIT-SHIFT-05", None),
("missing", "GET", "/api/nouns/eranos.plans/rq-none", None),
("practice", "POST", "/api/practice", {"draft": draft}),
]
)
help_noun = json.loads(out["help"]["body"])
assert out["help"]["status"] == 200 and help_noun["value"]["title"] == "Help in six steps"
keys = [r["key"] for r in json.loads(out["listing"]["body"])["records"]]
assert keys == sorted(p.stem for p in (ROOT / "instructions").glob("*.json"))
assert {
"shell",
"home",
"nonprofits-page",
"request-status",
"help-page",
"library",
"agent-banner",
} <= set(keys)
for name in ("private_store", "catalog_store", "missing"):
assert out[name]["status"] == 404, name
practice = json.loads(out["practice"]["body"])
expected = hashlib.sha256(canonical_json(draft).encode("utf-8")).hexdigest()
assert practice["draft_sha256"] == expected
assert "connect-src 'self' https://tessera.ta-amps.workers.dev" in out["help"]["csp"]
def test_static_page_and_readme_match_the_site_noun() -> None:
"""index.html shows the headline before the app loads the site noun; it must not drift from it."""
site = json.loads((ROOT / "instructions" / "site.json").read_text(encoding="utf-8"))
html = (ROOT / "web" / "index.html").read_text(encoding="utf-8")
assert f"Eranos ยท {site['title']}" in html
assert f"
{site['headline']}
" in html
readme = (ROOT / "README.md").read_text(encoding="utf-8").splitlines()
assert readme[2] == f"{site['headline']} {site['subline']}"
# Readers that run no script get the skip link and the privacy line too.
assert 'Skip to content' in html
assert '' in html
assert f"
{site['privacy']}
" in html
def test_starting_brief_noun_is_the_canonical_brief() -> None:
"""The help noun's brief is the onboarding module's text for the home origin, which is also
Agora's site/agent-brief.txt without its final newline."""
script = (
"import { buildAgentPrompt } from "
+ json.dumps((ROOT / "deploy" / "cloudflare" / "agent_start.js").as_uri())
+ "; console.log(JSON.stringify(buildAgentPrompt('https://home.ta-amps.workers.dev', 'any')));"
)
run = subprocess.run(
["node", "--input-type=module", "-e", script], check=True, capture_output=True, text=True
)
noun = json.loads((ROOT / "instructions" / "help.json").read_text(encoding="utf-8"))
assert noun["brief"] == json.loads(run.stdout)
assert not re.search(r"\btools?\b", " ".join(s["title"] + s["detail"] for s in noun["steps"]))
# Acceptance and accessibility fixes, October 30 ------------------------------------------------------------
def _router_pages() -> set[str]:
router = (ROOT / "web" / "src" / "router.tsx").read_text(encoding="utf-8")
table = router.split("const STATIC_ROUTES", 1)[1].split("};", 1)[0]
return set(re.findall(r'"(/[a-z-]*)": \{ name:', table))
def test_the_worker_knows_the_app_pages_the_router_knows() -> None:
worker = WORKER.read_text(encoding="utf-8")
listed = re.search(r"const APP_PAGES = \[([^\]]*)\];", worker)
assert listed, "the Worker lists the app's pages"
assert set(re.findall(r'"(/[a-z-]*)"', listed.group(1))) == _router_pages()
assert "const APP_KIT_PAGE_RE = /^\\/catalog\\/[^/]+$/;" in worker
assert "/^\\/catalog\\/([^/]+)$/" in (ROOT / "web" / "src" / "router.tsx").read_text(
encoding="utf-8"
)
def test_unknown_addresses_answer_404_with_the_app_view() -> None:
out = _worker(
[
("missing", "GET", "/this-page-does-not-exist-uat", None),
("missing_deep", "GET", "/help/more/pages", None),
("missing_head", "HEAD", "/no-such-page", None),
("missing_api", "GET", "/api/no-such-route", None),
*[(f"page{n}", "GET", path, None) for n, path in enumerate(sorted(_router_pages()))],
("kit", "GET", "/catalog/KIT-SHIFT-05", None),
("slash", "GET", "/nonprofits/", None),
("asset", "GET", "/snapshot/catalog.json", None),
("favicon", "GET", "/favicon.svg", None),
]
)
for name in ("missing", "missing_deep", "missing_head"):
assert out[name]["status"] == 404, name
assert out[name]["type"].startswith("text/html"), name
assert "script-src 'self'" in out[name]["csp"], name
# The 404 body is the app shell, so the app's "Page not found" view shows.
assert '
' in out["missing"]["body"]
assert out["missing_api"]["status"] == 404 and "json" in out["missing_api"]["type"]
for name in [n for n in out if n.startswith("page")] + ["kit", "slash"]:
assert out[name]["status"] == 200, name
assert out[name]["type"].startswith("text/html"), name
assert out["asset"]["status"] == 200 and "json" in out["asset"]["type"]
assert out["favicon"]["status"] == 200
def test_broken_escapes_wrong_kit_links_and_read_only_routes_answer_plainly() -> None:
"""Hunt, October 30, all read live first: a broken percent escape in an API path made the Worker throw, so
Cloudflare answered its bare "error code: 1101" 500 with no CORS headers; every kit address answered 200,
even one naming no kit; 405s on the read-only API had no Allow header; /connect.json set no cache rule."""
out = _worker(
[
("kit_escape", "GET", "/api/catalog/%E0%A4%A", None),
("noun_escape", "GET", "/api/nouns/eranos.instructions/%E0%A4%A", None),
("noun_ok", "GET", "/api/nouns/eranos.instructions/site", None),
("kit_page", "GET", "/catalog/KIT-SHIFT-05", None),
("kit_page_slash", "GET", "/catalog/KIT-SHIFT-05/", None),
("kit_page_missing", "GET", "/catalog/KIT-SHIFT-99", None),
("kit_page_lower", "GET", "/catalog/kit-shift-05", None),
("kit_page_escape", "GET", "/catalog/%E0%A4%A", None),
("kit_page_head", "HEAD", "/catalog/NOPE-KIT-99", None),
("post_api", "POST", "/api/catalog", {}),
("connect_json", "GET", "/connect.json", None),
("post_connect", "POST", "/connect.json", {}),
]
)
for name in ("kit_escape", "noun_escape"):
assert out[name]["status"] == 400, name
assert out[name]["type"] == "application/problem+json", name
assert json.loads(out[name]["body"])["code"] == "invalid_request", name
assert out[name]["cors"] == "*", name
assert out["noun_ok"]["status"] == 200
for name in ("kit_page", "kit_page_slash"):
assert out[name]["status"] == 200, name
for name in ("kit_page_missing", "kit_page_lower", "kit_page_escape", "kit_page_head"):
assert out[name]["status"] == 404, name
assert out[name]["type"].startswith("text/html"), name
# The 404 body is still the app shell, whose "Kit unavailable" view explains and links back.
assert '
' in out["kit_page_missing"]["body"]
assert out["post_api"]["status"] == 405 and out["post_api"]["allow"] == "GET, HEAD"
assert out["post_connect"]["status"] == 405 and out["post_connect"]["allow"] == "GET, HEAD"
assert out["connect_json"]["status"] == 200 and "no-store" in out["connect_json"]["cache"]
def _descriptor() -> dict[str, Any]:
script = (
"import { accessDescriptor } from "
+ json.dumps((ROOT / "deploy" / "cloudflare" / "access.js").as_uri())
+ "; console.log(JSON.stringify(accessDescriptor('eranos')));"
)
run = subprocess.run(
["node", "--input-type=module", "-e", script], check=True, capture_output=True, text=True
)
result: dict[str, Any] = json.loads(run.stdout)
return result
def test_connect_is_a_page_of_the_site_titled_connect_to_eranos() -> None:
noun = json.loads((ROOT / "instructions" / "connect.json").read_text(encoding="utf-8"))
out = _worker(
[
("connect", "GET", "/connect", None),
("connect_head", "HEAD", "/connect", None),
("connect_json", "GET", "/connect.json", None),
("connect_post", "POST", "/connect", {}),
]
)
page = out["connect"]
assert page["status"] == 200 and page["type"].startswith("text/html")
assert "script-src 'self'" in page["csp"] and page["frame"] == "DENY"
body = page["body"]
# The site's own shell: its title is this page's, and the app that draws the layout loads into it.
assert body.count("") == 1 and "Connect to Eranos" in body
assert noun["title"] == "Connect to Eranos"
assert 'Skip to content' in body
assert '