# PR #22943 (GitCafe 22942) running-server evidence: Create PR base resolution (issue #22920)
**Environment:** machine fs-08, Ubuntu 24.04.5 LTS (kernel 6.1.102), node v26.12.1, git 2.43.0. Before = `8d3b061121fe65669d5d43d011b48cd3027a4108` (merge-base on main, detached worktree /tmp/ev-22943/before). After = `607524efc8673321b5f2d85a6f76c224e9071daf` (PR head, /home/ubuntu/wt/pr-22943). Harness committed at `014feb6beb171234162c3bb22e7421e479433d23` under `apps/server/scripts/evidence/pr-22943/` (no product code changed by it).
## Setup
- Real server: `node apps/server/src/bin.ts start --bootstrap-fd 3 --log-level debug` spawned from each checkout, one fresh process and fresh t3Home per row per version at `/tmp/ev-22943/{before-out,after}/<row>/t3home` (this layout replaces the brief's `home-<row>-<ver>` naming; never `~/.t3`). Auth: bootstrap token -> `POST /oauth/token` -> `POST /api/auth/websocket-ticket` -> `/ws?wsTicket=`. RPC: `git.runStackedAction {actionId, cwd: <row>/work, action: "create_pr"}`; every stream event recorded.
- Server env replaced (not extended): `PATH=<harness>/bin:/usr/bin:/bin`, `HOME=<out>/fakehome`, `GIT_CONFIG_GLOBAL=<out>/gitconfig` (empty), `GIT_CONFIG_NOSYSTEM=1`, `GIT_TERMINAL_PROMPT=0`, `NODE_USE_ENV_PROXY=1`, `HTTPS_PROXY/HTTP_PROXY=http://127.0.0.1:<stub>`, `NO_PROXY=127.0.0.1,localhost`, `NODE_EXTRA_CA_CERTS=<out>/ca/ca.pem`. Bootstrap also sets `shellEnvironmentPrepared: true`: without it the server's login-shell PATH hydration put the machine's real `/usr/local/bin/codex` ahead of the fake (observed in a trial run: real codex was spawned and tried api.openai.com, which the proxy refused; that trial was discarded).
- Remote: origin URL `https://github.invalid/acme/demo.git` with `url.<bare>.pushInsteadOf`, i.e. a **local bare repo acting as the remote**. Fixture fetches use `-c url.<bare>.insteadOf` only inside `fixture.sh`.
- Forge stub: HTTPS CONNECT proxy, only `github.invalid:443` admitted (TLS terminated with a throwaway CA leaf); every other CONNECT is refused with 403 and logged. Serves `GET /api/v3/repos/acme/demo` (200 default_branch `main`; 404 for R4*), GraphQL `PullRequestsByHead` (empty until a PR is created, then returns it), `POST /api/v3/repos/acme/demo/pulls` (logged = the forge request; returns PR #7).
- Fake `gh` (only `auth token` -> `fake-token`), fake `codex` (`--version`, `mcp list --json` -> `[]`, `exec` saves the prompt and writes `{"title":"Fixture PR","body":"fixture body"}`).
- Proxy smoke test (before collecting rows): `fetch("https://github.invalid/api/v3/repos/acme/demo")` -> 200 from stub; `fetch("https://example.com/")` -> refused (`connect-refused example.com:443` in log).
- Leak check: in every row/version the only admitted CONNECT target was `github.invalid:443` (24 total). Refused (blocked, never reached): `raw.githubusercontent.com:443` and `ingest.t3.codes:443` on every run — server background traffic (catalog/telemetry), identical in before and after.
- Fixture integrity: `refs-before.txt` == `refs-after.txt` (bare remote refs + HEAD, work heads/remotes, origin/HEAD, branch.child config) for all 12 runs (`refsUnchanged: true`).

## Commands
```sh
export PATH="$HOME/.bun/bin:$HOME/.local/bin:$HOME/.local/share/vite-plus/bin:$PATH"
git -C /home/ubuntu/t3code worktree add --detach /tmp/ev-22943/before 8d3b0611 && (cd /tmp/ev-22943/before && pnpm install)
cd /home/ubuntu/wt/pr-22943
node apps/server/scripts/evidence/pr-22943/run.mjs --smoke --out /tmp/ev-22943/smoke
node apps/server/scripts/evidence/pr-22943/run.mjs --server /home/ubuntu/wt/pr-22943 --out /tmp/ev-22943/after
node apps/server/scripts/evidence/pr-22943/run.mjs --server /tmp/ev-22943/before   --out /tmp/ev-22943/before-out
```
(The driver from the PR worktree drives both servers; the RPC contracts are identical between the two SHAs — the PR only changes `GitManager.ts` and its test.)

## Summary table
| Row | Before base (POST /pulls) | After base (POST /pulls) | Notice (after) | Matches matrix? |
|---|---|---|---|---|
| R1 | `parent` (head `child`) | `parent` (head `child`) | none | yes |
| R2a | `parent` (head `child`) | `main` (head `child`) | `Base origin/parent is unavailable in this checkout. Using default branch main.` | yes |
| R2b | `parent` (head `child`) | `parent` (head `child`) | none | yes |
| R3 | `parent` (head `child`) | `main` (head `child`) | `Base origin/parent is unavailable in this checkout. Using default branch main.` | yes |
| R4a | `parent` (head `child`) | no request; RPC failed: GitCommandError readRangeContext.log | `Base origin/parent is unavailable in this checkout. Using default branch main.` | yes |
| R4b | no request; RPC failed: GitCommandError readRangeContext.log | no request; RPC failed: GitCommandError readRangeContext.log | none | yes |

## Per-row transcripts

### R1: recorded base `parent` pushed and present on remote
Fixture (before-version run; after-version fixture verified identical in refs and config, ignoring SHAs):
```
# bare remote (local bare repo acting as the remote): for-each-ref
604d2cf refs/heads/child
92cf680 refs/heads/main
ade242b refs/heads/parent
# bare remote HEAD: refs/heads/main
# work: for-each-ref refs/heads refs/remotes
604d2cf refs/heads/child
92cf680 refs/heads/main
ade242b refs/heads/parent
92cf680 refs/remotes/origin/HEAD
604d2cf refs/remotes/origin/child
92cf680 refs/remotes/origin/main
ade242b refs/remotes/origin/parent
# work: symbolic-ref refs/remotes/origin/HEAD: refs/remotes/origin/main
# work: branch.child.* config
branch.child.remote origin
branch.child.merge refs/heads/child
branch.child.gh-merge-base parent
```

**Before** (`8d3b061121`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `604d2cf Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

**After** (`607524efc8`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `604d2cf Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

### R2a: `parent` pushed, then deleted on the remote, then `fetch --prune` (origin/parent gone, local `parent` remains)
Fixture (before-version run; after-version fixture verified identical in refs and config, ignoring SHAs):
```
# bare remote (local bare repo acting as the remote): for-each-ref
f2b1fb7 refs/heads/child
62676ec refs/heads/main
# bare remote HEAD: refs/heads/main
# work: for-each-ref refs/heads refs/remotes
f2b1fb7 refs/heads/child
62676ec refs/heads/main
2eb33d1 refs/heads/parent
62676ec refs/remotes/origin/HEAD
f2b1fb7 refs/remotes/origin/child
62676ec refs/remotes/origin/main
# work: symbolic-ref refs/remotes/origin/HEAD: refs/remotes/origin/main
# work: branch.child.* config
branch.child.remote origin
branch.child.merge refs/heads/child
branch.child.gh-merge-base parent
```

**Before** (`8d3b061121`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `f2b1fb7 Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

**After** (`607524efc8`)
- forge POST /pulls body: {"base": "main", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Base origin/parent is unavailable in this checkout. Using default branch main. | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "main", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR Base origin/parent is unavailable in this checkout. Using default branch main.`
- text-generation prompt: `Base branch: main`; commits `f2b1fb7 Child commit`, `2eb33d1 Parent commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

### R2b: `parent` pushed, deleted on the remote, NO fetch (stale `refs/remotes/origin/parent` still present)
Fixture (before-version run; after-version fixture verified identical in refs and config, ignoring SHAs):
```
# bare remote (local bare repo acting as the remote): for-each-ref
5ea8e06 refs/heads/child
56d43b9 refs/heads/main
# bare remote HEAD: refs/heads/main
# work: for-each-ref refs/heads refs/remotes
5ea8e06 refs/heads/child
56d43b9 refs/heads/main
1ee6425 refs/heads/parent
56d43b9 refs/remotes/origin/HEAD
5ea8e06 refs/remotes/origin/child
56d43b9 refs/remotes/origin/main
1ee6425 refs/remotes/origin/parent
# work: symbolic-ref refs/remotes/origin/HEAD: refs/remotes/origin/main
# work: branch.child.* config
branch.child.remote origin
branch.child.merge refs/heads/child
branch.child.gh-merge-base parent
```

**Before** (`8d3b061121`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `5ea8e06 Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

**After** (`607524efc8`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `5ea8e06 Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

### R3: `parent` never pushed
Fixture (before-version run; after-version fixture verified identical in refs and config, ignoring SHAs):
```
# bare remote (local bare repo acting as the remote): for-each-ref
d122776 refs/heads/child
15145af refs/heads/main
# bare remote HEAD: refs/heads/main
# work: for-each-ref refs/heads refs/remotes
d122776 refs/heads/child
15145af refs/heads/main
794570d refs/heads/parent
15145af refs/remotes/origin/HEAD
d122776 refs/remotes/origin/child
15145af refs/remotes/origin/main
# work: symbolic-ref refs/remotes/origin/HEAD: refs/remotes/origin/main
# work: branch.child.* config
branch.child.remote origin
branch.child.merge refs/heads/child
branch.child.gh-merge-base parent
```

**Before** (`8d3b061121`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `d122776 Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

**After** (`607524efc8`)
- forge POST /pulls body: {"base": "main", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Base origin/parent is unavailable in this checkout. Using default branch main. | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "main", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR Base origin/parent is unavailable in this checkout. Using default branch main.`
- text-generation prompt: `Base branch: main`; commits `d122776 Child commit`, `794570d Parent commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

### R4a: repo built on `trunk`, no origin/HEAD, bare HEAD dangling at refs/heads/main, no `main` anywhere, stub returns 404 for repo info, `parent` never pushed, gh-merge-base=parent
Fixture (before-version run; after-version fixture verified identical in refs and config, ignoring SHAs):
```
# bare remote (local bare repo acting as the remote): for-each-ref
ba5d28b refs/heads/child
4139e05 refs/heads/trunk
# bare remote HEAD: refs/heads/main
# work: for-each-ref refs/heads refs/remotes
ba5d28b refs/heads/child
3a5f946 refs/heads/parent
4139e05 refs/heads/trunk
ba5d28b refs/remotes/origin/child
4139e05 refs/remotes/origin/trunk
# work: symbolic-ref refs/remotes/origin/HEAD: (none)
# work: branch.child.* config
branch.child.remote origin
branch.child.merge refs/heads/child
branch.child.gh-merge-base parent
```

**Before** (`8d3b061121`)
- forge POST /pulls body: {"base": "parent", "head": "child", "title": "Fixture PR", "body": "fixture body", "maintainer_can_modify": true}
- phase labels: pr: Preparing PR... | pr: Generating PR content... | pr: Creating pull request...
- result pr: `{"status": "created", "url": "https://github.invalid/acme/demo/pull/7", "number": 7, "baseBranch": "parent", "headBranch": "child", "title": "Fixture PR"}`
- toast: title `Created PR #7`, description `Fixture PR`
- text-generation prompt: `Base branch: parent`; commits `ba5d28b Child commit`
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

**After** (`607524efc8`)
- forge POST /pulls body: no request
- phase labels: pr: Preparing PR... | pr: Base origin/parent is unavailable in this checkout. Using default branch main.
- error event: `Git command failed in GitVcsDriver.readRangeContext.log (/tmp/ev-22943/after/R4a/work): Git command exited with a non-zero status.`
- text-generation prompt: codex exec never called
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

After-version git error reproduced by hand in the same fixture: `git log --oneline main..HEAD` -> `fatal: ambiguous argument 'main..HEAD': unknown revision or path not in the working tree.` (the server log does not include git stderr).

### R4b: R4a fixture with `branch.child.gh-merge-base` unset (control)
Fixture (before-version run; after-version fixture verified identical in refs and config, ignoring SHAs):
```
# bare remote (local bare repo acting as the remote): for-each-ref
6cce9fd refs/heads/child
2f6a784 refs/heads/trunk
# bare remote HEAD: refs/heads/main
# work: for-each-ref refs/heads refs/remotes
6cce9fd refs/heads/child
1c1b822 refs/heads/parent
2f6a784 refs/heads/trunk
6cce9fd refs/remotes/origin/child
2f6a784 refs/remotes/origin/trunk
# work: symbolic-ref refs/remotes/origin/HEAD: (none)
# work: branch.child.* config
branch.child.remote origin
branch.child.merge refs/heads/child
```

**Before** (`8d3b061121`)
- forge POST /pulls body: no request
- phase labels: pr: Preparing PR... | pr: Generating PR content...
- error event: `Git command failed in GitVcsDriver.readRangeContext.log (/tmp/ev-22943/before-out/R4b/work): Git command exited with a non-zero status.`
- text-generation prompt: codex exec never called
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

**After** (`607524efc8`)
- forge POST /pulls body: no request
- phase labels: pr: Preparing PR... | pr: Generating PR content...
- error event: `Git command failed in GitVcsDriver.readRangeContext.log (/tmp/ev-22943/after/R4b/work): Git command exited with a non-zero status.`
- text-generation prompt: codex exec never called
- refs unchanged by run: True; refused CONNECTs: ['ingest.t3.codes:443', 'raw.githubusercontent.com:443']

## What else changed (before vs after), besides the chosen base
1. **Progress label replaced, not added.** When the recorded base is missing (R2a, R3, R4a) the after-version's second `pr` `phase_started` label is the notice `Base origin/parent is unavailable in this checkout. Using default branch main.` *instead of* `Generating PR content...`. Event count and kinds are otherwise identical (action_started, 3× phase_started, action_finished/failed).
2. **Toast description gains the notice.** R2a/R3 after: `Fixture PR Base origin/parent is unavailable in this checkout. Using default branch main.` (title text + space + notice). Before: `Fixture PR`.
3. **Commit range in the generation prompt widens.** R2a/R3 after: `Base branch: main`, commits = Child + Parent. Before: `Base branch: parent`, commits = Child only.
4. **One extra forge request** in R2a/R3/R4a after: `GET /api/v3/repos/acme/demo` (provider default-branch lookup on the fallback path). R1/R2b after make no extra request vs before. No extra GraphQL calls.
5. **R4a outcome flips from silent wrong PR to an error.** Before: PR created with `base: parent` (codex exec called once, POST sent). After: zero POST /pulls, codex exec never called, RPC fails with `GitCommandError ... GitVcsDriver.readRangeContext.log ... non-zero status` after emitting the notice naming `main`. The notice claims "Using default branch main" even though `main` does not exist; the failure that follows is a generic git error, not a message explaining that no default branch could be resolved.
6. **R2b unchanged** (stale remote-tracking ref is trusted; no fetch). Known limitation, as stated in the PR body.
7. **R4b control unchanged** (both versions: literal `main`, same git error, no POST, no notice).
8. Notice text uses `origin/parent` (remote matching resolved origin to the target repo) in all affected rows.

## Raw logs
Per run: `/tmp/ev-22943/{before-out,after}/<row>/logs/` — `events.json`, `forge.jsonl`, `summary.json`, `server.log` (bootstrap token redacted), `gh.log`, `codex.log`, `prompt-*.txt`, `refs-before.txt`, `refs-after.txt`. Bundled in `raw-logs.tar.gz`.
