Commit 7607076
fix(spec): register sys_environment_credential in CLOUD_PROVIDED_OBJECT_NAMES (#18851)
Fixes #18309
Clause-②: yes (widening)
Scoped to **item 1 of the card only**. Item 2 — grading
`sys_tenant_database` under
enforce-or-remove — is decision-shaped and is not touched here;
`packages/spec/src/cloud/tenant.zod.ts` is unmodified.
## What changed
`CLOUD_PROVIDED_OBJECT_NAMES` gains one member,
`sys_environment_credential`, plus a
named pin test and a `minor` changeset. Three files, 69 insertions,
nothing removed and
no other member moved — the same shape as PR #17214, which added
`sys_package_version`.
## The cloud half is the filer's reading, not a measurement taken here
The registration chain — `objects/sys-environment-credential.object.ts`
exported through
`objects/index.ts`, listed in `tenantObjects` in `manifest.ts`, spread
into
`manifestService.register({ objects })` by `tenant-plugin.ts` — was read
**in the cloud
repository at `cb8ee7ff60`** and is carried here on its filer's name. It
is not
re-checkable from this repo, which is what the list's own header means
by "they cannot be
conformance-tested from this repo". Nothing in this PR re-took it, and
the pin comment and
changeset both say so in as many words.
What IS measured here is the objectstack half: the contents of the list,
the predicate
built from it, and the ladder verdict that consumes it.
## Re-taken readings
**Reference census, taken on this branch at `d18f7d78a8`** (the card's
own count was taken
2026-09-15 and is unchanged):
| query | files |
|---|---|
| `sys_environment_credential` in `*.object.ts` | **0** |
| `sys_environment_credential` anywhere tracked | 11 (2 ADRs, 7
`CHANGELOG.md` rename records, and this PR's two spec files) |
| `sys_package_version` anywhere tracked (positive control) | 34 |
| `sys_definitely_not_real` anywhere tracked (negative control) | 0 |
So **no shipped `*.object.ts` references the name**, the card's
`priority:p3` grading
stands on its stated reason, and nothing here promotes it.
**Does the existing pin test redden?** No.
`platform-object-names.test.ts` pins the list
neither by length nor by full set: it loops
`CLOUD_PROVIDED_OBJECT_NAMES` asserting each
member resolves and is not declared in this repo — both of which a new
member satisfies on
arrival — and then pins `sys_license` and the `sys_package*` family **by
name**. A member
added without a named pin is therefore invisible to the suite, which is
exactly the gap
the file's own comments say the by-name pins exist to close, so this
change adds one in
the same style. Suite went 9 tests to 10, green.
## Controls
Both legs rebuild `packages/spec` and prove the state reached `dist/`
with
`scripts/ablation-dist-preflight.mjs` before the reading is allowed to
mean anything —
`@objectstack/lint` resolves `@objectstack/spec/system` through
`exports`, so a verdict
taken without rebuilding is a fact about the previous build. Probe: an
object declaration
whose lookup field targets the name, through `validateObjectReferences`.
| name | BEFORE (member ablated out of `dist`) | AFTER (`d18f7d78a8`) |
|---|---|---|
| **`sys_environment_credential`** (LIT) | `predicate=false`, **1
finding** — `warning:object-reference-unregistered-platform` |
`predicate=true`, **0 findings** |
| `sys_app`, `sys_environment`, `sys_environment_member`, `sys_license`,
`sys_package`, `sys_package_installation`, `sys_package_version`
(DARK-A) | `predicate=true`, 0 findings — each | `predicate=true`, 0
findings — each |
| `sys_definitely_not_real` (DARK-B) | `predicate=false`, 1 finding |
`predicate=false`, 1 finding |
| `sys_approval_process` (instrument control) | `predicate=false`, 1
finding | `predicate=false`, 1 finding |
| `sys_user` / `crm_deployment` (instrument controls) | 0 findings | 0
findings |
The lit control is non-zero and every dark reading is unchanged.
Preflight confirmed the
marker absent from all 216 built files on the ablated leg and present in
8 on the restored
leg; the restore was proven by whole-tree `git status --porcelain` (0
lines) and by
`git hash-object` matching the HEAD blob `c10c88f1e0…`. No probe file
was left in the repo.
**One correction to the card's wording.** The card says "the first
shipped reference to it
would be refused". The measured verdict is a **`warning`**, not a
refusal: rung ④ of
`validate-object-references`'s severity ladder is advisory by design,
because a
third-party package may legitimately provide a platform-prefixed name.
`defineStack`'s own
hard throw uses a prefix test (`isPlatformObjectName` in
`stack.zod.ts`), which accepted
the name both before and after this change. So the flip is real and the
direction the card
describes is right, but what flipped is a diagnostic, not a rejection —
the name was never
hard-refused, and this PR does not manufacture a refusal to make the
stronger reading true.
## The two `merge=os-regen` artefacts do not move
`packages/spec/api-surface/system.json` and
`packages/spec/export-origins/system.json` were
pre-declared on the claim as regeneration targets. Measured: they record
export **names and
origins**, not values, so the list's contents are invisible to them —
`git grep -c sys_package` over both directories returns 0 hits. The
repo's own generator
wrapper confirms it: `pnpm --filter @objectstack/spec check:generated`
reports **all 15
generated artifacts up to date**, `check:api-surface` and
`check:export-origins` among
them, so `--fix` had nothing to regenerate. Neither file is hand-edited
and neither is in
this diff. PR #17214 touched the same three-file set for the same
reason.
## Verification
Run at `d18f7d78a8` unless noted.
- `pnpm --filter @objectstack/spec build` — green (through the shared
verify lock)
- `pnpm --filter @objectstack/spec test` — **487 files / 14055 tests
passed**
- `pnpm --filter @objectstack/spec typecheck` — green (incl.
`check:scripts-typecheck`, `check:test-typecheck`)
- `pnpm --filter @objectstack/lint test` — **104 files / 3879 passed, 5
skipped**, after building lint's dependency closure. The first run
showed 41 files failing to collect on `@objectstack/formula` /
`@objectstack/sdui-parser` having no `dist/`; that is unbuilt-closure
state, not this diff, and it cleared on `pnpm --filter
'@objectstack/lint^...' build`.
- `pnpm --filter @objectstack/spec check:generated` — all 15 up to date
- Gate families: `check:nul-bytes`, `check:merge-driver`,
`check:cross-package-test-inputs`, `check:test-source-alias`,
`check:published-files`, `check:dts-closure`,
`check:type-check-coverage`, `check:entry-nameability`,
`check:browser-reachable-entries`, `check:dual-source-exports`,
`check:exported-any`, `check-empty-changeset`,
`check-adr-0087-registration`, `check-platform-object-tenancy-census`,
`check-spec-docblock-symbol-anchors`, `check-comment-mask-adoption`,
`check-comment-mask-corpus`, `check-keyed-text-bounds` — all exit 0.
- eslint, narrowed and declared: `eslint --no-inline-config` over the
diff's two lintable files, **0 errors / 0 warnings**, file count read
from `--format json` (2 — the third changed path is a `.changeset/*.md`,
which no `files` entry in `eslint.config.mjs` matches). The narrowing is
safe because this config runs **no type-aware linting** —
`eslint.config.mjs:328` records "no `parserOptions.project`, no typed
`@typescript-eslint` rules", and there is no `projectService` anywhere
in it — so each file's verdict is a function of that file alone and a
two-file diff cannot move an untouched file's verdict. The repo-wide run
remains CI's.
NOT MEASURED, with reasons:
- `check:type-check-debt` exited **3**, which the script itself prints
as `PREREQUISITE NOT MET` — it needs the whole-repo build closure that
`lint.yml` builds before the step. Its own text: "This is NOT a pass and
NOT a finding: nothing was measured." Recorded as unmeasured, not as
red.
- `check-changeset-no-major.mjs` ran green but reports its **level axis
NOT APPLICABLE** locally: it reads the clause-② declaration from a
`pull_request` payload, which a local run has not got. The axis gets its
input once this PR exists.
- `dispatch-gates --ran` reconciles 27 of 81 derived families run
locally. The remainder are checker `--self-test` invocations and
repo-wide scans that CI owns.
## Acceptance notes
Observations from the surrounding code, filed nowhere and deliberately
not fixed here:
- `PLATFORM_OBJECTS_BY_PACKAGE` carries a per-package conformance scan
that reddens on
drift; `CLOUD_PROVIDED_OBJECT_NAMES` has no such half by construction,
so every member
it holds rests on a cross-repo reading with no local ratchet behind it.
That is the
documented design, not a defect, and it is why this PR adds a by-name
pin rather than
claiming conformance. Noted, not filed — no PR or person is queued
against this file.
- ADR-0007's inventory table lists `sys_environment_credential` as
existing while the
registry that decides whether a reference resolves said nothing
registers it. The two
now agree. Noted, not filed: an ADR stating a true fact about the cloud
runtime is not a
contract violation, and nothing in this repo consumed the ADR table as
metadata.
## Ownership
`needs:contract-review` is the PM seat's to place and the at-tier review
is the PM seat's
to run; this PR removes no label and flips no state. Left as a draft.
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent f2044ef commit 7607076
3 files changed
Lines changed: 69 additions & 0 deletions
File tree
- .changeset
- packages/spec/src/system/constants
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
Lines changed: 28 additions & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
184 | 184 | | |
185 | 185 | | |
186 | 186 | | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
| 208 | + | |
| 209 | + | |
| 210 | + | |
| 211 | + | |
| 212 | + | |
| 213 | + | |
| 214 | + | |
187 | 215 | | |
Lines changed: 1 addition & 0 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
149 | 149 | | |
150 | 150 | | |
151 | 151 | | |
| 152 | + | |
152 | 153 | | |
153 | 154 | | |
154 | 155 | | |
| |||
0 commit comments