Repository navigation
fix(framework): a Codex hook that was never trusted is skipped in silence, and the journal with it #699
Description
Activity
Said at install, and told apart in the diagnostic
At install, for Codex only:
Plugin "sample-plugin" (codex): Codex will not run this plugin's hooks until each one is trusted — approve the prompt once in an interactive session, or pass --dangerously-bypass-hook-trust to codex exec for a headless run. Until then, a session leaves no run journal and nothing says why.For a tool that declares no such gate, nothing is printed — asserted in the same test, because a warning that appears everywhere is read nowhere. The text lives on the tool's own declaration beside
acceptsHooksandpluginRootToken, so a second gated tool needs it written once.It is deliberately not a
PluginTranslationSkip. A skip means a component was never delivered; this means one was delivered with a precondition. Conflating them would make "hooks skipped" ambiguous between "Cursor cannot run this" and "Codex needs this approved".In the diagnostic, from a real untrusted session:
hook fired FAIL Codex has not trusted this plugin's hook — no trusted_hash for hooks/hooks.json:session_start in …/config.toml. Approve it interactively once, or pass --dangerously-bypass-hook-trust to codex exec for a headless run.That is now a fourth answer on that claim, distinct from "never observed firing" and "this session left no run file". The trust state is read only when
CODEX_THREAD_IDis set, never for another tool, and an unreadable config reads as unreadable rather than being guessed into either answer.Two limits, stated rather than glossed
The trusted path was not reproduced live. A persisted
trusted_hashis only written by an interactive TTY approval;--dangerously-bypass-hook-trustbypasses the check at runtime and writes no entry — confirmed empirically, the config was unchanged after that run. The key shape used is drawn from genuinely approved entries already on the machine for other plugins using the same mechanism, and the "reads ok" path is covered by fixtures rather than a fresh session. Three sessions were budgeted and three were spent, two of them on a setup shape that turned out wrong.The marketplace-registration route has no notice.
registerNativeGithubPluginsregisters a plugin by name and version without ever fetching its distribution, so it cannot know whether the plugin ships hooks without an extra network fetch on every install. Left unfixed rather than over-fetching or notifying blindly.Still open in this ticket
The last Done-when — a documented way to grant trust headlessly that does not need a person at a terminal — is not solved.
--dangerously-bypass-hook-trustis a per-invocation bypass, not a grant: it leaves no entry, so the next run needs it again. Whether Codex offers any way to persist trust without a TTY is unestablished.Done and awaiting review in #706, which closes this on merge.
The work is on
claude/aidd-telemetry-layer-e403uf, eleven commits, targetingnext. Gate at the time of push: 365 plugin specs, 1,931 CLI unit, 577 integration, 178 e2e,tscand biome clean, no broken markdown links.Read the eleven commits rather than the pull request's file count — the branch carries its own copy of the CLI migration that
nexthas since received, so the diff counts it twice. The range and the real figures are in the first comment on #706: 142 files, +10,518 −418.Every claim about a tool in this work rests on a session that was actually run. The negative results are kept in full in
aidd_docs/tasks/2026_08/2026_08_22_telemetry-every-tool/measurements.md, including the two probes that disagreed about OpenCode and the measurement that reconciled them.- added a commit that references this issue
on Aug 23, 2026
Metadata
Metadata
Assignees
Labels
Type
Fields
Priority
Projects
- StatusShow more project fieldsDone
Codex will not run a hook it has not been asked to trust, and says nothing when it declines. A freshly installed plugin therefore journals nothing, and the silence is indistinguishable from a session where nothing happened.
What was measured
A plugin installed for Codex, enabled in
~/.codex/config.toml, with a hook whose command resolves to a file that exists. Four consecutivecodex execsessions ran clean and wrote no journal. No warning, no line in the output, nothing in the log. The fifth ran with--dangerously-bypass-hook-trustand the same install produced all three hooks and its journal:The mechanism is
[hooks.state]in~/.codex/config.toml: onetrusted_hashper hook, written when a person approves it. A hook with no entry is skipped.Why it matters here
The run journal is the only thing that ties a session to the step that was running. Losing it on a tool loses per-step attribution on that tool, and it fails in the shape this measurement layer exists to avoid: no error, a plausible empty result, and nothing on the record saying a measurement was not taken.
It also lands hardest where it is least visible. A person running Codex interactively approves once and never thinks about it again. Anything headless — CI, an agent, a scripted run — never sees the prompt, and every session it produces is silently unattributed.
Done when
Out of scope
Granting trust automatically. A hook trust prompt exists because a plugin hook runs arbitrary commands; routing around it on the user's behalf is not this ticket.
Where it was found
While verifying #698 end to end. The hooks arrive correctly and the command resolves — that part works. This is the next gate after delivery.