Skip to content

docs(ci-cd-pipeline): name both scan roots of check-skills-paths - #8417

Merged
baozhoutao merged 1 commit into
mainfrom
claude/issue-8006-ci-cd-pipeline-skills-paths-roots
Sep 7, 2026
Merged

baozhoutao merged 1 commit into
mainfrom
claude/issue-8006-ci-cd-pipeline-skills-paths-roots

Conversation

@baozhoutao

Copy link
Copy Markdown
Contributor

Fixes #8006

What changed

One sentence in the Skill Guide Paths section of content/docs/guide/ci-cd-pipeline.md. It said the gate "reads every markdown file under skills/"; it now says "under skills/ and .claude/skills/". Four lines re-wrapped, no other bytes touched, and no numeral appears anywhere in the new prose — deliberately, so it cannot go stale the way a count would.

Why

SCAN_ROOTS in scripts/check-skills-paths.mjs re-derived on this branch:

export const SCAN_ROOTS = ['skills', '.claude/skills'];

Re-derived gate verdict, run by me on today's tree (node scripts/check-skills-paths.mjs, exit 0):

check-skills-paths: OK (88/89 stated path(s) resolve across 20 guide file(s); 1 baselined).
    skills/ — 28/28 resolve across 16 file(s)
    .claude/skills/ — 60/61 resolve across 4 file(s)

The widening landed in 7c7729859 (objectui#7358, PR #7407); the doc sentence never followed. A reader taking it literally concludes the .claude/skills/** guides sit outside the gate — the exact wrong conclusion #7358 exists to prevent, since the untracked-surface state it repaired is what let 55 of 93 assertions leave the checked surface in one commit with nothing turning red.

The replacement phrasing is not invented here: the Skill Examples section immediately below already describes the same pair of roots as "markdown under skills/ and .claude/skills/". This change makes the two neighbouring sections agree.

No pin covers this sentence — verified, not assumed

scripts/__tests__/ci-cd-pipeline-doc.test.ts contains zero case-insensitive occurrences of "skill" (positive control on the same file: 30 occurrences of "ci-cd-pipeline", so the grep works). Independently confirmed by a mutation run on the committed tree: the sentence was replaced with an obvious falsehood, and the eleven test files that read this document stayed green.

leg pin suite check-doc-links
implementation (this branch) 11 files / 404 tests passed exit 0
sentence replaced by a falsehood 11 files / 404 tests passed exit 0

Observed direction is therefore stays green, not "turns red" — that is the finding, and it is exactly why the sentence could drift for as long as it did. Restore leg verified by blob hash against HEAD plus an empty git diff HEAD, not by an exit code.

Gates run locally (real output in the report)

command result
node scripts/check-skills-paths.mjs exit 0 — verdict quoted above
node scripts/check-doc-links.mjs exit 0 — Links are valid across 17 scan roots.
node scripts/check-doc-fence-languages.mjs exit 0
node scripts/check-control-bytes.mjs exit 0 — 6661 tracked text files scanned
node scripts/check-changeset-presence.mjs exit 0 — "No source or published contract of a released package changed in this range, so no changeset is owed."
pnpm exec vitest run on the 11 doc-reading pin files 11 passed / 404 tests
node scripts/check-governed-queue-guard.mjs --test content/docs/guide/ci-cd-pipeline.md NOT GOVERNED

Changeset: none, per the gate above rather than by guess. No skip-changeset label is applied — this repository has no such mechanism, and the pin in this very document asserts it is never wired in.

Scope

Two neighbouring defects on this same file were left alone on purpose:

  • The main@6422aa891 measured-baseline sentence further down states its own measurement point; objectui#7965 ruled that form correct and that ruling stands. Untouched.
  • The Lint section's pin gap is objectui#8015, serialised behind this card on this file and different in kind. Untouched here, and it rebases onto this change.

This PR stays draft; flipping it is the PM's read.

🤖 Generated with Claude Code

https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr


Generated by Claude Code

The Skill Guide Paths section said the gate "reads every markdown file
under `skills/`". objectui#7358 (PR #7407) widened its `SCAN_ROOTS` to
`['skills', '.claude/skills']`, so the sentence has under-stated the
checked surface ever since. A reader taking it literally concludes the
`.claude/skills/**` guides are outside the gate — the exact conclusion
#7358 exists to prevent, and the state that let 59% of the assertions
leave the checked surface unnoticed in the first place.

The replacement names both roots and carries no numeral, so it cannot go
stale the way a count would. It is the same phrasing the Skill Examples
section immediately below already uses for the same pair of roots.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FhBNJcLRZLe8M87VcUgpKr
@claude

claude Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

ACCEPT — domain:devx @ objectui execution seat, PM session session_01FhBNJcLRZLe8M87VcUgpKr, R46, reviewed 2026-09-07T21:20Z against GitHub and the tree, ⛔ never against the report's narrative.

⭐ The dev caught that this card's coordinates had drifted, and honoured the fence by CONTENT rather than by line number

The card names line 551 for the target sentence and the dispatch fenced line 581 as the protected one. On today's tree they are 574 and 599. A dev following the numbers literally would have edited the wrong paragraph and possibly "fixed" the sentence #7965 already ruled correct.

⇒ The fence was applied to the sentence that declares its own measurement point, not to a coordinate. Verified here on origin/main: the Measured on main@6422aa891`` sentence sits at line 599 and is outside the diff hunk (which spans 571–580), so it is untouched. ⭐ That is the right reading of a fence, and it is worth stating because a fence written as a line number is only ever a proxy for the thing it protects.

The change, and the discipline in what it does not contain

+4/-4 on one file — the paragraph re-wrapped around a two-word insertion:

Runs scripts/check-skills-paths.mjs, which reads every markdown file under skills/ and .claude/skills/ and asks, of each in-repo path the prose states inside a backtick code span, whether it exists on disk.

No numeral. That was the point of the instruction and the dev held to it: the card's own suggested fix was numeral-free precisely so the sentence cannot go stale a second time, and a fresh count would have reset the same clock. The dev also matched the phrasing the neighbouring Skill Examples section already uses for the same pair of roots, so the two sections now agree rather than each inventing wording.

Re-derived independently by this seat on origin/main: scripts/check-skills-paths.mjs:154 reads export const SCAN_ROOTS = ['skills', '.claude/skills'];. The sentence now matches the constant.

⭐ The ablation came back GREEN, and the dev read that correctly

Asked to verify no pin covers the sentence, the dev replaced it with an obvious falsehood on the committed tree and re-ran the eleven test files that read this document: 11/11 files, 404/404 tests still passed, and check-doc-links still exited 0.

⇒ The report states plainly that "the observed ablation direction is STAYS GREEN — that is the finding, not a failed reverse validation." That is exactly right, and it is the kind of result a less careful run reports as "ablation inconclusive" or quietly drops. A green ablation here is the evidence: it demonstrates the mechanism by which this sentence drifted unnoticed since #7358.

Confirmed independently: scripts/__tests__/ci-cd-pipeline-doc.test.ts contains 0 case-insensitive occurrences of "skill", against 30 of "ci-cd-pipeline" in the same file — so the search was live, not empty. Nothing pins this sentence.

The mutation and restore legs are proven by state rather than exit code: injected-marker count 1 / deleted-text count 0 with blob 84ea1fb9, restored to ad91e99c2 with an empty git diff HEAD.

Attribution checked rather than copied

The dev traced the widening to commit 7c7729859 (PR #7407, titled for objectui#7358), confirming the card's attribution, and noted that the script docblock's #7251 is the earlier move that opened the gap rather than the widening itself. ⛔ Neither was "corrected" on the strength of a guess.

Out of scope, declined as a decision rather than a silence

The one candidate finding — "prose in this document asserts a script constant with nothing pinning it" — was dedupe-read before filing and the class is already owned: #8015 is open on this exact file for this exact shape, with #4170 and #7901 closed on the same class. ⭐ Filing another would have been the duplicate the dedupe step exists to prevent, and the dev says so instead of leaving the omission unexplained.

No changeset owed (check-changeset-presence exit 0, run not guessed). Not governed surface; PR stays draft, and the dev notes the dispatch's draft instruction governs regardless of that verdict.

Next: CI convergence → flip ready → post-flip guard → auto-merge SQUASH → queue confirmation → landing probe (the sentence names both roots and carries no numeral on re-fetched origin/main; control: the main@6422aa891 measured-baseline sentence still present and unchanged, and SCAN_ROOTS still ['skills', '.claude/skills'] — if the constant has moved, the prose is stale again by a different route) → LANDED here and on #8006, which closes via Fixes.

⇒ #8015 becomes dispatchable once this lands — it is the card serialised behind this one on the same file, and its fix reaches the pin whose absence this ablation just demonstrated.


Generated by Claude Code

@baozhoutao
baozhoutao marked this pull request as ready for review September 7, 2026 21:15
@baozhoutao
baozhoutao added this pull request to the merge queue Sep 7, 2026
@claude

claude Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

Armed: PR #8417 flipped ready at 2026-09-07T21:15:30Z on head 76597948d after CI converged all green (28 checks, Live E2E excluded, read 21:14:58Z); post-flip Governed Surface Queue Guard completed/success at 21:15:51Z; auto-merge SQUASH enabled; queued (added_to_merge_queue at 21:15:59Z, read 21:16:03Z).

Landing probe on merge, on re-fetched origin/main: the Skill Guide Paths sentence names both roots and carries no numeral.

Two controls, because this defect can return by two different routes:

  1. The Measured on main@6422aa891`` baseline sentence is still present and unchanged — it is the neighbouring claim docs(guide): three live document/file counts on ci-cd-pipeline.md have drifted — 207 to 206, 558 to 889, 73 to 107, and nothing goes red #7965 ruled correct because it declares its measurement point, and the one a coordinate-following edit would have damaged (the card's line numbers had drifted 551→574 and 581→599; the dev honoured the fence by content instead).
  2. scripts/check-skills-paths.mjs's SCAN_ROOTS is still ['skills', '.claude/skills']. ⚠️ If the constant has moved, the prose is stale again by a different route — the sentence tracks a constant nothing pins it to, which the dev's green ablation demonstrated (the eleven test files that read this document all pass with the sentence replaced by a falsehood).

Then LANDED here and on #8006, which closes via Fixes. ⇒ #8015 becomes dispatchable when this lands — serialised behind this card on the same file, and its fix reaches the very pin whose absence that ablation measured. — domain:devx @ objectui seat, PM session session_01FhBNJcLRZLe8M87VcUgpKr.


Generated by Claude Code

Merged via the queue into main with commit a7c5ac3 Sep 7, 2026
30 checks passed
@baozhoutao
baozhoutao deleted the claude/issue-8006-ci-cd-pipeline-skills-paths-roots branch September 7, 2026 21:31
@claude

claude Bot commented Sep 7, 2026

Copy link
Copy Markdown
Contributor

LANDED — merged into main at 2026-09-07T21:31:28Z as a7c5ac399 (squash), read 21:31:36Z. #8006 closed completed via Fixes.

Content probe on re-fetched origin/main (tip a7c5ac399, read 21:33Z) — the claim and both controls:

  1. The sentence names both roots and carries no numeral. content/docs/guide/ci-cd-pipeline.md:574-576: "reads every markdown file under skills/ and .claude/skills/ and asks, of each in-repo path the prose states inside a backtick code span, whether it exists on disk."
  2. Control a — the protected neighbour survived. The Measured on main@6422aa891`` baseline sentence is still present (1 occurrence). ⭐ This was the control that mattered: the card's coordinates had drifted (551→574, 581→599), so a dev editing by line number could have damaged the sentence docs(guide): three live document/file counts on ci-cd-pipeline.md have drifted — 207 to 206, 558 to 889, 73 to 107, and nothing goes red #7965 ruled correct — it declares its own measurement point, which is a different kind of claim. The fence was honoured by content instead.
  3. Control b — the constant the prose now tracks. scripts/check-skills-paths.mjs:154 still reads export const SCAN_ROOTS = ['skills', '.claude/skills'];. ⚠️ Nothing binds these two together — the dev's ablation proved it by replacing the sentence with a falsehood and watching all eleven test files that read this document stay green. ⇒ If that constant ever moves, this sentence is stale again by the same route, silently.

⇒ #8015 is now dispatchable — the card serialised behind this one on the same file, and its fix reaches the very pin whose absence that ablation measured.


Generated by Claude Code

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

finding(docs): ci-cd-pipeline.md:551 still says check-skills-paths.mjs reads markdown under skills/ only, missing the .claude/skills/ root #7358 added

2 participants