Files
orca/config/tsconfig.cli.json
T
Neil 26721bd632 fix(codex): stop blocking the main thread on trust grants (#16441) (#16594)
* fix(codex): stop blocking the main thread on trust grants (#16441)

Codex hook trust was granted by blocking the Electron main thread on
`spawnSync` of a bundled ELECTRON_RUN_AS_NODE entry for the whole
app-server deadline: 15s native, 35s WSL, ~45s on the real-home path
(rebase inspect + repair + grant). Cold start and every Codex pane
launch showed "Not Responding"; the reported event-loop gap was
15,049 ms.

The subprocess only ever existed to donate an event loop to a
deliberately blocked parent — `runCodexHookTrustGrantSession` was
already the real async implementation. Make the callers async and the
fork is unnecessary, so the bridge, the forked entry and its envelope
are deleted along with their build/knip/tsconfig registrations. The CLI
`agent hooks prepare-codex` handler is already async, so it awaits the
in-process session and saves a process spawn per managed-home shell.

`resolveCodexTrustGrantHost` is async too; the WSL identity probe moves
from `execFileSync` to `runProcess`, dropping that file from the
child-process import allowlist. Status reads keep a synchronous
native-only stamp path.

Two invariants that held only because the lane blocked:

- Overlapping capability probes were impossible by construction.
  `GitCapabilityCache`'s dedupe engine is extracted to a shared
  `CapabilityProbeCache` and `CodexAppServerCapabilityCache` now
  inherits it, so concurrent launches against a cold host share one
  app-server session instead of one each.
- Two grants on one `config.toml` could not interleave capture and
  restore. A reentrant per-file lane now serializes the whole install
  sequence (managed, WSL runtime, real-home ensure, legacy sweep) and
  the grant and rebase inside it.

Cold-start work moves off the critical path: retained-home
reconciliation (N sequential sessions) is fire-and-forget behind the
daemon provider, and the startup real-home ensure chains into managed
hook reconciliation instead of blocking app init.

Every preserved semantic is unchanged: never throws, the
ORCA_DISABLE_CODEX_TRUST_RPC kill switch, ledger hits, backfill-pending
and cooldown fallbacks, config rollback on every failure path,
pre-grant self-computed trust removal, the verify-failure taxonomy,
diagnostics and telemetry.

* fix(codex): widen the trust-config lane to every config.toml writer

Review follow-ups on #16441's async trust grant:

- `markCodexProjectTrusted` now runs inside the runtime+system config.toml
  lanes, so a project-trust write can no longer land inside a hook grant's
  capture->restore window and be silently reverted. Its callers await it.
- `install`/`refreshRuntimeUserHooks`/`remove` hold the system config.toml
  lane as well as the runtime one — they promote approvals into
  ~/.codex/config.toml and mirror it back. Lock order is runtime-before-system
  everywhere.
- The real-home ensure chain resumes after a rejection instead of returning
  the same rejected promise to every later pane launch, and resolving the real
  home is now inside the module's never-throws boundary.
- `buildSpawnEnv` awaits inside a cancelable pending-spawn registration, so
  shutdown during the (now long) env build stops the PTY from launching.
  `prepareLocalPtySpawn` generalizes into `awaitCancelableLocalPtySpawn`.
- CapabilityProbeCache drops the test-only `nowMs` passthrough; its probe
  backstop comment now describes what it actually guards.
- Preflight is a plain async function; the trust dispatch in orca-runtime
  collapses into one `markWorkspaceTrustedForAgent`.

* test(codex): exercise the trust-config lane under real concurrency

The async grant makes two pane launches overlap for the first time. These
drive the real modules end to end on real files: a rollback swallowing a
sibling's grant, a markCodexProjectTrusted write landing inside a capture
-> restore window, shared capability-probe dedupe on a cold host, the
host-scoped transient cooldown, and reentrancy from inside an installer.

Each was verified to fail against a deliberately broken implementation
(lane removed, dedupe disabled, cooldown made global, reentrancy pass-
through disabled).

* test(codex): stop hook-service suites spawning the developer's real codex

The forked grant bundle never existed under vitest, so the RPC lane was
unreachable in tests on main. Running it in-process makes these suites
spawn a real `codex app-server` when one is installed: 38 spawns and two
failures in hook-service-runtime-trust-repair on a machine with codex,
green in CI where there is none. Stand in for the missing binary so both
environments exercise the same fallback lane.

* docs(codex): scope the trust-RPC kill switch comment to what it actually gates

The comment read as though the flag forces the fallback lane everywhere. It
gates the managed grant only: the real-home rebase still runs its own
inspect/repair app-server sessions when Orca's insertion shifts a user's hook
positions, and never reads the flag.

Verified by exercise, not by reading — with the flag set, both
inspect-user-hook-trust and repair-user-hook-trust still ran. Pre-existing:
main has no check there either, it just blocked the main thread while doing it.

Widening the flag to cover the rebase is a follow-up; this only stops the
comment promising something the constant does not do.
2026-08-26 16:44:55 -07:00

126 lines
6.0 KiB
JSON

{
"extends": "@electron-toolkit/tsconfig/tsconfig.node.json",
"include": [
"../src/cli/**/*",
"../src/shared/**/*",
"../src/main/agent-state-file-reader.ts",
"../src/main/agent-hooks/hook-stdin-contract.ts",
"../src/main/agent-hooks/hook-config-write-path.ts",
"../src/main/agent-hooks/hooks-json-read.ts",
"../src/main/agent-hooks/installer-utils.ts",
"../src/main/agent-hooks/installer-utils-remote.ts",
"../src/main/agent-hooks/local-agent-cli-presence.ts",
"../src/main/agent-hooks/managed-agent-hook-controls.ts",
"../src/main/agent-hooks/managed-agent-hook-registry.ts",
"../src/main/agent-hooks/managed-hook-script-refresh.ts",
"../src/main/agent-hooks/posix-hook-command.ts",
"../src/main/agent-hooks/runtime-home-hook-command.ts",
"../src/main/agent-hooks/windows-powershell-hook-launcher.ts",
"../src/main/amp/agent-status-plugin-source.ts",
"../src/main/amp/hook-service.ts",
"../src/main/amp/managed-plugin-install-status.ts",
"../src/main/antigravity/hook-events.ts",
"../src/main/antigravity/hook-script.ts",
"../src/main/antigravity/hook-service.ts",
"../src/main/antigravity/hooks-json-bundle.ts",
"../src/main/claude/hook-settings.ts",
"../src/main/claude/hook-service.ts",
"../src/main/claude/statusline-script.ts",
"../src/main/claude-accounts/keychain.ts",
"../src/main/codex/codex-app-server-capability-cache.ts",
"../src/main/codex/codex-app-server-capability-signal.ts",
"../src/main/codex/codex-app-server-client.ts",
"../src/main/codex/codex-app-server-session.ts",
"../src/main/codex/codex-config-mirror.ts",
"../src/main/codex/codex-config-path-reference-rewrite.ts",
"../src/main/codex/codex-config-settings-preservation.ts",
"../src/main/codex/codex-config-settings-removal.ts",
"../src/main/codex/codex-config-settings-upsert.ts",
"../src/main/codex/codex-home-paths.ts",
"../src/main/codex/codex-managed-home-resource-copy-marker.ts",
"../src/main/codex/codex-managed-trust-grant-plan.ts",
"../src/main/codex/codex-path-observation.ts",
"../src/main/codex/codex-hook-identity.ts",
"../src/main/codex/codex-hook-trust-grant.ts",
"../src/main/codex/codex-managed-trust-reconciliation.ts",
"../src/main/codex/codex-process-exit-deadline.ts",
"../src/main/codex/codex-state-db.ts",
"../src/main/codex/codex-trust-identity.ts",
"../src/main/codex/codex-trust-config-rollback.ts",
"../src/main/codex/codex-trust-config-mutation-queue.ts",
"../src/main/codex/codex-trust-grant-telemetry.ts",
"../src/main/codex/codex-trust-grant-host.ts",
"../src/main/codex/codex-trust-grant-ledger.ts",
"../src/main/codex/codex-user-hook-trust-rebase-client.ts",
"../src/main/codex/codex-user-hook-trust-rebase.ts",
"../src/main/codex/codex-wsl-hook-install-plan.ts",
"../src/main/codex/config-settings-baseline.ts",
"../src/main/codex/config-settings-conflict-resolution.ts",
"../src/main/codex/config-settings-promotion.ts",
"../src/main/codex/config-settings-promotion-write-target.ts",
"../src/main/codex/config-sync-stall.ts",
"../src/main/codex/config-toml-atomic-write.ts",
"../src/main/codex/config-toml-deprecated-hook-flag.ts",
"../src/main/codex/config-toml-hook-trust-blocks.ts",
"../src/main/codex/config-toml-hook-trust-edit.ts",
"../src/main/codex/config-toml-hook-trust-read.ts",
"../src/main/codex/config-toml-key-path.ts",
"../src/main/codex/config-toml-line-scan.ts",
"../src/main/codex/config-toml-project-trust.ts",
"../src/main/codex/config-toml-runtime-owned-sections.ts",
"../src/main/codex/config-toml-syntax.ts",
"../src/main/codex/config-toml-trust.ts",
"../src/main/codex/hook-service.ts",
"../src/main/codex/hook-trust-promotion.ts",
"../src/main/codex/managed-home-shell-preflight.ts",
"../src/main/codex-accounts/fs-utils.ts",
"../src/main/codex-accounts/wsl-codex-command.ts",
"../src/main/codex-cli/command.ts",
"../src/main/command-code/command-code-managed-script.ts",
"../src/main/command-code/hook-service.ts",
"../src/main/copilot/copilot-managed-hook-definitions.ts",
"../src/main/copilot/copilot-managed-script.ts",
"../src/main/copilot/copilot-remote-hook-install.ts",
"../src/main/copilot/hook-service.ts",
"../src/main/cursor/hook-service.ts",
"../src/main/droid/hook-service.ts",
"../src/main/gemini/hook-service.ts",
"../src/main/grok/grok-hook-config.ts",
"../src/main/grok/grok-hook-config-cleanup.ts",
"../src/main/grok/grok-hook-config-file.ts",
"../src/main/grok/grok-hook-owners.ts",
"../src/main/grok/grok-hook-remote-install.ts",
"../src/main/grok/grok-hook-script.ts",
"../src/main/grok/grok-hook-symlink-cleanup-marker.ts",
"../src/main/grok/hook-service.ts",
"../src/main/grok/windows-grok-hook-script.ts",
"../src/main/devin/hook-settings.ts",
"../src/main/devin/hook-service.ts",
"../src/main/devin/hook-config-json.ts",
"../src/main/hermes/hermes-config-yaml.ts",
"../src/main/hermes/hermes-home-filesystem.ts",
"../src/main/hermes/hermes-managed-plugin-source.ts",
"../src/main/hermes/hook-service.ts",
"../src/main/kimi/hook-service.ts",
"../src/main/kimi/kimi-hook-config-toml.ts",
"../src/main/openclaude/hook-service.ts",
"../src/main/rolling-file-backup.ts",
"../src/main/startup/hydrate-shell-path.ts",
"../src/main/startup/windows-shell-path-ownership.ts",
// Why: serve-electron-flag-parity.test.ts checks the Electron-side serve argv rewrite against this
// project's serve spec; the module has no imports, so listing it pulls in nothing else.
"../src/main/startup/serve-mode-argv.ts",
"../src/main/runtime/runtime-metadata.ts",
"../src/main/sqlite/sync-database.ts",
"../src/main/win32-utils.ts"
],
"compilerOptions": {
"composite": true,
// TypeScript 7 removed node10 resolution; Node16 preserves CommonJS emit for this package.
"module": "Node16",
"moduleResolution": "Node16",
"rootDir": "../src",
"outDir": "../out"
}
}