Skip to content

Commit 60fa01c

Browse files
committed
revert(create-objectstack): keep the template stamp, the sync script and their tests as main has them
The Scaffold E2E gate (repo-built scaffolder, registry-installed @objectstack/* at ^17.0.0) refused a template declaring engines.protocol '^18': a template's range must match the protocol of the packages it installs, which is the package major the sync script and the template-consistency ratchet already enforce. The skew the nightly hit is the in-repo pairing of a published-line scaffold with the workspace runtime during the pre-mode window, so the alignment moves into that test's setup. Restores the four files to their blobs on main and drops the create-objectstack changeset. Claude-Session: https://claude.ai/code/session_01BmsuLyUeuG5CNpZFMH1jzS Co-authored-by: Claude <noreply@anthropic.com>
1 parent bff640d commit 60fa01c

5 files changed

Lines changed: 36 additions & 279 deletions

File tree

‎.changeset/22622-scaffold-engines-protocol-from-protocol-version.md‎

Lines changed: 0 additions & 14 deletions
This file was deleted.

‎packages/create-objectstack/src/template-consistency.test.ts‎

Lines changed: 4 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@ import { copyDir, TEMPLATE_FILE_ALIASES } from './template-copy.js';
1616
import { TEMPLATES } from './template-registry.js';
1717
import { gitFreeEnv } from '../../../scripts/git-env.mjs';
1818
import { SKILLS_CATALOG, SKILLS_INSTALL_COMMAND } from './skills-install.js';
19-
import { PROTOCOL_MAJOR, PROTOCOL_VERSION } from '@objectstack/spec/kernel';
2019

2120
const pkgRoot = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..');
2221
const repoRoot = path.resolve(pkgRoot, '..', '..');
@@ -192,17 +191,7 @@ describe('bundled template declared version surfaces', () => {
192191
// `objectstack.manifest.json` — the two were conflated in this suite's own
193192
// naming and in the sync script's log strings, and that conflation is part
194193
// of how the sibling key below went unwatched for eleven majors.
195-
//
196-
// NOTE the value: the PROTOCOL major, judged against `PROTOCOL_VERSION` —
197-
// the constant the runtime's ADR-0087 D1 handshake compares a scaffolded
198-
// project's range to — and NOT against this package's own major. The two
199-
// differ for the whole pre-mode window in which the protocol moves ahead of
200-
// the version pass (packages at 17.x beside protocol 18): judged against the
201-
// package major, a template the runtime refuses at boot stayed green here.
202-
// `@objectstack/spec/kernel` resolves to the spec's SOURCE through this
203-
// package's vitest alias, so the verdict needs no build — it runs on the
204-
// release path's post-version tree, where nothing has been built.
205-
it('objectstack.config.ts stamps an engines.protocol that PROTOCOL_VERSION satisfies (ADR-0087 D1)', () => {
194+
it("objectstack.config.ts stamps engines.protocol at the scaffolder's major (ADR-0087 D1)", () => {
206195
const config = readTemplateFile('objectstack.config.ts');
207196
const match = /engines:\s*\{\s*protocol:\s*'\^(\d+)'\s*\}/.exec(config);
208197
expect(
@@ -211,10 +200,9 @@ describe('bundled template declared version surfaces', () => {
211200
).not.toBeNull();
212201
expect(
213202
Number(match![1]),
214-
`${template} stamps engines.protocol '^${match![1]}', which PROTOCOL_VERSION ${PROTOCOL_VERSION} does not ` +
215-
'satisfy: every project it scaffolds is refused at the protocol handshake by the runtime it ships ' +
216-
'with. Run `node scripts/sync-template-versions.mjs` — it stamps this key from PROTOCOL_VERSION\'s major.',
217-
).toBe(PROTOCOL_MAJOR);
203+
`${template} stamps engines.protocol '^${match![1]}' but create-objectstack is v${ownMajor} — ` +
204+
'scripts/sync-template-versions.mjs re-stamps this at version time; keep them in lockstep',
205+
).toBe(ownMajor);
218206
});
219207

220208
// The key #9264 is about. Required by TemplateManifestSchema, read by the

‎packages/create-objectstack/src/template-version-stamps.test.ts‎

Lines changed: 4 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,7 @@
2525
// re-found the day a second template ships.
2626
//
2727
// The same fixture is deliberately built STALE (pinning ^17 while its
28-
// scaffolder reads 42.0.0 and its PROTOCOL_VERSION reads 43.0.0 — two majors,
29-
// because `engines.protocol` is stamped from the protocol constant and every
30-
// other surface from the package, and with the two equal a stamp read from the
31-
// wrong source would pass). That makes the import-safety assertion non-vacuous
28+
// scaffolder reads 42.0.0). That makes the import-safety assertion non-vacuous
3229
// in the one way that matters: an unguarded module imported against a stale
3330
// tree REWRITES it, so "the files are byte-identical after import" is evidence
3431
// only when there was something for a rewrite to do. Byte-identity over an
@@ -65,7 +62,6 @@ type SyncModule = {
6562
findTemplateDirs: (templateRoot?: string) => string[];
6663
stampedPaths: (options?: { root?: string }) => string[];
6764
loadScaffolderVersion: (file?: string) => { version: string; major: string; range: string };
68-
loadProtocolMajor: (file?: string) => { source: string; protocolMajor: string };
6965
};
7066

7167
const loadSync = async (file = SYNC_SCRIPT): Promise<SyncModule> =>
@@ -79,11 +75,6 @@ let fixtureScript: string;
7975

8076
/** Deliberately not the live version, so a stamp that ran is unmistakable. */
8177
const FIXTURE_VERSION = '42.0.0';
82-
/**
83-
* The fixture's PROTOCOL major — one ahead of its package major, the shape the
84-
* pre-mode window leaves in the real tree. `engines.protocol` must move to THIS.
85-
*/
86-
const FIXTURE_PROTOCOL_MAJOR = '43';
8778
/** Deliberately stale: every fixture surface pins this and must move to 42. */
8879
const STALE_MAJOR = '17';
8980

@@ -149,11 +140,6 @@ beforeAll(() => {
149140
path.join(fixture, 'packages', 'create-objectstack', 'package.json'),
150141
JSON.stringify({ name: 'create-objectstack', version: FIXTURE_VERSION }, null, 2) + '\n',
151142
);
152-
// The protocol major's one source, in the shape the real constant spells it.
153-
writeFixtureFile(
154-
path.join(fixture, 'packages', 'spec', 'src', 'kernel', 'protocol-version.ts'),
155-
`export const PROTOCOL_VERSION = '${FIXTURE_PROTOCOL_MAJOR}.0.0';\n`,
156-
);
157143

158144
for (const template of FIXTURE_TEMPLATES) {
159145
const dir = fixtureTemplateDir(template);
@@ -229,7 +215,6 @@ describe('sync-template-versions.mjs is import-safe', () => {
229215
expect(typeof sync.stampedPaths).toBe('function');
230216
expect(typeof sync.findTemplateDirs).toBe('function');
231217
expect(typeof sync.loadScaffolderVersion).toBe('function');
232-
expect(typeof sync.loadProtocolMajor).toBe('function');
233218
expect(Array.isArray(sync.TEXT_STAMPS)).toBe(true);
234219
expect(sync.TEXT_STAMPS.length).toBeGreaterThan(0);
235220
expect(sync.TEMPLATE_DIR).toBe('packages/create-objectstack/src/templates');
@@ -264,10 +249,9 @@ describe('the entry-point guard leaves the CLI path working', () => {
264249
'a non-@objectstack dependency is never touched',
265250
).toBe('^6.0.0');
266251

267-
expect(
268-
fs.readFileSync(path.join(dir, 'objectstack.config.ts'), 'utf8'),
269-
`${template}/objectstack.config.ts engines.protocol moves to the PROTOCOL major, not the package major`,
270-
).toContain(`engines: { protocol: '^${FIXTURE_PROTOCOL_MAJOR}' }`);
252+
expect(fs.readFileSync(path.join(dir, 'objectstack.config.ts'), 'utf8')).toContain(
253+
"engines: { protocol: '^42' }",
254+
);
271255

272256
const manifest = fs.readFileSync(path.join(dir, 'objectstack.manifest.json'), 'utf8');
273257
expect(manifest).toContain('"specVersion": "^42.0.0"');

‎packages/create-objectstack/src/templates/blank/objectstack.config.ts‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ export default defineStack({
3636
// match the ObjectStack version you installed — change it when you
3737
// deliberately move to a new protocol major, not to silence a mismatch.
3838
// Guide: https://objectstack.ai/docs/upgrading
39-
engines: { protocol: '^18' },
39+
engines: { protocol: '^17' },
4040
},
4141

4242
// `automation` backs flow execution and materializes any declarative

0 commit comments

Comments
 (0)