Release-management (spec)
June 2, 2026 · View on GitHub
Status
Proposed. No release-* skill code yet. This document defines the
runtime contract the future skills must satisfy. The lifecycle they
execute against is in process.md; the family overview
is in README.md. The pattern matches
Mentoring, spec lands first so the contract,
state-change boundaries, and adopter knobs are reviewable
independently from skill code.
This spec is binding on future PRs that add release-* skill code.
A skill PR that violates a cross-cutting commitment below is a
review-blocker, not a style nit.
Cross-cutting commitments
Every skill in this family inherits the four boundaries below. They are non-negotiable.
Boundary 1: Agent never holds the RM's signing key
The agent does not load, hold in memory, proxy, or invoke the
Release Manager's GPG private key, the GPG passphrase, the
hardware-token PIN, or any equivalent credential. Skills that need
a signature emit a paste-ready command sequence; the RM runs every
gpg --detach-sign, git tag -s, or token-backed operation on
their own machine, as themselves.
This mirrors
security-cve-allocate:
the skill emits the Vulnogram URL + paste-ready JSON, the human
submits the record. It satisfies
RFC-AI-0004 Principle 1.
Practical consequences:
- No skill in this family stores, requests, or reads from
GPG_PASSPHRASE, a passphrase file, a smartcard reader, or a key-server private endpoint. - The
adopter contract § signing declares the key
fingerprint the RM is expected to use; the skill verifies the
public counterpart appears in the project's
KEYSand refuses to advance if it does not. It never sees the private side. - Verification skills (
release-verify-rc) usegpg --verify <artefact>.asc <artefact>against the project's KEYS file as their only signature operation. They never sign. - Signing happens on hardware the RM personally controls. ASF policy requires the release-signing private key to live only on hardware the committer has physical possession of and full administrative control over; it MUST NOT be placed on, or used from, ASF-owned infrastructure (release-policy.html). The skill states this in its hand-off text; it cannot enforce it.
Boundary 2: Agent never publishes the release
The two operations that constitute publication are:
svn mv https://dist.apache.org/repos/dist/dev/<project>/<rc> https://dist.apache.org/repos/dist/release/<project>/<version>(Step 10).- The
[ANNOUNCE]email send toannounce@apache.organd the site-bump PR merge (Step 11).
Neither is performed by the agent. release-promote emits the
svn command set; the RM runs it under their own ASF credentials.
release-announce-draft emits the email body and opens (not
merges) the site-bump PR; the RM sends, a committer merges.
This boundary holds even with full per-skill permission grants. A
permission to run svn against dist.apache.org does not grant
permission to run the promotion svn move; that step is identified
by destination path (dist/release/) and is on a hard skill-side
denylist, not a permission denylist. Removing it requires editing
the skill, not the permission set.
Boundary 3: Agent never sends mail to dev@, users@, announce@
Drafting skills (release-vote-draft, release-announce-draft,
release-vote-tally for the [RESULT] reply) emit email bodies as
markdown blocks the RM copies into their mail client. No skill in
the family is wired to an outbound SMTP path, an MCP send-mail
endpoint, or a CLI that posts to mailing lists. This holds even
when the adopter ships a send-mail MCP for other skill families
(e.g. security-issue-import drafting reporter replies); the
release-management skill must explicitly not enumerate that
capability.
The boundary is read-side too: skills may read mail archives (PonyMail) to tally votes, but a read-mail capability for the project's PonyMail archive does not extend to a write-mail capability anywhere.
Boundary 4: Agent never auto-flips state labels
The planning issue's status label (see
process.md § Label reference) is
moved by the RM, not the skill. Every skill proposes the next
label transition in its output (e.g.
release-vote-tally proposes vote-passed or rc-rolled); the
RM applies it on the issue. This mirrors the security family's
discipline that
security-issue-triage
opens a discussion comment, never flips the label.
Rationale: labels are the lifecycle's audit trail. A label flip the RM cannot defend after the fact is worse than a slow flip.
Per-skill specifications
Each spec below names: scope, triggers, inputs, outputs, state- change boundary specifics, hand-off conditions, and adopter knobs the skill reads.
release-prepare
Mode: Drafting. Steps owned: 1, 2, 14.
Scope. Drafts the planning issue, the prep PR (version bump +
changelog + NOTICE/LICENSE), and the post-release -SNAPSHOT bump
PR.
Triggers.
- RM runs
/release-prepare <version>to open the planning issue. - RM runs
/release-prepare prep <version>to draft the prep PR after the planning issue is open and Step 1's scope is locked. - RM runs
/release-prepare post <version>after Step 11 to bump the development branch.
Inputs.
<project-config>/release-trains.md, train identity for the target version.- Merged-PR set between the previous release tag and the current
HEAD, fetched via
gh pr listfiltered by the configured base branch. <project-config>/release-management-config.md, Category-X dependency list to refuse on (per ASF licensing-howto).- The previous release's
NOTICEandLICENSEfiles for diff.
Outputs.
- A planning-issue body (markdown), labelled
release-planning. - A prep PR (separate invocation), labelled
prep-pr-open. - A post-release bump PR (third invocation), unlabelled.
State-change boundary. The skill opens the planning issue and opens the PRs as drafts. The RM marks them ready and merges. The skill never marks ready, never merges, never closes.
Hand-off conditions.
- A Category-X dependency appears in the prep diff → hand off to the RM with the dependency list; skill refuses to advance.
- The merged-PR set is empty (no changes since previous release) → hand off; the RM decides whether to skip the release.
- A
NOTICEdiff includes a removed attribution that the remaining file does not justify (still-vendored third-party code, missing notice) → hand off.
Adopter knobs.
| Key | Purpose |
|---|---|
release_planning_issue_template | Markdown template path under <project-config>/. |
release_branch_base | Default base branch for the prep PR (main, master, <release-train>-stable). |
category_x_dependencies | Pinned list of Category-X identifiers; skill refuses if any appear. |
version_manifest_files | Files the version bump touches (e.g. pom.xml, pyproject.toml). |
release-keys-sync
Mode: Drafting. Steps owned: 3.
Scope. Draft the diff that adds the RM's public key to the
project's KEYS file under dist/release/<project>/KEYS, emit the
svn commit sequence, remind the RM to upload to a public
keyserver, and validate that the key meets the ASF strength floor
(RSA at least 2048-bit, or an equivalently strong algorithm).
Triggers.
- RM runs
/release-keys-syncduring release prep; the skill detects whether the configured RM key fingerprint is already inKEYSand is a no-op if so.
Inputs.
<project-config>/release-management-config.md,rm_key_fingerprint.- Current
KEYSfile fromdist/release/<project>/KEYS. - RM's public key block (fetched from a keyserver
keys.openpgp.org/keyserver.ubuntu.comby fingerprint; fingerprint is the only input the agent uses).
Outputs.
- A markdown diff showing the
KEYSblock to append. - A paste-ready
svn checkout+edit+svn commitcommand sequence the RM executes under their ASF credentials.
State-change boundary. No commit, no key fetch into a held keyring. The skill formats the public-key block; the RM commits. The skill never operates on the private key half.
Hand-off conditions.
- The fingerprint configured in
<project-config>/release-management-config.mddoes not exist on the keyserver → hand off; the RM uploads it first or corrects the configured fingerprint. - The configured fingerprint is already in
KEYSbut for a different uid (key rolled) → hand off; the RM decides whether to replace or append. - The configured key is weaker than the ASF floor (an RSA key below 2048-bit) → hand off; the RM generates a conforming key before the release proceeds.
Adopter knobs.
| Key | Purpose |
|---|---|
keys_file_url | https://dist.apache.org/repos/dist/release/<project>/KEYS (overridable for non-ASF adopters). |
keyserver | Default keys.openpgp.org; overridable per project. |
rm_key_fingerprint | Set per-RM (often in .apache-magpie-overrides/user.md, not project config). |
release-rc-cut
Mode: Drafting. Steps owned: 4, 5.
Scope. Emit the paste-ready command sequence to tag the RC,
build artefacts, sign each artefact, generate checksums, and stage
to the adopter's distribution backend (default svn import to
dist/dev/<project>/<version>-rcN/; alternatives resolved from
release_dist_backend per
process.md § Adopter backends).
Triggers.
- RM runs
/release-rc-cut <version> rc<N>after the prep PR is merged.
Inputs.
<project-config>/release-build.md, build invocation, digest set (sha512, optionallysha256), binary-exclude list.- Current HEAD of the configured release branch.
- The RC number (from the trigger).
Outputs.
- A four-section markdown block: (1)
git tag -scommand, (2) build command, (3)gpg --detach-signfor each expected artefact, (4)sha512sum > artefact.sha512for each artefact. - A second markdown block with the backend-shaped staging command
sequence. For
svnpubsub(ASF default):svn importintodist/dev/<project>/<version>-rcN/. Forgithub-releases:gh release create <version>-rcN --draftplusgh release upload <version>-rcN <artefact>per artefact. Fors3:aws s3 cp --recursive <local> s3://<bucket>/<version>-rcN/. Forself-hosted: the command template atrelease_publish_command_templaterendered with<version>and<rcN>substituted.
The checksum commands emit .sha512 (and .sha256 where the
adopter's release-build.md requests it) only; MD5 and SHA-1
are prohibited for new releases. Signatures are detached .asc
files (gpg --detach-sign --armor), never a binary .sig. Both
prohibitions hold per
release-distribution § sigs-and-sums.
State-change boundary. The skill writes nothing to disk and runs nothing locally. The RM runs every command on their own machine, with their own key, in their own checkout, with their own ASF credentials.
Hand-off conditions.
- The RC tag already exists on the remote → hand off; the RM decides whether to delete (rare) or bump RC.
- The build command in
<project-config>/release-build.mdexits non-zero in the RM's run, the skill never sees this directly; the RM reports failure back, and the skill records it on the planning issue.
Adopter knobs. Inherits <project-config>/release-build.md
verbatim, see the
projects/_template/release-build.md
scaffold.
release-verify-rc
Mode: Triage / Pairing. Steps owned: 6.
Scope. Read-only verification of a staged RC. Designed to run
in two contexts: (1) the RM's pre-flight self-check before
posting the [VOTE] thread, and (2) any voter's Pairing-mode dev
loop before posting +1.
Triggers.
- RM or committer runs
/release-verify-rc <version>-rcNagainst a staged RC URL.
Inputs.
- The staging URL (from the trigger).
<project-config>/release-build.md, expected artefact list, digest set, binary-exclude rules, RAT (license-header) configuration path.- The project's
KEYSfile fromdist/release/<project>/KEYS.
Outputs.
- A pass/fail report per check (signatures, checksums, license headers via Apache RAT, NOTICE / LICENSE presence + diff vs previous release, no prohibited binaries, version-string consistency).
- A summary classification:
PASS,PASS-WITH-WARNINGS,FAIL.
The report is a mechanical aid, not a vote. A PASS does not
discharge a voter's own ASF obligation to download, build, and
test the candidate on their own hardware before posting a binding
+1; the skill states this in the report header.
State-change boundary. Read-only. The skill posts no comments
unless explicitly invoked with --post-to <planning-issue>, in
which case it proposes a comment for the RM's confirmation before
posting.
Hand-off conditions.
- A signature fails to verify against the project's
KEYS, the skill reportsFAILand refuses to mark the check ambiguous. The RM rolls a new RC. - A binary appears that the binary-exclude list neither permits
nor names, the skill reports
FAILand points at the file; the RM decides whether to exclude or pull the binary.
Adopter knobs. Inherits <project-config>/release-build.md.
release-vote-draft
Mode: Drafting. Steps owned: 7.
Scope. Draft the [VOTE] email body to dev@<project> from
the planning issue's metadata.
Expedited releases. A vote window shorter than the ASF 72h
baseline is permitted only in exceptional circumstances (e.g. a
critical security fix). When vote_window_hours is below 72, the
skill requires an explanation of why the release is expedited in
the [VOTE] body and flags the RM's obligation to report the
deviation in the project's next board report, per
release-policy.html § release approval.
The skill never silently drafts a sub-72h [VOTE].
Triggers.
- RM runs
/release-vote-draft <version>-rcNafter the RC is staged andrelease-verify-rcreportsPASS.
Inputs.
- Planning issue body.
- Staging URL, tag URL, KEYS URL, changelog URL.
<project-config>/release-management-config.md, vote-window length (overrides therelease-policy.html § release approvalbaseline if the project demands a longer window; the baseline is the floor, never the ceiling).<project-config>/canned-responses.md,[VOTE]body template if the project has one; otherwise the skill uses a default template that mirrors therelease-policy.html § release approvalreference body.
Outputs.
- A markdown block containing the
[VOTE]subject line and body. - A second markdown block for the planning-issue comment summarising the vote-open state (proposed, not auto-posted).
State-change boundary. No mail send. No issue comment without explicit RM confirmation.
Hand-off conditions.
release-verify-rcdid not run, or ran withFAIL, skill refuses to draft the[VOTE]and hands off; the RM either passes verification first or explicitly overrides (--skip-verify-check, logged on the planning issue).
Adopter knobs.
| Key | Purpose |
|---|---|
vote_window_hours | Hours the vote remains open; floor per ASF policy. |
vote_subject_template | Subject-line template ([VOTE] Release <project> <version>-rcN). |
vote_dev_list | Mailing list (dev@<project>.apache.org). |
release-vote-tally
Mode: Triage. Steps owned: 9.
Scope. After the approval window closes, fetch the approval
signal from the adopter's release_approval_mechanism backend,
classify each reply / approval as +1 / 0 / -1, classify each
approver as binding or non-binding against the configured
roster, propose the result body (mailing-list [RESULT] [VOTE]
or backend-equivalent).
Fractional votes. A fractional vote (+0.9, +0.5) is not
ambiguous: it is determinately non-binding per ASF voting
convention. The skill classifies it as non-binding directly and
does not mark it AMBIGUOUS. The skill also counts only the
explicit +1 replies it parses from the thread; it never
attributes an implicit +1 to the Release Manager.
Triggers.
- RM runs
/release-vote-tally <version>-rcNafter the configured approval window (vote_window_hoursfordev-list-vote,approval_window_hoursfor non-list mechanisms) has elapsed.
Inputs.
- Approval signal: mail thread (
dev-list-vote), Discussion thread + reactions (github-discussion), PR review approvals (pr-approval), or signed off-band roster file (maintainer-roster). Backend resolved fromrelease_approval_mechanism. - Approver roster:
<project-config>/pmc-roster.mdfor ASF (therelease_approver_roster_pathdefault), or<project-config>/release-approvers.md(or adopter-named path) for non-ASF. Both files share the same schema. <project-config>/release-management-config.md, vote-pass rule (baseline fordev-list-vote:release-policy.html § release approvalthree binding+1minimum, more binding+1than-1; project override permitted only to strengthen, never to weaken; for non-list mechanisms, the backend-specific rule keys (approval_pr_min_approvalsetc.) play the same role).
Outputs.
- Per-reply classification table: from-address, binding flag, vote value, ambiguous flag, raw vote line.
- Tally summary: binding
+1count, binding-1count, non-binding counts, ambiguous count, pass/fail per the configured rule. - A
[RESULT] [VOTE]email body (markdown block). - The proposed next label (
vote-passedorrc-rolled).
State-change boundary. No mail send. No label flip. The classification is the agent's; the decision is the RM's.
Hand-off conditions.
- An ambiguous vote (
+1 with one caveat,+1 if X is added), the skill marksAMBIGUOUS, needs RM calland refuses to count. The RM resolves by replying to the voter on the thread; the skill re-runs after the resolution lands. (A fractional vote is not ambiguous, it is classified non-binding directly, see the Fractional votes note above.) - A binding voter cannot be resolved against
pmc-roster.md, the skill flags and hands off; the RM updates the roster or corrects the from-address.
Adopter knobs.
| Key | Purpose |
|---|---|
mail_archive | Archive backend; default ponymail. |
mail_archive_url_template | URL template the skill uses to fetch the thread. |
vote_pass_rule_overrides | Optional stricter rule (e.g. require five binding +1); never weakens the ASF baseline. |
result_subject_template | Subject line for [RESULT] [VOTE] ([RESULT] [VOTE] Release <project> <version>-rcN). |
release-promote
Mode: Drafting. Steps owned: 10.
Scope. Emit the backend-shaped promotion command set after a
passing vote. For svnpubsub (ASF): svn mv dist/dev → dist/release
plus commit message. For github-releases:
gh release edit <version> --draft=false. For s3:
aws s3 mv --recursive s3://<bucket>/<version>-rcN/ s3://<bucket>/<version>/.
For self-hosted: the promote half of release_publish_command_template.
Triggers.
- RM runs
/release-promote <version>-rcNafterrelease-vote-tallyhas reportedvote-passed.
Inputs.
- Staging URL (
dist/dev/<project>/<version>-rcN/). - Target URL (
dist/release/<project>/<version>/). - The
[RESULT] [VOTE]archive URL (for the commit message). <project-config>/release-management-config.md,release_dist_url_template.
Outputs.
- A markdown block with the
svncommand sequence (svn mv,svn commit -m, expected mirror-propagation note). - A proposed next label:
promoted.
The mirror-propagation note also records the earliest time the
download page may be updated and the [ANNOUNCE] sent: ASF policy
requires at least one hour after the promote commit
(release-policy.html).
State-change boundary. This skill is the
Boundary 2
demonstration. The agent does not run the svn mv. The promotion
target URL is identified by dist/release/ prefix and is on a
hard skill-side denylist; removing it requires a skill PR.
Hand-off conditions.
- The planning issue does not carry
vote-passed, skill refuses to advance; the RM either rerunsrelease-vote-tallyor explains the override on the planning issue. - The target URL already contains the version (e.g. a previous promote attempt half-landed), skill refuses and hands off; the RM resolves with ASF infra.
- The RM is a committer but not on the PMC roster, the
dist/release/tree is PMC-write-only by default (release-policy.html); the skill emits an "ask a PMC member to publish" hand-off instead of thesvn mvcommand set.
release-announce-draft
Mode: Drafting. Steps owned: 11.
Scope. Draft the announcement artefact and the site-bump PR
on the configured site repo. The announcement artefact shape
depends on release_announce_backend: [ANNOUNCE] email body for
announce-list (ASF default), GitHub Release page body for
github-release-notes, blog-post markdown for site-post,
webhook message body for discord-channel. The site-bump PR is
emitted only when site_repo is configured.
Triggers.
- RM runs
/release-announce-draft <version>after the promote step is confirmed (planning issue carriespromoted).
Inputs.
- Planning issue body.
- The
dist/release/<project>/<version>/URL. - The previous release's announcement body, fetched from the
announce@apache.orgarchive, for tone and format consistency. <project-config>/site-repo.md, site repo path, files to update (download page, release notes index, current-version banner).<project-config>/release-management-config.md,announce_subject_template.
Outputs.
- A markdown block with the
[ANNOUNCE]subject + body. - A draft PR opened against the configured site repo with the download-page / release-notes / banner updates.
ASF constraints the drafted artefacts must satisfy, all stated in
the output so the RM cannot miss them: the [ANNOUNCE] goes out no
sooner than one hour after the Step 10 promote commit; it is sent
from an @apache.org address (the announce list rejects other
senders); the body links the project Download Page rather than a
direct dist.apache.org URL; and the site-bump PR's download links
resolve through the closer.lua mirror redirector
(release-policy.html,
release-distribution).
State-change boundary. No mail send. The PR is opened as draft; the agent never marks ready and never merges.
Hand-off conditions.
- The site repo does not exist or the agent lacks write access, hand off; the RM either opens the PR manually from the drafted diff or grants access.
- The previous announcement body cannot be fetched (archive unreachable), the skill drafts from the default template and flags the missing-precedent on the planning issue.
release-archive-sweep
Mode: Triage. Steps owned: 12.
Scope. Scan dist/release/<project>/, identify releases past
retention per the project's rule, propose the svn mv to
archive.apache.org (or the project's configured archive
location).
Triggers.
- RM runs
/release-archive-sweepperiodically (e.g. after each release; or on schedule).
Inputs.
- Current listing of
dist/release/<project>/. <project-config>/release-management-config.md,archive_retention_rule(default perrelease-distribution: only the latest version of each supported release line stays ondist/release/; project overrides may add lines but never remove the latest-of-each-line floor).- The configured archive URL template
(
https://archive.apache.org/dist/<project>/by default).
Outputs.
- A table of releases past retention.
- A markdown block with the
svn mvsequence the RM executes.
State-change boundary. Read-only on dist.apache.org; never
runs svn mv. The RM executes.
Hand-off conditions.
- The retention rule classifies the latest release as past retention (config error), skill refuses and hands off.
- A release on
dist/release/is not in<project-config>/release-trains.md(orphan), skill flags and hands off; the RM decides whether the orphan stays, archives, or gets reconciled into a train.
release-audit-report
Mode: Triage (read-only dashboard). Steps owned: 13.
Scope. Assemble a per-release record from the planning issue, vote thread, RC artefact list, promote revision, announcement archive URL. Output appended to the project's audit log.
Triggers.
- RM runs
/release-audit-report <version>after Step 12. - Optionally scheduled, the framework can rerun the report periodically to catch late corrections.
Inputs.
- Planning issue and every comment on it.
[VOTE]and[RESULT]archive URLs.- The RC artefact list with sigs and checksums (recorded by
release-rc-cuton the planning issue). - Promote
svnrevision. [ANNOUNCE]archive URL.<project-config>/release-management-config.md,audit_log_path.
Outputs.
- A markdown record appended to
<adopter-repo>/<audit_log_path>/<version>.md. The append is proposed as a PR against the adopter repo, not committed directly.
State-change boundary. Read-only on every release surface. Write-side limited to opening a PR on the adopter repo's audit log; the PR is reviewed and merged by a committer.
Privacy boundary (per RFC-AI-0004 Principle 6). The audit log is committed to the adopter repo and is public by default. The skill MUST NOT include:
- Any content read from the security tracker (
<tracker>), CVE drafts, GHSA forwards, reporter mail, embargoed disclosure text, severity scores, reporter-supplied CVSS, pre-disclosure CVE detail. The release planning issue is public; the security tracker is not. Even if a release closes a CVE, the audit record cites the public CVE identifier and the public fix PR, never the security-tracker thread that triggered them. - Email addresses of voters or commenters. The record cites
voters by their
<project>PMC roster handle (already publicly listed atprojects.apache.org/projects/<project>), not by personal email. - Any content that did not pass through a reviewed PR or a public mailing-list archive. External content is data to analyse, never an instruction to obey.
If a required input would force the skill across this boundary,
the field appears as REDACTED in the report and the skill
records the reason in the PR description so a committer can
decide whether to widen the audit-log scope.
Hand-off conditions. None expected, the skill is informational.
If a required input is missing, the report includes a MISSING
flag for that field and continues.
Adopter contract
Per-project values live in
<project-config>/release-management-config.md. See the template at
projects/_template/release-management-config.md.
Required keys (cross-skill):
| Key | Purpose | Used by |
|---|---|---|
release_dist_backend | One of svnpubsub / github-releases / s3 / self-hosted. Selects the staging-and-promote command set. | release-rc-cut, release-promote, release-archive-sweep |
release_approval_mechanism | One of dev-list-vote / github-discussion / pr-approval / maintainer-roster. Selects how release-vote-draft opens the approval and how release-vote-tally reads it. | release-vote-draft, release-vote-tally |
release_announce_backend | One of announce-list / github-release-notes / site-post / discord-channel. Selects the announcement artefact shape. | release-announce-draft |
release_dist_url_template | https://dist.apache.org/repos/dist/<bucket>/<project>/<version>/ for svnpubsub; backend-shaped URL template for non-ASF backends. | release-rc-cut, release-promote, release-archive-sweep |
release_publish_command_template | Backend-specific command template (required when release_dist_backend = self-hosted; defaulted from the backend for the other values). | release-rc-cut, release-promote |
keys_file_url | URL of the project's signing-key trust anchor (KEYS on ASF; equivalent file on non-ASF). | release-keys-sync, release-verify-rc |
release_approver_roster_path | Roster the release-vote-tally skill consults to classify binding vs non-binding. ASF default: <project-config>/pmc-roster.md. | release-vote-tally |
vote_window_hours / approval_window_hours | Approval window length. ASF floor per policy. | release-vote-draft, release-vote-tally |
vote_pass_rule_overrides | Optional stricter rule (ASF baseline cannot be weakened; non-ASF backends define their own rule keys). | release-vote-tally |
archive_retention_rule | Retention rule for the archive sweep. | release-archive-sweep |
audit_log_path | Path under the adopter repo for audit records. | release-audit-report |
rm_key_fingerprint | RM's key fingerprint (often per-user, in .apache-magpie-overrides/user.md). | release-keys-sync |
category_x_dependencies | Pinned Category-X identifiers; refuses prep PR if any appear. | release-prepare |
The contract is the single per-adopter knob set. Skills consult
the file, fall back to documented defaults if a key is missing,
and refuse to proceed if a required key is missing (refusal
text names the key). Backend-specific required keys (per the
backend table in
projects/_template/release-management-config.md)
are required only when the corresponding backend is selected.
ASF TLP releases are pinned to release_approval_mechanism = dev-list-vote (mandatory per
release-policy.html § release approval)
and release_announce_backend = announce-list (mandatory per
release-policy.html § announcements).
release-vote-tally and release-announce-draft refuse to run an
ASF TLP release against any other value; non-ASF adopters set the
keys their workflow uses.
Eval
Skill behaviour in this family is probabilistic; correctness lives
in distributions, not unit tests. Every skill in this family
ships with eval cases and a grading methodology before it
leaves experimental. A skill without an eval is unreleased,
regardless of how well it performs in a demo. This complements
RFC-AI-0004 Principle 4
on conversational correctability.
Eval expectations per skill:
| Skill | Eval focus | Grading signal |
|---|---|---|
release-prepare | Version-bump correctness across version_manifest_files; Category-X denylist hits; changelog draft on real release history | Diff matches hand-rolled bump; denylist refuses on seeded violations; changelog covers ≥90% of merged PRs in window |
release-keys-sync | KEYS-block diff correctness for first-time RM | Public block matches gpg --export --armor <fp> byte-for-byte; never proposes a private key fragment |
release-rc-cut | Paste-ready recipe completeness; signed-tag + detached-sig + checksum command set | Recipe reproduces a known-good RC end-to-end on a fixture project; no missing or extra commands |
release-verify-rc | False-negative rate on tampered fixtures (mutated sig, missing checksum, prohibited binary, missing LICENSE/NOTICE, RAT failure) | Catches 100% of seeded defects; false-positive rate <5% on known-good RCs |
release-vote-draft | [VOTE] body conformance to ASF policy; subject template correctness | Body includes mandatory checklist; subject matches vote_subject_template; never schedules window shorter than vote_window_hours |
release-vote-tally | Binding/non-binding classification accuracy on real vote threads; AMBIGUOUS detection rate | Classification matches PMC ground truth on a labelled corpus; AMBIGUOUS, needs RM call fires on every adversarial case (lazy +1, conditional +1, retracted vote) |
release-promote | svn mv command-set correctness | Commands replay against a sandbox svn mirror produce the expected target layout |
release-announce-draft | [ANNOUNCE] body completeness; site-PR scope correctness | Body cites canonical URLs (release, KEYS, sigs); site PR touches only files in site_pr_files |
release-archive-sweep | Retention-rule application accuracy | Identifies the exact set of past-retention releases on a fixture dist/release/<project>/ listing; refuses on latest_of_supported_line violation |
release-audit-report | Field coverage; MISSING flag accuracy | Report includes every required field where source data exists; MISSING only fires when source data is genuinely absent |
Eval corpora are project-specific (real [VOTE] threads, real
RC artefact lists), so each adopter is expected to contribute
fixtures from their own release history. The framework ships a
seed corpus per skill (synthetic but realistic) so a new adopter
can run a baseline eval before recording their own.
Open questions
Surfaced here so reviewers can weigh in before any skill is built.
- Should
release-verify-rcship as a Pairing skill from day one, or land as Triage and graduate later? Current draft: ship Triage-marked with explicit Pairing-mode invocation (/release-verify-rc --pairing) so the same code path serves the RM's project-side self-check and the voter's developer-side pre-flight. The framework's Pairing-mode definition is still proposed (docs/modes.md§ Pairing); this question is best resolved alongside the Pairing spec, not in isolation. - Where do non-ASF adopters' release-distribution analogues
plug in? Current draft:
release_dist_url_templateis generic enough to point at a GitHub Releases URL or a self-hosted artefact store, but thesvn-shaped commands inrelease-rc-cutandrelease-promoteassume an svnpubsub workflow. A non-ASF adopter may need a parallel template (release_dist_command_template) that swapssvnforaws s3 mvorgh release upload. Defer to first non-ASF pilot. release-audit-reportaudit-log location: in the adopter repo, or in a separate audit repo? Current draft: adopter repo (<adopter>/<audit_log_path>/). A separate audit repo is the right call for projects with audit-trail isolation requirements; the skill can support both by accepting either a path inside the adopter repo or a URL to a separate repo, but the second case requires extra credentials and is deferred.- Auto-merge eligibility for the prep PR's
-SNAPSHOTbump (Step 14)? Current draft: not eligible. The Step 14 PR is mechanical (<version>-SNAPSHOTbump on a single manifest file) but perdocs/modes.md§ Auto-merge, Auto-merge is off until Pairing has run stable for two quarters. Revisit when Auto-merge sequencing changes; the bump is a plausible first eligible class given its mechanical shape and reversibility. - Publishing to distribution areas beyond
dist/release/, and validating them. Some projects also publish a release to language package indexes (PyPI, npm, Maven Central) or container registries as part of the same cycle. The current family scopes to the ASFdist/svnpubsub area only. A future skill could draft and verify those secondary publications. Out of scope for this first docs PR; tracked here so it is not lost.
Cross-references
README.md,process.md, within this family.projects/_template/release-management-config.md, adopter contract scaffold.docs/modes.md§ Drafting, § Triage, modes the skills inhabit.docs/security/README.md, precedent for a multi-skill ASF-process family with shared state-change discipline.docs/mentoring/spec.md, precedent for spec-before-code.docs/rfcs/RFC-AI-0004.md, the principles every boundary inherits.- ASF release policy, ASF release distribution, ASF release signing, ASF licensing-howto, Apache RAT, canonical foundation references.