dos-replan-loop
The dos-replan-loop skill executes the /dos-replan planning task repeatedly on a fixed schedule for a bounded number of iterations, then halts. It wraps /dos-replan with an optional auto-commit and release mechanism that safely guards against off-trunk commits by reading the repository's actual trunk branch from git configuration rather than assuming a hardcoded branch name, making it suitable for unattended recurring planning sweeps across workspaces with different default branches.
git clone --depth 1 https://github.com/anthony-chaudhary/dos-kernel /tmp/dos-replan-loop && cp -r /tmp/dos-replan-loop/src/dos/skills/dos-replan-loop ~/.claude/skills/dos-replan-loopSKILL.md
# dos-replan-loop — the generic recurring planning sweep
> **The thin loop.** It is mostly sequencing: run `/dos-replan`, run an
> optional auto-commit/release contract, increment a counter, schedule the next
> wakeup, and stop at the iteration cap. The one thing it must get right
> generically is the **release guard** — it reads the workspace's trunk from
> config, not a hardcoded branch name. (This repo's trunk is `master`, not
> `main` — exactly the kind of host fact the guard must read, not assume.)
## Inputs
- `--interval <seconds>` (optional, default 600 — 10 minutes).
- `--max-iterations <N>` (optional, default 20).
## Step 1 — First entry
Set the iteration counter to 1. Record the pre-existing dirty state of the tree
(so the auto-commit guard can tell what *this* sweep changed). Invoke the
`/dos-replan` Skill.
## Step 2 — After `/dos-replan` finishes: the guarded release contract
If `/dos-replan` made garden-only writes, optionally commit + release them — but
only behind the guard. **The guard reads the trunk from config, not a literal:**
```bash
dos doctor --workspace . --json
```
There is no `trunk` field in the doctor report today (it is a host fact); resolve
it the generic way: `git symbolic-ref --short refs/remotes/origin/HEAD` (the
remote's default branch). **Fail closed:** if that cannot be resolved (no
`origin/HEAD` — common in fresh clones / CI checkouts), treat the trunk as
**UNKNOWN** and **skip the release entirely** (record the sweep only). Do NOT fall
back to "the current branch" — that would make the on-trunk check below trivially
true on any branch and let an auto-commit proceed off-trunk. Then the guard fires
only when ALL hold:
- **the trunk is positively known** (resolved above, not UNKNOWN), AND **HEAD is
on it** (the resolved default branch — `master` here, `main` elsewhere;
**never hardcode either**).
- the working-tree changes are docs/state-only (the replan queue + cooldown
state, nothing in code).
- there is something to commit (a productive sweep).
If the guard passes, commit the garden writes with a generic subject and (if the
host wants it) call `/release`. If any condition fails — including an UNKNOWN
trunk — skip the release and just record the sweep — do not push code, do not
commit off-trunk.
Increment the counter; if it is below `--max-iterations`, schedule the next
wakeup `--interval` seconds out; else stop.
## Step 3 — On wakeup re-entry
Parse the counter from the prior iteration, run `/dos-replan`, and re-run Step 2
again. Stop when the counter reaches `--max-iterations`.
## The outer ratchet for this loop (docs/351)
This loop's "am I producing a witnessed net gain, or just spinning?" ratchet
already exists as the kernel's **`REPLAN_STALLED`** stop (`loop_decide` / docs/258,
#506): K consecutive UNPRODUCTIVE `/dos-replan` sweeps — replans that refilled or
gardened *nothing* — stop the loop and surface, because a sweep that did costly
nothing twice will not on a third identical pass. That IS the docs/351 outer ratchet
for a planning loop: its net gain is gardening/refill (a different metric than the
dispatch loop's reconcile-VERIFIED ship-count), so it does NOT fold under the
`improve` keep-gate — `REPLAN_STALLED` is its shaped equivalent. Same doctrine
across the loop roster: a loop that is running but not *improving* stops and hands
the judgment back, rather than burning the cap (the dispatch loop names this
`not-ratcheting`; this loop names it `REPLAN_STALLED`).
## What this skill deliberately does NOT do (no silent gap)
- **No hardcoded trunk.** It resolves the default branch from git, so a `master`
trunk and a `main` trunk are both handled — the SKP Phase 4 litmus.
- **No host release ceremony.** The generic loop commits garden writes and
optionally calls `/release`; it does not build artifacts or run a host's
bespoke promotion gate (those are host/dev tooling, outside this loop).
## Worked example (live transcript)
> **One replan cycle.** The loop re-runs `dos verify` over the portfolio each
> cadence, then lets `dos gate` decide DRAIN-vs-continue by **exit code** — the
> typed verdict, never the prose. Read the **rung** (`source`) and the **code**,
> not the headline.
```bash
$ dos doctor --workspace . --json | python -c "import sys,json;d=json.load(sys.stdin);print(d['paths']['plans_glob'])"
docs/**/*-plan.md
```
The WCR on-ramp: the portfolio is whatever matches `plans_glob` — host fact, read from config, not assumed.
```bash
$ dos verify --workspace . docs/82_liveness-oracle-plan liveness --json
{"phase":"liveness","plan":"docs/82_liveness-oracle-plan","rung":"direct","sha":"80d4f30","shipped":true,"source":"grep-subject","summary":"80d4f30 liveness: exclude the BIRTH acquire from the ADVANCING event count"}
```
SHIPPED via the **grep-subject** rung (exit 0) — a commit SUBJECT carrying the phase token flips it green; read the rung, not the bare verdict.
```bash
$ dos verify --workspace . docs/99_runtime-validation-and-the-actuation-boundary halt --json
{"phase":"halt","plan":"docs/99_runtime-validation-and-the-actuation-boundary","shipped":false,"source":"none"}
```
NOT_SHIPPED via the **none** rung (exit 1) — git ancestry has not stamped it; this phase is still in flight.
```bash
$ dos gate dispositions.json ; echo "exit=$?"
exit=3
```
`dos gate` returns the typed exit code: **3 = DRAIN** (LIVE=0, DRAIN=3, STALE-STAMP=4, BLOCKED=5, RACE=6). Exit 3 means stop taking new work and let the in-flight phases settle this cycle — continue (LIVE=0) otherwise.
```bash
$ dos arbitrate --workspace . --lane src
{"auto_picked":true,"free_clusters":[],"lane":"benchmark","lane_kind":"cluster","outcome":"acquire","pick_count":null,"reason":"auto-picked free cluster lane benchmark (requested src was refused: lane src would edit the orchestrator's own running code … (SELF_MODIFY) …).","tree":["benchmark/**"]}
```
You asked for `src`; the arbiter handed back `benchmark` (exit 0, `outcome:acquire`) — the admission conAdjudicate 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.
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`.