release
The release skill automates versioning and publication of the DOS kernel by bumping the semantic version in `pyproject.toml`, generating release notes, committing and tagging with `vX.Y.Z`, pushing to the master branch, and creating a GitHub release. The tag push triggers the gated PyPI publish pipeline (`publish.yml`), which builds platform-specific wheels and source distributions and surfaces the workflow run and its approval gate. Use this skill when cutting a new DOS kernel version for public release.
git clone --depth 1 https://github.com/anthony-chaudhary/dos-kernel /tmp/release && cp -r /tmp/release/.claude/skills/release ~/.claude/skills/releaseSKILL.md
# Release — the DOS kernel
Semver: `major.minor.patch`. Patch = bug fix, minor = new feature, major = breaking.
> **DOS is a substrate, not an app.** This skill is the DOS-context adaptation of
> the `job` release skill. It is deliberately *thinner*: DOS single-sources its
> version from `pyproject.toml` (one marker, not four), ships **no** release-asset
> zip archive, screenshots, versioned-install snapshot, plan-state regeneration,
> apply-loop gate, or fanout/dispatch manifest. The dist artifacts — one wheel per
> OS/arch, each embedding its native `dos-hook` fast-path binary at `dos/_bin/`
> (docs/286), plus a pure-source sdist — are built by CI (`publish.yml` via
> `scripts/build_wheels.py`), **never by this skill locally**. The verification
> step is the kernel test suite + the truth syscall, not an apply pipeline. If you
> find yourself reaching for any of those job-only ceremonies, you're in the wrong
> repo's skill.
>
> **One exception — the plugin's native hook binaries.** The Claude Code plugin
> (`claude-plugin/`) bundles the compiled `dos-hook` fast-path binaries (docs/125
> GHF4), committed into `claude-plugin/bin/` so a marketplace install (a git clone)
> is a direct install. They are NOT a release asset and NOT in the wheel — they live
> in the git tree. Step 5.5 rebuilds them so a release never ships a stale binary
> against changed Go source.
**Trunk is `master`** (there is no `main` branch in DOS). Every `git push` in
this skill targets `master`. Master-direct is the deliberate branching model for
now (a trunk+lane-branch PR cutover is planned, evidence-triggered — not a `dev`
branch); this skill assumes it.
**This repo is PUBLIC and the tag is a publish trigger (the 2026-06-10 cutover).**
Three consequences every release run must respect:
1. **A push IS publication.** `origin` is the public `anthony-chaudhary/dos-kernel`.
The machine-local pre-push hook (`.git/hooks/pre-push`) runs the leak scanner
(`scripts/leak_scan.py`, a *gitignored* sync of the canonical
`../dos-private/tools/leak_scan.py`) and is **fail-closed**: a hit — or a
missing scanner — refuses the push. On a refusal: scrub and amend, never
`--no-verify` ("a leak is a refusal, not a warning"). Details in the runbook's
**Public-repo push gates** section.
2. **Pushing the `vX.Y.Z` tag starts the PyPI publish pipeline.** `publish.yml`
fires on every `v*` tag: it builds the per-platform wheels + sdist, asserts
tag == `pyproject.toml` version, refuses to upload any SHA without a green
`ci.yml` run on it (the **ci-green witness gate** — it polls while CI
finishes), then pauses at the protected `pypi` environment for the operator's
approval before the OIDC Trusted-Publishing upload. So Step 6's tag push is
also the publish request, and Step 7.4 is "surface/approve the pipeline,"
not "run twine."
3. **Release notes are public documents.** `docs/releases/vX.Y.Z.md` ships to the
world (and into the GH release body). No dev-machine absolute paths, hostnames,
or personal identifiers; private-SUBJECT prose (operator process, fleet audits,
launch mechanics) is born in `dos-private`, never here — the `CLAUDE.md`
route-privacy-at-authoring-time rule, applied to the notes you draft in Step 3.
## Cadence — two channels, one rule
- **Rolling `vX.Y.Z` (this skill): ship whenever the gates are green.** A
coherent, user-visible unit of work + a green suite is enough to cut a tag —
several per week is healthy, not churn. The cost is low by design: every hard
gate is mechanical and already wired (pre-push leak scan, `ci.yml` on the push,
the publish ci-green witness, one human approval click for PyPI). Don't batch
work waiting for a "big enough" release — the oracle reads git, and unshipped
work is `NOT_SHIPPED`.
- **Stable `stable/<codename>` (`/stable-release`): promote deliberately.** The
infrequent counterweight — a promotion of an already-soaked rolling tag (green
suite + green third-party CI + clean truth syscall + soak window), producing
the evidence file + the tag consumers pin in production
(`pip install dos-kernel==<underlying>`). Rolling moves fast *because* stable
exists; stable can afford its soak window *because* rolling carries the urgency.
- **Semver carries the compatibility promise; the channel carries the trust
promise.** Major = breaking ABI (verdict vocabulary, syscall signature,
`SubstrateConfig` shape). A major bump deserves a stable promotion soon after
it soaks, so consumers get a provably-good anchor on the new ABI.
**Git authorization.** Invoking this skill is the user's explicit authorization
to run `git add`, `git commit`, `git tag`, and `git push origin master`/`vX.Y.Z`
as specified in Steps 5–6. The "never commit/push unless asked" default does NOT
apply here — committing and pushing IS the skill's job, and stopping mid-flow to
re-confirm each git mutation is the wrong behavior. Confirmation is still
required for anything destructive the steps don't list (force-push, history
rewrites, branch deletion, `git reset --hard`).
**The kernel-vs-tooling boundary.** The release scripts (`scripts/release_*.py`)
and this skill are **dev/release tooling that operates ON the package** — they
are never imported BY `dos.*`. Editing them never touches the kernel's import
graph, so the "kernel imports no host, no `scripts/`" litmus in `CLAUDE.md`
stays intact. Keep release logic here, not in `src/dos/`.
**Fast path** (most releases): Steps 1–7.5 below. Edge cases (racing agents,
version drift, release-notes nuance) live in [`release-runbook.md`](release-runbook.md)
— load it only when a step tells you to.
**This skill is the deliberate act; the always-on nudge is the reminder.** A
second, advisory `Stop` hook (`scripts/git_hygiene.py`, wired in
`.claude/settings.json`) runs at every stopping point and prints a one-line
*"N uncommitted files on master, K commits not pushed — commit the lane or run
/release"* whenever the treeAdjudicate a GitHub issue's "this is resolved" claim from witnesses the claimant didn't author — then close it carrying the evidence, or refuse with the typed gap. Use when an issue looks already-solved, after landing a fix that should have closed one, or to sweep open issues for silently-resolved ones.
Pick the next most important open GitHub issue this agent can actually complete, make its done-condition true, land it with witnesses (suite + parity + commit-audit), and priority-tag every issue touched along the way. Use when asked to "work the backlog", "complete the next most important issue", or to fix a specific issue number end-to-end.
Promote an already-shipped rolling release (vX.Y.Z) of the DOS kernel to a named stable channel — gated on a green kernel suite + a green third-party CI run on the candidate + a clean truth syscall + a soak window. Writes an evidence file and adds a stable/<codename> git tag on the same commit. Does NOT bump versions or build new artifacts.
One automatic plan-class lifecycle tick. Reads the DECLARED class set + transition list from the workspace `[lifecycle]` table (not a hardcoded taxonomy), evaluates each trigger, spawns a read-only JUDGE-rung adjudicator (the `dos.judges` seam — advisory, fail-to-abstain) to approve/defer each candidate transition, applies the gated transitions as plan-meta edits + one commit per cycle, and logs to the run archive. Failsafes (per-cycle cap, per-plan cooldown, a veto class) are `[lifecycle]` data; the judge content is a host `dos.judges` driver. Every path/class comes from `dos doctor --json`. Use to garden a plan portfolio's lifecycle automatically, judge-gated. The DOS lifecycle gardener (SKP Axis 5, docs/207 Phase 5c).
Run /dos-dispatch on a recurring cadence, alternating with /dos-replan when the backlog drains — the dispatch→replan→dispatch cycle. The continue/stop/next-mode decision is the kernel's typed loop decision, not inline prose: each iteration is classified (`dos gate`) into a verdict and the loop's counters (drained-twice, the unclear/dirty-zero breakers, the iteration cap) drive the next step. Several loops on disjoint lanes run concurrently, each taking its own lane lease via `dos arbitrate`. Driven entirely by `dos` verbs + the workspace's `dos.toml`. The DOS reference loop workflow (SKP Axis 5).
End-to-end plan-and-ship for one lane — snapshot the portfolio with /dos-next-up, take a lane lease via `dos arbitrate` so parallel dispatches don't collide, gate the empty case via `dos gate`, ship the packet, and archive the run under the configured run dir. Driven entirely by `dos` verbs + the workspace's `dos.toml`; names no host path, lane, or commit convention. Use when you want to plan and ship the next batch on one lane in a single command, with concurrency safety. The DOS reference dispatch workflow (SKP Axis 5).
Ground a "keep working until the goal is met" stop condition in a witness the agent did not author, instead of letting the agent self-certify "done". A harness goal/Stop-hook condition is normally checked by the model re-reading its OWN work — consistency, not grounding. This skill turns the operator's goal into checkable EFFECT claims and wires `dos hook stop` so the Stop is refused until git ancestry (a shipped phase) or an effect read-back corroborates the claimed effect. Driven by `dos` verbs and the workspace's own `dos.toml` — no host-specific paths, lanes, or commit conventions. Use when you want a self-stopping agent (or a `/loop` worker) to be unable to declare a goal complete on its own say-so. The single-agent self-stop analogue of `dos-witness-claim`.
Snapshot a repo's phased-plan portfolio and produce a parallel-agent dispatch packet, driven entirely by `dos` verbs and the workspace's own `dos.toml` — no host-specific paths, lanes, or commit conventions. Walks the configured plans glob, audits each candidate pick against `dos verify` for its true shipped/unshipped status, renders a self-contained packet to the configured output dir, and reports a typed gate verdict via `dos gate`. Use when you want a "where are we / what's next / who-does-what" snapshot of any repo that has a few plan docs and real commits. This is the DOS reference workflow (SKP Axis 5); a host may use it, fork it, or ignore it.