Skip to main content

entwurf-release

Operate entwurf SemVer releases through four explicit modes: land, prepare, make, and publish. Use for pre-version exact-SHA CI landing, CHANGELOG and package preparation, static and LIVE gates, prepared-HEAD CI, exact artifact acceptance, tag and GitHub release creation, repair-dist-tag publication, and post-publish registry proof. Each mode is a separate authority boundary. Triggers: release land, prepare-release, make-release, publish release, release cut, prerelease, repair release.

Ir a la instalación

Datos de origen

Repositorio
junghan0611/entwurf
Última actividad en el origen
12 de septiembre de 2026 a las 21:57
Idioma detectado de SKILL.md
inglés
Estrellas
28
Forks
4

Opciones de instalación

De forma predeterminada está seleccionado el prompt que primero revisa el origen. Puedes cambiar a un comando directo o descargar una copia local.

Revisa los archivos de origen

Lee SKILL.md y los archivos complementarios que muestra SkillsMP antes de decidir si quieres instalarlo.

Explorador de archivos
2 archivos

Mostrando SKILL.md

SKILL.md
Instrucciones de origen · Vista previa de solo lectura
name
entwurf-release
description
Operate entwurf SemVer releases through four explicit modes: land, prepare, make, and publish. Use for pre-version exact-SHA CI landing, CHANGELOG and package preparation, static and LIVE gates, prepared-HEAD CI, exact artifact acceptance, tag and GitHub release creation, repair-dist-tag publication, and post-publish registry proof. Each mode is a separate authority boundary. Triggers: release land, prepare-release, make-release, publish release, release cut, prerelease, repair release.
user_invocable
true
# entwurf-release Repository: `~/repos/gh/entwurf`. This skill is the shared release-operation SSOT that replaces the former `.pi/prompts/prepare-release.md` and `.pi/prompts/make-release.md` files. Claude Code discovers it natively under `.claude/skills/`; pi discovers the same file through `.pi/settings.json` and its `"skills": ["../.claude/skills"]` entry. ## Invocation ```text # Claude Code - stable example /entwurf-release land 0.12.8 /entwurf-release prepare 0.12.8 /entwurf-release make 0.12.8 /entwurf-release publish 0.12.8 /absolute/path/to/candidate.tgz latest # pi - prerelease/repair example /skill:entwurf-release land 0.12.8-repair.1 /skill:entwurf-release prepare 0.12.8-repair.1 /skill:entwurf-release make 0.12.8-repair.1 /skill:entwurf-release publish 0.12.8-repair.1 /absolute/path/to/candidate.tgz repair ``` Natural-language requests map to the same four modes. - `land` pushes an already reviewed pre-version HEAD and waits for the required exact-SHA CI jobs. It never edits, versions, tags, or publishes. - `prepare` edits release records, runs deterministic and LIVE gates, and creates the release-prep commit. It never pushes, tags, or publishes. - `make` pushes the prepared HEAD, waits for exact-SHA CI, creates and accepts one preserved candidate, then tags, stamps, and creates the GitHub release. It never runs `npm publish`. - `publish` publishes only the already accepted preserved candidate under an explicitly supplied dist-tag and proves the registry-installed result. The invocation authorizes only the named mode. `prepare` is not `land` authorization. `make` is not `publish` authorization. If the mode, version, or a mode-specific required argument is missing, ask for it and stop. ## Shared version contract Accept a normal SemVer release or prerelease. Reject a leading `v`. ```bash VERSION="<user argument>" case "$VERSION" in "") echo "ABORT: version required (for example 0.12.8 or 0.12.8-repair.0)"; exit 1 ;; v*) echo "ABORT: drop the leading 'v'"; exit 1 ;; esac if [[ ! "$VERSION" =~ ^[0-9]+\.[0-9]+\.[0-9]+(-[0-9A-Za-z-]+(\.[0-9A-Za-z-]+)*)?$ ]]; then echo "ABORT: version must be SemVer, optionally with a prerelease suffix" exit 1 fi ``` Valid examples: `0.12.8`, `0.12.8-repair`, and `0.12.8-repair.0`. `npm version` remains the final package-version validator. ## Exact-SHA CI oracle The shared helper is the only release instruction that classifies the required GitHub Actions run: ```bash CI_ORACLE=".claude/skills/entwurf-release/scripts/verify-exact-ci.sh" bash "$CI_ORACLE" "$(git rev-parse HEAD)" wait ``` It selects only a push-triggered `ci.yml` run whose `headSha` is the supplied full SHA, waits when requested, and requires these exact jobs to conclude `success`: - `check` - `install-surface` - `artifact-consumer` - `macos-install-surface` Use mode `verify` instead of `wait` when a prior run must already be complete. Never replace this with a branch-level green badge or the newest unrelated run. --- # LAND `land` exists for a narrower release contract that requires a pre-version implementation HEAD to receive its own CI run before release metadata changes. It is not required for every ordinary release. A `land <version>` invocation is explicit authorization for one ordinary push of `main`. It is not authorization for version edits, tags, GitHub releases, or npm publication. ## L0. Establish the landing boundary 1. Read `AGENTS.md`, `NEXT.md`, and `VERIFY.md` completely. 2. Read the `commit` skill because its push and post-push stamp rules remain in force. 3. Confirm that the current narrower contract actually requires a pre-version CI checkpoint. If it does not, stop and direct the operator to `prepare`. 4. Inspect and require a clean, non-diverged `main`: ```bash git status --short --branch git diff-index --quiet HEAD -- test "$(git branch --show-current)" = main git fetch origin main read -r BEHIND AHEAD < <(git rev-list --left-right --count origin/main...HEAD) test "$BEHIND" = 0 test "$AHEAD" -gt 0 ``` Confirm from the diff and log that HEAD contains only the reviewed landing set. Do not absorb an unrelated local commit into a release push. For a required pre-version checkpoint, the package must not already equal the target version: ```bash test "$(node -p "require('./package.json').version")" != "$VERSION" ``` ## L1. Prove pushability and push main ```bash SHA="$(git rev-parse HEAD)" git push --dry-run origin main git push origin main test "$(git ls-remote origin refs/heads/main | cut -f1)" = "$SHA" ``` Never force and never bypass verification. ## L2. Stamp the pushed commit Stamp only after the push succeeds, following the `commit` skill. If the stamp fails, report the exact error and stop; do not write the agenda target by hand. ## L3. Require exact-SHA CI ```bash CI_ORACLE=".claude/skills/entwurf-release/scripts/verify-exact-ci.sh" bash "$CI_ORACLE" "$SHA" wait ``` The oracle requires four axes on one run at that exact SHA: the workflow conclusion, the FOUR required job conclusions (`check`, `install-surface`, `artifact-consumer`, `macos-install-surface`), and the `check` job's `./run.sh check-gate-qualification` step concluding `success`. A skipped body is not evidence, so it fails the same way a red one does. `macos-install-surface` joined the required set in 0.20.0 on its first green; a red macOS runner now blocks a cut exactly like any other required job. If the oracle names the qualification step -- absent or skipped -- the body did not run at this SHA. Force it, wait, and re-run the oracle. `gh workflow run` takes a branch, never a SHA, so the branch must still point at `$SHA` when it is dispatched; the oracle re-checks `headSha` afterwards and refuses a run whose branch moved. `gh workflow run --ref` runs the REMOTE branch head, so check that head, not the local one. And do not sleep: until the dispatch run is registered, the oracle's newest-run rule would pick the already-finished push run and ABORT on the same axis. Wait for the run to appear, then hand it to the oracle. ```bash BRANCH="$(git rev-parse --abbrev-ref HEAD)" git fetch origin "$BRANCH" test "$(git rev-parse FETCH_HEAD)" = "$SHA" count_dispatch_runs() { gh run list --workflow ci.yml --event workflow_dispatch --commit "$SHA" \ --limit 20 --json databaseId --jq length } BEFORE="$(count_dispatch_runs)" gh workflow run ci.yml --ref "$BRANCH" -f qualify=true for _ in $(seq 1 12); do sleep 5 if [ "$(count_dispatch_runs)" -gt "$BEFORE" ]; then break; fi done test "$(count_dispatch_runs)" -gt "$BEFORE" || { echo "ABORT: no dispatch run appeared for $SHA within 60s" >&2 exit 1 } bash "$CI_ORACLE" "$SHA" wait ``` Report the SHA, workflow URL, the run event, all FOUR required job conclusions (`check`, `install-surface`, `artifact-consumer`, `macos-install-surface`), and the qualification-step conclusion. End with: ```text Landing checkpoint complete. Ready for /entwurf-release prepare <version>. ``` --- # PREPARE `prepare` edits, verifies, and commits. It does not push, tag, create a GitHub release, stamp a release, notify, or publish. ## P0. Establish the release boundary 1. Read `AGENTS.md`, `NEXT.md`, and `VERIFY.md` completely. A narrower current release contract in those files overrides a generic instruction in this skill. 2. Read the `commit` skill before creating any commit. 3. Inspect the current state: ```bash git status --short --branch git diff --check ``` Do not mix pre-existing implementation or review fixes into the release-prep commit. If a completed, clearly scoped fix is present and GLG has approved its commit, close it as a separate atomic commit first. If scope is ambiguous or unrelated, stop and ask. If the current contract requires a pre-version landing checkpoint, verify it before making any edit: ```bash git fetch origin main SHA="$(git rev-parse HEAD)" test "$(git rev-parse origin/main)" = "$SHA" bash .claude/skills/entwurf-release/scripts/verify-exact-ci.sh "$SHA" verify ``` A missing landing run is not a prepare failure to work around. Stop with the exact next command: `/entwurf-release land <version>`. Prepare may commit only release-prep files such as `CHANGELOG.md`, `package.json`, `pnpm-lock.yaml`, and an evidence handoff explicitly required by the current release contract. Forbidden in prepare mode: - pushes - tags - GitHub releases - release agenda stamps - notifications - npm publication - final candidate creation for a contract that requires post-commit CI first ## P1. Audit changes since the last release ```bash LAST_TAG=$(git tag --sort=-version:refname | head -1) printf 'baseline=%s\n' "$LAST_TAG" git log "${LAST_TAG}..HEAD" --oneline ``` Compare the commit range and closed `NEXT.md` work with the existing `CHANGELOG.md` `## Unreleased` section. Record only verified changes. Do not rewrite historical release sections. ## P2. Promote the release section Use the current KST date and transform the top of the changelog into this shape: ```text ## Unreleased ## <VERSION> - YYYY-MM-DD ``` Keep a fresh empty `## Unreleased` section above the promoted release body. Preserve the repository's existing heading punctuation if it uses an em dash. Release-gate paths and summaries may live in the release section or in an explicit durable operator handoff, following the repository's current convention. The paths and actual MUST/BEHAVIOR counts must not be lost. ## P3. Update package version and lockfile ```bash npm version "$VERSION" --no-git-tag-version pnpm install --lockfile-only ``` Inspect the resulting diff. Do not manufacture a lockfile change when the resolver produced none. ## P4. Run the deterministic floor ```bash pnpm run check:full ``` The FULL tier is the candidate floor; the everyday `pnpm check` core alone is never release evidence. Do not summarize the aggregate as a fixed number of gates. The current `package.json` check:* scripts are the SSOT. If any check fails, stop at that axis, fix it, and rerun the complete aggregate. The check chains carry only the qualification HEAD (`check-gate-manifests`) and deliberately exclude the mutant-executing body `check-gate-qualification`: the LIVE release gate (P5) runs the body as its own MUST step, and the exact-SHA CI `check` job (M2) requires it on the release commit. Do not add a manual qualification rerun here. Pushing the release tag creates no run, so the exact-SHA oracle never reads a tag run. It reads whichever run at that commit carries the body: the branch push when the push touched the qualification surface, otherwise the dispatch run the recovery above creates. ## P5. Run the LIVE release gate from fresh scratch Use the `tmux` skill because this command is long-running. Preserve the scratch directory and complete log. ```bash SCRATCH=$(mktemp -d "/tmp/entwurf-release-gate-${VERSION}.XXXXXX") LOG="$SCRATCH/release-gate.log" set -o pipefail LIVE=1 ./run.sh release-gate "$SCRATCH" --cut 2>&1 | tee "$LOG" ``` The release gate has two tiers: - `MUST` is release-blocking and owns the exit code. `FAIL` must be zero, and `--cut` enforces the other half: any MUST `SKIP` makes the run red, so a release run can no longer hide required LIVE work behind a skip. Each step is invoked and reports its own outcome (exit 0 PASS / 97 SKIP / else FAIL); a `[entwurf:skip]` line names the prerequisite that was missing. Drop `--cut` only for an unattended diagnostic pass, which is not acceptance. - `BEHAVIOR` is advisory model-in-loop evidence. A failure does not block the release, but its PASS/FAIL counts and artifact path must be recorded. Do not expect a fixed PASS count. Record actual output. Do not waive a MUST failure without diagnosing and explicitly classifying the failing axis. Do not hide a BEHAVIOR failure. **Freeze HEAD, index, and working tree while the gate is running.** `check-gate-qualification` pins the origin HEAD and aborts if that moves, but the other sequential P5 steps consume the candidate checkout directly. A working-tree or index edit can therefore make one release-gate verdict describe multiple candidates even when qualification's own snapshot stays pure. Queue every edit and commit request (including one from GLG) until the gate reports its verdict; any movement voids that P5 receipt. **When the gate reports its verdict, run P9 before doing anything else.** This is the heaviest resource event in the whole release (the full floor, `check-gate-qualification` and every LIVE smoke on one host), and it is where residue is BOTH largest and freshest, so the prefix a leak carries still names the gate that produced it. Do it here, not only at P8: by P8 the trail is cold. Report the P9 numbers together with the gate's own verdict; a large residue at this point is a finding about a gate, not housekeeping. ## P6. Apply release-specific pre-commit acceptance `NEXT.md` and `VERIFY.md` may require gates beyond `pnpm run check:full` and the LIVE release gate. Apply every requirement that belongs before the release-prep commit. For #51-style repair releases, do not create the final candidate here. The exact candidate must be created from the clean prepared HEAD only after that exact SHA has been pushed and all FOUR required CI jobs are green. `make` owns that post-CI acceptance. A checkout pack-once result is not release-artifact evidence. Never claim an unrun gate as passed. ## P7. Create the release-prep commit Stage only release-prep files. Never pull preceding implementation changes into this commit. ```bash git status --short git diff --check git diff --cached --check git commit -m "chore(release): prepare v${VERSION}" ``` Do not bypass hooks. A commit request does not authorize a push. ## P8. Final preparation check ```bash test "$(node -p "require('./package.json').version")" = "$VERSION" grep -qE "^## ${VERSION}([[:space:]]|$)" CHANGELOG.md git diff-index --quiet HEAD -- ``` Report: - prepared version and commit SHA - `pnpm run check:full` result - release-gate scratch, log, and artifact paths - actual `MUST: PASS=n FAIL=0 SKIP=n` (includes the `check-gate-qualification` MUST step) - actual `BEHAVIOR: PASS=n FAIL=n` - release-specific work deliberately deferred to `make` - clean-tree result - host residue before and after P9, by prefix ## P9. Reclaim the host Run this **twice**: once the moment P5's release gate reports its verdict (freshest trail, largest residue), and again here at the end of `prepare`. `publish` calls it a third time after U3. It is the same procedure each time. The floor and the LIVE gates are the heaviest resource consumers this repo has, and what they leave behind is invisible until a disk fills. Measure it on the host that just ran them, and reclaim only what nothing is using. A gate that ends RED ends by THROWING, so any teardown written as its last statement is skipped. That is how `oracle` reached ~9,200 stale roots and 3.8G under `/tmp` before 2026-09-08. Gates now register their roots with `scripts/lib/reclaim-on-exit.ts`, so this step should find LITTLE. A large number here is not routine housekeeping: it names a gate that still reclaims on its last line, or a fixture child with no parent-death watchdog. Report the prefix, do not just delete it. **Census prefix-blind; delete by a prefix this repo can prove it owns.** The first version of this step looked only at `entwurf-*` and reported a clean host while 5,329 roots sat under `psa-*`, `acp-*` and `omp-*`: a census that only counts what it already suspects will always confirm the fix it was written for. So the report below counts every directory this operator owns under `/tmp`, while the DELETE list is derived from the gates' own `mkdtempSync` prefixes at run time. A hand-kept name list would rot on the next gate; a prefix-blind `rm` would take `nix-shell`, editor and toolchain state that is not ours. Report (read-only, prefix-blind, and never counts a root some live process is using): ```bash mapfile -t IN_USE < <({ ps -eo args --no-headers | grep -oE '/tmp/[A-Za-z0-9._-]+'; for l in /proc/[0-9]*/cwd; do readlink "$l" 2>/dev/null; done; } | sed -E 's#(/tmp/[^/]+).*#\1#' | sort -u)
Ver en GitHub
Este SKILL.md es muy grande, por eso SkillsMP muestra aqui solo la primera seccion. Ver en GitHub