Repository navigation
Commit 1de7def
fix(runtime)!: the package disable door refuses while an enabled package's validation rule reads a field the package adds (#30825)
<!-- claude-projects-attribution: {"github_login":"os-elon-musk"} -->
Fixes #30379
_Requested by **Elon** · [project
thread](https://claude.ai/code/project/chan_01WedDzV26nniwxv7jC88B9D?thread=cmsg_01WedDzV26nniwxv7jC88B9DRdR8tDhhemV41rvCmTN1MR)_
domain:server#4 · os-elon-musk · session_016WV4cwCWp9qZ5SgMof1qLa
Clause-②: no (narrowing)
Metadata-protocol: none
Skills-docs: updated here — `content/docs/api/metadata-api.mdx` (the
disable door's entry),
`content/docs/deployment/marketplace-handbook.mdx` (the
Enable-and-disable step and the Disabling-a-module list) and
`content/docs/api/error-catalog.mdx` (the code's 409 entry and the
wire-code count) name the refusal; `skills/**` teaches no package
disable door (grep for `packages/:id/disable`, `disableable`,
`WRITABLE_PACKAGE_REQUIRED`: none), so no skill or eval moves.
Claim: 6672353180 (amended 6672467575) · Branch:
`claude/project-thread-mwjmre` · Ruling-ref: 6670643454 (letter A, items
1–3) · ADR line: #30729 (merged) · Error code: #30724 / PR #30775
(merged) · Carry note: 6675092387 · Contract review: 6677642547 (FAIL)
and delta review 6679292152 (FAIL), both addressed at `c15ba57084`
## 维护者速读
- 改了什么:设置里停用一个模块时,如果停用后对象上仍然生效的某条校验规则读了这个模块加到别的对象上的字段,停用会被拒绝(409,错误码
`PACKAGE_DISABLE_RESTRICTED_BY_VALIDATION_RULE`),提示里逐条列出「包 · 对象 ·
规则」,什么都不改。规则按停用后对象实际生效的样子判断:同名规则只判胜出的那一份,客户在自己那份对象上关掉的规则算关闭,规则归到它生效文本所在的那一层(客户覆写层写作
`tenant overlay`)。用 `enableOnInstall: false`
覆盖一个当前启用的包时同样判断:装上,但保持启用,答同一个
409;全新安装、删除后重装、覆盖已停用的包照旧装成停用。公式读这些字段不拦(停用后答空值)。
- 为什么改:以前能停用,但停用后那条规则读不到字段,该对象的每一次写入都被拒(400 VALIDATION_FAILED),直到重新启用。这是
#30379 裁决 A(你 2026-11-05 21:56Z 的「同意」);本版按合同复审 6677642547 和增量复审
6679292152 改过。
- 风险与回滚:小。只多了一种拒绝,只在会把对象写死的停用上出现;读写接口、元数据和导出都不变。回滚即撤 PR。
- 先看:`packages/runtime/src/domains/packages.ts` 的
`readDisableDependentRules`(第二遍改为读注册表自己的折叠结果)、`ruleLayerLabel`、停用门和安装门的
409 分支;测试文件最后三个 describe。
- 两分钟验证:`pnpm --filter @objectstack/runtime exec vitest run
src/domains/packages-disable-module-extension-fields.test.ts`,预期 20 条全绿。
- 需要你做的:无,席位落地。
## What changes
**`@objectstack/runtime`: `PATCH /api/v1/packages/:id/disable`**
(`domains/packages.ts`)
- After the read-only check (`isDisableablePackage` /
`requireWritablePackage`), and before `registry.disablePackage` and
`setPackageDisabled`, the door asks `readDisableDependentRules(registry,
id)`. If that is non-empty, it answers `409` with `error.code`
`PACKAGE_DISABLE_RESTRICTED_BY_VALIDATION_RULE` (ledgered under
`@objectstack/runtime` by PR #30775). The message names every rule as
`package · object · rule (reads FIELD)`, one or several. Nothing changes
on a refusal. The refusal carries no `error.details` beyond the code
(the seat's ruling on carry-note item 2, see Out of scope).
- **What the disable withholds**, per object the package extends: the
fields its `extend` contributions add that neither the owner's own
declaration nor an extension that stays served also declares. This is
the registry's own reading of a withheld member
(`withholdDisabledExtensions`), asked of the state the disable would
leave.
- **Which rules count** (ruling items 1–2, contract review must-fix 1):
the rules the served object will carry once the disable lands, of every
severity, from any enabled package, declared dependent or not (no
`manifest.dependencies` entry is read), an app's `BASE.custom` pair
included. They are read off the registry's own fold,
`getAllObjects(undefined, { withoutExtensionsOf: id })`, never
re-assembled in the door. So:
- **one rule per name**, the copy the fold serves: a later layer's rule
replaces an earlier one of its name (`mergeValidationsByName`), and only
the winning copy is judged;
- **the tenant overlay's switch is honoured**: its `message` and
`active` sit on the packaged rule it names (`tenantRuleSettingsOf` /
`withPackagedOwnerRules`), so a rule the tenant switched off through the
overlay is off;
- **less the rules the disable takes off a base that carries them**
(`withoutWithheldMembers`), the one step a left-out fold does not take,
which the scan mirrors.
On an object whose owner is disabled or is the package itself, no write
reaches any rule, so none counts. A package already disabled withholds
nothing more, so the scan answers empty.
- **Who a rule is named after** (must-fix 1): the LAST layer in fold
order (the base, then each `extend` contribution that stays) that
declares the rule's name, which is the layer its served text comes from.
A tenant overlay is named `tenant overlay of PKG` (or `tenant overlay`
when it carries no package); the `(no package)` placeholder is gone (an
unpackaged layer is `unpackaged object` / `unpackaged extension`).
- **What "reads" means:**
- A predicate is read with `analyzeRelationshipTraversals`
(`@objectstack/formula`) over `record` and `previous`. That covers
`script` / `cross_field` `condition` and a `conditional`'s `when`, at
any depth. It is the reading the rule validator itself asks before it
refuses a write (`readsRecordColumn`).
- A `record.REF.FIELD` read is also a hop into REF's target, judged with
`referenceTargetOf` on the served field.
- A `state_machine` / `format` / `json_schema` rule reads the `field` it
names.
- No second parser.
- **Not counted:**
- a formula field over the withheld field (it answers `null`, PR #30362,
ruling item 1);
- a rule switched off (`active: false`, on its own copy or through the
tenant overlay; the remedy the refusal names);
- a rule a later layer replaced by name (only the winning copy is
judged);
- a rule of a disabled package.
- The code is held as its wire pair `{ code, status: 409 }`, the shape
`check:error-status-conformance` reads as a producer.
**`@objectstack/runtime`: `POST /api/v1/packages` with `enableOnInstall:
false`, on an overwrite of an enabled package** (contract review
should-fix, delta review must-fix 3)
- Before either install limb writes, the door reads whether the id's row
exists and is enabled (`registry.getPackage(pkgId)?.enabled === true`).
Only then can the install's `enableOnInstall: false` arm withhold a
field a rule is served against, so only then does it ask the same
`readDisableDependentRules(registry, pkgId)` before it disables.
- When a rule would read a field the disable withholds, the overwrite
still lands, the package stays enabled on the row, in the registry and
in the state file (all three follow the row the door returns), and the
door answers the same `409` and code, with the message lead `Package
'ID' was installed and stays enabled: enableOnInstall: false cannot
disable it`, instead of a `201` that claims a disable.
- A fresh install (or a reinstall after `DELETE /packages/:id`) and an
overwrite of a disabled package withhold nothing served, so they honour
`enableOnInstall: false` exactly as #18877 rules (「有旗 = 设置」): `201`,
disabled. With no reading rule, an overwrite of an enabled package
disables as before.
**`@objectstack/core`: the second-object read census**
(`src/security/second-object-read-exposure.pin.test.ts`)
- The scan follows a rule's `record.REF.FIELD` hop with
`referenceTargetOf`, which makes
`packages/runtime/src/domains/packages.ts` a new caller of the
reference-target arbiter. The census names it `not-a-served-read`: it
reads no record of the target and serves none of its fields, it only
asks whether FIELD is one the disable would withhold, from declared
metadata. (Unclassified, this pin turned Test Core 7/8 red on
`d315efca97`.)
**Docs** (carry-note item 3, must-fix 2)
- `content/docs/api/error-catalog.mdx`: the advertised count moves from
57 to **58 error codes reachable on the wire** (L7;
`packages/spec/src/api/error-catalog-docs.test.ts` pins it against the
wire face). A `### PACKAGE_DISABLE_RESTRICTED_BY_VALIDATION_RULE` entry
under *Conflict Errors (409)*, with cause (the served-fold judgment, the
layer naming and the install arm on an overwrite of an enabled package),
fix and `no_retry`. The status-conformance gate reconciles it against
the producer above (`packages.ts: { code, status }`, 409).
- `content/docs/deployment/marketplace-handbook.mdx`: the
Enable-and-disable step and the Disabling-a-module list gain the 409
row, a customer's switched-off copy counting as off, and the install arm
on an overwrite of an enabled module (a fresh install still lands
disabled). Before, they named only `422 WRITABLE_PACKAGE_REQUIRED`.
- `content/docs/api/metadata-api.mdx`: the `PATCH /packages/:id/disable`
entry names the refusal, the served-fold judgment, its remedy and the
install arm on an overwrite of an enabled package.
**Changeset**: `@objectstack/runtime` patch, with the BREAKING banner
(accept-set narrowing on the disable door, and on the install door for
an overwrite of an enabled package), `Clause-②: no (narrowing)`,
`Metadata-protocol: none` and the ADR-0087 disposition `not-required
(no-migration-prescription)`.
## Tests
`packages/runtime/src/domains/packages-disable-module-extension-fields.test.ts`
is the PR #30362 harness: real `HttpDispatcher` doors over a file-backed
SQLite kernel. It has 20 cases.
- `[#30379] the disable door refuses …` (3 cases). The fixture has:
- a rules module with an error `script`, a warning `conditional`, a
switched-off rule, and an info rule on the app's visit that reads
`record.account.qx_credit`;
- a formula module;
- a tenant rule saved and published into the app's `.custom` pair,
through `POST /packages/:app/ensure-customization` and the protocol's
save and publish.
The cases:
- **Disable:** `409` with
`PACKAGE_DISABLE_RESTRICTED_BY_VALIDATION_RULE`. The message reads `4
active validation rules read fields …` and lists exactly the four
reading rules, in order (pair, two on the account, the hop on the
visit), each with what it reads. The switched-off rule and the formula
module are not named, and `error.details` is absent. The row stays
enabled, the fields stay served, a write still lands and the state file
does not list the package.
- **Reading module disabled first:** the refusal names only the pair's
rule (`an active validation rule reads a field …`). Once the pair is
disabled, the disable proceeds (200), the fields are withheld, the
formula answers `null` and writes land.
- **Measured, not ruled:** re-enabling the reading module while the
field stays withheld refuses writes with `400 VALIDATION_FAILED` naming
the rule. That is the enable door, #30756; it flips this pin.
- `[#30379 contract review] the scan judges the rules the served fold
serves` (2 cases). A third module extends the account at a later
priority and redeclares two of the rules module's rules by name: one so
it no longer reads the field, one so it does.
- **Replaced by name (pin b):** `409` naming exactly 2 rules: the
visit's hop, and the redeclared reader named after the override module.
The rule whose winning copy no longer reads the field is not named,
though the rules module's own copy still reads it.
- **Tenant overlay (pin a):** a tenant overlay of the account
(registered as `overlay`) switches the override's reader off and
declares its own reader. The refusal names the visit's hop and the
overlay's own rule as `tenant overlay of com.qa.extsuite`, and no `(no
package)`. Once overlays switch every served reader off (`active:
false`), the disable answers `200`, the module's fields are withheld
(the overlay's copies of them included) and a write lands.
- `[#30379 contract review] POST /packages with enableOnInstall: false
asks the same scan` (3 cases, a real `SchemaRegistry` and
`HttpDispatcher` over a stub kernel):
- an overwrite with `enableOnInstall: false` of an enabled extender
whose field another package's rule reads answers `409` with the code and
the exact message; the package stays enabled, the state file does not
list it and the field is still served;
- **fresh install (delta review must-fix 3):** with no row before the
install and the same reading rule registered, `enableOnInstall: false`
answers `201` and the package is disabled, in the registry and in the
state file;
- **control:** with no rule reading the field, the overwrite answers
`201` and the package is disabled.
- The formula describe stays the CONTROL: a formula alone over the field
⇒ the disable proceeds (200) and writes land.
<details><summary>Run and ablation</summary>
All at head `c15ba57084` (merge base `origin/main` `c17719dd6c`), under
`scripts/pm/os-verify-lock.sh`, after a whole-tree `pnpm turbo run build
--concurrency=2` at that head (119/119 tasks, VERDICT command-exit 0).
```text
pnpm --filter @objectstack/runtime exec vitest run src/domains/packages-disable-module-extension-fields.test.ts
Test Files 1 passed (1)
Tests 20 passed (20)
os-verify-lock: VERDICT command-exit 0 · held the lock 19s
```
Six ablations, each `node scripts/ablation-replace.mjs --file
packages/runtime/src/domains/packages.ts --anchor A --replacement R --
(the same vitest run)`, all on the committed head under one lock
(VERDICT command-exit 0, 116s). Each mutation landed (anchor 1 → 0),
every one went red, and every restore left the file at HEAD's blob
`b1cec1748292` (`git diff HEAD` empty).
| Ablation | Anchor → replacement | Red |
| --- | --- | --- |
| A0 the disable door's scan | `readDisableDependentRules(registry,
id);` → the same call with an always-false `.filter` | 4 failed / 20 |
| A1 `active` ignored | drop `rule.active === false \|\|` from the
served-rule filter | 3 failed / 20 |
| A2 named after the base | `ruleLayerLabel(layerOf.get(rule.name) ??
base)` → `ruleLayerLabel(base)` | 6 failed / 20 |
| A3 the install arm's scan | `overwritesEnabledRow ?
readDisableDependentRules(registry, pkgId) : [];` → `[]` | 1 failed / 20
(the overwrite-of-enabled pin) |
| A4 every contributor's copy judged | `declaredRulesOf(served)` → every
contributor's `declaredRulesOf(c.definition)` | 2 failed / 20 |
| A5 the scan on every install | `overwritesEnabledRow ?
readDisableDependentRules(registry, pkgId) : [];` →
`readDisableDependentRules(registry, pkgId);` | 1 failed / 20 (the
fresh-install pin) |
A4 is the reading the contract review measured: judged per copy, the
replaced rule and the overlay-switched rule both refuse again. A5 is the
delta review's: scanned on a fresh install, the package lands enabled
against `enableOnInstall: false`.
The second-object census row, before and after, with the tree built:
```text
pnpm --filter @objectstack/core run test:repo (at d315efc, without the row)
× every caller of the reference-target arbiter is classified, and every classified file still calls it
- packages/runtime/src/domains/packages.ts
Test Files 1 failed | 5 passed (6)
Tests 1 failed | 93 passed (94)
pnpm --filter @objectstack/core run test:repo (at c15ba57)
Test Files 6 passed (6)
Tests 94 passed (94)
os-verify-lock: VERDICT command-exit 0 · held the lock 6s
```
```text
pnpm --filter @objectstack/core test
Test Files 136 passed (136)
Tests 3131 passed (3131)
os-verify-lock: VERDICT command-exit 0 · held the lock 36s
pnpm --filter @objectstack/spec run test:repo
Test Files 90 passed (90)
Tests 1539 passed (1539)
os-verify-lock: VERDICT command-exit 0 · held the lock 425s (7m05s)
pnpm --filter @objectstack/runtime test
Test Files 547 passed (547)
Tests 8768 passed | 19 skipped (8787)
os-verify-lock: VERDICT command-exit 0 · held the lock 675s (11m15s)
pnpm --filter @objectstack/runtime typecheck (tsc --noEmit && check:test-typecheck)
os-verify-lock: VERDICT command-exit 0 · held the lock 31s
pnpm --filter @objectstack/core typecheck (tsc --noEmit, the examples project, check:test-typecheck)
os-verify-lock: VERDICT command-exit 0 · held the lock 21s
```
No `@objectstack/objectql` file is touched (the install pins import its
`SchemaRegistry`); its suite is CI's.
Premise, re-measured on `origin/main` `6ef7f583` before the change: the
disable answered 200 and the write after it 400 `VALIDATION_FAILED`
(12/12 of the then harness).
</details>
## Acceptance notes
- **The enable door is not judged here.** With the field's package
already disabled, enabling a package whose rule reads the field is
accepted, and every write to the object then answers `400
VALIDATION_FAILED` naming the rule. A boot replaying such a state file
ends in the same state. Pinned as measured. The mirror is #30756
(pm:blocked behind this card).
- **`disableable` is unchanged.** The package row's `disableable` (the
door's PACKAGE verdict, ADR-0070 / #28318) still answers `true` for such
a module. The dependent rule is an environment-state conflict, answered
by the `409`. Showing it on the Settings page is the `domain:ui` card
the seat files after this lands.
- **The install arm keeps the install.** A refused `enableOnInstall:
false` (only ever on an overwrite of an enabled package) does not roll
the overwrite back: the artifact the request carried is installed and
stays enabled, and the `409` says so. Undoing the install would be a
second write the request did not ask for.
- **The install arm reads the row before the install.** A fresh install,
a reinstall after a delete and an overwrite of a disabled package are
not scanned: none of them withholds a field a rule is served against,
and #18877's 「有旗 = 设置」 holds for them unchanged.
- **`cross_field.fields` is advisory** (per the spec, only its first
entry labels the violation), so a `cross_field` rule is judged by its
`condition`.
- **A source that does not parse reads nothing here.** Such a rule
already refuses every write, whatever is enabled.
- **The cloud route is not measured.**
`/api/v1/cloud/environments/:env/packages/:pkg/disable` (`carrier:
cloud`) was not run here.
## Out of scope
- **A machine-readable `error.details` shape** for the package · object
· rule triples. The seat ruled (A) on carry-note item 2: no structured
details, and no `packages/spec`. If the Settings page ever needs the
triples machine-readable, that is a `domain:spec` contract card first: a
`contracts/` schema plus the ledger row comment, the
`ACTION_CONFIRMATION_REQUIRED` pattern. The runtime would stamp it after
that card lands. The seat records this on the UI card.
- **The enable door's mirror**: #30756.
- **The uninstall door.** `DELETE /packages/:id` withdraws the same
extension fields with no scan. The seat files it as its own card.
## Verification
<details><summary>Local gates (dispatch-gates --commands on this
diff)</summary>
At head `c15ba57084`: `node scripts/pm/dispatch-gates.mjs --commands
--repo objectstack-ai/objectstack` derived 92 commands; each ran with
its exit code captured before any pipe.
```text
node scripts/check-adr-0087-registration.mjs --base origin/main :: exit 0
node scripts/check-adr-0087-registration.mjs --self-test :: exit 0
node scripts/check-adr-links.mjs :: exit 0
node scripts/check-adr-links.mjs --self-test :: exit 0
node scripts/check-changeset-no-major.mjs --base origin/main :: exit 0
node scripts/check-closing-keyword-parity.mjs :: exit 0
node scripts/check-closing-keyword-parity.mjs --self-test :: exit 0
node scripts/check-comment-mask-adoption.mjs :: exit 0
node scripts/check-comment-mask-adoption.mjs --self-test :: exit 0
node scripts/check-comment-mask-corpus.mjs :: exit 0
node scripts/check-dev-prereqs.mjs --self-test :: exit 0
node scripts/check-doc-route-spelling.mjs --advisory :: exit 0
node scripts/check-doc-route-spelling.mjs --self-test :: exit 0
node scripts/check-docs-section-name.mjs :: exit 0
node scripts/check-docs-section-name.mjs --self-test :: exit 0
node scripts/check-dts-emitted.mjs --self-test :: exit 0
node scripts/check-empty-changeset.mjs --base origin/main :: exit 0
node scripts/check-empty-changeset.mjs --self-test :: exit 0
node scripts/check-issue-citations.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs :: exit 0
node scripts/check-plugin-teardown-shape.mjs --self-test :: exit 0
node scripts/check-section-landing-index.mjs :: exit 0
node scripts/check-section-landing-index.mjs --self-test :: exit 0
node scripts/ci/assert-turbo-remote-cache.mjs --self-test :: exit 0
node scripts/ci/plan-test-core-shards.mjs --self-test :: exit 0
node scripts/ci/prune-turbo-cache.mjs --self-test :: exit 0
node scripts/docs-audit/check-affected-docs.mjs :: exit 0
node scripts/docs-audit/check-drift-comment.mjs :: exit 0
node scripts/pm/release-rehearsal-clone.mjs --self-test :: exit 0
node scripts/release-pending-publish.mjs --self-test :: exit 0
pnpm --filter @objectstack/lint run check:doc-formula-expressions :: exit 0
pnpm --filter @objectstack/lint run check:doc-security-posture :: exit 0
pnpm --filter @objectstack/spec run check:docs :: exit 0
pnpm --filter @objectstack/spec run check:duration-unit-keys :: exit 0
pnpm --filter @objectstack/spec run check:empty-state :: exit 0
pnpm --filter @objectstack/spec run check:liveness :: exit 0
pnpm --filter @objectstack/spec run check:skill-examples :: exit 0
pnpm --filter @objectstack/spec run check:strictness-ledger :: exit 0
pnpm --filter @objectstack/spec run check:variant-docs :: exit 0
pnpm --filter @objectstack/spec run check:yaml-examples :: exit 0
pnpm check:changeset-gate-self-tests :: exit 0
pnpm check:ci-filter-parity :: exit 0
pnpm check:closed-ceremony-text :: exit 0
pnpm check:corpus-claim-drift :: exit 0
pnpm check:cross-package-test-inputs :: exit 0
pnpm check:dispatcher-error-vocabulary :: exit 0
pnpm check:doc-anchors :: exit 0
pnpm check:doc-authoring :: exit 0
pnpm check:doc-frontmatter :: exit 0
pnpm check:docs-audit-scope :: exit 0
pnpm check:docs-redirects :: exit 0
pnpm check:docs-single-h1 :: exit 0
pnpm check:docs-spec-enumerations :: exit 0
pnpm check:docs-transcript-drift :: exit 0
pnpm check:driver-memory-census :: exit 0
pnpm check:dts-closure :: exit 0
pnpm check:dual-build-cjs-loads :: exit 0
pnpm check:durability-log-level :: exit 0
pnpm check:engine-double-contract :: exit 0
pnpm check:error-status-conformance :: exit 0
pnpm check:gitlink-declared :: exit 0
pnpm check:issue-citations :: exit 0
pnpm check:kernel-hook-pairs :: exit 0
pnpm check:keyed-text-bounds :: exit 0
pnpm check:lean-entry-closure :: exit 0
pnpm check:logger-receiver-detach :: exit 0
pnpm check:nul-bytes :: exit 0
pnpm check:objectql-double-limit :: exit 0
pnpm check:org-identifier :: exit 0
pnpm check:page-declaration-shape :: exit 0
pnpm check:platform-object-tenancy-census :: exit 0
pnpm check:published-files :: exit 0
pnpm check:published-readme-links :: exit 0
pnpm check:query-options-erasure :: exit 0
pnpm check:react-page-adapter-contract :: exit 0
pnpm check:refd-timer-probe :: exit 0
pnpm check:registry-log-declared :: exit 0
pnpm check:rest-log-spy-declared :: exit 0
pnpm check:role-word :: exit 0
pnpm check:route-envelope :: exit 0
pnpm check:skill-identifier-liveness :: exit 0
pnpm check:slot-lookup :: exit 0
pnpm check:sourcemap-no-sources-content :: exit 0
pnpm check:system-context-census :: exit 0
pnpm check:test-source-alias :: exit 0
pnpm check:tier-file-adoption :: exit 0
pnpm check:type-check-coverage :: exit 0
pnpm check:type-check-debt :: exit 0
pnpm check:undeclared-dep-imports :: exit 0
pnpm check:vendor-version-stamps :: exit 0
pnpm check:watch-hint-literal :: exit 0
pnpm check:where-matcher :: exit 0
```
`node scripts/pm/dispatch-gates.mjs --ran`: 92 derived, 92 run, 0
NOT-MEASURED, 0 UNRUN (exit 0).
CI families outside the derivation (the artifact rosters, the
wide-population families, the path-scheduled jobs and the type-check
lanes) belong to CI; this PR's check-runs are their record.
</details>
<details><summary>Full dogfood battery (Clause-② carries the (narrowing)
arm)</summary>
```text
pnpm --filter @objectstack/dogfood test (whole-tree build first; no OS_TEST_SHARD, no path)
Test Files 423 passed | 3 skipped (426)
Tests 3533 passed | 41 skipped (3574)
os-verify-lock: VERDICT command-exit 0 · held the lock 1558s (25m58s)
```
Head `c15ba57084`. No failure.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(not touched)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes. (CI's repo-wide run)
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed. (not touched)
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
---
_Generated by [Claude
Code](https://claude.ai/code/session_016WV4cwCWp9qZ5SgMof1qLa)_
<!-- signed: domain:server#4 · os-elon-musk ·
session_016WV4czvZykUqhYxYXSSDt4 -->
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 000a4c0 commit 1de7def
7 files changed
Lines changed: 843 additions & 26 deletions
File tree
- .changeset
- content/docs
- api
- deployment
- packages
- core/src/security
- runtime/src/domains
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
4 | 4 | | |
5 | 5 | | |
6 | 6 | | |
7 | | - | |
| 7 | + | |
8 | 8 | | |
9 | 9 | | |
10 | 10 | | |
| |||
546 | 546 | | |
547 | 547 | | |
548 | 548 | | |
| 549 | + | |
| 550 | + | |
| 551 | + | |
| 552 | + | |
| 553 | + | |
549 | 554 | | |
550 | 555 | | |
551 | 556 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
182 | 182 | | |
183 | 183 | | |
184 | 184 | | |
| 185 | + | |
| 186 | + | |
| 187 | + | |
| 188 | + | |
| 189 | + | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
185 | 199 | | |
186 | 200 | | |
187 | 201 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
228 | 228 | | |
229 | 229 | | |
230 | 230 | | |
| 231 | + | |
| 232 | + | |
| 233 | + | |
231 | 234 | | |
232 | 235 | | |
233 | 236 | | |
| |||
302 | 305 | | |
303 | 306 | | |
304 | 307 | | |
| 308 | + | |
| 309 | + | |
| 310 | + | |
| 311 | + | |
| 312 | + | |
| 313 | + | |
| 314 | + | |
| 315 | + | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
305 | 323 | | |
306 | 324 | | |
307 | 325 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
313 | 313 | | |
314 | 314 | | |
315 | 315 | | |
| 316 | + | |
| 317 | + | |
| 318 | + | |
| 319 | + | |
| 320 | + | |
| 321 | + | |
| 322 | + | |
| 323 | + | |
| 324 | + | |
316 | 325 | | |
317 | 326 | | |
318 | 327 | | |
| |||
0 commit comments