Repository navigation
Commit 557973d
feat(spec)!: retire kernel/package-upgrade.zod.ts whole — the upgrade plan, diff, snapshot and rollback model nothing implemented (ADR-0049) (#25757)
Fixes #25608
Clause-②: no (narrowing)
Metadata-protocol: narrowed
Ruling-ref: 6259332195 (ruling A on #24443, item 3); triage first grade
6382810541
Retires `packages/spec/src/kernel/package-upgrade.zod.ts` whole — the
package upgrade plan, metadata diff, impact level, pre-upgrade snapshot,
upgrade and rollback request/response pairs and the phase vocabulary —
together with the four `IPackageService` members that returned them
(`planUpgrade`, `upgrade`, `rollback`, `getSnapshot`) and their three
input interfaces, and the `plan` member of
`PackageUpgradeResponse.data`. ADR-0049 enforce-or-remove, route 3
(whole-def removal). Nothing ever implemented, served or read any of it.
The two governed sentences (ADR-0126 about `:321`, and the ADR-0138 D5
sentence ruling A `6386464761` orders) ride their own draft PR, #25716,
which merges after this one.
## Ruling executed (quoted, not re-ruled)
Ruling `6259332195` on #24443, letter A, maintainer 「其他同意」, item 3:
"**Retired:** `packages/spec/src/kernel/package-upgrade.zod.ts` (plan,
diff, conflict, snapshot, rollback; zero runtime consumers), with its
ADR-0087 conversion." Triage `6382810541`: done directly in 18.x with no
retirement stage.
## Premise re-measured (every zero beside a lit control)
| reading | tree | retired names (29) + `planUpgrade` + the module
specifier | control |
| --- | --- | --- | --- |
| objectstack, outside `packages/spec`, CHANGELOGs excluded | base
`47af3dde42` | 0 code files: 3 generated reference pages +
`references/kernel/meta.json`, `content/docs/upgrading.mdx`, one
ADR-0126 sentence | the same pattern hits 17 files inside
`packages/spec` |
| objectui `main` | `a3c0da9` | 0 files | `@objectstack/spec`: 2123
files |
| objectui at the pinned `.objectui-sha` | `2958f17e9c` | 0 files |
`@objectstack/spec`: 2131 files |
| hotcrm `main` | `a4b3560` | 0 files | `@objectstack/spec`: 293 files |
| providers | base | nothing implements `IPackageService` | — |
The card's inventory held, with two additions it did not list:
`src/system/compliance-families-retirement.test.ts` used
`MetadataChangeType` as its "live near-namesake" must-survive control
(its only reader was the retired module itself; the control is now
`BreakingChange`), and the contract lost **four** members and three
input interfaces, not two — `rollback` and `getSnapshot` returned the
retired `RollbackPackageResponse` / `UpgradeSnapshot` as well.
## Why no D2 conversion and no tombstone
None of the ten shapes is a stack collection member or a metadata type,
so there is no authored document a D2 conversion could rewrite and no
carrier key a `retiredKey()` tombstone could sit on. The ruling's
"ADR-0087 conversion" is therefore the ledger record, exactly as for the
export-job and change-management whole-family retirements: ten
`RETIRED_DEFS_BY_MAJOR[18]` entries (which the manifest-deletion gate
reads), one D3 semantic entry `kernel-package-upgrade-family-retired`,
and one `STEP18_RATIONALE` fragment. The `UpgradePlan.estimatedDuration`
tombstone's `RETIRED_KEYS_BY_MAJOR[18]` entry and the D3 entry
`kernel-package-lifecycle-durations-unit-in-key` stay as history
(pinned). `PackageUpgradeResponse.data` is a non-strict object bound to
no route, so its `plan` leaves without a tombstone (route 3: nothing
parses it); a pin asserts a stray `plan` is stripped.
## What changed
- **Removed:** `src/kernel/package-upgrade.zod.ts` and its test; the
re-export in `src/kernel/index.ts` (a comment block stays in its place
naming the retirement); the upgrade section of
`src/contracts/package-service.ts` and its test cases; `plan` in
`src/api/package-api.zod.ts`.
- **Registered:** `src/migrations/entries/retired-defs/18.kernel__*.ts`
×10,
`src/migrations/entries/semantic/18.kernel-package-upgrade-family-retired.ts`,
a `STEP18_RATIONALE` fragment in `src/migrations/registry.ts.template`.
- **Pinned:** `src/kernel/package-upgrade-family-retirement.test.ts`
(listed in `vitest.repo-tests.json`; its walk radius is the one already
declared for `@objectstack/spec` in
`scripts/cross-package-test-inputs.mjs`): zero holders on every public
entry, runtime namespaces, the four contract members absent at the type
level with a lit control, `plan` absent from the shape, module gone from
disk and unimported, shards clean, ledger wired with no D2 conversion,
and tree-scoped absence across `packages`, `examples`, `skills`,
`content`, `scripts`.
- **Generated (regenerated, not hand-typed):**
`json-schema.manifest/kernel.json` (−10, deleted deliberately as the
manifest-deletion gate requires), `authorable-surface/kernel.json` (−48,
the whole-def route; check (c) re-proved it against the git base),
`authorable-defaults/kernel.json`,
`api-surface/{kernel,contracts}.json`, `declaration-map/kernel.json`,
`export-origins/{kernel,contracts}.json`,
`dropped-refinements.baseline.json` (two entries and their header
totals), the strictness-ledger counts, and `content/docs/references/**`
(the `package-upgrade` page is gone).
- **Count pins that follow the module:**
`type-alias-convention.pin.test.ts` 790 → 786 (four isomorphic pins and
the `M92` import), `scripts/file-description.test.ts` 31 → 30 level-1
openers, `llms.txt` 206 → 205 schemas / kernel 31 → 30,
`quick-reference.mdx` kernel 30 → 29.
- **Hand-written docs made false by the diff:**
`content/docs/upgrading.mdx` described a package-upgrade lifecycle
(pre-check, plan, snapshot, …) and linked the removed page; it now says
what the platform serves — a re-install with `overwrite: true` and the
commit rollback — and links Package Management in the Metadata API.
- **Changeset:** `.changeset/25608-retire-package-upgrade.md`, `minor`
(launch-window convention) with the BREAKING banner, the FROM → TO
table, both declaration lines and `registered
kernel-package-upgrade-family-retired`.
## Tests and gates
All readings below are at head `3e7b204be7` (after merging `origin/main`
`c61f75d10f` through `scripts/pm/os-regen-merge.sh`, then `pnpm install
--frozen-lockfile`, a full `turbo run build` and `@objectstack/spec`
`build` + `check:generated`), under `scripts/pm/os-verify-lock.sh`, exit
codes captured before any pipe.
| command | result |
| --- | --- |
| `pnpm --filter @objectstack/spec typecheck` | exit 0 |
| `pnpm --filter @objectstack/spec test` | exit 1: 21787 passed, 23
failed, **all 23 in `scripts/liveness/check-liveness.test.ts`, each
naming the main-red below** |
| `pnpm --filter @objectstack/spec test:repo` | exit 0: 80 files, 1279
tests |
| `pnpm --filter @objectstack/cli test` (unit **and** integration
projects) | exit 0: 501 files, 6297 tests |
| `pnpm --filter @objectstack/dogfood test` (the `(narrowing)` arm's
full battery) | exit 0: 295 files, 2520 tests |
| `pnpm --filter @objectstack/metadata-protocol test` (pre-merge head
`80ed3baba1`) | exit 0: 263 files, 21485 tests |
| plugin-audit `sys-comment-retired-fields.test.ts`, service-automation
`decision-overlapping-edge-conditions.pin.test.ts` (both read the
ledger; pre-merge) | exit 0 each |
| `node scripts/check-platform-checklist.mjs --changed-from origin/main`
| exit 0: no checklist anchor in the change set |
**Derived gates.** `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` at `3e7b204be7`: 120 families. Every one
run; `--ran` reconciles: "120 derived famil(ies) accounted for — 120
run, 0 NOT-MEASURED (a DERIVED zero — all 120 recorded an exit code and
none of them is 3)". 118 exit 0, including
`check-adr-0087-registration`, `check-changeset-no-major`,
`check-empty-changeset`, `check:api-surface`,
`check:authorable-surface`, `check:docs`, `check:llms-txt`,
`check:quick-reference-counts`, `check:spec-parsed-alias`,
`check:cross-package-test-inputs` and `check:nul-bytes`. Two are red,
both the main-red below: `check:liveness` and `check:generated` (whose
only stale artifact is `liveness/state-counts/`).
**Main-red, not this PR's.** `check:liveness` refuses
`translation/flows.screens →
packages/services/service-automation/src/engine.ts`: the citation names
a file that no longer names the property. Reproduced on a clean
`origin/main` `c61f75d10f` worktree (exit 1, same line). The
service-automation refactors that moved bodies out of `engine.ts`
(#25725, #25734) moved `renderFlowTextSlot` to
`packages/services/service-automation/src/node-text-rendering.ts`. The
proposed patch, not carried here because it is outside this diff: in
`packages/spec/liveness/translation.json`, re-point that row's
`engine.ts#renderFlowTextSlot` evidence to
`node-text-rendering.ts#renderFlowTextSlot`. No fix PR existed to port
when this was measured.
**Ablation (reverse verification of the pin).** The pin imports `src`,
so there is no `dist/` leg. Through `node scripts/ablation-replace.mjs`
on the committed tree, I replaced the retirement comment in
`src/kernel/index.ts` with `export * from './package-upgrade.zod';`
(anchor 1 → 0, blob `baf1437875cf` → `cc18be2f5671`) and restored the
module from the base under an EXIT trap. Predicted red: runtime
namespaces, module-on-disk / importer, and the tree-scoped walk.
Predicted green: export-origin holders (they read the committed
artifact), shards, registration, the contract type and the `plan` shape.
**Observed exactly that: 3 red, 7 green.** The restore was
blob-identical to `HEAD` (`baf1437875cf`), `git diff HEAD` was empty,
and the restored module was deleted. A first attempt was a recorded
no-op (its replacement kept the anchor, so the tool refused it) and is
not counted.
**Downstream.** objectui main `a3c0da9` / pin `2958f17e9c`, and hotcrm
`a4b3560`: zero hits (table above). No objectui fix or pin bump is
needed.
## Acceptance notes
- `content/docs/protocol/kernel/lifecycle.mdx` § Upgrades describes
`objectstack upgrade` strategies and pre-upgrade backups as design
intent, flagged as such at the top of the page; it never cited the
retired spec and this diff does not make it false. Not touched.
- `PackageUpgradeRequestSchema` / `PackageUpgradeResponseSchema` stay
published and bound to no route (recorded by the existing D3 entry
`package-api-contracts-unmounted-entries-retired`); retiring them is
outside this card.
- The D3 entry `change-management-family-retired` (history) still says
`kernel/MetadataChangeType` was "a different declaration with a live
consumer" and "unaffected". That was true of that retirement; its only
reader was the module retired here. Left as history.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01T5pRzjp4QpCwioKZ9Gt5tC
---
_Generated by [Claude
Code](https://claude.ai/code/session_01T5pRzjp4QpCwioKZ9Gt5tC)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: objectstack-fleet[bot] <332303061+objectstack-fleet[bot]@users.noreply.github.com>1 parent 52f3f51 commit 557973d
44 files changed
Lines changed: 642 additions & 1374 deletions
File tree
- .changeset
- content/docs
- getting-started
- references
- api
- kernel
- docs/audits/2026-07-unknown-key-strictness-ledger.counts
- packages/spec
- api-surface
- authorable-defaults
- authorable-surface
- declaration-map
- export-origins
- json-schema.manifest
- scripts
- src
- api
- contracts
- kernel
- migrations
- entries
- retired-defs
- semantic
- system
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
| 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 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
61 | 61 | | |
62 | 62 | | |
63 | 63 | | |
64 | | - | |
| 64 | + | |
65 | 65 | | |
66 | 66 | | |
67 | 67 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
585 | 585 | | |
586 | 586 | | |
587 | 587 | | |
588 | | - | |
| 588 | + | |
589 | 589 | | |
590 | 590 | | |
591 | 591 | | |
| |||
616 | 616 | | |
617 | 617 | | |
618 | 618 | | |
619 | | - | |
620 | 619 | | |
621 | 620 | | |
622 | 621 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
| 29 | + | |
30 | 30 | | |
31 | 31 | | |
32 | 32 | | |
33 | 33 | | |
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
37 | | - | |
| 37 | + | |
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| |||
199 | 199 | | |
200 | 200 | | |
201 | 201 | | |
202 | | - | |
| 202 | + | |
203 | 203 | | |
204 | 204 | | |
205 | 205 | | |
| |||
222 | 222 | | |
223 | 223 | | |
224 | 224 | | |
225 | | - | |
226 | 225 | | |
227 | 226 | | |
228 | 227 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1 | 1 | | |
2 | 2 | | |
3 | 3 | | |
4 | | - | |
| 4 | + | |
5 | 5 | | |
6 | 6 | | |
7 | 7 | | |
| |||
26 | 26 | | |
27 | 27 | | |
28 | 28 | | |
29 | | - | |
30 | 29 | | |
31 | 30 | | |
32 | 31 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
18 | 18 | | |
19 | 19 | | |
20 | 20 | | |
21 | | - | |
22 | 21 | | |
23 | 22 | | |
24 | 23 | | |
| |||
0 commit comments