Tamper-evident tool-call records behind HookRunner / EventLog
Nobody has claimed this yet.
- Dominant language
- Go
- Stars
- 152
- Forks
- 16
- Avg merge
- 14h 48m
- Merged PRs (30d)
- 536
Description
Opening this per CONTRIBUTING to agree on scope before any code; I'd plan to implement whichever shape you pick.
Think of the harness as a workshop and the event log as the shop's own logbook. This stations a notary at the bench: one sealed slip when a tool is handed over, one when it comes back, stapled together by the first slip's own fingerprint.
docs/agent-identity-model.md names the gap: "The audit trail is the harness's word. The event log records what happened, but it is self-attested. An operator, auditor, or downstream service cannot verify that a given action traces back through a specific subagent, agent, and user."
What this would add. Each tool call becomes a signed, content-addressed record. At PreToolUse: a planned record binding the tool name, CallID, and a digest of Input. At PostToolUse: an outcome record with a digest of the result and confirmed/failed from IsError (both already on the PostToolUse Input payload), carrying the planned record's content address as its parent; CallID is only the lookup key that finds which planned record to point at, the link itself is the content address, verified by recomputation. A third party with the issuer's public key verifies tamper-evidence, chain order, and non-repudiation of each record after the fact, without the harness's log. It is not independence from the harness — a key the harness holds is still the harness signing — which is why who holds the key is #478's question and this composes with it rather than competing. Nor is it the "traces back through a specific subagent, agent, and user" half of your gap: SessionID and user identity do not enter the record as fields (anything inside a tool payload is committed only within the payload digest); attribution is the issuer's job, not the record's.
The format is an individual IETF Internet-Draft, work in progress and not WG-adopted, profiling SCITT signed statements: draft-mih-scitt-agent-action-capsule-04 (https://datatracker.ietf.org/doc/draft-mih-scitt-agent-action-capsule/). The Go producer is action-state-group/capsule-emit-go (Apache-2.0; depends on veraison/go-cose and fxamacker/cbor; not yet tagged as a release, which I'd fix before proposing anything in-tree). The Python producer, capsule-emit, ships the same planned→outcome shape for other frameworks and carries the verifier; the emit→verify round-trip test lives in the out-of-tree repo's CI, so nothing here ever puts Python in your test matrix.
Two shapes, both on ports you already ship.
port.HookRunner: a native GoHookRunneron capsule-emit-go, out of tree, in-process.port.EventLog/port.ToolCallRecorder: seal at the durable append rather than in the request path. I'd want your read on which process that lives in — if the durable append is at the relay per AGENTS.md, this is a relay-side implementation, not a loop-side port — and whether the log carries the pre-call event; if it only sees completed calls, shape 2 emits one record per call rather than a planned/outcome pair.
Non-goals and limits. Records only; never blocks or mutates (that stays with the guardrail checker and permission policy). Only digests are sealed — data minimization, not confidentiality; low-entropy inputs like paths or short commands would need salted commitments, which the producer supports. Fail-open by default: if the recorder is unavailable the call proceeds, and a gap shows as a planned CallID with no outcome record — veto that default if you'd rather. Individual records are verifiable; that nothing was omitted is not, and that is what registration with a transparency service buys, deferred here.
Questions. Which port, and which process for shape 2? Out of tree is my proposal, with a link from the extension-points docs if you keep a list of community implementations; in-tree only if you'd want it, wherever you'd put it.
Disclosure: I co-maintain capsule-emit and am on a paid engagement with Action State Group.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with docs/agent-identity-model.md and AGENTS.md, then inspect the port.HookRunner, port.EventLog, and port.ToolCallRecorder entry points. Resolve which port and process owns the work, and whether pre-call events are available, before defining scope. Done means an agreed implementation shape with its verification, attribution, and fail-open behavior specified.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- cryptography, go
- Domain
- backend-api-design, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100