fix(spec): register sys_license as a cloud-provided platform object - #14533
Conversation
`sys_license` is declared by `@objectstack/service-tenant` in the cloud
repository (`packages/service-tenant/src/objects/sys-license.object.ts`) and
referenced across 24 files there, but it was absent from
`CLOUD_PROVIDED_OBJECT_NAMES`, so `isPlatformProvidedObjectName('sys_license')`
returned `false` and every consumer of the registry treated a real
cross-reference as a probable typo.
This repository meanwhile cites the name repo-wide as the canonical
`tenancy.enabled: false` fixture — the driver tenant-scope suites, the
platform-global note on `ObjectSchema`, ADR-0066's worked example — which is
the stale-registry failure the module's own maintenance contract describes:
consumers trust the curated list, so a missing entry is worse than the prefix
heuristic it replaced.
The conformance test's cloud loop already covers the new entry generically; a
named positive control is added beside the existing `sys_user` /
`sys_approval_request` predicate pins so removing it fails one readable
assertion.
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
📓 Docs Drift CheckThis PR changes 1 package(s): ⛔ 1 release-owned page(s) name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 128 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 975ff9b27af5f5a55760b849d7f6e2e9ed242fa5 && git checkout 975ff9b27af5f5a55760b849d7f6e2e9ed242fa5
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin b339a38377036095c180e010921b04331d5e5bd2 e9602694896e5374c7eb0da48cede80a8b616d04 && git checkout -B drift-repro b339a38377036095c180e010921b04331d5e5bd2 && git merge --no-ff e9602694896e5374c7eb0da48cede80a8b616d04
node scripts/docs-audit/affected-docs.mjs --json b339a38377036095c180e010921b04331d5e5bd2
|
Fixes #13842
sys_licensejoinsCLOUD_PROVIDED_OBJECT_NAMESinpackages/spec/src/system/constants/platform-object-names.ts, soisPlatformProvidedObjectName('sys_license')now returnstrueand acloud-targeted stack that references the object resolves instead of being
warned about a probable typo.
Premise re-checked on
origin/main(branch basee5812fa43)Route 1 — the registry is missing a real cloud-provided object — holds. Route 2
(re-pointing driver doc comments and fixtures at a different object) is not
taken: every citation names an object that genuinely exists.
git grep -n "sys_license" origin/main -- packages/spec/src/system/constants/platform-object-names.tsreturns nothing (exit 1).
git grep -n "name: 'sys_license'" origin/main -- '*.object.ts'returnsnothing (exit 1), which is why the conformance scan never flagged the gap.
origin/maintoday:packages/spec/src/data/object.zod.ts:695— the platform-global note onObjectSchema(sys_licensekeeps an optional owner FK)packages/spec/src/data/object.test.ts:1896,:1992,:2088,:2100—the
isTenancyDisabledworked examplepackages/drivers/driver-sql/src/sql-driver.ts:4264,:9182— doc commentspackages/drivers/driver-sql/src/sql-driver-tenant-scope.test.ts:308-:385packages/drivers/driver-sqlite-wasm/src/sqlite-wasm-driver-tenant-scope.test.ts:211-:277packages/drivers/driver-memory/src/memory-tenancy-guard.test.ts:117,:221packages/drivers/driver-mongodb/src/mongodb-tenancy-guard.test.ts:134packages/lint/src/validate-capability-references.test.ts:12,:43,:49packages/cli/src/commands/migrate/duplicates.probe-sql.test.ts:127,:161docs/adr/0066-unified-authorization-model.md:68— the worked example theobject was designed against
The cloud declaration, re-cited from the checkout rather than taken on trust
git -C ../cloud grep -n "name: 'sys_license'" origin/mainon cloudorigin/main3856fbf7cf7ca27f979df5232b9639da4058bf42:24 files in that repository reference the name. It ships from
@objectstack/service-tenant— the same package that provides the five namesalready on the list, so the positive control (
sys_package_installation) hitsthe same tree.
The change
One name added to
CLOUD_PROVIDED_OBJECT_NAMES, in the neighbours' alphabeticalorder and their provenance style (the group docstring carries the provenance;
the entries themselves are bare). Nothing else in the module moves.
This is precisely the failure the module's own maintenance contract describes:
Pins
packages/spec/src/system/constants/platform-object-names.test.tsalready loopsover
CLOUD_PROVIDED_OBJECT_NAMESgenerically, so the new entry is covered themoment it lands (it is asserted platform-provided, and asserted not declared
in this repo). No count or enumeration pin needed updating — there is none.
Added beside the existing
sys_user/sys_approval_requestpredicate pins: anamed positive control asserting
sys_licenseresolves as cloud-provided, soremoving it fails one readable assertion rather than nothing.
No consumer behaviour moves for any name already on the list. The two consumers
that key on the registry both abstain here:
ObjectQLEngine.resolvePrimaryDatasourceintersects the list with what thedeployment actually registered (an OSS runtime registers no
sys_license), andvalidate-object-referencesgains one more did-you-mean candidate for namesthat are already findings.
Gates, on the final head
e96026948Derived mechanically, no paths passed:
node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack(53 commands; the script reads the change set from the merge base itself), plus
check:nul-bytes= 54. Every exit code captured by redirect before any pipe.Working tree still clean afterwards, so nothing regenerated anything, and the
whole union ran on this exact tree.
49 of 54 exit 0. Including
check:api-surface,check:authorable-surface,check:export-origins,check:docs,check:liveness,check:generated("All 15 generated artifacts are up to date"),
check:type-check-coverage,check:cross-package-test-inputs,check:merge-driver,check:published-files,check:test-source-alias,check:nul-bytes.Tests and typecheck:
pnpm --filter @objectstack/spec typecheck— exit 0. Coverage proven ratherthan assumed: the base
tsconfig.jsoncompiles 0 of the edited test file, thesibling
tsconfig.test.json(whichtypecheckreaches viacheck:test-typecheck) compiles 1 — checked withtsc --listFiles.vitest run --maxWorkers=2 src/system/constants/platform-object-names.test.ts— exit 0, 8/8.
command at ~10 minutes, so the suite was sharded rather than narrowed:
--shard=1/2226 files / 6172 tests;--shard=3/4113 / 2705;--shard=4/4minus its one slow file 112 / 3324; that file
(
scripts/publish-smoke-port-collision.test.ts, a port-collision smoke testthis diff cannot reach) run alone, 8/8 in 6.5s. Union = all 452 files, 12209
tests, exit 0 throughout.
5 of 54 NOT MEASURED — none is a red, and all five have one cause: only
packages/specand its dependency closure were built locally, not the full67-package workspace. Each gate says so in its own words and names
pnpm buildas the fix; CI builds the workspace, so all five are measured there.
check-dev-prereqsexit 1 — "The workspace is not built ... 1 unmetprecondition, not a list of problems."
check:dual-build-cjs-loadsexit 3 — "PREREQUISITE NOT MET ... This is NOT apass: nothing was measured." (Its 93-case self-test does pass.)
check:type-check-debtexit 3 — refuses to re-measure through unbuiltdependencies: "NOT a pass and NOT a finding". Its sibling
check:type-check-coverageis green.@objectstack/lint check:doc-formula-expressionsexit 3 — needs@objectstack/formulacompiled.check-test-completenessexit 3 — its own text: the derived family names itwith no argument, "so the local reading for this gate is NOT MEASURED".
Note on the shared verify lock: builds and the test suite were run under
scripts/pm/os-verify-lock.sh. The remaining staticcheck:*audits were rununlocked — that lock's own
--statustext states it does not cover gatescripts — after two acquisitions returned
exit 99(queue-timeout) against along holder. No coverage was narrowed by that choice.
Declarations
Clause-②: no— a registry constant gains a name that already exists; noaccept-set change on any schema, no authorable surface moves.
Changeset:
@objectstack/specpatch (a published constant gains a name).Agent session: https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
🤖 Generated with Claude Code
https://claude.ai/code/session_01GDA48PuRFrHyRfdkBz8m21
Generated by Claude Code