openai / openai/codex

App-server: project hooks are unavailable to hooks/list until thread/start establishes project trust

Open
#45,856 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

app-server bug hooks
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/start preflight/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
  1. Create an isolated CODEX_HOME with no existing project trust.
  2. Create a workspace containing:
{
  "hooks": {
    "SessionStart": [
      {
        "hooks": [
          {
            "type": "command",
            "command": "printf %s CODEX_HOOK_MARKER > hook-marker.txt",
            "timeout": 5
          }
        ]
      }
    ]
  }
}
  1. Start and initialize app-server.
  2. Call:
{
  "method": "hooks/list",
  "params": { "cwds": ["/path/to/workspace"] }
}
  1. Observe that no project hook metadata is returned.
  2. Start a writable thread for the same cwd, without sending a turn.
  3. Call the same hooks/list request again.
  4. 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.