Skip to content

packages: a published dashboard or report override removes the item from the base's export, where ADR-0146 D8 item 3 says the base export is unchanged #29649

Closed

Description

@objectstack-fleet

epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848

Filing gate: ④ child of epic #28236, filed on the maintainer's word in direct chat with the epic PM seat, 2026-11-03: 「发记录并立卡」 and 「相关卡 p1, 让车道处理」. ⛔ Not a claim.
QA-source: #29648 · studio-authoring.package-customize-restore-display · acceptance[4]
Part of #28236 · governs: ADR-0146 D8 item 3
Reader: domain:server (the export read in packages/runtime).
Dedupe (open and closed): base export, export override, declaresOverrideOf. #29563 (closed, the earlier symptom) and #29600 (open, the registry cause) are the nearest. Neither says the item goes missing. New.
reach: any read-only base whose .custom pair has published a dashboard or report override.
type: Bug

Business reason. A customer who exports their base after customizing it gets a package with items missing. That export cannot be redeployed as the vendor's package, and nothing warns them.

What happens

Measured on main at 322cf9068f, on a real showcase boot, before and after a restart.

type item base export before base export with a published override
dashboard showcase_ops_dashboard 3 items 2 items: absent
report showcase_hours_by_status 4 items 3 items: absent
view showcase_task.in_progress 36 items 36 items, byte-identical

D8 item 3: GET /packages/hotcrm.custom/export "carries the overriding item with its overrides block; GET /packages/hotcrm/export carries the base unchanged". Removing the override brings the item back.

Reproduce

  1. On a fresh showcase, GET /api/v1/packages/com.example.showcase/export: dashboards[] holds showcase_ops_dashboard.
  2. POST /api/v1/packages/com.example.showcase/ensure-customization; PUT /api/v1/meta/dashboard/showcase_ops_dashboard?mode=draft&package=com.example.showcase.custom with the item and overrides: {package:'com.example.showcase', basedOn:'0.1.0'}; POST /api/v1/packages/com.example.showcase.custom/publish-drafts.
  3. Repeat step 1's read. Expected: the item byte-identical to step 1, no overrides key. Actual: absent.

Why (read from source, the dev confirms)

PR #29597 added items.filter((it) => !declaresOverrideOf(it, packageId)) at packages/runtime/src/domains/packages.ts:3423. It assumes the per-package layer holds both documents. On this boot the layer holds no base document for that name, so the filter leaves nothing. #29600 measured the override registered in the bare slot wearing the base's envelope.

PR #29597's pin stays green while this fails: packages-export-base-unchanged-per-type.integration.test.ts registers its base so that the layer lists both documents.

Wanted

  • GET /packages/BASE/export carries the base's own document for every type while an override is live, byte-identical to the export without it.
  • A pin that fails on today's behaviour: drive a base booted as the showcase is, and assert the item is present and equal, not only that no overrides key appears.
  • The re-run of studio-authoring.package-customize-restore-display acceptance[4] passes on a real boot.

Serial: #29600 is in flight in the same area (os-steve), and it may remove the cause. Read its branch first, and say on this card whether it closes this one. Do not hand this card over to #29600 without measuring it on a real boot.

Links back: #29648, #29563, #29600, PR #29597, #28236, ADR-0146 D8.

Activity

  1. added
    bugSomething isn't working
    priority:p1High: required for production / M2
    area:studioChanging a running app without code — authoring, publish, docs and the portal
    domain:serverDomain lane — seat card indexed by label:pm:seat
    on Nov 2, 2026
  2. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

    Claim: PM loop round 9 · 2026-11-03T00:03Z
    Session: session_01JQwxbacSXJQqAztgt4UMrS (seat); dev = card thread session_01JQwxbac7S1AsbGi5a46PrB
    Account: os-warren
    Branch: claude/project-thread-56mldo (a project card thread pushes only its assigned branch; measured platform exception to claude/issue-<n>-<slug>)
    Worktree: objectstack-issue-29649
    Domain: domain:server
    Seat: domain:server#4
    File surface: the base-export assembly in packages/runtime/src/domains/packages.ts (assemblePackageManifest, declaresOverrideOf) and its integration pins; tests, changesets (stop on breach; explain in the report). ⛔ No packages/spec/**; no packages/metadata-protocol/src/protocol.ts (freeze until 2026-11-03 06:00Z); the registry slot (#29600's cause) is out of scope, stop and report if the fix needs it.
    Container & model: M, mode:thread (the os-dev agent type is not loaded in seat sessions), model: TIER_DEFAULT, effort: project default (the maintainer sets effort)
    Clause-②: no
    Metadata-protocol: none
    Responsibility: own regression — PR #29597 (#29563), landed by this seat
    Thread-read: none
    Premise: measured by the filer on main 322cf9068f (real showcase boot); dev reproduces red per type first and measures whether #29600 would close it
    Serial constraints: #29600 (open, pm:queue, the registry cause) — not a blocker; this card's fix stays in the export read

  3. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#5 · os-warren · session_01JQwxbZUR3xvHyDPCjNL5P4

    Serial note · 2026-11-03T00:31Z

    From domain:server#5, answering seat 4's mailbox note 6591910232. PR #29640 (#29600) merged 2026-11-03T00:13:00Z as 7dae3b3c0d. Its diff does not touch packages/runtime/src/domains/packages.ts; it changes packages/metadata-protocol/src/protocol-package-bindings.ts, protocol.ts, two objectql tests and a changeset. Whether it closes this card is for this card's measurement on origin/main at or after 7dae3b3c; seat 5 holds no claim on packages.ts.

  4. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbac7S1AsbGi5a46PrB
    os-dev-report

    {
      "issue": 29649,
      "status": "done",
      "branch": "claude/project-thread-56mldo",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/29687",
      "pr_state": "draft",
      "head": "51c4d1ee",
      "session": "session_01JQwxbac7S1AsbGi5a46PrB",
      "premise_still_valid": true,
      "summary": "Premise measured true on a real showcase boot at b391feb1: a published dashboard or report override left the base export without the item (dashboards 3 to 2, reports 4 to 3, views 36 to 36 equal). Cause: the per-package layer merges the registry's items over the metadata service's, one per (name, package) slot, so the override copy in the registry bare slot (wearing the base's envelope) takes the base's slot and the #29563 filter leaves nothing; the #29597 pin has no metadata service, so its layer listed both. #29600 (PR #29640, merged as 7dae3b3c during this card) closes the dashboard and report rows on its own, measured on a real boot, but NOT the card: on 7dae3b3c a published page, app, dataset, doc or book override still drops the item (pages 29 to 28, apps 1 to 0, datasets 4 to 3, docs 8 to 7, books 1 to 0). Fix stays in the export read: assemblePackageManifest replaces an item declaring an override of the exported package by the package's own code artifact (registry.getArtifactItem prefer-local, kept only when its _packageId is the package's and it declares no override), in place, when the layer lists no own item of the name. With it, all eight types are equal and the whole base export is byte-identical on a real boot (7dae3b3c), and after a restart (b391feb1, persistent OS_HOME). No protocol.ts, no registry slot, no packages/spec.",
      "files_changed": [
        "packages/runtime/src/domains/packages.ts (ownDocumentsOf + call site comment)",
        "packages/runtime/src/domains/packages-export-base-showcase-boot.integration.test.ts (new pin, 8 types)",
        ".changeset/29649-base-export-keeps-overridden-items.md (patch @objectstack/runtime)"
      ],
      "tests": "New pin (real HttpDispatcher, protocol, ObjectQL on SQLite, real MetadataManager stamped as MetadataPlugin's artifact door stores the base): asserts presence, equality and a byte-identical whole base export before/after the published override and after a restart. Red first: 3-type version on b391feb1 without the fix, dashboard and report red ('expected [] to deeply equal' the shipped item), view green; 8-type version on 7dae3b3c without the fix, page/app/dataset/doc/book red, the other three green; with the fix 8/8. Neighbours green: packages-export-base-unchanged-per-type, packages-export-override-declaration, packages-export-per-package-layer. pnpm --filter @objectstack/runtime test exit 0 on e373cc16: Test Files 530 passed (530), Tests 8520 passed, 19 skipped (lock VERDICT command-exit 0, 870 s). Runtime typecheck exit 0 on 51c4d1ee. Live repro script per tree in the PR's Tests table.",
      "gates": "Head 51c4d1ee: dispatch-gates --commands derived 59; 58 exit 0; NOT MEASURED exit 3: node scripts/check-plugin-teardown-shape.mjs --self-test (positive control pinned to a commit the shallow clone cannot reach). --ran: '59 derived famil(ies) accounted for, 58 run, 1 NOT-MEASURED'. Earlier union on e373cc16 caught check:query-options-erasure exit 1 (the pin's as-any driver query, test surface 236 to 237), fixed in 51c4d1ee, exit 0 at 236. pnpm lint exit 0 (e373cc16; the later commit only removes an as-any in the pin). CI check-runs: in_progress at report time.",
      "dogfood_battery": "n/a: no '!' in the PR title and no (narrowing) arm",
      "mcp_calls": "0",
      "api_writes": "2: fleet-write relay pr_create (PR #29687, 7658 bytes sent and stored, identical); post-stamped os-dev-report comment on #29649 (this one). Plus git push (not REST).",
      "open_questions": [],
      "security_findings": "withheld",
      "out_of_scope_findings": [
        "class: a · reach: GET /api/v1/meta/page/showcase_start_here (with or without ?package=com.example.showcase) on a real showcase boot at 7dae3b3c answers the shipped label after a published .custom override; same for app, dataset, doc, book; the pair's export lists none of them · evidence: live repro in this card thread; the pin's control records it (pairServed false); #29613 measured getMetaItem serving these overrides from the bare slot on a harness with no metadata service, and on a real boot the metadata service copy wins · carrier: #29613 (its row-served path, item 1), noted for the seat to add there, not filed · dedupe words: override not served metadata service page, real boot effective read override, pair export empty page"
      ],
      "deviations": "Commit messages carry no card trailer (pre-push check refused 'Refs #29649' once; reworded before any push). origin/main merged into the branch once (7dae3b3c) to measure #29640; origin/main has since moved to 744211fc (spec only), not merged."
    }
  5. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    domain:server#4 · os-warren · session_01JQwxbacSXJQqAztgt4UMrS

    Landing record · #29649 · PR #29687 · 2026-11-03T02:13Z

    Reading Probe Result
    Queue membership git ls-remote origin 'refs/heads/gh-readonly-queue/main/pr-29687-*' 0 refs (released)
    Ancestry git merge-base --is-ancestor 33ee9aa1 origin/main yes
    Content git grep -c ownDocumentsOf origin/main -- packages/runtime/src/domains/packages.ts 2

    Release: claim 6591700109 (session_01JQwxbacSXJQqAztgt4UMrS, card thread session_01JQwxbac7S1AsbGi5a46PrB, branch claude/project-thread-56mldo) · full landing
    Produce: PR #29687 merged as 33ee9aa1 at 2026-11-03T02:12Z. The base package's export now keeps an item that a later package overrides: ownDocumentsOf swaps the override copy back for the base's own artifact item, for all eight overridable types (dashboard, report, page, app, dataset, doc, book, and the rest of the list), pinned on a real showcase-style boot with the metadata service registered. #29640 had closed only dashboard and report. ACCEPT on the PR. Fixes #29649 closed this card as completed.

  6. added a commit that references this issue on Nov 3, 2026
  7. objectstack-fleet commented on Nov 3, 2026

    @objectstack-fleet
    ContributorAuthor

    epic:#28130#1 · hotlong · session_040dfd80c4c9411b895c698e785a6848
    2026-11-03T02:52Z

    Re-measured live on main at c9636f1e50, on a real showcase boot: with published overrides of showcase_ops_dashboard and showcase_hours_by_status, the base export keeps dashboards 3 → 3 and reports 4 → 4, each item byte-identical to the export without the override and with no overrides key. Removing them returns the export to baseline. studio-authoring.package-customize-restore-display acceptance[4] passes for both. The view leg was not repeated; it passed at 322cf9068f.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

area:studioChanging a running app without code — authoring, publish, docs and the portalbugSomething isn't workingdomain:serverDomain lane — seat card indexed by label:pm:seatpriority:p1High: required for production / M2

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions