Skip to content

docs(pm-skill): the ledger's merge-tree reading is the registered-driver hazard, probed from a driver-less clone - #16499

Merged
os-zhuang merged 1 commit into
mainfrom
claude/issue-16457-merge-tree-reading-reconciled
Sep 7, 2026
Merged

docs(pm-skill): the ledger's merge-tree reading is the registered-driver hazard, probed from a driver-less clone#16499
os-zhuang merged 1 commit into
mainfrom
claude/issue-16457-merge-tree-reading-reconciled

Conversation

@claude

@claude claude Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Fixes #16457
Fixes #15647

One file, one site, line-neutral: .claude/skills/pm-dispatch/references/platform-readings.md
stays at 388 lines (ceiling 388, headroom 0). No other line, no ceiling change, no ratchet edit.

The contradiction, in the two texts themselves

Old lines 26–28 (the older, ruled reading):

- 它只答默认文本合并,不套 `.gitattributes` 的 merge driver。
- ⇒ 两侧同动一条 `merge=os-regen` 路径时系统性低报,方向危险:报干净而真合并会停。
- 这类 diff 由 `mergeable_state` 或 scratch worktree 里的真 `git merge` 定夺。

Old lines 352–353 (the measured reading that landed with PR #16379, git 2.43.0):

- `merge-tree` 套不套 `.gitattributes` 驱动随本克隆注册与否变,驱动 exit 0 只说驱动收下了。
- ⇒ 驱动管辖的路径上冲突证明跑两遍,第二遍带 `-c merge.os-regen.driver=false` 关掉驱动。

Both observations are true and they are about different clones: merge-tree --write-tree
runs git merge's own merge-ort, so a clone that has the driver registered honours it and one
that does not falls back to git's default text merge. The inference on the old line 27 is
what does not survive — "it never applies the driver, therefore it systematically UNDER-reports"
— and the real hazard runs the other way on a registered clone: a driver that took the path
exits 0 because it deferred the content judgement, so a clean report says nothing about
content at all.

The new lines (26–30)

- 它跑 `git merge` 的 merge-ort ⇒ 注册 `merge=os-regen` 的克隆照用驱动,未注册的退回文本合并。
- 注册按克隆(`pnpm install` 的 prepare),服务端一个驱动都不跑 ⇒ 两侧答的不是同一个问题。
- 驱动接手的路径上 exit 0 只说内容判断被推迟,⛔ 不是无冲突:它对内容什么都没说。
- ⇒ 对照复现的是被测条件不只是命令:冲突证明从无驱动裸克隆 `clone --bare --shared` 探。
- ⛔ 永不用 `-c merge.os-regen.driver=` 覆盖:驱动不是被关掉而是跑失败,路由路径全报冲突。

They sit where the probe is actually used — directly under the two lines that spell the
git merge-tree --write-tree origin/main REF command (24–25), which is where a seat reading
"is this head dirty" arrives.

The fold that paid for the two extra lines

3 lines out, 5 lines in at the kept site; old 352–353 deleted, because after the rewrite they
were the same mechanism stated a second time in 读数陷阱. 5 insertions / 5 deletions,
388 → 388.
The one clause old 353 carried that the new text does not is its -c recipe, and
that recipe is the thing this PR bans.

The probe rule is the corollary's, not the earlier two-leg habit

PR #15885's AGENTS.md corollary is not on main yet, so it was read from that PR's head
(claude/issue-15871-agents-merge-tree-corollary, ca2088e3d8), verbatim:

Probe from a throwaway bare clone that shares the object store and has no driver registered
(git clone --bare --shared . PROBE.git, then git --git-dir=PROBE.git merge-tree --write-tree --name-only BASE HEAD), ⛔ never with -c merge.os-regen.driver=, which 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.

The new lines say the same thing in the ledger's register, and the in-repo authority
(scripts/pm/os-regen-merge.sh, its measured 2×3 table) already agrees with both.

#15647 §2 item 2, folded as a clause and not as a fourth line

The ruled principle — a control reproduces the CONDITION under test, not merely the command;
same repo, same configuration; when comparing with the server's view the custom driver has to
be genuinely absent
— is the first clause of the probe line above
(对照复现的是被测条件不只是命令). It rides the fact it governs, which is the file's house
style, and it costs no line of its own.

Reported, not edited: the two-leg -c form

The dispatch expected .claude/skills/pm-dispatch/SKILL.md to spell the two-leg -c form
today. It does not, on origin/main (4500bc5) or in the open PR that holds that file
(PR #16486): the only site in the whole tree that spelled it was this ledger's own line 353,
which this PR deletes.

$ git grep -n 'merge\.os-regen\.driver' -- '*.md' '*.mjs' '*.sh' '*.ts'
packages/spec/src/migrations/entries/README.md:96  ... no `merge.os-regen.driver` configured ...
packages/spec/src/migrations/entries/README.md:129  git clone --shared --no-local . /tmp/driverless
scripts/pm/os-regen-merge.sh:143  # ⛔ NOT `git -c merge.os-regen.driver= merge-tree ...`
.claude/skills/pm-dispatch/references/platform-readings.md:353  (deleted here)

So no SKILL.md follow-up card is needed; the seat may still want the finding recorded.

Gates — every exit captured before any pipe, all on the final commit 1e489533f1

node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 16
runnable families from the change set (which it derived itself, from the merge base — 1 path);
all 16 were run and reconciled:

✓ dispatch-gates --ran: 16 derived famil(ies) accounted for — 16 run, 0 NOT-MEASURED.

Named verdict lines:

✓ check-skill-line-ratchet self-test: 157 cases pass.
✓ check-skill-line-ratchet: .claude/skills/pm-dispatch/references/platform-readings.md is 388 lines (ceiling 388; headroom 0).
✓ check-skill-frame-sync self-test: 13 cases pass, plus 5 dispatch-gates declaration cases and 3 scan-population cases
✓ check-skill-frame-sync: 2 copies of the decision frame are structurally isomorphic across 2 files
✓ check-skill-id-lint self-test: 14 cases pass.
✓ check-skill-id-lint: 26 file(s) clean (pattern /#[0-9]{3,}/g).
✓ check-nul-bytes (pnpm check:nul-bytes, exit 0) — plus a hand scan of the edited file for the other control bytes, zero hits

Governed-surface predicate, quoted:

$ node scripts/pm/check-governed-merges.mjs --test .claude/skills/pm-dispatch/references/platform-readings.md ; echo EXIT=$?
governed-surface predicate: 1 of 1 path(s) hit the register (5 surfaces, repo-agnostic).
  ⛔  GOVERNED — a human merge is the review record for this PR (#9495 regime).
EXIT=3

Whole-repo lint, not narrowed — pnpm lint (eslint . --no-inline-config) through the shared
verify lock, slot issue-16457:

os-verify-lock: VERDICT command-exit 0 · held the lock 94s (1m34s) · waited 1s

One family needed a prerequisite before it could measure anything: check:doc-formula-expressions
first exited 3 (PREREQUISITE NOT MET — @objectstack/formula and @objectstack/lint unbuilt,
nothing measured). After building both under the same lock it exits 0. Both readings are recorded
rather than the second one alone.

Serial

No open PR touches this ledger — checked over all 31 open PRs by file list; PR #16486 holds
SKILL.md, core-rules.md, seat-post-protocol.md and the ratchet script, and this PR touches
none of those. The sixth readings increment (the 8-card family) is not yet dispatched, so the
seat should sequence it after this lands rather than in parallel.

维护者速读(草稿)

事情:台账里关于 git merge-tree 的三行旧读数被改写成实测那条 —— 驱动注册了就照用,驱动报 exit 0 只表示内容判断被推迟;探针改为从无驱动的裸克隆跑,并顺手带上「对照要复现被测条件」这条纪律。
为什么:两处文字互相矛盾,旧的那处推论已被 git 2.43.0 的实测推翻,而按它去读会把「会冲突」读成「干净」;两条都是您已答「同意」的裁决。
风险:纯文字,零代码;行数 388 不动、上限不动、棘轮不动;回滚即 revert 一个 commit。
要您做什么:受管面,人工合并这张 PR;或指出哪一行措辞与您的裁决不符。


Generated by Claude Code

…ver hazard, probed from a driver-less clone

`git merge-tree --write-tree` runs `git merge`'s own merge-ort, so a clone that
has the `merge=os-regen` driver registered HONOURS it and a clone that does not
falls back to git's default text merge. Both observations are true; the old
line's inference — "it only answers the default text merge, therefore it
systematically under-reports" — is not, and it is the half that had been ruling
the reading.

Rewritten in the register the file uses, one fact per line: what decides whether
the driver applies (registration, which is per clone), what the driver's exit 0
means (the content judgement was deferred — it says nothing about content), the
sound probe with the control rule it carries (a control reproduces the CONDITION
under test, not merely the command, so the probe runs from a driver-less bare
clone), and the ban on the `-c merge.os-regen.driver=` override, which does not
disable the driver but leaves git failing to run it and reporting a conflict for
every routed path.

The later restatement of the same mechanism under 读数陷阱 is the fold that paid
for the two extra lines: one site instead of two, the file unchanged at 388
lines, the ratchet ceiling untouched.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019RfFHiRCSs3JXLK4cwcfox
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/s skip-changeset PR has no user-facing published change; bypasses the changeset gate

Projects

None yet

2 participants