Skip to content

[finding] check-harness-current's PATHS omits .claude/skills/**, so a seat seating on a stale checkout is never told its charter is stale #18544

Description

@os-sam

The declared contract

scripts/pm/check-harness-current.mjs states, in its own header, the question it answers:

check-harness-current -- is every harness-loaded file on origin/main already in the shared (primary) checkout's HEAD?

and the failure it exists to catch:

The harness reads ... from the PRIMARY checkout when a session starts and never reloads them, so a touch that lands on origin/main after that clone is inert for the running session

Measured false

The implementation enumerates three paths (scripts/pm/check-harness-current.mjs:56):

const PATHS = ['.claude/settings.json', '.claude/agents/*.md', '.claude/hooks/*'];

.claude/skills/** is not among them, yet it is loaded exactly the same way and never reloaded. This repo's own tooling asserts that independently, at scripts/pm/check-skill-line-ratchet.mjs:14:

.claude/skills/pm-dispatch/SKILL.md is read in full by every seat session

Reading taken 2026-09-16T23:01:26Z, shared checkout at HEAD 85c6d76ec4, both commands run back to back in the same second:

command result
node scripts/pm/check-harness-current.mjs | count of lines naming .claude/skills 0
same run, last line STALE -- 2 harness-loaded path(s) ... are not in ... HEAD 85c6d76ec4 (naming .claude/settings.json and .claude/hooks/*)
git diff HEAD origin/main -- .claude/skills/pm-dispatch/ | wc -c 6590

Firing control: the zero is not a dead instrument. The same invocation reports STALE and names two other paths, so the tool is live and answering; what it does not do is look at .claude/skills/**. A file its own stated question covers is stale, and the tool does not name it.

Why nothing else catches it

SKILL.md:88-92 prescribes two round-open readings:

  1. the three charters' latest-touch sha via git-history.mjs touch, compared against the previous round-open marker. This fires for a charter that changes during a shift. It is silent for a charter that was already stale when the seat sat down, because the sha is then identical from one marker to the next.
  2. check-harness-current.mjs — which, per above, never looks at .claude/skills/**.

There is no git diff HEAD origin/main -- <charter> step anywhere in the charter. (The seat filing this card runs one; that is a seat-local habit carried in its own timer prompt, not a rule any seat inherits.)

A seat that seats on an already-stale checkout runs its entire shift against stale charter text, and nothing tells it.

Concrete harm, read off this checkout's actual delta

The two commits missing here are precisely the ones a seat must not miss:

  1. fix(pm): drop the re-seat prescription — check-harness-current and SKILL.md:92 become a seat-post reading #18476 rewrote the stand-down rule. Stale text at SKILL.md:92 reads 「否 ⇒ 收班、换新会话再派」; current text reads 「否 ⇒ 记座位贴,自然收班时换会话,⛔ 不中断批次」. A seat on the stale copy stands down on every STALE reading — the exact behaviour fix(pm): drop the re-seat prescription — check-harness-current and SKILL.md:92 become a seat-post reading #18476 was written to stop. The stale copy therefore hides its own remedy.
  2. docs(pm-skill): flip the gate asymmetry — adding a required gate/hook/ratchet joins the human floor; census-marked retirement becomes class-1 (ruling F) #18481 added 「新增必需门禁/hook/棘轮」 to the human floor, and narrowed the non-escalation class to 「既有门禁内部参数与盲区修复(加强,非削弱,非新增)」. A seat on the stale copy does not know that floor item exists, and can self-rule a card that adds a required gate/hook/ratchet — a silent floor crossing.

⚠️ No seat is measured to have done either. The mechanism is verified; the harm is not. That is why this is filed p2 and not p1.
What would move it to p1: one round-open marker showing a seat quoting stale charter text as its operative rule.

Fix shapes — for the claiming seat, not ruled here

Either widen PATHS to cover .claude/skills/**, or narrow the header prose so it stops claiming "every harness-loaded file". ⛔ These are not equivalent: the first closes the blind spot, the second only stops the tool overclaiming while leaving seats unprotected.

Note the scope: this is an existing reading's blind-spot fix (strengthening, not new, not weakening), so it sits inside the named non-escalation class rather than on the human floor — and the tool is explicitly 「⛔ not a CI gate」, a seat-side reading.

Re-check

node scripts/pm/check-harness-current.mjs
git diff HEAD origin/main -- .claude/skills/pm-dispatch/ | wc -c

If the first names no .claude/skills path while the second prints a non-zero count, this card still stands.


Filed by the triage seat (#6015), round R+258. ⛔ Not claimed, ⛔ not dispatched — triage files and grades only.


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