Skip to content

fix(devx): a merge-tree probe no longer records an os-regen deferral, and name the sound probe spelling - #15868

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-15815-merge-tree-probe-os-regen
Sep 5, 2026
Merged

fix(devx): a merge-tree probe no longer records an os-regen deferral, and name the sound probe spelling#15868
baozhoutao merged 1 commit into
mainfrom
claude/issue-15815-merge-tree-probe-os-regen

Conversation

@claude

@claude claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Part of #15815 — the ORDINARY half only. The governed half (the same corollary sentence in AGENTS.md Multi-agent discipline section 11) is a separate card the PM seat files, so this PR deliberately does not touch it. .gitattributes is unchanged.

⚠️ The dispatch ruling's probe spelling is FALSIFIED, and this PR does not ship it

The ruling named git -c merge.os-regen.driver= merge-tree --write-tree BASE HEAD as the safe spelling. The card's own correction comment (11:01Z) says that command is unsound, and I measured it and the correction is right. Setting the driver to the empty string does not disable it: git still tries to RUN it, fails with error: cannot run : No such file or directory, and marks the path conflicted — so it reports a conflict for every routed path, including ones that text-merge perfectly.

Two pairs over packages/spec/spec-changes.json, git 2.43.0, exit codes captured before any pipe. Ground truth is git merge-file on the three blobs, which is what a driver-less server-side merge runs:

pair truth driver ON -c ...driver= bare shared clone
same line edited both sides exit 1 exit 0 exit 1 ✓ exit 1 ✓
edits 1996 lines apart exit 0 exit 0 ✓ exit 1 exit 0 ✓

The middle column is the trap the card is about. The third is a false-positive instrument that agrees with the truth only by coincidence. Only the bare-shared-clone column tracks the truth in both rows, so that is the spelling the header now carries:

git clone --bare --shared . PROBE.git
git --git-dir=PROBE.git merge-tree --write-tree --name-only BASE HEAD
rm -rf PROBE.git

The ruling's corollary sentence itself is unchanged and is in the header verbatim in substance: a local merge-tree of any merge=os-regen path with the driver registered is not evidence about GitHub's mergeability.

The marker gate — what actually distinguishes a probe

The ruling's hypothesis was "a merge-tree invocation has no worktree to write". Measured false: merge-tree runs with is-inside-work-tree: true, show-toplevel and absolute-git-dir identical to a real merge. So is the next candidate. The driver was replaced by a shim dumping argv, env and git state; every shape rebuilt from a fresh fixture:

shape GITHEAD_* GIT_REFLOG_ACTION $(git-path index).lock
merge-tree 0 unset no
merge-tree (old mode) 0 unset no
merge 1 merge other YES
merge --squash 1 merge other YES
merge --no-commit · · YES
pull 1 pull … other YES
cherry-pick 0 unset YES
rebase 0 unset YES
am -3 · · YES
checkout -m · · YES

⛔ The two env vars a reader reaches for first are absent for cherry-pick and rebase — real merges that DO write the worktree and DO owe the marker. Gating on them would drop the marker there, silently, in the dangerous direction. The index lock is held by all eight real-merge shapes and by neither merge-tree mode, and it is the mechanism rather than an accident: merge-tree is the low-level command that does not touch the index or working tree. Read through git rev-parse --git-path index, so a linked worktree's own index and GIT_INDEX_FILE both answer correctly (verified from a linked worktree: probe no, real merge YES).

Anything unmeasurable falls back to marking — the asymmetry is written into the code comment: a false "real merge" costs one self-clearing marker, a false "probe" would leave pre-commit nothing to refuse.

Verification

Exit codes captured before any pipe; verdict lines quoted as the tools printed them.

  • Reproduction, before (real driver, clone with pnpm install --offline run; merge.os-regen.driver = node "$(git rev-parse --show-toplevel)/scripts/git-merge-regen.mjs" %O %A %B %P): merge-tree with the driver on exited 0, printed ⟳ packages/spec/spec-changes.json / not text-merged — it is generated, and left the marker containing packages/spec/spec-changes.json.
  • Reproduction, after: same probe, both pairs, still exit 0 with the same defer notice, marker ABSENT. Control in the same clone: a REAL git merge still records packages/spec/spec-changes.json.
  • node scripts/git-merge-regen.mjs --self-test: exit 0 before and after; the only output delta is the added line ✓ probe gate: git merge-tree reaches the driver and records nothing; the same repo's real merge still records.
  • Ablation (trap-guarded, git hash-object proof both ways): commenting out the one gate line changed the blob 7b4734ba…cacac5ab…, and the self-test went red with ✗ self-test: a git merge-tree probe wrote os-regen-pending — the probe gate is not firing✗ merge driver wiring is inconsistent — 1 failure(s). Restore verified byte-identical to HEAD with an empty git diff HEAD.
  • The new battery carries its own firing control: the driver's defer notice must appear on the probe's stderr before an absent marker is allowed to mean anything — otherwise "the fixture stopped routing" and "the gate works" print the same green.
  • bash scripts/pm/os-regen-merge.sh --self-test: exit 0 before and after, output byte-identical.
  • node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstack --commands derived 31 families; all 31 run, all green. Reconciled: ✓ dispatch-gates --ran: 31 derived famil(ies) accounted for — 31 run, 0 NOT-MEASURED. Six of them first refused with exit 3 / ERR_MODULE_NOT_FOUND (prerequisite not met, nothing measured) and were re-run green after the offline install. pnpm check:pm-dispatch-gates needed more than 420s and is green at ✓ dispatch-gates self-test: 1511 cases pass.
  • pnpm check:nul-bytes exit 0, plus a direct control-character sweep over both files (no hits).
  • node scripts/pm/check-governed-merges.mjs --test on the final file list: ✅ NOT governed — ordinary queue landing applies to a PR with exactly this file list.
  • Mergeability of this branch, using the sound instrument against origin/main: exit 0, merges clean.
  • No open PR touches either file (all 27 open PRs enumerated through pulls/N/files).

Scripts-only diff, so skip-changeset.

🤖 Generated with Claude Code

https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk


Generated by Claude Code

…l, and name the sound probe spelling

`git merge-tree --write-tree` runs merge-ort, so it invokes the `os-regen`
merge driver — which recorded `$GIT_DIR/os-regen-pending` for a merge that
wrote nothing. The next ordinary commit in that checkout was then refused by
`pre-commit` with a staleness report for a merge that never happened.

Gate the marker write on the index lock. Measured across ten invocation
shapes: `GITHEAD_*`/`GIT_REFLOG_ACTION` — the obvious signals — are absent for
cherry-pick and rebase, which are real merges that do owe the marker; the
index lock is held by all eight real-merge shapes and by neither merge-tree
mode. Pinned in `--self-test` in both directions, with a firing control so
"no marker" cannot pass by never reaching the driver.

`scripts/pm/os-regen-merge.sh`'s header gains the corollary and the sound
probe spelling. The `-c merge.os-regen.driver=` spelling is documented as
REFUSED: the empty string does not disable the driver, so it reports a
conflict for every routed path, including ones that text-merge cleanly.

Part of #15815

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
@claude

claude Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor Author

Flipped ready + auto-merge enabled (12:18Z, method: MERGE). All seven required contexts on af1161675 read non-failing: Lint & Repo Gates, TypeScript Type Check, Test Core, Dogfood Regression Gate, Governed Surface Queue Guard success; Build Core, Temporal Conformance (live PG + MySQL) skipped; no other red. Mergeability through the sound bare-clone probe (no driver) → EXIT=0 against ef3a1388d. Watched; Part of #15815 — the card stays open until the governed half (#15871, dispatched) lands.


Generated by Claude Code

@baozhoutao
baozhoutao added this pull request to the merge queue Sep 5, 2026
baozhoutao pushed a commit that referenced this pull request Sep 5, 2026
…regen path is not GitHub mergeability, and name the sound probe (#15871)

AGENTS.md §11 already says the `merge=os-regen` driver is a LOCAL facility. What
it never stated is the corollary that costs a seat a round trip: a local
`git merge-tree` of a routed path runs the same merge-ort machinery as
`git merge`, so it HONOURS the driver, while GitHub runs none — the two answer
different questions about the same snapshot.

The added bullet names the sound instrument (a throwaway bare clone sharing the
object store, where the driver is genuinely absent, which is GitHub's actual
condition) and refuses the falsified `-c merge.os-regen.driver=` spelling, whose
empty string does not disable the driver but leaves git failing to run it and
reporting a conflict for every routed path — including ones that text-merge
cleanly. Measurements are on PR #15868, which carries the same text in
`scripts/pm/os-regen-merge.sh`'s header.

Part of #15815

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk
Merged via the queue into main with commit af29b66 Sep 5, 2026
36 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-15815-merge-tree-probe-os-regen branch September 5, 2026 12:49
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/m skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants