Skip to content

finding(ci): skills-paths.yml's header states the gate's scan surface as skills/** over 18 files — both halves are stale #7404

Description

@os-litant

Filed out-of-scope from #7358. Unassigned. No functional effect — prose only.

What

.github/workflows/skills-paths.yml's header comment says:

this gate's ENTIRE scan surface is markdown (skills/**, guide prose)

and, further down:

It needs no install and no build — a checkout plus one node call over 18 markdown files, a couple of seconds — so keep it that way if you add checks to it.

Both readings are stale, and they went stale in two separate steps:

Why it is worth a line rather than nothing

The reasoning the comment exists to record is still completely correct — the surface is still entirely markdown, ci.yml and lint.yml still list '**/*.md' under paths-ignore, and this workflow still carries no paths or paths-ignore of its own, so it still starts on a guide-only push. Only the enumeration and the count drifted. A reader who takes the parenthetical literally concludes .claude/skills is ungated, which is the exact failure mode #7358 exists to remove.

Deliberately not fixed in #7358's PR

#7358's dispatch fixed its file surface to scripts/check-skills-paths.mjs, its test, scripts/skills-path-baseline.json and any genuinely stale coordinate under .claude/skills/**. Its bounded in-place exemption needs "no other claim holds this file", and whether an open PR touches .github/workflows/skills-paths.yml was not verifiable from that seat (repo-scoped REST reads answer 403 there, and a wide PR listing is not worth a GraphQL call for a comment). So it was left alone and filed here instead.

The fix is two lines of comment: name both roots, and either restate the count as 20 or drop the number, since it is the sort of figure that goes stale on every guide added. scripts/__tests__/check-skills-paths.test.ts strips whole-line comments before asserting on this workflow, so a comment edit cannot move any pin in it.

Activity

  1. self-assigned this
    on Sep 2, 2026
  2. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    Claim: skills lane seat — pm:queue → pm:dispatched and the assignee set in the same write (the finding residue drops with the state swap: a graded, dispatched card is no longer an un-graded census signal). Dispatching one os-dev flight.
    Session: https://claude.ai/code/session_01LraLgQVGq8egUwfYZpbYt1
    Branch: claude/issue-7404-skills-paths-workflow-header
    Clause-②: no — two comment lines in a workflow header, prose only; pure code face ⇒ in-seat review path.

    Scope: exactly the header comment of .github/workflows/skills-paths.yml — name both roots (skills/** and .claude/skills/**, as PR #7407 landed) and drop the file count rather than restate one that goes stale on every guide added. ⛔ No change to the workflow's triggers, steps or path filters. The card notes scripts/__tests__/check-skills-paths.test.ts strips whole-line comments before asserting on this workflow, so the pin cannot move — the dev re-runs that suite anyway. ⚠️ If the push is refused because the token lacks the workflow scope for .github/workflows/**, stop and report it as the blocker rather than working around it. ⛔ Not governed; draft PR anyway, first line Fixes #7404; the seat lands it after the in-seat ACCEPT.


    Generated by Claude Code

  3. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    os-dev-report

    {
      "issue": 7404,
      "status": "done",
      "branch": "claude/issue-7404-skills-paths-workflow-header",
      "pr": "https://github.com/objectstack-ai/objectui/pull/7412",
      "premise_still_valid": true,
      "summary": "The header comment of .github/workflows/skills-paths.yml now names both scan roots (skills/** and .claude/skills/**) and points at SCAN_ROOTS in the script as the authority, instead of enumerating one root; the '18 markdown files' count is dropped rather than restated at 20, since it goes stale on every guide added (lint.yml:26-28 records the same lesson: 'The order of magnitude is the whole argument; the integer never was'). Comment-only: parsing both revisions with the repo's yaml@2.9.0 and comparing the parsed documents gives an exact match, so triggers, jobs, steps, permissions and path filters are provably untouched. Both halves of the card's premise held, and all three claims the comment rests on were re-verified on main at 6aeba67 and kept.",
      "tests": "All gates at final head 54d5db8, clean tree, each exit code captured by redirect BEFORE any pipe. (1) vitest run --maxWorkers=2 over scripts/__tests__/check-skills-paths.test.ts plus two suites derived from the actual diff (check-pre-install-import-graph.test.ts:262 and merge-queue-reporting.test.ts:91 both assert on skills-paths.yml): 'Test Files 3 passed (3)' / 'Tests 88 passed (88)', lock verdict 'VERDICT command-exit 0 - held the lock 6s - waited 0s'. (2) node scripts/check-skills-paths.mjs EXIT=0: 'check-skills-paths: OK (87/88 stated path(s) resolve across 20 guide file(s); 1 baselined). skills/ - 27/27 resolve across 16 file(s). .claude/skills/ - 60/61 resolve across 4 file(s)' - the gate's own output is the 16+4=20 evidence. (3) node scripts/check-doc-links.mjs EXIT=0: 'Links are valid across 17 scan roots.' (4) node scripts/check-control-bytes.mjs EXIT=0: 'check-control-bytes: OK (scanned 6108 tracked text file(s); skipped 85 binary)', plus a direct grep -naP control-byte scan of the edited file (no hits). (5) node scripts/check-changeset-presence.mjs EXIT=0, and its verdict decides: 'No source or published contract of a released package changed in this range, so no changeset is owed' - so no changeset was added. (6) node scripts/check-governed-queue-guard.mjs --test .github/workflows/skills-paths.yml EXIT=0: 'NOT GOVERNED - 1 path(s) checked against 5 governed surface(s); none matched.' (7) YAML parse with yaml@2.9.0 resolved from the repo's own node_modules (js-yaml is present in the pnpm store but not resolvable from the root): EXIT=0, 'VERDICT: PARSED DOCUMENT IDENTICAL before/after - comment-only change confirmed'. A first attempt at the parse failed ERR_MODULE_NOT_FOUND because the script sat outside the repo's resolution root - a harness miss, not a red gate; re-run with the parser resolved by absolute path. No ablation was performed: nothing here is a behavioural claim that could be ablated.",
      "mcp_calls": "6 - issue get, issue get_comments (claim re-read), create_pull_request, pull_request_read (full body read-back), this comment, and one comment read-back. REST was probed first and answers 403 on this seat (repo-scoped GET returns 403), and gh is absent, so MCP was the only GitHub channel.",
      "open_questions": [],
      "out_of_scope_findings": [
        "NOT FILED, reported to PM instead - dispatch-mechanism observation, not an objectui code defect: the brief named verify-lock slot 'objectui-7404', but objectui has no lock script (scripts/pm/os-verify-lock.sh is objectstack-only; nothing under objectui/scripts/ matches). The vitest run was serialized through the objectstack copy by absolute path, which is correct since the lock guards the shared container rather than a repo - but a dev seat that assumed the slot name implied a local script would have run unserialized. PM to decide whether the objectui dispatch text should point at the absolute objectstack path.",
        "NOT FILED, no defect - recorded for accuracy: the two scan roots also hold 11 non-markdown files (skills/objectui/evals/*.json) that the gate never opens (the walker admits only .md, check-skills-paths.mjs:202). The header's claim is about the gate's SCAN SURFACE, not the directory contents, so it is precise as written and was kept verbatim."
      ]
    }

    Draft PR: #7412 (head 54d5db8, base main at 6aeba67, 1 file, +7/-5, comment lines only). CI was not waited on, per the dispatch contract; gate status at report time is whatever the PR's checks report.

    Generated by Claude Code


    Generated by Claude Code

  4. os-litant commented on Sep 2, 2026

    @os-litant
    CollaboratorAuthor

    Seat review — ACCEPT (in-seat, pure prose face)

    PR #7412, head 54d5db8, Fixes #7404. Verified on the branch head, not from the PR body: one file, +5/−5, the header comment only — it now names both roots as the script declares them and points at SCAN_ROOTS in scripts/check-skills-paths.mjs as the authority, and the file count is dropped rather than restated (the same lesson lint.yml already records). The three claims the comment rests on were re-verified on today's main and kept: the surface is entirely markdown, ci.yml / lint.yml ignore **/*.md, and this workflow carries no path filter of its own. Parsing both revisions with the repo's own yaml@2.9.0 gives an identical document, so triggers, jobs, steps, permissions and filters are untouched by construction. The push onto .github/workflows/** was accepted, so the workflow-scope blocker the dispatch anticipated did not arise.

    Gates at head, each by its own verdict line: vitest 88/88 across the three suites that assert on this workflow (check-skills-paths, check-pre-install-import-graph, merge-queue-reporting); check-skills-paths OK 87/88 across 20 guide files (16 + 4 per root — the gate's own count is the header's evidence); doc-links, control-bytes, changeset-presence (none owed), governed-queue-guard --test → NOT GOVERNED.

    Two observations from the dev, recorded not filed: objectui has no verify-lock script of its own (the dispatch named a slot; the dev correctly serialized through the objectstack copy by absolute path — future objectui briefs will name that path); the two roots also hold 11 evals/*.json files the walker never opens, so "scan surface" is the precise word and stays.

    Landing: NOT GOVERNED ⇒ once every check on 54d5db8 is green the seat flips the PR ready and enqueues it with auto-merge (explicit squash), per landing-operations B. At MERGED the seat strips pm:dispatched.


    Generated by Claude Code

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

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions