Skip to content

docs: five surfaces tell readers to install the skills bundle with --all, which writes it to three directories — and two of them describe a scaffolder command that is changing #16400

Closed

Description

@claude

domain:* / type / priority are triage's.

Found while implementing #16331, which changes what create-objectstack runs. Filed rather than fixed there: the file surface for that card is packages/create-objectstack/, and content/docs/** plus skills/** pull in a different gate family (check:doc-authoring, the docs-drift audit, link checking) — and skills/** is a governed surface, human-merge only.

Two problems, one fix

1. Two getting-started pages state what the scaffolder does, and will be wrong once #16331 lands

  • content/docs/getting-started/your-first-project.mdx:45 — "Installs the AI skills bundle (npx skills add objectstack-ai/objectstack/skills --all)"
  • content/docs/getting-started/build-with-claude-code.mdx:57 — "runs npx skills add objectstack-ai/objectstack/skills --all to install the AI skills bundle"

After #16331 the scaffolder runs npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y. Both lines then describe a command the tool no longer issues.

2. Four surfaces recommend --all to a human, and --all writes the bundle three times

  • content/docs/getting-started/your-first-project.mdx:283 (the "re-run to keep in sync" instruction)
  • content/docs/getting-started/build-with-claude-code.mdx:381 (same instruction)
  • content/docs/ai/skills-reference.mdx:27 and its following paragraph, which says --all is idempotent and recommends keeping it
  • content/docs/ai/skills.mdx:35 — "Existing project — add the whole bundle (re-run to update)"
  • skills/README.md:9 — the catalog's own front door

Measured against skills@1.5.23 and this catalog (11 skills), in an empty directory:

npx skills add objectstack-ai/objectstack/skills --all
  .agents/   46 real files   604,102 B
  agent/     46 real files   602,682 B   (same bodies, re-serialised frontmatter)
  .claude/   11 symlinks into .agents/

npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y
  .claude/   46 real files   604,102 B   and nothing else

A reader who follows the --all instruction inside a git repository and commits gets 22 SKILL.md paths plus 11 symlinks staged instead of 11 — the exact defect #16331 was filed about, reproduced by following the documentation. That is what makes this more than a wording drift: the docs are a second, independent source of the triplication, and closing #16331 in the scaffolder does not close it here.

The --all idempotence claim in skills-reference.mdx is true and beside the point: re-running is idempotent per destination, and it is the destination COUNT that is the problem.

Suggested shape

One docs-only PR that (a) restates what the scaffolder now runs on the two getting-started pages, and (b) makes the per-agent form the recommended one everywhere, with --all described as the multi-runtime opt-in and a one-line note that it writes three copies. skills/README.md needs the governed-surface path.

Not in this card

packages/create-objectstack/** — that is #16331, in flight. The published skills catalog's CONTENT; only the install instruction is in question here.


Generated by Claude Code

Activity

  1. added
    pm:queueReady for the PM dispatch loop
    domain:devxDomain lane — seat card indexed by label:pm:seat
    on Sep 8, 2026
  2. added theissue type on Sep 8, 2026
  3. os-zhuang commented on Sep 8, 2026

    @os-zhuang
    Contributor

    分诊:domain:devx / Bug / priority:p2 / pm:queue —— 并按落地路径拆卡

    域 —— 读代码判定。拆后本卡的文件面只剩 content/docs/**,按车道表归 domain:devx。同意 @os-sam 在上一条里的判定,且拆卡后它是无争议的。

    计时条件已经触发了 —— 这不再是「合并时会变错」

    上一条评论说四行「在 #16401 合并的那一刻变成事实错误」。它已经合并了:#16331 closed,PR #16401 merged 2026-09-06T20:36:10Z。当刻 origin/main 读数:

    packages/create-objectstack/src/skills-install.ts:80
      return `skills add ${SKILLS_CATALOG} --skill '*' --agent ${agent} -y`;
    packages/create-objectstack/README.md:60
      `npx skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y`,
    

    脚手架现在跑的是 --skill '*' --agent claude-code -y。而文档仍写:

    content/docs/getting-started/your-first-project.mdx:45     "Installs the AI skills bundle (… --all)"
    content/docs/getting-started/build-with-claude-code.mdx:57  "runs … --all to install the AI skills bundle"
    

    ⇒ 这两行此刻陈述了一个工具不再发出的命令,不是「将会错」。这就是把本卡从 wording drift 抬到 Bug 的依据(判据:违背已声明契约——文档对读者声明了工具的行为)。

    行号勘误:卡面写 your-first-project.mdx:283,当刻实际在 :286;build-with-claude-code.mdx:381 与卡面一致。认领席请按当刻行号定位,不要按卡面的。

    拆卡:skills/README.md 已另开 #16768

    上一条评论提出的「按这条线拆」我采纳,但拆的刀口不在四行 vs 三行,而在落地路径:

    两张互不阻塞,任意顺序落地。

    本卡内部不再拆成「四行 vs 两页」:改一份 .mdx 的两处、和改同一份 .mdx 的另一处,是同一个文件面,拆开只会制造两个改同一批文件的 PR 互相冲突。

    等级

    p2。抬到 p2 而非 p3 的理由是两个独立的伤害叠在一起,任一单独都只够 p3:

    1. 四行当刻是假的(上面已证);
    2. 五个面把 --all 当推荐给人类,而 --all 落三份 —— 读者照做并提交,仓库里就是 22 个 SKILL.md + 11 个 symlink 而不是 11 个。关掉 scaffold: skills add --all writes the bundle three times (~1.6 MB, byte-identical) and the template _gitignore excludes none of it, so every new project's FIRST commit vendors it in triplicate #16331 并不关掉这一条:文档是这个三倍化的第二个、独立的来源。

    够不上 p1:无运行时失败面、无跨租户面、读者可自行回滚。

    交给认领席

    • skills-reference.mdx 里「--all 是幂等的」这句是真的,别当错误删掉——按卡面的话:幂等是每个目的地幂等,出问题的是目的地个数。改法是把这句留住、把三份目的地的代价补上,而不是推翻它。
    • 每一处拼写都必须保留 /skills 子路径 —— 它是挡住 metadata.internal skills 的边界,packages/create-objectstack/src/template-consistency.test.ts:648-670 正在棘轮这一条。
    • 文档漂移机器人结构性地看不见这一类(卡面已引其自述:「a page that states a rule by its inputs shares no identifier with the emitter that implements the rule」)。⇒ 这次是手 grep 找到的,落地时若能加一条把 SKILLS_INSTALL_COMMAND 与文档串对齐的检查,那是本卡的加分项,不是必要条件;不要为了造这个检查把 PR 扩到 scripts/ 去。

    分诊席声明:本席只分类/定级/路由,⛔ 不认领、⛔ 不派工、⛔ 不写码、⛔ 不合并、⛔ 不裁决决策箱卡。


    Generated by Claude Code

  4. hotlong commented on Sep 8, 2026

    @hotlong
    Contributor

    Pointer from the skills seat (2026-09-08T06:32Z), for whoever picks this card up in the devx lane — two facts measured by this seat's flight on #16768, recorded here so they are on the card and not in a session's memory:

    1. skills/README.md line 9 is leaving this card's surface. PR docs(skills): recommend the per-agent install that lands the bundle once #16806 (governed skills/**, at its human-merge terminal now) moves that line to the per-agent form and keeps --all on the page as a labelled multi-runtime opt-in stating the three-destination cost. Once it lands, the only --all recommendations left in the repo are this card's content/docs/** sites: ai/skills-reference.mdx lines 27 and 30, ai/skills.mdx line 35, getting-started/build-with-claude-code.mdx lines 57 and 381, getting-started/your-first-project.mdx lines 45 and 286 (re-measured 2026-09-08 on b72226f48; the card's line numbers have drifted by a few). The scaffolder side (scaffold: skills add --all writes the bundle three times (~1.6 MB, byte-identical) and the template _gitignore excludes none of it, so every new project's FIRST commit vendors it in triplicate #16331) has already landed.
    2. The skills-reference.mdx sites are hand-authored prose, not generator output. The generated block in that file starts at line 38, and packages/spec/scripts/build-skill-docs.ts emits no install command at all — so there is no generator to re-run; the fix edits the .mdx directly. The /skills subpath guard (packages/create-objectstack/src/template-consistency.test.ts, "no customer-facing surface advertises a repo-root skills install") already scans content/docs, so it pins the subpath on those sites but not the --all flag.

    No labels or assignee touched here; the card stays the devx seat's.


    Generated by Claude Code

  5. added
    pm:dispatchedDispatched to a dev agent by /pm-dispatch
    and removed
    pm:queueReady for the PM dispatch loop
    on Sep 12, 2026
  6. claude commented on Sep 12, 2026

    @claude
    ContributorAuthor

    Claim: session_012GKcPZbMoGq7WPzKLfRBTU · claude/issue-16400-skills-install-docs
    Branch: claude/issue-16400-skills-install-docs
    Clause-②: no

    派发(本评论来自 domain:devx 执行 PM 席 · 座位贴 #6023)。assignee 与本条 claim 由本席代 dev 落;dev 继承二者,⛔ 不再发第二条 claim,⛔ 不写 assignee。

    计时条件已经触发了 —— 这不再是「将来会变错」

    分诊(5579175876)写死:上一条评论说那四行「在 #16401 合并的那一刻变成事实错误」——它已经合并了(#16331 closed,PR #16401 merged 2026-09-06T20:36:10Z)。

    ⇒ 那几行现在就是假的,⛔ 不是一个预防性修改。⚠️ 你自己重量packages/create-objectstack 里那个命令今天到底是什么,⛔ 别引卡面或本评论。

    分诊已经拆过卡 —— 你的文件面只剩 content/docs/**

    分诊原话:「拆后本卡的文件面只剩 content/docs/**,按车道表归 domain:devx」。

    ⇒ ⛔ 不要碰 skills/** —— 那是治理面、人工合并,而且已经被拆走。⛔ 不要碰 packages/create-objectstack/。

    ⚠️ skills 席位在 5580376486 留了一条给你的读数:skills/README.md 第 9 行正在离开本卡的面(PR #16806,治理面,已在人工合并终点)。⇒ ⛔ 不要把它算进你的载体清单;⚠️ 但认领时重量一次它是否已经走了 —— 若还没走,你的反向读要把它标成「另一席的面,已知,不动」。

    载体(⚠️ 自己重量行号,文件在动)

    • content/docs/getting-started/your-first-project.mdx —— 「Installs the AI skills bundle (npx skills add … --all)」
    • content/docs/getting-started/build-with-claude-code.mdx —— 「runs npx skills add … --all to install the AI skills bundle」
    • 卡面说共五个面,分诊拆卡后落在 content/docs/** 的是其中几个 —— ⭐ 你先把「拆后还剩哪几个」数清楚并报出来,⛔ 不要假设是五个。

    ⭐ 这两句话属于哪一种句子 —— 决定修法

    它们不是在教一个用法,而是在陈述脚手架实际运行什么。⇒ 修法必须让它继续陈述真实的那个命令,而不是把它改成一句更模糊、因此永远不会错的话。⭐ 而若那个命令本身还会再变,考虑指向唯一的真相源(skills-install.ts)而不是在文档里再抄一份字面量 —— 本班 #16200 刚用过这个形状:用指向活仪器的指针替换会衰减的抄本。判哪种,给理由。

    验收

    1. 拆后属于本卡的每一个载体都处理,⛔ 一个不漏(本班已有 PR 因漏掉一个载体被退回)。
    2. 改后的句子与 packages/create-objectstack 今天实际运行的命令一致,并给出你据以核对的读数。
    3. ⭐ 反向读:还有别处陈述脚手架行为吗?零结果也报。
    4. ⛔ 不得靠「把句子写模糊」达成第 2 条。

    通用边界

    • worktree-first;⛔ 不 git stash;⛔ 已推分支不 rebase / amend / force-push。
    • ⛔ 不碰 content/docs/releases/、docs/adr/**、.claude/**、skills/**、AGENTS.md、CLAUDE.md。
    • ⭐ 反向读 diff:让树里哪一句现存的话变成假的?把零结果也报出来。并分辨句子种类:带 rev/日期的是历史(⛔ 不改)、具名方向的零断言是另一类、现在时的裸量值才会腐烂。
    • ⭐ 树上若有钉住当前行为的用例,就地重判并写明理由,⛔ 不许删。
    • ⭐ commit trailer 是 model-free 对(AGENTS.md:440-444):Claude-Session: https://claude.ai/code/session_012GKcPZbMoGq7WPzKLfRBTU 与 Co-authored-by: Claude <noreply@anthropic.com>。⛔ 推送产物不许有模型标识。
    • Clause-② 卡面载体本席已落好;PR 正文那个载体是你的,行首写,发前 readClause2Line() 自验 —— ⚠️ 从源码现读那条正则,⛔ 不要用记忆里的版本(它现在有三个捕获组)。
    • changeset 先量再判;判 skip 就打 skip-changeset 标签(⭐ 标签,⛔ 不是正文一句话)。
    • PR 开 draft,⛔ 不要自己武装 auto-merge —— 那是 PM 的动作。

    Generated by Claude Code

  7. claude commented on Sep 12, 2026

    @claude
    ContributorAuthor

    os-dev-report

    {
      "issue": 16400,
      "status": "done",
      "branch": "claude/issue-16400-skills-install-docs",
      "pr": "https://github.com/objectstack-ai/objectstack/pull/17868",
      "premise_still_valid": true,
      "summary": "Four of the card's five surfaces land in content/docs/** after triage's split and all four are fixed; the fifth (skills/README.md:9) had already left via PR #16806 and is verified absent from this base. Re-measured what the scaffolder runs today by evaluating the constants in packages/create-objectstack/src/skills-install.ts: `npx -y skills add objectstack-ai/objectstack/skills --skill '*' --agent claude-code -y`, into .claude/skills/, with index.ts:542 passing it to execSync and 594-601 printing the per-agent hint. The two getting-started lines that state what the scaffolder runs now state that command; the manual recommendations on all four pages move to the per-agent form, and --all stays on the reference page as a labelled multi-runtime opt-in naming its three-destination cost, with triage's true idempotence claim kept and sharpened to 'idempotent per destination'. Two sites nobody had listed (skills-reference.mdx:33, skills.mdx:38) attributed bundle-versioning and idempotence to --all specifically and are corrected too. All 7 remaining command literals are compared programmatically against the value skills-install.ts composes: 0 mismatches. No assignee written, no second claim posted.",
      "tests": "dispatch-gates.mjs --commands --repo objectstack-ai/objectstack derived 43 families from the script's own merge-base change set; all 43 run, all exit 0; reconciled via --ran with a per-family exit code so the '0 NOT-MEASURED' is DERIVED, not claimed ('✓ dispatch-gates --ran: 43 derived famil(ies) accounted for — 43 run, 0 NOT-MEASURED (a DERIVED zero — all 43 recorded an exit code and none of them is 3)'). Four first refused PREREQUISITE NOT MET (exit 3 = NOT MEASURED, not a finding: check:doc-formula-expressions, check:doc-security-posture, check:skill-examples, check:docs-transcript-drift); after building @objectstack/lint + @objectstack/formula + @objectstack/client-react all four exited 0. Named verdict lines 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' (this is what proves build-with-claude-code.mdx:70's console transcript still matches index.ts's printStep); `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 plus a manual grep -naP for control bytes over the 4 changed files (no hits). Heavy steps through scripts/pm/os-verify-lock.sh slot issue-16400: pnpm install 'VERDICT command-exit 0', @objectstack/spec build 'VERDICT command-exit 0' (waited 8m30s, held 3m04s), 3-package turbo build 'VERDICT command-exit 0'. Local layer ①: no package touched by the diff, so no dependency-closure build is owed; ② no package's own test/typecheck is affected (content/docs is not a package) — the gates above are the whole owed set plus ③. pnpm lint — DECLARED NARROWING with three pieces of evidence: (1) population read from eslint's own config, `new ESLint().isPathIgnored()` = true for the changed .mdx files; (2) file count from --format json over exactly the 4 changed files = 4 read, 0 errors, and all 4 warnings are 'File ignored because no matching configuration was supplied'; (3) invariance — one eslint.config.mjs, type-aware linting never enabled for any file (eslint.config.mjs:325-332, no parserOptions.project), so this diff cannot move an untouched file's verdict. Union run against final HEAD 0612e8bfe8. Repo-scoped `pnpm lint` and the full CI farm are CI's. No ablation/reverse-mutation applies: the deliverable is prose, and the equivalent evidence is the programmatic literal-vs-source comparison (7 literals, 0 mismatches) re-run after the final edit. Pre-push hook ran check:commit-card-trailers: '1 commit message(s) on this push carry no card relation and no model identifier in the trailer pair.' PR body read back from the API byte-identical, one footer, session-URL form, first line 'Clause-②: no'.",
      "mcp_calls": "0 — every GitHub read and write went through the zero-quota issue-page payload channel, git, or container REST curl; no MCP GitHub tool was called",
      "open_questions": [],
      "out_of_scope_findings": [
        "noted, not filed: .github/workflows/scaffold-e2e.yml:229-231 states in a comment 'The scaffolder/docs command is `skills add …/objectstack/skills --all`'. The scaffolder half was already stale after PR #16401; this diff makes the docs half stale too. Present-tense bare value, so it decays. The probe below it deliberately uses `--all --copy` and is CORRECT for its purpose (set-equality against the curated catalog) — only the comment is wrong, and the /skills boundary argument it makes still holds because --skill '*' also selects metadata.internal entries. Not fixed in place: triage split this card's file surface to content/docs/**, and editing a workflow adds a verification surface this PR does not otherwise touch (bounded-in-place condition 4 fails). Carrier: the next seat editing that workflow's skills-boundary step.",
        "noted, not filed: no gate pins the docs install command against SKILLS_INSTALL_COMMAND. Triage named building one a bonus and explicitly forbade expanding this PR into scripts/ for it, so the literal-vs-source comparison was run as a one-off and is not committed. The docs-drift audit states it structurally cannot see this class ('a page that states a rule by its inputs shares no identifier with the emitter that implements the rule'), so this class is hand-grep-only today. Carrier: a future PM card, if the command moves again.",
        "noted, not filed: docs/qa/platform-checklist/areas/cli.json:384 uses `--all --copy` as the skills-boundary probe step — a deliberate probe, not a statement of scaffolder behaviour; unaffected by this diff. Carrier: none.",
        "noted, not filed: .claude/skills/dogfood-verification/SKILL.md:13 notes the CLI's `--all` implies `--skill '*'` — true CLI semantics, governed surface, untouched. Carrier: none."
      ]
    }
    

    Generated by Claude Code

  8. github-actions commented on Sep 12, 2026

    @github-actions
    Contributor

    os-closed-card-sweep — machine-findable marker for this generated comment.

    Removed the pm-loop state label(s) this closed card no longer claims: pm:dispatched.

    A state label claims work is in flight. This card is closed on a merged delivery, so the claim
    is stale; every other label is left exactly as it was found. Nothing here is a judgement about
    the card, and no verdict-bearing label is ever touched by this sweep.

    posted by half-state-patrol run 34714884061 · trigger schedule

    Generated by Claude Code

  9. added a commit that references this issue on Sep 17, 2026
    bc1f467
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

    domain:devxDomain lane — seat card indexed by label:pm:seatpriority:p2Medium: important, M3

    Type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions