Skip to content

chore(release-skill): tighten Rust-crates count and commit-list truncation#276

Merged
brunopgalvao merged 3 commits into
masterfrom
chore/improve-release-skill
Apr 19, 2026
Merged

chore(release-skill): tighten Rust-crates count and commit-list truncation#276
brunopgalvao merged 3 commits into
masterfrom
chore/improve-release-skill

Conversation

@brunopgalvao

@brunopgalvao brunopgalvao commented Apr 19, 2026

Copy link
Copy Markdown
Contributor

Summary

Three clarifications to the /release skill, caught while cutting v0.16.0 (#275).

What's changing

1. render.py — stop generating Python scripts per release

Every release until v0.16.0 produced /tmp/render_cover.py, /tmp/render_chain.py, /tmp/render_notes.py, /tmp/render_manifest.py, /tmp/render_pr_body.py as one-off scratch files with hardcoded scalars (VERSION strings, commit lists, RPC-captured values) re-typed each release. That's wasteful and — more importantly — hardcoded VERSION = "0.16.0" literals are fabricated values, violating the skill's own "no fabricated values" rule.

.claude/skills/release/render.py now ships as the single committed renderer with argparse subcommands:

Subcommand What it does
cover Executes the full cover.data.md contract: scalars from git, 6 variable-count fragments per the documented scaling rules, xmllint + zero-unresolved assertions.
cover-chain Walks primary → fallback endpoints (added a User-Agent header — rpc.polkadot.io was 403'ing Python's default UA), runs the one-shot capture, writes nothing + exit 0 if every endpoint fails (per the "never fabricate, never cache-reuse" rule).
notes, manifest, pr-body Scalars from args + git diff --shortstat; narrative markers from --summary-file / --whats-new-file / --commits-file / --breaking-file so LLM-authored prose stays separate from deterministic rendering.

End-to-end tested: all 5 subcommands produce xmllint-clean / yaml-valid outputs with zero unresolved tokens. SKILL.md now shows the render.py ... --out ... invocation in each render section instead of prescribing the substitution pipeline in prose.

2. Fix wrong commit subject in SKILL.md Phase 4

Phase 4 told the skill to commit with chore(release): vX.Y.Z, but COMMIT_CONVENTIONS.md says the subject must be Release v{VERSION} — the downstream tag regex ^Release v[0-9]+\.[0-9]+\.[0-9]+ \(#[0-9]+\)$ matches squash-merged commits on master. During the v0.16.0 cut I followed SKILL.md and committed chore(release): v0.16.0; only the PR title rescued the squash subject to Release v0.16.0 (#275). Fixed.

3. Rust crates count is now unambiguous (from the earlier commit on this branch)

The old rule — "count [package] sections across workspace Cargo.toml files" — was vague enough that v0.15.0 and v0.15.1 shipped 7 Rust crates even though the live workspace has only two members (dot/sdk + dot/cli). v0.16.0 correctly shows 2 because I interpreted the rule strictly, but the drift shouldn't depend on the renderer's judgment. The new rule is explicit about scope (workspace members only, not templates, not clones) and pins the expected answer so future drifts are obvious. render.py cmd_cover parses members = [ … ] directly, matching the documented rule.

4. @@COMMIT_LIST ≤13 case now has a truncation cap

The scaling table previously specified truncation for 14–26 commits (32 chars + …) and ≥27 commits, but said nothing for ≤13 commits. The B2 terminal panel is 444 px wide at font-size 10 (monospace), which fits about 46 chars after the │ {sha} {icon} prefix. Added subject truncated to 42 chars with …. Matches what v0.15.1 and v0.16.0 already did by eyeballing, and what render.py now enforces.

Test plan

  • cover.data.md rule changes read correctly
  • render.py syntax + --help parse
  • render.py manifest produces valid YAML
  • render.py cover-chain hits rpc.polkadot.io (UA header works) and renders a 15 KB SVG, xmllint-clean
  • render.py cover renders against live git range (v0.15.1..HEAD), xmllint-clean, zero unresolved
  • render.py notes substitutes scalars + reads marker files
  • render.py pr-body computes stats from git diff --shortstat, embeds {{HEAD_SHA}}-pinned cover URL
  • SKILL.md Phase 4 now uses Release vX.Y.Z subject per conventions
  • Dry-run the next release (e.g. v0.16.1 if/when cut) through render.py end-to-end

@brunopgalvao brunopgalvao marked this pull request as ready for review April 19, 2026 12:01
…ation

- Rust crates count now specifies exactly which Cargo.toml files are in scope (workspace members only, not templates or clones). v0.15.0 and v0.15.1 shipped '7 Rust crates' because the rule was vague; v0.16.0 correctly shows 2 but the drift shouldn't rely on luck.
- @@COMMIT_LIST scaling table now documents a 42-char subject cap for the ≤13 case. Previously only 14-26 and ≥27 had explicit truncation rules, forcing renderers to hand-pick a cap that fits the 444px B2 panel.
…per release

Every release until v0.16.0 (#275) produced /tmp/render_cover.py,
/tmp/render_chain.py, /tmp/render_notes.py, /tmp/render_manifest.py,
/tmp/render_pr_body.py as scratch files with hardcoded scalars (VERSION,
commit lists, RPC values). That wastes work, drifts from the data
contracts in covers/*.data.md, and — more importantly — hardcoded
VERSION strings are fabricated values, violating the skill's own
"no fabricated values" rule.

render.py with argparse subcommands replaces that pattern:

  cover         Runs the full cover.data.md contract: computes every
                scalar from git, generates the 6 variable-count fragments
                (COMMIT_LIST, DAILY_TIMELINE, CONTRIBUTOR_LIST, BAR_CHART,
                COMMIT_TYPES, REPO_STATE) per documented scaling rules,
                xmllint + zero-unresolved assertions.

  cover-chain   Walks endpoint primary -> fallbacks (User-Agent header
                added so rpc.polkadot.io stops 403-ing on Python's
                default UA), executes the one-shot capture sequence,
                writes nothing + exit 0 if all endpoints fail (per the
                "never fabricate, never cache-reuse" rule).

  notes,
  manifest,
  pr-body       Scalar tokens come from args (what the skill already
                decided) and git shortstat; narrative markers come from
                --summary-file / --whats-new-file / --commits-file /
                --breaking-file so the LLM-authored prose stays separate
                from deterministic rendering.

Also fixed in SKILL.md:
- Phase 4 commit subject was `chore(release): vX.Y.Z` but
  COMMIT_CONVENTIONS.md says it MUST be `Release v{VERSION}` (caught
  during v0.16.0 cut — the downstream regex
  `^Release v[0-9]+\.[0-9]+\.[0-9]+ \(#[0-9]+\)$` would not have
  matched the squashed commit; PR title rescued the squash subject by
  luck).
- All 3c/3d/3g sections now show the render.py invocation instead of
  prescribing "compute scalars + substitute + validate" in prose.
- Cover-chain skip path is now explicit ("renderer exits 0 and writes
  nothing; omit the footer embed").

End-to-end tested: manifest, cover-chain (live RPC), cover (local git),
notes, pr-body all produce xmllint-clean / yaml-valid outputs with zero
unresolved tokens.
Drift check on the chore/improve-release-skill branch flagged that
hero-dark.svg and hero-light.svg still embed v0.15.1 in the caption
line, while Cargo.toml on master is now 0.16.0 post-release. The
v0.16.0 release PR (#275) did not regenerate the brand assets after
bumping the workspace version, so this branch picks up the drift on
rebase. Regenerated via generate.sh; the only diff is the version
string in the caption.
@brunopgalvao brunopgalvao force-pushed the chore/improve-release-skill branch from 4012509 to fd51621 Compare April 19, 2026 12:03
@brunopgalvao brunopgalvao enabled auto-merge (squash) April 19, 2026 12:03
@brunopgalvao brunopgalvao merged commit 5c05f25 into master Apr 19, 2026
5 checks passed
@brunopgalvao brunopgalvao deleted the chore/improve-release-skill branch April 19, 2026 12:04
@brunopgalvao brunopgalvao mentioned this pull request Apr 22, 2026
9 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant