Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 10 additions & 3 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Contributing to Agent Hook Spec
# Contributing to Agent Hook Unity

Thank you for your interest in improving the Agent Hook Spec. We welcome
Thank you for your interest in improving the Agent Hook Unity. We welcome
documentation corrections, schema and example improvements, feature proposals,
and fixes.

Expand All @@ -16,7 +16,7 @@ and fixes.
## Discussing ideas and reporting issues

Use [GitHub Discussions](https://github.com/trendmicro/agent-hook-unity/discussions)
for questions, ideas, use cases, and proposed changes to the Agent Hook Spec.
for questions, ideas, use cases, and proposed changes to the Agent Hook Unity.
Start a discussion before drafting an RFC so the community can help shape the
proposal.

Expand All @@ -33,6 +33,13 @@ For substantial changes to the protocol, schema, or semantics, follow the RFC
process in [GOVERNANCE.md](GOVERNANCE.md). A formal RFC pull request must link
to its prior GitHub Discussion.

The repository's existing unaccepted draft files include a consolidated
candidate described by [RFC 0007](rfcs/0007-core-draft-consolidation.md).
They are preparatory review material, not a record of completed governance.
Discussions was enabled on 2026-09-21; formal review still requires a linked
Discussion and the normal review window and votes. Do not mark a proposal
Accepted merely because its candidate files have been merged.

## Contributing changes

1. Fork the repository and clone your fork locally.
Expand Down
21 changes: 14 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Agent Hook Spec
# Agent Hook Unity

Agent Hook Spec is a community effort to define a portable lifecycle-hook
Agent Hook Unity is a community effort to define a portable lifecycle-hook
protocol for AI agents and their tooling. It will let agent builders describe
events, hook payloads, hook responses, and security telemetry using a shared,
interoperable model.
Expand All @@ -16,11 +16,17 @@ occur.

## Status

The repository contains an adoption-ready Agent Hook 0.1 draft proposed by
[RFC 0001](rfcs/0001-agent-hook-core-event-contract.md), with five additional
standard events proposed by
[RFC 0004](rfcs/0004-standard-lifecycle-events.md). It is not active until
accepted through the RFC process. Join the
The repository contains a candidate Agent Hook Unity 0.1 draft for review.
[RFC 0007](rfcs/0007-core-draft-consolidation.md) consolidates the original
RFC 0001 and RFC 0004 proposals with subsequent working-draft changes, the
12 Gate / 6 Observe registry, and the minimum cross-handler deny guarantee.
The canonical wire identifier is `agent-hook-unity/0.1`; see the
[migration guide](schemas/README.md#migrating-the-unaccepted-draft) before
upgrading an integration that uses the former `agent-hooks/0.1` identifier.

The candidate is not an active standard until accepted through the RFC
process. Working files and merged PRs do not substitute for recorded review
and votes. Join the
[GitHub Discussions](https://github.com/trendmicro/agent-hook-unity/discussions)
to help shape it.

Expand All @@ -30,6 +36,7 @@ to help shape it.
- [`spec/`](spec/README.md) — canonical normative specification Markdown.
- [`schemas/`](schemas/README.md) — machine-readable JSON Schemas.
- [`fixtures/`](fixtures/README.md) — schema-validation fixtures.
- [`conformance/`](conformance/gate-composition.md) — behavioral scenarios for host integration tests; not an executed runtime claim.
- [`examples/`](examples/README.md) — illustrative integrations.
- [`website/`](website/) — Docusaurus source for the GitHub Pages site.

Expand Down
64 changes: 64 additions & 0 deletions conformance/gate-composition.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
# Agent Hook Unity Core Gate composition scenarios

These behavioral scenarios exercise the minimum composition rules in the Agent
Hook Unity 0.1 draft. They do not define a reference reducer, handler scheduler,
or mutation algorithm. A host harness that claims to test Core Gate composition
MUST cover every scenario whose decision or rewrite form applies to the Gate
capabilities it declares. It MUST record the host version, adapter version,
capability mode, handler set, scheduling mode, and configured deadlines used for
the run. Passing these scenarios is useful evidence, not by itself a claim of
runtime conformance.

All example events use `spec: "agent-hook-unity/0.1"`. `A` and `B` are
handlers. `D1`, `D2`, and `D3` are distinct schema-valid UUID `event_id` values.
Unless a scenario says otherwise, the events describe one pending action at one
Gate boundary, all responses are schema-valid and correlated to their own
delivery, no native policy independently blocks the action, and no approval is
outstanding.

Every enforcement scenario below requires a host declaration of `gate` at the
tested boundary. A registry Gate exposed by the host as `observe` is covered
by the final isolation case, not by an obligation to enforce its responses.

The consolidation that introduces these obligations is tracked by
[draft RFC 0007](../rfcs/0007-core-draft-consolidation.md). The RFC remains
unaccepted.

The approval scenario applies to `BeforeModelRequest`, `PreToolUse`,
`PreNetworkAccess`, `PreMemoryWrite`, and `PreConfigChange`, whose canonical
response shapes support `ask` and `defer`. Rewrite scenarios apply only to
`UserPromptSubmit` (`updatedPrompt`), `BeforeModelRequest` (`updatedMessages`),
`AfterModelResponse` (`updatedResponse`), `PreToolUse` and `PermissionRequest`
(`updatedInput`, plus `updatedPermissions` for `PermissionRequest`),
`PostToolUse` (`updatedOutput`), and `PreMemoryWrite` (`updatedContent`).

## Required scenarios

| Scenario | Harness stimulus | Required observation |
| --- | --- | --- |
| Sequential allow then deny | Deliver the pending action to A as D1 and accept `allow`. Deliver it to B as D2 and accept `deny`. | The host does not cross the Gate. It waits for B instead of treating A's earlier `allow` as final permission. |
| Sequential deny then allow | Deliver the pending action to A as D1 and accept `deny`, then obtain `allow` from B as D2 if the host continues scheduling. | The host does not cross the Gate. B's later `allow` does not clear A's denial. The host may short-circuit B only after the action is irrevocably denied. |
| Parallel outcomes | Invoke A and B in parallel. Exercise both completion orders with one valid `allow` and one valid `deny`; repeat with the other outcome replaced by a timeout or handler error. | Every run containing an accepted denial prevents the action, independent of completion order. A timeout or error supplies no result and does not erase the denial. |
| Invalid or mismatched response | A returns a schema-invalid response or a response correlated to a different `event_id`; B returns a valid `deny` for D2. Repeat with B returning `allow`. | The invalid or mismatched response supplies no result. The valid denial prevents the action. With only B's valid `allow`, the response failure does not independently deny the action. |
| Timeout only | Every applicable handler invocation reaches its declared deadline without a usable response, with no accepted denial, unresolved approval, or native restriction. | The timeouts supply no Agent Hook decision. The Core default permits the host to continue after the deadlines; the harness does not report the timeouts as approval decisions. |
| Approval remains unresolved | For a Gate whose response shape supports `ask` and `defer`, A returns `ask`. Exercise an interactive host while approval is pending, and a non-interactive host without native suspension. Also exercise `defer` while native policy has not resolved. | The interactive host does not cross the Gate while approval is pending. The non-interactive host treats `ask` as denial. `defer` does not count as approval. |
| Deadline and late denial | A returns `allow` promptly. B returns `deny` immediately before B's declared deadline. Repeat with B returning only after the deadline and after the host has crossed the Gate under the timeout rule. | The host waits through B's deadline and honors the on-time denial. A response after the expired invocation cannot retroactively undo an action already performed; if the host performs a new reevaluation, it uses a new delivery and applies that evaluation before crossing the still-pending boundary. |
| Redelivery with distinct event IDs | Deliver the same pending action and boundary as D1 and accept `deny`; redeliver it as D2 and receive `allow`. For events with `operation_id`, retain the same value. | D1 and D2 remain separately correlated deliveries, while the D1 denial remains binding to the same pending action. The host does not cross the Gate. |
| Reevaluation after change | Accept `deny` for D1. Change a target or proposed value in a way that requires reevaluation of the same pending action, deliver D2, and receive `allow`. | The host performs the required reevaluation but does not clear the earlier denial. Re-proposing the work as a truly new action requires treating it as a distinct underlying action, using a distinct correlation identifier where Core defines one, and obtaining all applicable decisions again. |
| Same operation, distinct Pre and Post boundaries | For one `operation_id`, accept `allow` at `PreNetworkAccess`, complete the request on a buffered transport, then accept `deny` at `PostNetworkAccess`. | The request may be dispatched after the Pre Gate permits it. The Post denial prevents response delivery to the caller and does not claim rollback of the request. A Pre denial instead prevents dispatch and produces no Post event as execution evidence. The shared `operation_id` does not merge the two pending actions. |
| Unrelated operations | Deny operation X at a Gate, then evaluate unrelated operation Y at the same event boundary with a distinct operation identity and accept `allow`. | X remains denied. X's denial does not deny Y; Y proceeds only after its own applicable handler outcomes, approvals, and native policy permit it. |
| Rewrite plus response failure | For a Gate with an event-supported rewrite, A returns a valid `allow` with that rewrite. B times out or returns an invalid response. | B supplies no result and does not silently restore the original value. If the action is otherwise permitted, the host carries A's accepted rewrite into its host-defined mutation ordering and native validation. If native validation of the value to be committed fails, the host fails closed as required by Core. |
| Conflicting rewrites and denial | For a Gate with an event-supported rewrite, A and B return different valid rewrites under each scheduling mode the host supports; add a valid denial from either handler in a second run. | The host applies its own ordering or conflict policy and native validation in the first run. The denial prevents the action in the second run regardless of which rewrite would otherwise win. |

### Observe isolation

Expose a registry Gate as `observe`, or use an Observe event. Return
schema-valid control responses, including a deny and event-supported rewrite
fields. The host MUST ignore these responses for control purposes and make no
Gate enforcement claim for this capability. Native policy remains independent.

For Post Gates, “cross the Gate” means delivery, rendering, or context
ingestion, not rollback of the completed inference, tool execution, or network
request. The `PostNetworkAccess` cases exercise delivery control on a buffered
transport only. They do not require response-body fields, inspection, or
rewriting, which remain outside the current Core behavior.
74 changes: 74 additions & 0 deletions docs/superpowers/plans/2026-09-21-core-draft-consolidation.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# Core Draft Consolidation Implementation Plan

> **For agentic workers:** Use superpowers:subagent-driven-development to implement the independent tasks and review the combined change.

**Goal:** Resolve the four PM findings against main `08ecf2973ed8a3fb7b09f7a8f3a9450f2ea206b3` with a coherent, explicitly unaccepted draft baseline.

**Architecture:** Keep this repository a specification and schema project. Clarify the minimum host composition invariant, synchronize consumer guidance, and introduce the user-approved `agent-hook-unity/0.1` identity. Record the provenance and outstanding adoption decisions in consolidation RFC 0007 without inventing review dates or votes.

**Tech Stack:** Markdown, JSON Schema Draft 2020-12, Node.js validation, Docusaurus.

**Spec:** User-approved PM-feedback assessment in this task; normative source files in `spec/0.1/` and the proposed consolidation in `rfcs/0007-core-draft-consolidation.md`.

## Global Constraints

- Preserve 18 Core events: 12 Gate and 6 Observe; per-host capabilities remain explicit.
- Preserve supported legacy nested control when top-level decision is absent.
- A valid denial of the same pending action survives other handler outcomes and redelivery; timeout alone retains baseline fail-open behavior.
- Preserve native policy and unresolved approval restrictions; no action execution before required decisions finish or reach their declared deadlines.
- Do not claim runtime conformance from schema validation or a reference reducer.
- Keep RFCs Draft and review/vote metadata truthful. No fabricated acceptance or external publication.
- New wire identity: `agent-hook-unity/0.1`; canonical schema IDs use the existing `agent-hook-unity` Pages paths. Do not silently negotiate the colliding old identity.
- Product repositioning and full Responsible AI interoperability remain an explicitly separate design question.

## Task 1: Core composition and behavioral conformance

**Files:** `spec/0.1/core.md`, `spec/0.1/events.md`, `spec/0.1/security.md`, `website/docs/conformance.md`, `conformance/`.

- [x] Define accepted valid deny as binding to the host's same pending action, across per-handler event IDs, retries of delivery, and reevaluation.
- [x] Qualify every fail-open continuation with other applicable decisions and independent native policy; distinguish timeout from permission.
- [x] Leave scheduling and mutation conflict resolution host-defined subject to deny preservation and existing approval rules.
- [x] Replace stale unresolved rewrite-validation language with the current fail-closed requirement.
- [x] Publish behavioral test scenarios for allow/deny order, failures, parallel outcomes, deadlines, redelivery, and distinct operations; label them as obligations for a host harness.

## Task 2: Consumer-facing baseline synchronization

**Files:** `spec/0.1/index.md`, `spec/0.1/adapters.md`, `examples/`, `website/docs/intro.md`, `website/docs/responses.md`, `website/docs/capabilities.md`.

- [x] Align event modes and result-delivery semantics with the registry; remove stale seven/eleven counts.
- [x] Use canonical top-level decisions in examples and explicitly explain nested legacy fallback.
- [x] Align adapter and capability guidance with all current Gate controls and supported rewrites.
- [x] Explain draft status, partial RFC 0005 implementation, consolidation provenance, and safe host capability claims.

## Task 3: Mechanical regression checks

**Files:** `scripts/validate.mjs`, focused validator helpers/tests if needed, `package.json`.

- [x] Demonstrate failing checks for mismatched published schema copies and registry/schema event drift before implementing them.
- [x] Derive the active identity from canonical schemas and validate current Markdown JSON examples against it, detecting stale envelope identifiers instead of silently skipping them.
- [x] Check event counts where summarized and canonical Gate membership where mirrored; avoid enforcing arbitrary prose wording.
- [x] Verify the validator with deliberate temporary mutations in isolated test data, including newly introduced or removed events and missing files.

## Task 4: Consolidation RFC, identity migration, publication guidance

**Files:** `rfcs/0007-core-draft-consolidation.md`, existing RFC baseline/status summaries, `schemas/`, `fixtures/`, published schema copies, active identifier references, root and website status guidance.

- [x] Record which behavior came from PR #9, which RFC 0005 features remain proposals, and what RFC 0006 actually proposes.
- [x] Document new Core deny invariant, identity migration, schema locations, compatibility impact, and explicitly pending review requirements.
- [x] Move canonical `spec` constants and current examples to `agent-hook-unity/0.1`; add invalid fixtures for the former colliding identity.
- [x] Change schema IDs to their current published URLs; link immutable pre-migration schemas for pinned old integrations and explain that `$id` is not a retrieval requirement.
- [x] Document the future telemetry/correlation interoperability evaluation without claiming an adapter or external certification exists.

## Exit Gate

- [x] Simplify for reuse, quality, and efficiency; remove redundant checks and contradictory claims.
- [x] Run focused validator tests, `npm run validate`, `npm run build`, and `git diff --check`.
- [x] Run scoped independent `codex exec -p review` diff review; fix findings and re-review until Mergeable.
- [x] Report concrete changes, checks, review verdict, and remaining external adoption/publication steps.

Validation: 14 validator regression tests, schema/fixture/Markdown validation,
image parser guards, the website production build, and five executable
PreToolUse example cases passed. The independent review profile returned
**Mergeable** with zero findings after the two initial findings were fixed.
This branch prepares the candidate only; RFC acceptance, a tested external
adapter, and publication after merge remain separate steps.
5 changes: 4 additions & 1 deletion examples/README.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
# Examples

This directory contains non-normative, runnable or copyable examples of Agent
Hook behavior. The initial 0.1 draft includes a
Hook Unity behavior. The initial 0.1 draft includes a
[pre-tool security guard](./pre-tool-guard.md) and a
[post-tool audit event](./post-tool-audit.md).

Examples must identify the specification and schema version they target, and
must not introduce behavior absent from the canonical specification.
Current examples target the unaccepted `agent-hook-unity/0.1` draft. A host's
declared capability still determines whether a registry Gate is enforced or
delivered for observation only.
10 changes: 7 additions & 3 deletions examples/post-tool-audit.md
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
# Post-tool audit event

This non-normative example records a successful tool invocation after it has
completed. `PostToolUse` is an Observe event, so the handler returns
completed. The registry classifies `PostToolUse` as a Gate, but the host in
this example declares it `observe`: it can report the completed invocation but
cannot hold the result before context ingestion. The handler therefore returns
correlated metadata rather than a control response.

Event delivered by the adapter:

```json
{
"spec": "agent-hooks/0.1",
"spec": "agent-hook-unity/0.1",
"event_id": "862a966f-6f7b-4c15-a8c5-40df353eeaac",
"hook_event_name": "PostToolUse",
"session_id": "session-42",
Expand All @@ -26,7 +28,7 @@ Response from the audit handler:

```json
{
"spec": "agent-hooks/0.1",
"spec": "agent-hook-unity/0.1",
"event_id": "862a966f-6f7b-4c15-a8c5-40df353eeaac",
"metadata": {
"audit_id": "audit-20260909-17",
Expand All @@ -37,3 +39,5 @@ Response from the audit handler:

Handlers should not copy raw prompts, tool arguments, outputs, or credentials
into audit records unless a documented privacy policy permits it.
Because this delivery is `observe`, any response control fields would be
ignored. The completed tool execution also cannot be rolled back.
Loading
Loading