# Agent Hook Control Plane

## Metadata

- Category: Research Control Plane
- Status: verified from official hook docs and repository configuration
- Last updated: 2026-06-07
- Main local files:
  - `AGENTS.md`
  - `CLAUDE.md`
  - `.claude/settings.json`
  - `.codex/hooks.json`
  - `scripts/hooks/research-control.py`
  - `advanced-site/Claude-Code-Analysis.html`
  - `knowledge-base/index.md`

## Summary

This repository now has a shared research-control hook layer for Claude Code and Codex.
The goal is not to silently rewrite the knowledge base or public HTML after every turn.
The goal is to add a lifecycle control point that keeps research sessions from ending
without deciding whether a durable finding should be preserved.

The default public-facing target is:

```text
advanced-site/Claude-Code-Analysis.html
```

The durable knowledge-base target is:

```text
knowledge-base/
knowledge-base/index.md
```

## Configuration Surfaces

Claude Code reads project hooks from:

```text
.claude/settings.json
```

Codex reads project hooks from:

```text
.codex/hooks.json
```

Both configurations call the same script:

```text
scripts/hooks/research-control.py
```

Root-level instruction files provide static guidance:

```text
AGENTS.md
CLAUDE.md
```

This split keeps static repository rules separate from lifecycle enforcement.

## Hook Events

### SessionStart

Adds context at session start:

- durable findings go into `knowledge-base/`
- new topic files must be linked from `knowledge-base/index.md`
- `advanced-site/Claude-Code-Analysis.html` is the external explanation target
- a final answer should say why no KB or HTML update is needed if none was made

### UserPromptSubmit

Checks whether the submitted prompt looks like repository research.
When it does, it injects a short checklist into the model context instead of
blocking immediately.

### PostToolUse

Checks successful write/edit events.
When a knowledge-base file or `Claude-Code-Analysis.html` changes, it reminds the active
agent to keep the index, evidence links, and public explanation aligned.

### Stop

Acts as the hard checkpoint.

It blocks stopping when:

- a new `knowledge-base/*.md` topic file exists but `knowledge-base/index.md` was not updated
- a new durable research note exists but `advanced-site/Claude-Code-Analysis.html` was not updated and the final answer does not explain why
- the session appears to have researched repository internals but no KB or HTML update exists and the final answer does not explain why

The script checks `stop_hook_active` when present so it does not create an
unresolvable stop-hook loop.

## Flow

```mermaid
flowchart TD
  A["Claude or Codex session"] --> B["Static repo guidance"]
  B --> C["AGENTS.md / CLAUDE.md"]
  A --> D["Lifecycle hook config"]
  D --> E[".claude/settings.json / .codex/hooks.json"]
  E --> F["scripts/hooks/research-control.py"]
  F --> G{"Event"}
  G --> H["SessionStart: inject control context"]
  G --> I["UserPromptSubmit: detect research prompt"]
  G --> J["PostToolUse: check edited artifacts"]
  G --> K["Stop: block unresolved research closeout"]
  K --> L["knowledge-base/"]
  K --> M["knowledge-base/index.md"]
  K --> N["advanced-site/Claude-Code-Analysis.html"]
```

## Evidence Map

| Claim | Evidence |
|---|---|
| Claude and Codex use separate project hook config surfaces. | `.claude/settings.json`, `.codex/hooks.json` |
| Both tools share one control script. | `scripts/hooks/research-control.py` |
| New topic notes must be indexed. | `knowledge-base/agents.md`, `knowledge-base/claude.md`, `knowledge-base/index.md` |
| `Claude-Code-Analysis.html` is the default public-facing target. | `AGENTS.md`, `CLAUDE.md`, `advanced-site/Claude-Code-Analysis.html` |
| The hook prefers checkpoint feedback over silent autonomous rewrites. | `scripts/hooks/research-control.py` |

## Operational Notes

- Hook output is JSON so Claude Code and Codex can treat the result as structured lifecycle feedback.
- The hook uses local git status to detect changed KB and HTML artifacts.
- The hook is intentionally conservative about file edits. It asks the active agent to finish the update rather than writing large KB or HTML sections itself.
- Project-local Codex hooks require the project `.codex/` layer to be trusted before they load.
- Claude Code hooks can be inspected with `/hooks`.

## Open Questions

- Whether future Codex versions expose richer hook output fields that should replace the currently shared Claude-style JSON shape.
- Whether `PostToolUse` should also watch Bash commands that generate files indirectly.
- Whether a future dedicated renderer should regenerate `Claude-Code-Analysis.html` from structured knowledge-base metadata instead of maintaining it manually.
