Skip to content
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 36 additions & 0 deletions .github/workflows/lint.yml
Original file line numberDiff line numberDiff line change
Expand Up@@ -1081,6 +1081,42 @@ jobs:
- name: Check the decision frame is in sync across its four copies
run: pnpm check:skill-frame-sync

# The SECOND skill-frame gate — and deliberately only HALF of it (#8110).
#
# `pnpm check:skill-frame-freshness` is `--self-test && the scan`, and only the
# SCAN half is CI-hostile: it asks "is THIS WORKING TREE's frame current with
# origin/main?", which on a fresh merge ref is a tautological green, and on any
# PR that legitimately edits the frame would be a false red — "differs from main"
# is that PR's whole purpose. That script's own header ("WHERE IT RUNS") argues
# it, and the scan stays out of CI for exactly that reason. It is NOT wired here.
#
# The `--self-test` half is a different animal. It DERIVES a coherent two-axis
# specimen from this tree's own frame documents, commits it and the real
# documents into throwaway git repos whose `origin` points at a path that does
# not exist, and asserts 12 verdicts against the gate's own code. No network, no
# origin/main, no history: measured green in a `--depth 1` clone carrying no
# remote-tracking ref at all, in ~1.3s. So the half that CANNOT run in CI was
# keeping the half that CAN out of it, and the price was measured on #8024 —
# the fixture had stranded TWICE, neither time noticed, while the gate sat in
# the gate list reading as coverage and protecting nothing.
#
# This step cannot redden a PR that edits the frame on purpose: the specimen is
# re-derived from whatever the frame currently is, so a reword, a reflow or a
# principles-only rewrite carries the fixture with it (verified adversarially
# before wiring this — rewording axis prose across all three frame files keeps
# both gates green). What DOES redden it is a STRUCTURAL change — an axis added,
# removed, or its declaring sentence reworded past the shared anchors — and that
# reddens `check:skill-frame-sync` directly above with the same diagnosis, which
# the self-test's own failure message names as the thing to fix first. No PR can
# reach this step red with the step above green.
#
# Invoked as `node`, NOT `pnpm check:skill-frame-freshness`, precisely because
# that npm script would drag the scan half in with it — the same shape as the
# `dev` chain calling check-dev-prereqs.mjs directly rather than through its
# pnpm script (see that script's header).
- name: Self-test the skill-frame freshness gate (self-test half only, never the scan)
run: node scripts/check-skill-frame-freshness.mjs --self-test

# The third gate over SKILL.md, covering the one line the other two cannot see
# (#5331). check:skill-docs / check:skill-refs compare generated artifacts and
# check:skill-examples typechecks `os:check` blocks; none of them reads the
Expand Down
Loading