diff --git a/scripts/indexnow.mjs b/scripts/indexnow.mjs index 58dc444..77a4f60 100644 --- a/scripts/indexnow.mjs +++ b/scripts/indexnow.mjs @@ -38,6 +38,7 @@ const URLS = [ `https://${HOST}/guides/prompt-injection`, `https://${HOST}/guides/claude-code`, `https://${HOST}/guides/secret-exfiltration`, + `https://${HOST}/guides/ecc`, ]; /** diff --git a/src/data/guides.ts b/src/data/guides.ts index a59204e..f60d44e 100644 --- a/src/data/guides.ts +++ b/src/data/guides.ts @@ -57,6 +57,15 @@ export const GUIDES: readonly Guide[] = [ blurb: 'Reading a file and posting to a URL are both ordinary. The pair is the problem, and a list of allowed tools cannot express it.', }, + { + slug: 'ecc', + h1: 'Run agent-chaperone alongside ECC', + title: 'Run agent-chaperone alongside ECC | agent-chaperone', + description: + "Add runtime screening next to ECC's hooks. What AgentShield, GateGuard and agent-chaperone each check, how their hooks run together, and how to start without blocking anything.", + blurb: + "ECC checks your setup and makes the agent look before it edits. This checks what each call does and what each result says, and runs next to ECC's hooks without changing them.", + }, ]; export const SITE = 'https://agentchaperone.dev'; diff --git a/src/data/schema.ts b/src/data/schema.ts index 38e4f6b..bd756ad 100644 --- a/src/data/schema.ts +++ b/src/data/schema.ts @@ -187,7 +187,7 @@ export function guideSchema(guide: Guide): unknown { * The guides index. * * `CollectionPage` naming every member, so a reader that fetches this one page - * comes away knowing the other four exist and what each answers, rather than + * comes away knowing the others exist and what each answers, rather than * having to crawl the section to find out. */ export function guidesIndexSchema(): unknown { @@ -201,7 +201,7 @@ export function guidesIndexSchema(): unknown { '@id': GUIDES_ID, name: 'agent-chaperone guides', description: - "Setting up screening for MCP servers, for a client's own shell and file tools, for prompt injection arriving in tool results, and for secrets on their way out.", + "Setting up screening for MCP servers, for a client's own shell and file tools, for prompt injection arriving in tool results, for secrets on their way out, and next to ECC's hooks.", url: `${SITE}/guides`, isPartOf: { '@id': SITE_ID }, about: { '@id': APP }, diff --git a/src/pages/guides/ecc.astro b/src/pages/guides/ecc.astro new file mode 100644 index 0000000..0609116 --- /dev/null +++ b/src/pages/guides/ecc.astro @@ -0,0 +1,187 @@ +--- +import Base from '../../layouts/Base.astro'; +import { REPO } from '../../data/benchmark'; +import { findGuide, guideUrl } from '../../data/guides'; +import { guideSchema } from '../../data/schema'; + +const guide = findGuide('ecc'); +const ECC = 'https://github.com/affaan-m/ECC'; +const AGENTSHIELD = 'https://www.npmjs.com/package/ecc-agentshield'; +--- + + +
+

{guide.h1}

+

+ ECC, Everything Claude Code, installs a large set of Claude Code hooks, and + two of the security pieces it ships are AgentShield and GateGuard. agent-chaperone installs + next to it and screens something neither of those looks at: what each tool call is about to + do, and what each result says, as they happen. +

+

+ The two run side by side and stay independent. Nothing in ECC changes, ECC does not know + agent-chaperone is there, and this is not an integration its maintainers have reviewed. It is + two plugins whose hooks both fire. +

+
+ +
+

+ What each one checks{' '} + + # + +

+ +

+ None of the three substitutes for another. A configuration can pass a scan and a call can + follow a thorough investigation, and the call can still be the one that posts a key to a + stranger, because the instruction to do it arrived in a page the agent fetched a minute + earlier. +

+
+ +
+

+ Install it next to ECC{' '} + + # + +

+

From inside a Claude Code session:

+
{`/plugin marketplace add agent-chaperone/agent-chaperone
+/plugin install agent-chaperone@agent-chaperone`}
+

+ That registers three hooks: one before shell commands, file edits and web fetches, and two + after shell commands, file reads and web fetches, including ones that failed. It brings the + agent-chaperone skill as well, which tells the agent what to do when a call is held. +

+

+ If agent-chaperone is installed globally the plugin uses that. Otherwise the + first screened call installs the matching version into the plugin's own data directory, which + took 13 seconds when I measured it, and every call after that runs it directly in about a + seventh of a second. Uninstalling the plugin removes all of it. +

+

+ Registering the hooks by hand works too, and{' '} + the Claude Code guide has the configuration and what each + entry is for. +

+
+ +
+

+ How the two sets of hooks run together{' '} + + # + +

+

+ Claude Code runs every hook whose matcher fits a call, from every plugin and every settings + file, in parallel. On shell commands, edits and writes, ECC's hooks and agent-chaperone's both + fire. +

+ +

+ Claude Code's documentation does not say how it combines an ask from one hook with a deny from + another. So do not build anything that depends on an order between ECC's hooks and these. +

+
+ +
+

+ Start by reading, not blocking{' '} + + # + +

+

+ Probabilistic screens get some calls wrong, and the only honest way to choose where the lines + go is on your own traffic. Leave it in shadow for a while, then: +

+
agent-chaperone report
+

+ That leads with what enforcement would have stopped and did not. If a line looks wrong, move + its threshold with agent-chaperone replay --policy candidate.yaml, which decides + again over what was already judged and shows which way each decision moves. When the log stops + surprising you, set mode: enforce in the policy file. +

+

+ The model screens need a TYPESAFE_API_KEY in the environment Claude Code starts + hooks in. Without one the deterministic rules still run, which is the allow and deny lists, + the secret patterns, dangerous shell forms and hidden text, and every judgment records that no + model was asked. +

+
+ +
+

+ What this does not cover{' '} + + # + +

+ +

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

+
+ diff --git a/src/pages/guides/index.astro b/src/pages/guides/index.astro index 5d043a0..57509bb 100644 --- a/src/pages/guides/index.astro +++ b/src/pages/guides/index.astro @@ -6,7 +6,7 @@ import { guidesIndexSchema } from '../../data/schema'; const title = 'Guides | agent-chaperone'; const description = - 'Setting up screening for MCP servers, for a client’s own shell and file tools, for prompt injection arriving in tool results, and for secrets on their way out.'; + 'Setting up screening for MCP servers, for a client’s own shell and file tools, for prompt injection arriving in tool results, for secrets on their way out, and next to ECC’s hooks.'; ---

Guides

- Four things people set this up to do. Each one says what it covers, what the configuration - looks like, and where it stops, which is the part most of this kind of writing leaves out. + What people set this up to do. Each one says what it covers, what the configuration looks + like, and where it stops, which is the part most of this kind of writing leaves out.

They assume the package is installed and describe the current release. If you want the diff --git a/src/pages/llms.txt.ts b/src/pages/llms.txt.ts index e50399d..7e56a9d 100644 --- a/src/pages/llms.txt.ts +++ b/src/pages/llms.txt.ts @@ -41,7 +41,7 @@ ${GUIDES.map((one) => `- [${one.h1}](${SITE}/guides/${one.slug}.md): ${one.blurb ## This site, as markdown - [Overview](${SITE}/index.md): what it screens, what it is not, how it compares, and the shadow-to-enforce path -- [Guides](${SITE}/guides.md): the four setups, each with what it covers and where it stops +- [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