Skip to content

decision(ci): check:doc-examples is declared in package.json and run by no workflow — wire it, or record that it is hand-run only #8757

Description

@os-warren

Filed unassigned by the os-dev seat implementing #8221 (branch claude/issue-8221-retire-legacy-string-sort). Deliberately NOT fixed there — different defect class, and #8221's diff must stay on the sort retirement.

Measured, with a control at the merge base

node scripts/check-doc-example-types.mjs exits 1 on an unmodified origin/main, one failure:

UNDECLARED FAILURE  packages/types/src/zod/imported-defaults.ts:318 stripImportedDefaults
  [semantic]  packages/types/src/zod/imported-defaults.ts:319:28  TS2304: Cannot find name 'stripImportedDefaults'.

The measurement was taken in a separate detached worktree at f6205c10 (the merge base), pnpm install, then the build the gate itself prescribes (pnpm exec turbo run build $(node scripts/check-doc-snippet-types.mjs --build-filter) --concurrency=2, exit 0), then the gate. Exactly one UNDECLARED FAILURE there, and exactly the same one on the #8221 branch — the delta from that branch is zero, which is what makes this a property of main and not of a pull request.

Control that the gate is not simply refusing everything: on the same run it judged every other @example block in the tree and reported no other failure and no stale ledger row.

The example

packages/types/src/zod/imported-defaults.ts:318-322:

import { ListViewSchema as ImportedSpecListViewSchema } from '@objectstack/spec/ui';
const SpecListViewSchema = stripImportedDefaults(ImportedSpecListViewSchema);

The block imports the spec schema it operates on but never imports stripImportedDefaults, which is the very symbol the example documents. The gate compiles each block in isolation against the built types, so the free identifier is TS2304.

It arrived with PR #8721 (objectui#8317), merged 645087cd at 2026-09-09T02:24Z — about two hours before this reading.

Why nobody saw it

check:doc-examples is declared in package.json and is run by no workflow:

git grep -rn "doc-examples\|check-doc-example-types" -- .github package.json
package.json:68:    "check:doc-examples": "node scripts/check-doc-example-types.mjs",

Control that the read fires: the sibling check:doc-snippets is grepped the same way and does appear in .github/workflows/doc-snippet-types.yml. So the absence above is a reading, not a bad grep.

⚠️ The half that IS enforced per PR is scripts/__tests__/check-doc-example-types.test.ts (it runs under pnpm test), and it only asserts that every LEDGER ROW names a real block. It does not assert the absence of undeclared failures, so this class is invisible to CI in both directions.

The two honest routes

  1. Fix the example — add import { stripImportedDefaults } from './imported-defaults'; (or make the fenced block a usage fragment that declares it), so the gate goes green on its own terms.
  2. Declare it — add a ledger row keyed packages/types/src/zod/imported-defaults.ts:318 stripImportedDefaults carrying codes [2304], a written reason and the card that owns it, which is the escape hatch the gate itself prints.

⚠️ Route 2 on a symbol's OWN example is the weaker one: the ledger's existing rows are all "usage fragment references symbols the example never declares", i.e. context the example deliberately elides. Here the missing name is the documented function itself, which is the one name a reader will copy.

⚠️ Separately worth a decision, and NOT assumed here: whether check:doc-examples should join a workflow at all. A gate with a ledger and a maintained escape hatch that nothing runs is a gate that will keep drifting; but wiring it is a CI-surface decision, so it is named rather than taken.

⛔ Note that the LINE NUMBER in a ledger key moves whenever anything above it in the file moves — #8221 had to re-key packages/types/src/objectql.ts:1604 ObjectFormSchema to :1607 purely because three lines were added higher up. That coupling is a separate observation and is not part of this card.

Dedup

MCP search_issues on repo:objectstack-ai/objectui stripImportedDefaults example returned total_count: 0. Known-hit control on the same tool in the same session: repo:objectstack-ai/objectui convertSortToQueryParams returned total_count: 2 (#8221, #6006), so the zero above is a reading and not a silently cleared query.

Related: #8317 (the card whose PR added the example), #8221 (the card whose seat measured this).

Filed by an agent seat via Claude Code, session session_01Jmxdo7bmeqCQHLSfmLVX9w.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    ci/cddomain:devxobjectui devx stream: fix lands on .github/, scripts/ or release pipeline — devx lane cross-repofindingpriority:p2tooling

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions