App-server: project hooks are unavailable to hooks/list until thread/start establishes project trust
Nobody has claimed this yet.
- Dominant language
- Rust
- Stars
- 125k
- Forks
- 19.4k
- PR merge metrics
- PR metrics pending
Description
What variant of Codex are you using?
App Server
What issue are you seeing?
An embedding host cannot reliably discover a workspace's project hooks with hooks/list before starting the first writable thread for that workspace.
With a fresh Codex home and a workspace containing .codex/hooks.json, the observed sequence is:
hooks/list({ cwds: [workspace] })
-> no project hooks
thread/start({ cwd: workspace, writable workspace permissions })
-> Codex establishes native project trust and creates thread A
hooks/list({ cwds: [the same workspace] })
-> project hook metadata is now returned, including key and currentHash
The second request is for the same folder; it is not inspecting thread A. Starting the writable thread changes Codex's native project-trust state, which makes the project hook definitions available to the later folder-scoped lookup.
This creates a bootstrap problem for an embedding host that needs the hook key/hash before constructing the thread configuration.
Impact in VS Code Agent Host
VS Code uses the returned hook.key and hook.currentHash to supply narrow, per-thread hook trust:
config['hooks.state'] = {
[hook.key]: { trusted_hash: hook.currentHash }
};
That avoids bypass_hook_trust and avoids persisting per-hook grants globally.
When the initial hooks/list returns no project-hook information, the first thread is created without hooks.state. A trusted workspace SessionStart hook can then be skipped on the first turn. This surfaced as an intermittent integration-test timeout waiting for the marker file created by the hook.
VS Code tracking and implementation:
- Original per-thread hook trust support: microsoft/vscode#334063
- Host-side startup workaround: microsoft/vscode#336306
- Original VS Code tracking issue, closed in favor of this upstream issue: microsoft/vscode#336367
Current workaround
The workaround in microsoft/vscode#336306 is:
hooks/list(same folder) -> no usable project-hook information
thread/start -> provisional thread A, without hook grants
hooks/list(same folder) -> hook key/currentHash now available
thread/unsubscribe(A)
thread/start -> replacement thread B, with matching hooks.state
turn/start(B) -> first user message
Thread A has not processed a user message, so replacing it does not discard conversation history. Resume requires a similar unsubscribe/reload sequence while preserving existing history.
This workaround adds lifecycle complexity and an extra lookup/start sequence solely to bridge project-trust establishment and hook discovery. It also requires the host to reconcile Workspace Trust changes while cached hook grants are waiting to be applied.
Expected behavior
Please provide a supported app-server flow that lets an embedding host establish the project-trust context required for project-hook discovery before creating the target thread.
Possible solutions include:
- A request-scoped project-trust input to
hooks/list. - An explicit API for establishing project trust before customization discovery.
- A typed
thread/startpreflight/discovery API that returns the effective project hooks before committing the thread. - A structured result that distinguishes "there are no hooks" from "project hooks were not loaded because project trust is not established," together with the supported next action.
The important properties are:
- The host can discover the exact project hooks and their current hashes before creating the target thread.
- Trust remains scoped and does not require
bypass_hook_trust. - Managed restrictions continue to take precedence.
- Behavior is defined consistently for thread start, resume, and fork.
- The host does not need to create and discard a provisional thread merely to make project hooks discoverable.
Minimal protocol reproduction
- Create an isolated
CODEX_HOMEwith no existing project trust. - Create a workspace containing:
{
"hooks": {
"SessionStart": [
{
"hooks": [
{
"type": "command",
"command": "printf %s CODEX_HOOK_MARKER > hook-marker.txt",
"timeout": 5
}
]
}
]
}
}
- Start and initialize app-server.
- Call:
{
"method": "hooks/list",
"params": { "cwds": ["/path/to/workspace"] }
}
- Observe that no project hook metadata is returned.
- Start a writable thread for the same
cwd, without sending a turn. - Call the same
hooks/listrequest again. - Observe that the project hook is now returned with its
key,currentHash, source, and trust status.
The workspace hook file remains unchanged between the two requests. The relevant change is Codex's native project-trust configuration during thread/start.
Relationship to openai/codex#38371
openai/codex#38371 requests safe, typed, thread-scoped registration and trust for host-provided hooks. This issue is related but narrower: it concerns discovering native project hooks before thread creation, so an embedding host can construct the target thread's scoped trust configuration without a provisional thread.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the minimal protocol reproduction using hooks/list and thread/start in an isolated CODEX_HOME, then trace the app-server handling for those requests. Compare the initial and post-thread hook results and review the related VS Code workaround. Done means a supported pre-thread discovery flow exposes project hook keys and hashes while preserving scoped trust and consistent thread, resume, and fork behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- rust
- Domain
- api, security
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Active
- Clarity
- Mostly clear
- Newbie friendliness
- 35/100