Skip to content

🤖 refactor: extract the task git patch engine from the apply tool - #4008

Open
ibetitsmike wants to merge 4 commits into
mainfrom
mike/arch-git-patch-engine
Open

🤖 refactor: extract the task git patch engine from the apply tool#4008
ibetitsmike wants to merge 4 commits into
mainfrom
mike/arch-git-patch-engine

Conversation

@ibetitsmike

@ibetitsmike ibetitsmike commented Aug 29, 2026

Copy link
Copy Markdown
Contributor

Summary

Extracts the git patch engine out of tools/task_apply_git_patch.ts behind a 3-method TaskGitPatchEngine seam (applyPatch, findPatch, generatePatch) in src/node/services/taskGitPatchEngine.ts. The model tool and the workflow adapter become thin adapters that own their own locking, and the engine has no taskService dependency.

Net LOC delta vs main (f04e0f8): production -192 (+2113/-2305), tests -364 (+2125/-2489), total -556. No irreducible net additions: every new line is the seam's interface surface, offset by deleted duplication.

Background

From the 2026-08-29 architecture review: the 1,995-line tool file was a full git diff parser, dirty-tree detector, and 3-way merge engine with a 9-line tool adapter at the bottom. WorkflowTaskServiceAdapter imported those internals and passed taskService: undefined to dodge the non-reentrant artifact lock (an inverted seam where the engine knew about the lock owner and callers had to know to disarm it), while carrying its own duplicate git patch-path parser for allowedPathPrefixes validation. The raw git format-patch invocation lived inline in gitPatchArtifactService.

Implementation

  • src/node/services/taskGitPatchEngine.ts (moved with git mv to retain history): the apply pipeline, parsers, dirty-tree overlap detection, pending-generation wait, and ancestor artifact lookup, exposed as applyPatch / findPatch / generatePatch. The engine validates untrusted args at entry but returns typed result literals instead of re-validating its own output; it no longer imports tool-layer utilities.
  • tools/task_apply_git_patch.ts is now a 17-line adapter: schema wiring plus lock acquisition via config.taskService.withGitPatchArtifactOperationLock when present.
  • WorkflowTaskServiceAdapter.applyPatch holds its existing lock and calls the engine directly; the taskService: undefined hack, its duplicate parser (~103 lines), and the artifact-lookup helpers are deleted. allowedPathPrefixes is enforced inside the engine and rides the dry-run precheck, so policy violations fail before any worktree is created.
  • gitPatchArtifactService keeps all artifact bookkeeping and calls engine.generatePatch for the raw git format-patch stream.
  • findPatch currently has no production caller outside the engine (the adapter consumes Pick<TaskGitPatchEngine, "applyPatch">); it stays on the seam intentionally as the lookup capability of the engine and is covered directly by the engine tests.

A Codex review round caught a real regression in the consolidated parser (the old adapter parser handled mixed quoted/unquoted diff --git header sides; the consolidation did not); fixed with a real-repo rename round trip covering both mixed-quoting directions.

Tests: the 2,394-line tool test was moved into taskGitPatchEngine.test.ts (2,015 lines) and reworked to exercise the engine directly on real temp git repos, including a generate-then-apply round trip; the tool test shrank to a 52-line dispatch test (lock acquisition and delegation); adapter patch tests became seam tests against a fake engine.

Validation

  • Remote dogfood UAT (Coder Agents) passed on the tested SHA: fork-artifact apply paths (dry run, real apply, already-applied guard, force, dirty-overlap rejection, conflict recovery) and the workflow adapter path (prefix policy, lock non-recursion, dry-run precheck), with result shapes verified unchanged against the tool schema.
  • Local: make static-check green; 94 tests across the five touched suites pass.

Risks

Behavior-preserving refactor of intricate logic (patch application). The two intentional behavior deltas are internal and narrow: prefix-policy violations in workflow applies now fail at the dry-run precheck instead of after it (same error, earlier), and engine results are no longer re-parsed through the result schema at runtime (they are typed literals; the schema remains the tool contract). Severity if wrong: patch application in sub-agent and workflow flows, covered by the real-repo suites above.


Generated with xum • Model: anthropic:claude-fable-5 • Thinking: xhigh • Cost: $51.58

Audit-driven cleanup: the engine no longer imports tools/toolUtils (inlined
workspaceId assert, engine-named assert messages) and returns typed result
literals instead of re-validating its own output through the result schema.
The workflow adapter passes allowedPathPrefixes on the dry-run precheck too,
so policy violations fail fast before the worktree dance.
@chatgpt-codex-connector

This comment has been minimized.

@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a1d5d9c36

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/node/services/taskGitPatchEngine.ts
@chatgpt-codex-connector

This comment has been minimized.

Codex P2: git C-quotes each header side independently, so an ASCII to
non-ASCII rename emits a mixed quoted/unquoted path pair that the
consolidated parser treated as unparseable, falsely rejecting valid
renames under allowedPathPrefixes. Handle both mixed directions and
cover them with a real-repo rename round trip.
@ibetitsmike

Copy link
Copy Markdown
Contributor Author

@codex review

@chatgpt-codex-connector

Copy link
Copy Markdown

Codex Review: Didn't find any major issues. Nice work!

Reviewed commit: f79bd23640

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

@chatgpt-codex-connector

This comment has been minimized.

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.

1 participant