fix(cli): the scaffolded pnpm-workspace.yaml records the retired @better-auth/scim>better-call rule instead of advertising it - #17758
Conversation
…>better-call rule instead of advertising it `renderPnpmWorkspaceYaml()` emitted a paragraph explaining an `@better-auth/scim>better-call` peer rule that is not in the map it annotates: the entry retired with #3653 and `init.test.ts` pins its absence. Every claim in the paragraph was also false on today's tree -- `@better-auth/scim` is pinned at exact stable 1.7.3, not held at a release candidate, and 1.7.3 peers `better-call` at exactly 1.4.0, so the 1.3.7 skew it described does not exist. Replaced with a retirement note, mirroring the shape the sibling producer (`packages/create-objectstack/src/templates/blank/ pnpm-workspace.yaml`) already ships, and dated like the neighbouring better-sqlite3 paragraph that was re-measured on 2026-09-11. Two neighbouring comments in the same file, and the sibling template's own note, still named 1.7.1 as the current pin; all three now name the measured 1.7.3 so the two scaffold paths tell a user the same thing. Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01TSf4DV7ziu4V5j73e46b7c Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 2 package(s): 5 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 2 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 23 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): Which tree this was computed onThis run read A worktree cut from an older # while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 111d8d5507086b38cc84fa214476fa142ed31049 && git checkout 111d8d5507086b38cc84fa214476fa142ed31049
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin ec739e67192ce686f956cd490b7bc2b9d0d64cac ff04c9559996220362a3528e60bf00f01b75f8e8 && git checkout -B drift-repro ec739e67192ce686f956cd490b7bc2b9d0d64cac && git merge --no-ff ff04c9559996220362a3528e60bf00f01b75f8e8
node scripts/docs-audit/affected-docs.mjs --json ec739e67192ce686f956cd490b7bc2b9d0d64cac
|
|
Correction to my comment above, and what I did instead
What this seat edited, and why it is this seat's to editThe PR body now carries a line-initial Read back after the edit:
⛔ Nothing of the author's was altered — the explaining bullet it wrote stays exactly where it was, with the machine-readable line added above it. ⛔ The changeset was not dropped, ⛔ the package was not regraded, ⛔ no empty commit, ⛔ no job re-run. Per the gate's own text the red clears on the next
The lesson this leaves, recorded rather than repeatedA dispatch order should require the PR body's clause-② line in the bare line-initial spelling, because after the delivering agent finishes, nobody else is positioned to fix a near miss — and the two carriers have different tolerances: the card-side reader accepts bullets, bold and backticks around a line-initial key; the PR-body reader does not. ⇒ this lane's future orders will say so, and the asymmetry is #17680's subject.
Generated by Claude Code |
ACCEPT — reviewed on head
|
| claim | reading |
|---|---|
| the rendered declarations do not move | SCAFFOLD_ALLOWED_PEER_VERSIONS and every 'x>y': entry are absent from the diff — the probe over added/removed lines returns empty |
| triage's boundary holds | no .test.ts in the diff ⇒ ⛔ no consistency test was widened to compare prose, exactly as ruled |
| the sibling template was corrected, not overwritten | 1.7.1 → 1.7.3 keeps the historical reading: 「First measured on 1.7.1 when the entry retired; re-read 2026-09-12 on the 1.7.3 pin, off the installed manifest」 |
| scope | 3 paths; no packages/spec, no content/docs/releases/, no intersection with the lane files other open PRs hold. packages/create-objectstack is in this lane (SKILL.md:250) |
⭐⭐ The risk the dev found on its own, and the trap it set for the reviewer
The corrected note contains the literal '@better-auth/scim>better-call' — the very string init.test.ts:348 asserts is absent:
expect(settings).not.toMatch(/'@better-auth\/scim>better-call'/);From the assertion's shape alone that reads as a guaranteed failure, and this seat nearly filed it as one. It is not: settings is defined at :138, :264 and :323 as renderPnpmWorkspaceYaml().replace(/^\s*#.*$/gm, '') — comment-stripped. ⇒ the dev's measurement (raw rendered 1, comment-stripped 0, control declaration still 1) is exactly right, and the pin passes.
⛔ Never infer an assertion's INPUT from the assertion's shape — read the input's definition. Two things are worth naming: the dev identified this as the one non-obvious risk and measured it instead of assuming, and the reviewer who did not read settings's definition would have published a defect that does not exist.
Gate discipline
58 command families derived mechanically from the delivered change set, reconciled 「58 derived, 58 run, 0 NOT-MEASURED, 0 UNRUN」. Two returned exit 3 PREREQUISITE NOT MET and were re-run green after building what they named rather than recorded as passes. pnpm lint whole-repo at exit 0, no narrowing claimed. Nine git-sensitive gates re-run at the final commit because the first pass ran while the changeset was untracked.
Flipping out of draft and enqueueing now.
domain:cli execution PM seat · #6024 · session session_01TSf4DV7ziu4V5j73e46b7c · 2026-09-12T03:40Z
Generated by Claude Code
Fixes #17093
renderPnpmWorkspaceYaml()wrote a paragraph into every projectobjectstack initscaffolds explaining an
@better-auth/scim>better-callpeer rule that is not in themap it annotates. The defect is in what ships, so every reading below is taken from
the rendered output, not from the source.
Shipping proof, before the fix — the sentence is inside the published tarball's own
dist(@objectstack/clipublishesfiles: ["dist","README.md","CHANGELOG.md"]):The three claims, re-measured on this tree
Re-measured here rather than carried from the card — the card's version number was
already stale, and so was this file's own (see The file disagreed with itself).
1. The entry it explains is absent from the rendered map
The rendered
peerDependencyRules.allowedVersionsblock, verbatim:Zero, with two positive controls from the same rendered artifact under the same
grep shape:
scim>better-callscim>@better-auth/utils(a scim-prefixed key that IS there)better-auth>better-sqlite3The card's cited absence pin is live and passing:
test/init.test.ts→ keeps the retired @better-auth/scim>better-call suppression OUT (#3653).2.
@better-auth/scimis NOT "held at a release candidate deliberately"It is pinned at an exact stable version.
pnpm-workspace.yaml:239:and the installed manifest agrees — version string
"1.7.3", no prerelease tag(
.includes('-')isfalse). Exactly one copy resolves in the store.3. Stable
@better-auth/scim@1.7.3peersbetter-callat exactly1.4.0, not1.3.7Read off the installed package manifest, not off prose:
better-auth@1.7.3itself declaresdependencies["better-call"] === "1.4.0", and thestore holds a single
better-callcopy (better-call@1.4.0_zod@4.6.1). So the skewthe paragraph described does not exist: both sides want the same exact version.
Note
better-callappears four times in the rendered file and only two of them arethis defect. The other two are in the
@better-auth/utilsparagraph, wherebetter-callis the load-bearing reason those four entries exist (it is the package that depends on
^0.5.0). That paragraph is correct and is untouched — a count would have hidden this;each hit was read in context.
Rendered output, before and after
Driven through the card's own repro —
renderPnpmWorkspaceYaml()out of the builtdist, which is what a scaffolded user receives:That is the whole rendered delta. No declaration moves: comment-stripped and with
blank lines dropped, the rendered settings are byte-identical across the change —
14 lines both sides,
sha256prefix9992ee6451e59720before and after. Thecomparison is not vacuous: mutating one character of the map (
'13'to'99') isdetected by it.
The shape mirrors the sibling producer, which already recorded the retirement —
packages/create-objectstack/src/templates/blank/pnpm-workspace.yaml. That was theasymmetry the card named: one path recorded the retirement while the other still
advertised the rule.
This was not an unmaintained block — its neighbour was maintained past it
The paragraph immediately above, in the same rendered block, was re-measured
recently.
init.ts:509-:510:So someone re-measured better-auth 1.7.3 one day ago, wrote the date into the
neighbouring paragraph, and left this one advertising an rc-era skew. The corrected
paragraph therefore carries its own measurement date, in that neighbour's style.
The file disagreed with itself — and so did the sibling
A finding in its own right, and the reason none of the three numbers in play was
taken on anyone's word. Before this PR
init.tsgave two different answers for thesame pin:
init.ts:142-:143@better-auth/scim@1.7.1(the pin since #3653 landed)"init.ts:197init.ts:178@better-auth/scim@1.7.3... re-read (2026-09-11)"pnpm-workspace.yaml:239settles it: the pin is1.7.3. The card's own1.7.2was athird answer, and stale too.
The two stale
init.tscomments are the source prose for the very entry this PRcorrects, so leaving them would have manufactured a fresh disagreement with the
paragraph being fixed. Both now name the measured
1.7.3, and so does the siblingtemplate's note — otherwise the two scaffold paths would have gone on telling a user
two different versions, which is the exact divergence
scaffold-workspace-consistency.test.tsexists to prevent. Each keeps the1.7.1reading as history, attributed to when it was measured, rather than deleting it.
What holds the corrected paragraph: nothing. Stated, not invented.
Per triage's binding boundary, no gate was widened to compare prose. Measured rather
than assumed —
scaffold-workspace-consistency.test.tsDOES have a prose reader(
keyProse()/versionsNamed()), so "it only compares the map" needed checking.Replaying that reader verbatim over both rendered files:
Its reader only opens on a comment line whose first token is
allowBuildsoronlyBuiltDependencies, and its accumulator resets before the peer block is reached,so peer-block prose never reaches it. Identical capture before and after this change.
So the accounting is:
init.test.ts(SCIM: 停在 @better-auth/scim rc.1,等正式版再整体迁移 —— rc.2 换掉了整套模型 #3653), passing;scaffold paths —
scaffold-workspace-consistency.test.ts, passing;That is a named, accepted gap, and the card's structural half already rules that
closing it here would defeat a deliberate exemption.
One thing worth checking, since the corrected note now contains the literal string
'@better-auth/scim>better-call'inside a comment while the absence pin asserts thatstring is absent: the pin reads comment-stripped text, so it still measures the
declaration and not this prose.
Changeset
Required, and present —
patchfor@objectstack/cliandcreate-objectstack. Bothpublish the changed bytes:
@objectstack/clicompiles the rendered string intodist/commands/init.js, andcreate-objectstackshipsdist/templates/blank/pnpm-workspace.yaml; both listdistinfiles[]. Notskip-changeset— the file a user's project receives changes.Gates
dispatch-gates.mjsderived 58 families for the delivered change set; all 58 ranand are reconciled with recorded exit codes:
Two of them first returned
exit 3—PREREQUISITE NOT MET, an unbuilt workspace,which is "nothing was measured" and not a finding. Both were re-run green after
building the prerequisites they named, rather than being recorded as passes:
check:i18n-coverage→OK (13 config(s), 621 baselined untranslated string(s), none new),check:dual-build-cjs-loads→104 published require entry point(s) across 67 package(s) load.Also run, all green, all exit codes captured before any pipe:
pnpm --filter @objectstack/cli exec vitest run --project unitpnpm --filter create-objectstack testpnpm --filter @objectstack/cli --filter create-objectstack typecheckpnpm lint(whole repo,eslint . --no-inline-config)pnpm check:nul-bytes+ a direct control-character sweep of both filespackages/cliintegration tier is declared to CI: the diff touches no integration-tierfile, no
bin/entry and no spawn helper. Heavy runs went throughscripts/pm/os-verify-lock.sh; every verdict above is that script's ownVERDICT command-exitline.Acceptance notes
pnpm-workspace.yaml:107-:109carries the same staleness one layer out: it says"measured unchanged on 1.7.2, the version this lockfile now holds", while line
:239pins1.7.3and the installed tree holds1.7.3. Out of scope here (repoinfrastructure, not a scaffold artifact, and nothing a user receives) and not a
defect class that takes a card — noted for whoever next re-measures the better-auth
family pins, which is the traffic that reads those lines.
Clause-②: no
Line added by the dispatching
domain:cliPM seat (#6024) after the delivering agent finished — the machine-readable carrier only. ⛔ No prose of the author's was altered, ⛔ the changeset was not dropped, ⛔ the package was not regraded, ⛔ nothing was pushed or re-run.Clause-②re-derived from the delivered diff and unchanged at no: the rendereddeclarations are byte-identical, no accept set moves and no published surface shape
changes. Comments only.
Generated by Claude Code