Skip to content

os package publish validates manifest ids with a hand-copied MANIFEST_ID_RE that admits what PackageSchema.manifestId rejects — the CLI leg of cloud#1932 #16520

Description

@claude

What was measured

Read at framework e581457b (cloud's current pin) while implementing cloud#1932 / cloud#1949 (cloud PR #2032), filed here because the fix lands in this repo.

packages/cli/src/commands/package/publish.ts:36 declares its own package-id rule:

const MANIFEST_ID_RE = /^[a-z0-9][a-z0-9._-]{0,254}$/i;

and os package publish checks --manifest-id (or the derived id) against it at :330, printing on failure:

Invalid manifest-id '...'. Expected reverse-domain form like 'com.acme.crm' (a-z0-9._-).

That literal is byte-identical to the two copies cloud just retired from package-publish.ts and package-export.ts. The contract this repo itself declares for the column the CLI is publishing into is PackageSchema.manifestId (packages/spec/src/cloud/package.zod.ts), verbatim:

/^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)+$/

The CLI copy is looser on every axis the cloud card tabulated: it admits a single segment (crm), underscores (com.acme.repair_desk), upper case (COM.ACME.CRM), a digit-first segment (9foo.bar), an empty segment (com..acme) and a trailing dot (com.acme.). Its own deriver (deriveManifestId, :61) trusts artifact.manifest.id through the same loose test, so a manifest carrying one of those shapes is forwarded unchanged.

Why this is a contract violation and not an observation

Maintainer ruling recorded on cloud#1932 (2026-09-05, verbatim): 「cloud#1932 不普查,直接按协议修改。」 under 「本项目以协议为基准。所以开发应该对其协议,协议有问题应该立卡修改协议」. Cloud PR #2032 makes POST /cloud/packages parse manifest_id through PackageSchema.manifestId by import. Once it lands, this CLI's preflight ADMITS what the server REFUSES: a user with manifest.id = com.acme.repair_desk passes the local check, the request goes out, and the answer is a 400 INVALID_FORMAT naming PackageSchema.manifestId — while the CLI's own error text, when it does fire, states a contract (a-z0-9._-) that is not the protocol's.

Same defect class as cloud#1932: a hand-copied regex with nothing pinning it to the declaration it copies. The remedy the ruling fixed is import, never transcription: parse through PackageSchema.shape.manifestId (a real runtime export of @objectstack/spec/cloud, already proven importable and .max()-chainable in cloud), and let the message quote the pattern the schema's own invalid_format issue reports.

Not in scope here

Cross-links: cloud#1932 (ruling record), cloud#1949 (the other cloud producers), cloud PR #2032.


Generated by Claude Code

Activity

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

Metadata

Metadata

Labels

Type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions