Skip to content

fix(cli): os package publish sends the manifest's listing tags, and uses a top-level tagline only as a missing description - #27573

Merged
objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-27364-publish-sends-tags
Oct 29, 2026
Merged

objectstack-fleet[bot] merged 4 commits into
mainfrom
claude/issue-27364-publish-sends-tags

Conversation

@objectstack-fleet

@objectstack-fleet objectstack-fleet Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw

Requested by Sales · project thread

Fixes #27364

Clause-②: no
Metadata-protocol: none
Skills-docs: updated here — content/docs/deployment/marketplace-handbook.mdx, content/docs/deployment/cli.mdx (commit 94a3512, claim amendment 6498466275)

维护者速读

  • 改了什么:os package publish 现在把清单里的 tags 原样发给云端;警告改口:publisher、isStarter 由平台决定、作者写了不生效(不再说「暂未携带」);顶层 tagline 只在没有 description 时充当 description,否则不发并提示。
  • 为什么改:云端发布接口已能校验并保存 tags(cloud#3361),CLI 还在丢弃它,警告也说错了原因;tagline 云端没有这一列,一直白发。
  • 风险与回滚:只动 CLI 一个命令的请求体与警告文案;超长或过多的标签由云端 400 拒收并原样打印,CLI 不自设上限。回滚即 revert 本 PR。
  • 先看:packages/cli/src/commands/package/publish.ts(pkgBody.tags 与 tagline/description 那一段、uncarriedManifestWarnings);packages/cli/test/package-publish-uncarried-manifest-keys.test.ts。
  • 两分钟验证:pnpm --filter @objectstack/cli exec vitest run --project unit test/package-publish-uncarried-manifest-keys.test.ts,预期 14 个用例全绿。
  • 需要你做的:无,席位落地。

What changes

packages/cli/src/commands/package/publish.ts, one command:

  • tags is sent. When objectstack.manifest.json declares tags, the package POST carries tags as written. The hosted route owns the shape and the bounds; the CLI keeps no copy of them and pre-checks nothing, so a refused list comes back as the server's 400 and is printed as the server wrote it (the existing failure path). An absent key leaves the stored tags alone; [] clears them. tags leaves UNCARRIED_MANIFEST_KEYS.
  • Warning wording. publisher and isStarter get their own warning: decided by the platform, an author's value has no effect, so publish does not send them. ⛔ Neither is ever sent. preview keeps the "hosted catalog does not carry yet" warning with the tracking link; visibility keeps its flag warning.
  • Top-level tagline. With no --description flag and no manifest description, the trimmed tagline is sent as description. Otherwise the tagline is not sent, and a warning names it (dropping an authored key silently is the defect this module's warnings exist for). The per-locale translations.LOCALE.tagline path is unchanged.

Importers of the two exported constants: UNCARRIED_MANIFEST_KEYS and CATALOG_SEND_ISSUE are imported only by packages/cli/test/package-publish-uncarried-manifest-keys.test.ts (repo-wide grep at the branch head).

One changeset, @objectstack/cli patch.

Tests

packages/cli/test/package-publish-uncarried-manifest-keys.test.ts drives the real command (PackagePublish.run) against a stubbed fetch and reads the request body it sends:

  • tags: sent as written; [] sent; no key when undeclared; 21 over-long tags reach the wire unchanged, and the server's 400 message reaches the output, exit 1, no version POST.
  • tagline: becomes description when none is given; not sent and named in a warning when the manifest or the flag gives one; per-locale tagline untouched.
  • warnings: publisher/isStarter platform-decided and never sent; preview still not carried, with the link; visibility separate; quiet when only sent keys are declared.
  • the schema-key partition moves tags to SENT.

Acceptance notes

  • Docs updated here (commit 94a3512f, file surface extended by claim amendment 6498466275). content/docs/deployment/marketplace-handbook.mdx: the warn callout no longer says tags is not sent (publisher / isStarter are platform-decided, never sent, warned), and the key table gains a tags row. content/docs/deployment/cli.mdx: the keys-read list names tags (sent as written) in place of tagline, and says a top-level tagline is used only as a missing description.
  • The hosted bounds (20 tags, 64 characters each) are cloud's numbers and are not exported in this repository, so per the triage ruling the CLI does not pre-check them.

Verification

All readings below are at head 083edf170d (fix fadb51292f plus one merge of origin/main), except the red leg and the ablation, which name their commit.

Red first (test commit f2c48fc, source unchanged)
Test Files  1 failed (1)
     Tests  9 failed | 5 passed (14)

Failing: the three tags-sent cases, the three tagline cases, the platform-decided wording, the quiet case, and the partition.

Green
publish suites (5 files): Test Files 5 passed (5) · Tests 59 passed (59)
pnpm --filter @objectstack/cli exec vitest run --project unit: Test Files 349 passed (349) · Tests 5063 passed (5063) · VERDICT command-exit 0
pnpm --filter @objectstack/cli typecheck: VERDICT command-exit 0 (test layer: 28 errors / 6 signatures held in test-typecheck-debt.json, unchanged)
eslint --no-inline-config packages/cli: exit 0

The integration layer is declared to CI (the diff touches no spawn entry).

Ablation (scripts/ablation-replace.mjs, at fadb512)
anchor "if (m.tags !== undefined) pkgBody.tags = m.tags;" x1 -> x0, replacement x0 -> x1
blob 4bc0cb2f227b -> d0cced9bda65
Tests 3 failed | 11 passed (14): the three tags-sent cases
restored: blob == HEAD (4bc0cb2f227b) and git diff HEAD is empty

The test imports the command from src/, so no build sits between the mutation and the run. The tagline and wording changes are evidenced by the red leg against the unchanged source.


Generated by Claude Code

🤖 Generated with Claude Code

https://claude.ai/code/session_01L6bhgXcN9HaZYSEUdJWEjw

…ine, and words the platform-decided keys (red)

Claude-Session: https://claude.ai/code/session_01L6bhgXcN9HaZYSEUdJWEjw
Co-authored-by: Claude <noreply@anthropic.com>
… platform-decided keys, maps tagline to a missing description

Claude-Session: https://claude.ai/code/session_01L6bhgXcN9HaZYSEUdJWEjw
Co-authored-by: Claude <noreply@anthropic.com>
@github-actions github-actions Bot added size/m documentation Improvements or additions to documentation tests tooling labels Oct 29, 2026
@github-actions

github-actions Bot commented Oct 29, 2026 •

Copy link
Copy Markdown
Contributor

📓 Docs Drift Check

This PR changes 1 package(s): @objectstack/cli, touching 6 documentable anchor(s).

11 hand-written doc(s) NAME something this change touched and may need an implementation-accuracy re-verification:

  • content/docs/api/declarative-endpoints.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/concepts/metadata-lifecycle.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/deployment/cli.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/deployment/index.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/deployment/marketplace-handbook.mdx (via isStarter (literal, a string literal in PLATFORM_DECIDED_MANIFEST_KEYS; a string literal in UNCARRIED_MANIFEST_KEYS), os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/deployment/publish-and-preview.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/protocol/kernel/index.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/protocol/kernel/lifecycle.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/protocol/kernel/metadata-service.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/protocol/objectql/index.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/protocol/objectql/schema.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))

⛔ 3 release-owned page(s) also name something this change touched. These are read-only:

  • content/docs/releases/v17/17-5.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/releases/v17/17-6.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))
  • content/docs/releases/v9.mdx (via os package publish (command, read off packages/cli/src/commands/package/publish.ts))

content/docs/releases/ is RELEASE-OWNED (AGENTS.md "Documentation Guardrails"): release
notes are written centrally at release time, and a code PR that edits them is the exact PR
that guardrail exists to stop. They are still audited — read-only. If one of them is actually
wrong, file an issue or open a dedicated docs-only PR; do not edit it here.

What this run could not see
  • the SDK route bridge reached 58 of 210 client-bound route-ledger rows — the other 152 have no registrar path: tail to select them, so pages documenting THEIR client methods cannot appear above, on this or any run. Of those 152: 0 are remediable by widening that discovery convention (an in-repo file declares the path; the convention did not scan it); 55 are structural — on a ledger where NOT ONE row is declared in-repo, so no discovery change reaches them at any price; 97 are undecided (no in-repo declaration, on a ledger that has other in-repo registrars — absence and an unreadable spelling are not distinguishable here). The rows themselves: node scripts/docs-audit/affected-docs.mjs --bridge-coverage
  • a page that states a rule by its inputs shares no identifier with the emitter that implements the rule, so an emitter-only diff cannot list it — not on this run and not on any run. Measured on fix(driver-sql): emit varchar(maxLength) for a text field a declared index keys on #11430: content/docs/protocol/objectql/types.mdx documents the text-family column mapping by the ObjectQL type names it maps FROM (text / textarea / html) while the diff changed createColumn; it went unlisted, and it was the page that diff falsified, in four places. No shared token exists to detect this on, so a rule your change carries has to be re-read by hand in the pages that restate it.
  • a key NAME is not a key, so the hand re-read the line above prescribes can land on the wrong schema. The same spelling is authorable on one governed type and a [REMOVED] tombstone on another for each of active, aria, joins, objects, template, tools and version (censused on [finding] tools is a key on BOTH AgentSchema (tombstoned, dead) and SkillSchema (live, cloud-attested), so a name-based search attributes skill examples to the agent key — it produced a false stop-the-line alarm on PR #19059 #19093 over the liveness ledger's governed types, top-level keys); nothing in a search result distinguishes the two, so a grep hit on a LIVE example reads as evidence about the DEAD key. Measured on fix(spec): the agent.tools liveness row says dead — it claimed live on a key the schema tombstoned #19059: content/docs/ai/agents.mdx was reported as contradicting the agent.tools tombstone over its tools: example at :161, which is inside the defineSkill({ block opened at :155 — the page was already correct. Settle ownership by PARSING the value against both schemas, never by the name: that literal PASSES SkillSchema, and as an AgentSchema it FAILS at tools with the tombstone prescription. ⛔ These names are not the whole class — a key retired through a .strict() guidance map leaves no tombstone in the walked shape and none of them here (tool.category, live as AIToolDefinition.category).

Coarse fallback — 35 page(s) merely mention a changed package (the pre-#9192 predicate, kept for the deliberately-wide backstop): node scripts/docs-audit/affected-docs.mjs --json 1ed33609731b0bc3b2da81c97242e9c8582d003d → packageMentionDocs.

Which tree this was computed on

This run read content/docs from 056650bf55cc3d688f3a2bdcb709dc31710c4edb — the merge of head 94a3512f57dc0aef7b63579268f662f46c61d885 into base 1ed33609731b0bc3b2da81c97242e9c8582d003d, which is what actions/checkout gives a pull_request run. Not the PR head.

A worktree cut from an older main holds a different content/docs, so re-deriving there can legitimately return a different list — that is a different tree, not a wrong row. To answer on the same tree:

# while this PR is open — GitHub drops the merge commit once it closes
git fetch origin 056650bf55cc3d688f3a2bdcb709dc31710c4edb && git checkout 056650bf55cc3d688f3a2bdcb709dc31710c4edb
# afterwards, rebuild it from the two parents, which stay fetchable
git fetch origin 1ed33609731b0bc3b2da81c97242e9c8582d003d 94a3512f57dc0aef7b63579268f662f46c61d885 && git checkout -B drift-repro 1ed33609731b0bc3b2da81c97242e9c8582d003d && git merge --no-ff 94a3512f57dc0aef7b63579268f662f46c61d885

node scripts/docs-audit/affected-docs.mjs --json 1ed33609731b0bc3b2da81c97242e9c8582d003d

⚠️ That checkout carried uncommitted changes, so the commit above does not fully identify what was read.

Advisory only, and a precision-first one (#9192): a page is listed because it names a
symbol, wire route or SDK method this diff touched — not because it mentions a changed
package. Each row says which anchor put it there, so a wrong row is reportable rather than
merely annoying. To re-verify, run the docs-accuracy-audit workflow scoped to these files:
node scripts/docs-audit/affected-docs.mjs 1ed33609731b0bc3b2da81c97242e9c8582d003d → pass the list as
args.docs, on the commit named under Which tree this was computed on.

…latform-decided; tagline only as a missing description

Claude-Session: https://claude.ai/code/session_01L6bhgXcN9HaZYSEUdJWEjw
Co-authored-by: Claude <noreply@anthropic.com>
@objectstack-fleet

Copy link
Copy Markdown
Contributor Author

domain:server#1 · os-sales · session_01L6bhgXcN9HaZYSEUdJWEjw

维护者速读(席位终稿)

  • 改了什么:os package publish 现在把清单里的 tags 原样发给云端。警告改口为:publisher、isStarter 由平台决定,作者写了不生效。顶层 tagline 只在没有 description 时充当 description,否则不发并提示。两页文档同步改正。
  • 为什么改:os package publish sends the manifest's listing tags (cloud now stores them), and drops or maps the top-level tagline #27364。云端发布接口已能校验并保存 tags,CLI 却还在丢弃它,警告也说错了原因;tagline 云端没有这一列,一直白发。
  • 风险与回滚:低。只动 CLI 一个命令的请求体和警告文案;坏的标签列表由云端 400 拒收,CLI 原样打印。回滚就是还原这一个 PR。
  • 先看:packages/cli/src/commands/package/publish.ts(pkgBody.tags、tagline/description 那一段、uncarriedManifestWarnings)。
  • 两分钟验证:pnpm --filter @objectstack/cli exec vitest run --project unit test/package-publish-uncarried-manifest-keys.test.ts,预期 14 个用例全绿。
  • 需要你做的:无。Tier S,不碰契约四面,席位落地。

席位意见:接受。这次修改让本已过时的两页文档变得明确错误,所以按 os-dev 规则在同一 PR 里改正(认领修正 6498466275),没有拖成后续卡。

席位核对 — ACCEPT · domain:server#1 · head 94a3512 · 2026-10-29T14:42Z

  • Shape: publish.ts sends pkgBody.tags = m.tags when the manifest declares tags: an absent key is omitted, [] is sent, and there is no client-side bound. tags leaves UNCARRIED_MANIFEST_KEYS. publisher / isStarter get their own platform-decided warning and are never sent. A top-level tagline becomes description only when neither --description nor the manifest's description gives one; otherwise it is not sent and is warned. translations.LOCALE.tagline and visibility are unchanged. The docs commit 94a3512f corrects the two pages the change falsified.
  • Premise: claim 6496121102 with amendment 6498466275 holds; Fixes #27364; triage 6487515493.
  • Gates: 54 check-runs on this head: 39 success, 15 skipped, 0 failed, 0 pending. check-expected-skips --pr 27573 (fresh origin/main): VERDICT … OK — 15 skipped check-run(s), every one in main's roster (exit 0). mergeable_state: clean. Dev (os-dev-report 6498414007 + addendum): red-first on the test file (9 failed / 5 passed), ablation of the tags send red (3 failed) and restored to the HEAD blob, cli unit 349 files / 5063 tests pass, typecheck exit 0; at the docs head dispatch-gates --ran 92 derived, 91 exit 0, 1 NOT-MEASURED (check:dual-build-cjs-loads, full-repo build; CI green on it).
  • Contract review: not owed. Clause-②: no: no accept set narrows, because the hosted route judges tags and a CLI request-body key is not a published accept set. There is no packages/spec/** and no governed path. Seat read per contract-review.md.
  • Prose read against the diff: each docs sentence was checked against publish.ts at this head.
    • marketplace-handbook.mdx: the tags row (sent as written, 400 printed as is, [] clears, absent keeps); the callout (publisher / isStarter platform-decided, never sent, warned).
    • cli.mdx: the keys-read list names tags; the top-level tagline is a missing description only.
    • Changeset: @objectstack/cli: patch, Clause-②: no.
  • Accepted deviations: the extra warning when a top-level tagline is dropped beside a description. An authored key is never dropped silently (the module's own rule).
  • Declaration: Clause-②: no, Metadata-protocol: none, Skills-docs: updated here — content/docs/deployment/marketplace-handbook.mdx, content/docs/deployment/cli.mdx (patched onto the body by the seat).
  • Out of scope: none.
  • Landing: Tier S, NOT governed, 379 changed lines ≤ 3000 → pr_ready + automerge_enable via the relay now.

@objectstack-fleet
objectstack-fleet Bot marked this pull request as ready for review October 29, 2026 14:43
@objectstack-fleet
objectstack-fleet Bot enabled auto-merge October 29, 2026 14:43
@objectstack-fleet
objectstack-fleet Bot added this pull request to the merge queue Oct 29, 2026
Merged via the queue into main with commit 882d4e4 Oct 29, 2026
55 checks passed
@objectstack-fleet
objectstack-fleet Bot deleted the claude/issue-27364-publish-sends-tags branch October 29, 2026 15:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Improvements or additions to documentation size/m tests tooling

Projects

None yet

Development

Successfully merging this pull request may close these issues.

os package publish sends the manifest's listing tags (cloud now stores them), and drops or maps the top-level tagline

1 participant