Skip to content

Repository hooks silently untrusted (no trust prompt) in worktree sessions started from the new-session composer with a prompt #4649

Description

@Thetanner

Short summary

Repository hooks (.github/hooks/*.json) are not trusted, and no trust prompt is shown, in worktree sessions created from the new-session composer with a first prompt.

Affected version or release

GitHub Copilot app 1.1.28, bundled runtime 1.0.94-3

Installation context

Copilot desktop app on macOS 26.5.2 (arm64). Repository project with repo-level hooks in .github/hooks/*.json, previously accepted through the repository config trust prompt. Default worktree workspace type.

What happened?

When a new session is started from the new-session composer with an initial prompt, in a new worktree, the app resolves repository_hooks_trusted=false. The CLI then logs loadDeferredRepoHooks(<session>): file hooks disabled; skipping, so no repository hooks run (sessionStart, preToolUse and so on). The UI shows no trust prompt or banner, and no accept_repo_config is recorded, so the user cannot fix it from the session.

Sessions in the same project at the same commit behave differently depending on how they were created:

  • The main checkout is resolved repository_hooks_trusted=true, and its hooks load (loadDeferredRepoHooks(...): loaded repo hooks (hookCount=37)).
  • Worktree sessions created by an agent session through create_session are resolved repository_hooks_trusted=true.

App log counts for worktree sessions in one project, grouped by the innermost task span on the resolved repository execution admission for session creation line:

Creation path (task span) trusted=true trusted=false
workspace_kickoff_after_init (composer, new worktree, with prompt) 1 39
ws_session_operation_loop 63 13
workspace_branch_kickoff_create_session 4 0

Timing on both paths: the trust decision is logged before deferred worktree checkout complete for that workspace. Two examples:

  • composer path: admission at 04:26:21.880Z, deferred worktree checkout complete at 04:26:22.633Z (populate_ms=785), result trusted=false;
  • agent create_session path: admission at 02:40:34.46Z, checkout complete at 02:40:39.39Z, result trusted=true.

So deferred checkout alone does not explain it. The composer path either hashes the repository config of a worktree that is not fully populated, or it does not get the trust that the other paths get. I could not tell which from the logs.

Steps to reproduce

  1. Add a project for a repository that has .github/hooks/*.json (for example, a sessionStart hook that prints a marker into additional context), and accept the repository config trust prompt.
  2. Confirm that a session in the main checkout runs the hook.
  3. From the new-session composer, create a new session in a new worktree and type a first prompt (for example test).
  4. Observe:
    • the hook output is missing;
    • the CLI log shows file hooks disabled; skipping;
    • the app log shows repository_hooks_trusted=false for that worktree's cwd;
    • no trust prompt is shown.
  5. From an existing agent session, call create_session for a new worktree in the same project. The app log shows repository_hooks_trusted=true, and the hooks run.

Expected behavior

A worktree session started from the composer should either get the trust already accepted for the project's repository config, when the config content is unchanged, or show the trust prompt before the first prompt runs. It should not silently start with hooks disabled.

Additional context

  • Log lines are from the app log (github_app::session::manager::lifecycle: resolved repository execution admission for session creation cwd=... repository_hooks_trusted=...) and the CLI process log (loadDeferredRepoHooks).
  • Possibly related first-message race: [Windows] Sending the first message immediately can skip an extension's onSessionStart hook. #4407 (Windows, extension onSessionStart skipped when the first message is sent immediately).
  • Impact: repositories that use preToolUse hooks as guardrails get no guardrails in composer-created worktree sessions, and nothing in the UI tells the user. Our workaround: agents fail closed when a sessionStart marker is missing, and sessions are started through create_session.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions