Skip to content

finding(docs): ci-cd-pipeline.md's Lint section names 1 of the 4 scripts/check-*.mjs gates that job runs, and nothing pins it the way ci.yml's job table is pinned #8015

Description

@claude

Found while implementing objectui#7692 (the bash 3.2 floor gate, which adds a step to lint.yml). Out of scope for that card; filed rather than fixed.

The gap

content/docs/guide/ci-cd-pipeline.md's ## Lint (\lint.yml`)` section describes the job's steps in prose:

  • scripts/check-lint-coverage.mjs runs first: every package must run ESLint or be declared a known gap. […]
  • Then pnpm lint.
  • Then pnpm check […]

Measured on origin/main 28cfff4 by parsing the workflow and testing each first-party command against that section's text:

command the lint job runs named in that section
scripts/check-lint-coverage.mjs yes
pnpm lint yes
pnpm check yes
scripts/check-entry-guard.mjs no
scripts/check-upstream-port-parity.mjs no
scripts/check-cross-repo-closer-outcome.mjs no

So three blocking gates in a required check run undescribed on the page whose stated job is to tell a contributor which checks can block them. All three predate objectui#7692; that card adds a fourth step and, per its dispatch, does not touch the page (nothing forced a row — see "Why no test caught it").

Positive control for the reading: the same scan, same parser, same section text, reports scripts/check-lint-coverage.mjs, pnpm lint and pnpm check as PRESENT. A zero is not being read off a broken matcher.

Why no test caught it

scripts/__tests__/ci-cd-pipeline-doc.test.ts has exactly the pin this needs — names every first-party command the job actually runs plus its inverse credits no job with a first-party command it does not run — and it is scoped to ONE workflow:

describe('ci-cd-pipeline.md — ci.yml job table', () => {
  const ciWorkflow = fs.readFileSync(path.join(workflowDir, 'ci.yml'), 'utf8');

lint.yml is covered only by the workflow-INVENTORY pin, which requires a heading naming the file and nothing about its contents. lint.yml has a heading, so it passes while its step list drifts. That is objectui#3212's shape one level down: the page reads as authoritative about a required gate, and the part that is wrong is the part nothing looks at.

Direction of harm is the one this repository treats as worst — the page UNDERSTATES the gate, so a contributor reading it to find out why Lint is red will not find check-entry-guard or check-upstream-port-parity there at all.

Shape of the fix (not asserted)

Either extend the existing both-directions command pin to lint.yml (the job is a single lint job, so it needs no job-table parse — a section-scoped command set on both sides would do), or move lint.yml's steps into a pinned table the way ci.yml's are. Updating the prose alone repeats the drift, which is the lesson that test file records at length for this same page.

Related but distinct, both on this page and neither covering this: objectui#8006 (the check-skills-paths.mjs description at line 551) and objectui#7965 (three drifted live counts).

Filed unassigned, finding.


Generated by Claude Code

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

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions