Repository navigation
fix(runtime): the base export serves the base's own document while a .custom override of it is live - #29687
Conversation
….custom override of it is live On a showcase-shaped boot the per-package layer lists only the override copy under the base's name (the metadata service holds the base's code documents too), so the override filter dropped the item from the base's export. Serve the base's code artifact in its place, and pin it on that boot shape. Claude-Session: https://claude.ai/code/session_01JQwxbac7S1AsbGi5a46PrB Co-authored-by: Claude <noreply@anthropic.com>
…ill holds in its bare slot On a showcase-shaped boot a published page, app, dataset, doc or book override still drops the item from the base export after the dashboard and report copies left the bare slot; the export-read fix covers them too. Claude-Session: https://claude.ai/code/session_01JQwxbac7S1AsbGi5a46PrB Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JQwxbac7S1AsbGi5a46PrB Co-authored-by: Claude <noreply@anthropic.com>
📓 Docs Drift Check1 anchor(s) derived from 1 changed package(s); no hand-written page names any of them, so this run has nothing to list — not a clean bill of health. This check sees only pages that NAME a derived anchor: one that documents this change in prose, or enumerates it in an authoring dialect, names none and stays invisible to it on every run. What this run could not see
Coarse fallback — 28 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 00c305e59e9bd1e3f5f0afa3bcaf206a8b0dac11 && git checkout 00c305e59e9bd1e3f5f0afa3bcaf206a8b0dac11
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin ece5faacbe5ebf3cad45114aff5f0b2f440f5cb1 51c4d1ee1a2c63e76a61ddf1b6176ad6166a112c && git checkout -B drift-repro ece5faacbe5ebf3cad45114aff5f0b2f440f5cb1 && git merge --no-ff 51c4d1ee1a2c63e76a61ddf1b6176ad6166a112c
node scripts/docs-audit/affected-docs.mjs --json ece5faacbe5ebf3cad45114aff5f0b2f440f5cb1 |
|
domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS 席位核对ACCEPT ·
|
Requested by Warren · project thread
Fixes #29649
Clause-②: no
Metadata-protocol: none
维护者速读
GET /packages/BASE/export在.custom覆盖已发布时,改为输出基础包自己的那份文档(原样),不再把该项丢掉。packages.ts这一处。packages/runtime/src/domains/packages.ts(ownDocumentsOf)、新 pinpackages-export-base-showcase-boot.integration.test.ts。pnpm --filter @objectstack/runtime exec vitest run src/domains/packages-export-base-showcase-boot.integration.test.ts,预期 8/8 通过。What changes
assemblePackageManifest(packages/runtime/src/domains/packages.ts): the per-package layer's items now go throughownDocumentsOf. An item that declares it overrides the exported package (the pair's override) is still never exported under the base, as packages: the base export carries a published dashboard or report override from its .custom pair, where ADR-0146 D8 item 3 says the base export is unchanged #29563 ruled, but it is now replaced, in its place, by the base's own code artifact of the name (registry.getArtifactItem(type, name, BASE), the prefer-local composite slotregisterAppfilled) when the layer lists no own item beside it. Before, it was only dropped, which left the item out when the layer held the override alone.packages/runtime/src/domains/packages-export-base-showcase-boot.integration.test.ts: the packages: the base export carries a published dashboard or report override from its .custom pair, where ADR-0146 D8 item 3 says the base export is unchanged #29563 harness (realHttpDispatcher, protocol,ObjectQLon SQLite) plus the realMetadataManagerholding the base's code documents asMetadataPlugin's artifact door stores them, which is the shape everydefineStackhost boots with. Per type (view, dashboard, report, page, app, dataset, doc, book) it asserts the base's whole export is byte-identical before and after the published override, and after a restart over the same database; the item is present and equal; no item carriesoverrides; the pair's row is published; and for view, dashboard and report the effective read and the pair's export serve the override.@objectstack/runtime.Why
ADR-0146 D8 item 3:
GET /packages/hotcrm/export"carries the base unchanged". The per-package layer merges the registry's items over the metadata service's, one per(name, package)slot. A published.customoverride registered in the registry's bare slot wearing the base's envelope therefore takes the base's slot, and the base's own item is not listed at all. The #29563 filter then left nothing. The #29563 pin stayed green because its boot has no metadata service, so the layer listed both documents.#29600 (PR #29640, merged as 7dae3b3 while this card ran) takes the dashboard, report and email_template copy out of the bare slot, which closes this card's dashboard and report rows on its own. It deliberately leaves page, app, dataset, doc and book in the bare slot (#29613), and for those five the base export still loses the item. This fix holds the D8 item 3 guarantee for every type at the export door, whatever the registry holds.
Tests
Measured on a real showcase boot (
pnpm --filter @objectstack/example-showcase dev -- --fresh), with the card's reproduction (ensure-customization, draft PUT withoverrides,publish-drafts), counting items inGET /api/v1/packages/com.example.showcase/export:Pin, red first: on b391feb (pin alone) dashboard and report red ("expected [] to deeply equal" the shipped item), view green; on 7dae3b3 (pin alone) page, app, dataset, doc and book red the same way, the other three green; with the fix 8/8 green. The export-read neighbours stay green:
packages-export-base-unchanged-per-type.integration.test.ts,packages-export-override-declaration.test.ts,packages-export-per-package-layer.test.ts(4 files, 12/12 before the pin grew to 8 types).Acceptance notes
GET /api/v1/meta/page/showcase_start_here(with or without?package=com.example.showcase) answers the shipped label, and the pair's export lists none of them. metadata-protocol: page, app, dataset, doc and book serve a published override only from the registry bare slot; build the row-served path, then take them out of it #29613 measuredgetMetaItemserving these overrides from the bare slot on a harness with no metadata service; on a real boot the metadata service's copy wins. This is metadata-protocol: page, app, dataset, doc and book serve a published override only from the registry bare slot; build the row-served path, then take them out of it #29613's row-served path, reported there, not touched here.studio-authoring.package-customize-restore-displayacceptance[4] re-run belongs to the QA seat; the card's own reproduction passes on a real boot (table above).Verification
Local gates
Head 51c4d1e (origin/main 7dae3b3 merged in).
node scripts/pm/dispatch-gates.mjs --commandsderived 59 families; each run with its exit code captured before any pipe, then--ran:node scripts/check-plugin-teardown-shape.mjs --self-test, its positive control is pinned to a commit this shallow clone cannot reach.--ranreconciliation: "59 derived famil(ies) accounted for, 58 run, 1 NOT-MEASURED".check:query-options-erasure(exit 1, the pin'sas anydriver query grew the test surface 236 → 237); fixed in 51c4d1e, now exit 0 at 236.Outside the derivation, also run:
pnpm lintexit 0 (e373cc1; the later commit only drops anas anyin the pin);pnpm --filter @objectstack/runtime typecheckexit 0 (51c4d1e);pnpm --filter @objectstack/runtime testexit 0 on e373cc1, Test Files 530 passed (530), Tests 8520 passed, 19 skipped; the new pin alone 8/8 on 51c4d1e.Human Minimum
packages/specholds no runtime logic.pnpm lintpasses.main, one pull request.packages/spectouched: not touched.content/docs/references/,packages/*/CHANGELOG.mdorcontent/docs/releases/.Generated by Claude Code