Skip to content

Package disable and uninstall never reach the metadata/data layer: a disabled package's objects still serve rows, and uninstall leaves 7 orphaned sys_metadata rows #7557

Description

@huangyiirene

Blocked-by: #7705

> Status 2026-08-11 (engine-core seat): half (A) and the envelope part of half (B) LANDED via PR #7700 (8f1851ea7). What remains open on this card is the persistence half of (B) only, transferred to the metadata lane as #7705. This card closes when #7705 lands. See the ACCEPT comment below for the full verification record.

Two halves of one gap: a package lifecycle operation moves the registry/UI surfaces but never propagates to the metadata store or the data plane. Filed as one card because both are the same missing propagation, on the two operations that need it.

Symptom

(A) Disable is not an enforcement for objects.FIXED by PR #7700. With the owning package at status:'disabled':

  • GET /api/v1/data/<object> still answers 200 with all rows. → now 404 OBJECT_PACKAGE_DISABLED
  • /meta/objects still lists the object. → now dropped from the listing
  • Nav and views are correctly dropped — so disable is honoured on some surfaces and not others.
  • The console renders the live list too, so this is not an API-only artefact.

Reproduced over two disable/enable cycles.

Expected: a disabled package's objects are dropped from the metadata registry and refuse on the data plane, consistently with the nav/view surfaces that already honour the status.

(B) Uninstall leaves orphaned metadata. ⚠️ HALF fixed. DELETE /packages/:id answers 200, with:

persisted: { success: false, deletedCount: 0 }

The package disappears from /packages, but 7 sys_metadata rows survive and /meta/* keeps serving them. Reproduced with a second, single-view package.

Expected: either the persisted delete succeeds and the metadata rows go with the package, or the failed persistence is reported as a failure instead of being wrapped in a 200.

Honest negative, recorded so nobody re-derives it: disable destroys no data — 3 rows before, during and after the disabled window. Now pinned by packages/objectql/src/package-disable-enforcement.test.ts.

Root cause

Not located by the report beyond the symptoms above. Two facts it does pin down:

  • The persisted:{success:false,deletedCount:0} envelope means the delete's own persistence step reported failure and the route answered 200 anyway — the status code and the payload disagree.
  • Disable is enforced at the nav/view layer but not at the registry or data layer, so the status is consulted in some readers and not others rather than being missing entirely.

Filed domain:engine-core because the surviving surfaces are registry-backed reads; re-route if the fix lands in the /packages route layer (packages/rest) or in the metadata repository instead.

> Measured answer to that last sentence: the disable asymmetry was listItems' early return for object/objects (registry.ts) plus the same exemption in getMetaItems (protocol.ts) — engine-core, as filed. The envelope was packages/runtime (cli lane, declared on #6024). The persistence is packages/metadata-protocol (#7705).

Related

Reproduction

(A)

  1. Install a package that ships an object with rows.
  2. PATCH the package to status:'disabled'.
  3. GET /api/v1/data/<object> → 200, all rows. GET /meta/objects → object still listed. Nav and views → correctly gone.
  4. Re-enable and repeat — reproduced over two cycles. Row count is 3 before, during and after.

(B)

  1. Install a package (repeated with a second, single-view package).
  2. DELETE /packages/:id → 200 with persisted:{success:false,deletedCount:0}.
  3. GET /packages → gone. Query sys_metadata → 7 rows survive. GET /meta/* → still serving them.

Source

Extracted from the QA run #7514 (framework a86db17, console 09987b68).

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions