Codex hook trust is not synchronized into Cindy's isolated CODEX_HOME
- Dominant language
- TypeScript
- Stars
- 2.7k
- Forks
- 395
- Avg merge
- 21h 48m
- Merged PRs (30d)
- 776
Description
## Summary
Cindy starts Codex with an isolated `CODEX_HOME` under its application data directory, but it does not carry over or establish Codex hook trust receipts in that home. As a result, project and plugin hooks that are already explicitly trusted in native Codex are reported as `untrusted` in Cindy and are silently skipped. In our case this prevented a `SessionStart` hook from updating a child repository.
## Environment
- Reproduced on macOS on September 14-15, 2026
- Cindy bundled Codex: `0.153.4`
- Native Codex home: `~/.codex`
- Cindy Codex home: `/codex-home`
- Workspace contains project hooks at `/.codex/hooks.json` and `/repos/android/.codex/hooks.json`
## Reproduction
1. Explicitly trust the project hooks in native Codex. The exact hook hashes are then present under `[hooks.state]` in `~/.codex/config.toml`.
2. Open the same workspace in Cindy.
3. Query the bundled app-server with `hooks/list` for the workspace and child repository.
## Actual result
The project and plugin hooks are returned with `trustStatus: "untrusted"`. Cindy's own config contains project `trust_level = "trusted"`, but has no `[hooks.state]` receipts. The `SessionStart` hook does not execute.
Control experiment: running the exact same Cindy-bundled Codex `0.153.4` binary with `CODEX_HOME=~/.codex` returns the same hooks as `trusted`. Running it with Cindy's isolated `CODEX_HOME` returns them as `untrusted`.
This shows that repository trust and hook trust are separate, and the missing state is specifically in the Codex home selected by Cindy.
## Expected result
Cindy should provide a hook trust handshake for the actual `CODEX_HOME` used by its Codex app-server. Hooks should not be silently skipped merely because the user previously approved them through a different Codex home.
This should remain hash-based and scoped. Cindy should not globally bypass hook trust or automatically trust arbitrary repository hooks.
## Suggested approach
Before `thread/start` or `thread/resume`:
1. Call `hooks/list` for the effective working directory.
2. Surface approval for untrusted project hooks, or migrate only receipts that the user has already explicitly approved and whose current hashes still match.
3. Write the exact receipt to the active Codex home through `config/batchWrite`, using `hooks.state..trusted_hash`.
4. Call `hooks/list` again and require the expected hooks to be `trusted` before starting the thread.
The same rule should apply to account-specific homes and remote Codex daemon environments: trust must be written to the home actually used by that app-server process.
## Regression coverage
Add an integration or contract test with an isolated `CODEX_HOME` where a matching receipt exists only in another home. Verify that Cindy either completes the trust handshake or clearly asks for approval, and that `SessionStart` is not silently lost after approval.
Contributor guide
Research direction
Trace Cindy's Codex app-server setup around hooks/list, thread/start, thread/resume, and config/batchWrite, focusing on how the effective CODEX_HOME is selected. Add regression coverage for an isolated home whose matching receipt exists only elsewhere; done means approval or migration is explicit, the receipt is written to the active home, hooks/list reports trusted, and SessionStart is not silently skipped.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- electron, typescript
- Domain
- desktop, devtools
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 55/100