Observation
captureRepoStateIdentity (added in #101, closing #98) fingerprints a working-tree review target so a queued background review can refuse to run once the repository has moved under it. Building that fingerprint hashes content per path:
- each dirty tracked path goes through
git hash-object --no-filters -- <path> (plugins/codex/scripts/lib/git.mjs, hashWorkingTreePath)
- each untracked regular file goes through the same, one call at a time (
hashUntrackedPath)
Every one of those is a separate synchronous spawnSync. The cost is O(dirty paths) process startups, paid inline on the --background enqueue path — the interactive call the user is waiting on before the command returns a job ID.
Impact
Enqueue latency only; no correctness issue. It is invisible on a handful of changed files and grows linearly. A tree with hundreds of untracked or dirty files (a fresh build output directory that is not ignored, a large generated fixture set, a vendored dependency dump) makes /codex:review --background and friends noticeably slow to return.
Repositories where git status --porcelain is already slow will feel it worst, since the fingerprint work lands on top of that.
Context
Non-prescriptive notes
git hash-object accepts multiple paths in one invocation and emits one OID per line in argument order, which would collapse the tracked and untracked passes into a small constant number of processes. Anything batched would need to stay clear of platform argument-length limits — chunking, or feeding paths on stdin with --stdin-paths, rather than one unbounded argv.
Whatever shape is chosen should keep the current per-path semantics intact: symlinks, directories/gitlinks, and unreadable or missing paths are handled separately from regular files today, and the submodule branch folds in that submodule's own HEAD and diff content.
Observation
captureRepoStateIdentity(added in #101, closing #98) fingerprints a working-tree review target so a queued background review can refuse to run once the repository has moved under it. Building that fingerprint hashes content per path:git hash-object --no-filters -- <path>(plugins/codex/scripts/lib/git.mjs,hashWorkingTreePath)hashUntrackedPath)Every one of those is a separate synchronous
spawnSync. The cost isO(dirty paths)process startups, paid inline on the--backgroundenqueue path — the interactive call the user is waiting on before the command returns a job ID.Impact
Enqueue latency only; no correctness issue. It is invisible on a handful of changed files and grows linearly. A tree with hundreds of untracked or dirty files (a fresh build output directory that is not ignored, a large generated fixture set, a vendored dependency dump) makes
/codex:review --backgroundand friends noticeably slow to return.Repositories where
git status --porcelainis already slow will feel it worst, since the fingerprint work lands on top of that.Context
Non-prescriptive notes
git hash-objectaccepts multiple paths in one invocation and emits one OID per line in argument order, which would collapse the tracked and untracked passes into a small constant number of processes. Anything batched would need to stay clear of platform argument-length limits — chunking, or feeding paths on stdin with--stdin-paths, rather than one unbounded argv.Whatever shape is chosen should keep the current per-path semantics intact: symlinks, directories/gitlinks, and unreadable or missing paths are handled separately from regular files today, and the submodule branch folds in that submodule's own HEAD and diff content.