From e4a7fd47d07f4afa31e60835c79367f73b226add Mon Sep 17 00:00:00 2001 From: sepehr-safari Date: Wed, 23 Sep 2026 15:34:04 +0300 Subject: [PATCH] feat: serve the design, hooks and benchmark documents on the site The design document, the hooks reference and the benchmark method are the most specific writing about the tool, and the guides and the footer sent every reader who wanted the exact behavior to GitHub to read them. They are now pages under /docs, with an index, and every link that pointed at them on GitHub points here instead. The documents are still written in the tool's repository, next to the code they describe. src/docs holds copies made by `pnpm sync:docs`, which fetches each one from main and changes nothing but relative links, which point at the page serving that file or at the file on GitHub. CI runs the script with `--check` and fails when a copy is not what main says, so a copy cannot quietly disagree with its original. Prettier skips the copies, since reformatting them is the same failure. Two things keep the CSP honest. Syntax highlighting is off, because it colours code with inline style attributes, and a right-aligned table column, which markdown also renders as an inline style on every cell, gets the class the site's numeric tables already use. A new CI step fails on any inline style attribute in the build. Each page carries TechArticle data with `isBasedOn` naming the original file, and the breadcrumb is shared with the guides. llms.txt, the IndexNow list and the nav include the new pages, /hooks now redirects to /docs/hooks, and the /docs redirect to GitHub is gone because /docs is a page. --- .github/workflows/ci.yml | 19 ++ .prettierignore | 2 + README.md | 6 +- astro.config.mjs | 5 + package.json | 3 +- scripts/indexnow.mjs | 4 + scripts/sync-docs.mjs | 118 +++++++ src/data/doc-files.ts | 53 +++ src/data/docs.ts | 67 ++++ src/data/schema.ts | 90 +++++- src/docs/benchmark.md | 109 +++++++ src/docs/design.md | 355 +++++++++++++++++++++ src/docs/hooks.md | 151 +++++++++ src/layouts/Base.astro | 7 +- src/pages/docs/[slug].astro | 84 +++++ src/pages/docs/index.astro | 81 +++++ src/pages/guides/claude-code.astro | 4 +- src/pages/guides/ecc.astro | 3 +- src/pages/guides/index.astro | 8 +- src/pages/guides/mcp-security.astro | 11 +- src/pages/guides/prompt-injection.astro | 5 +- src/pages/guides/secret-exfiltration.astro | 6 +- src/pages/llms.txt.ts | 7 +- src/pages/results.astro | 4 +- vercel.json | 7 +- 25 files changed, 1169 insertions(+), 40 deletions(-) create mode 100644 scripts/sync-docs.mjs create mode 100644 src/data/doc-files.ts create mode 100644 src/data/docs.ts create mode 100644 src/docs/benchmark.md create mode 100644 src/docs/design.md create mode 100644 src/docs/hooks.md create mode 100644 src/pages/docs/[slug].astro create mode 100644 src/pages/docs/index.astro diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index dcbacf4..3cf9230 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -49,6 +49,25 @@ jobs: - name: No word runs into a tag run: pnpm check:spacing + - name: No inline styles ship + # style-src 'self' refuses a style attribute as firmly as a diff --git a/src/pages/docs/index.astro b/src/pages/docs/index.astro new file mode 100644 index 0000000..34476c8 --- /dev/null +++ b/src/pages/docs/index.astro @@ -0,0 +1,81 @@ +--- +import Base from '../../layouts/Base.astro'; +import { REPO } from '../../data/benchmark'; +import { DOCS } from '../../data/docs'; +import { headlines } from '../../data/doc-files'; +import { docsIndexSchema } from '../../data/schema'; + +const title = 'Docs | agent-chaperone'; +const description = + 'The reference documents for agent-chaperone: the design, the hooks adapter and the benchmark method, copied from the repository and kept identical to it.'; +const named = headlines(); +--- + + +
+

Docs

+

+ How the tool works, as opposed to how to set it up. The guides cover the + setup; these are the documents the guides point to when a question needs the exact behavior. +

+

+ Each one is written and reviewed in the repository, next to the code it + describes, and copied here with only its links changed. Every change to this site is checked + against the repository's main branch, and a copy that differs from it fails the check. +

+
+ +
+

+ The documents{' '} + + # + +

+ +
+ +
+

+ In the repository only{' '} + + # + +

+ +
+ diff --git a/src/pages/guides/claude-code.astro b/src/pages/guides/claude-code.astro index 1521aa1..a6b47da 100644 --- a/src/pages/guides/claude-code.astro +++ b/src/pages/guides/claude-code.astro @@ -1,6 +1,6 @@ --- import Base from '../../layouts/Base.astro'; -import { REPO, SETS, SHELL } from '../../data/benchmark'; +import { SETS, SHELL } from '../../data/benchmark'; import { findGuide, guideUrl } from '../../data/guides'; import { guideSchema } from '../../data/schema'; @@ -248,7 +248,7 @@ agent-chaperone task --clear`}

The full hooks document, including how a replacement is matched to a tool's own output shape, - is in the repository. + is in the hooks reference.

diff --git a/src/pages/guides/ecc.astro b/src/pages/guides/ecc.astro index 643dcb1..21b9ca9 100644 --- a/src/pages/guides/ecc.astro +++ b/src/pages/guides/ecc.astro @@ -1,6 +1,5 @@ --- import Base from '../../layouts/Base.astro'; -import { REPO } from '../../data/benchmark'; import { findGuide, guideUrl } from '../../data/guides'; import { guideSchema } from '../../data/schema'; @@ -182,7 +181,7 @@ const AGENTSHIELD = 'https://www.npmjs.com/package/ecc-agentshield';

The full hook reference, including how a withheld result is matched to a tool's own output - shape, is in the repository. + shape, is in the hooks reference.

diff --git a/src/pages/guides/index.astro b/src/pages/guides/index.astro index 11d65d9..c951064 100644 --- a/src/pages/guides/index.astro +++ b/src/pages/guides/index.astro @@ -25,7 +25,7 @@ const description =

They assume the package is installed and describe the current release. If you want the architecture rather than the setup, that lives in{' '} - the design document. + the design document.

npm install -g agent-chaperone
@@ -68,11 +68,11 @@ const description =
  • - Design + Docs

    - The architecture, the exact wording of every screening question, the policy file and the - audit log format. + The design, with the exact wording of every screening question, the policy file and the + audit log format, plus the hooks reference and the benchmark method.

  • diff --git a/src/pages/guides/mcp-security.astro b/src/pages/guides/mcp-security.astro index 7827cdc..1e73fa5 100644 --- a/src/pages/guides/mcp-security.astro +++ b/src/pages/guides/mcp-security.astro @@ -1,6 +1,6 @@ --- import Base from '../../layouts/Base.astro'; -import { REPO, SHIPPED } from '../../data/benchmark'; +import { SHIPPED } from '../../data/benchmark'; import { findGuide, guideUrl } from '../../data/guides'; import { guideSchema } from '../../data/schema'; @@ -159,9 +159,8 @@ agent-chaperone wrap ~/.claude.json --write change, then the policy, then the task. Anything left over is forwarded.

    - The exact wording of every question is in{' '} - the design document, because a screen whose - questions you cannot read is asking you to trust a summary of them. + The exact wording of every question is in the design document, + because a screen whose questions you cannot read is asking you to trust a summary of them.

    @@ -270,8 +269,8 @@ agent-chaperone wrap ~/.claude.json --write .
  • - The design document, for the exact wording - of every question and the full policy file. + The design document, for the exact wording of every question and + the full policy file.
  • diff --git a/src/pages/guides/prompt-injection.astro b/src/pages/guides/prompt-injection.astro index 8aa1e9a..50e3960 100644 --- a/src/pages/guides/prompt-injection.astro +++ b/src/pages/guides/prompt-injection.astro @@ -1,6 +1,6 @@ --- import Base from '../../layouts/Base.astro'; -import { REPO, SETS, SHIPPED, caught, missed, flaggedInError } from '../../data/benchmark'; +import { SETS, SHIPPED, caught, missed, flaggedInError } from '../../data/benchmark'; import { findGuide, guideUrl } from '../../data/guides'; import { guideSchema } from '../../data/schema'; @@ -243,8 +243,7 @@ const benign = SETS.find((one) => one.id === 'benign');

    The false criterion on the main question, and the second question that was measured and - dropped for adding no signal, are both in{' '} - the design document. + dropped for adding no signal, are both in the design document.

    diff --git a/src/pages/guides/secret-exfiltration.astro b/src/pages/guides/secret-exfiltration.astro index 351fd12..64337a7 100644 --- a/src/pages/guides/secret-exfiltration.astro +++ b/src/pages/guides/secret-exfiltration.astro @@ -1,6 +1,6 @@ --- import Base from '../../layouts/Base.astro'; -import { REPO, SHIPPED } from '../../data/benchmark'; +import { SHIPPED } from '../../data/benchmark'; import { findGuide, guideUrl } from '../../data/guides'; import { guideSchema } from '../../data/schema'; @@ -275,8 +275,8 @@ const guide = findGuide('secret-exfiltration');

    The measured results for the call side are the hand-labeled set, scored at {SHIPPED.holdDestructive}, the stricter of the two call thresholds.{' '} - The design document has the exact wording of - each question and the full pattern list. + The design document has the exact wording of each question and the + full pattern list.

    diff --git a/src/pages/llms.txt.ts b/src/pages/llms.txt.ts index 7e56a9d..2ec3c4e 100644 --- a/src/pages/llms.txt.ts +++ b/src/pages/llms.txt.ts @@ -1,5 +1,7 @@ import type { APIRoute } from 'astro'; import { CURRENT_VERSION, NPM, REPO, RUN } from '../data/benchmark'; +import { DOCS } from '../data/docs'; +import { headlines } from '../data/doc-files'; import { GUIDES, SITE } from '../data/guides'; /** @@ -18,6 +20,7 @@ import { GUIDES, SITE } from '../data/guides'; const RAW = 'https://raw.githubusercontent.com/agent-chaperone/agent-chaperone/main'; export const GET: APIRoute = () => { + const named = headlines(); const body = `# agent-chaperone > agent-chaperone is an open-source npm package that screens an AI agent's tool calls before they run, and the tool results those calls return before the agent reads them. It covers MCP servers through a transparent proxy, and a client's own shell commands, file edits and web fetches through a hooks adapter. @@ -43,12 +46,12 @@ ${GUIDES.map((one) => `- [${one.h1}](${SITE}/guides/${one.slug}.md): ${one.blurb - [Overview](${SITE}/index.md): what it screens, what it is not, how it compares, and the shadow-to-enforce path - [Guides](${SITE}/guides.md): each setup, with what it covers and where it stops - [Measured results](${SITE}/results.md): the same tables as the HTML page +- [Docs](${SITE}/docs.md): the reference documents, copied from the repository ## Docs +${DOCS.map((one) => `- [${named[one.slug] ?? one.title}](${SITE}/docs/${one.slug}.md): ${one.blurb}`).join('\n')} - [README](${RAW}/README.md): install, the two screens, the commands, and the measured results -- [Design](${RAW}/docs/design.md): architecture, every screening question and its exact wording, the policy file, the audit log -- [Hooks](${RAW}/docs/hooks.md): screening a client's own tools, what each hook command answers, and what hooks cannot see - [Roadmap](${RAW}/ROADMAP.md): what each version shipped ## Measured diff --git a/src/pages/results.astro b/src/pages/results.astro index c564c7c..584e9eb 100644 --- a/src/pages/results.astro +++ b/src/pages/results.astro @@ -24,8 +24,8 @@ const description = `One run of ${RUN.model} on ${RUN.date}: what the screening

    This is one dated run, not a scoreboard. The recorded model responses are committed, so the - scorer reproduces these numbers with no API key.{' '} - The harness and the method are in the repository. + scorer reproduces these numbers with no API key. The method says + how, and the harness itself is in the repository.

    diff --git a/vercel.json b/vercel.json index b74564c..ea586cf 100644 --- a/vercel.json +++ b/vercel.json @@ -70,14 +70,9 @@ "destination": "https://www.npmjs.com/package/agent-chaperone", "permanent": true }, - { - "source": "/docs", - "destination": "https://github.com/agent-chaperone/agent-chaperone/blob/main/docs/design.md", - "permanent": true - }, { "source": "/hooks", - "destination": "https://github.com/agent-chaperone/agent-chaperone/blob/main/docs/hooks.md", + "destination": "/docs/hooks", "permanent": true }, {