test(cli): widen the scaffold-comment pin to both scaffolders - #15151
Merged
Conversation
`init-template-comments-self-contained.test.ts` rendered its population from one source — `TEMPLATES` from `init.js` — so its three assertions held for `os init` only. `create.ts` exports a second, independent template map whose entries render text straight into a scaffolded project, and nothing read it: an edit to a `create` literal citing an ADR, or linking a docs page that later moves, shipped to every `os create` user with every gate green. The population is now DERIVED from both maps, the way `scaffold-manifest-schema.test.ts` derives its own sweep, so a template added to either map is swept the day it is added. `create` has no `configContent`/`srcFiles` split, so every entry of its one `files` map is rendered and serialised exactly the way `Create.run()` does. The three assertions are reused unchanged; only their labels now name the scaffold arm (`init:app`, `create:example`) so a failure says which command ships the text. The `create` vacuity guard checks its in-source LITERALS were reached rather than requiring an `objectstack.config.ts`, which its `plugin` template deliberately does not emit. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
Contributor
📓 Docs Drift CheckNothing in this diff resolved to a documentable surface (no symbol, route or SDK anchor derived from 0 changed package(s)), so this run has no opinion about the docs. What this run could not see
Coarse fallback — 0 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): |
os-trump
marked this pull request as ready for review
September 4, 2026 03:42
os-trump
enabled auto-merge
September 4, 2026 03:42
This was referenced Sep 4, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14823
packages/cli/test/init-template-comments-self-contained.test.tsrendered its population from exactly one source —TEMPLATESfrominit.js— so its three assertions held foros initonly.packages/cli/src/commands/create.tsexports a second, independent template map whose entries render text straight into a scaffolded project, and nothing read it.The population is now derived from both maps, the way
scaffold-manifest-schema.test.tsderives its own sweep, so a template added to either map is swept the day it is added. The three assertions are reused unchanged; only their labels now name the scaffold arm (init:app,create:example) so a failure says which command ships the text.The sequencing fence is released
Triage ruled "Sequence after #14821" because the two-source precedent did not exist on
main. It does now —packages/cli/test/scaffold-manifest-schema.test.tsis present atorigin/maine37456eb03, and this change follows its shape.Derived, not inherited: what the three assertions say about
create's current textThe card's "self-contained today" sentence described #14821's branch. Run against
main's actualcreatetemplate text, all three assertions pass. The widened pin is green on the unmodified tree — 25 tests, over 15 rendered files across 5 scaffold arms (3init+ 2create).So there is nothing for this PR to report as caught, and no follow-up card falls out of a red. Assertion 2 in particular now covers
create:example's protocol-range comment (the one #14821 added), and assertion 3 checks itshttps://objectstack.ai/docs/upgradinglink againstcontent/docs/upgrading.mdx, which is present.What the
createhalf sweepscreatehas noconfigContent/srcFilessplit — onefilesmap keyed by destination path, rendered by calling the entry. Every entry is rendered and serialised exactly the wayCreate.run()does it (a string verbatim, anything else throughJSON.stringify(_, null, 2)). Sweeping the whole map rather than a chosen subset is deliberate: a filter is a place a future file can escape through silently, which is the shape of the defect being closed. This picks up theplugintemplate'ssrc/index.tsandREADME.mdliterals, as the card asked — a pin covering onlyexamplewould recreate the card one template over.The
createvacuity guard checks its in-source literals were reached rather than requiring anobjectstack.config.ts, which itsplugintemplate deliberately does not emit.Proof — red-first, with the arm named
One ablation run, both legs, trap-guarded restore on absolute paths. Both legs mutate source the pin imports relatively (
../src/commands/*.jsresolving topackages/cli/src/commands/*.ts), so vite reads the mutated source directly — there is no dist hop, and the reddening itself is the proof the mutation reached the code under test.The injection is a synthetic monorepo-only reference (
// Rationale: ADR-0999, see #12345) added after the shared anchor line in each file.create.ts779e4fecto723cd4ba, marker count 1create:example/objectstack.config.ts cites nothing that only exists in this monorepoinit.ts26565625to02386b79, marker count 3init:app,init:plugin,init:emptyobjectstack.config.tsThe harness discriminates: the
createinjection reddens exactly onecreatearm and noinitarm; theinitinjection reddens exactly the threeinitarms and nocreatearm. The failure message carries the arm and the marker:Restore proven on both legs by blob-hash equality against the HEAD blob (
779e4fec == 779e4fec,26565625 == 26565625), marker count back to 0, andgit diff HEADempty. Every restore rangit checkout HEAD -- ABSOLUTE_PATH, never a baregit checkout --.Verification
Gate union derived by
node scripts/pm/dispatch-gates.mjs --repo objectstack-ai/objectstackat final HEAD912a2715b5on a clean tree — 35 runnable families (25 by path + 6 by change kind + 6 declared whole-tree, 2 reached both ways).pnpm lint(the repo-wideeslint . --no-inline-config): 5855 files, 0 errors, 0 warnings, exit 0. Not narrowed.pnpm --filter @objectstack/cli run typecheck: exit 0.check:test-typecheckholds at 3 files / 28 errors / 6 pinned signatures — the pre-existing ledger, unmoved; zero diagnostics in the edited file. Coverage proven positively:tsc -p packages/cli/tsconfig.test.json --noEmit --listFilesputs 1794 files in the program and the edited pin is among them (control:scaffold-manifest-schema.test.ts, also present). This matters becausepackages/cli'stsconfig.jsonisinclude: ["src"], so nothing else compilestest/.pnpm --filter @objectstack/cli exec vitest run test/init-template-comments-self-contained.test.ts: 25 passed.Two families NOT MEASURED — reported as NOT MEASURED, neither a pass nor a red:
pnpm check:dual-build-cjs-loads— exit 3, PREREQUISITE NOT MET: it reads built output and twelve packages have nodist/in this worktree, which built only the@objectstack/clidependency closure. Its own text: "This is NOT a pass: nothing was measured."pnpm check:type-check-debt— exit 124, killed by the 300s per-gate timeout. It needs the whole workspace closure built and re-runs tsc per ledger entry. Its relevant half is measured by other means above: the ledger a new test file in this package would move ispackages/cli's, andcheck:test-typecheckholds it unchanged;check:type-check-coverage(the structural half) is green; this diff adds no package and touches no tsconfig.Test scope narrowed, and the narrowing is measured rather than assumed: the diff is one file, it is a test file, and
git grepfinds no importer of it anywhere underpackages/(the single hit is a prose reference in another test's comment). No source changed, so the affected-test set is exactly the file that was run.Changeset
None, and
skip-changesetapplies — measured frompackages/cli's own manifest rather than asserted: itsfilesfield is["dist","README.md","CHANGELOG.md"].test/is not among them, so a test-only diff undertest/publishes nothing and no user-visible change exists to describe.Out of scope, filed not fixed
Per the card's fence, no comment this pin sweeps was edited. One finding came out of the sweep and is filed as #15150: assertion 1's
MONOREPO_ONLYvocabulary has no pattern for a monorepo-relative path, socreate'sREADME.mdlinking../../content/docsis swept and passes. Widening the vocabulary is a different review question from widening the population, and it carries a false-positive design problem the population change did not. The neighbouring instances (workspace:*,extends: '../../tsconfig.json') are already recorded as measured fact 1 of #14824, which remains open as the two-scaffolder decision; this PR is independent of its outcome, exactly as its triage said.🤖 Generated with Claude Code
https://claude.ai/code/session_016yfqQh2dBgPAymYd7xipza
Generated by Claude Code