Skip to content

Commit 1847594

Browse files
claude[bot]claude
andauthored
test(qa): ledger out-of-repo consumers’ specifiers against the published exports maps (#15717)
* wip(qa): inherited draft of the consumer-specifier ledger Committed as-is from a dead session's worktree, before verification, so a container restart cannot lose it. Verified and rewritten in the commits that follow. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * test(qa): ledger the out-of-repo consumer specifiers, held against the exports maps An `exports` map is a PACKAGING contract, and inside this monorepo nothing is sealed: every in-repo consumer reaches any file through a relative import, a vitest alias or a `paths` entry. So the repo could not observe a sealing regression at all, by construction — twice the seal 17.3.0 introduced (#13123) was found after publish, by the consumer, during an upgrade (#13662, #15325). `consumer-specifiers.ledger.json` imports that knowledge from outside: the bare specifiers named out-of-repo consumers import, each with the consumer, a date and the card that ratified it. The suite packs each ledgered package with `pnpm pack`, unpacks it into a throwaway `node_modules` outside the workspace, and resolves every specifier from there with Node's real resolver under both the `require` and `import` conditions — failing with a message that names the specifier AND the consumer it breaks. Option A of #15589 only. Option B (a changeset-gated seal declaration in `check:published-files`) is deliberately not here. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk * test(qa): shrink SEALED_TODAY to empty — #15611 landed and opened both doors The set-equality assertion did exactly what its header said it would. #15611 ratified `./hook-body` and `./package.json` and merged while this branch was in flight; merging main turned the suite red naming the two lines to delete. They are deleted, so the ledger of losses has reached its floor: every specifier a named out-of-repo consumer imports now resolves from a packed tarball. The empty table is KEPT rather than removed. "Every ledgered specifier resolves" is the contract; "the sealed set is exactly empty" is the ratchet — the line an author has to edit, past a ⛔, to make a red green by recording a break instead of repairing it. Also separates two diagnoses the exports map cannot tell apart on its own: a specifier that fails with ERR_PACKAGE_PATH_NOT_EXPORTED is SEALED (the subject of this file), while one failing MODULE_NOT_FOUND is a declared door leading nowhere — the package is unbuilt, or `files` does not ship the path `exports` names. Now that all three doors are open, an unbuilt tree would otherwise have read as "hotcrm is broken". Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_012zGPuVVX3deAx9LdjK8jCk --------- Co-authored-by: Claude <noreply@anthropic.com>
1 parent 76ba5b7 commit 1847594

4 files changed

Lines changed: 497 additions & 2 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
{
2+
"$comment": {
3+
"purpose": [
4+
"The bare specifiers that OUT-OF-REPO consumers import from this repo's published packages,",
5+
"held against each package's `exports` map by test/consumer-specifier-ledger.test.ts.",
6+
"An `exports` map is a PACKAGING contract, and inside this monorepo nothing is sealed: every",
7+
"in-repo consumer reaches any file through a relative import, a vitest alias or a `paths` entry.",
8+
"So the repo cannot observe a sealing regression at all, by construction — twice now a seal was",
9+
"found after publish, by the consumer, during an upgrade (#13662, #15325). This file is the",
10+
"knowledge those two incidents left behind, written down where a PR can be red against it."
11+
],
12+
"owner": "OWNER: the `domain:devx` seat. A ledger with no owner rots — an entry here is a claim about a repository this one cannot see, so it is only as true as the person who keeps it.",
13+
"shrinkOnly": [
14+
"SHRINK-ONLY. An entry LEAVES only with a recorded consumer-side migration, CITED in `note`:",
15+
"the consumer repo has stopped importing the specifier, and there is a link that says so.",
16+
"⛔ Deleting an entry to make a red test green is the defect this file exists to make visible.",
17+
"The remedy for a red is to re-open the subpath, or to migrate the consumer and cite it here."
18+
],
19+
"entryShape": {
20+
"specifier": "the bare specifier as the consumer writes it — never a `dist/` deep path",
21+
"consumer": "repo + the file or harness that imports it",
22+
"since": "ISO date this repo first recorded the consumer's need",
23+
"ratifiedBy": "the card or PR that recorded it",
24+
"note": "optional — and the required place to cite a migration when an entry leaves"
25+
}
26+
},
27+
"entries": [
28+
{
29+
"specifier": "@objectstack/cli/console",
30+
"consumer": "objectstack-ai/cloud — the `objectos-runtime` node server, which mounts the Console SPA through resolveConsolePath / hasConsoleDist / createConsoleStaticPlugin",
31+
"since": "2026-08-31",
32+
"ratifiedBy": "#13662",
33+
"note": "Reached as `@objectstack/cli/dist/utils/console.js` until #13123 sealed the package in 17.3.0. #13662 ratified the subpath rather than re-opening `dist/`, which is the remedy #13123's own body prescribes."
34+
},
35+
{
36+
"specifier": "@objectstack/cli/hook-body",
37+
"consumer": "objectstack-ai/hotcrm — test/helpers/action-sandbox.ts, the hook-body fidelity harness that lowers a body with the platform's own extractor so a test runs what `os build` ships",
38+
"since": "2026-09-04",
39+
"ratifiedBy": "#15325, ratified by PR #15611",
40+
"note": "The same 17.3.0 seal, second consumer: `@objectstack/cli/dist/utils/extract-hook-body.js` went dead at type level (TS2307) and at run time (ERR_PACKAGE_PATH_NOT_EXPORTED) while the file still shipped in the tarball. Only the door was gone. PR #15611 opened `./hook-body` and landed while this ledger was being written — the entry stays, because what is ledgered is the CONSUMER'S NEED, which does not end when the door opens. That is the whole point: an open door with nothing recording who walks through it is what got sealed twice."
41+
},
42+
{
43+
"specifier": "@objectstack/cli/package.json",
44+
"consumer": "objectstack-ai/hotcrm — the same action-sandbox harness, reading the dependency's own manifest to assert the pinned CLI version the lowering came from",
45+
"since": "2026-09-04",
46+
"ratifiedBy": "#15325, ratified by PR #15611",
47+
"note": "Sealed by the same map, measured in #15325 as `require.resolve('@objectstack/cli/package.json') -> ERR_PACKAGE_PATH_NOT_EXPORTED`, and re-opened by PR #15611 as `\"./package.json\": \"./package.json\"`. ⚠️ hotcrm is the only CITED consumer: #15589's dispatch attributes this specifier to cloud as well, and no reading of #13123 / #13662 / #15325 records that, so it is NOT claimed here — an uncited row would make this ledger exactly as trustworthy as the memory it replaces."
48+
}
49+
]
50+
}

packages/qa/downstream-contract/package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@
1313
"@objectstack/spec": "workspace:*"
1414
},
1515
"devDependencies": {
16+
"@objectstack/cli": "workspace:*",
1617
"typescript": "^6.0.3",
1718
"vitest": "^4.1.10"
1819
}

0 commit comments

Comments
 (0)