Repository navigation
Commit 7e6fca0
ci(scaffold-e2e): build the skills-boundary expected set from the whole curated skills/ catalog (#26285)
<!-- claude-projects-attribution: {"github_login":"os-steve"} -->
_Requested by **Steve** · [project
thread](https://claude.ai/code/project/chan_01FdL1XeUyvVNxLreh3F4Qi9?thread=cmsg_01FdL1XeUyvVNxLreh3F4Qi97RDQRRsHagYpbF6jeYVbtq)_
Fixes #26204
Clause-②: no
Metadata-protocol: none
⛔ **Tier H** (`.github/workflows/**`): this PR stays a draft until a
`GOVERNED_APPROVERS` approval. No seat readies it, queues it or arms
auto-merge before that.
## 维护者速读(草稿)
- **改了什么**:`Scaffold E2E` 里「Skills boundary」这一步的期望技能集合,从「只认
`skills/objectstack-*`」改成「`skills/` 下凡是带 `SKILL.md` 的目录都算」。另外加了一道保护:若
`skills/` 读出来是空集,这一步直接失败。两条防泄漏断言(安装集合相等、仓根发现数相等)一字未动。
- **为什么改**:objectui 技能并入根 `skills/` 之后,这一步把它当成「泄漏」,所有动到
`packages/create-objectstack/**` 的 PR 都挂红。`@objectstack/skills`
发布包本来就是把整个 `skills/` 原样打包,所以 `skills/`
本身就是策展目录;在工作流里再维护一份白名单,等于以后每加一个技能都要改一次受管文件。
- **风险与代价(含回滚)**:只改一个 CI 步骤,不影响任何发布包。代价是:往 `skills/`
新放一个普通技能目录会被当成策展技能放行(它本来也会随 npm 包发布);内部技能(`metadata.internal`)放进
`skills/`、或放在 `skills/` 之外却没标 internal 的技能,仍然会让这一步失败(本地已实测,见下)。回滚就是
revert 这一个提交。
- **席位意见**:
- **你要做的**:看一眼 diff,同意的话批准这个 PR。批准后由席位负责转 ready 并入队。
## What changed
`.github/workflows/scaffold-e2e.yml`, step "Skills boundary: only the
curated skills/ catalog installs":
- `expected` was `ls -d objectstack-*/` inside `skills/`. It is now
every `skills/` subdirectory that holds a `SKILL.md`, read with the same
loop shape as the later "Skills: the scaffolder installed exactly the
@objectstack/skills catalog" step.
- An empty `expected` now fails the step loudly instead of comparing two
empty sets.
- `expected_count`, and therefore the `Found N skill` check, follows the
new set. Both assertions (installed set equality, repo-root discovery
count, and the `dogfood-verification` grep) are unchanged.
**Why a directory read and not an allow-list.** The card allowed either.
`@objectstack/skills` ships the whole `skills/` tree
(`packages/skills/scripts/sync-catalog.mjs` copies `skills/**` and
`--check` refuses any difference), so `skills/` is the curated catalog
by definition. An allow-list in this file would be a second registry of
the same fact, and every new curated skill would red this step until a
Tier H edit of the workflow. That is the same failure this card fixes.
With the directory read, what the boundary still catches is anything
that is not curated: a skill outside `skills/` without the internal
marker, an internal-marked skill placed in `skills/`, and a nested skill
inside a curated directory. All three are rehearsed below.
## Rehearsal
The step's `run:` block was extracted verbatim from the workflow (the
YAML parsed with the `yaml` package) and run with `bash -e`, the
runner's default shell for a step with no `shell:`. `GITHUB_WORKSPACE`
was the checkout, or a `git archive HEAD` copy for the controls.
`RUNNER_TEMP` was a fresh temp dir. skills CLI 1.7.4 via `npx -y
skills`. `create-objectstack` was built from this tree. The final head's
run block is byte-identical to the rehearsed one (`cmp`).
| run | workspace | exit | what the log shows |
|:---|:---|:---|:---|
| old step (`origin/main` e05e0de) | checkout | **1** | installed = ten
`objectstack-*` + `objectui`, expected = ten `objectstack-*`,
`::error::scaffolded skill set != curated skills/ catalog`. The card's
failure, reproduced. |
| new step | checkout at a9585ae | **0** | installed = expected = the
11 skills, `Found 11 skills` twice |
| new step | archive copy, unmodified | **0** | control leg for the
three negatives below |
| negative A: unmarked skill at `.claude/skills/leak-probe/` | archive
copy | **1** | `Found 12 skills`, `::error::repo-root discovery does not
match the curated catalog (expected 11 skills)` |
| negative B: `metadata.internal: true` skill at
`skills/internal-probe/` | archive copy | **1** | expected lists
`internal-probe`, installed does not, `::error::scaffolded skill set !=
curated skills/ catalog` |
| negative C: nested `skills/objectui/guides/nested-probe/SKILL.md` |
archive copy | **1** | installed lists `nested-probe`,
`::error::scaffolded skill set != curated skills/ catalog` |
| control D: plain new skill at `skills/new-curated-probe/` | archive
copy | **0** | `Found 12 skills`. A new curated skill passes without a
workflow edit, by design. |
| new step after removing every probe | archive copy | **0** | restore
leg |
Negative B shows the skills CLI hides `metadata.internal` skills even
under `--all` today, so an internal skill in `skills/` trips assertion
1. If an older CLI did install it, assertion 2's count would trip
instead. The step's comment says both.
## Gates
At head a9585ae, all 38 commands from `node
scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack` (change set: this one file, 14 changed
lines) were run one by one with stdin from `/dev/null`, and each exit
was captured before any pipe. Every one exited 0, including `pnpm
check:pm-dispatch-gates` (fast tier, 1899 cases). The `--ran`
reconciliation reads `38 derived, 38 run, 0 NOT-MEASURED, 0 UNRUN`, a
derived zero because every line recorded its exit code. The families the
derivation prints as NOT MEASURED (workflow-valued argv, the `Test Core`
shard steps, the type-check lanes) are CI's. Their verdicts are this
PR's check-runs.
Changeset: none. The diff is one CI workflow and publishes nothing, so
`skip-changeset` rides the create.
## Acceptance notes
- The card's negative control reads "an extra non-curated skill
directory". Under the directory-read rule, a plain directory added to
`skills/` is curated by definition (control D passes) because it also
ships in `@objectstack/skills`. The non-curated shapes are A, B and C,
and each fails.
- The workflow's `pull_request.paths` lists
`.github/workflows/scaffold-e2e.yml` itself, so this PR runs `Scaffold
E2E`. The card's first acceptance line is read from this PR's `Scaffold
with repo dist` check-run, which is a real CI run of the edited step
against unchanged skills.
---
_Generated by [Claude
Code](https://claude.ai/code/session_014kunMthReAU7eVraV1qLsb)_
---------
Co-authored-by: Claude <noreply@anthropic.com>1 parent f60f4ea commit 7e6fca0
1 file changed
Lines changed: 13 additions & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
248 | 248 | | |
249 | 249 | | |
250 | 250 | | |
| 251 | + | |
| 252 | + | |
| 253 | + | |
| 254 | + | |
| 255 | + | |
| 256 | + | |
| 257 | + | |
| 258 | + | |
251 | 259 | | |
252 | 260 | | |
253 | 261 | | |
254 | 262 | | |
255 | | - | |
| 263 | + | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
256 | 268 | | |
257 | 269 | | |
258 | 270 | | |
| |||
0 commit comments