Skip to content
Merged
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
13 changes: 13 additions & 0 deletions .changeset/expired-docblock-member-and-command-counts.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
---
"@objectstack/spec": patch
---

Two spec docblocks now say what the tree does: `StrandedRunState` is no longer given a member list here, and the `navigationContributions[].group` JSDoc names the mis-aimed case (#16708, #16507)

**`contracts/automation-service.ts`** — the `AutomationResult.status` docblock explains why plugin-approvals' `StrandedRunState` is deliberately *not* promoted to this status, and it did so through a parenthetical copy of that union's members, `'missing' | 'failed'`. The plugin has since split `'failed'` into `'repairable'`, `'snapshot_dropped'` and `'unrepairable'` (the #15358 discriminator), so the copy described a shape the type contradicted — a spec docblock telling a reader the type cannot express a distinction the platform had already published. The copy is **removed rather than refreshed**: the union is plugin-local, is declared and documented member by member on the type itself, and `automation-result-status.pin.test.ts` excludes it from its pins *on purpose*, so any member list restated in this package is unpinned prose with nothing to keep it honest. The docblock now names where the members live instead of counting them.

**`ui/app.zod.ts`** — the JSDoc above `NavigationContributionSchema` documented only the case where `group` is **omitted**, while the `.describe()` a few lines below it (corrected in #14925) also names the case where `group` is **present and names no group the target app declares**. The two halves of one key's authoring-time documentation disagreed, and they disagreed on the case an author cannot detect from their own source — the target app belongs to another package. The JSDoc now carries that case in the spelling the `.describe()` and `content/docs/ui/setup-app.mdx` already use: not refused, items appended at the app top level anyway, a `nav_contribution_group_missing` diagnostic emitted by the runtime at `warn` and by `os build` and `os validate` at compile time.

Prose only, in both files. No type, no schema, no accept set and no exported name moves; nothing that reaches a generated artefact changed, so the reference pages, the authorable surface and the JSON-Schema manifest are byte-identical. The changeset exists because both strings **ship**: `src/**/*.zod.ts` is in this package's `files[]`, and both docblocks are emitted into the published `dist/*.d.ts`.

One private fixture comment rides along, outside any published package: `examples/app-multi-package/src/packages/orders/index.ts` credited only `os build` with the compile-time finding, where `findNavGroupDiagnostics` has been folded into both `os build` and `os validate` since #14920.
9 changes: 5 additions & 4 deletions examples/app-multi-package/src/packages/orders/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,11 @@ import { defineStack } from '@objectstack/spec';
* ⚠️ `group` names `sales_group`, a container the CORE package declares. A
* module cannot see that id at authoring time, and a typo in it does not fail:
* the runtime RELOCATES the items to the app's top level and says so
* (`nav_contribution_group_missing`, at `warn`), and `os build` reports the
* same finding at compile time. This fixture is where that is measured — keep
* the id spelled correctly here, so a build of this example stays clean and the
* pin that typos it has something to differ from.
* (`nav_contribution_group_missing`, at `warn`), and `os build` and
* `os validate` report the same finding at compile time. This fixture is
* where that is measured — keep the id spelled correctly here, so a build of
* this example stays clean and the pin that typos it has something to differ
* from.
*/
export default defineStack({
manifest: {
Expand Down
13 changes: 9 additions & 4 deletions packages/spec/src/contracts/automation-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -342,10 +342,15 @@ export interface AutomationResult {
* something to repair. This member is the ruling's contract half; the
* engine begins stamping it when #13937's services half (the re-arm verb
* and the catch-arm stamp in `resumeInternal`) lands. plugin-approvals'
* `StrandedRunState` (`'missing' | 'failed'`) is a report-only label over
* a request's run and is deliberately NOT promoted to this status (same
* ruling): it classifies WHY a request's run is unrecoverable, this names
* the run's own lifecycle verdict.
* `StrandedRunState` is a report-only label over a request's run and is
* deliberately NOT promoted to this status (same ruling): it classifies
* WHY a request's run is unrecoverable, this names the run's own lifecycle
* verdict. ⛔ Its members are deliberately NOT restated here: the union is
* plugin-local — declared, and documented member by member, on the type
* itself in `plugins/plugin-approvals/src/approval-service.ts` — and
* `automation-result-status.pin.test.ts` excludes it from its pins on
* purpose, so a member list copied into this file is unpinned prose that
* goes stale the next time the plugin splits an arm.
*
* `'refused'` names the run that reached an `end` node declaring
* `outcome: 'refused'` (#14945; maintainer ruling 2026-09-05, option 2′):
Expand Down
12 changes: 9 additions & 3 deletions packages/spec/src/ui/app.zod.ts
Original file line number Diff line number Diff line change
Expand Up @@ -753,9 +753,15 @@ export const NavigationItemSchema: z.ZodType<NavigationItem, NavigationItemInput
* The runtime merges all contributions into the owning app's `navigation`
* tree by **target group id + priority** (lower priority applied first,
* mirroring object extender ordering). When `group` is omitted the items are
* appended at the app's top level. Contributed items keep the normal nav
* gating fields (`requiresObject` / `requiredPermissions` / `visible`), so an
* uninstalled capability simply contributes nothing and its slot stays empty.
* appended at the app's top level. Naming a group the target app does not
* declare is not refused either: the items are appended at the app top level
* anyway and a `nav_contribution_group_missing` diagnostic is emitted — by the
* runtime at `warn`, and by `os build` and `os validate` at compile time. That
* second case is the one an author cannot detect from their own source,
* because the target app belongs to another package. Contributed items keep
* the normal nav gating fields (`requiresObject` / `requiredPermissions` /
* `visible`), so an uninstalled capability simply contributes nothing and its
* slot stays empty.
*
* @example
* {
Expand Down
Loading