Skip to content

Extract release-notes voice into shared, mechanically enforceable rules #538

Description

@williamthorsen

Problem

The summarize-change skill's ## What guidance still produces verbose, mechanism-heavy entries — even after #489's sharpening pass. PR williamthorsen/node-monorepo-tools#387 shows the failure mode: a ~120-word ## What that names schema fields the reader has never seen (description, body, breaking, audience: 'skip'), internal files (.meta/changelog.json), and internal versioning ("v1 supports… for a future reclassification feature"). It passes the post-#489 release-notes test on a literal-checklist read but fails the underlying purpose: A release-notes reader will skip it.

The recurring failure mode is soft tests applied to a verbose draft. The agent reads the rules, drafts something that nominally passes them on a literal check, and ships. New rules layered on the same frame won't catch this; the frame itself needs replacing.

The shipped version after manual rewrite was 17 words: "Allows release-kit consumers to skip or correct historical changelog entries by means of an overrides file." The entry is short not because brevity is a constraint but because the detail belongs in the PR, not the changelog.

Context

Audience and destination:

  • The PR's ## What section is extracted into the changelog (every type except fmt) and, for public-tier work types, into release notes.
  • The reader is glancing through entries in 2–5 seconds. They have no project-internal context.
  • Audience routes by tier (per work-types.json): Public-tier readers are end-users; other-tier readers are developers. Both are glancing readers.

Cross-skill ripple: The current ## What voice guidance lives inline in summarize-change/SKILL.md. commit/SKILL.md already cross-references summarize-change as the canonical voice statement, so tightening here transitively improves commit-body quality. Extracting the principle into a shared file makes the cross-reference structurally honest.

Why #489 didn't suffice: The soft tests (release-notes test, ~100-word soft ceiling) can be passed by a literal-checklist read of a verbose draft. The fix needs rules tight enough that a verbose draft cannot satisfy them mechanically.

No skill-content test framework. The agents package's test suite covers code, not skill semantics. Acceptance is by inspection of the rewritten guidance and by the next several PRs' ## What quality.

Solution

Extract the voice principle into a new shared data file, replacing the existing ## What block with a thin pointer. The reframe operates on three axes:

  1. Frame. Lead with the glancing reader and the principle that detail is routed, not omitted. The PR carries the full story; cutting from the entry doesn't lose information, it puts it where it belongs. Audience routes by tier with work-types.json as the source of truth.

  2. Two mechanically enforceable rules:

    • Per-sentence outcome test. Each sentence must describe what the change means for the reader: An outcome, a stated invariant worth confirming (e.g., "behavior is unchanged"), or migration info. Mechanism, internal naming, refactor mechanics, internal counts, and output-format details fail the test and are cut. Indirect outcomes (reliability, performance) are permitted only if specific — "more reliable progress visibility during long runs" passes; "improves reliability" is generic puffery and is forbidden.
    • Identifier ban. Only top-level user-configurable surface (package names, CLI commands and flags, top-level config-file paths, public-API endpoints) may appear. Schema field names, default values, internal file paths, function/type names, internal subsystem names, internal versioning, and output-format details are banned. The one exception: A removed user-facing identifier may be named for migration ("the --fix-low flag is replaced by …").
  3. Length. As long as needed to convey outcomes, invariants, and migration info — and not one word longer. The per-sentence test is the only check; word counts and sentence counts are not the rule.

Structural changes:

  • Create packages/agents/content/skills/_data/release-notes-voice.md carrying the frame, the two rules, the cross-type one-liner examples, and worked Bad/Good pairs (rename, low-action feature, internal-tier, mechanism-cut, over-elaborated fix, TMI feature).
  • Slim the ## What curly-brace block in summarize-change/SKILL.md to a thin pointer plus ## What-specific framing (this section becomes a changelog/release-notes entry; route mechanism to ## Details). Remove the previous inline rules, audience constraint, release-notes test, length target, voice paragraph, cross-type examples, and Bad/Good pairs (subsumed by the shared file).
  • Update the voice paragraph in commit/SKILL.md to point to the new shared file (replacing the current cross-reference to summarize-change). Add the distinction that the first paragraph of the commit body must stand alone as the changelog/release-notes entry; subsequent paragraphs may elaborate for the engaged reader.

Out of scope (related, but separable): commit/SKILL.md lines 60–62 enumerate the work-type tiers verbatim, duplicating work-types.json. This is the same source-of-truth concern but lives in a different section. Tracked as #542.

Acceptance criteria

  • A new file packages/agents/content/skills/_data/release-notes-voice.md exists and carries: The reader/audience frame, the detail-is-routed principle, the two rules (per-sentence outcome test and identifier ban with the user-configurable-surface allowlist), the length statement, the cross-type one-liner examples, and the worked Bad/Good pairs.
  • The ## What curly-brace block in summarize-change/SKILL.md is replaced with a thin pointer to the shared file plus ## What-specific framing. The previous inline rules and examples are removed.
  • The voice paragraph in commit/SKILL.md points to the shared file as the canonical voice source and includes the "first paragraph stands alone" distinction.
  • Audience-by-tier guidance in the new shared file references work-types.json rather than enumerating types inline.
  • The per-work-type one-line examples (fix:, feat:, internal:, refactor:, deps:) are present in the shared file unchanged in voice from the current versions.
  • The new guidance is tight enough that an agent can fail it on a literal-checklist read (the per-sentence test and identifier ban are mechanical). Verified by inspection of the rewritten guidance and by the next 3–5 feature/fix PRs' ## What quality.

Metadata

Metadata

Labels

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions