Skip to content

Latest commit

 

History

1 Commit

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 

Repository files navigation

hook-contracts

What each agent CLI's hooks actually send — recorded from live sessions, once a day, and published here as pack.json.

This repo holds data, not code. It is written by the contracts lab, a job that runs in failproofai's integration suite.

Why it exists

failproofai enforces policies by reading the payloads agent CLIs hand to their hooks — a shell command here, a file path there. Every one of those reads depends on a translation written against one version of one CLI, verified once, live, and then left alone.

Vendors move. When GitHub Copilot 1.0.71 renamed a file tool's file_path to path, the hooks kept firing, the CLI kept reporting success, and the policy that blocks reading .env files quietly stopped matching anything. Nothing failed. That is the shape of the problem: enforcement does not break loudly, it goes inert.

A machine cannot notice this about itself. It only ever sees the payloads its own agents happen to produce, and if a vendor rejects a hook config outright it sees nothing at all — which looks exactly like a quiet day. So the observation has to happen somewhere that drives every CLI deliberately. That is the lab, and this is what it found.

pack.json

{
  "generatedAt": "2026-08-18T06:00:00.000Z",
  "clis": {
    "goose": {
      "version": "1.43.0",
      "hooks": {
        "PreToolUse": {
          "envelope": ["event", "session_id", "tool_input", "tool_name", "working_dir"],
          "tools": { "write": ["content", "path"] }   // the vendor's own names
        }
      },
      "probe": { "verdict": "OK", "note": "tool ran and we were called" }
    }
  }
}

Key names only — never values. The lab records the shape of a payload, not its contents, so nothing here can carry a path, a command, or anything else from the session that produced it.

verdict says whether that entry can be trusted:

OK a tool ran and the vendor called our hook — the entry describes a real session
DRIFT the tool ran and no hook arrived; the vendor no longer accepts our config
INCONCLUSIVE hooks fired but the model never used a tool; nothing to record
ERROR the CLI could not be driven at all

There is deliberately no schema version. Consumers ignore fields they do not recognise, which is what lets this file grow without a coordinated release on the other side.

Two branches, two channels

Branch What it is Who follows it
packs The lab pushes here unattended, the moment it measures a change. Cuts a prerelease. failproofai's own machines
main Reached only by a reviewed pull request from packs. Cuts the release. Everyone else

releases/latest skips prereleases, so the split needs no extra machinery: a pack from a lab run that went wrong cannot become the one client machines resolve to. It has to be promoted first, and promotion takes two independent agreements —

  1. a machine that runs these CLIs for real compares the pack against its own accumulated observations and agrees with it, and
  2. a human reads the diff and approves the pull request.

Step 2 is not politeness. The diff is the vendor's own key names, so approving it is a person agreeing that somebody else shipped a change.

What a release means

pack.json is compared before it is committed, with generatedAt removed — so a run that finds everything unchanged pushes nothing. A commit here means a vendor's contract actually moved.

If releases ever start appearing daily, that property has been lost and the notification has stopped being worth reading.

Using it

curl -sL https://github.com/FailproofAI/hook-contracts/releases/latest/download/pack.json

failproofai fetches this on a schedule and reports anything in it that its own translation maps can no longer read. See failproofai doctor.

About

What each agent CLI's hooks actually send today. Published by the failproofai contracts lab; a release means a vendor's contract moved.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors