Skip to content
Open
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
7 changes: 7 additions & 0 deletions codex-plugin/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,13 @@ register as a single user-level guard for UI work:
- `PreToolUse` blocks edits to UI files until `accessibility-lead` has been dispatched in that same turn.
- `Stop` blocks final answers until `accessibility-lead` and required specialists have completed.

Codex surfaces that provide collaboration agents without emitting custom-subagent
lifecycle hooks can forward a review to the same guard over stdin using the
`AccessibilityReviewReceipt` event. Set `receipt_source` to
`codex-collaboration`, provide the tracked `agent_type`, and send `state` as
`started` or `completed`. Send completion only after the agent returns its final
result. Unknown sources, states, and agent types are ignored.

This is intentionally paired with the router skill. The hook enforces the rule at the edit boundary, while the router still owns the dispatch plan and specialist selection. If Codex has lazy-loaded the subagent tool, the router must use `tool_search` before claiming subagents are unavailable.

The Codex plugin manifest does not advertise hooks directly. The universal installer writes the hook guard into `~/.codex/hooks.json` because current Codex builds load normal hooks consistently while plugin-bundled hooks can also be loaded in some sessions, which would duplicate `UserPromptSubmit` context. Codex requires users to review and trust non-managed command hooks before they run. After the hook is trusted, users should not need to manually name every specialist for ordinary UI accessibility work.
Expand Down
11 changes: 11 additions & 0 deletions codex-plugin/hooks/a11y-codex-dispatch-guard.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,23 @@ if (eventName === "UserPromptSubmit") {
handleSubagentLifecycle(input, "started");
} else if (eventName === "SubagentStop") {
handleSubagentLifecycle(input, "completed");
} else if (eventName === "AccessibilityReviewReceipt") {
handleAccessibilityReviewReceipt(input);
} else if (eventName === "PreToolUse") {
handlePreToolUse(input);
} else if (eventName === "Stop") {
handleStop(input);
}

function handleAccessibilityReviewReceipt(input) {
const state = input.state === "started" ? "started" : input.state === "completed" ? "completed" : "";
const agentType = String(input.agent_type || "");
if (input.receipt_source !== "codex-collaboration" || !state || !isTrackedAgent(agentType)) {
return;
}
handleSubagentLifecycle(input, state);
}

async function readJsonFromStdin() {
let raw = "";
for await (const chunk of process.stdin) {
Expand Down
1 change: 1 addition & 0 deletions scripts/codex-accessibility-dispatch-smoke.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,7 @@ for (const phrase of [
"look for",
"selectRequiredSpecialists",
"modal-specialist",
"AccessibilityReviewReceipt",
]) {
if (!hookScript.includes(phrase)) {
fail(`${hookScriptPath}: missing dispatch guard phrase "${phrase}".`);
Expand Down
Loading