Repository navigation
Commit 60f9baf
docs(spec): the routes / App.apis retire text stops sending app authors to an imperative http.server route (ruling C′ item 2) (#23785)
Fixes #23216
Clause-②: no
Ruling C′ on #23128 (`6142279866`), item 2: the imperative `http.server`
route is retired as an app-author surface. This PR changes the retire
text and the published copies so they no longer send app authors to a
`kernel:ready` handler. An app declares `defineStack({ apis })` (`type:
'object_operation'` or `'flow'`, ADR-0121), computes in a flow, and
registers code as a stack function (`defineStack({ functions })`) or a
connector. The `http.server` service, `core-service-contracts.ts` and
the platform plugins that mount on it are untouched. No key is added or
removed.
## What changed
| Site | Change |
|:---|:---|
| `packages/spec/src/kernel/manifest.zod.ts` (`contributes.routes`
retire message + TSDoc) | The imperative sentence is replaced by the
app-author rule, with the reason: a code-mounted route gets no caller
identity, auth gate, rate limit, namespace carve-out or OpenAPI entry. |
| `packages/spec/src/ui/app.zod.ts` (`App.apis` retire message) |
**Surface extension, declared here.** The dispatch hypothesis said this
row was a different key and should be edited only if it said the same
thing. It does: it said "A route that genuinely needs handler CODE is
mounted imperatively instead: resolve the `http.server` service …
register the route on `kernel:ready`". This is the source of the
`metadata.mdx` / `app.mdx` hits that the acceptance grep covers, and the
claim names `metadata.mdx` "where it renders the same text". Code now
goes to a flow plus a stack function or connector. |
|
`packages/spec/src/migrations/entries/semantic/18.plugin-manifest-contributes-routes-retired.ts`
| The published `replacement` no longer gives the imperative advice or
names the deleted showcase `POST /api/v1/showcase/recalc` route.
`acceptanceCriteria` now describes the current teaching sites. `reason`
is kept as is, because it records the earlier ruling. |
| `packages/spec/src/api/plugin-rest-api.zod.ts:34-39` TSDoc | The
example now says it shows a **platform** plugin mounting its own doors,
and states the app-author rule. The deleted recalc-endpoint "real
consumer" claim is removed. |
| `packages/spec/src/api/dispatcher.zod.ts` docblock item 4 (+ generated
`api/dispatcher.mdx`) | Patch round (contract review FAIL `6206636299`
on `3c31cd913e`): `http.server` is the platform plugins' own
door-building primitive; an app declares `defineStack({ apis })`,
computes in a flow, and registers code as a stack function or connector.
The `contributes.routes` removal clause is kept. |
| `packages/spec/src/kernel/metadata-plugin.zod.ts:119,127`,
`manifest.zod.ts:753`,
`retired-keys/18.kernel__Manifest__contributes.routes.ts:10`, migration
18 `reason` | Sweep fixes: the comments no longer present the imperative
mount as the app answer, and the 2026-08-22 provenance gains one
sentence saying ruling record 6142279866 narrowed the redirect. |
| `packages/spec/liveness/manifest.json` row note | Same correction: the
recalc-endpoint mention is removed and `http.server` is described as the
platform plugins' primitive. |
| `scripts/check-optional-error-sink-contract.mjs:164` scope comment |
`examples/**` now holds zero further red sinks, not one, because the
recalc route was deleted. Comment only. |
| `packages/spec/src/kernel/manifest.test.ts` | The pin's regex used to
match `…http\.server` (the old advice). It now asserts the new rule's
substance (`does not mount routes on http.server` … `defineStack({ apis
})` … flow … `defineStack({ functions })` … connector) and that
`kernel:ready` / the imperative wording does not come back. The pin is
changed, not deleted. |
| `content/docs/references/**` (5 pages) | **Generated, not
hand-edited:** `pnpm --filter @objectstack/spec check:generated --fix`
(it proved only `check:docs` stale) rewrote `kernel/manifest.mdx`,
`api/package-api.mdx`, `api/metadata.mdx`, `ui/app.mdx`,
`api/plugin-rest-api.mdx`. |
| `.changeset/23216-routes-retire-text.md` | `@objectstack/spec`
`patch`. |
Each of the four pointer sites from `6147168221` was re-read on `main`
at `4fe8b3def`. All four were still stale, and all four are edited here;
none had been fixed already.
## Acceptance
- `git grep -n "mounted imperatively" -- packages/spec content/docs`
finds nothing (exit 1).
- The manifest reference page renders the new sentence
(`content/docs/references/kernel/manifest.mdx:92`): "… Delete the key.
An app does not mount routes on `http.server` — that service is the
platform's own door-building primitive, … Declare the endpoint under
`defineStack({ apis })` (`type: 'object_operation'` or `'flow'`,
ADR-0121), compute in a flow, and register code as a stack function
(`defineStack({ functions })`) or a connector."
- `pnpm --filter @objectstack/spec build && pnpm --filter
@objectstack/spec check:generated`: "All 14 generated artifacts are up
to date", exit 0.
- `pnpm --filter @objectstack/spec typecheck && pnpm --filter
@objectstack/spec test`: 680 files, 20784 passed, 1 todo, exit 0. This
includes `retired-key-migrate-sentence.test.ts` and its family, and
`manifest.test.ts`.
- Derived gates at head `846feb0c` (134 families): 131 exit 0, 3 NOT
MEASURED (exit 3, declared to CI: teardown-shape self-test,
dual-build-cjs-loads, lean-entry-closure); `--ran` reconciles 134 / 131
/ 3 / 0 UNRUN, exit 0.
## Imperativ sweep (patch round)
git grep -n -i imperativ -- packages/spec/src content/docs (releases/
excluded) at 846feb0. FIXED (app-author route advice):
api/dispatcher.zod.ts:17 + references/api/dispatcher.mdx:19;
kernel/metadata-plugin.zod.ts:119,127; kernel/manifest.zod.ts:753
(provenance, supersede note added);
migrations/entries/retired-keys/18.kernel__Manifest__contributes.routes.ts:10
(same); semantic/18.plugin-manifest-contributes-routes-retired.ts reason
(closing sentence added). KEPT, platform-only:
api/plugin-rest-api.zod.ts:32 + plugin-rest-api.mdx:32 heading, now
'Serving routes from a platform plugin (imperative http.server mount)';
the example is a platform plugin mounting its own doors, which the
ruling keeps. KEPT, provenance of the 2026-08-22 ruling, with the
narrowing now stated in the same field: semantic/18…routes-retired.ts
reason lines 23/33/41. KEPT, different capability (not routes or
http.server): manifest.zod.ts:811 and
semantic/18.plugin-manifest-contributes-dead-members-retired.ts:15/36
plus retired-keys/18…contributes.events.ts:10 (event subscription in
plugin code); manifest.zod.ts:851 + package-api.mdx:233/manifest.mdx:88
(engine.registerAction); studio/plugin.zod.ts +
references/studio/plugin.mdx (Studio component activation). KEPT,
unrelated word sense: concepts/glossary/protocol prose 'imperative code'
vs declarative; retired-key.ts:303, retired-key.test.ts:159,
ui/component.test.ts:1375/1382, ui/form-option-enum-derive.test.ts:86,
kernel/manifest.test.ts:406/552 ('an imperative fix' = an
imperative-mood prescription); manifest.test.ts:462 is the negative pin
itself. kernel:ready beside http.server sweep: only
content/docs/kernel/events.mdx:22/35 and
contracts/plugin-lifecycle-events.ts:77, which describe kernel lifecycle
and platform HTTP middleware, not app routes; kept. git grep 'mounted
imperatively' -- packages/spec content/docs: exit 1.
## Acceptance notes
- The published skill `skills/objectstack-api/SKILL.md:119` still has a
decision-table row: "`http.server` mount (plugin code) — The endpoint
needs real handler CODE … Mount it on `http.server`." It is the same
retired advice, and its eval
`skills/objectstack-api/evals/endpoints-auth-routes.json` may pin it.
Both are outside this card's claimed surface, and `skills/**` is a Tier
H governed surface, so they are not edited here. They are reported to
the seat to file.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
https://claude.ai/code/session_017dvSKLgBT3sjuE98di6PW1
---
_Generated by [Claude
Code](https://claude.ai/code/session_017dvSKLgBT3sjuE98di6PW1)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent 9b799e6 commit 60f9baf
17 files changed
Lines changed: 108 additions & 64 deletions
File tree
- .changeset
- content/docs/references
- api
- kernel
- ui
- packages/spec
- liveness
- src
- api
- kernel
- migrations/entries
- retired-keys
- semantic
- ui
- scripts
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
19 | | - | |
20 | | - | |
21 | | - | |
22 | | - | |
23 | | - | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
24 | 27 | | |
25 | 28 | | |
26 | 29 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
99 | 99 | | |
100 | 100 | | |
101 | 101 | | |
102 | | - | |
| 102 | + | |
103 | 103 | | |
104 | 104 | | |
105 | 105 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
234 | 234 | | |
235 | 235 | | |
236 | 236 | | |
237 | | - | |
| 237 | + | |
238 | 238 | | |
239 | 239 | | |
240 | 240 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
29 | 29 | | |
30 | 30 | | |
31 | 31 | | |
32 | | - | |
| 32 | + | |
33 | 33 | | |
34 | | - | |
35 | | - | |
36 | | - | |
37 | | - | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
38 | 40 | | |
39 | 41 | | |
40 | 42 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
89 | 89 | | |
90 | 90 | | |
91 | 91 | | |
92 | | - | |
| 92 | + | |
93 | 93 | | |
94 | 94 | | |
95 | 95 | | |
| |||
0 commit comments