diff --git a/.changeset/expired-docblock-member-and-command-counts.md b/.changeset/expired-docblock-member-and-command-counts.md new file mode 100644 index 0000000000..b590660a30 --- /dev/null +++ b/.changeset/expired-docblock-member-and-command-counts.md @@ -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. diff --git a/examples/app-multi-package/src/packages/orders/index.ts b/examples/app-multi-package/src/packages/orders/index.ts index 46ea1919c8..3b77e13858 100644 --- a/examples/app-multi-package/src/packages/orders/index.ts +++ b/examples/app-multi-package/src/packages/orders/index.ts @@ -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: { diff --git a/packages/spec/src/contracts/automation-service.ts b/packages/spec/src/contracts/automation-service.ts index aabe2113d2..2d82047493 100644 --- a/packages/spec/src/contracts/automation-service.ts +++ b/packages/spec/src/contracts/automation-service.ts @@ -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′): diff --git a/packages/spec/src/ui/app.zod.ts b/packages/spec/src/ui/app.zod.ts index ea9a5bff13..d124663c97 100644 --- a/packages/spec/src/ui/app.zod.ts +++ b/packages/spec/src/ui/app.zod.ts @@ -753,9 +753,15 @@ export const NavigationItemSchema: z.ZodType