Skip to content

gen:openapi's artifact is ungated AND is deleted by gen:schema's cleanup — the one combination where staleness is invisible #11216

Description

@os-sam

Measured while verifying #10928 (PR #11213). Outside that card's declared file surface, so recorded rather than fixed. Filed unassigned per finding discipline.

What

check:generated reports its own coverage gap on every run:

Generated but ungated (2): gen:openapi, gen:sbom — nothing verifies these are current.

Separately, AGENTS.md documents that gen:schema's cleanup wipes gen:openapi's output, with the recovery being pnpm --filter @objectstack/spec gen:openapi. Each half is known. The finding is that they compose badly: the one generated artifact that another generator silently deletes is also the one nothing checks.

Measured here, incidentally

I hashed all generated JSON schemas twice while proving my diff changed none of them:

  • Baseline taken immediately after pnpm --filter @objectstack/spec check:authorable-surface (which runs gen:schema): 1584 files, json-schema/openapi.jsonabsent.
  • After a full turbo run build (which runs gen:openapi): 1585 files, openapi.json present, and all 1584 originals byte-for-byte identical.

So the deletion is real and reproducible on a clean tree, by running a green check. No gate anywhere notices the file is gone, and the next build puts it back — which is exactly why it stays invisible.

Why it is worth recording rather than shrugging at

./openapi.json is a published entry point (packages/spec/package.jsonexports), so this is not an internal scratch artifact. The failure mode is not "the file goes missing" — a build restores it. It is that nothing establishes the committed/published copy ever matched the schemas it is derived from, and the one operation that would make them diverge (running gen:schema alone, then publishing without a full build) leaves no trace. Compare check:authorable-surface, which does gate its artifact and is loud about the anchor.

gen:sbom is named in the same line as ungated and is not analysed here — I only measured the openapi half.

Not proposing a shape

Whether the answer is a check:openapi mirroring check:authorable-surface, making gen:schema's cleanup narrower so it stops deleting a sibling's output, or a note that the artifact is build-only and should not be read from a partially-generated tree, is a call for whoever owns the generator set.

Backlink: #10928 · PR #11213 · packages/spec/scripts/check-generated.ts (prints the gap) · AGENTS.md packages/spec clause (documents the deletion)

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions