Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
33 changes: 33 additions & 0 deletions .changeset/spec-publish-command-spelling.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
---
"@objectstack/spec": patch
---

Route the stored-envelope refusal to a command that exists — `os package publish`, not the retired `objectstack publish` (#12223)

An author who hand-writes one of the seven `STORED_ENVELOPE_KEYS` onto an `api`
declaration is refused, and the refusal tells them where publication state actually
comes from. It named a command that resolves to nothing:

```text
before: Remove it — publication state is managed by `objectstack publish`, not authored.
after: Remove it — publication state is managed by `os package publish`, not authored.
```

`os publish` was the legacy direct-to-environment command, retired with the path that
wrote `sys_environment_revision`. Re-measured on this tree against the **built oclif
`Config`** rather than against docs — loading the CLI's plugin and reading the command
table oclif derives from `dist/commands/**`: **61** ids, of which the only two containing
`publish` are `package publish` and `plugin publish`. There is no bare `publish` id and no
`publish` topic, so the old spelling exits as an unknown command. The message's own
neighbouring sentence already names `publishPackage` as the writer, and
`packages/cli/src/commands/package/publish.ts` is the command that runs it.

This is the shape #12177 deliberately left alone elsewhere inverted: those sentences are
*about* the removal and are correct as history, while this one is **present tense and
prescriptive** — text an AI author obeys at the moment its write is refused.

Text only. No accept/reject behaviour changes: the same seven keys are refused on the same
declarations, with the same `unrecognized_keys` upgrade path; only the sentence an author
reads is corrected. The same stale spelling is fixed in the `publisher` doc comment of
`packages/spec/src/cloud/package.zod.ts`, which ships to consumers in the package's type
declarations.
2 changes: 1 addition & 1 deletion content/docs/api/declarative-endpoints.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -86,7 +86,7 @@ export default defineStack({
});
```

Publish it (`objectstack publish`), and the two URLs answer. `objectstack validate` — and
Publish it (`os package publish`), and the two URLs answer. `objectstack validate` — and
`os build` — run the same gates the publish path runs, so a declaration that would be
refused is refused before you deploy.

Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/api/endpoint.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -36,7 +36,7 @@ const STORED_BOOKKEEPING_GUIDANCE =
'This is the metadata layer\'s own storage bookkeeping, not endpoint vocabulary. It is written onto '
+ 'the stored ROW by `register` / `publishPackage` and peeled off before this schema sees a body '
+ '(#5309), so writing it on a declaration configures nothing. Remove it — publication state is '
+ 'managed by `objectstack publish`, not authored.';
+ 'managed by `os package publish`, not authored.';

/**
* API Endpoint Schema
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/cloud/package.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -234,7 +234,7 @@ export const PackageSchema = lazySchema(() => z.object({
/**
* Publisher provenance tier — surfaced as a trust badge in the Marketplace
* and Studio. Defaults to `private` for org-scoped packages; the
* `objectstack publish` CLI sets it explicitly when promoting first-party
* `os package publish` command sets it explicitly when promoting first-party
* or partner content.
*/
publisher: PackagePublisherSchema.default('private'),
Expand Down
21 changes: 9 additions & 12 deletions scripts/check-cli-command-ids.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -213,19 +213,16 @@ const FIXTURE_EXEMPTIONS = [
* follow in the owning lane, which is the same order `check-cli-test-child-env` shipped in
* and for the same reason: sweeping without the gate restates a convention instead of
* enforcing it.
*
* EMPTY, and that is the design working rather than a list nobody kept. The gate shipped
* with exactly one entry -- the `objectstack publish` refusal message in
* `packages/spec/src/api/endpoint.zod.ts` (#12223) -- and it retired ITSELF: fixing the
* string to `os package publish` made the entry stop reproducing, the `stale` check below
* RED, and deleting it the only way back to green. A baseline here cannot outlive its
* defect, so this list stays a record of work in flight and never becomes a silent
* exemption. Add to it only under the rule above: a real defect, filed and linked.
*/
const BASELINED_VIOLATIONS = [
{
file: 'packages/spec/src/api/endpoint.zod.ts',
text: 'objectstack publish',
why: 'STALE. `os publish` was retired with the direct-to-environment path (#11465 measured '
+ 'it against the built oclif Config: the registered publish ids are `package publish` and '
+ '`plugin publish`). This is a present-tense AUTHOR-FACING refusal message -- "publication '
+ 'state is managed by `objectstack publish`" -- so an author who trips it is sent to a '
+ 'command that does not exist. Correct spelling: `os package publish`.',
issue: '#12223',
},
];
const BASELINED_VIOLATIONS = [];

const isExempt = (file, text) =>
FIXTURE_EXEMPTIONS.some((e) => e.file === file && e.text === text)
Expand Down
Loading