Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions .changeset/19339-kernel-install-request-describe-honours.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
---
"@objectstack/spec": patch
---

`kernel/InstallPackageRequest.enableOnInstall` no longer tells authors the in-process primitive ignores the key — it now states the three states that primitive really applies (#19339).

The declaration's published description read "this protocol primitive does not read it". That was true when it was written and stopped being true when `MetadataProtocol.installPackage` started honouring the key (`482d584121`): `true` enables, `false` disables, and an ABSENT key makes no lifecycle call at all. Nothing went red, because `check:docs` holds the generated reference page equal to the `.describe()` and the two still agreed with each other — internal consistency, not truth.

Clause-②: no

**What moves**

The `.describe()` text of one key, the doc block above it, and the two reference pages generated from that text (`references/api/protocol.mdx`, `references/kernel/package-registry.mdx`). It now reads: "restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive honours it on the registry row: true enables, false disables, absent makes no lifecycle call".

The scope word "on the registry row" is load-bearing and is spelled out in the doc block: the durable disabled-package file is keyed by environment, which an `InstallPackageRequest` does not carry, so this seam moves the registry row for the life of the process and `POST /api/v1/packages` still owns the record that survives a restart.

**What does not move**

No key is added, removed, renamed or retyped, and no default changes — the accept set is byte-for-byte what it was, and `api-surface`, `authorable-surface` and `authorable-defaults` are all unchanged. `PackageInstallRequestSchema` (`api/package-api.zod.ts`) remains the one authority for this key, and the parity pin that holds the copy to it is untouched.
2 changes: 1 addition & 1 deletion content/docs/references/api/protocol.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -1910,7 +1910,7 @@ Install package request
| :--- | :--- | :--- | :--- |
| **manifest** | `{ id: string; namespace?: string; defaultDatasource?: string; version: string; … }` | ✅ | Package manifest to install |
| **settings** | `Record<string, any>` | optional | User-provided settings at install time |
| **enableOnInstall** | `boolean` | optional (default: `true`) | Whether to enable immediately after install — restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive does not read it |
| **enableOnInstall** | `boolean` | optional (default: `true`) | Whether to enable immediately after install — restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive honours it on the registry row: true enables, false disables, absent makes no lifecycle call |
| **platformVersion** | `string` | optional | Current platform version for compatibility verification |

### Nested Shape: `InstallPackageRequest.manifest`
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/kernel/package-registry.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ Install package request
| :--- | :--- | :--- | :--- |
| **manifest** | `{ id: string; namespace?: string; defaultDatasource?: string; version: string; … }` | ✅ | Package manifest to install |
| **settings** | `Record<string, any>` | optional | User-provided settings at install time |
| **enableOnInstall** | `boolean` | optional (default: `true`) | Whether to enable immediately after install — restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive does not read it |
| **enableOnInstall** | `boolean` | optional (default: `true`) | Whether to enable immediately after install — restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive honours it on the registry row: true enables, false disables, absent makes no lifecycle call |
| **platformVersion** | `string` | optional | Current platform version for compatibility verification |

### Nested Shape: `InstallPackageRequest.manifest`
Expand Down
44 changes: 32 additions & 12 deletions packages/spec/src/kernel/package-registry.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -293,19 +293,39 @@ export const InstallPackageRequestSchema = lazySchema(() => z.object({
* ⛔ Never let the two drift: `src/api/package-install-one-authority.test.ts`
* parses BOTH over one matrix and reds when they disagree on any cell.
*
* ## ⚠️ This contract's own implementation does not read the key
* ## This contract's own implementation HONOURS the key — on the registry row
*
* This schema types the in-process protocol primitive
* `ObjectStackProtocol.installPackage` (`src/api/protocol.zod.ts`), whose
* implementation reads `request.manifest` and `request.settings` and nothing
* else (`packages/metadata-protocol/src/protocol.ts`). The HTTP door does
* NOT forward the key down this seam either: it calls
* `installPackage({ manifest, settings })` and performs the enable/disable
* flip itself afterwards, because the durable half must follow the ROW that
* door returned rather than the request's intent. So an `enableOnInstall`
* spelled on THIS request reaches no code that acts on it — which is why the
* `.describe()` says so on the published reference page rather than
* repeating the authority's promise a layer that cannot keep it.
* `ObjectStackProtocol.installPackage` (`src/api/protocol.zod.ts`), and that
* implementation (`packages/metadata-protocol/src/protocol.ts`) applies the
* same rule the HTTP door applies — 「缺省 = 保持,有旗 = 设置」 — through the
* same registry verbs `PATCH /packages/:id/enable` and
* `PATCH /packages/:id/disable` use:
*
* - `true` ⇒ `enablePackage` — clears a disable, including a boot-seeded one;
* - `false` ⇒ `disablePackage` — the row and its `status` both move;
* - ABSENT ⇒ no lifecycle call at all; the row the registry returned stands.
*
* `=== true` / `=== false`, never a truthiness test and never a `??` default:
* the THREE states are the contract, and a non-boolean value is read as
* ABSENT rather than coerced. The `.default(true)` below never reaches that
* path — nothing parses an install request through this schema there — so an
* absent key arrives intact and is read as absent.
*
* ⚠️ What this seam does NOT write, stated so the scope is not over-read: the
* runtime's DURABLE disabled-package file. That record is keyed by
* ENVIRONMENT (`setPackageDisabled(environmentId, id, disabled)`,
* `packages/runtime/src/package-state-store.ts`) and an
* `InstallPackageRequest` carries no environment, so the key cannot even be
* formed here; that module also lives in `@objectstack/runtime`, which
* depends on the protocol package and not the other way round. It is also why
* the HTTP door still calls `installPackage({ manifest, settings })` and
* performs its own enable/disable flip afterwards rather than forwarding the
* key down this seam: the durable half must follow the ROW that door returned
* rather than the request's intent. So an `enableOnInstall` spelled on THIS
* request moves the registry row — what every in-process reader serves from —
* for the life of the process; a caller that needs the choice to survive a
* restart goes through `POST /api/v1/packages`.
*
* ## ⛔ Why the reference is documentary and not `…Schema.shape.…`
*
Expand All @@ -322,7 +342,7 @@ export const InstallPackageRequestSchema = lazySchema(() => z.object({
* mechanical half of the reference, and it is the half that can fail.
*/
enableOnInstall: z.boolean().default(true)
.describe('Whether to enable immediately after install — restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive does not read it'),
.describe('Whether to enable immediately after install — restates the install-door request key, whose one authority is api/PackageInstallRequest; this protocol primitive honours it on the registry row: true enables, false disables, absent makes no lifecycle call'),
/**
* Current platform version for compatibility checking.
* When provided, the system compares this against the package's
Expand Down
Loading