Repository navigation
Commit 81cd9eb
<!-- claude-projects-attribution: {"github_login":"os-warren"} -->
_Requested by **Warren** · [project
thread](https://claude.ai/code/project/chan_01U5RdnAAmkSQmZbqh6FtqZ8?thread=cmsg_01U5RdnAAmkSQmZbqh6FtqZ8CS9iUSJwYcxNgNAu6nCtWs)_
Fixes #29563
Clause-②: no
Metadata-protocol: none
## 维护者速读
- 改了什么:基础包的导出 `GET /packages/BASE/export` 不再夹带 `.custom`
配对包已发布的仪表盘、报表覆盖项;配对包的导出照旧带覆盖项和 `overrides` 声明。
- 为什么改:ADR-0146 D8 第 3
条要求基础包导出「原样」;视图已经如此,仪表盘和报表却把客户的改动写进了厂商的包文件,无法当作厂商包重新部署。
- 风险与回滚:只在导出时多过滤一类条目(声明「覆盖本包」的条目),其余读取不变;回滚即撤回本 PR 的一个 commit。
- 先看:`packages/runtime/src/domains/packages.ts` 的 `declaresOverrideOf` 与
`assemblePackageManifest` 里的那一行过滤;再看新测试
`packages-export-base-unchanged-per-type.integration.test.ts`。
- 两分钟验证:`pnpm --filter @objectstack/runtime exec vitest run --project
local
src/domains/packages-export-base-unchanged-per-type.integration.test.ts`,预期
3 条全绿(视图、仪表盘、报表)。
- 需要你做的:无,席位落地。
## What changes
`assemblePackageManifest` (the `GET /packages/:id/export` door) now
leaves out, from a package's own export read through the per-package
layer, any item whose `overrides.package` names that same package. A
package's own document never declares that it overrides itself: that
declaration is what an item of the base's `.custom` pair carries. The
pair's export is unchanged and keeps the overriding item with its
`overrides` block. A protocol with no per-package layer is read as
before, so the existing CONTROL in
`packages-export-per-package-layer.test.ts` stays as it is.
One `@objectstack/runtime` patch changeset.
## Why
ADR-0146 D8 item 3: "`GET /packages/hotcrm.custom/export` carries the
overriding item with its `overrides` block; `GET
/packages/hotcrm/export` carries the base unchanged."
Measured red first on the real protocol and engine (new pin, before the
fix), per type:
- view: the base's export carried only the base's document (already
correct);
- dashboard: `expected [ 'Shipped label', 'Edited label' ] to deeply
equal [ 'Shipped label' ]`;
- report: `expected [ 'Shipped label', 'Edited label' ] to deeply equal
[ 'Shipped label' ]`.
Where the second item comes from, read off the registry in the same
harness: publishing the pair's row writes it through to the
SchemaRegistry's bare slot (`hydrateOverlayIntoRegistry` in
`packages/metadata-protocol/src/protocol.ts`). The artifact lookup there
falls back to the base's code artifact, because the pair ships no
artifact of that name, so the bare copy wears the base's envelope
(`_packageId` = the base, `_provenance: 'package'`). `listItems(type,
BASE)` then answers both the base's composite entry and that copy, and
the per-package layer lists both under the base. Views are spared by the
#22057 guard in the same hydrator, which is view-only by its own
comment.
The upstream (the hydrator lending a base's envelope to its pair's row)
is in `protocol.ts`, which is frozen until 2026-11-03 06:00Z and outside
this card's claim. It is reported in the card's os-dev-report as a
follow-up, with the minimal change named. This PR closes the export
contract at the door the card names.
**ADR-0146 D8 item 2, "the export of X's app surface":** read here as
the pair's export, the one that carries X's app surface as customized,
not as `GET /packages/X/export`. Item 3 names that route and gives it
the opposite rule, and `getMetaItemsPerPackage`'s docblock
(`protocol.ts`) and #28409 read it the same way. The ADR text is not
edited here (outside the claim); the report names the clarifying
sentence for the seat.
## Tests
- New
`packages/runtime/src/domains/packages-export-base-unchanged-per-type.integration.test.ts`:
the real door (`HttpDispatcher.handlePackages`) over the real
`ObjectStackProtocolImplementation` and `ObjectQL` on a SQLite file. The
base is a code package, the pair is installed through the package door,
each override goes through the draft save and the per-item publish. Per
type (view, dashboard, report): the effective read serves the override
(CONTROL), the base's export carries only the base's document with no
`overrides` block, and the pair's export carries the override with its
declaration.
- Ablation (fix committed first, mutation through
`scripts/ablation-replace.mjs`; the test reads `packages.ts` from
source, no dist in the path): deleting the filter line turned dashboard
and report red with the same two messages above, view stayed green;
restore proved `blob == HEAD` and `git diff HEAD` empty.
## Acceptance notes
- `studio-authoring.package-customize-restore-display` acceptance[4] is
a live-run checklist item; its record is not edited in this PR (outside
the claim). The seat can mark it once a live run reads the base export
clean.
## Verification
Head `e81217fe` (main merged at `1a95c746`; the 11 later `main` commits
touch none of this PR's files).
- `pnpm --filter @objectstack/runtime exec vitest run --project local
src/domains/packages-export…` (3 files): before the fix 2 failed | 1
passed (dashboard, report red); after, `Test Files 3 passed (3)`, `Tests
9 passed (9)`.
- `pnpm --filter @objectstack/runtime test` at `e81217fe`: `Test Files
526 passed (526)`, `Tests 8489 passed | 19 skipped (8508)`, lock
`VERDICT command-exit 0`.
- `pnpm --filter @objectstack/runtime typecheck` at `e81217fe`: exit 0
(tsc and `check:test-typecheck`; the new file is in the checked zone
with no ledger entry).
- `pnpm lint`: exit 0.
<details><summary>dispatch-gates --commands (60) and --ran
reconciliation</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derived 60 commands; 58 exit 0. The union
ran on `4a7b14f4`; the only later commit (`e81217fe`) deletes one unused
line in the new test file.
NOT MEASURED, exit 3 (prerequisite not met), CI runs both:
- `node scripts/check-plugin-teardown-shape.mjs --self-test`: its
fixture is pinned to a commit the shallow clone does not hold
(checker-health only).
- `pnpm check:dual-build-cjs-loads`: needs every package's `dist/`; only
the runtime closure was built here.
`dispatch-gates --ran`: "60 derived famil(ies) accounted for — 58 run, 2
NOT-MEASURED (2 DERIVED from a recorded exit 3)", exit 0.
</details>
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
(No `packages/spec` change.)
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes.
- [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: n/a.
- [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 (the 维护者速读 block is the
os-dev house format).
- [x] The *Before Submitting* list in CONTRIBUTING.md is done.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_01JQwxbXd7sSh6S5XDDEd7Ei
---
_Generated by [Claude
Code](https://claude.ai/code/session_01JQwxbXd7sSh6S5XDDEd7Ei)_
---------
Co-authored-by: Claude <noreply@anthropic.com>
1 parent e7d971d commit 81cd9eb
3 files changed
Lines changed: 248 additions & 0 deletions
File tree
- .changeset
- packages/runtime/src/domains
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 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 | + | |
| 41 | + | |
| 42 | + | |
| 43 | + | |
| 44 | + | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
| 50 | + | |
| 51 | + | |
| 52 | + | |
| 53 | + | |
| 54 | + | |
| 55 | + | |
| 56 | + | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
| 61 | + | |
| 62 | + | |
| 63 | + | |
| 64 | + | |
| 65 | + | |
| 66 | + | |
| 67 | + | |
| 68 | + | |
| 69 | + | |
| 70 | + | |
| 71 | + | |
| 72 | + | |
| 73 | + | |
| 74 | + | |
| 75 | + | |
| 76 | + | |
| 77 | + | |
| 78 | + | |
| 79 | + | |
| 80 | + | |
| 81 | + | |
| 82 | + | |
| 83 | + | |
| 84 | + | |
| 85 | + | |
| 86 | + | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
| 94 | + | |
| 95 | + | |
| 96 | + | |
| 97 | + | |
| 98 | + | |
| 99 | + | |
| 100 | + | |
| 101 | + | |
| 102 | + | |
| 103 | + | |
| 104 | + | |
| 105 | + | |
| 106 | + | |
| 107 | + | |
| 108 | + | |
| 109 | + | |
| 110 | + | |
| 111 | + | |
| 112 | + | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
| 129 | + | |
| 130 | + | |
| 131 | + | |
| 132 | + | |
| 133 | + | |
| 134 | + | |
| 135 | + | |
| 136 | + | |
| 137 | + | |
| 138 | + | |
| 139 | + | |
| 140 | + | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| 150 | + | |
| 151 | + | |
| 152 | + | |
| 153 | + | |
| 154 | + | |
| 155 | + | |
| 156 | + | |
| 157 | + | |
| 158 | + | |
| 159 | + | |
| 160 | + | |
| 161 | + | |
| 162 | + | |
| 163 | + | |
| 164 | + | |
| 165 | + | |
| 166 | + | |
| 167 | + | |
| 168 | + | |
| 169 | + | |
| 170 | + | |
| 171 | + | |
| 172 | + | |
| 173 | + | |
| 174 | + | |
| 175 | + | |
| 176 | + | |
| 177 | + | |
| 178 | + | |
| 179 | + | |
| 180 | + | |
| 181 | + | |
| 182 | + | |
| 183 | + | |
| 184 | + | |
| 185 | + | |
| 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 | + | |
| 215 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
3331 | 3331 | | |
3332 | 3332 | | |
3333 | 3333 | | |
| 3334 | + | |
| 3335 | + | |
| 3336 | + | |
| 3337 | + | |
| 3338 | + | |
| 3339 | + | |
| 3340 | + | |
| 3341 | + | |
| 3342 | + | |
| 3343 | + | |
| 3344 | + | |
3334 | 3345 | | |
3335 | 3346 | | |
3336 | 3347 | | |
| |||
3377 | 3388 | | |
3378 | 3389 | | |
3379 | 3390 | | |
| 3391 | + | |
3380 | 3392 | | |
3381 | 3393 | | |
3382 | 3394 | | |
| |||
3398 | 3410 | | |
3399 | 3411 | | |
3400 | 3412 | | |
| 3413 | + | |
| 3414 | + | |
| 3415 | + | |
| 3416 | + | |
| 3417 | + | |
| 3418 | + | |
| 3419 | + | |
| 3420 | + | |
| 3421 | + | |
| 3422 | + | |
| 3423 | + | |
3401 | 3424 | | |
3402 | 3425 | | |
3403 | 3426 | | |
| |||
0 commit comments