Plugin: review · Category: baked repo assumption / silent wrong-or-empty diff base
Source: bot review on #591 (chatgpt-codex-connector, two P1 findings) + the maintainer's own thread-1 scope note; confirmed VALID, deferred out of #591's scope as design-shaped.
Summary
#591 fixed the origin/main-baked terminal fallback and the full-depth --single-branch default-base case (fetch resolved default branch, diff against FETCH_HEAD). Two constrained-clone facets of the diff-base ladder remain, both sharing one root — the ladder resolves the base from local refs / a single shared FETCH_HEAD that constrained clones don't populate as assumed — and one fix design fork. They belong together in a single reworked base-resolution path, not re-patched across the five dense one-liners (four reviewer agents + the fanout diff-size snippet), where each inline escalation has demonstrably invited the next bot finding.
Facet A — --depth=1 shallow clone (default actions/checkout shape)
After fetching the resolved default branch at the same shallow depth, git merge-base FETCH_HEAD HEAD finds no common ancestor, so the ladder degrades to echo HEAD and git diff HEAD is empty — the silent no-op #591 set out to eliminate. Reproduced (3-commit main, feature off its tip, --depth=1 --single-branch): after git fetch origin main, merge-base FETCH_HEAD HEAD fails; git fetch --unshallow origin flips is-shallow-repository false and it then resolves.
Facet B — full-depth --single-branch clone with a PR against a NON-default base
The PR_BASE rung (git merge-base "origin/${PR_BASE:-HEAD}" HEAD) — pre-existing, untouched by #591 — relies on a local origin/<base> ref. In a --single-branch clone, git fetch origin "$PR_BASE" populates only FETCH_HEAD, never refs/remotes/origin/<base>, so this rung fails. The ladder then falls to #591's new default-branch rung, which fetches the default branch into FETCH_HEAD (overwriting the PR base) and diffs against the default merge-base rather than the PR's real base (e.g. release) — silently folding the base branch's pre-existing changes into the review as if they were the PR's. git fetch needs --append to add to FETCH_HEAD instead of overwriting; the base must be captured (an explicit rev/ref) before the default-branch fallback runs. #591 changed this scenario's symptom from empty-diff to a wrong, misleading diff base; it was already broken (empty) pre-#591. Maintainer flagged the same root in #591 thread 1: "the pre-existing PR_BASE rung shares the same local-resolution limitation for a non-default PR base in single-branch clones."
Design fork (needs a human decision — hence status: needs-decision)
- Fetch-more / deepen — capture each fetched base as an explicit rev before the next fetch overwrites
FETCH_HEAD (facet B), and lazily git fetch --unshallow when the shallow merge-base fails (facet A). Correct, but --unshallow on a large repo is a heavy, unbounded download on every affected agent invocation — a cost that should be chosen deliberately, not baked into an unattended pass.
- Convention-aligned report-and-stop —
fanout/SKILL.md already prescribes "report which ref failed and STOP" for an unresolvable base; the agent files currently violate that by silently reaching echo HEAD (facet A) or a wrong base (facet B). Failing loudly is cheap and honest but changes agent behavior on constrained clones.
Picking between "fetch/unshallow at any cost" and "fail loudly", and factoring the shared resolution into one helper, is a real design decision — the maintainer's stated intent is for this logic to live once in a shared default-branch/base helper rather than across five one-liners.
Relationships
Plugin:
review· Category: baked repo assumption / silent wrong-or-empty diff baseSource: bot review on #591 (chatgpt-codex-connector, two P1 findings) + the maintainer's own thread-1 scope note; confirmed VALID, deferred out of #591's scope as design-shaped.
Summary
#591 fixed the
origin/main-baked terminal fallback and the full-depth--single-branchdefault-base case (fetch resolved default branch, diff againstFETCH_HEAD). Two constrained-clone facets of the diff-base ladder remain, both sharing one root — the ladder resolves the base from local refs / a single sharedFETCH_HEADthat constrained clones don't populate as assumed — and one fix design fork. They belong together in a single reworked base-resolution path, not re-patched across the five dense one-liners (four reviewer agents + thefanoutdiff-size snippet), where each inline escalation has demonstrably invited the next bot finding.Facet A —
--depth=1shallow clone (defaultactions/checkoutshape)After fetching the resolved default branch at the same shallow depth,
git merge-base FETCH_HEAD HEADfinds no common ancestor, so the ladder degrades toecho HEADandgit diff HEADis empty — the silent no-op #591 set out to eliminate. Reproduced (3-commitmain,featureoff its tip,--depth=1 --single-branch): aftergit fetch origin main,merge-base FETCH_HEAD HEADfails;git fetch --unshallow originflipsis-shallow-repositoryfalse and it then resolves.Facet B — full-depth
--single-branchclone with a PR against a NON-default baseThe PR_BASE rung (
git merge-base "origin/${PR_BASE:-HEAD}" HEAD) — pre-existing, untouched by #591 — relies on a localorigin/<base>ref. In a--single-branchclone,git fetch origin "$PR_BASE"populates onlyFETCH_HEAD, neverrefs/remotes/origin/<base>, so this rung fails. The ladder then falls to #591's new default-branch rung, which fetches the default branch intoFETCH_HEAD(overwriting the PR base) and diffs against the default merge-base rather than the PR's real base (e.g.release) — silently folding the base branch's pre-existing changes into the review as if they were the PR's.git fetchneeds--appendto add toFETCH_HEADinstead of overwriting; the base must be captured (an explicit rev/ref) before the default-branch fallback runs. #591 changed this scenario's symptom from empty-diff to a wrong, misleading diff base; it was already broken (empty) pre-#591. Maintainer flagged the same root in #591 thread 1: "the pre-existing PR_BASE rung shares the same local-resolution limitation for a non-default PR base in single-branch clones."Design fork (needs a human decision — hence
status: needs-decision)FETCH_HEAD(facet B), and lazilygit fetch --unshallowwhen the shallow merge-base fails (facet A). Correct, but--unshallowon a large repo is a heavy, unbounded download on every affected agent invocation — a cost that should be chosen deliberately, not baked into an unattended pass.fanout/SKILL.mdalready prescribes "report which ref failed and STOP" for an unresolvable base; the agent files currently violate that by silently reachingecho HEAD(facet A) or a wrong base (facet B). Failing loudly is cheap and honest but changes agent behavior on constrained clones.Picking between "fetch/unshallow at any cost" and "fail loudly", and factoring the shared resolution into one helper, is a real design decision — the maintainer's stated intent is for this logic to live once in a shared default-branch/base helper rather than across five one-liners.
Relationships
review0.14.3.originhardcoded in pull-request create flow (low severity) #442 (source-controloriginremote-name hardcode) — same "baked repo assumption" ladder family, distinct mechanism; kept separate to avoid muddying source-control: remote nameoriginhardcoded in pull-request create flow (low severity) #442's ready, source-control-scoped spec.