Repository navigation
spec/kernel: carve the package-registry persistence out of marketplace into an always-on core capability - #18694
Conversation
…e` into an always-on core capability `sys_packages` and the boot hydration that replays it are the persistence half of what the `marketplace` token named; a package is a first-class persistent entity whether or not the deployment has a store. Give that half its own vocabulary token, its own open-edition provider row, and a place on the always-on slate; leave `marketplace` naming only the optional catalogue / browsing half. The slate's ordering contract moves with it: `package-registry` binds into nothing on the slate, so it joins the tail, and the falsifiability control that enumerates the tail literally is updated from the same rule rather than around it. Claude-Session: https://claude.ai/code/session_01JbZnqu8bt6YqfJsr9vaFb3 Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift CheckThis PR changes 1 package(s): 1 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:
⛔ 1 release-owned page(s) also name something this change touched. These are read-only:
What this run could not see
Coarse fallback — 136 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 55a4cba1d045fef9c4b609e9fbf0d53ade48e224 && git checkout 55a4cba1d045fef9c4b609e9fbf0d53ade48e224
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 1bc22b3dcddc8a30b4826da8625e7787d5518a8f 37a112e0f2a32aed323add69f32dda16b55b1899 && git checkout -B drift-repro 1bc22b3dcddc8a30b4826da8625e7787d5518a8f && git merge --no-ff 37a112e0f2a32aed323add69f32dda16b55b1899
node scripts/docs-audit/affected-docs.mjs --json 1bc22b3dcddc8a30b4826da8625e7787d5518a8f
|
Contract reviewServed-tier: 92/92 Isolated reviewer. Inputs: card #18053 body, ruling comment 5650202813 on #17676, PR #18694 body / diff / commit / check runs, and the tree at the head above (detached worktree; ① Derived judgmentsDiff = 4 files ( Row 1 —
Row 2 — Row 3 — Row 4 — spec pin: literal control updated; new describe with 5 cases asserting both halves. RIGHT. The near-miss case is an absence assertion (passes for any rewrite) but is supplementary, not load-bearing. Row 5 — CLI pin: new surface case on Public surface touched without an edit (measured):
Measurements at head (mine, not the PR's): spec pins ② Semver levelChangeset ③ Boundary flagsPR question 1 — does the split move the length or the boundary derivation? Answered and verified: +1 on each constant; PR question 2 — what does the CLI vocabulary pin actually follow? Verified: set relations and package equality in the serve-to-spec direction; no order enumerated; the only case a carve-out could redden is the 1:1 pin. Declared gap — no Escalated — the Ruling item 4 — is an ADR note owed? I agree with the PR: not by this diff. Measured: ADRs naming Cloud per-tenant runtime — NOT MEASURED (out of tree). If its loader keys the spec slate through the spec provider rows, every tenant mounts Published skill staleness (from ①). Disposition: fix the two numerals and add one sentence for the new token in CI at this head: 39 check runs, all completed; every non-skipped conclusion is success (six Test Core shards, four Type Check jobs, Lint & Repo Gates, Check Changeset on both runs, Governed Surface Queue Guard, Temporal Conformance, five Dogfood jobs); the skipped ones are path-filtered (Packed-tarball smoke, Build Docs, Console Pin Gate, one Auto Label, one Check PR Size). No red. Implemented-by: VERDICT: PASS Generated by Claude Code |
|
契约复核 provenance —— PASS 已逐字采纳,双载体同笔已剥。 记录与采纳
⇒ 本席对它三条 boundary 输出的处置① flag:发布的 ⇒ 不在本 PR 改,另立卡 #18705。 判据不是省事,是路线代价:那是手写的 ② escalated: ③ 它与 dev 对 item 4(ADR)的判断一致:本 diff 不欠 ADR 注记(0 条 ADR 点名该 slate 常量;ADR-0087 对 NOT MEASURED,原样留着复核自标:云侧的 per-tenant 运行时行为(树外);被污染的那次 bare-marker dist 探针(按 delta 报);以及「是否已有引擎那半的卡」—— 代理够不到 Generated by Claude Code |
…its count in objectstack-platform (objectstack-ai#18839) Fixes objectstack-ai#18705 Clause-②: no The `requires:` section of the published `skills/objectstack-platform/SKILL.md` copied two numbers out of the platform capability vocabulary into prose — 「The other eight tokens in the vocabulary …」 and 「The authoritative list of all 28 is `PLATFORM_CAPABILITY_TOKENS`」 — and no gate reads either number against `packages/spec/src/kernel/platform-capabilities.ts`. PR objectstack-ai#18694 (objectstack-ai#18053) took the vocabulary 28 → 29 when it landed at 2026-09-17T16:10Z, so on `origin/main` both sentences were already false when this branch was cut. This PR is the card's option A in the shape of the objectstack-ai#16853 precedent (`a256f18962`, PR objectstack-ai#17259 「cite the platform-tool registry instead of restating it」): the two counts become citations, and nothing is left in those two sentences that a registry change can falsify. No other sentence in the file moves. The `package-registry` runtime half is objectstack-ai#17676's and is not addressed here; objectstack-ai#16767 (the example block's TypeScript range, same file) remains open and is not folded. ## 维护者速读(草稿) **改了什么** — 发布给客户项目的 `skills/objectstack-platform/SKILL.md` 里,`requires:` 一节原来写死了两个数字(「the other eight tokens」「the authoritative list of all 28」)。本 PR 把这两句改成引用常量 `PLATFORM_CAPABILITY_TOKENS`,不再写数字;其余 1221 行一字未动(diff 是 3 行增 / 3 行删)。 **为什么改** — 这两个数字是从 `packages/spec` 的能力词汇表抄来的,没有任何门禁核对它们。objectstack-ai#18694 落地后词汇表已是 29 个 token(新增 `package-registry`),这两句在 `main` 上已经是假话,而客户项目里的 AI 每次加载这份 skill 都会读到。同一类缺陷在 `skills/objectstack-ai/SKILL.md` 上已由 objectstack-ai#16853 / PR objectstack-ai#17259 用同样的办法修过一次:引用注册表,不复述它。 **风险与代价(含回滚)** — 纯文档改动,不发布代码,不改任何运行时行为;skill 的 token 计数 12980 → 12975,上限 12984 不动。回滚就是 revert 这一个提交。留下一处未动:同一节 :440 的「all 20 of its entries」仍是一个抄写的计数(今天为真,objectstack-ai#17676 引擎侧落地时会变假),按派发令本卡不动其它句子——要不要顺手折进来由席位定,见下方 Acceptance notes。 **席位意见** — **你要做的** — 这是受管面(`skills/**`),按 Prime Directive objectstack-ai#14 需要你亲自确认并合并;PR 保持 draft。读一眼 diff 里那两句(6 行),没有别的。 ## Re-derived readings All on `origin/main` `5941246b70` (the branch point); none copied from the card. | reading | value | how | |:--|:--|:--| | `PLATFORM_CAPABILITY_TOKENS` size | **29** | parsed the frozen array literal in `packages/spec/src/kernel/platform-capabilities.ts`; `PLATFORM_CAPABILITY_PROVIDERS` has the same 29 keys | | `Serve.CAPABILITY_PROVIDERS` size (the map the section describes) | **20** | top-level keys of the static at `packages/cli/src/commands/serve.ts` :1863–:2009; the skill's :442 table names the same 20 as a set | | vocabulary tokens NOT in that map | **9** | `ai` `ai-studio` `i18n` `ui` `auth` `hierarchy-security` `ai-seat` `governance` — the eight the section lists — plus `package-registry` | | 「all 28」 on the tip | **false** (29) | | | 「the other eight」 on the tip | **false** (nine) | | | 「all 20 of its entries」 at :440 (same section; not named by the card) | **true** today (20 = 20) | | **Gate reading — which gate surfaces read the constant name — with controls (`git grep -l` at `5941246b70`):** - `scripts/` · `packages/*/scripts/` · `.github/` for `PLATFORM_CAPABILITY_TOKENS`: **0 files** (exit 1) - lit control, the same grep across the whole tree: **18 files** (exit 0; the card read 17 before objectstack-ai#18694 landed — `.changeset/18053-package-registry-capability.md` and `content/docs/releases/v16.mdx` are the new hits) - dark control, a forged constant name across the whole tree: **0 files** (exit 1) ## The two sentences, before / after :452–:453 before: ``` The other eight tokens in the vocabulary are **not** in that map and do not resolve through it: ``` after: ``` The tokens in `PLATFORM_CAPABILITY_TOKENS` not in that map do not resolve through it: ``` :463 before: ``` The authoritative list of all 28 is `PLATFORM_CAPABILITY_TOKENS` ``` after: ``` The authoritative list is `PLATFORM_CAPABILITY_TOKENS` ``` The diff is 3 insertions / 3 deletions in one file. ## The enumeration under :452, re-read against the constant at the tip Every name the two bullets carry — tier-gated `ai`, `ai-studio`, `i18n`, `ui`, `auth` (= the five keys of `Serve.CAPABILITY_TO_TIER` at :1577–:1585, verbatim); enterprise / cloud `hierarchy-security`, `ai-seat`, `governance` — is in `PLATFORM_CAPABILITY_TOKENS` at the tip, and none of the eight is a `Serve.CAPABILITY_PROVIDERS` key. So the list is kept as the list it is: no name dropped, no name added. The ninth not-in-map token, `package-registry`, is in the vocabulary and in `PLATFORM_CAPABILITY_PROVIDERS` (`@objectstack/service-package`, open edition) but has no `Serve.CAPABILITY_PROVIDERS` row yet — the constant's own comment says it is inert under `objectstack serve` until objectstack-ai#17676's runtime half lands. Per the card this PR documents no new token; the Acceptance notes say who holds that. The `marketplace` provider line (:444, `@objectstack/service-package`) was read against `Serve.CAPABILITY_PROVIDERS.marketplace.pkg` at :1958 (`@objectstack/service-package`): it matches the tip and is not touched — repointing it is objectstack-ai#17676's engine lane. ## Token ratchet `node scripts/check-skills-token-ratchet.mjs`, convention ceil(utf8 bytes / 4): | | bytes | tokens | ceiling | headroom | exit | |:--|--:|--:|--:|--:|--:| | before (`5941246b70`) | 51918 | 12980 | 12984 | 4 | 0 | | after (`bef0dc6dfa`) | 51898 | 12975 | 12984 | 9 | 0 | No ceiling moves. The published-skill readings the os-dev definition asks for: this file 1223 → 1223 lines and 12980 → 12975 tokens; the package (all ten `skills/*/SKILL.md`) 6145 → 6145 lines and 70695 → 70690 tokens; the whole priced bundle 139987 → 139982 tokens. Lowering this file's ceiling to 12975 is the script's stated option, but it edits `scripts/check-skills-token-ratchet.mjs`, outside this card's one-file surface — left to the seat. ## Gates Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo objectstack-ai/objectstack` from the worktree (no hand-fed paths; change set read from the merge base `5941246b70`); every exit code captured redirect-then-`$?`; all runs at `bef0dc6dfa`. 23 derived commands, every one exit 0: `node scripts/check-ci-filter-parity.mjs` · `node scripts/check-closing-keyword-parity.mjs` · `node scripts/check-closing-keyword-parity.mjs --self-test` · `node scripts/check-comment-mask-corpus.mjs` · `node scripts/check-doc-route-spelling.mjs --advisory` · `node scripts/check-doc-route-spelling.mjs --self-test` · `node scripts/check-skills-token-ratchet.mjs` · `node scripts/check-skills-token-ratchet.mjs --self-test` · `pnpm --filter @objectstack/spec run check:skill-docs` · `pnpm check:agent-test-spelling` · `pnpm check:corpus-claim-drift` · `pnpm check:cross-package-test-inputs` · `pnpm check:doc-authoring` · `pnpm check:driver-memory-census` · `pnpm check:nul-bytes` · `pnpm check:pm-governed-merges` · `pnpm check:refd-timer-probe` · `pnpm check:role-word` · `pnpm check:skill-compatibility` · `pnpm check:skill-frame-sync` · `pnpm check:skill-identifier-liveness` · `pnpm check:watch-hint-literal` · `pnpm --filter @objectstack/lint run check:doc-formula-expressions` - `check:doc-formula-expressions` answered exit **3** (PREREQUISITE NOT MET) on its first run, before any build; then `pnpm --workspace-concurrency=2 --filter '@objectstack/lint...' build` under `scripts/pm/os-verify-lock.sh` (VERDICT command-exit 0, held 169s, waited 0s); the second run answered exit **0** — the 0 above is the second run. - Reconciliation: `node scripts/pm/dispatch-gates.mjs --ran ran.list` → `✓ dispatch-gates --ran: 23 derived famil(ies) accounted for — 23 run, 0 NOT-MEASURED (a DERIVED zero — all 23 recorded an exit code and none of them is 3)`, exit 0. - Named by the dispatch and run in addition (not in the derivation): `pnpm check:pm-skill-id-lint` exit 0. - Repo-wide `pnpm lint` (`eslint . --no-inline-config`) under the verify lock: VERDICT command-exit 0 (held 88s, waited 65s — shared-box seconds), at `bef0dc6dfa`. - Control-byte self-scan of the edited file (`grep -naP` over the C0/DEL range): 0 hits. Not owed locally, because the diff touches no package: no dependency-closure build, no package `test` / `typecheck`. What stays CI's, as the derivation's stderr names it: 51 artifact-roster families, 11 wide-population families, 14 pending-changeset families, and the path-scheduled `Test Core` job. ## Acceptance notes - noted, not filed — :440 「all 20 of its entries」 is a third copied count in the same section, true on the tip (map = 20, table = the same 20 names) and the same class as this card; it turns false the moment objectstack-ai#17676's runtime half keys `package-registry` in `Serve.CAPABILITY_PROVIDERS`. Kept out by the dispatch's 「no other sentence moves」. 承接者: the seat (a patch round on this PR — 「— all 20 of its entries:」 → 「— its entries:」 — pays for itself in tokens) or objectstack-ai#17676's runtime-half PR, which must edit the :442 table anyway. - noted, not filed — `package-registry` (in the vocabulary since objectstack-ai#18694, no CLI provider row yet) is not documented in this section, so the enumeration of not-in-map tokens is one name short on the tip. Incompleteness, not a wrong instruction: an author never writes the token, it is always-on. It closes by itself when objectstack-ai#17676's runtime half adds the row (the enumeration is complete again and the :442 table gains a line). 承接者: objectstack-ai#17676 (open, `domain:engine`); the card's 「objectstack-ai#18694 / objectstack-ai#18053's own text」 has no live holder — objectstack-ai#18053 is done and objectstack-ai#18694 landed without touching the skill. - option B, one sentence for the seat, no code: the gate that already walks `skills/**` for exactly this shape is `scripts/check-skill-identifier-liveness.mjs` Leg 2 (its header: 「the missing row — a doc enumeration presented as exhaustive stopped growing when the schema did」); registering this section's enumeration (the :442 table plus the two bullets) against `PLATFORM_CAPABILITY_TOKENS` there would flag `package-registry` today, while a prose COUNT such as 「all 20」 is outside both of its legs (existence, not arithmetic) and `check-skills-token-ratchet.mjs` prices bytes, not claims. - objectstack-ai#16767 remains open — the example block's TypeScript range in this file is a different number and is not folded. --- _Generated by [Claude Code](https://claude.ai/code/session_01Gqi43smmqjJ5sUrhfoPeKu)_ Co-authored-by: Claude <noreply@anthropic.com>
Fixes #18053
Clause-②: yes
Director ruling
5650202813on #17676 (decision batch #125 item 2, maintainer verbatim 「同意」), item 1 — the spec-constant half. The runtime half (items 2, 3, 5) stays on #17676 with thedomain:enginelane. ⛔ The ruling's direction is not re-opened here; the one judgment this card carries is the NAME, which the ruling deliberately declines to give.What changed
Three edits in
packages/spec/src/kernel/platform-capabilities.ts, plus the pins that read it.PLATFORM_CAPABILITY_TOKENSpackage-registryadded aftermarketplace; none removed; the relative order of all 28 unchangedPLATFORM_ALWAYS_ON_CAPABILITIESpackage-registryappended at the tail; none removed; the relative order of all 10 unchangedPLATFORM_CAPABILITY_PROVIDERSpackage-registry=@objectstack/service-package,openeditionThe full before/after item lists are in the report comment on #18053.
The name — and the candidates it beat
The comparison set, every token in the vocabulary today:
ai,ai-studio,i18n,ui,auth,automation,analytics,audit,cache,storage,queue,job,messaging,triggers,realtime,mcp,marketplace,email,sms,sharing,pinyin-search,reports,approvals,settings,webhooks,hierarchy-security,ai-seat,governance.Chosen:
package-registry. Four reasons, in order of weight:packages/spec/src/kernel/package-registry.zod.tssits in the same directory and opens "# Package Registry Protocol — Defines the runtime state and lifecycle operations for installed packages"; it exportsInstalledPackageSchemaand the installed-package lifecycle types, and its own prose calls a package row "the 'row' in the installed-packages table". The token now names the capability that PERSISTS exactly the protocol that module DEFINES, at the same spelling, in the same kernel. Nothing has to be learned to read it.QUALIFIER-NOUNwhere the noun is the thing and the qualifier narrows it:ai-studio,ai-seat,pinyin-search,hierarchy-security.package-registryis that shape exactly.sys_packagescontainer and the boot hydration that replays it — rather than what a deployment might additionally sell on top of it.@objectstack/service-packagealready says it in caller-visible prose ("The package registry could not store this package").Rejected, and why:
marketplace— forbidden by the ruling, and the reason the ruling exists: a token advertising a store that is not there.packages— grammatical (the set has plural tokens:reports,approvals,webhooks,triggers), but in this tree "package" means both an npm workspace package and a metadata package, and arequires: ['packages']line inside a monorepo is exactly the ambiguity the vocabulary header exists to prevent. It also names the noun, not the service.package-store— "store" is the connotation the ruling is REMOVING; re-importing it under a fresh spelling defeats the split.package-state— collides head-on withpackages/runtime/src/package-state-store.ts, which is the OTHER medium (the operator's disabled-id set under the ObjectStack home directory). Item 4 is about those two media not being confused; a token namedpackage-statewould make that confusion permanent.package-persistence— names a mechanism, not a service domain. No token in the set names an implementation property;storageis the service, not "file-persistence".sys-packages— the table name. A repo-private abbreviation, which the card forbids by name.registryalone — this tree already has three (the npm registry, ObjectQL'sSchemaRegistry, the metadata type registry).package-catalog/catalog— that IS the halfmarketplacekeeps.Question 1 — does the split move the length, or the always-on boundary derivation?
Measured before and after, not assumed.
requires: ['marketplace']keeps meaning today what it meant yesterday; this widens the accept set and narrows nothing.68e8b4b53cthe boundary is the rule "every entry that is not a bind target is mounted after ALL of them", withBIND_TARGETS = queue / job / cache / settings.package-registryis not a bind target: nothing on the slate binds into it duringkernel:ready, and its one hard requirement is the ObjectQL engine, which is not a capability token. So it joins the TAIL, exactly as the declaration's own comment instructs, and the derived rule covers it on arrival with no new target and no new prefix.platform-capabilities.test.ts, which pinsorderingViolations(slate + a new bind target). That assertion went red on the first edit and is updated from the rule rather than around it. That is the "ordering contract moves with it" half of the card, and it is this PR's first red (Evidence below).Question 2 — what does the CLI's
serve-capability-vocabulary.test.tsactually follow?Read, not copied from the card's sentence. That file reads the CONSTANTS (
PLATFORM_CAPABILITY_TOKENS,PLATFORM_CAPABILITY_PROVIDERS,PLATFORM_PLUGIN_WIRED_RUNTIMES) together withServe.CAPABILITY_PROVIDERS/Serve.CAPABILITY_TO_TIER/Serve.ALWAYS_ON_CAPABILITIES, and asserts set relations and package equality. It enumerates no slate ORDER anywhere.servereally appends:Serve.ALWAYS_ON_CAPABILITIEScarriespackage-registryand does not carrymarketplace. Both halves are asserted, because a one-sided pin would stay green on a slate that force-mounted the catalogue half too — the outcome the ruling refused.Measured on
serve's capability resolver atc17ff70f3f: a slate entry is force-appended to every app'srequires, and the CLI then mounts it only ifServe.CAPABILITY_PROVIDERSkeys the token — a token with no entry that IS in the vocabulary is skipped silently, by design. That registry keysmarketplace(=@objectstack/service-package/PackageServicePlugin) and does not keypackage-registry, andPackageServicePluginhas exactly one mount path in this repo: that row. Therefore:POST /api/v1/packagesis registered in memory only — it does not survive a restart, and leaves its published metadata orphaned #17676 items 2, 3, 5 — the engine lane);packages/cli/src/**is outside this card's declared file surface (0 paths in the diff — the DARK control below).This is recorded in three places a later reader will stand in: the slate declaration's own comment, the changeset, and the report comment — so the engine half is written against a stated fact rather than a discovered one.
Two related measured facts, neither changed by this PR: (a) the module header's growth instruction says to add a new token "HERE as well as to the runtime's provider registry", i.e. it expects the two in one PR; (b) the same header claims "the CLI's vocabulary-drift test fails if the registries and this list fall out of sync", which holds only in the serve-to-spec direction.
Item 4 — the ADR question (report-back;
docs/adr/**is untouched)What I read: #5047 and its verification comment
5174777602, which is where the phrase comes from. The two media are (1) the operator's disabled-id set in a flat JSON file under the ObjectStack home directory, written bypackages/runtime/src/package-state-store.ts, whose header states the choice outright — "intentionally a flat file rather than asys_*object: package lifecycle state is runtime/operational state, not project metadata"; and (2) the package rows themselves insys_packages. ADR-0016 §9.7 records medium (1) and ADR-0025 reuses it by reference ("the ADR-0016 §9.7package-state-store.tspattern").My judgment: no ADR note is owed by this diff, and one becomes worth considering only when the runtime half lands.
marketplaceas the owner ofsys_packages; the only ADR that namessys_packagesat all is ADR-0087 (a row-level upgrade diagnostic), which this diff does not touch; and no ADR namesPLATFORM_ALWAYS_ON_CAPABILITIES. So no recorded decision becomes false, and nothing here reverses one — the ruling's own reading holds: this changes which capability OWNS an existing medium, not the number of media.requires: ['marketplace'], while medium (1) is written unconditionally. Once the runtime half mounts the registry on every stock boot, the drift window ADR-0016 §9.7 knowingly accepted applies to every deployment rather than to marketplace-enabled ones only. That is a change in the trade-off's EXPOSURE, not in its SHAPE — a candidate for a one-line amendment to §9.7, filed as its own card by the seat, never assumed and never written from here.Evidence
Red before green (the ordering contract). With only the declaration edited and no test touched:
platform-capabilities.test.ts= 1 failed / 26 passed, naming "…and the rule is falsifiable — a hostile slate is named, not shrugged off", diff+ "package-registry". Green after the control is updated from the rule: 32 passed.Ablation — declaration reverted to the merge base, with an on-disk proof and a hash-verified restore.
ablation-dist-preflight @objectstack/specreports the marker absent from all 216 built filesexpected [ 'queue', 'job', 'cache', …(7) ] to include 'package-registry'git hash-object=b6c0292c5d2b5f0c012f12b8cacbdf97aed38ac7= theHEADblobWhole-tree
git status --porcelainafter the restore: empty. The restore leg is pinned toHEAD(never a baregit checkout --, never a moving ref) and runs from a trap onEXIT INT TERM. The CLI leg is measured against the rebuiltdist/, becausepackages/clicarries no vitest alias for@objectstack/specand resolves it throughexports.Controls. LIT: the token reads 5 occurrences in the declaration and the preflight finds it in 8 built files — the instrument fires. DARK, each of which must read 0 and does:
docs/adr/**paths in the diff = 0;packages/cli/src/**paths in the diff = 0;'marketplace'insidePLATFORM_ALWAYS_ON_CAPABILITIES= 0. The CLI'sserve-defaults.test.tscontrol runs over a FIXED synthetic slate rather than the live one, so it neither moved nor needed to.Suites and gates, all green at
37a112e0f2:@objectstack/specbuild;@objectstack/specfull suite 485 files / 13873 tests;@objectstack/spec typecheck; the four CLI capability files (serve-capability-vocabulary,serve-defaults,capability-preflight,serve-settings-ordering.pin) 44 tests; andcheck:nul-bytes,check-empty-changeset,check-changeset-no-major, speccheck:api-surface/check:export-origins/check:authorable-surface,check-spec-docblock-symbol-anchors,check:test-source-alias,check:cross-package-test-inputs,check:published-files. The full derived family list for this diff is 82 commands; the narrowing to the set above is declared in the report comment, and CI runs the farm.Generated by Claude Code