# PR #22943 (GitCafe 22942): proof audit, pass 2

**Verdict: SUFFICIENT**

Auditor: Claude Opus 5.5 (Claude Code, review sub-agent), 2026-10-22. Scratch: `/tmp/ev-22943/audit2`.

## 1. SHAs and scope
- `git diff --stat 607524efc8 014feb6beb` touches only `apps/server/scripts/evidence/pr-22943/{bin/codex,bin/gh,fixture.sh,forge-stub.mjs,run.mjs}` (5 files, +521). No product code changed.
- `git diff --stat 8d3b0611 607524efc8` touches only `apps/server/src/git/GitManager.ts` and its test.
- Captured `summary` lines: the after run recorded `serverSha 607524efc8…` (taken before the harness commit) and the before run recorded `8d3b061121…`. The driver computes this with `git rev-parse HEAD` in `--server`.
- Independent confirmation from server stack traces: the captured before-logs reference `/tmp/ev-22943/before/apps/server/src/...` and the after-logs reference `/home/ubuntu/wt/pr-22943/apps/server/src/...`. The notice string `unavailable in this checkout` exists in GitManager.ts at the after commit and is absent at 8d3b0611.

## 2. Row-by-row: captures vs matrix
| Row | Matrix expectation | Captured before | Captured after | Rebuilt (audit2) | ok |
|---|---|---|---|---|---|
| R1 | no change, base `parent` | POST base `parent` | POST base `parent`, no notice | not rebuilt (no diff) | yes |
| R2a | after falls back to `main` + notice | POST `parent` | POST `main`, notice in pr label + toast, prompt range Parent+Child | **before + after rebuilt: identical** | yes |
| R2b | no change (stale ref = known limitation) | POST `parent` | POST `parent`, no notice | not rebuilt | yes |
| R3 | after falls back to `main` + notice | POST `parent` | POST `main`, notice, range Parent+Child | **before + after rebuilt: identical** | yes |
| R4a | before silent wrong base; after errors, no POST | POST `parent` (silent wrong base) | 0 POST, codex exec not called, `action_failed` GitCommandError readRangeContext.log | **before + after rebuilt: identical** | yes (see finding F1) |
| R4b | control, unchanged | 0 POST, same git error | 0 POST, same git error, no notice | not rebuilt | yes |

In every captured and rebuilt run, `refs-before.txt` == `refs-after.txt` (`refsUnchanged: true`). For the rebuilt rows, the fixture refnames and config match the captured fixtures. Only the SHAs differ, because commits carry timestamps.

## 3. Rebuild
- After: `node apps/server/scripts/evidence/pr-22943/run.mjs --server /home/ubuntu/wt/pr-22943 --out /tmp/ev-22943/audit2/after --rows R2a,R3,R4a`. Exit 0. Base, POST body, phase labels, toast, prompt range and failure message all match the captures. The serverSha recorded here is 014feb6beb, whose `apps/server/src` is identical to 607524efc8.
- Before: detached worktree at 8d3b0611 under `/tmp/ev-22943/audit2/before` (`vp i`), the same three rows, output in `audit2/before-out`. All three POST `base:"parent"` with no notice, which matches the captures. The worktree was removed afterwards with `git worktree remove`.
- Process handling: the driver kills only the child it spawned (SIGTERM, then SIGKILL after 10s). No pattern kills were used.

## 4. Isolation
- Forge: across all 24 captured runs and the 6 rebuilt runs, the only admitted CONNECT was `github.invalid:443` (36 admitted). Refused CONNECTs were `raw.githubusercontent.com:443` and `ingest.t3.codes:443` (18 each). Those are background catalog/telemetry requests, they were blocked, and they are identical in before and after. `.invalid` cannot resolve, so no real forge was reachable.
- Fakes: `gh.log` shows only `gh auth token --hostname github.invalid`. `codex.log` shows only the fake handling `--version`, `app-server`, `mcp list --json` and `exec`. The model slug in the exec argv is the server's default and went nowhere.
- State: each run had a fresh `t3Home` under the out dir (with `userdata/statev2.sqlite` etc. present there), `HOME=<out>/fakehome` and an empty `GIT_CONFIG_GLOBAL`. The server logs contain no reference to `/home/ubuntu/.t3`. The only `/home/ubuntu` paths in them are source paths in stack traces.
- Deviation `shellEnvironmentPrepared: true` is justified. Without it, login-shell PATH hydration puts the real `/usr/local/bin/codex` ahead of the fake. It only affects env hydration, not the git or PR code under test. The discarded trial was correctly excluded.

## 5. Findings
- **F1 (non-blocking, UX):** in R4a the after-version emits `Base origin/parent is unavailable in this checkout. Using default branch main.` even though `main` does not exist anywhere. It then fails with a generic `GitCommandError ... readRangeContext.log ... non-zero status` that gives no git stderr and doesn't say that no default branch could be resolved. The requirement "error surfaces, no silent wrong base" is **met**: there is no POST, no PR and no codex exec, and the RPC fails. The notice is misleading, though, and the error doesn't help the user. A follow-up could validate the literal `main` fallback and emit "could not determine a base branch". The same generic error already exists before the PR in R4b, so this is not a regression.
- **F2 (documented limitation):** R2b, a stale remote-tracking ref without prune, still targets the deleted `parent`. This matches the PR body's stated limitation.
- **F3 (cosmetic):** in the affected rows the notice replaces the `Generating PR content...` progress label rather than adding to it. The toast description joins title and notice with a single space.

## 6. Gaps
None blocking. R1, R2b and R4b were not rebuilt. They are no-diff guard rows, and the code paths behind them are exercised by the rebuilt runs.
