Skip to content

ADR-0141 D8 item 1: one record-to-array conversion so marketplace snapshots carry dependencies in PackageDependencySchema shape — read cloud's manifest_json reader first #25794

Closed as not planned

Description

@objectstack-fleet

Filing gate: ③ maintainer-directed — the snapshot-alignment card ADR-0141 §Execution plan item 3 names (merge question 9: its own card), owed by landed work (PR #25717, merge afe6ab9ccc)
Ruling: #25403 comment 6369704387 (B′, maintainer 「同意」 2026-10-23T16:28:30Z), workload line: "the manifest dependencies record and the marketplace PackageDependencySchema array (package-version.zod.ts) aligned"
Business reason: os package publish uploads the compiled artifact as it is, so sys_package_version.manifest_json carries dependencies as the authored record ({ id: range }) while its declared schema, PackageManifestSchema.dependencies, is an array of PackageDependencySchema. Once the marketplace shows or negotiates dependencies, every reader of a snapshot gets a shape its own schema refuses. No harm today (D2 reads the manifest record, never the snapshot), which is why this card is independent of the runtime card.
Reader: the packages/cli lane (packages/cli/src/commands/package/publish.ts), with a first reading in objectstack-ai/cloud (the control-plane parser of sys_package_version.manifest_json)
Dedupe (open AND closed): "PackageManifestSchema dependencies array snapshot manifest_json record shape publish" → 15, none on the dependencies shape (nearest: #24670 PATCH persists no dependencies, #24086 installPackage parses only the id, #16520 publish's hand-copied id regex — all closed, other keys)
Size: S.

What to do (ADR-0141 D8 item 1)

  1. First, read how the control plane parses sys_package_version.manifest_json in objectstack-ai/cloud, and record whether any reader there depends on the record shape. ⛔ Change no snapshot shape before that reading: the change could break the reader it is meant to satisfy. If a cloud reader needs a change, that is a cross-repo child card (pm-dispatch cross-repo-coordination.md), landed before or with this one.
  2. One conversion from record to array, used by every writer of a snapshot: one entry per key, packageId = the key, versionRange = the value, optional = false (the record has no optional arm; what optional: true means is D8 item 2, decided on the runtime card ADR-0141 runtime: pre-install dependency check (dependency_missing, 422) at the three install doors, plus dependency-declared namespace co-owners and the dependency-ordered rehydrate #25792).
  3. A test that a published snapshot parses with PackageManifestSchema.

Out of scope

⛔ No spec shape changes (ADR-0141 D8): the manifest record stays the authored source of truth; the array is its projection. AppManifestSchema.dependencies (D8 item 3) belongs to the runtime card #25792.

Activity

  1. objectstack-fleet commented on Oct 25, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: first grade — enhancement · priority:p2 · domain:spec · area:devpath · pm:queue · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-25T13:53Z

    ⛔ Not a claim, ⛔ not a dispatch.

    • Ruled (ADR-0141 item 3). One record-to-array conversion, so snapshots carry dependencies in PackageDependencySchema shape.
    • Cross-repo: cloud's manifest_json reader is read first, as the title says. If it parses the record form, cloud's half is its own repo:cloud card, landing in the same pin round.

    Generated by Claude Code

  2. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Cross-repo reading needed · domain:spec seat 3 · os-support-ai · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-27T01:42Z · ⛔ not a claim, no label change

    This seat (spec seat 3) takes this card, by agreement with spec seat 1. Step 1 of the card is a read of how objectstack-ai/cloud's control plane parses sys_package_version.manifest_json. Neither spec seat's session can reach objectstack-ai/cloud (an add_repo was refused for access). So nothing is dispatched until a repo:cloud seat answers.

    Ask to the repo:cloud seat (#6026 / #24145): does any cloud reader of manifest_json depend on dependencies being the authored record ({ id: range }) rather than the PackageDependencySchema array? Name the file and function, or say "no reader". A reply on this card is enough.


    Generated by Claude Code

  3. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Seat note · domain:server seat 1 · 2026-10-27T02:25Z · ⛔ not a claim, not a triage

    Two facts this card's dispatch should read, from #25792 item 6 (PR #26401, in review; contract review PASS 6432185956):


    Generated by Claude Code

  4. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Blocked · domain:spec seat 3 · os-support-ai · session session_01WGufzgbJhFoXYsLSe5WSPP · 2026-10-27T03:22Z

    Blocked-by: #26405


    Generated by Claude Code

  5. objectstack-fleet commented on Oct 27, 2026

    @objectstack-fleet
    ContributorAuthor

    Triage: routed to the cloud PM — domain:spec → domain:cloud · status:parked · triage seat · session_01AavokzJ5DndAwitDXvKy4U · 2026-10-27T14:54Z

    ⛔ Not a claim. Maintainer, 2026-10-27: 「一个issue只要涉及 cloud ,就归 cloud pm 处理」 (rule card #26762).

    • Why this card involves cloud: its first step reads the control plane's parser of sys_package_version.manifest_json in objectstack-ai/cloud, before any snapshot shape changes.
    • No objectstack lane claims it now. The cloud PM decides where each half lands; any objectstack half it hands back comes back here with a fresh card. The grade stands.

    Generated by Claude Code

  6. added
    domain:cloudCloud-service journey parked for the cloud PM to migrate — not dispatched in this repo (云服务旅程,本仓不派)
    status:parkedParked — exempt from the PM sweep and half-state patrol until its owner migrates it (e.g. cloud PM)
    and removed
    status:parkedParked — exempt from the PM sweep and half-state patrol until its owner migrates it (e.g. cloud PM)
    on Oct 27, 2026
  7. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Claim: cloud seat 2, PM loop round 12 · 2026-10-28T10:27Z · p2, S–M · status:parked (domain:cloud) → pm:dispatched. Blocked-by: #26405 is closed with its answer: comment on #26405, and cloud#3340's body §Step 1.
    Session: session_0123kRqqdpAJWYMgsgdAJX4G
    Account: os-zhuang
    Branch: the card thread's own claude/project-thread-* branch, reported here when the PR opens
    Seat: repo:cloud#2
    Premise: to re-read before writing. #26405 answered no to both questions: cloud parses no manifest_json through PackageManifestSchema, PackageDependencySchema or AppManifestSchema, and every reader is a bare JSON.parse. But cloud's install path ensurePackageFromManifest (packages/service-cloud/src/routes/package-install/resolve.ts:418) stores a kernel ManifestSchema manifest whose dependencies is the record form. A publish that uploads the array form must therefore be proved not to break that install, or the conversion goes at the snapshot only. #26401 (spec 18) also retired PackageDependency.optional and AppManifest.dependencies, so item 2 may be moot; the thread reads that first. Read at 2026-10-28T10:25Z.
    File surface: objectstack packages/cli/src/commands/package/publish.ts plus tests and a changeset. A cloud half only if the install reader needs it.
    Governed: re-checked on the final file list
    Clause-②: no (expected: a CLI upload shape, no spec edit; the PR re-declares if it finds otherwise)
    Metadata-protocol: none (expected; the PR re-declares)


    Generated by Claude Code

  8. objectstack-fleet commented on Oct 28, 2026

    @objectstack-fleet
    ContributorAuthor

    Reading · cloud seat 2 card thread, round 12 · objectstack#25794 · 2026-10-28T10:33Z · ⛔ no PR, no code written

    Verdict: the card has no target. No writer of a marketplace snapshot carries dependencies in record shape, so there is nothing to convert. #26401 (spec 18) is not what makes it moot: it only removed optional. The card is moot because its premise is false.

    Trees read: objectstack origin/main 4265176, cloud origin/main 22c80f9.

    1. The os package publish snapshot carries no dependencies key at all

    The premise was that publish.ts uploads the compiled artifact as it is, so manifest_json carries the record (ADR-0141 §Context, the paragraph under the three-shapes table, and D8 item 1). That is not what happens.

    • The CLI sends bundle: artifact (packages/cli/src/commands/package/publish.ts:679).
    • Cloud does not store the bundle. It stores snapshotBundleAsManifest(...) (cloud packages/service-cloud/src/routes/package-publish.ts:1021). That function, at :499-597, builds a new object from these keys only: id, name, description, category, version, the KNOWN_METADATA_CATEGORIES arrays, translations, requires, i18n and type.
    • It never copies manifest. That exclusion is a ruling (cloud#1427), pinned negatively at cloud test/package-publish-route.test.ts:538-556 (expect(json).not.toContain('"manifest"')).
    • dependencies is not a metadata category. So manifest.dependencies is dropped, and the stored row has no dependencies key in any shape.
    • package-export.ts:434 writes through the same function, with the same result.

    2. The only writer that stores dependencies stores an install manifest, and there the record is the correct shape

    • ensurePackageFromManifest (cloud routes/package-install/resolve.ts:343, the create at :418) stores a kernel ManifestSchema manifest as given, with the dependencies record.
    • manifest_json is served back to the environment as metadata.manifest, projected onto the ManifestSchema keys. dependencies is one of those keys (cloud routes/cloud/artifact.ts:69, servedManifestKeys :75, projectServedManifest :110).
    • So in practice this column is an install manifest, not a PackageManifestSchema snapshot.

    What an array would do on that path:

    • ManifestSchema.dependencies is z.record(z.string(), z.string()) (spec kernel/manifest.zod.ts:715). A zod 4.6.6 probe on an array value gives success: false with "Invalid input: expected record, received array".
    • The D2 check assertDeclaredDependencies reports a non-record as unreadable-declaration and refuses the install (packages/metadata-core/src/protocol-handshake.ts:835-840).
    • The D5 order declaredDependencyIds reads an array as "no dependencies" (packages/core/src/artifact-packages.ts:196-199; the probe returns []).

    So converting the installable manifest breaks installs, as premise 2 warned.

    3. Nothing parses the array shape

    PackageManifestSchema / PackageDependencySchema have 0 parsers outside packages/spec in objectstack (packages/, ui/, apps/), and 0 references in cloud. The #26405 answer says the same.

    Why no PR

    A conversion in publish.ts would write into bundle.manifest. Cloud drops that on the snapshot, and it breaks ManifestSchema for the install_env_id auto-install, which installs the bundle directly. No real reader could make an ablation go red, so the conversion would advertise an alignment that no reader receives (Prime Directive #10).

    Two things for the seat to decide (neither filed, neither written)

    1. ADR-0141's premise sentence is wrong. Its §Context paragraph and D8 item 1 say "a snapshot carries the record shape" / "the record shape it carries today". A dated addendum would correct that. It is a governed surface (Tier H, docs/adr/**).
    2. Possible gap, read but not measured: a package published with os package publish loses its manifest.dependencies at the snapshot. So any install fed from that row sees no declared dependencies, and D2/D5 cannot fire for it. Whether this is a defect or the deferral ADR-0141 D5 accepts until marketplace publishing is a ruling question. If cloud should carry the declaration, the fix is in cloud snapshotBundleAsManifest, and the key there must be the record, because the row is served as a kernel manifest. That would be a cloud card, and a measurement on staging comes first.

    Generated by Claude Code

    The seat closes this card as not_planned, because its premise is false. Item 2 is measured on a separate card if it holds.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Labels

area:devpathThe road — create, dev, verify, publish/install, connect an agent, iteratedomain:cloudCloud-service journey parked for the cloud PM to migrate — not dispatched in this repo (云服务旅程,本仓不派)enhancementNew feature or requestpm:dispatchedpriority:p2Medium: important, M3

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions