Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
32 changes: 32 additions & 0 deletions .changeset/skill-catalog-projected-issue-ids.md
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
---
"@objectstack/spec": patch
---

docs(spec): strip the internal issue-id references that were projected into the published skill catalog

The 2026-08-23 ruling stripped internal `#NNNN` citations from the published
skill corpus, but 14 of them were not authored in `skills/**` at all — they were
projected there from `.describe()` / TSDoc text in `packages/spec/src/**` by
`gen:skill-refs` and `gen:react-blocks`, so a hand-edit of the corpus could not
reach them and a regeneration would have put them straight back.

Six source sites are rewritten to say the same thing without the citation, and
the artifacts are regenerated: the module summaries of `data/driver/common`,
`data/driver/config-registry`, `data/driver/turso`, `shared/retry-policy` and
`system/translation`, plus the `ListView.objectName` / `ListView.viewType`
deprecation notes and the `<Block>` summary in `ui/react-blocks`. The teaching in
each is kept, per the standing ruling of 2026-08-12, verbatim and untranslated:
「处理 issue 时犯的错应该总结成经验,保留 issue id没有意义」.

Customer-facing text changes in three places from the one source edit: the
published catalog (`skills/*/references/_index.md`,
`skills/objectstack-ui/references/react-blocks.md` and its sibling
`contracts/react-blocks.contract.json`), and the docs site
(`content/docs/references/data/driver-common.mdx`, `driver-turso.mdx`). No
schema shape, no `.describe()` used for validation, and no accept/reject
behaviour changes — the edits are comment and documentation text only.

The doc-authoring gate's path exemption for the generated artifacts is removed
in the same change: it existed only because those files still carried projected
ids, and an exemption over a surface that no longer needs one is where the next
regeneration would smuggle one back in.
2 changes: 1 addition & 1 deletion content/docs/references/data/driver-common.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ description: Driver Common protocol schemas

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}

Shared building blocks for the per-driver `datasource.config` shapes (#4410).
Shared building blocks for the per-driver `datasource.config` shapes.

Every schema under `data/driver/` describes ONE driver's `config` slot — the
keys an author may write and the platform actually reads. They are the
Expand Down
2 changes: 1 addition & 1 deletion content/docs/references/data/driver-turso.mdx
Original file line numberDiff line numberDiff line change
Expand Up@@ -5,7 +5,7 @@ description: Driver Turso protocol schemas

{/* ⚠️ AUTO-GENERATED — DO NOT EDIT. Run build-docs.ts to regenerate. Hand-written docs live in the module folders under content/docs/. */}

Turso / libSQL Driver Protocol (#6345).
Turso / libSQL Driver Protocol.

## Why this arrives late, and what it closes

Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/data/driver/common.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,7 +3,7 @@
import { z } from 'zod';

/**
* Shared building blocks for the per-driver `datasource.config` shapes (#4410).
* Shared building blocks for the per-driver `datasource.config` shapes.
*
* Every schema under `data/driver/` describes ONE driver's `config` slot — the
* keys an author may write and the platform actually reads. They are the
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/data/driver/config-registry.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -15,7 +15,7 @@ import {
import { getTursoConfigJsonSchema, TursoConfigSchema } from './turso.zod';

/**
* The driver-id → `datasource.config` shape registry (#4410).
* The driver-id → `datasource.config` shape registry.
*
* ## Why this exists
*
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/data/driver/turso.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -17,7 +17,7 @@ import {
} from './common.zod';

/**
* Turso / libSQL Driver Protocol (#6345).
* Turso / libSQL Driver Protocol.
*
* ## Why this arrives late, and what it closes
*
Expand Down
7 changes: 4 additions & 3 deletions packages/spec/src/shared/retry-policy.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -3,9 +3,10 @@
/**
* @module shared/retry-policy
*
* The **single declaration** of the exponential-backoff retry policy (#4661,
* the #4535 C8 dual-source cluster; completed for the anonymous inline blocks
* by #4964 / #4962).
* The **single declaration** of the exponential-backoff retry policy.
*
* Converged in 17.0.0 in two passes: first the two same-named exports a
* dual-source scan could see, then the anonymous inline blocks it could not.
*
* Until 17 this shape existed twice — `automation/control-flow.zod.ts` (the
* `try_catch` node's `retry` region) and `system/job.zod.ts` (`job.retryPolicy`)
Expand Down
2 changes: 1 addition & 1 deletion packages/spec/src/system/translation.zod.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -13,7 +13,7 @@ export const LocaleSchema = lazySchema(() => z.string().describe('BCP-47 Languag
export type Locale = z.input<typeof LocaleSchema>;

/**
* Shared history sentence for every shape in this file (#4001).
* Shared history sentence for every shape in this file.
*
* Translation data has the most literal version of the silent-strip failure in
* the whole spec: a misspelled group or key is dropped, the bundle saves or
Expand Down
6 changes: 3 additions & 3 deletions packages/spec/src/ui/react-blocks.ts
Original file line numberDiff line numberDiff line change
Expand Up@@ -275,7 +275,7 @@ export const REACT_BLOCKS: ReactBlockDef[] = [
replacedBy: 'data',
note: "Write the metadata-tier data source instead: data={{ provider: 'object', object: '…' }} — the same spelling a metadata list view authors. objectName keeps working during the deprecation window.",
},
description: "[DEPRECATED → `data={{ provider: 'object', object }}`] The object this block binds to (server-connected). Converging on the metadata-tier spelling (#11284); this alias is removed after the deprecation window.",
description: "[DEPRECATED → `data={{ provider: 'object', object }}`] The object this block binds to (server-connected). Converging on the metadata-tier spelling; this alias is removed after the deprecation window.",
},
{
name: 'viewType',
Expand All@@ -285,7 +285,7 @@ export const REACT_BLOCKS: ReactBlockDef[] = [
replacedBy: 'type',
note: 'Write type="kanban" (ListViewSchema\'s own `type`, the metadata-tier view kind) instead. viewType keeps working during the deprecation window.',
},
description: '[DEPRECATED → `type`] Which visualization to render (default grid). Converging on the metadata-tier spelling (#11284): write `type`, the same key a metadata list view authors.',
description: '[DEPRECATED → `type`] Which visualization to render (default grid). Converging on the metadata-tier spelling: write `type`, the same key a metadata list view authors.',
},
{ name: 'filters', type: "FilterArray e.g. ['status','=','active']", kind: 'controlled', description: 'ObjectQL base filter; drive from React state for tabbed/searched lists. ([field, op, value]; ops =, !=, >, <, contains, in; compound: [\"and\", […], […]]).' },
{ name: 'navigation', type: "{ mode: 'page' | 'drawer' | 'modal' | 'split' | 'none' }", kind: 'binding', description: 'What a row click does. Use { mode: \"none\" } when you handle clicks via onRowClick.' },
Expand DownExpand Up@@ -344,7 +344,7 @@ export const REACT_BLOCKS: ReactBlockDef[] = [
{
tag: 'Block',
schemaType: '(any)',
summary: 'Escape hatch — render any registered component by type. <Block type="object-kanban" objectName="task" /> etc. Not a way back to the record:* family: those need a record page\'s record context and are rejected here too (#4413).',
summary: 'Escape hatch — render any registered component by type. <Block type="object-kanban" objectName="task" /> etc. Not a way back to the record:* family: those need a record page\'s record context and are rejected here too.',
interactions: [
{ name: 'type', type: 'string', kind: 'binding', required: true, description: 'The registered component type to render.' },
],
Expand Down
60 changes: 35 additions & 25 deletions scripts/check-doc-authoring.mjs
Original file line numberDiff line numberDiff line change
Expand Up@@ -263,17 +263,13 @@ const FENCE_CLOSE = /^```\s*$/;
// guard: the exact failure this file's header opens with, one rule over.
const PUBLISHED_SKILLS_ROOT = 'skills';

// Generated artifacts under `skills/**`. Their ids are not authored here — they
// are projected from `.describe()` / TSDoc in `packages/spec`, so the fix for
// one is a spec-source edit plus a regeneration, on a surface with its own
// gates. Flagging them here would red a file no author can legally hand-edit
// ("do not edit" is in their own headers) and point the remedy at the wrong
// repo layer. They are exempt from THIS rule, not absolved: the spec-side ids
// are tracked separately.
const GENERATED_SKILL_ARTIFACTS = [
/\/references\/_index\.md$/,
/\/references\/react-blocks\.md$/,
];
// There is deliberately NO exemption for the generated artifacts under
// `skills/**` (`references/_index.md`, `references/react-blocks.md`). The first
// cut carried one, because those files still held ids projected from TSDoc in
// `packages/spec/src/**`. Those source lines are stripped now, and an exemption
// over a surface that no longer needs one is where the next regeneration would
// smuggle one back in. A red here is fixed AT THE SPEC SOURCE, never by hand-
// editing the artifact — the failure text below prescribes exactly that.

// There is deliberately NO per-passage allowlist here, and adding one is not a
// remedy this gate offers.
Expand DownExpand Up@@ -429,11 +425,11 @@ function collectFiles() {
}

/**
* Every hand-authored Markdown file in the PUBLISHED catalog.
* Every Markdown file in the PUBLISHED catalog — generated artifacts included.
*
* Its own walk, for the reason argued at {@link PUBLISHED_SKILLS_ROOT}: the
* `collectFiles()` walk skips `references/`, where hand-authored companions
* live. Generated artifacts are dropped by path.
* `collectFiles()` walk skips `references/`, where both the hand-authored
* companions and the generated `_index.md` files live.
*
* Empty is a hard error here for the same reason it is in `collectFiles`
* (#4932): "the catalog is clean" and "the catalog was never opened" are the
Expand All@@ -460,9 +456,8 @@ function collectPublishedSkillFiles(root = PUBLISHED_SKILLS_ROOT) {
else if (/\.mdx?$/.test(e)) files.push(posix(p));
}
})(root);
const kept = files.filter((p) => !GENERATED_SKILL_ARTIFACTS.some((re) => re.test(p)));
if (kept.length === 0) throw new EmptyRootError([root], 0);
return kept.sort();
if (files.length === 0) throw new EmptyRootError([root], 0);
return files.sort();
}

/** Bare internal issue-id references in one published file's source. */
Expand DownExpand Up@@ -663,9 +658,9 @@ function selfTest() {
'skills/objectstack-demo/SKILL.md': 'The `cursor` key was removed in protocol 17.',
'skills/objectstack-demo/references/data-hooks.md': 'Hooks fire per row.',
'skills/objectstack-demo/rules/indexing.md': '`type` was retired.',
// Generated artifacts — exempt: their ids come from packages/spec TSDoc.
'skills/objectstack-demo/references/_index.md': 'Driver registry (#4410).',
'skills/objectstack-ui/references/react-blocks.md': 'Converging on the metadata tier (#11284).',
// Generated artifacts — IN scope and clean; their text comes from spec TSDoc.
'skills/objectstack-demo/references/_index.md': 'Driver registry.',
'skills/objectstack-ui/references/react-blocks.md': 'Converging on the metadata tier.',
// The internal roots are NOT this rule's business.
'.claude/agents/os-dev.md': 'Lesson learned while fixing #4286.',
'docs/adr/0049-enforce-or-remove.md': 'Superseded by #5248.',
Expand All@@ -686,14 +681,14 @@ function selfTest() {
// GREEN: the corpus as stripped.
expect('a clean published corpus is green', scan().length, 0);

// Scope: the collector reaches references/, and drops the generated files.
// Scope: the collector reaches references/, generated artifacts included.
const seen = collectPublishedSkillFiles();
expect('the id scan reaches hand-authored references/ (the other rule\'s walk does not)',
seen.includes('skills/objectstack-demo/references/data-hooks.md'), true);
expect('generated references/_index.md is exempt',
seen.includes('skills/objectstack-demo/references/_index.md'), false);
expect('the generated react-blocks contract page is exempt',
seen.includes('skills/objectstack-ui/references/react-blocks.md'), false);
expect('the generated references/_index.md is IN scope (no exemption)',
seen.includes('skills/objectstack-demo/references/_index.md'), true);
expect('the generated react-blocks contract page is IN scope (no exemption)',
seen.includes('skills/objectstack-ui/references/react-blocks.md'), true);
expect('the id scan does not reach .claude/', seen.some((f) => f.startsWith('.claude/')), false);
expect('the id scan does not reach docs/', seen.some((f) => f.startsWith('docs/')), false);
expect('the id scan does not reach content/', seen.some((f) => f.startsWith('content/')), false);
Expand All@@ -706,6 +701,17 @@ function selfTest() {
expect('the red names the file', red[0]?.file, 'skills/objectstack-demo/SKILL.md');
expect('the red names the id', red[0]?.ids?.join(','), '#4286');

// ...and in a GENERATED artifact — listing the file proves collection,
// this proves it is SCANNED, which is what dropping the exemption bought.
const regen = join(idDir, 'skills', 'objectstack-demo', 'references', '_index.md');
writeFileSync(planted, 'The `cursor` key was removed in protocol 17.');
writeFileSync(regen, 'Driver registry (#4410).');
red = scan();
expect('an id a regeneration put back into a generated artifact is RED', red.length, 1);
expect('the red names the generated file', red[0]?.file, 'skills/objectstack-demo/references/_index.md');
writeFileSync(regen, 'Driver registry.');
writeFileSync(planted, 'The `cursor` key was removed in protocol 17 (#4286).');

// ...and in a comment inside a code fence, which is where half the
// measured population lived.
writeFileSync(planted, ['```ts', " cursor: 'abc', // removed in #4286", '```'].join('\n'));
Expand DownExpand Up@@ -918,6 +924,10 @@ function main() {
+ `\nresolvable anchor where one exists — a protocol version, an ADR number, a lint rule id.`
+ `\n\nWriting a usage example that needs an issue number? Use the placeholder \`#<n>\`.`
+ `\nIt teaches the same syntax and is unmistakable to a customer reading it.`
+ `\n\nFlagged file says "Auto-generated — do not edit"? Then the id is not authored there:`
+ `\nit is projected from a \`.describe()\` / TSDoc string in \`packages/spec/src/**\`. Strip it`
+ `\nAT THE SOURCE and regenerate (\`gen:skill-refs\`, \`gen:react-blocks\`, \`gen:docs\`) — the`
+ `\nartifact is not exempt, because an exemption there is where the next one would land.`
+ `\n\nThere is no per-passage exemption to reach for, by design: this rule has none.`
+ `\n\nMaintainer ruling 2026-08-12, verbatim: 「处理 issue 时犯的错应该总结成经验,保留 issue id没有意义」\n`,
);
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-automation/references/_index.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -28,7 +28,7 @@ from `node_modules` — there is no local copy in the skill bundle.
- `node_modules/@objectstack/spec/src/shared/expression.zod.ts` — Expression Protocol
- `node_modules/@objectstack/spec/src/shared/identifiers.zod.ts` — System Identifier Schema
- `node_modules/@objectstack/spec/src/shared/protection.zod.ts` — Package-level metadata protection (ADR-0010 §3.7 — Phase 4.3)
- `node_modules/@objectstack/spec/src/shared/retry-policy.zod.ts` — The **single declaration** of the exponential-backoff retry policy (#4661,
- `node_modules/@objectstack/spec/src/shared/retry-policy.zod.ts` — The **single declaration** of the exponential-backoff retry policy.
- `node_modules/@objectstack/spec/src/shared/suggestions.zod.ts` — "Did you mean?" Suggestion Utilities

## How to read these
Expand Down
6 changes: 3 additions & 3 deletions skills/objectstack-data/references/_index.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -23,14 +23,14 @@ from `node_modules` — there is no local copy in the skill bundle.
- `node_modules/@objectstack/spec/src/automation/flow-function.zod.ts` — The contract for a **named handler function a `script` node invokes** —
- `node_modules/@objectstack/spec/src/data/driver-sql.zod.ts` — SQL Dialect Enumeration
- `node_modules/@objectstack/spec/src/data/driver.zod.ts` — Common Driver Options
- `node_modules/@objectstack/spec/src/data/driver/common.zod.ts` — Shared building blocks for the per-driver `datasource.config` shapes (#4410).
- `node_modules/@objectstack/spec/src/data/driver/config-registry.zod.ts` — The driver-id → `datasource.config` shape registry (#4410).
- `node_modules/@objectstack/spec/src/data/driver/common.zod.ts` — Shared building blocks for the per-driver `datasource.config` shapes.
- `node_modules/@objectstack/spec/src/data/driver/config-registry.zod.ts` — The driver-id → `datasource.config` shape registry.
- `node_modules/@objectstack/spec/src/data/driver/memory.zod.ts` — Memory Driver Configuration Schema
- `node_modules/@objectstack/spec/src/data/driver/mongo.zod.ts` — MongoDB Standard Driver Protocol
- `node_modules/@objectstack/spec/src/data/driver/mysql.zod.ts` — MySQL / MariaDB driver configuration — the `config` slot of a `datasource`
- `node_modules/@objectstack/spec/src/data/driver/postgres.zod.ts` — PostgreSQL driver configuration — the `config` slot of a `datasource` whose
- `node_modules/@objectstack/spec/src/data/driver/sqlite.zod.ts` — SQLite driver configuration — the `config` slot of a `datasource` whose
- `node_modules/@objectstack/spec/src/data/driver/turso.zod.ts` — Turso / libSQL Driver Protocol (#6345).
- `node_modules/@objectstack/spec/src/data/driver/turso.zod.ts` — Turso / libSQL Driver Protocol.
- `node_modules/@objectstack/spec/src/data/field-value.zod.ts` — Field runtime VALUE-shape contract (ADR-0104 D1).
- `node_modules/@objectstack/spec/src/data/filter.zod.ts` — Unified Query DSL Specification
- `node_modules/@objectstack/spec/src/data/hook-body.zod.ts` — Capability tokens a script body may request.
Expand Down
2 changes: 1 addition & 1 deletion skills/objectstack-i18n/references/_index.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -9,7 +9,7 @@ from `node_modules` — there is no local copy in the skill bundle.

## Core schemas

- `node_modules/@objectstack/spec/src/system/translation.zod.ts` — Shared history sentence for every shape in this file (#4001).
- `node_modules/@objectstack/spec/src/system/translation.zod.ts` — Shared history sentence for every shape in this file.
- `node_modules/@objectstack/spec/src/ui/i18n.zod.ts` — Display-label and ARIA-label primitives shared by every `ui/` shape.

## Transitive dependencies
Expand Down
6 changes: 3 additions & 3 deletions skills/objectstack-platform/references/_index.md
Original file line numberDiff line numberDiff line change
Expand Up@@ -22,14 +22,14 @@ from `node_modules` — there is no local copy in the skill bundle.
## Transitive dependencies

- `node_modules/@objectstack/spec/src/api/errors.zod.ts` — Standardized Error Codes Protocol
- `node_modules/@objectstack/spec/src/data/driver/common.zod.ts` — Shared building blocks for the per-driver `datasource.config` shapes (#4410).
- `node_modules/@objectstack/spec/src/data/driver/config-registry.zod.ts` — The driver-id → `datasource.config` shape registry (#4410).
- `node_modules/@objectstack/spec/src/data/driver/common.zod.ts` — Shared building blocks for the per-driver `datasource.config` shapes.
- `node_modules/@objectstack/spec/src/data/driver/config-registry.zod.ts` — The driver-id → `datasource.config` shape registry.
- `node_modules/@objectstack/spec/src/data/driver/memory.zod.ts` — Memory Driver Configuration Schema
- `node_modules/@objectstack/spec/src/data/driver/mongo.zod.ts` — MongoDB Standard Driver Protocol
- `node_modules/@objectstack/spec/src/data/driver/mysql.zod.ts` — MySQL / MariaDB driver configuration — the `config` slot of a `datasource`
- `node_modules/@objectstack/spec/src/data/driver/postgres.zod.ts` — PostgreSQL driver configuration — the `config` slot of a `datasource` whose
- `node_modules/@objectstack/spec/src/data/driver/sqlite.zod.ts` — SQLite driver configuration — the `config` slot of a `datasource` whose
- `node_modules/@objectstack/spec/src/data/driver/turso.zod.ts` — Turso / libSQL Driver Protocol (#6345).
- `node_modules/@objectstack/spec/src/data/driver/turso.zod.ts` — Turso / libSQL Driver Protocol.
- `node_modules/@objectstack/spec/src/data/field-value.zod.ts` — Field runtime VALUE-shape contract (ADR-0104 D1).
- `node_modules/@objectstack/spec/src/data/field.zod.ts` — Field Type Enum
- `node_modules/@objectstack/spec/src/data/filter.zod.ts` — Unified Query DSL Specification
Expand Down
Loading
Loading