# One Workspace, Two Patch Jobs: A Gate That Validated a Mixed Tree

> Source: <https://dev.to/bytepro_1774/one-workspace-two-patch-jobs-a-gate-that-validated-a-mixed-tree-2kg4>
> Published: 2026-11-09 21:14:21+00:00

**Conclusion first:** a patch gate is only as trustworthy as the working tree it inspects. When two jobs share one directory, the gate can validate a tree that no single job produced, and still report green.

The scenario below is an illustrative drill, not a report of a real incident. It is written for teams that gate AI-generated patches before they touch main. No measurements or test outcomes are claimed here.

Two patch jobs run against the same checkout on one host. Job A edits `src/a.py` and starts a slow test. Job B edits `src/b.py` in the same directory one second later. The gate then runs the full suite once, on one tree, and reports green.

No single patch caused that tree. Job A's tests exercised Job B's file. Both patches may be individually correct, but the gate proved nothing about either one.

`/srv/patch-work`, for every job.
Isolation starts with a job-scoped path. Clone fresh, check out the base commit, then apply.

``` bash
#!/usr/bin/env bash
# illustrative gate runner; not executed in this article
set -euo pipefail

JOB_ID="${1:?job id required}"
PATCH_FILE="${2:?patch file required}"
WORK_ROOT="${WORK_ROOT:-/srv/patch-jobs}"
BASE_SHA="${BASE_SHA:?base sha required}"

WORKDIR="$WORK_ROOT/$JOB_ID"
rm -rf "$WORKDIR"
git clone --quiet --no-hardlinks "$REPO_URL" "$WORKDIR"
cd "$WORKDIR"
git checkout --quiet "$BASE_SHA"

git apply --index "$PATCH_FILE"
git diff --cached --name-only --diff-filter=ACMR | sort > .changed-files
test -s .changed-files   # an empty diff is a gate failure, not a pass
```

The `test -s` line matters. A no-op patch should stop the pipeline, not sail through it.

Ask the patch producer for the file list up front. Write it to `.declared-files` before applying anything. Then assert equality, not overlap.

```
sort .declared-files > .declared.sorted
sort .changed-files  > .changed.sorted

diff -u .declared.sorted .changed.sorted
```

Strict equality catches two useful failures at once: undeclared edits, and patches that silently lost a hunk. Set comparison beats counts. A patch declaring three files that touches three different files is still a violation.

Diffs describe intent. Tree hashes describe state. Record both ends.

```
fingerprint() {
  git add -A
  git write-tree
}

BEFORE="$(fingerprint)"
# ... run the test command here ...
AFTER="$(fingerprint)"

if [ "$BEFORE" != "$AFTER" ]; then
  echo "tests mutated the tree; result is not attributable" >&2
  exit 1
fi
```

A test run that rewrites fixtures, snapshots, or config invalidates its own verdict. The comparison above forces the suite to be read-only, or the job to declare its side effects.

Before trusting any of this, run a canary patch on purpose. It should break exactly one assertion and should turn the gate red.

`.changed-files`.
This plan is illustrative and was not executed. Run it in a sandbox repository with quick tests.

```
for i in 1 2 3 4 5; do
  ./gate.sh "a-$i" patches/a.patch &
  sleep 1
  ./gate.sh "b-$i" patches/b.patch &
  wait
done
```

Expected result with job-scoped directories: zero cross-links in five rounds. Expected result with a shared directory: at least one run where `.changed-files` contains both `a` and `b` paths. Record the count either way, and keep it as a regression baseline.

| Setup | Isolation | Cost | Where it fits | 
|---|---|---|---|
| Shared dir, one worker, fresh reset per run | Time-only | Lowest disk | Low volume, strict serialization | 
| Per-job clone | Full | Repo size times jobs | Default for untrusted model patches | 
| Per-job `git worktree` | Full working tree, shared objects | Medium | Many jobs on one repo | 
| Container per job | Full, including toolchain | Highest | Concurrency plus untrusted build steps | 

The shared-directory row is honest only when the queue guarantees one job at a time and resets the tree. Concurrency breaks it silently.

Disclosure: This article was prepared as part of MonkeyCode's product outreach.

The project offers free model access and a free server option, as described by its operator. That combination makes parallel patch jobs tempting on one machine. It also makes path collisions more likely, because one host often means one working directory unless the runner creates more.

A practical split for that setup:

`git write-tree` ignores `.gitignore` d files; model-written caches can hide there.`--no-hardlinks` trades space for safety.
Solo developers patching their own branch do not need three gates. Teams without a stable job identifier should add that first. Anyone whose test suite must write artifacts should fix the suite before adding fingerprints.

`.declared-files`.
If a mixed-tree postmortem sounds familiar, the free model access and free server option are a cheap way to rehearse this drill. Check the current terms first, then keep the canary red until the gate earns its green.
