You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Commit 150f740
Browse filesBrowse the repository at this point in the historyBrowse files
feat(spec)!: retire TemplateManifest publisher and isStarter — the platform decides both (#31178)
<!-- claude-projects-attribution: {"github_login":"marchtian"} -->
_Requested by **田騏** · [project
thread](https://claude.ai/code/project/chan_01VmuUhXU9SSUzqJYyXSmYSi?thread=cmsg_01VmuUhXU9SSUzqJYyXSmYSi3Q621zfrgQodZHLx3cUop2)_Fixes#31035
Clause-②: no (narrowing) — two authorable keys of
`TemplateManifestSchema` become tombstones, and `os package publish`
refuses the file's `publisher` by name
Metadata-protocol: narrowed
Skills-docs: none — no `skills/**` page teaches
`objectstack.manifest.json`; the two `content/docs` pages that name
these keys are updated here
## 维护者速读
- 改了什么:`objectstack.manifest.json` 里最后两个"写了不生效"的键
`publisher`、`isStarter` 改成 `retiredKey()` 墓碑,tsc 和 schema
解析都按键名拒绝并给出处方;blank 模板先去掉 `isStarter: true`,脚手架也会把这两个键从模板清单里剥掉;`os
package publish` 遇到 `publisher` 直接拒绝,遇到 `isStarter` 只提示删除、照常发布。
- 为什么改:按你的裁决(#31035 评论 6708417668,选项
2):信任等级是平台按发布者凭据定的,作者自己写的值从来不生效,这种声明不该放在作者能改的文件里;`isStarter`
同理由平台决定。前五个键已由 #31064 退役,这是后一半。
- 风险与回滚:收窄(BREAKING 横幅 + adr-0087 登记)。还写着这两个键的旧清单在 schema 解析时被拒;之前从
blank 模板生成的项目都带 `isStarter: true`,所以发布时对它只警告不拒绝。hotcrm
的清单和服务模式发布脚本要另开卡把值挪进脚本(席位立卡)。回滚即 revert。
-
先看:`packages/spec/src/marketplace/template-manifest.zod.ts`(两个墓碑和处方);`packages/cli/src/commands/package/publish.ts`(`publisher`
拒绝、`isStarter`
并入删除警告);`packages/create-objectstack/src/templates/blank/objectstack.manifest.json`(去掉
`isStarter`)。
- 两分钟验证:`pnpm --filter @objectstack/spec exec vitest run --project repo
src/marketplace/template-manifest-inert-keys-retirement.test.ts`,预期 17
个用例全绿(七个键逐个拒绝、tsc 墓碑、两个 D3 登记、全树清单扫描)。
- 需要你做的:无,席位落地。
## What changes
- **Spec (`TemplateManifestSchema`).** `publisher` and `isStarter`,
inherited from `CreatePackageRequestSchema`, are re-declared as
`retiredKey()` tombstones on this file only. A parse refuses each at its
own path with the prescription `` `TemplateManifest.<key>` was removed
in @objectstack/spec 18 (ADR-0049) — … Delete the key. ``. The publish
request's own `publisher` / `isStarter` and the server `Package` row are
untouched.
- **ADR-0087 bookkeeping.** Two `RETIRED_KEYS_BY_MAJOR[18]` rows
(`marketplace/TemplateManifest:publisher`, `:isStarter`), one new D3
semantic entry
`marketplace-template-manifest-platform-decided-keys-retired` (its own
family: the reason differs from the five inert keys — these are platform
decisions), and its `STEP18_RATIONALE` fragment (inserted where its id
sorts, `order: 121`). No D2 conversion: this file is not a stack
collection member (the `category` precedent). The sibling D3 entry's
comment now points at the new family.
- **Liveness.** Both `template_manifest` rows stay `dead` (tombstone
route) with REMOVED notes and `verifiedAt` 2026-11-07; `_note` and the
README row updated; counts unmoved.
- **`os package publish`.** A manifest declaring `publisher` is refused
before any network call (`retiredPublisherRefusal()`, the `visibility`
shape). `isStarter` joins `RETIRED_INERT_MANIFEST_KEYS` and is named in
the deletion warning, still publishing. `UNCARRIED_MANIFEST_KEYS` is now
`['preview']`; `PLATFORM_DECIDED_MANIFEST_KEYS` and its warning branch
are gone. Neither key is ever sent.
- **create-objectstack.** The blank template drops `isStarter: true`
(the ruling's first step). `RETIRED_TEMPLATE_MANIFEST_KEYS` gains both
keys, so scaffolding strips them; the pin keeps that list equal to the
spec's registry rows.
- **Pins.** `template-manifest-inert-keys-retirement.test.ts` gains a
top-level `describe` for the two keys (refusal per key, `isStarter:
false` refused too, `@ts-expect-error` tsc pins), their registration and
D3 entry, and its tree-scoped walk now covers all seven keys (same
radius and `heldBy` registration as before). CLI pins: `publisher`
refused with no network call plus a control; `isStarter` warned, not
sent under either spelling; the key partition updated.
- **Docs.** Marketplace handbook callout and the CLI reference
paragraph; `template-manifest.mdx` regenerated, not hand-edited.
- **Carried (comment 6701806800).** `taxonomy.zod.ts`'s module doc now
says released values are append-only and retiring a released value is
the ADR-0087 route; `taxonomy.mdx` regenerated.
- **Changeset.** `@objectstack/spec` minor, `@objectstack/cli` minor,
`create-objectstack` patch, with both declaration lines, BREAKING
banner, FROM → TO per key and the adr-0087 marker.
## Why
Maintainer ruling 6708417668 on #31035, verbatim in its binding part:
"`publisher` and `isStarter` are retired from
`objectstack.manifest.json` (`TemplateManifestSchema`) under ADR-0087,
through the `spec-property-retirement` playbook." Measured on
`origin/main` 9f61e06: both were schema members recorded `dead`; `os
package publish` only named them in a warning and never sent them.
## Verification
Final head after merging `origin/main` (8ef4d30) and a full `pnpm
build` (119/119 tasks): see the `os-dev-report` comment on #31035 for
the full record.
<details><summary>Tests</summary>
- `@objectstack/spec` `test` (local project): Test Files 820 passed
(820), Tests 25936 passed, 1 todo; `test:repo`: Test Files 91 passed
(91), Tests 1556 passed. Re-run on the merged head: the pin file 17/17,
`src/marketplace` + `src/migrations` 13 files / 347 tests.
- `@objectstack/spec` `check:generated` :: exit 0 (standalone);
`check:test-typecheck` :: exit 0.
- create-objectstack `vitest run`: 25 files / 374 tests passed;
`typecheck` :: exit 0.
- `@objectstack/cli` unit project: 394 of 396 files passed on the first
run; the 2 red were `published-subpath-*.pin.test.ts` refusing a
not-yet-built `packages/cli/dist` (prerequisite, not the diff) and pass
after the full build, together with the three publish suites (5 files /
67 tests).
- `packages/apps/connector-{docusign,github,stripe}` `pnpm test`: 28, 14
and 20 passed.
- `eslint --no-inline-config` on every touched source file :: exit 0.
</details>
<details><summary>Derived gates</summary>
`node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` derives 114 families, identical before and
after the merge; results and the `--ran` reconciliation are in the
report comment.
</details>
## Acceptance notes
- **Design choice the seat may strike:** `publisher` is refused by `os
package publish`, `isStarter` only warned. This mirrors #31064
(`visibility` refused; keys the blank template shipped warned): no
scaffold ever wrote `publisher`, so refusing it strands no project,
while every project scaffolded before this release carries `isStarter:
true`. The schema parse refuses both either way.
- `RETIRED_INERT_MANIFEST_KEYS` keeps its name although it now holds
`isStarter`; its doc comment says what the list is ("never changed what
this command published").
- **Out of scope, for the seat to file:** hotcrm's
`objectstack.manifest.json` (writes `publisher` / `isStarter`) and
`scripts/lib/marketplace-listing.mjs` (`packageUpsertBody` reads them
off the manifest) move both values into the script, per the ruling. Not
read from this container.
- `.github/workflows/release.yml` (governed) is untouched.
- Fable full review: PASS with should-fix, all fixed; two delta reviews
(verdict comment on this PR).
## Human Minimum
- [x] 1. Schemas start as Zod; `packages/spec` holds no runtime logic.
- [x] 2. Every name I added uses the casing for its kind.
- [x] 3. No formatter ran; `pnpm lint` passes (touched files locally;
repo scan is CI's).
- [x] 4. One issue, one branch off an up-to-date `main`, one pull
request.
- [x] 5. A change that publishes carries a changeset, and both
declaration lines are filled in here and in the changeset.
- [x] 6. `packages/spec` touched: its generated artifacts are
regenerated and committed.
- [x] 7. No hand edits to `content/docs/references/`,
`packages/*/CHANGELOG.md` or `content/docs/releases/`.
- [x] 8. Title, body and comments are in English.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_017ihL2dLTDTsCKoixfFLh7U
---------
Co-authored-by: Claude <noreply@anthropic.com>
feat(spec)!: retire `objectstack.manifest.json``publisher` and `isStarter` — the platform decides both (#31035)
8
+
9
+
Clause-②: no (narrowing) — two authorable keys of `TemplateManifestSchema` become tombstones, and `os package publish` refuses the file's `publisher` by name
**BREAKING** for an `objectstack.manifest.json` that still writes `publisher` or `isStarter`, and for `os package publish` run on a manifest that declares `publisher`.
15
+
16
+
-**Retired (ADR-0049 enforce-or-remove).**`TemplateManifest.publisher` and `TemplateManifest.isStarter` are `retiredKey()` tombstones: `tsc` refuses them and a parse of `TemplateManifestSchema` refuses each with its prescription. Neither ever had an effect from this file: `publisher` is the trust tier that gates listing privileges, which the platform assigns from the publisher's credentials, and the platform honours a starter flag only on a first-party seed; `os package publish` never sent either. A trust claim does not belong in an author-editable file. `RETIRED_KEYS_BY_MAJOR[18]` lists both keys and the upgrade guide carries the semantic entry `marketplace-template-manifest-platform-decided-keys-retired`. No ADR-0087 conversion: this file is not a stack collection member, so `os migrate meta` has nothing to rewrite; a runtime boot never reads it. The publish request's own `publisher` and `isStarter` (`CreatePackageRequestSchema`) are unchanged.
17
+
-**Migration** — FROM → TO, in `objectstack.manifest.json`:
18
+
-`publisher` → delete it. The platform assigns a package's trust tier from the credentials it is published with.
19
+
-`isStarter` → delete it. The platform decides which packages are starters; a first-party script that seeds one in service mode carries the flag itself, not in the manifest.
20
+
-**`@objectstack/cli`.**`os package publish` refuses a manifest declaring `publisher` before any network call. It names `isStarter` in the deletion warning with `name`, `specVersion`, `skills` and `scaffold`, and still publishes, because every project scaffolded from the blank template before this release carries `isStarter: true`. Neither key is ever sent.
21
+
-**`create-objectstack`.** The blank template's manifest drops `isStarter`, and scaffolding strips both keys (with the other retired ones) from a template's manifest, so a template authored before this release still scaffolds a manifest the schema accepts.
|**publisher**|`never`| optional |[REMOVED]`TemplateManifest.publisher` was removed in @objectstack/spec 18 (ADR-0049) — the platform assigns a package's publisher trust tier from the publisher's credentials, so a value written here never had an effect and `os package publish` never sent it. Delete the key.|
58
+
|**isStarter**|`never`| optional |[REMOVED]`TemplateManifest.isStarter` was removed in @objectstack/spec 18 (ADR-0049) — the platform decides which packages are starters (honoured only on a first-party seed), so a value written here never had an effect and `os package publish` never sent it. Delete the key.|
59
59
|**translations**|`Record<string, { displayName?: string; description?: string; readme?: string; tagline?: string; … }>`| optional | Locale-keyed overrides; missing keys fall back to base columns |
60
60
|**manifestId**|`string`| optional | Optional declarative default for the published package id (reverse-domain, e.g. com.acme.crm). Absent on a template source tree: `objectstack package publish` falls back to --manifest-id and then to a derived `local.<slug>`. NOT optional on the publish request itself |
61
61
|**name**|`never`| optional |[REMOVED]`TemplateManifest.name` was removed in @objectstack/spec 18 (ADR-0049) — nothing read it: `os package publish` addresses the package by `manifestId` (or derives one from the compiled artifact), and a project's slug is its `package.json``name`. Delete the key. |
0 commit comments