Skip to content

fix(edge-worker): stop-hook ignores pre-existing untracked files (CYPACK-1196)#1204

Open
cyrusagent wants to merge 2 commits into
mainfrom
cypack-1196
Open

fix(edge-worker): stop-hook ignores pre-existing untracked files (CYPACK-1196)#1204
cyrusagent wants to merge 2 commits into
mainfrom
cypack-1196

Conversation

@cyrusagent
Copy link
Copy Markdown
Contributor

@cyrusagent cyrusagent commented May 12, 2026

Assignee: @PaytonWebber (payton)

Summary

Fixes CYPACK-1196. The Stop-hook guardrail was treating every line of git status --porcelain (including untracked ?? lines) as unshipped work. Customers whose worktrees contained stray untracked files outside .gitignore (scratch files, env files, IDE artifacts) got wedged: committing was wrong, and the agent looped trying to satisfy a condition it could not resolve.

Approach

Layered fix that preserves the original guardrail goal (catching forgotten new files Cyrus wrote but didn't commit):

  1. IntentToAddHook (new) — PostToolUse hook on Write/Edit/MultiEdit/NotebookEdit runs git add --intent-to-add on the file the tool touched. Intent-to-add marks the file as tracked-with-empty-content, so the guardrail (git diff semantics) surfaces it if left uncommitted. No-op for: non-git cwd, gitignored paths, already-tracked paths, missing paths.
  2. Guardrail switches to tracked-onlyinspectGitGuardrail now uses git status --porcelain --untracked-files=no. Combined with Say hi [CEE-574] #1, pre-existing untracked junk is ignored while forgotten new files Cyrus wrote still block.

SOLID notes

The new hook follows the same strategy pattern as PrMarkerHook:

  • IntentToAddGitClient interface separates git/fs side effects (DIP)
  • DefaultIntentToAddGitClient implements it against the real git binary (SRP)
  • applyIntentToAdd holds the precondition policy as a pure function over the client (testable without spawning git)

Trade-off (documented in the issue)

Files created via Bash (e.g. echo > foo, codegen, scaffolders) that Cyrus forgets to git add are no longer flagged. Every variant of instrumenting Bash to close this gap either reintroduces Cooper's bug, adds significant per-call overhead, or relies on brittle command-line parsing. Failing safe in this direction (missed nag, not customer-blocking loop) is the right call; the PR-marker early-exit and the unchanged unpushed-commits check provide partial coverage.

Test plan

  • inspectGitGuardrail returns null for the Cooper case (untracked-only worktree)
  • inspectGitGuardrail still blocks on tracked-file modifications
  • inspectGitGuardrail still blocks on --intent-to-add files (forgotten new files preserved)
  • inspectGitGuardrail still blocks on unpushed commits
  • applyIntentToAdd is a no-op for non-git cwd, missing paths, gitignored paths, already-tracked paths
  • IntentToAddHook matcher covers Write/Edit/MultiEdit/NotebookEdit and excludes Bash/Read
  • Full edge-worker test suite passes (630 tests)

Tip: I will respond to comments that @ mention @cyrusagent on this PR. You can also submit a review with all your feedback at once, and I will automatically wake up to address each comment.

…ACK-1196)

Switch `inspectGitGuardrail` to `git status --porcelain --untracked-files=no`
so stray untracked files in the customer's worktree (scratch files, env
files, IDE artifacts outside .gitignore) no longer block end-of-session.

Preserve the "forgot to ship a new file" check by adding a PostToolUse
`IntentToAddHook` that runs `git add --intent-to-add` on files touched
by Write/Edit/MultiEdit/NotebookEdit — those still show up as a tracked
diff in the guardrail. No-ops for non-git cwd, gitignored paths,
already-tracked paths, and missing paths.

Hook follows the same strategy pattern as PrMarkerHook: injectable
`IntentToAddGitClient` interface separates git/fs side effects from the
precondition policy in `applyIntentToAdd`.

Reported by Cooper @ QuitCarbon.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants