You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Our 11 guardrail hooks (hooks/hooks.json) are distributed by registering them into the per-user ~/.claude/settings.json via scripts/install-hooks.py --fix. That model cleanly covers exactly one world: Claude Code sessions on a machine where ai-config is installed at ~/.claude (the laptop-dev case). It fits poorly everywhere the frontier has moved. This issue asks us to decide the mechanism; it is decision-shaped with a real do-nothing option, so it may be better as a Q&A discussion (see "Venue" below).
Evidence (measured this session, in a cloud sandbox)
install-hooks.py reported registered=0 missing=11 -- none of the declared hooks were active.
~/.claude/settings.json does not exist in the container; the two hooks that do fire every session (session-start.sh, check-install.sh) persist only because they live in the repo's committed .claude/settings.json.
command_for() emits python3 "$HOME/.claude/hooks/<script>", so every hook command is coupled to an ai-config install existing at ~/.claude.
The three environments the current model misses
Ephemeral cloud sandboxes.~/.claude is wiped each session, so a user-level registration does not persist -- install-hooks.py --fix would be a per-session chore that dies with the container.
Other repos. User-level registration is machine-wide if ai-config is installed at ~/.claude; in a sandbox for another repo (bcs, gha, ...) there is no ai-config checkout, so the command path points at a missing script. Project-level committed .claude/settings.json persists but is per-repo, and would need replicating into every repo (with the same broken script-path dependency).
Non-Claude runtimes (codex). These are Claude Code hooks (inject into Claude's prompt / block Claude's Stop). Codex is a separate runtime that never reads Claude Code settings or runs these Python hooks. The only cross-runtime form of these rules is the prose fragment (e.g. shared/workflow/learn-from-review-findings.md), and only if the other runtime reads an AGENTS.md/CLAUDE.md that restates it.
Options
Wire install-hooks.py --fix into session-start.sh. Self-healing user-level registration per sandbox session. Smallest change; still ai-config-only and Claude-only.
Package the hooks into the ai-config plugin distributed via the Plugin Marketplace. The docs confirm a plugin ships hooks in hooks/hooks.json with a format identical to settings.json ("Copy the hooks object from your .claude/settings.json... since the format is the same"), installed with /plugin install and reusable across projects. Since ai-config already ships skills this way, this is the most likely single answer to persistence + cross-repo -- for Claude Code. Open questions: do marketplace plugin hooks auto-activate in cloud/web/headless sessions, and does our plugin currently include the hooks at all?
Codex parity via prose. Encode the guardrail in whatever the other runtime reads (AGENTS.md), accepting it is soft, not mechanical. There is no way to give codex the hook without building a codex-native equivalent.
Decisions needed
Do we adopt the plugin path (option 2) as the primary distribution mechanism, retire/relegate the ~/.claude/settings.json opt-in model, or keep both?
If plugin hooks do not work in cloud/web/headless sessions, is option 1 the interim answer?
Blast radius: several of the 11 are Stop guards that block message-send. Distributing them broadly (marketplace or committed settings) activates blocking behavior for every consumer/session -- is that intended, or should only the inject-only reminders travel by default while Stop guards stay opt-in?
What is the codex story -- prose parity, a codex-native equivalent, or explicitly out of scope?
Context
Surfaced while deciding whether to activate remind-learn-from-review.py (merged in #1075, still unregistered per its own activation gate). The activation question generalized into "how should mechanical guardrails reach the environments that now dominate," which is this issue.
This discussion was converted from issue #1121 on August 04, 2026 02:03.
Heading
Bold
Italic
Quote
Code
Link
Numbered list
Unordered list
Task list
Attach files
Mention
Reference
Menu
reacted with thumbs up emoji reacted with thumbs down emoji reacted with laugh emoji reacted with hooray emoji reacted with confused emoji reacted with heart emoji reacted with rocket emoji reacted with eyes emoji
Uh oh!
There was an error while loading. Please reload this page.
Summary
Our 11 guardrail hooks (
hooks/hooks.json) are distributed by registering them into the per-user~/.claude/settings.jsonviascripts/install-hooks.py --fix. That model cleanly covers exactly one world: Claude Code sessions on a machine where ai-config is installed at~/.claude(the laptop-dev case). It fits poorly everywhere the frontier has moved. This issue asks us to decide the mechanism; it is decision-shaped with a real do-nothing option, so it may be better as a Q&A discussion (see "Venue" below).Evidence (measured this session, in a cloud sandbox)
install-hooks.pyreportedregistered=0 missing=11-- none of the declared hooks were active.~/.claude/settings.jsondoes not exist in the container; the two hooks that do fire every session (session-start.sh,check-install.sh) persist only because they live in the repo's committed.claude/settings.json.command_for()emitspython3 "$HOME/.claude/hooks/<script>", so every hook command is coupled to an ai-config install existing at~/.claude.The three environments the current model misses
~/.claudeis wiped each session, so a user-level registration does not persist --install-hooks.py --fixwould be a per-session chore that dies with the container.~/.claude; in a sandbox for another repo (bcs, gha, ...) there is no ai-config checkout, so the command path points at a missing script. Project-level committed.claude/settings.jsonpersists but is per-repo, and would need replicating into every repo (with the same broken script-path dependency).shared/workflow/learn-from-review-findings.md), and only if the other runtime reads anAGENTS.md/CLAUDE.mdthat restates it.Options
install-hooks.py --fixintosession-start.sh. Self-healing user-level registration per sandbox session. Smallest change; still ai-config-only and Claude-only.hooks/hooks.jsonwith a format identical tosettings.json("Copy thehooksobject from your.claude/settings.json... since the format is the same"), installed with/plugin installand reusable across projects. Since ai-config already ships skills this way, this is the most likely single answer to persistence + cross-repo -- for Claude Code. Open questions: do marketplace plugin hooks auto-activate in cloud/web/headless sessions, and does our plugin currently include the hooks at all?AGENTS.md), accepting it is soft, not mechanical. There is no way to give codex the hook without building a codex-native equivalent.Decisions needed
~/.claude/settings.jsonopt-in model, or keep both?Stopguards that block message-send. Distributing them broadly (marketplace or committed settings) activates blocking behavior for every consumer/session -- is that intended, or should only the inject-only reminders travel by default while Stop guards stay opt-in?Context
Surfaced while deciding whether to activate
remind-learn-from-review.py(merged in #1075, still unregistered per its own activation gate). The activation question generalized into "how should mechanical guardrails reach the environments that now dominate," which is this issue.All reactions