dos-class-cycle
dos-class-cycle automates portfolio lifecycle management by evaluating declared transition triggers, consulting a read-only JUDGE-rung adjudicator for approval, and applying gated transitions to plan metadata with per-cycle and per-plan safeguards. Use it to keep plan classes synchronized with actual status (active, done, parked, etc.) without manual intervention, with all rules sourced from workspace configuration rather than hardcoded logic.
git clone --depth 1 https://github.com/anthony-chaudhary/dos-kernel /tmp/dos-class-cycle && cp -r /tmp/dos-class-cycle/src/dos/skills/dos-class-cycle ~/.claude/skills/dos-class-cycleSKILL.md
# dos-class-cycle — the judge-gated plan-lifecycle tick
> **Garden the portfolio, but never alone.** A plan's class (active / done /
> parked / …) should track reality — a done plan should not sit "active," a
> long-idle one should park. `/dos-class-cycle` runs ONE tick of that gardening:
> it evaluates the declared triggers, asks a **JUDGE-rung adjudicator** (advisory,
> fail-to-abstain) to approve each candidate transition, applies only the gated
> ones, and logs the cycle. The class set, the legal transitions, and the
> failsafes are **declared data** (`[lifecycle]`) — a 2-class repo and a richly-
> classed one run the identical mechanism.
The shape: **read the declared lifecycle → evaluate triggers → build candidates
(deterministic order) → judge each → enact gated transitions → log.** The cycle
is domain-free mechanism; the taxonomy is `[lifecycle]` policy; the judge content
is a host `dos.judges` driver.
## Inputs
- `--dry-run` (optional) — evaluate + judge but enact nothing (a preview cycle).
## Step 0 — Read the declared lifecycle + the layout
```bash
dos doctor --workspace . --json
```
Read `lifecycle` — the declared `classes`, `transitions` (each `{from, to,
trigger, auto}`), `veto_class`, `max_transitions_per_cycle`, and
`per_plan_cooldown_hours` — and `paths` (the plan + run dirs). **Use these; never
hardcode a class name, a trigger, or a cap.** A repo that declared only
`active`/`done` cycles with those two; a repo with a richer taxonomy declares more.
## Step 1 — Evaluate each declared trigger → candidate transitions
For each declared `transition`, evaluate its `trigger` against the portfolio (the
plan-meta classes, the run-archive history, git). A trigger that fires on a plan
proposes that plan for that `from→to` transition. Build the candidate list in a
DETERMINISTIC order (plan id ascending) so a replay is byte-stable.
Skip a plan that is:
- in the `veto_class` (never auto-transitioned — a human moves it by hand), or
- transitioned within `per_plan_cooldown_hours` (the per-plan cooldown), or
- already past `max_transitions_per_cycle` candidates this tick (the cap).
The trigger evaluator is the host's (an opaque trigger token like
`all_phases_shipped` / `idle_30d` — the kernel never interprets it). A natural
ground-truth trigger: a plan whose `dos enumerate` residual is empty AND every
unit `dos verify`s SHIPPED is a real `all_phases_shipped` → done candidate.
## Step 2 — Judge each candidate (the JUDGE rung, advisory)
A class transition is a judgment call, so it goes to the **JUDGE rung** — a
non-deterministic adjudicator that rules on the residue the deterministic checks
left. Resolve the active judge by name and ask it to approve / defer each
candidate:
```bash
dos judge-eval --judge <name> # the judge seam; built-in `abstain`, shipped `llm`, or a dos.judges plugin
```
The judge is hedged by the four disciplines (deterministic-first, advisory-only,
**fail-to-abstain** — a raise/bad-return becomes ABSTAIN, never APPROVE —
abstention-first). The judge *content* (the prompt) is a host `dos.judges` driver;
this skill spawns it via the seam and reads its verdict. An ABSTAIN defers the
transition to a human (the safe direction — the kernel never auto-applies on an
abstention).
## Step 3 — Enact the gated transitions (auto only where declared)
For each candidate the judge APPROVED **and** whose declared transition has
`auto = true`, enact it: rewrite the plan-meta `classification:` to the `to`
class, ONE commit per cycle. Read the trunk + ship grammar from `dos doctor
--json`'s `stamp`; **do not hardcode a commit prefix.** A transition with
`auto = false`, or one the judge deferred/abstained on, is surfaced for a human —
never enacted.
## Step 4 — Log the cycle (even a 0-transition tick)
Write a cycle record under `paths.runs`: the candidates, the judge verdicts, the
applied transitions, and the failsafe state (cap/cooldown/veto). A heartbeat row
every cycle — even one that applied nothing — so the gardener's history is
auditable.
## What this skill deliberately does NOT do (no silent gap)
- **No host class taxonomy.** Classes/transitions/failsafes are `[lifecycle]`
data; this skill carries none. A transition naming an unknown class is a config
error the kernel raises at load, not a silent skip.
- **No judge content.** The adjudicator prompt is a host `dos.judges` driver; the
skill resolves + spawns it, fail-to-abstain. Forcing the prompt generic would
re-couple the kernel.
- **No transition past a failsafe.** The per-cycle cap, the per-plan cooldown, and
the veto class are hard gates; the cycle never exceeds them.
## Anti-patterns
- ❌ Applying a transition the judge ABSTAINED on — abstention defers to a human;
the kernel never auto-applies on an abstention (the fail-to-abstain floor).
- ❌ Hardcoding `ACTIVE`/`PARK`/`TOMB` or a trigger like `idle_14d` — read the
declared set from `dos doctor --json`'s `lifecycle`.
- ❌ Exceeding `max_transitions_per_cycle` in one tick — a runaway judge must not
churn the whole portfolio; the cap is the backstop.Adjudicate 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.
Cut a versioned release of the DOS kernel — bump the version, draft release notes, commit, tag, push to master, and create a GitHub release. The tag push triggers the gated PyPI publish pipeline (publish.yml); the skill surfaces the run and its approval gate.
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.
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.