Skip to content

Migrate work-types to JSON as canonical structured SSOT #511

Description

@williamthorsen

Origin: node-monorepo-tools#355 (work-types alignment + drift detection)

Problem

packages/agents/content/skills/_data/work-types.md is the canonical work-types reference for skill consumers, but its markdown-table shape is hard to consume programmatically:

  • Downstream repos (e.g., node-monorepo-tools) need to derive constants like DEFAULT_WORK_TYPES from it. Markdown table parsing is brittle.
  • Drift detection between repos requires byte-level or semantic comparison. Markdown formatting (whitespace, alignment) introduces noise that obscures real semantic drift.
  • The current document mixes structural data (work-type rows) with prose (precedence rule, breaking-change rule, AI-instructions carve-out). The two have different lifecycles and consumers.

node-monorepo-tools#355 establishes a structured-data SSOT (packages/release-kit/src/work-types.json) for the release-kit package and adds a release-kit work-types check command that fetches upstream and asserts equivalence. Until codeassembly publishes a matching JSON file, the check runs in tolerant mode (warn on 404 → exit 0). This ticket lands the upstream JSON so the check can flip to blocking.

Context

  • node-monorepo-tools#355 is still pending; this ticket is no longer bound by its prior schema decisions. Any agreed shape here will be reflected in that repo before it lands.
  • The current work-types.md carries 11 types in PRIMARY/SECONDARY/TERTIARY tiers. The new JSON adopts a 15-type vocabulary (adds drop, deprecate, sec, perf) in public/internal/process tiers, aligned with conventional changelog ecosystems.
  • The schema validation precedent in this repo is packages/agents/schemas/preferences.json + packages/agents/src/lib/__tests__/preferences-schema.test.ts. The new schema and test mirror that pattern.
  • The install command's _data/ copy already ships any file regardless of extension; no install-code change is required for the JSON to land in ~/.claude/skills/_data/.

Solution

Data shape

packages/agents/content/skills/_data/work-types.json carries the canonical taxonomy with this per-type record shape:

{
  "key": "feat",
  "aliases": ["feature"],
  "tier": "public",
  "emoji": "🎉",
  "label": "Features",
  "breakingPolicy": "optional"
}

emoji and label are separate fields (not a combined header). Consumers needing a pre-rendered string concatenate them. The 15 types in canonical render order: feat, drop, deprecate, fix, sec, perf, internal, refactor, tests, tooling, ci, deps, ai, docs, fmt. fmt carries excludedFromChangelog: true.

Schema

packages/agents/schemas/work-types.schema.json is a JSON Schema (draft 2020-12) with additionalProperties: false everywhere. It enforces:

  • Top-level: version (semver), tiers (the three-element array ["public", "internal", "process"]), types (array)
  • types[].key: lowercase pattern ^[a-z][a-z0-9-]*$
  • types[].tier: must be one of the values in the top-level tiers
  • types[].emoji: non-empty string
  • types[].label: non-empty string
  • types[].breakingPolicy: enum of forbidden | optional | required
  • types[].excludedFromChangelog: optional boolean

Cross-element uniqueness (unique key values, globally unique aliases) is asserted in the validation test, not the schema (JSON Schema can't express it cleanly).

Markdown removal

packages/agents/content/skills/_data/work-types.md is deleted. Its prose content (precedence rule, breaking-change rule, AI-instructions carve-out) moves into commit/SKILL.md, which is the only skill that consumes those rules. The structural data lives only in work-types.json.

Skill prose updates

commit/SKILL.md "Work types reference" section is rewritten to:

  • Group types by the new tiers (public/internal/process)
  • State the precedence rule using tier ordering
  • State the breaking-change rule using each type's breakingPolicy field (replacing the legacy "PRIMARY only" rule)
  • Carry the AI-instructions carve-out

summarize-change/SKILL.md updates:

  • Link target: [work-types.md](../_data/work-types.md)[work-types.json](../_data/work-types.json)
  • Priority phrase: Primary → Secondary → Tertiarypublic → internal → process

Sync mechanism

codeassembly-agents install continues to copy _data/ whole into ~/.claude/skills/_data/. The new work-types.json ships automatically. node-monorepo-tools fetches it via the raw.githubusercontent.com URL pattern in its release-kit work-types check command.

Acceptance criteria

  • packages/agents/content/skills/_data/work-types.json exists with the 15-type taxonomy and emoji/label field shape.
  • packages/agents/schemas/work-types.schema.json exists and is well-formed JSON Schema (draft 2020-12).
  • packages/agents/content/skills/_data/work-types.md is deleted.
  • commit/SKILL.md carries the new tier vocabulary, precedence rule, breaking-change rule, and AI-instructions carve-out.
  • summarize-change/SKILL.md references work-types.json and uses tier-order phrasing.
  • A schema validation test (work-types-schema.test.ts) asserts the live work-types.json validates against the schema and rejects malformed inputs (unknown keys, bad enum values, duplicate keys, duplicate aliases).
  • codeassembly-agents install ships work-types.json into ~/.claude/skills/_data/ without code changes (verified by an existing install test or a new one if no existing test covers _data/ JSON files).
  • New/modified behavior is covered by tests.
  • Documentation criterion: any skill prose referencing work-types.md (path or content) is updated. No remaining references to PRIMARY/SECONDARY/TERTIARY tier vocabulary in skill content.
  • Once landed, node-monorepo-tools#355's schema is updated to match the agreed shape before that repo merges (separate follow-up coordinated by the ticket author).

Coordination notes

  • The schema in this repo is canonical. node-monorepo-tools fetches it via the raw.githubusercontent.com URL pattern. If the schema evolves, both repos update in lockstep.
  • Order of types[] is canonical render order. Asserted by the schema validation test.
  • The breaking-change rule is now per-type (breakingPolicy field), not tier-level. Both repos must reflect this.

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions