Skip to content
Draft
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
25 changes: 25 additions & 0 deletions .changeset/31035-template-manifest-inert-keys-retired.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
---
'@objectstack/spec': minor
'@objectstack/cli': minor
'create-objectstack': patch
---

feat(spec)!: retire five `objectstack.manifest.json` keys nothing read — `name`, `specVersion`, `skills`, `scaffold` and `visibility` (#31035)

Clause-②: no (narrowing) — five authorable keys of `TemplateManifestSchema` become tombstones, and `os package publish` refuses the file's `visibility` by name
Metadata-protocol: narrowed

<!-- adr-0087: registered marketplace-template-manifest-inert-keys-retired -->

**BREAKING** for an `objectstack.manifest.json` that still writes any of the five keys, and for `os package publish` run on a manifest that declares `visibility`.

- **Retired (ADR-0049 enforce-or-remove).** `TemplateManifest.name`, `.specVersion`, `.skills`, `.scaffold` and `.visibility` are `retiredKey()` tombstones: `tsc` refuses them and a parse of `TemplateManifestSchema` refuses each with its prescription. None ever had an effect: no reader of the file's `name`, `specVersion`, `skills` or `scaffold` existed, and `os package publish` read `visibility` only to warn that it ignores it. `RETIRED_KEYS_BY_MAJOR[18]` lists the five keys and the upgrade guide carries the semantic entry `marketplace-template-manifest-inert-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 `visibility` (`CreatePackageRequestSchema`) is unchanged.
- **Migration** — FROM → TO, in `objectstack.manifest.json`:
- `name` → delete it. The project slug is `package.json` `name`; the published package id is `manifestId` (or the one `os package publish` derives from the compiled artifact).
- `specVersion` → delete it. The protocol your package needs is `manifest.engines.protocol` in `objectstack.config.ts`; the spec release it builds against is its `@objectstack/spec` dependency.
- `skills` → delete it. create-objectstack installs the whole skills catalog.
- `scaffold` → delete it. Nothing prompted for `scaffold.variables` or ran `scaffold.postInstall`.
- `visibility` → delete it and pass `os package publish --visibility <private|org|marketplace>`.
- **`@objectstack/cli`.** `os package publish` refuses a manifest declaring `visibility` before any network call, naming `--visibility`. It names the other four in a warning for deletion and still publishes, because every project scaffolded from the blank template before this release carries them.
- **`create-objectstack`.** The blank template's manifest drops the five keys it wrote (`name`, `specVersion`, `skills`, `scaffold`), and scaffolding strips every retired key (`category` and these five, one list pinned to the spec's registry rows) from the template's manifest instead of writing `name`, so a template authored before this release still scaffolds a manifest the schema accepts. The release version pass (`scripts/sync-template-versions.mjs`) no longer stamps `specVersion`.
- **Not retired here:** `publisher` and `isStarter`. A first-party publish script sends both to the hosted packages route, so their fate is a maintainer decision.
4 changes: 3 additions & 1 deletion content/docs/deployment/cli.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -3307,7 +3307,9 @@ checked against the spec's schema before anything is sent, and a declared
`solutionType` against the built artifact: a `template` needs the `unmanaged`
install mode, a `connector` a declared connector. The retired `category` — in
the file, or as `--category` — is refused before any network call, with the
facets that replace the value it held. `tags` has no flag and is
facets that replace the value it held, and so is a `visibility` in the file
(pass `--visibility`). The retired `name`, `specVersion`, `skills` and
`scaffold`, which nothing ever read, are named in a warning for deletion. `tags` has no flag and is
sent as written: the control plane judges the list, and a refusal is its 400,
printed as it is. A top-level `tagline` is used only as the description, when
neither `--description` nor the file's `description` gives one; otherwise it is
Expand Down
16 changes: 10 additions & 6 deletions content/docs/deployment/marketplace-handbook.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -96,6 +96,9 @@ with no image to caption. The schema also accepts `publisher` and `isStarter`,
but the platform decides both: an author's value has no effect, so
`os package publish` never sends them and prints a warning naming each one the
file declares. `tags` is different: it is sent as written (see the table above).
The file no longer accepts `visibility` (pass `--visibility`; publish refuses the
key by name) nor `name`, `specVersion`, `skills` or `scaffold`, which nothing
ever read: publish names each one still present so you can delete it.
Put the icon, the description, the tags, the tagline and the README where the
table above says, and nothing else.
</Callout>
Expand Down Expand Up @@ -139,10 +142,11 @@ npx os verify # boots the app in-process and proves it through the real H
npm run build # os build -> dist/objectstack.json
```

Two declarations name the platform major your app is authored against:
`engines.protocol` in the `defineStack` manifest, and `specVersion` in
`objectstack.manifest.json`. A runtime outside the `engines.protocol` range
refuses the app rather than half-loading it. See
One declaration names the platform major your app is authored against:
`engines.protocol` in the `defineStack` manifest. A runtime outside that range
refuses the app rather than half-loading it. (The `specVersion` an older
scaffold wrote into `objectstack.manifest.json` was never read, and spec 18
retired it: delete it.) See
[Validating metadata](/docs/deployment/validating-metadata) for what the checks
cover.

Expand Down Expand Up @@ -261,8 +265,8 @@ loaded, and the app's page shows **Not loaded** with the protocol range it
targets.

To move, run `os migrate meta --from <the major you authored against>` on your
source, apply what it lists, update `engines.protocol` and `specVersion`,
rebuild, and publish a new version. [Upgrading](/docs/upgrading#the-metadata-app)
source, apply what it lists, update `engines.protocol`, rebuild, and publish a
new version. [Upgrading](/docs/upgrading#the-metadata-app)
owns the loop.

## Extras: dependencies and modules
Expand Down
2 changes: 1 addition & 1 deletion content/docs/getting-started/your-first-project.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -104,7 +104,7 @@ between all four entry points by the artifact you want rather than by the word.
```
my-app/
├── objectstack.config.ts # defineStack() — the single entry point
├── objectstack.manifest.json # name, namespace, specVersion
├── objectstack.manifest.json # displayName, namespace — the package listing
├── package.json
├── tsconfig.json
├── note.test.ts # the starter test `npm test` runs
Expand Down
14 changes: 7 additions & 7 deletions content/docs/references/marketplace/template-manifest.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ description: "objectstack.manifest.json — on-disk descriptor for a template /

`objectstack.manifest.json` — on-disk descriptor for a template / package
source tree. Strict projection of `CreatePackageRequestSchema` (server-
managed fields excluded) plus scaffold-time extras (name slug,
specVersion, namespace, skills, preview, scaffold, readmePath), with
managed fields excluded) plus scaffold-time extras (namespace, preview,
readmePath), with
`manifestId` locally relaxed to OPTIONAL — this file is a source tree, not
a publish request (#7319; the field's own TSDoc carries the measurement).

Expand Down Expand Up @@ -44,7 +44,7 @@ objectstack.manifest.json — template / package source descriptor
| :--- | :--- | :--- | :--- |
| **displayName** | `string` | ✅ | Display name shown in Studio and Marketplace |
| **description** | `string` | optional | Short package description |
| **visibility** | `Enum<'private' \| 'org' \| 'marketplace'>` | optional | Package visibility: private = owner org only; org = all envs in owner org; marketplace = public registry |
| **visibility** | `never` | optional | [REMOVED] `TemplateManifest.visibility` was removed in @objectstack/spec 18 (ADR-0049) — `os package publish` never read it from this file. Delete the key and pass `--visibility` (`private`, `org` or `marketplace`) to `os package publish`. |
| **category** | `never` | optional | [REMOVED] `TemplateManifest.category` was removed in @objectstack/spec 18 (ADR-0087) — one category had to say both who a package is for and what it is, and the platform and the cloud catalog spelled it from lists that disagreed. Delete the key. Declare `businessFunctions` (1-3 business functions, the primary one first), optionally `industries` (up to 3; absent means cross-industry) and `solutionType` (`app`, `template` or `connector`; absent means `app`). `LEGACY_CATEGORY_MAPPING` in @objectstack/spec/marketplace gives the facets for every old category value. |
| **businessFunctions** | `Enum<'sales' \| 'marketing' \| 'customer-service' \| 'finance' \| 'hr' \| 'supply-chain' \| 'administration' \| 'project' \| 'legal' \| 'it' \| 'collaboration'>[]` | optional | Business functions the package serves: 1-3 distinct values, the first is primary |
| **industries** | `Enum<'manufacturing' \| 'trade-distribution' \| 'retail' \| 'logistics' \| 'professional-services' \| 'financial-services' \| 'healthcare' \| 'education' \| 'public-sector' \| 'real-estate-construction'>[]` | optional | Industries the package is built for: up to 3 distinct values; absent means cross-industry |
Expand All @@ -58,12 +58,12 @@ objectstack.manifest.json — template / package source descriptor
| **isStarter** | `boolean` | optional | |
| **translations** | `Record<string, { displayName?: string; description?: string; readme?: string; tagline?: string; … }>` | optional | Locale-keyed overrides; missing keys fall back to base columns |
| **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 |
| **name** | `string` | ✅ | CLI slug (kebab-case, no namespace prefix) |
| **specVersion** | `string` | ✅ | Compatible @objectstack/spec semver range |
| **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. |
| **specVersion** | `never` | optional | [REMOVED] `TemplateManifest.specVersion` was removed in @objectstack/spec 18 (ADR-0049) — nothing read it. Delete the key. The protocol a package needs is `manifest.engines.protocol` in `objectstack.config.ts` (the handshake the runtime checks), and the spec release it builds against is the `@objectstack/spec` version in `package.json`. |
| **namespace** | `string` | optional | Scaffold-only: the template’s own metadata namespace, rewritten by create-objectstack at scaffold time and read back as the fallback source for the template’s original namespace. NOT the publish namespace — publish reads that off the compiled artifact’s manifest.namespace (ADR-0048 addendum §A.2) |
| **skills** | `string[]` | optional | Skill ids exercised by this template (for docs / picker) |
| **skills** | `never` | optional | [REMOVED] `TemplateManifest.skills` was removed in @objectstack/spec 18 (ADR-0049) — nothing read it: create-objectstack installs the whole `@objectstack/skills` catalog whatever this file lists. Delete the key. |
| **preview** | `{ screenshots?: string[]; demoUrl?: string }` | optional | |
| **scaffold** | `{ variables?: Record<string, any>; postInstall?: string[] }` | optional | |
| **scaffold** | `never` | optional | [REMOVED] `TemplateManifest.scaffold` was removed in @objectstack/spec 18 (ADR-0049) — nothing read it: create-objectstack never prompted for `scaffold.variables` nor ran `scaffold.postInstall`. Delete the key. |
| **readmePath** | `string` | optional | Path (relative to manifest) to long-form README |

### Nested Shape: `TemplateManifest.translations[string]`
Expand Down
11 changes: 6 additions & 5 deletions content/docs/upgrading.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -83,11 +83,12 @@ command for this move; it is four steps you run yourself.
what older scaffolds wrote) moves entirely here. Read whatever
peer-dependency warnings this prints — the `--frozen-lockfile` install your CI
runs skips resolution and will never print them.
3. **Check the two protocol declarations your app ships** — `specVersion` in
`objectstack.manifest.json`, and `engines.protocol` in your `defineStack`
manifest. Both name the protocol **major**, so a move inside one major leaves
both alone, and a major boundary is where they change. Move them deliberately
when you cross one; never edit them to silence a mismatch.
3. **Check the protocol declaration your app ships** — `engines.protocol` in
your `defineStack` manifest. It names the protocol **major**, so a move inside
one major leaves it alone, and a major boundary is where it changes. Move it
deliberately when you cross one; never edit it to silence a mismatch. (An
older scaffold also wrote `specVersion` into `objectstack.manifest.json`.
Nothing ever read it, and spec 18 retired it: delete it.)
4. **Re-install the AI skills from the moved catalog, and commit them.** The
skills your coding agent reads come from the `@objectstack/skills` dev
dependency, which moves only with the other `@objectstack/*` packages — in
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,4 +19,4 @@ hand-patch a number here** — fix the code or the verdict and regenerate.

| Dir | Sites |
|---|---|
| `marketplace/` | 31 |
| `marketplace/` | 30 |
2 changes: 0 additions & 2 deletions packages/apps/connector-docusign/objectstack.manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
"manifestId": "app.objectstack.connector-docusign",
"name": "connector-docusign",
"specVersion": "^18.0.0",
"displayName": "DocuSign eSignature",
"description": "Send documents for signature, read envelopes and follow their signature status from flows, over DocuSign's eSignature OpenAPI document. Developer sandbox; your administrator registers their own DocuSign integration key.",
"businessFunctions": ["collaboration", "legal"],
Expand Down
2 changes: 0 additions & 2 deletions packages/apps/connector-github/objectstack.manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
"manifestId": "app.objectstack.connector-github",
"name": "connector-github",
"specVersion": "^18.0.0",
"displayName": "GitHub",
"description": "Search and read GitHub issues and pull requests from flows, through GitHub's remote MCP server. Read only.",
"businessFunctions": ["it"],
Expand Down
2 changes: 0 additions & 2 deletions packages/apps/connector-stripe/objectstack.manifest.json
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
{
"$schema": "https://schemas.objectstack.dev/template-manifest.json",
"manifestId": "app.objectstack.connector-stripe",
"name": "connector-stripe",
"specVersion": "^18.0.0",
"displayName": "Stripe",
"description": "Read Stripe customers, charges, invoices and payment intents from flows, over Stripe's own OpenAPI document. Read only.",
"businessFunctions": ["finance"],
Expand Down
Loading
Loading