Found while fixing the last remaining site on #14806 (dev seat, session session_01D47qPfEWVPmhguWgBZCi5N, branch claude/issue-14806-publish-help-example-app-path, PR #15390). Filed unassigned for triage. Deliberately NOT fixed there — that delivery was ruled to exactly one line.
⚠️ This is an observation about a drift risk, not a live defect. After PR #15390 the two copies agree in substance. The finding is that nothing holds them together, and that they demonstrably came apart once.
The pair
The same five-example set for os package publish is written out independently in two places:
packages/cli/src/commands/package/publish.ts — static override examples, printed verbatim by oclif under EXAMPLES:
$ os package publish
$ os package publish --manifest-id com.acme.crm --version 1.2.0
$ os package publish --env env_abc123 --install
$ os package publish dist/objectstack.json --visibility org --note "first cut"
$ OS_CLOUD_URL=http://localhost:4000 os package publish # local dev
content/docs/deployment/cli.mdx:1610 — the #### os package publish block:
os package publish # dist/objectstack.json - your org
os package publish --manifest-id com.acme.crm --version 1.2.0
os package publish dist/objectstack.json --visibility org --note "first cut"
os package publish --env env_abc123 --install # publish, then install into an environment
OS_CLOUD_URL=http://localhost:4000 os package publish # against a local control plane
Same five invocations, same order of ideas, two hand-maintained copies.
The evidence that they drift
They did. The CLI line carried # local dev (apps/cloud) — pointing at a directory deleted from this repo — while the docs line, for the same example, said # against a local control plane and named no directory. The docs copy was correct the whole time the shipped --help output was wrong, and nothing noticed, because nothing compares them.
That is the same shape #15297 records for a comment pair (objectql/src/plugin.ts:142 and serve.ts:4549 — "written as a pair and since drifted apart"), one layer up: here the drifting pair is published CLI output against published documentation.
Why it is worth a look rather than a shrug
This repo gates pairs like this routinely, and the CLI surface specifically is already covered by two halves that were deliberately designed not to overlap:
packages/cli/src/commands/environments/environments.test.ts (the #10967 pin) checks that every examples entry inside packages/cli resolves to a registered command id.
scripts/check-cli-command-ids.mjs checks the same property for command-id literals outside packages/cli — its header states "every oclif package is excluded from its own scan -- so the two never touch the same line", and it does cover content/docs/deployment/cli.mdx.
So both copies are already checked for "does this name a real command". Neither is checked for "do these two copies still say the same thing", which is the property that actually failed.
Not a recommendation, just the options a triager will want
- Gate it — assert the docs block and the
examples array carry the same invocations. Cheap, but it fixes the comment wording in place, and the two comments legitimately differ in voice (help text is terse, docs prose can be longer).
- Generate it — derive the docs block from
examples at build time, so there is one source.
- Do nothing, deliberately — decide that two audiences justify two copies, and record that so the next person who notices does not re-file this.
⛔ Whatever the disposition, do not sweep the bare tokens objectos or cloud while acting on it — grep the paths apps/cloud / apps/objectos only. objectos.ai, cloud.objectos.ai, DEFAULT_CLOUD_URL and several literal plugin ids are all correct, and a token sweep breaks working code. That trap is documented on #14806 and it is real.
Re-checkable
git grep -n "os package publish" -- packages/cli/src/commands/package/publish.ts content/docs/deployment/cli.mdx
Refs: #14806 (the card whose last site surfaced this), #15390 (the PR that made the two agree again).
Found while fixing the last remaining site on #14806 (dev seat, session
session_01D47qPfEWVPmhguWgBZCi5N, branchclaude/issue-14806-publish-help-example-app-path, PR #15390). Filed unassigned for triage. Deliberately NOT fixed there — that delivery was ruled to exactly one line.The pair
The same five-example set for
os package publishis written out independently in two places:packages/cli/src/commands/package/publish.ts—static override examples, printed verbatim by oclif underEXAMPLES:content/docs/deployment/cli.mdx:1610— the#### os package publishblock:Same five invocations, same order of ideas, two hand-maintained copies.
The evidence that they drift
They did. The CLI line carried
# local dev (apps/cloud)— pointing at a directory deleted from this repo — while the docs line, for the same example, said# against a local control planeand named no directory. The docs copy was correct the whole time the shipped--helpoutput was wrong, and nothing noticed, because nothing compares them.That is the same shape #15297 records for a comment pair (
objectql/src/plugin.ts:142andserve.ts:4549— "written as a pair and since drifted apart"), one layer up: here the drifting pair is published CLI output against published documentation.Why it is worth a look rather than a shrug
This repo gates pairs like this routinely, and the CLI surface specifically is already covered by two halves that were deliberately designed not to overlap:
packages/cli/src/commands/environments/environments.test.ts(the#10967pin) checks that everyexamplesentry insidepackages/cliresolves to a registered command id.scripts/check-cli-command-ids.mjschecks the same property for command-id literals outsidepackages/cli— its header states "every oclif package is excluded from its own scan -- so the two never touch the same line", and it does covercontent/docs/deployment/cli.mdx.So both copies are already checked for "does this name a real command". Neither is checked for "do these two copies still say the same thing", which is the property that actually failed.
Not a recommendation, just the options a triager will want
examplesarray carry the same invocations. Cheap, but it fixes the comment wording in place, and the two comments legitimately differ in voice (help text is terse, docs prose can be longer).examplesat build time, so there is one source.⛔ Whatever the disposition, do not sweep the bare tokens
objectosorcloudwhile acting on it — grep the pathsapps/cloud/apps/objectosonly.objectos.ai,cloud.objectos.ai,DEFAULT_CLOUD_URLand several literal plugin ids are all correct, and a token sweep breaks working code. That trap is documented on #14806 and it is real.Re-checkable
Refs: #14806 (the card whose last site surfaced this), #15390 (the PR that made the two agree again).