Skip to content

The route-level seed apply cannot consume the shipping protocol's own read-back envelope: _packageId / _diagnostics survive the unwrap and SeedLoaderRequestSchema rejects them as unrecognized_keys #15591

Description

@os-litant

Filed unassigned and unlabelled by the domain:cli execution seat while working #15068 — grading and domain:* are triage's to produce. ⛔ Not fixed there: a different defect class (provenance keys surviving an unwrap, not org read scope), so it was left alone rather than folded in as a rider.

The site

packages/runtime/src/domains/packages.ts, applyPublishedSeeds — the route-level seed apply behind POST /packages/:id/publish-drafts. Locate by content, not by line: the surrounding function moved 119 lines while #15068 was open.

It reads each just-published seed body back through protocol.getMetaItem, unwraps the envelope, and hands the result to SeedLoaderRequestSchema.safeParse:

const seed = item?.object && Array.isArray(item?.records)
    ? item
    : (item?.item ?? item?.metadata ?? item?.body);
...
const parsedRequest = SeedLoaderRequestSchema.safeParse({ seeds: datasets, config: { ... } });
if (!parsedRequest.success) throw seedRequestValidationError(parsedRequest.error.issues);

What was measured

Driven for real on a #15068 branch: a state:'draft' seed row promoted by the shipping publishPackageDrafts on a real ObjectStackProtocolImplementation, then read back through that same protocol. The wrapper getMetaItem answers is

{"type":"seed","name":"project_seed","lock":"none","packageId":"com.workspace","editable":true,
 "item":{"object":"project","externalId":"name","mode":"upsert","records":[...],
         "_packageId":"com.workspace","_diagnostics":{"valid":true}}}

.item is the branch the unwrap takes, and the two underscore keys are inside it — added by decorateMetadataItem (packages/metadata-protocol/src/metadata-diagnostics.ts), which runs on every read exit and appends _diagnostics whenever a schema is registered for the type. SeedLoaderRequestSchema is closed, so the parse fails and the route answers, on a 200, as data:

[handlePackages] seed apply failed: [invalid_metadata] the published seed bodies failed spec validation: 1 issue — seeds.0 [unrecognized_keys]

⇒ zero rows load, and the author is told their seed body is malformed when nothing about it is.

Why it has stayed invisible

Two independent reasons, and they compose:

  1. The shipping protocol self-applies. publishPackageDrafts reports seedApplied itself, and the route runs its fallback only when that field is absent ("never run both, or an externalId-less seed would double-insert"). So the shipping composition never reaches this parse.
  2. The existing coverage doubles the read. packages/runtime/src/domains/packages-seed-apply-disclosure.test.ts builds its protocol with getMetaItem: vi.fn(...) returning a hand-written wrapper with no decoration — a body the schema accepts. Its section 0 positive control is green precisely because the decoration is not there.

⇒ The fallback is exercised only against undecorated doubles, and would be reached in production only by a custom protocol that does not self-apply. Whether such a protocol decorates is the open question below.

What is not settled here

  • Is the fallback still live at all? If no supported composition can reach it, the honest fix may be to delete it rather than to strip keys — and that is a decision, not an implementation detail.
  • If it is live, where does the strip belong? applyPublishedSeeds already owns a provenance-stripping helper for its export path (PROVENANCE_KEYS, same file), so the shape exists; but stripping at the consumer is the tolerant-reader move this repo's contract-first rule pushes back on, and the alternative is that the seed apply should read a body that was never decorated.
  • ⚠️ Underscore keys are not one population: _packageId is provenance the export path already knows to drop, while _diagnostics is a computed badge. A blanket startsWith('_') strip would be a guess about both.

Refs

Activity

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions