Skip to content

check:skill-examples leaves packages/spec/.examples-build/ behind, and check:docs-audit-scope then fails its own self-test in the same working tree #15446

Description

@os-litant

Filed out of scope from #15079. Found while running that card's derived gate union: two gates that are each green in isolation, where running one first reds the other.

Reproduce

In a clean checkout, in this order:

pnpm --filter @objectstack/spec run check:skill-examples   # compiles marked examples
pnpm check:docs-audit-scope                                # now FAILS
✗ self-test "every contract declaration admitted is a packages/spec API declaration":
  kind=contract → expected scanRouteSurface=true, got false

✗ affected-docs self-test failed (1 case(s)).

rm -rf packages/spec/.examples-build and re-running check:docs-audit-scope is green again — measured, both directions.

Why

check:skill-examples writes the marked doc/skill examples out as compilable TypeScript under packages/spec/.examples-build/ (gitignored, .gitignore:68). scripts/docs-audit/affected-docs.mjs's scanRouteSurface() walks source files on the FILESYSTEM, so those emitted files enter the walk, and five of them declare a path: beside an HTTP method and are therefore admitted as kind-contract route sources:

packages/spec/.examples-build/docs__api_declarative-endpoints__1.ts
packages/spec/.examples-build/docs__api_declarative-endpoints__2.ts
packages/spec/.examples-build/docs__getting-started_quick-reference__2.ts
packages/spec/.examples-build/docs__protocol_kernel_http-protocol__1.ts
packages/spec/.examples-build/skills__objectstack-api_SKILL__1.ts

The self-test's pin — liveKind('contract').every((f) => f.startsWith('packages/spec/src/api/')) — is exactly the shape assertion those five violate. The pin is correct; the walk's population is what includes a scratch directory.

Status on CI today, stated rather than assumed

Green, by step ordering only: in .github/workflows/lint.yml, pnpm check:docs-audit-scope runs at line 1975 and pnpm --filter @objectstack/spec run check:skill-examples at line 5227, so the scratch directory does not exist yet when the scope gate runs. That is a latent coupling, not a design: reordering the steps, splitting them across jobs differently, or any local run in the natural order (gate union alphabetical, or "run the docs gates after the spec gates") reds a gate that has nothing wrong with it. The cost lands on whoever is holding an unrelated diff at the time — it did here.

Candidate fixes (a lane call, not asserted)

  • Exclude **/.examples-build/** from the scanRouteSurface / source walk in scripts/docs-audit/affected-docs.mjs, beside the existing isTestFile exclusions. Narrowest, and the walk already has the notion of "not a real source input".
  • Or have check-skill-examples.ts emit into a path outside the repo tree (or clean up after itself).

The first is preferable: it makes the walk's population a stated property of the walk rather than a property of which other gates have run.

Refs

scripts/docs-audit/affected-docs.mjs (the walk and the self-test pin) · packages/spec/scripts/check-skill-examples.ts (the emitter) · .gitignore:68 · found from #15079

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions