agentleFS
lbednerlbedner/aegis-stack/.claude/skills/release/SKILL.md

release

Skill144 starsChanged 15 months agoMITView on GitHub

Use when cutting a release of the aegis-stack package. Covers the version-bump file set, the changelog cut, the three release gates, TestPyPI rc verification, and the tag-push mechanics that trigger the publish workflow.

  • Commits and pushes

We split this skill into the rules it gives an agent

11 rules. 0 are common, 7 are distinctive, and 4 are very specific to this project.

  • 0

    Common

    Most of the 183 edited versions we read keep these.

  • 7

    Distinctive

    This author's own choices. Worth a look.

  • 4

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Use when the task is "release a new version of aegis-stack" (bump the version, publish to PyPI, cut a GitHub release).

    line 15
  2. Distinctive:

    Do NOT use for ordinary feature or fix work with no release attached, and do NOT use for generated-project releases (those follow the …

    line 18
  3. Distinctive:

    NOT use for generated-project releases (those follow the target project's own process, not this one).

    line 19
  4. Distinctive:

    Every other match of the old version string in the repo is test data or an unrelated coincidence.

    line 37
  5. Very specific:

    Commit the version bump and changelog cut.

    line 64
  6. Distinctive:

    Run the three gates (see Gates).

    line 67
  7. Distinctive:

    If the rc verification finds a problem, fix it, bump to the next rc number (never reuse or re-tag a burned rc, see Pitfalls), and repeat …

    line 77
  8. Distinctive:

    Before the final tag, list the bugs filed since the previous release tag, and for each one ask the user whether to fix it in this release …

    line 95
  9. Distinctive:

    All three are required; each independently catches a class of failure the others miss.

    line 107
  10. Very specific:

    Every line must read markers=0 rej=0 check_exit=0.

    line 150
  11. Very specific:

    Never pass skip-existing to the publish step: TestPyPI would then keep serving the stale build under that filename instead of failing …

    line 164

“Common” is measured: kept by at least 6 in 10 of the 183 edited versions of this file we could read. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Release

Cuts a new version of the aegis-stack package itself (not a generated project). Bumps the version string, cuts the changelog, runs three independent gates, verifies an rc on TestPyPI, then tags for a real PyPI publish and verifies again against the published package.

When to use

Use when the task is "release a new version of aegis-stack" (bump the version, publish to PyPI, cut a GitHub release).

Do NOT use for ordinary feature or fix work with no release attached, and do NOT use for generated-project releases (those follow the target project's own process, not this one).

Files that change

Version bump (all five must be touched together; verify each file actually contains the version string before editing it, since it is easy to assume a file participates when it does not):

  • aegis/__init__.py: __version__ = "X.Y.Z".
  • pyproject.toml: version = "X.Y.Z" under [project].
  • copier.yml (repo root): _version: "X.Y.Z".
  • CHANGELOG.md: the version also appears here as the new dated section heading (see the changelog cut step in Procedure).
  • uv.lock: the [[package]] name = "aegis-stack" entry's own version = "X.Y.Z" field. This one is not hand-edited; the pre-commit ty hook rewrites it, so stage it in a second commit pass (see Procedure).

Every other match of the old version string in the repo is test data or an unrelated coincidence; leave it alone.

Gate-relevant files (read, not edited, unless a gate fails):

  • Makefile (repo root): check, test-stacks-full, test-stacks-quick targets.
  • tests/test_runtime_dependencies.py: guards that ruff (and any other binary the updater shells out to at runtime) stays in [project].dependencies, not only a dev extra.
  • .github/workflows/release.yml: the tag-triggered publish workflow (v*.*.*-rc* routes to TestPyPI, bare v*.*.* routes to PyPI); read this if tagging behavior is ever in question.

Procedure

  1. Confirm the target version and the previous released tag.
  2. Bump the version string in all five files listed above. Open each file and grep for the old version string to confirm the edit landed; do not assume a file needs changing just because a prior release touched it.
  3. Cut the changelog in CHANGELOG.md: identify which items under [Unreleased] actually shipped in this release (cross-check with git log --first-parent <prev-tag>..HEAD so nothing merged after the branch point is mis-attributed), rename that content into a new dated [X.Y.Z] - YYYY-MM-DD section, draft the section body from the PR history for this range, and leave a fresh, empty ## [Unreleased] heading above it. This step is required and routinely forgotten; do not skip it.
  4. Commit the version bump and changelog cut. If the pre-commit ty hook rewrites uv.lock during this commit, git add uv.lock and commit again so the lockfile's own version field matches.
  5. Run the three gates (see Gates). Fix anything red before proceeding.
  6. Tag the release commit as a release candidate: git tag vX.Y.Z-rcN && git push origin vX.Y.Z-rcN. This is what actually triggers the publish workflow; merging the version-bump PR alone publishes nothing. Name the version-bump branch release-X.Y.Z-rcN, never vX.Y.Z-rcN: a branch with the tag's name makes git push origin vX.Y.Z-rcN fail with "src refspec matches more than one".
  7. Once the workflow is green, verify the rc via the TestPyPI upgrade-path recipe (see Gates, gate 3) run against the published rc rather than a local wheel.
  8. If the rc verification finds a problem, fix it, bump to the next rc number (never reuse or re-tag a burned rc, see Pitfalls), and repeat from step 5.
  9. Once an rc is clean, bump the version string from X.Y.ZrcN to the bare X.Y.Z in aegis/__init__.py, pyproject.toml, and copier.yml (the changelog section heading already says X.Y.Z from the cut; refresh uv.lock via uv lock), commit, and tag THAT commit: git tag vX.Y.Z && git push origin vX.Y.Z. Do not tag the rc commit itself: the publish workflow builds whatever version pyproject.toml carries, so tagging the rc commit as vX.Y.Z would publish an X.Y.ZrcN wheel under a final tag. This publishes to PyPI and drafts a GitHub release.
  10. Post-publish, run the upgrade recipe once more against the published PyPI package (INDEX=pypi) to confirm real users get a clean upgrade.

Process follow-ups (a gap in this skill, a missing gate, a doc that should change) belong in the release they were found in. Raise them before the final tag (step 9), never after publishing.

Before the final tag, list the bugs filed since the previous release tag, and for each one ask the user whether to fix it in this release or ship without it. Bugs often get filed from other sessions while a release is in progress: #1523 (aegis add mcp conflicts) was filed between rc1 and rc2, and 0.15.0 shipped without it.

gh issue list --state open --label bug --search "created:>=<prev-tag date>"

Gates

All three are required; each independently catches a class of failure the others miss.

  • make check: framework lint, typecheck, and pytest. Catches a constant/config change made without updating the test that asserts on it.
  • make test-stacks-full: the full stack generation matrix (generate, install, lint, typecheck, pytest per stack combination). Catches template drift on stacks that no single local test generates on its own. make test-stacks-quick (base/everything/insights subset) is for iteration only; it never substitutes for the full run before a release.
  • Production-mode wheel test: the repo's own test venv installs --all-extras, so a dependency that lives only in the dev extra looks fine locally but is missing from a real uvx/pip install. Before tagging, run uv build, then uvx --from ./dist/aegis_stack-<ver>-py3-none-any.whl aegis update -y -p <fresh prev-release project> -t <repo> --to-version HEAD, and assert zero conflict markers and a completed post-gen run. Confirm tests/test_runtime_dependencies.py exists and passes; it guards ruff specifically for this exact failure mode.

Upgrade-path verification recipe (used in Procedure steps 7 and 10). Run it on several stack shapes, not one base project. A base project has too few files to catch most update bugs: 0.15.0rc1 passed on base but never brought files new to a stack to htmx projects. upgrade_stacks.sh (next to this file) creates five stacks at the previous release: base, everything, htmx-auth, finance-pg and worker-ai. It updates each one, then reports conflict markers, .rej files and the make check result for each:

# step 7: the rc on TestPyPI
FROM=<prev-version> TO=<rc-version> .claude/skills/release/upgrade_stacks.sh <scratch-dir>
# step 10: the final release on PyPI
FROM=<prev-version> TO=<version> INDEX=pypi .claude/skills/release/upgrade_stacks.sh <scratch-dir>

Also pass every component and service that is new in this release, as ADD=mcp ADD_SERVICES=research. Each stack then runs aegis add after its update. A new component is merged into files that were rendered before it existed, and the update check alone never tests that: 0.15.0 shipped with aegis add mcp conflicting in main.py (#1523). List only things new in this release. No stack made with the previous version can already have them, so the add never fails because the stack already has one.

Every line must read markers=0 rej=0 check_exit=0. The everything stack takes about 7 minutes, so run the script in the background. Delete <scratch-dir> afterwards.

Pitfalls

  • This procedure describes git add, git commit, git tag, and git push as the steps that must happen, but per the repo git policy the agent runs no git command without explicit user approval; stop and ask before each, the same as any other workflow.
  • A burned rc version string (any rc that ever reached TestPyPI) can never be reused, even after deletion: PyPI/TestPyPI reject the filename permanently, and re-running the same tag replays the same HTTP 400. Always increment to the next rc number instead of re-tagging.
  • Never pass skip-existing to the publish step: TestPyPI would then keep serving the stale build under that filename instead of failing loudly, and the smoke test would silently verify the wrong artifact.
  • The release workflow triggers only on a tag push, not on a merge. Merging the version-bump PR into main publishes nothing; the actual publish and GitHub-release steps only run after git push origin vX.Y.Z[-rcN] against the merged commit.
  • A dependency that lives only in the dev extra (--all-extras in the repo's own test venv) passes every local and CI test yet is silently absent from a real uvx/pip install; this is exactly what the production-mode wheel test gate exists to catch, so do not skip it even when the other two gates are green.
  • UV_PYTHON=3.11 is tool-only: it belongs in the release/CI/canary jobs that build and test this CLI, and must never be set globally in the stack matrix, because generated projects require Python >= 3.13. Pair it with UV_LINK_MODE=copy to avoid broken cache hardlinks.
  • The changelog cut is easy to forget entirely since nothing fails loudly if it is skipped; verify the dated section exists and [Unreleased] is empty again before tagging, not just that the version files were bumped.

Download now (ZIP)

  • Other versions194 projects use a version of this.

    Word for word · 0

    None found.

    Edited · 0

    None found.

    Wrote their own version · 194

    1. paperclipai/paperclip★ 110ksame name
    2. modelcontextprotocol/servers★ 92ksame name
    3. remotion-dev/remotion★ 70ksame name
    4. traefik/traefik★ 65ksame name
    5. usememos/memos★ 64ksame name
    6. tw93/Pake★ 63ksame name
    7. Yeachan-Heo/oh-my-claudecode★ 40ksame name
    8. Yeachan-Heo/oh-my-claude-sisyphus★ 40ksame name
    9. tobi/qmd★ 30ksame name
    10. jlowin/fastmcp★ 28ksame name

    184 more not listed

    How matches are found. Word for word: the exact same text. Edited: shares passages with this file (“99% same” means 99% of its five-word phrases also appear here; 10% or more counts). Their own version: similar meaning, or, weakest, the same name. We can’t tell which project had it first. Projects are counted among the 200 most-starred candidates, and mentions are links to the repository we found, up to 50 per site, so both counts are a floor.

  • Used alongsideProjects with it also use create-agent-adapter, changelog-style and 10 more.

    Other files people use alongside this one.

    Files found in the same public projects as a version of this one, more often than they turn up anywhere else. Each project counts once, large collections count for less, and this file's own repository is left out.
    • MicrosoftSkill

      create-agent-adapter

      Technical guide for creating a new Paperclip agent adapter. Use when building a new adapter package, adding support for a new AI coding tool (e.g. a new CLI agent, API-based agent, or custom process), or when modifying the adapter system. Covers the required interfaces, module structure, registration points, and conventions derived from the existing claude-local and codex-local adapters.

      Also in 5 projects that use this

    • GrinvSkill

      changelog-style

      Turn a commit range into CHANGELOG.md entries following common-changelog style. Use when finishing a PR (adding to the [Unreleased] section) or cutting a release (moving [Unreleased] under a new version heading).

      Also in 4 projects that use this

    • GrinvSkill

      docs-consistency-check

      Check README/manifest.json/server.json/CHANGELOG.md/AGENTS.md and docs/*.md for drift against the actual registered tools and source. Use after adding, renaming, or removing a tool, or as part of a live-audit pass.

      Also in 4 projects that use this

    • MicrosoftSkill

      pr-report

      Review a pull request or contribution deeply, explain it tutorial-style for a maintainer, and produce a polished report artifact such as HTML or Markdown. Use when asked to analyze a PR, explain a contributor's design decisions, compare it with similar systems, or prepare a merge recommendation.

      Also in 5 projects that use this

    • Microsoft AzureSkill

      documentation-consistency

      Keeps GPT-RAG MCP service and umbrella documentation aligned with shipped behavior. Use for capabilities, configuration keys, deployment steps, endpoints, defaults, operations, or breaking changes.

      Also in 6 projects that use this

    • parcadeiSkill

      agent-context-isolation

      Agent Context Isolation

      Also in 3 projects that use this

    • +3 more from Grinv
  • In this repository14 other files it gives its agents.

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.