Commit bc1f467
docs(getting-started,ai): state the skills install command the scaffolder actually runs (#17868)
Clause-②: no
Closes #16400
## What was false
Four `content/docs/**` pages recommended installing the AI skills bundle
with
`npx skills add objectstack-ai/objectstack/skills --all`, and **two of
them
stated that flag as what the scaffolder runs**. That second half was
already
false in the tree, not about to become false: the scaffolder moved to a
single
named agent when PR #16401 landed (2026-09-06T20:36:10Z), so the two
getting-started lines described a command `create-objectstack` no longer
issues.
## What it actually runs today — re-measured, not cited
Read from `packages/create-objectstack/src/skills-install.ts` on this
branch's
base (`c88fa2ccdc`), by evaluating the constants rather than eyeballing
the
template literal:
```
SKILLS_INSTALL_COMMAND npx -y skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y
skillsInstallHint(default) npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y
skillsInstallHint('codex') npx skills add objectstack-ai/objectstack/skills --skill '*' --agent codex -y
DEFAULT_SKILLS_DIR .claude/skills/
```
`index.ts:542` passes `SKILLS_INSTALL_COMMAND` to `execSync`, and lines
594-601
print `skillsInstallHint(...)` in the closing summary — so "one agent,
one
directory, and the command is printed for any other runtime" is the
behaviour,
not just the constant.
A check in the PR: all **7** command literals left in the four pages are
compared programmatically against the value that module composes. 0
mismatches.
## Carriers — 4 of the card's 5 surfaces are this PR's
The card named five surfaces. Triage split on the landing path, not on
the
sentence kind: 「拆后本卡的文件面只剩 `content/docs/**`,按车道表归 `domain:devx`」.
| surface | kind | state |
|:---|:---|:---|
| `getting-started/your-first-project.mdx` 45, 286 | states what the
scaffolder runs + re-run instruction | fixed here |
| `getting-started/build-with-claude-code.mdx` 57, 381 | same pair |
fixed here |
| `ai/skills-reference.mdx` 27, 30, **33** | manual recommendation + two
prose claims | fixed here |
| `ai/skills.mdx` 35, **38** | manual recommendation + prose claim |
fixed here |
| `skills/README.md` 9 | governed surface | not ours — already moved to
the per-agent form by PR #16806, verified absent from this base |
The two bolded sites were not on the card's or the skills seat's line
list;
`skills-reference.mdx:33` and `skills.mdx:38` attribute the
bundle-versioning
and idempotence properties to `--all` specifically, so leaving them
would have
kept the flag as the recommended form in prose after the commands
changed.
## Fix shape, and why not a pointer
The brief asked whether to keep a corrected literal or point at the
single
source of truth (`skills-install.ts`), as this shift's #16200 did. Split
by
reader:
- **Where the reader must type the command** (all four pages' install
and
re-run instructions) the literal stays, corrected. A docs reader cannot
resolve a pointer into a TypeScript module in our monorepo — that page
is not
on the docs site and they cannot run it. Pointing there would remove the
fact
instead of keeping it true, which is the vague-sentence failure in a
different costume.
- **Where the reader does not need the value**, the pointer shape is
used:
`skills-reference.mdx`'s "new projects" paragraph now states the
observable
properties (one runtime, `.claude/skills/`, once) and points at the live
instrument the reader actually holds — *the scaffolder's own closing
summary
prints the exact command it ran*. That paragraph previously named no
command,
so this keeps the number of decaying copies at what it was rather than
adding
an eighth.
`--all` is not deleted: it is a real CLI option, and triage's
instruction was
that the idempotence claim is true and must not be removed. It survives
on the
reference page as a labelled multi-runtime opt-in that names its cost
(three
destinations: real copies in both `.agents/` and `agent/`, plus
`.claude/`
symlinks), with the distinction that makes the idempotence claim useful
—
re-running is idempotent *per destination*, and it is the destination
count that
grows.
## Reverse-read
*Does anywhere else state the scaffolder's behaviour, and does this diff
make
any standing sentence false?*
- `content/docs/deployment/cli.mdx` 29, 93, 94 — "installs the AI skills
bundle
+ `AGENTS.md`". True, names no command, no decay. **Unchanged.**
- `content/docs/getting-started/how-ai-development-works.mdx:45`,
`getting-started/index.mdx` 26, 161 — same shape. **Unchanged.**
- `getting-started/build-with-claude-code.mdx:70` — a console transcript
quoting `→ Installing AI skills for your coding agent...`, byte-equal to
`index.ts`'s `printStep`. True. `pnpm check:docs-transcript-drift`
measured it
green on the final text. **Unchanged.**
- `getting-started/build-with-claude-code.mdx:26` (mermaid) and
`your-first-project.mdx:272` — "installs the skills bundle", no command.
**Unchanged.**
- `packages/create-objectstack/README.md:60`,
`src/templates/AGENTS.md:82`,
`src/templates/blank/README.md:148`, `skills/README.md:9` — all four
already
carry the per-agent form. This diff agrees with them; none becomes
false.
- `packages/create-objectstack/src/template-consistency.test.ts:597-602`
— "the
boundary is the `/skills` SUBPATH, and it did not move when the
scaffolder
stopped passing `--all`". Directional and historical, still true, and
this
diff keeps the subpath on every literal.
- **Zero** results for: any other `content/docs` page naming a `skills
add`
command; any test or gate pinning `--all` in the docs (none exists — see
the
acceptance note below); any generated block containing an install
command
(`build-skill-docs.ts` emits none; `skills-reference.mdx`'s generated
region
starts at line 38, below every site edited).
One sentence outside this card's file surface **is** made false by this
diff,
reported rather than fixed: `.github/workflows/scaffold-e2e.yml:229-231`
says in
a comment "The scaffolder/docs command is `skills add
…/objectstack/skills
--all`". The scaffolder half was already stale; the docs half becomes
stale
here. The probe below it deliberately uses `--all --copy` and is correct
for its
purpose (set-equality against the curated catalog), so only the comment
is
wrong. Left alone because triage split this card's file surface to
`content/docs/**` and editing a workflow would add a verification
surface this
PR does not otherwise touch.
## 验收备注
- **No gate pins the docs against the scaffolder's command.** Triage
flagged
building one as a bonus and explicitly told the claiming seat not to
expand
the PR into `scripts/` for it — so the programmatic literal comparison
above
was run as a one-off in this PR and is not committed. Noted, not filed:
the
next surface to state this command has nothing mechanical to catch it,
and the
docs-drift audit states it structurally cannot see this class.
- `docs/qa/platform-checklist/areas/cli.json:384` uses `--all --copy` as
a
skills-boundary probe. Not a statement of scaffolder behaviour;
unaffected.
- `.claude/skills/dogfood-verification/SKILL.md:13` notes that the CLI's
`--all` implies `--skill '*'`. True CLI semantics, governed surface,
untouched.
## Verification
Derived with `node scripts/pm/dispatch-gates.mjs --commands --repo
objectstack-ai/objectstack`
(change set taken by the script from the merge base, not from a
hand-written
diff): **43 families, 43 run, 0 NOT-MEASURED, 0 UNRUN, all exit 0** —
reconciled back through `--ran` with an exit code recorded per family,
so the
zero is derived rather than claimed. Four of them first refused with
`PREREQUISITE NOT MET` (exit 3, not a finding); `@objectstack/lint`,
`@objectstack/formula` and `@objectstack/client-react` were built and
all four
then exited 0.
Named readings, all on the final text:
```
pnpm --filter @objectstack/spec check:docs ✅ 222 generated files in sync with packages/spec
pnpm check:docs-transcript-drift ✓ 4 declared transcript value(s) across 402 page(s)
under content/docs/ equal what the registry derives today
pnpm check:doc-authoring ✓ 44 published skill files clean
pnpm check:corpus-claim-drift OK, no new claim sites beside a pinned spelling
pnpm check:role-word OK, no new occurrences of the reserved word
pnpm check:nul-bytes exit 0
```
Heavy steps ran through `scripts/pm/os-verify-lock.sh` (slot
`issue-16400`):
`pnpm install` `VERDICT command-exit 0`, `@objectstack/spec build`
`VERDICT command-exit 0`, the three-package turbo build
`VERDICT command-exit 0`.
**`pnpm lint` — a declared narrowing, measured in three parts.** The
repo-scoped
run is CI's; the reading here is that this diff is outside eslint's
population
entirely. (1) Population from eslint's own config, not a guess:
`new ESLint().isPathIgnored(...)` returns `true` for the changed `.mdx`
files.
(2) File count from `--format json` over exactly the four changed files:
4 files
read, 0 errors, and each of the 4 warnings is `File ignored because no
matching
configuration was supplied`. (3) Invariance: this repo runs one
`eslint.config.mjs` which never enables type-aware linting for any file
(`eslint.config.mjs:325-332`; no `parserOptions.project`), so nothing in
this
diff can move the verdict on a file it does not touch. Union run against
final
`HEAD` `0612e8bfe8`.
**Changeset: skipped, measured.** No package's `files[]` names
`content/docs` —
checked across every `packages/*/package.json` carrying a `files` array,
zero
hits. The only consumer of this tree is `apps/docs`
(`@objectstack/docs`,
`private: true`, no `files`). Positive control: the corrected command
string
does appear in published surfaces
(`packages/create-objectstack/README.md`,
`src/templates/AGENTS.md`, `src/templates/blank/README.md`) — none of
which this
diff touches. Nothing shipped moves, so the `skip-changeset` label is
applied
rather than a body sentence.
**`Clause-②: no`** — the diff is four `.mdx` prose files: no schema key,
no
closed-set member, no published export, no registry entry.
`pnpm check:pm-widening-tells` exit 0.
---
_Generated by [Claude
Code](https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU)_
Co-authored-by: Claude <noreply@anthropic.com>1 parent 57cbb1d commit bc1f467
4 files changed
Lines changed: 28 additions & 17 deletions
File tree
- content/docs
- ai
- getting-started
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
15 | 15 | | |
16 | 16 | | |
17 | 17 | | |
18 | | - | |
| 18 | + | |
19 | 19 | | |
20 | 20 | | |
21 | 21 | | |
| |||
24 | 24 | | |
25 | 25 | | |
26 | 26 | | |
27 | | - | |
| 27 | + | |
28 | 28 | | |
29 | 29 | | |
30 | | - | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
31 | 33 | | |
32 | 34 | | |
33 | | - | |
| 35 | + | |
34 | 36 | | |
35 | 37 | | |
36 | 38 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
28 | 28 | | |
29 | 29 | | |
30 | 30 | | |
31 | | - | |
| 31 | + | |
32 | 32 | | |
33 | 33 | | |
34 | | - | |
35 | | - | |
| 34 | + | |
| 35 | + | |
36 | 36 | | |
37 | 37 | | |
38 | | - | |
| 38 | + | |
39 | 39 | | |
40 | 40 | | |
41 | 41 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
54 | 54 | | |
55 | 55 | | |
56 | 56 | | |
57 | | - | |
58 | | - | |
| 57 | + | |
| 58 | + | |
| 59 | + | |
| 60 | + | |
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
| |||
378 | 380 | | |
379 | 381 | | |
380 | 382 | | |
381 | | - | |
382 | | - | |
383 | | - | |
| 383 | + | |
| 384 | + | |
| 385 | + | |
| 386 | + | |
| 387 | + | |
384 | 388 | | |
385 | 389 | | |
386 | 390 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
45 | | - | |
46 | | - | |
| 45 | + | |
| 46 | + | |
| 47 | + | |
| 48 | + | |
| 49 | + | |
47 | 50 | | |
48 | 51 | | |
49 | 52 | | |
| |||
283 | 286 | | |
284 | 287 | | |
285 | 288 | | |
286 | | - | |
287 | | - | |
| 289 | + | |
| 290 | + | |
| 291 | + | |
| 292 | + | |
288 | 293 | | |
289 | 294 | | |
290 | 295 | | |
| |||
0 commit comments