Skip to content

Commit 78fd6b2

Browse files
os-litantclaude
andcommitted
fix(cli): correct the shipped provenance claim, and record the two new declarations in the CI filter-parity pin
Two review findings from PR #15974. 1. The head reddened `check-ci-filter-parity --self-test`: the pre-#10015 rollback now uncovers 21 globs, not 19. Measured, the delta is exactly the two `content/docs` pages this branch declared for `@objectstack/cli` (troubleshooting.mdx, getting-started/index.mdx) — an origin/main control yields 19 with an empty symmetric difference otherwise. Both are recorded by name, the way the pin's own comment prescribes for #14824's three, rather than the count merely being bumped. 2. The shipped history claim was wrong. `dbb54e12f0c` (2026-05-25) added the bundled template at `^5.3.0`, not `^6.0.0`; `eaff01425b7` (#2907, 2026-07-14) moved it to `^6.0.0` and recorded no reasoning about TypeScript — in that same one-file diff the five `@objectstack/*` ranges move `^6.0.0` to `^14.0.0` while the `typescript` line moves onto the `^6.0.0` they are vacating. So the three-value split is 53 days old, not 102, and the two-value split is 210 (the changeset said 211). Corrected in init.ts, create.ts, the pin's header and the changeset, which now agree. A dated provenance claim written into source comments is exactly the restated fact nothing checks that this card exists to close; shipping a wrong one inside the fix would have been self-refuting. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01D47qPfEWVPmhguWgBZCi5N
1 parent 65bafb4 commit 78fd6b2

5 files changed

Lines changed: 50 additions & 19 deletions

File tree

.changeset/scaffold-emission-policy-one-definition.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
`objectstack init` and `objectstack create` now read one emission policy instead of each restating it.
66

7-
Both commands write a `tsconfig.json` and a set of third-party dependency ranges into a new project. Each had written those in its own words, and the words had come apart. Measured on the tree: the TypeScript range — the value that decides whether a scaffolded project type-checks at all — was written in six places across three scaffolders and had split into three values (`^5.3.0`, `^5.8.0`, `^6.0.0`); the vitest range into two. The two CLI values were written in the same commit and stayed apart for 211 days.
7+
Both commands write a `tsconfig.json` and a set of third-party dependency ranges into a new project. Each had written those in its own words, and the words had come apart. Measured on the tree: the TypeScript range — the value that decides whether a scaffolded project type-checks at all — was written in six places across three scaffolders and had split into three values (`^5.3.0`, `^5.8.0`, `^6.0.0`); the vitest range into two. Dated off `git log -G` as of 2026-09-05: the two CLI values were written in the same commit and stayed apart for 210 days, and the third value is 53 days old — the bundled template landed at `^5.3.0` like the others and was moved to `^6.0.0` later, in a commit that records no reasoning about TypeScript.
88

99
The control for that reading was already in the same file: `SCAFFOLD_PNPM_RANGE` and `renderPnpmWorkspaceYaml()` are imported by the second scaffolder rather than restated, and across the same five emissions, the same window and the same authors, they had not drifted at all. So the policy moved to where those already live — `renderScaffoldTsconfig()` and one `SCAFFOLD_*_RANGE` constant per dependency, in `init.ts`, imported by `create.ts`.
1010

packages/cli/src/commands/create.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,9 @@
6565
* already been paid for twice in this repo: the build-approval block landed in
6666
* one scaffold path and not the other, and one of them shipped the pre-fix shape
6767
* for months; and the TypeScript range a scaffold installs was written in six
68-
* places and split into three values, the split surviving 102 days on the value
69-
* that decides whether the scaffold type-checks at all. The emission policy has
68+
* places and split into three values — the two CLI values 210 days apart, the
69+
* third 53 and recorded nowhere — on the value that decides whether the
70+
* scaffold type-checks at all. The emission policy has
7071
* one home now — see the block above `renderScaffoldPackageJson` in `init.ts`
7172
* for the measurement and for which values survived.
7273
*

packages/cli/src/commands/init.ts

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -234,12 +234,24 @@ export const SCAFFOLD_PNPM_RANGE = '>=10.15';
234234
// os create `^5.8.0` (two write points in create.ts)
235235
// create-objectstack `^6.0.0` (its bundled template's package.json)
236236
//
237-
// The split is not recent and nobody caused it deliberately: `^5.3.0` and
238-
// `^5.8.0` were written in the same commit (2026-02-07), and the third value
239-
// arrived with the bundled template on 2026-05-25 — 102 days of three
240-
// scaffolders answering "which TypeScript does a new ObjectStack project
241-
// install?" three different ways, on the value that decides whether the
242-
// scaffold type-checks at all.
237+
// The split is not recent and nobody caused it deliberately. Read off `git
238+
// log -G` over the three files, as of 2026-09-05:
239+
//
240+
// 338e68d2564 2026-02-07 `^5.3.0` and `^5.8.0` written in the SAME commit
241+
// — 210 days apart and counting
242+
// dbb54e12f0c 2026-05-25 the bundled template lands, also at `^5.3.0`
243+
// — so this is still a TWO-value tree
244+
// eaff01425b7 2026-07-14 that template's line moves `^5.3.0` → `^6.0.0`
245+
// — the third value, 53 days old
246+
//
247+
// ⚠️ And the move that made the third value recorded no reasoning about
248+
// TypeScript at all. #2907's commit message documents the `@objectstack/*`
249+
// version sync and nothing else, and in that same one-file diff the five
250+
// `@objectstack/*` ranges move `^6.0.0` → `^14.0.0` while the `typescript`
251+
// line moves ONTO the `^6.0.0` those lines are vacating. Whatever the intent
252+
// was, no statement of it exists — which is the point: an unrecorded value is
253+
// what a restatement decays into, and it decayed on the value that decides
254+
// whether a new project type-checks at all.
243255
//
244256
// The control for that reading is in this same file: `SCAFFOLD_PNPM_RANGE`
245257
// and `renderPnpmWorkspaceYaml()` are IMPORTED by the other scaffolder rather

packages/cli/test/scaffold-emission-policy.e2e.test.ts

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,12 @@
1111
* whether a scaffolded project type-checks at all — was written in SIX places
1212
* across three scaffolders and had split into THREE values (`^5.3.0` in
1313
* `init.ts`, `^5.8.0` in `create.ts`, `^6.0.0` in the bundled
14-
* `create-objectstack` template). vitest had split into two. The two CLI values
15-
* were written in the SAME commit and stayed apart for 211 days; the third
16-
* arrived 102 days before the measurement.
14+
* `create-objectstack` template). vitest had split into two. Dated off `git
15+
* log -G` as of 2026-09-05: the two CLI values were written in the SAME commit
16+
* (338e68d2564, 2026-02-07) and stayed apart for 210 days; the bundled template
17+
* landed at `^5.3.0` too (dbb54e12f0c, 2026-05-25) and only became the third
18+
* value 53 days ago, when eaff01425b7 moved it to `^6.0.0` without recording
19+
* any reasoning about TypeScript.
1720
*
1821
* The control for that reading sits in the same file as the defect:
1922
* `SCAFFOLD_PNPM_RANGE` and `renderPnpmWorkspaceYaml()` are IMPORTED by the

scripts/check-ci-filter-parity.mjs

Lines changed: 22 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -680,14 +680,20 @@ export async function selfTest() {
680680
// @objectstack/cli: `os create`'s emitted plugin shape is stated nowhere but
681681
// its documentation, so the pin holding the template to it reads all three
682682
// pages, each covered only through the `content/**` root #10015 added.
683-
// Ten plus one plus two plus one plus one plus one plus three: the rollback
684-
// now uncovers nineteen. This pin is judged over the LIVE declaration table on
685-
// purpose: a declaration added under a root the rollback keeps leaves the
686-
// count alone, one under a new root moves it and is recorded here by name.
683+
// Plus, since #15818, the two doc pages THAT card declared for the same
684+
// package: the TypeScript floor both scaffolders emit was chosen because those
685+
// two pages already promise it, so the pin holding the emitted range to that
686+
// promise reads both -- and each is covered only through the same `content/**`
687+
// root, exactly like #14824's three.
688+
// Ten plus one plus two plus one plus one plus one plus three plus two: the
689+
// rollback now uncovers twenty-one. This pin is judged over the LIVE
690+
// declaration table on purpose: a declaration added under a root the rollback
691+
// keeps leaves the count alone, one under a new root moves it and is recorded
692+
// here by name.
687693
const preFix = judge(fixtureWorkflow({ core: real.filters?.core, crosspkg: ['scripts/**'] }), CROSS_PACKAGE_TEST_INPUTS);
688694
assert(
689-
new Set(uncoveredGlobs(preFix)).size === 19,
690-
`rolling \`crosspkg\` back to its pre-#10015 list uncovers the ten it fixed plus #10848's one plus #10178's two plus #12201's one plus #12924's one plus #14561's one plus #14824's three -- got ${new Set(uncoveredGlobs(preFix)).size}`,
695+
new Set(uncoveredGlobs(preFix)).size === 21,
696+
`rolling \`crosspkg\` back to its pre-#10015 list uncovers the ten it fixed plus #10848's one plus #10178's two plus #12201's one plus #12924's one plus #14561's one plus #14824's three plus #15818's two -- got ${new Set(uncoveredGlobs(preFix)).size}`,
691697
);
692698
assert(
693699
uncoveredGlobs(preFix).includes('skills/**'),
@@ -723,6 +729,15 @@ export async function selfTest() {
723729
`-- and #14824 added the \`os create plugin\` scaffold-listing page ${page}, by name`,
724730
);
725731
}
732+
for (const page of [
733+
'content/docs/deployment/troubleshooting.mdx',
734+
'content/docs/getting-started/index.mdx',
735+
]) {
736+
assert(
737+
uncoveredGlobs(preFix).includes(page),
738+
`-- and #15818 added the TypeScript-floor page ${page}, by name`,
739+
);
740+
}
726741

727742
// ── (7) WIRING: the gate and its self-test really run in CI ──────────────
728743
battery('(7) WIRING: the gate and its self-test really run in CI');
@@ -794,7 +809,7 @@ export async function selfTest() {
794809
`same-root-different-file case observed failing and then covered by naming the file, a glob covered by ` +
795810
`\`core\`, one covered only by \`crosspkg\` and one covered by neither judged separately in one table, the ` +
796811
`stale-entry direction, seven refusals over subjects that could not be read, the checked-in ci.yml, the ` +
797-
`pre-#10015 rollback uncovering the ten it fixed plus #10848's one plus #10178's two plus #12201's one plus #12924's one plus #14561's one plus #14824's three, ` +
812+
`pre-#10015 rollback uncovering the ten it fixed plus #10848's one plus #10178's two plus #12201's one plus #12924's one plus #14561's one plus #14824's three plus #15818's two, ` +
798813
`and the CI wiring read out of lint.yml.`,
799814
);
800815
selfTestReachedVerdict = true;

0 commit comments

Comments
 (0)