Release (project-local)
SkillDev toolsRelease for this repo — CalVer tag + narrative prepend.
Available today. Use it from your connected AI after setup.
No other account needed.
Connect ahel once, and every AI you use reads what you have installed.
Then ask your AI: use the Release (project-local) skill
What this skill tells your AI
The instructions your AI receives, as published by jongwony/epistemic-protocols in .claude/skills/release/SKILL.md and read by ahel’s review.
Creates a CalVer tagged release with a hand-written narrative prepended to the body CI generates via scripts/package.js. Overrides the global /release skill for this repo.
Purpose
- Push CalVer tag → CI (
release.yml) runsscripts/package.jsto build ZIPs + producedist/release-notes.md, thengh release create --draft --notes-fileattaches it - Prepend a hand-written narrative block to the script-generated body so the release surfaces "why this release matters" before the commit list
- Leave publish (draft → published) to the user for manual review
Preconditions
- Working tree clean, on
main(or user-specified branch) ghauthenticated with push access to the target remote (fork or upstream)- Node 22+ on PATH (packaging requires
zlib.crc32)
Flow
Phase 1: Tag decision
- Previous tag:
git describe --tags --abbrev=0(excludes drafts, gives last tagged commit) - Today: derive
YYYY.MM.DDfrom current date - Candidate tag:
v{YYYY.MM.DD}, orv{YYYY.MM.DD}.{N+1}if same-day tag exists - If latest tag is already today's and is Draft (not published), ask whether to re-tag (delete + recreate) or increment
.N
Phase 2: Tag push
git tag <tag>git push origin <tag>→ triggersrelease.yml
Phase 3: Wait for CI draft
- Poll
gh run list --workflow=release.yml --limit 1 --json status,conclusion,databaseIdevery 5s, max 12 attempts (60s total) - When
status=completedandconclusion=success, fetch draft:gh release view <tag> --json body,url - If still
in_progressafter 60s: surface run URL and ask user whether to keep waiting - If CI fails: surface logs via
gh run view <id> --log-failed, do not proceed to Phase 4. Remediation: fix the cause and retag with.Nincrement, or clean up the pushed tag withgit push origin :refs/tags/<tag>before retrying
Phase 4: Narrative drafting
Analyze commits since previous tag:
git log --oneline <prev-tag>..HEAD
Select 3-4 highest-impact changes. Prioritize:
- New skills or protocols (
feat:with newSKILL.md) - Architectural principles (
rules/,CLAUDE.md, axiom tier changes) - User-facing behavior changes
- Cross-cutting refactors that affect multiple protocols
Deprioritize:
- Single-PR review-round commits, CI test count bumps, version bumps without content
- Commits whose only effect is subsumed by a broader commit in the same range
Theme axis enumeration (conditional on commit set complexity):
When the commit set admits multiple plausible theme axes — distinct ways to group the same commits under different unifying frames — enumerate ALL axes before drafting. Trigger: no single dominant change carries the release on its own; 5+ semantically distinct change clusters in the commit range is a heuristic signal of this condition, not the trigger by itself.
For each candidate axis, present as a numbered list (text output, not a gate option set — the user's response is free-form selection, supplement, or a new axis):
- Theme line: the unifying frame the axis would emphasize
- Foregrounds: which commits become the narrative centerpiece
- Backgrounds: which commits become accompanying detail
- Trade-off signal: structural strength (faithful to commit shape) vs. interpretive weight (post-hoc grouping)
Include a brief epistemic observation on which axes preserve the commit set's actual shape vs. which apply heavier grouping. When the commit set admits a single dominant theme — one frame is uniquely the best fit and other framings would feel like post-hoc reframing — skip axis enumeration and proceed directly to drafting.
After enumeration, draft narrative using the axis the agent judges best-fit; the gate at Phase 5 lets the user pick a different axis if preferred.
Draft narrative using this template (Korean, matching repo's PR body convention):
> **Background**
>
> {experiential / contextual narrative — the lived origin and why this release matters; 1-3 paragraphs. Background IS pure context — the theme sentence belongs in the 무엇이 새로운가요? section below.}
>
> ---
>
> **무엇이 새로운가요?**
>
> 이번 릴리스의 핵심은 **{theme}** — {one sentence summarizing the release}.
>
> - {emoji} **`/command`** 또는 **{feature name}** — {user-facing narrative, 1-2 sentences}
> - {emoji} **...** — ...
> - {emoji} **...** — ...
> - {emoji} **...** — ...
>
> ---
{script-generated body, with its leading `# Epistemic Protocols vX` H1 line removed so it starts at `## Highlights`}
The narrative splits into two blockquoted sections, matching the repo's prior-release convention:
- Background — pure experiential/contextual narrative (the lived origin). The label is intentionally English
**Background**: a grandfathered exception to the Korean-narrative convention, carried forward from earlier releases (v2026.05.18,v2026.05.15) for visual continuity. The change-section label**무엇이 새로운가요?**stays Korean. - 무엇이 새로운가요? — leads with the theme sentence (
이번 릴리스의 핵심은 **{theme}** — ...), then the change bullets.
Both sections, and the close before the script body, are bounded by in-blockquote dividers (> ---). Each > --- must be preceded by a blank > line: in CommonMark a --- placed flush against paragraph text parses as a setext H2 underline, which would render the preceding line as a heading instead of a divider — the blank > line keeps it a thematic break.
The script body's leading # Epistemic Protocols vX H1 is stripped: the GitHub release title already renders the version, so a body H1 would surface a duplicate title. After stripping, the body begins at ## Highlights.
Emoji selection is descriptive: choose an emoji whose visual semantic matches the change class. The same change class may take different emoji across releases — match the release's framing, not a fixed table.
Phase 5: Gate with horizon fusion
Context (emit before the gate, as text output):
- Theme axis enumeration when generated in Phase 4 — condense to a labels-only form (axis names without per-axis 4-tuple) and reference the Phase 4 detail above when full re-surfacing would bloat the gate context; otherwise re-surface in full. Either form preserves Recognition that the user may select a different axis than the one the agent drafted from.
- Full composed body preview: narrative draft (closed with
> ---inside the blockquote) + script-generated body with its leading# Epistemic Protocols vXH1 stripped (begins at## Highlights) - Theme sentence and bullet selection rationale
Experiential elicitation (emit as part of context):
Background narratives benefit from the user's experiential grounding — the lived origin that motivated the release. The AI draft maps commit shape; the user supplies the grounding that makes the shape readable. Explicitly invite the user to supplement Background; supplementation is optional. When the AI draft already captures the origin from commit content alone, the invitation can be lightweight — but it must still be surfaced so the option is recognized rather than recalled.
Question: Apply the drafted narrative, supplement with experiential context, modify other elements, or skip?
Options:
- Apply — prepend narrative as drafted; proceed to Phase 6
- Add experiential context — user supplies lived origin / environmental observation; AI fuses it with the draft Background as a new horizon (preserving the AI's commit-mapping spine, adding the user's experiential grounding); revised draft re-presents at Phase 5 (loop)
- Modify — user supplies edits to axis selection, bullet text, emoji, or tone; revised draft re-presents at Phase 5 (loop)
- Skip — leave script-generated body as-is (patch-only releases per Rule 5); proceed to Phase 6 with no prepend
This gate is mandatory even if the narrative seems obvious — theme choice and origin framing are constitutive judgments the user owns.
Horizon fusion sub-protocol (engaged when user selects Add experiential context):
- Treat the AI draft Background as Horizon A — the commit-shape narrative
- Treat the user's experiential input as Horizon B — the lived origin
- Fuse: preserve Horizon B's voice and the arc the user actually supplied; let Horizon A inform which protocol/utility is named in the closing sentence
- Bullets remain anchored to Horizon A (commit-mapping); only Background absorbs Horizon B
- Per-horizon trace (preserved / transformed / dropped) renders as a single line before the fused candidate at Phase 5 — naming what each horizon contributed, what was transformed in fusion, and what was dropped. The trace surfaces fusion accountability, matching the trace-visibility pattern in
/realign. - Iteration is expected: each loop pass refines whatever dimension the prior pass left under-specified. Continue looping until Apply or Skip — do not pre-empt convergence by treating the first fusion as final.
Phase 6: Apply + surface
- Compose final body: narrative (closed with
> ---inside the blockquote) + CI body with its leading# Epistemic Protocols vXH1 stripped (begins at## Highlights) — prevents a duplicate title alongside the GitHub release title gh release edit <tag> --notes-file <tmp-path>- Output draft URL with a note that the user publishes manually via GitHub web UI
Rules
- Tag before narrative: CI must create the draft first. Narrative prepends to the script-generated body (Highlights/Protocols/Assets sections from
scripts/package.js); the skill does not replace or regenerate those sections. - Korean narrative: matches the repo's PR body language convention.
- Terminal operation bounded to body edit: the skill's terminal operation is
gh release edit <tag> --notes-file <path>against the existing draft. Release creation is owned by CI (via tag push trigger); publish-to-public is owned by the user via the GitHub web UI. - Theme over item list: the narrative answers "why this release matters"; the auto-generated section already enumerates what changed.
- 3-4 bullets max: more dilutes impact. If fewer than 3 user-facing changes exist, propose skipping the narrative entirely (patch-only releases do not need it).
- No draft republish on existing body: if the draft already has a narrative (check for leading
>blockquote in fetched body), ask before overwriting. - Failure surfacing: if CI fails, do not attempt narrative drafting — surface the failure to the user and stop.
Failure Modes
- CI timeout:
release.ymltypically completes in <15s. Ifstatus=in_progressafter 60s, surface the run URL and let user decide whether to wait or abort. - Working tree dirty: refuse to tag. Surface
git statusoutput. - Tag already exists (published): must increment
.Nsuffix — cannot overwrite a published release. - Tag already exists (draft): ask whether to delete draft + re-tag, or increment
.N.
Signals
- GitHub stars
- 161
- Forks
- 15
- Last commit
- Sep 2026
- Hacker News mentions
- 20
Advanced
- Catalog kind
- skill
- Gateway key
release-jongwony- Source
- github.com/jongwony/epistemic-protocols