Repository navigation
Commit 340eab7
ci(release): the post-version guard admits the SKILL.md stamps through stampedSkillPaths() (#22980)
Fixes #22970
Clause-②: no
Refs #22085 (the version-PR lane: the first scheduled `release.yml` run
after this lands is the reading owed there).
## What changed
- **The export.** `scripts/check-skill-compatibility-version.mjs`
exports `stampedSkillPaths({ root })`: every repo-relative
`skills/NAME/SKILL.md` path its `--fix` may write, in walk order,
derived from `readSkillFiles()`. The `--fix` leg itself moved into an
exported `applyFix(scanned, pkgs, root)` that writes from that same
walk, so the list and the writes come from one walk. Zero skills throws,
the same way `stampedPaths()` does. The one EXEMPT file
(`skills/objectstack-upgrade/SKILL.md`) is in the list, because the
exemption covers its pin and not its `metadata.version` stamp. `main()`
prints the same lines as before.
- **The fourth list, `release.yml`** (the `Validate the post-version
tree` step only): `SKILL_LIST` is resolved by `node --input-type=module
-e 'import { stampedSkillPaths } ...'`. It has the siblings' two
refusals: could not resolve, and resolved EMPTY. It is added as a fifth
whole-line exact filter, `grep -vxF -f "${SKILL_LIST}"`, after the three
existing lists.
- **The judging gate.** `run_gate pnpm check:skill-compatibility`
(self-test plus check, no `--fix`) now runs in the content half, after
`check:release-index-currency-sync`.
- **The fourth list, `cut-rc.yml`** (`Build the single version commit`):
the same resolve and the same two refusals. `SKILL_SURFACES` joins the
`git add -A` pathspec, and `SKILL_LIST` joins the `BAD` re-check as the
fifth filter.
- Not touched: `skills/**`, the root `version` script, `.changeset/**`,
`content/docs/releases/**`. There is no regex widening: the skill paths
are admitted only by exact match against the exported list.
## The dispatch's hypotheses, measured
- **H1 (where the guard sits, parity checkers).** The guard is at
`release.yml` `Validate the post-version tree` and at `cut-rc.yml`'s
`BAD` filter, as stated. I ran `git grep` for
`TEMPLATE_LIST|SURFACE_LIST|INDEX_LIST|post-version-paths|stampedPaths|syncedPaths`
outside the two workflows and the two rewriters. It hits only:
- create-objectstack's own `stampedPaths()` test;
- a comment in `scripts/cross-package-test-inputs.mjs`;
- two unrelated `H43_`/`H48_SURFACE_LIST_CAP` constants in
`scripts/pm/check-half-states.mjs`.
**No parity checker pins the list count or the three names, so none had
to learn the fourth list.** `check-self-test-wired` credits the new
`./scripts/...` import the same way it credits the existing ones, and it
stays green.
- **H2 (import safety).** The script already carried the entry-point
guard (`if (isEntrypoint(import.meta.url)) main();`). Importing it the
workflow way prints the 10 paths, writes nothing (`git status` stays
clean), and exits 0. `pnpm check:entry-guard` is green.
- **H3 (the list).** On this tree the list is the 10 published skills.
They are exactly the 10 `unexpected:` paths of run 38212422606,
`objectstack-upgrade` included.
- **H4 (the judging gate).** `check:skill-compatibility` was absent from
`release.yml` and is now added to its content half. `cut-rc.yml` carries
no post-version content half: its gates are pre-version and read
`.changeset/`. So no `run_gate` was added there. Its `Version the
workspace` step already goes red on a wrong stamp, because `--fix`
re-checks what it wrote and exits 1.
- **H5 (the content half on a real `18.0.0-next.0` tree).** Measured
below.
- **H6 (size).** +187/-20 over 3 files. The workflows are +45/-7. The
script is +142/-13, about 95 of which are the self-test rows and their
fixture.
## H5: the version pass and the step, run on a scratch tree
I made a scratch worktree at this branch's `9540d87a8` (`origin/main`
`246edf5b3` plus the two commits here) and ran `pnpm install
--frozen-lockfile`. I then ran the `Render the post-version tree` and
`Validate the post-version tree` step bodies, extracted verbatim from
this branch's `release.yml`, with `RUNNER_TEMP` and
`GITHUB_STEP_SUMMARY` pointed at scratch files. The scratch tree was
discarded afterwards, and nothing from the version pass was committed.
- **Render:** 426 pending changesets consumed and 1021 paths moved.
`check-skill-compatibility-version --fix` reported "10 of 10 SKILL.md
file(s) rewritten" (`@objectstack/spec 17.x → 18.x`, `metadata.version
"17.7.0" → "18.0.0-next.0"`; the upgrade skill's stamp only), then its
own check passed. `protocol-version.ts` did not move.
- **Control: the guard as it is on `main`** (the step extracted from
`246edf5b3`), run on the same rendered tree: 10 lines of `unexpected:
skills/...SKILL.md`, then the treadmill refusal, exit 1. This is run
38212422606's signature.
- **This branch's guard on the same tree:** the shape check passed and
the content half ran in full. Step summary: 1021 paths, all inside the
reviewed shape; template stamps moved: 3; content gates failed: 0;
unvalidated: 0. It ended with `Post-version tree validated.`
(verify-lock `VERDICT command-exit 0`).
| content gate (`run_gate`) | verdict on the `18.0.0-next.0` tree |
|---|---|
| `pnpm check:docs-image-tag` | green (3/3 surfaces, pins at the newest
GA 17.7.0, pre mode) |
| `pnpm check:docs-image-tag-sync` | green |
| `pnpm check:template-version-sync` | green |
| `pnpm check:release-index-currency-sync` | green |
| `pnpm check:skill-compatibility` (new) | green: 10 files, 11 pins at
18.x, 10 stamps at 18.0.0-next.0, 1 exemption |
| `pnpm check:nul-bytes` | green (10995 text files) |
| `pnpm check:release-notes` | green |
| `pnpm check:release-page-status` | green (v16, v17 in scope) |
| `node scripts/check-release-section-coverage.mjs` | green |
| `pnpm check:published-readme-links` | green |
| `pnpm --filter create-objectstack --fail-if-no-match test` | green (18
files, 261 tests) |
| `pnpm --filter @objectstack/spec --fail-if-no-match
check:template-manifests` | green |
| `pnpm --filter @objectstack/spec ... vitest run --project local
src/kernel/protocol-version.test.ts` | green |
| `pnpm --filter @objectstack/spec --fail-if-no-match
check:spec-changes` | green |
| `pnpm --filter @objectstack/spec --fail-if-no-match
check:upgrade-guide` | green |
Two more readings on the same rendered tree:
- **The judging gate can fail.** I restored
`skills/objectstack-ai/SKILL.md` to its pre-version bytes. `node
scripts/check-skill-compatibility-version.mjs` then exited 1 with 2
problems naming that file: the `17.7.0` stamp and the `17.x` pin.
`--fix` put it back.
- **`cut-rc.yml`'s staging and allowlist half** (from the `SURFACE_LIST`
resolve down to the `LEFT` check, with no git config, reset or commit):
- the step as it is on `main` refuses with 10 `unstaged:
skills/...SKILL.md` lines (exit 1), so an RC cut would fail the same
way;
- this branch stages 595 paths, 10 of them the skill stamps, and `BAD`
and `LEFT` are both empty.
- Not part of the step, read because AGENTS.md ties SKILL.md edits to
it: `pnpm --filter @objectstack/spec check:skill-docs` is green on the
rendered tree.
## Self-test pin and ablation
`check:skill-compatibility`'s self-test gains three registered rows. The
battery floor moves 27 → 30.
- **The export equals the set `--fix` writes.** The fixture is
all-stale: two skills plus the exempt-shaped one, a skill directory with
no SKILL.md, `skills/README.md`, and an internal
`.claude/skills/internal/SKILL.md`. The export is compared against the
set `applyFix` writes on that fixture, in walk order. The row also
checks that the writes landed under the fixture root and that the
internal skill was not touched.
- **A SKILL.md write outside the export stays unexpected.** The row
writes the list the way the workflows print it and spawns the guard's
own `grep -vxF -f LIST MOVED`. Three outside paths
(`.claude/skills/internal/SKILL.md`, `skills/a/nested/SKILL.md`,
`skills/no-skill-md/SKILL.md`) come back as unexpected, exit 0. Control:
the listed set alone is all admitted (exit 1, no output).
- **An empty tree throws.** It never yields an empty list.
**Ablation** (one-off, after the commit, through
`scripts/ablation-replace.mjs`). The mutation widened the export's
return to append `.claude/skills/internal/SKILL.md`, and the tool
confirmed it landed (anchor 1 → 0, blob `42eb51200996` →
`be0d19170cee`). The self-test then exited 1 with exactly the first two
rows red:
- "--fix wrote [3 paths], the export lists [4 paths]";
- "unexpected [2 paths], wanted [3 paths]".
The tool restored the file and confirmed the restore: blob equals HEAD
`42eb51200996`, and `git diff HEAD` is empty.
## Gates (at `9540d87a8`)
I derived the gate list with `node scripts/pm/dispatch-gates.mjs
--commands --repo objectstack-ai/objectstack` on the actual diff. It
returned 50 commands, identical to the dispatch's list. I ran all 50 and
recorded each exit code before any pipe. All 50 exited 0.
`check:pm-dispatch-gates` ended with "1828 cases pass" (fast tier).
Reconciled with `--ran`: "50 derived, 50 run, 0 NOT-MEASURED, 0 UNRUN",
a derived zero because all 50 lines carry an exit code. `node
scripts/check-skill-compatibility-version.mjs --self-test` reports "22
check cases and 8 --fix derivation cases pass". A control-byte self-scan
of the three files found none.
## Acceptance notes
- `release.yml`'s `version-pr` header comment sits outside the `Validate
the post-version tree` step, so I did not edit it. Two parts of it are
now stale:
- the CONTENT gate list does not name `check:skill-compatibility`;
- the note above `Create or update the "chore: version packages" PR`
counts the version script's rewriters as four. The script has five after
`changeset version`, and the skill stamper is the fifth.
Carrier: the next change to that header; none is named yet.
- The self-test's success line counts the three new rows inside "--fix
derivation cases". They are registered and floored like every other row;
only the label is loose.
- The H5 reading is for `9540d87a8`. The scheduled run will render
`main` at whatever sha it reads, so `main` landing more before then can
still move a verdict. That run is the done-when reading on #22085.
- `cut-rc.yml` requires pre-mode tag `rc`, and `.changeset/pre.json`
currently says `next`. So the cut-rc reading above is a simulation of
its staging and allowlist half on the `next.0` tree, not a dispatch.
---
_Generated by [Claude
Code](https://claude.ai/code/session_012yK1ddAdAqfzwigRHZq3r2)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent eede467 commit 340eab7
3 files changed
Lines changed: 187 additions & 20 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
665 | 665 | | |
666 | 666 | | |
667 | 667 | | |
| 668 | + | |
| 669 | + | |
| 670 | + | |
| 671 | + | |
| 672 | + | |
| 673 | + | |
| 674 | + | |
| 675 | + | |
| 676 | + | |
| 677 | + | |
| 678 | + | |
| 679 | + | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
668 | 686 | | |
669 | 687 | | |
670 | 688 | | |
| |||
673 | 691 | | |
674 | 692 | | |
675 | 693 | | |
676 | | - | |
| 694 | + | |
| 695 | + | |
677 | 696 | | |
678 | 697 | | |
679 | 698 | | |
| |||
682 | 701 | | |
683 | 702 | | |
684 | 703 | | |
685 | | - | |
| 704 | + | |
686 | 705 | | |
687 | | - | |
| 706 | + | |
688 | 707 | | |
689 | 708 | | |
690 | 709 | | |
691 | 710 | | |
692 | 711 | | |
693 | 712 | | |
694 | 713 | | |
695 | | - | |
| 714 | + | |
| 715 | + | |
696 | 716 | | |
697 | 717 | | |
698 | 718 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
613 | 613 | | |
614 | 614 | | |
615 | 615 | | |
616 | | - | |
617 | | - | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
618 | 634 | | |
619 | 635 | | |
620 | 636 | | |
621 | 637 | | |
622 | 638 | | |
623 | | - | |
| 639 | + | |
| 640 | + | |
624 | 641 | | |
625 | 642 | | |
626 | 643 | | |
| |||
672 | 689 | | |
673 | 690 | | |
674 | 691 | | |
| 692 | + | |
675 | 693 | | |
676 | 694 | | |
677 | 695 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
82 | 82 | | |
83 | 83 | | |
84 | 84 | | |
| 85 | + | |
85 | 86 | | |
86 | 87 | | |
87 | 88 | | |
| |||
590 | 591 | | |
591 | 592 | | |
592 | 593 | | |
| 594 | + | |
| 595 | + | |
| 596 | + | |
| 597 | + | |
| 598 | + | |
| 599 | + | |
| 600 | + | |
| 601 | + | |
| 602 | + | |
| 603 | + | |
| 604 | + | |
| 605 | + | |
| 606 | + | |
| 607 | + | |
| 608 | + | |
| 609 | + | |
| 610 | + | |
| 611 | + | |
| 612 | + | |
| 613 | + | |
| 614 | + | |
| 615 | + | |
| 616 | + | |
| 617 | + | |
| 618 | + | |
| 619 | + | |
| 620 | + | |
| 621 | + | |
| 622 | + | |
| 623 | + | |
| 624 | + | |
| 625 | + | |
| 626 | + | |
| 627 | + | |
| 628 | + | |
| 629 | + | |
| 630 | + | |
| 631 | + | |
| 632 | + | |
| 633 | + | |
| 634 | + | |
| 635 | + | |
| 636 | + | |
| 637 | + | |
| 638 | + | |
| 639 | + | |
| 640 | + | |
| 641 | + | |
| 642 | + | |
| 643 | + | |
| 644 | + | |
| 645 | + | |
593 | 646 | | |
594 | 647 | | |
595 | 648 | | |
| |||
698 | 751 | | |
699 | 752 | | |
700 | 753 | | |
| 754 | + | |
| 755 | + | |
| 756 | + | |
701 | 757 | | |
702 | 758 | | |
703 | 759 | | |
| |||
706 | 762 | | |
707 | 763 | | |
708 | 764 | | |
709 | | - | |
| 765 | + | |
710 | 766 | | |
711 | 767 | | |
712 | 768 | | |
| |||
727 | 783 | | |
728 | 784 | | |
729 | 785 | | |
| 786 | + | |
| 787 | + | |
| 788 | + | |
| 789 | + | |
| 790 | + | |
| 791 | + | |
| 792 | + | |
| 793 | + | |
| 794 | + | |
| 795 | + | |
| 796 | + | |
| 797 | + | |
| 798 | + | |
| 799 | + | |
| 800 | + | |
| 801 | + | |
| 802 | + | |
| 803 | + | |
| 804 | + | |
| 805 | + | |
| 806 | + | |
| 807 | + | |
| 808 | + | |
| 809 | + | |
730 | 810 | | |
731 | 811 | | |
732 | 812 | | |
| |||
997 | 1077 | | |
998 | 1078 | | |
999 | 1079 | | |
| 1080 | + | |
| 1081 | + | |
| 1082 | + | |
| 1083 | + | |
| 1084 | + | |
| 1085 | + | |
| 1086 | + | |
| 1087 | + | |
| 1088 | + | |
| 1089 | + | |
| 1090 | + | |
| 1091 | + | |
| 1092 | + | |
| 1093 | + | |
| 1094 | + | |
| 1095 | + | |
| 1096 | + | |
| 1097 | + | |
| 1098 | + | |
| 1099 | + | |
| 1100 | + | |
| 1101 | + | |
| 1102 | + | |
| 1103 | + | |
| 1104 | + | |
| 1105 | + | |
| 1106 | + | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
1000 | 1136 | | |
1001 | 1137 | | |
1002 | 1138 | | |
| |||
1177 | 1313 | | |
1178 | 1314 | | |
1179 | 1315 | | |
1180 | | - | |
1181 | | - | |
1182 | | - | |
1183 | | - | |
1184 | | - | |
1185 | | - | |
1186 | | - | |
1187 | | - | |
1188 | | - | |
1189 | | - | |
| 1316 | + | |
1190 | 1317 | | |
1191 | | - | |
1192 | | - | |
| 1318 | + | |
| 1319 | + | |
| 1320 | + | |
| 1321 | + | |
1193 | 1322 | | |
1194 | 1323 | | |
1195 | 1324 | | |
| |||
0 commit comments