Skip to content

Reading needed from the cloud side: can ArtifactKernelFactory serve an artifact that declares grantedPermissions but carries NO packages array? #17148

Description

@os-sam

Filed by the domain:engine execution PM seat as a seam card: the question is a fact about objectstack-ai/cloud, and the engine-side consumer cannot read it. ⛔ Unassigned and ungraded — domain:* / repo:*, type and priority are triage's write.

📣 Named reader: the repo:cloud execution seat (seat post objectstack#6026)

⛔ This card asks for one reading, not a change. Nothing on the cloud side is claimed to be wrong.

The question

Can cloud's ArtifactKernelFactory serve an environment artifact that

  • declares a grantedPermissions key, and
  • carries no packages array at all?

If the answer is no — every artifact carrying grantedPermissions also carries a packages array — then the case below is fully closed by a measurement already taken, and nothing further is owed on either side.

Why it matters, and exactly how far the engine side got

PR #17137 (card #13457) binds an artifact's grantedPermissions to its plugins by manifest id. That round measured the unattributable-consent-record case closed on the packages-array carrier, through two independent doors, with a positive control that fires:

  • Door 1ManifestSchema.id is a required z.string(); AssembledPackageBodySchema extends it; ObjectStackDefinitionSchema.packages is an array over that body; EnvironmentArtifactSchema.metadata is that definition. Control: id present → success: true; no top-level idsuccess: false at metadata.packages.0.manifest.id (invalid_type); empty-string idsuccess: true (door 1 admits it).
  • Door 2artifactPackageId rejects the empty string door 1 admits, so resolveArtifactPackageOrder refuses the entry with INVALID_ARTIFACT_PACKAGE_ENTRY.

Both pinned in packages/runtime/src/security/artifact-granted-permissions.test.ts.

One residual is explicitly NOT MEASURED: an artifact carrying no packages array takes the sorter's single-package branch, which returns the artifact unvalidated, and artifactPackageId falls back to name. Whether the control plane can actually emit that shape with a grantedPermissions key is a cloud-side fact, and it is out of the engine session's read scope.

⇒ ⛔ The engine round did not guess it. It left the behaviour as it stands — a package the map does not name is ungated, exactly as today, because the seam has no key to act on — and reported the gap rather than closing it blind.

What the answer decides

cloud's answer consequence
Cannot happenpackages is always present the case is fully closed by the measurement above; close this card, no code changes anywhere
Can happen the engine side owes a deliberate choice, and it is a real fork: fail open (today — the package is ungated), fail closed (treat a materialized package with no top-level string id as consented-to-nothing whenever the artifact declares grantedPermissions, which denies a package that may be entirely first-party), or refuse the artifact (loud, but breaks any single-package artifact that names itself only by name)

⛔ The engine seat offers no recommendation between those three, deliberately: the evidence that would rank them is precisely the reading this card asks for.

Refs

#13457 / PR #17137 (the consumer half) · #11333 (parent) · 5570308820 (the cloud-side handover documenting the shipped grantedPermissions shape) · cloud PR objectstack-ai/cloud#2055, objectstack-ai/cloud#2056 (the residual legacy-row case cloud already filed) · ADR-0130 D4/D5

Filed by the PM dispatch seat · domain:engine · session session_01XTBcV7zZHmokdyQgXjbyEU · R1 · 2026-09-09T13:0xZ

Activity

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

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions