Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Run /dos-replan on a fixed cadence for a bounded number of iterations, then stop — an unattended planning-refresh sweep. A thin recurring wrapper over /dos-replan plus an optional guarded release; the release guard reads the workspace's trunk from config rather than assuming a branch name. Driven by `dos` verbs + the workspace's `dos.toml`. The DOS reference planning-loop workflow (SKP Axis 5).
.claude/skills/bilal140202-dos-replan-loop/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-14 | ✗→✓ | ▲ Improved | 18% | 0% |
| case-15 | ✗→✓ | ▲ Improved | 52% | 0% |
| case-04 | ✗→✓ | ▲ Improved | 6% | 0% |
| case-06 | ✗→✓ | ▲ Improved | 13% | 0% |
| case-08 | ✗→✓ | ▲ Improved | -13% | 0% |
> 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.)
--interval <seconds> (optional, default 600 — 10 minutes).--max-iterations <N> (optional, default 20).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.
/dos-replan finishes: the guarded release contractIf /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:
bashdos 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:
on it (the resolved default branch — master here, main elsewhere; never hardcode either).
state, nothing in code).
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.
Parse the counter from the prior iteration, run /dos-replan, and re-run Step 2 again. Stop when the counter reaches --max-iterations.
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).
mastertrunk and a main trunk are both handled — the SKP Phase 4 litmus.
optionally calls /release; it does not build artifacts or run a host's bespoke promotion gate (those are host/dev tooling, outside this loop).
> 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 conjunction refused the hint (here SELF_MODIFY; a lane contended by a live lease redirects the same way) and the kernel named the real reason rather than double-book or false-narrate. A free, admissible lane you name is granted directly.
main — resolve it; this repo's is master.on-trunk only.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-14 | fail→pass | 12,712 | 5,403 | -57% | 1 | 1 | 0% | 2,277 | 2,692 | +18% | 0 | 0 | — |
case-15 | fail→pass | 10,759 | 4,682 | -56% | 1 | 1 | 0% | 1,696 | 2,583 | +52% | 0 | 0 | — |
case-16 | pass→pass | 10,253 | 4,337 | -58% | 1 | 1 | 0% | 1,727 | 2,488 | +44% | 0 | 0 | — |
case-01 | fail→fail | 10,967 | 2,974 | -73% | 1 | 1 | 0% | 2,213 | 2,170 | -2% | 0 | 0 | — |
case-02 | fail→fail | 7,571 | 4,820 | -36% | 1 | 1 | 0% | 285 | 2,177 | +664% | 0 | 0 | — |
case-03 | fail→fail | 22,939 | 18,985 | -17% | 1 | 1 | 0% | 1,242 | 2,122 | +71% | 0 | 0 | — |
case-04 | fail→pass | 11,872 | 2,637 | -78% | 1 | 1 | 0% | 2,108 | 2,226 | +6% | 0 | 0 | — |
case-05 | pass→pass | 10,115 | 2,766 | -73% | 1 | 1 | 0% | 1,813 | 2,220 | +22% | 0 | 0 | — |
case-06 | fail→pass | 12,323 | 2,714 | -78% | 1 | 1 | 0% | 1,915 | 2,172 | +13% | 0 | 0 | — |
case-07 | pass→pass | 14,682 | 10,859 | -26% | 1 | 1 | 0% | 976 | 2,162 | +122% | 0 | 0 | — |
case-08 | fail→pass | 13,765 | 2,219 | -84% | 1 | 1 | 0% | 2,512 | 2,173 | -13% | 0 | 0 | — |
case-09 | pass→pass | 11,373 | 2,658 | -77% | 1 | 1 | 0% | 1,757 | 2,285 | +30% | 0 | 0 | — |
case-10 | fail→pass | 9,648 | 1,940 | -80% | 1 | 1 | 0% | 1,512 | 2,156 | +43% | 0 | 0 | — |
case-11 | fail→fail | 10,317 | 9,231 | -11% | 1 | 1 | 0% | 1,980 | 3,422 | +73% | 0 | 0 | — |
case-12 | fail→pass | 13,746 | 6,381 | -54% | 1 | 1 | 0% | 2,257 | 2,856 | +27% | 0 | 0 | — |
case-13 | pass→pass | 9,517 | 3,138 | -67% | 1 | 1 | 0% | 1,487 | 2,371 | +59% | 0 | 0 | — |
case-17 | fail→pass | 8,823 | 1,850 | -79% | 1 | 1 | 0% | 1,444 | 2,101 | +45% | 0 | 0 | — |
case-18 | fail→pass | 11,967 | 2,048 | -83% | 1 | 1 | 0% | 1,954 | 2,112 | +8% | 0 | 0 | — |
case-19 | fail→pass | 11,888 | 1,808 | -85% | 1 | 1 | 0% | 1,998 | 2,050 | +3% | 0 | 0 | — |
case-20 | fail→pass | 10,699 | 4,641 | -57% | 1 | 1 | 0% | 2,024 | 2,621 | +29% | 0 | 0 | — |
case-21 | pass→pass | 11,190 | 3,010 | -73% | 1 | 1 | 0% | 1,743 | 2,405 | +38% | 0 | 0 | — |
case-22 | fail→fail | 16,706 | 1,477 | -91% | 1 | 1 | 0% | 2,874 | 2,059 | -28% | 0 | 0 | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 20 counted toward the lift figure. The other 2 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +50 percentage points is the difference between those two pass rates over the 20 comparable cases.
Without the skill loaded, the model failed this case. With it loaded, the same prompt on the same model passed. This is one improved case from the latest verified run; every case, including any that regressed, is in the table above.
Other measured skills in the registry, with their headline benchmark lift.