Skip to content

build-skill-references.ts still picks the first JSDoc block anywhere in the file — the defect build-docs.ts fixed, publishing a private constant's comment to customers #12094

Description

@os-litant

Filed unassigned, measured while stripping the projected issue-ids in #11930 (out of that card's scope — that one strips ids, this is about which doc block gets published at all).

What

packages/spec/scripts/build-skill-references.ts derives each _index.md entry's description with its own extractDescription():

constjsdocMatch=content.match(/\/\*\*\s*\n([\s\S]*?)\*\//);

That is the first JSDoc block anywhere in the file, verbatim — a rule about ordering, not about descriptions. Whichever declaration happens to sit nearest the top donates its comment to a customer-facing page.

This is the same defect that was measured and fixed on the docs-site side. build-docs.ts no longer does this: it calls findModuleDocBlock() from packages/spec/scripts/lib/file-description.ts, which follows TSDoc's own rule read back — the block must start at column 0 and precede the first declaration. packages/spec/CHANGELOG.md records the original measurement (six victim pages) and the reasoning:

getFileDescription() took the first doc block anywhere in a *.zod.ts file, verbatim, and published it as the page's opening paragraph. That is not a rule about descriptions — it is a rule about ordering […] Adding a helper above the first schema silently rewrote a published page, and no gate could see it.

The fix landed in the docs generator only. The skill-references generator was never converted, and it publishes to a surface with a strictly higher cost curve: skills/** is loaded whole into customer agent context windows.

Live victim

packages/spec/src/system/translation.zod.ts has no module docblock. Its first JSDoc block documents a private constant, TRANSLATION_HISTORY. So skills/objectstack-i18n/references/_index.md currently opens its only core-schema entry with:

- `node_modules/@objectstack/spec/src/system/translation.zod.ts` — Shared history sentence for every shape in this file.

"Shared history sentence for every shape in this file" describes an internal string constant used to build .describe() text. It is not a description of the Translation protocol, and it is meaningless to the customer reading it. The docs site does not have this problem for the same file — findModuleDocBlock() correctly declines that block — which is the cleanest possible demonstration that the two generators disagree.

Note this is exactly the file the CHANGELOG names as a victim of the original defect ("The Translation protocol reference opened with Shared history sentence for every shape in this file"), so the docs-side repair is confirmed and the skills-side one is confirmed missing.

Why no gate catches it

check:skill-refs compares the generated file against what the generator produces — it reproduces the wrong block faithfully, so there is no drift to report. Same green-through-the-defect shape the docs side had.

What a card here would do

  1. Replace extractDescription() in build-skill-references.ts with the shared findModuleDocBlock() + renderFileDescription() path, rather than porting the rule a second time — one selector, two consumers.
  2. Regenerate and read the diff as a census: every _index.md line that changes is a file that was donating the wrong block. Some will fall through to the Exports: … fallback, which is a separate authoring question (does that file want a real module docblock?) and may want its own follow-up.
  3. Decide whether the fallback chain is right for a customer-facing surface at all, or whether a .zod.ts with no module docblock should be a loud refusal instead of a quiet Exports: line.

⚠️skills/** is a governed surface — whatever lands here is draft + human merge, and the regeneration diff should be reviewed line by line rather than accepted wholesale.

Metadata

Metadata

Assignees

Type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions