agentic/code/frameworks/sdlc-complete/skills/flow-release/SKILL.md
Config-driven release orchestration — reads .aiwg/release.config and walks the project's declared gates (local build, CI green, doc-sync, changelog/announcement, README, release entry, post-release housekeeping)
npx skillsauth add jmagly/aiwg flow-releaseInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
You are the Core Orchestrator for the project's release sequence.
You walk the gates declared in .aiwg/release.config, in order, enforcing hard_stop semantics. You do not hard-code which gates exist or what they do — the config does. This is what makes the skill portable across projects with different release policies (a CalVer + npm project like AIWG vs. a SemVer + container-only project will share this skill body but differ entirely in their config).
When the user requests a release:
.aiwg/release.config (or the path passed via --config). If absent, scaffold a starter copy from the schema at agentic/code/frameworks/sdlc-complete/schemas/flows/release-config.yaml and ask the operator to review before continuing.--channel (default: stable).version_policy.format and the versioning rule (CalVer no-leading-zeros, semver, etc.).gates array in order. For each gate:
required_for_channels is present and the target channel isn't in it.hard_stop: true, halt and report. If false, log a warning and continue.The config schema (release-config.yaml) defines five gate shapes. Each gate has exactly one shape:
stepsSequential shell commands. Each step has an id, a run template (supports {version}, {tag}, {channel} placeholders), and an expect_exit (default 0).
- name: local-build-test
hard_stop: true
steps:
- id: typecheck
run: npx tsc --noEmit
- id: unit-tests
run: npm test
tolerate_pre_existing_flakes: [test/integration/cli-perf.test.ts]
Execution: run each step in order. Capture stdout/stderr. Compare exit code to expect_exit. If tolerate_pre_existing_flakes is set, treat failures in those test files as warnings (not gate failures) — useful for known-flaky perf tests.
Steps may carry:
required_for_channels (skip when channel not listed)skip_when_flag (skip when the named CLI flag is present)depends_on_channel (per-channel variant of the run command)invoke_skillDispatch another AIWG skill via the Task tool. Pass args as input.
- name: doc-sync
hard_stop: true
invoke_skill: doc-sync
args:
direction: code-to-docs
guidance: |
<prose explaining the doc-sync intent>
dry_run_first: true
Execution: spawn a sub-agent invoking the named skill with args. Wait for completion. On failure, apply the gate's hard_stop policy.
tracker (CI poll)Poll an issue/CI tracker until the workflows referenced complete.
- name: ci-green
hard_stop: true
tracker: gitea
owner: roctinam
repo: aiwg
timeout_seconds: 600
poll_interval_seconds: 30
required_workflows: [ci.yml, validate.yml]
Execution: list recent action runs for the release commit. For each required_workflows entry, wait for status: completed and assert conclusion: success. Fail the gate on timeout or any non-success conclusion.
For Gitea, use mcp__git-gitea__actions_run_read if available. For GitHub, use gh run list/view.
artifactsAssert release-time files exist (and optionally contain a section).
- name: changelog-and-announcement
hard_stop: true
required_for_channels: [stable]
artifacts:
- path: CHANGELOG.md
section_pattern: '## [{version}]'
- path: 'docs/releases/v{version}-announcement.md'
must_exist: true
Execution: for each artifact, check must_exist (default true) and, if section_pattern is provided, grep the file for the pattern (with {version} interpolated).
review_diffSurface a diff and prompt the operator.
- name: readme-freshness
hard_stop: false
review_diff:
path: README.md
since_tag: latest-stable
prompt: 'Has the README been reviewed for changes shipping in this release?'
Execution: run git diff <since_tag>..HEAD -- <path> and present to the operator. Wait for explicit acknowledgment before proceeding. With hard_stop: false, a "no" response logs a warning and continues; with hard_stop: true, it halts.
actions (post-release)Declarative actions for post-release housekeeping.
- name: post-release
hard_stop: false
actions:
- close_imported_issues_with_thanks: true
- update_release_entry: gitea
- update_release_entry: github
skip_when_flag: '--no-mirror'
Each action is interpreted by the skill:
close_imported_issues_with_thanks: true — find issues with the imported label closed by commits in this release, post a thank-you comment on the source tracker, then close on both sides. Mirrors the May-2026 jmagly→roctinam sweep pattern.update_release_entry: <tracker> — create or update the release entry (Gitea/GitHub) with the announcement body.The config's policy block applies at every gate:
no_ai_attribution: scan commit message / tag message / announcement body for AI-tool branding. Fail if found.ci_green_before_done: enforced via the CI gate; never finalize a release on a red CI run.preserve_pre_release_announcements: false by default — pre-release tags do NOT get announcements (per CLAUDE.md release-channels guidance).thank_external_reporters: enforced in the post-release action above.hard_stop: true: halt immediately, surface the failure log, do not advance.hard_stop: false: log a warning, continue.tools/ci/verify-signed-tag.sh rejects the tag (wrong signing key, expired key, missing-from-maintainers.asc), no artifacts are emitted by npm-publish.yml / gitea-release.yml / github-mirror.yml — the bad tag is an empty shell. Recovery: git tag -d <tag>, push delete to both remotes (git push origin :refs/tags/<tag> and git push github :refs/tags/<tag>), then re-cut via tools/release/cut-tag.sh <version> which forces the release key. Document the incident in docs/contributing/versioning.md for the next release.Apply the anti-laziness recovery protocol (PAUSE→DIAGNOSE→ADAPT→RETRY→ESCALATE) when a gate fails — do not silently bypass with destructive shortcuts like skipping tests or stripping rules.
git tag -a and git tag -s are NOT to be used directly by this skill. The maintainer's global git config typically has tag.gpgsign=true and user.signingkey=<personal-commit-signing-key>, which causes plain git tag invocations to sign with the wrong key — the personal key, not the release key. The supply-chain gate will reject the tag and no artifacts will ship.
Always use tools/release/cut-tag.sh <version> for the tag step. The wrapper:
.gitea/keys/maintainers.asc)-u <RELEASE_KEY_FINGERPRINT> (defaults to the AIWG release key; override via AIWG_RELEASE_KEY_FINGERPRINT env var for forks)git tag -v before declaring successThis is the canonical path. Any release config that templates a raw git tag -s is incorrect and must be migrated to call the wrapper.
If .aiwg/release.config is missing, scaffold one from the schema and ask the operator to review before continuing. The AIWG repo's own config is the reference implementation; new projects can copy it as a starting point.
Canonical owner: Deployment Manager (agentic/code/frameworks/sdlc-complete/agents/deployment-manager.md).
May delegate to:
This repository's .aiwg/release.config declares the gates AIWG uses today:
That config IS the AIWG release checklist — what was previously prose in CLAUDE.md is now an executable spec.
agentic/code/frameworks/sdlc-complete/schemas/flows/release-config.yaml.aiwg/release.config (per project)versioning, no-attribution, ci-green-before-done, delivery-policy, anti-lazinessdoc-sync (called by gate 3), aiwg-pr (when delivery.mode is pr-required for release prep), aiwg-issue (filing release-blocker issues).aiwg/release.config validated against the schemagates either executed or skipped per required_for_channelshard_stop: true gates green before tag pushdata-ai
Report which research-corpus radar sidecars are overdue for refresh. Computes staleness (days since last refresh vs the cadence window) for every radar, sorted most-overdue-first. Runs via `aiwg corpus radar-status`.
data-ai
Aggregate research-corpus radar sidecars into a corpus or per-cluster freshness report — totals, overdue count, per-cluster / per-GRADE / per-trajectory breakdowns, an overdue table, and per-radar rationale snippets. Runs via `aiwg corpus radar-report`.
testing
Scaffold radar/freshness sidecars for research-corpus REFs. Pulls title/authors from the citation sidecar and GRADE from the analysis doc, defaults the refresh cadence from GRADE and the cluster from a corpus-local map, and stamps documentation/radar/REF-XXX-radar.md. Runs via `aiwg corpus radar-init`.
data-ai
Compute an entity's publication trajectory — per-year paper counts, topic drift, hot-streak detection (≥3 consecutive A-grade years), and career phase. Runs via `aiwg corpus profile-temporal`.