dos-kernel 0.22.0__py3-none-win_amd64.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- dos/__init__.py +261 -0
- dos/_bin/dos-hook.exe +0 -0
- dos/_filelock.py +255 -0
- dos/_job_policy.py +97 -0
- dos/_tree.py +145 -0
- dos/admission.py +433 -0
- dos/answer_shape.py +299 -0
- dos/arbiter.py +859 -0
- dos/archive_lock.py +266 -0
- dos/arg_provenance.py +814 -0
- dos/attest.py +472 -0
- dos/breaker.py +311 -0
- dos/churn.py +226 -0
- dos/claim_extract.py +229 -0
- dos/claim_ttl.py +150 -0
- dos/cli.py +8721 -0
- dos/commit_audit.py +666 -0
- dos/completion.py +466 -0
- dos/concurrency_class.py +154 -0
- dos/config.py +1380 -0
- dos/config_lint.py +464 -0
- dos/cooldown.py +390 -0
- dos/coverage.py +387 -0
- dos/dangling_intent.py +287 -0
- dos/data_class.py +397 -0
- dos/decisions.py +1274 -0
- dos/decisions_tui.py +251 -0
- dos/dispatch_top.py +740 -0
- dos/dispatch_top_tui.py +116 -0
- dos/drivers/__init__.py +40 -0
- dos/drivers/ci_status.py +630 -0
- dos/drivers/citation_resolve.py +703 -0
- dos/drivers/decision_stop.py +98 -0
- dos/drivers/export_file.py +173 -0
- dos/drivers/export_otlp.py +275 -0
- dos/drivers/export_statsd.py +242 -0
- dos/drivers/hook_dialects.py +391 -0
- dos/drivers/job.py +47 -0
- dos/drivers/llm_judge.py +360 -0
- dos/drivers/memory_recall.py +1231 -0
- dos/drivers/notify_slack.py +373 -0
- dos/drivers/notify_webhook.py +251 -0
- dos/drivers/operator_judge.py +114 -0
- dos/drivers/os_acceptance.py +228 -0
- dos/drivers/paste_log.py +132 -0
- dos/drivers/plan_scope.py +133 -0
- dos/drivers/self_improve.py +375 -0
- dos/drivers/similarity_judge.py +249 -0
- dos/drivers/state_diff.py +274 -0
- dos/drivers/supervisor.py +347 -0
- dos/drivers/watchdog.py +363 -0
- dos/drivers/workshop.py +160 -0
- dos/durable_schema.py +344 -0
- dos/effect_witness.py +393 -0
- dos/efficiency.py +318 -0
- dos/enforce.py +414 -0
- dos/enumerate.py +776 -0
- dos/env_print.py +378 -0
- dos/event_severity.py +258 -0
- dos/evidence.py +692 -0
- dos/exec_capability.py +256 -0
- dos/export_cursor.py +143 -0
- dos/exporter.py +320 -0
- dos/firing_label.py +353 -0
- dos/fleet_roll.py +226 -0
- dos/gate_classify.py +827 -0
- dos/gh4_coverage.py +179 -0
- dos/git_delta.py +122 -0
- dos/guard.py +215 -0
- dos/health.py +552 -0
- dos/help_summary.py +519 -0
- dos/home.py +934 -0
- dos/hook_binary.py +194 -0
- dos/hook_dialect.py +271 -0
- dos/hook_exit.py +191 -0
- dos/hook_install.py +437 -0
- dos/id_alloc.py +304 -0
- dos/improve.py +499 -0
- dos/intent_ledger.py +635 -0
- dos/interpret.py +176 -0
- dos/intervention.py +769 -0
- dos/intervention_eval.py +371 -0
- dos/journal_delta.py +308 -0
- dos/judge_eval.py +328 -0
- dos/judges.py +366 -0
- dos/lane_infer.py +127 -0
- dos/lane_journal.py +1001 -0
- dos/lane_lease.py +952 -0
- dos/lane_overlap.py +228 -0
- dos/lease_health.py +282 -0
- dos/lifecycle.py +211 -0
- dos/liveness.py +352 -0
- dos/lock_modes.py +185 -0
- dos/log_source.py +395 -0
- dos/loop_decide.py +1746 -0
- dos/marker_gate.py +254 -0
- dos/marker_sensor.py +396 -0
- dos/noop_streak.py +280 -0
- dos/notify.py +479 -0
- dos/observe.py +175 -0
- dos/oracle.py +1661 -0
- dos/overlap_eval.py +214 -0
- dos/overlap_policy.py +342 -0
- dos/packet_sidecar.py +267 -0
- dos/phase_shipped.py +1985 -0
- dos/pick_priority.py +225 -0
- dos/pickable.py +369 -0
- dos/picker_oracle.py +1037 -0
- dos/plan_board.py +513 -0
- dos/plan_board_tui.py +113 -0
- dos/plan_source.py +455 -0
- dos/posttool_sensor.py +528 -0
- dos/precursor_gate.py +499 -0
- dos/precursor_gate_eval.py +239 -0
- dos/preflight.py +825 -0
- dos/pretool_sensor.py +490 -0
- dos/proc_delta.py +181 -0
- dos/productivity.py +296 -0
- dos/provider_limit.py +242 -0
- dos/py.typed +4 -0
- dos/reason_morphology.py +299 -0
- dos/reasons.py +449 -0
- dos/reconcile.py +173 -0
- dos/recurring_wedge.py +206 -0
- dos/render.py +393 -0
- dos/result_state.py +468 -0
- dos/resume.py +578 -0
- dos/resume_evidence.py +293 -0
- dos/retention.py +344 -0
- dos/reward.py +372 -0
- dos/rewind.py +587 -0
- dos/rewind_evidence.py +168 -0
- dos/rewind_tokens.py +252 -0
- dos/run_id.py +342 -0
- dos/scope.py +520 -0
- dos/scope_source.py +382 -0
- dos/scout.py +982 -0
- dos/self_modify.py +209 -0
- dos/sibling_scan.py +569 -0
- dos/skills/EXAMPLES.md +584 -0
- dos/skills/dos-class-cycle/SKILL.md +107 -0
- dos/skills/dos-dispatch/SKILL.md +177 -0
- dos/skills/dos-dispatch-loop/SKILL.md +254 -0
- dos/skills/dos-goal-gate/SKILL.md +269 -0
- dos/skills/dos-next-up/SKILL.md +231 -0
- dos/skills/dos-promote/SKILL.md +114 -0
- dos/skills/dos-replan/SKILL.md +159 -0
- dos/skills/dos-replan-loop/SKILL.md +114 -0
- dos/skills/dos-self-improve/SKILL.md +213 -0
- dos/skills/dos-supervise-loop/SKILL.md +180 -0
- dos/skills/dos-unstick/SKILL.md +108 -0
- dos/skills/dos-witness-claim/SKILL.md +251 -0
- dos/stamp.py +1002 -0
- dos/state_health.py +387 -0
- dos/status.py +114 -0
- dos/stop_policy.py +334 -0
- dos/supervise.py +1014 -0
- dos/testwitness.py +392 -0
- dos/timeline.py +1027 -0
- dos/tokens.py +485 -0
- dos/tool_stream.py +393 -0
- dos/tool_stream_eval.py +226 -0
- dos/trace.py +524 -0
- dos/verdict.py +140 -0
- dos/verdict_cli.py +189 -0
- dos/verdict_journal.py +497 -0
- dos/verdict_rollup.py +217 -0
- dos/verdicts.py +181 -0
- dos/wedge_reason.py +282 -0
- dos_kernel-0.22.0.dist-info/METADATA +859 -0
- dos_kernel-0.22.0.dist-info/RECORD +178 -0
- dos_kernel-0.22.0.dist-info/WHEEL +5 -0
- dos_kernel-0.22.0.dist-info/entry_points.txt +39 -0
- dos_kernel-0.22.0.dist-info/licenses/LICENSE +21 -0
- dos_kernel-0.22.0.dist-info/top_level.txt +2 -0
- dos_mcp/__init__.py +52 -0
- dos_mcp/py.typed +2 -0
- dos_mcp/server.py +779 -0
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dos-replan
|
|
3
|
+
description: Garden a repo's plan portfolio from accumulated evidence — detect closures (a queue item whose phases now `dos verify` as shipped is done), track cooldown state, and surface the 0-2 items the operator must actually decide via the `dos decisions` queue. Read-only on code/data; writes only its queue + cooldown state. Driven by `dos` verbs + the workspace's `dos.toml`; names no host path or convention. Use after a burst of dispatches, when the backlog looks drained, or when recurring findings start hurting throughput. The DOS reference planning-sweep workflow (SKP Axis 5).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dos-replan — the generic portfolio gardening sweep
|
|
7
|
+
|
|
8
|
+
> **The planning refresh that keeps the loop honest.** Its domain-free core is
|
|
9
|
+
> small: a queue item whose phases now `dos verify` as shipped is *closed*; the
|
|
10
|
+
> operator should see only the 0-2 items that truly need a human. The heavy
|
|
11
|
+
> host-specific gardening passes (anchor reconciliation, soak-state drift, the
|
|
12
|
+
> postmortem evidence stream) are host driver hooks, scoped OUT of the generic
|
|
13
|
+
> baseline. Closure detection rides the truth syscall; the operator surface is
|
|
14
|
+
> the `dos decisions` queue.
|
|
15
|
+
|
|
16
|
+
The shape: **read the queue → close what verifies as shipped → rank what's left →
|
|
17
|
+
surface only what needs a human.** Closure is a kernel call (`dos verify`); the
|
|
18
|
+
operator inbox is the kernel's decisions projection.
|
|
19
|
+
|
|
20
|
+
## Inputs
|
|
21
|
+
|
|
22
|
+
- `--force` (optional) — run even if the no-op skip gate would fire (no new
|
|
23
|
+
evidence since the last sweep).
|
|
24
|
+
|
|
25
|
+
## Step 0 — Discover the layout
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
dos doctor --workspace . --json
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
Read `paths` (where the queue/cooldown state live) and `stamp` (the active ship
|
|
32
|
+
grammar `dos verify` applies). Read the active trunk from config if you will
|
|
33
|
+
gate a release later (see `/dos-replan-loop`).
|
|
34
|
+
|
|
35
|
+
## Step 1 — No-op skip gate
|
|
36
|
+
|
|
37
|
+
If there is no new evidence since the last sweep (no new commits, no new findings)
|
|
38
|
+
and `--force` was not given, print one line and exit cheap — writing nothing.
|
|
39
|
+
This is the gate that keeps a recurring loop from doing 0-work sweeps; an
|
|
40
|
+
*unproductive* replan (this skip, or a 0/0/0 sweep) must NOT arm the loop's
|
|
41
|
+
drained-twice trigger (the kernel loop decision enforces that — report the
|
|
42
|
+
productivity honestly so `/dos-dispatch-loop` reads it right).
|
|
43
|
+
|
|
44
|
+
## Step 2 — Closure detection (the domain-free core, via the truth syscall)
|
|
45
|
+
|
|
46
|
+
For each open item in the queue, ask the kernel whether its phases have shipped:
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
dos verify --workspace . <PLAN> <PHASE> --json
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
If every phase of a queue item now reports `shipped: true`, the item is **closed**
|
|
53
|
+
— move it from the open queue to the closed section. **Never trust the plan doc's
|
|
54
|
+
own stamp; the truth syscall is the source.** This is the auto-close pass that
|
|
55
|
+
keeps the queue from carrying already-shipped work as if it were pending.
|
|
56
|
+
|
|
57
|
+
Count the closures — this is part of the productivity signal Step 5 reports.
|
|
58
|
+
|
|
59
|
+
## Step 3 — Cooldown-state tracking
|
|
60
|
+
|
|
61
|
+
Bump the cooldown timestamp in the configured state file so `/dos-next-up` knows
|
|
62
|
+
when this sweep last ran (the cooldown banner). Generic, no host specifics.
|
|
63
|
+
|
|
64
|
+
## Step 4 — Rank what's left
|
|
65
|
+
|
|
66
|
+
Order the remaining open items by a domain-free signal (recency, how many phases
|
|
67
|
+
remain). Do not impose a host's bespoke ranking — that's a driver hook.
|
|
68
|
+
|
|
69
|
+
## Step 5 — Surface only what needs a human (the operator inbox)
|
|
70
|
+
|
|
71
|
+
The ruthless filter: of everything you swept, at most **0-2 items** should reach
|
|
72
|
+
the operator — the ones no mechanism can resolve (a real decision-needed). The
|
|
73
|
+
kernel's operator inbox is the `dos decisions` queue; read it to see what is
|
|
74
|
+
already pending so you don't duplicate a row:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
dos decisions --workspace . --json
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
The `dos decisions` projection is the generic operator inbox: a HUMAN-resolvable
|
|
81
|
+
row is one a mechanism (an ORACLE/JUDGE) cannot close.
|
|
82
|
+
|
|
83
|
+
**Honesty about the write path (a named open seam).** `dos decisions` is
|
|
84
|
+
**read-only** today — there is no generic `dos` verb to *append* a decision-needed
|
|
85
|
+
row (the queue's write path, `home.append_decision`, is currently reached only by
|
|
86
|
+
`dos arbitrate --force`'s override capture). So the generic baseline **surfaces**
|
|
87
|
+
the 0-2 items in its operator summary (Step 6) and reads the existing queue here;
|
|
88
|
+
*emitting a new decision row into the queue is a host/driver capability* (the
|
|
89
|
+
named open seam — see `docs/74-friction-log.md`). Do not imply `dos decisions`
|
|
90
|
+
writes; it lists and drills in.
|
|
91
|
+
|
|
92
|
+
## Step 6 — Emit the operator summary
|
|
93
|
+
|
|
94
|
+
Print a terse summary: how many items closed (Step 2), how many remain, and the
|
|
95
|
+
0-2 that need a decision (with a pointer to `dos decisions`). Report the
|
|
96
|
+
productivity verdict honestly (PRODUCTIVE iff it closed/refilled/gardened
|
|
97
|
+
anything) — `/dos-dispatch-loop` reads this to decide drained-twice.
|
|
98
|
+
|
|
99
|
+
## What this skill deliberately does NOT do (no silent gap)
|
|
100
|
+
|
|
101
|
+
- **No host gardening passes.** Anchor reconciliation, soak-state drift, the
|
|
102
|
+
postmortem evidence stream, gitignore drift — those are host-specific evidence
|
|
103
|
+
surfaces, scoped OUT of the generic baseline (a driver hook, or out of scope).
|
|
104
|
+
The generic sweep does closure detection + the operator surface, and `log`s
|
|
105
|
+
what it is skipping.
|
|
106
|
+
- **No host inbox file.** It writes to the kernel's `dos decisions` queue — the
|
|
107
|
+
generic operator-inbox surface — not a host-specific pending-decisions file.
|
|
108
|
+
|
|
109
|
+
## Worked example (live transcript)
|
|
110
|
+
|
|
111
|
+
> **The stale-stamp catch.** A queue item points at a plan whose phase the doc
|
|
112
|
+
> still narrates as in-flight — but the grep rung sees a commit *subject* carrying
|
|
113
|
+
> the phase token, so `dos verify` flips it SHIPPED. Read the **rung**, not the
|
|
114
|
+
> bare verdict, then reconcile the queue.
|
|
115
|
+
|
|
116
|
+
Step 0 — discover the layout (the on-ramp every sweep runs):
|
|
117
|
+
|
|
118
|
+
```bash
|
|
119
|
+
$ dos doctor --workspace . --json
|
|
120
|
+
... "stamp": {"style": "grep", "grammar": "generic (any/no dir prefix)"} ...
|
|
121
|
+
... "exit_codes": {"gate": {"LIVE": 0, "DRAIN": 3, "STALE-STAMP": 4, "BLOCKED": 5, "RACE": 6}} ...
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
Step 2 — closure detection. Ask the truth syscall, never the plan doc's own stamp:
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
$ dos verify --workspace . docs/82_liveness-oracle-plan liveness --json
|
|
128
|
+
{"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"}
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
Verdict carried by the **`source: grep-subject`** rung — a commit SUBJECT containing
|
|
132
|
+
the phase token flips this to SHIPPED even if little was built. The doc lagging the
|
|
133
|
+
git fact IS the stale stamp; close the item from this rung, not from the doc.
|
|
134
|
+
|
|
135
|
+
Contrast — an item still genuinely in flight returns the **`none`** rung:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
$ dos verify --workspace . docs/99_runtime-validation-and-the-actuation-boundary halt --json
|
|
139
|
+
{"phase":"halt","plan":"docs/99_runtime-validation-and-the-actuation-boundary","shipped":false,"source":"none"}
|
|
140
|
+
```
|
|
141
|
+
|
|
142
|
+
Step 6 reconcile — feed the dispositions to the gate; a stale stamp returns exit 4:
|
|
143
|
+
|
|
144
|
+
```bash
|
|
145
|
+
$ dos gate ./dispositions.json ; echo "exit=$?"
|
|
146
|
+
exit=4
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
`gate` exit **4 = STALE-STAMP** — the plan doc lags the verified git fact; the
|
|
150
|
+
replan's reconciliation is to close the over-claimed item against the `grep-subject`
|
|
151
|
+
rung and drop the doc's self-narrated status. (Exit 0 = LIVE, 3 = DRAIN, 5 = BLOCKED.)
|
|
152
|
+
|
|
153
|
+
## Anti-patterns
|
|
154
|
+
|
|
155
|
+
- ❌ Closing an item from its plan-doc stamp — close from `dos verify` only.
|
|
156
|
+
- ❌ Surfacing more than 0-2 items — the operator surface is ruthless by design;
|
|
157
|
+
everything a mechanism can resolve stays out of it.
|
|
158
|
+
- ❌ Reporting an unproductive sweep as productive — it would arm a false
|
|
159
|
+
drained-twice stop in the loop. Report honestly.
|
|
@@ -0,0 +1,114 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dos-replan-loop
|
|
3
|
+
description: 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).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dos-replan-loop — the generic recurring planning sweep
|
|
7
|
+
|
|
8
|
+
> **The thin loop.** It is mostly sequencing: run `/dos-replan`, run an
|
|
9
|
+
> optional auto-commit/release contract, increment a counter, schedule the next
|
|
10
|
+
> wakeup, and stop at the iteration cap. The one thing it must get right
|
|
11
|
+
> generically is the **release guard** — it reads the workspace's trunk from
|
|
12
|
+
> config, not a hardcoded branch name. (This repo's trunk is `master`, not
|
|
13
|
+
> `main` — exactly the kind of host fact the guard must read, not assume.)
|
|
14
|
+
|
|
15
|
+
## Inputs
|
|
16
|
+
|
|
17
|
+
- `--interval <seconds>` (optional, default 600 — 10 minutes).
|
|
18
|
+
- `--max-iterations <N>` (optional, default 20).
|
|
19
|
+
|
|
20
|
+
## Step 1 — First entry
|
|
21
|
+
|
|
22
|
+
Set the iteration counter to 1. Record the pre-existing dirty state of the tree
|
|
23
|
+
(so the auto-commit guard can tell what *this* sweep changed). Invoke the
|
|
24
|
+
`/dos-replan` Skill.
|
|
25
|
+
|
|
26
|
+
## Step 2 — After `/dos-replan` finishes: the guarded release contract
|
|
27
|
+
|
|
28
|
+
If `/dos-replan` made garden-only writes, optionally commit + release them — but
|
|
29
|
+
only behind the guard. **The guard reads the trunk from config, not a literal:**
|
|
30
|
+
|
|
31
|
+
```bash
|
|
32
|
+
dos doctor --workspace . --json
|
|
33
|
+
```
|
|
34
|
+
|
|
35
|
+
There is no `trunk` field in the doctor report today (it is a host fact); resolve
|
|
36
|
+
it the generic way: `git symbolic-ref --short refs/remotes/origin/HEAD` (the
|
|
37
|
+
remote's default branch). **Fail closed:** if that cannot be resolved (no
|
|
38
|
+
`origin/HEAD` — common in fresh clones / CI checkouts), treat the trunk as
|
|
39
|
+
**UNKNOWN** and **skip the release entirely** (record the sweep only). Do NOT fall
|
|
40
|
+
back to "the current branch" — that would make the on-trunk check below trivially
|
|
41
|
+
true on any branch and let an auto-commit proceed off-trunk. Then the guard fires
|
|
42
|
+
only when ALL hold:
|
|
43
|
+
|
|
44
|
+
- **the trunk is positively known** (resolved above, not UNKNOWN), AND **HEAD is
|
|
45
|
+
on it** (the resolved default branch — `master` here, `main` elsewhere;
|
|
46
|
+
**never hardcode either**).
|
|
47
|
+
- the working-tree changes are docs/state-only (the replan queue + cooldown
|
|
48
|
+
state, nothing in code).
|
|
49
|
+
- there is something to commit (a productive sweep).
|
|
50
|
+
|
|
51
|
+
If the guard passes, commit the garden writes with a generic subject and (if the
|
|
52
|
+
host wants it) call `/release`. If any condition fails — including an UNKNOWN
|
|
53
|
+
trunk — skip the release and just record the sweep — do not push code, do not
|
|
54
|
+
commit off-trunk.
|
|
55
|
+
|
|
56
|
+
Increment the counter; if it is below `--max-iterations`, schedule the next
|
|
57
|
+
wakeup `--interval` seconds out; else stop.
|
|
58
|
+
|
|
59
|
+
## Step 3 — On wakeup re-entry
|
|
60
|
+
|
|
61
|
+
Parse the counter from the prior iteration, run `/dos-replan`, and re-run Step 2
|
|
62
|
+
again. Stop when the counter reaches `--max-iterations`.
|
|
63
|
+
|
|
64
|
+
## What this skill deliberately does NOT do (no silent gap)
|
|
65
|
+
|
|
66
|
+
- **No hardcoded trunk.** It resolves the default branch from git, so a `master`
|
|
67
|
+
trunk and a `main` trunk are both handled — the SKP Phase 4 litmus.
|
|
68
|
+
- **No host release ceremony.** The generic loop commits garden writes and
|
|
69
|
+
optionally calls `/release`; it does not build artifacts or run a host's
|
|
70
|
+
bespoke promotion gate (those are host/dev tooling, outside this loop).
|
|
71
|
+
|
|
72
|
+
## Worked example (live transcript)
|
|
73
|
+
|
|
74
|
+
> **One replan cycle.** The loop re-runs `dos verify` over the portfolio each
|
|
75
|
+
> cadence, then lets `dos gate` decide DRAIN-vs-continue by **exit code** — the
|
|
76
|
+
> typed verdict, never the prose. Read the **rung** (`source`) and the **code**,
|
|
77
|
+
> not the headline.
|
|
78
|
+
|
|
79
|
+
```bash
|
|
80
|
+
$ dos doctor --workspace . --json | python -c "import sys,json;d=json.load(sys.stdin);print(d['paths']['plans_glob'])"
|
|
81
|
+
docs/**/*-plan.md
|
|
82
|
+
```
|
|
83
|
+
The WCR on-ramp: the portfolio is whatever matches `plans_glob` — host fact, read from config, not assumed.
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
$ dos verify --workspace . docs/82_liveness-oracle-plan liveness --json
|
|
87
|
+
{"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"}
|
|
88
|
+
```
|
|
89
|
+
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.
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
$ dos verify --workspace . docs/99_runtime-validation-and-the-actuation-boundary halt --json
|
|
93
|
+
{"phase":"halt","plan":"docs/99_runtime-validation-and-the-actuation-boundary","shipped":false,"source":"none"}
|
|
94
|
+
```
|
|
95
|
+
NOT_SHIPPED via the **none** rung (exit 1) — git ancestry has not stamped it; this phase is still in flight.
|
|
96
|
+
|
|
97
|
+
```bash
|
|
98
|
+
$ dos gate dispositions.json ; echo "exit=$?"
|
|
99
|
+
exit=3
|
|
100
|
+
```
|
|
101
|
+
`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.
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
$ dos arbitrate --workspace . --lane src
|
|
105
|
+
{"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 busy).","tree":["benchmark/**"]}
|
|
106
|
+
```
|
|
107
|
+
You asked for `src`; the arbiter handed back `benchmark` (exit 0, `outcome:acquire`) — a live lease made `src` contended, and the admission kernel refused to double-book the busy region.
|
|
108
|
+
|
|
109
|
+
## Anti-patterns
|
|
110
|
+
|
|
111
|
+
- ❌ Assuming the trunk is `main` — resolve it; this repo's is `master`.
|
|
112
|
+
- ❌ Committing off-trunk or committing code changes — the guard is docs/state +
|
|
113
|
+
on-trunk only.
|
|
114
|
+
- ❌ Looping unbounded — the iteration cap is the stop; honor it.
|
|
@@ -0,0 +1,213 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dos-self-improve
|
|
3
|
+
description: Run a self-improving work loop where the kernel — not the agent's say-so — decides whether each candidate change actually improved the codebase. The propose→verify→measure→keep-or-revert cycle with one rule no prior auto-improver enforced: a candidate is KEPT only if a witness the candidate's author did not write CONFIRMS it improved (the test suite green on a clean worktree, the truth syscall clean, and a strictly-measured metric gain). Otherwise it is REVERTED. The keep/revert/escalate decision is the kernel's typed `improve` verdict (`dos improve`), not inline prose; a run of non-keeps trips a breaker that ESCALATEs to a human. Each candidate is applied in an ISOLATED git worktree so the kernel adjudicating it is never the kernel being rewritten. Driven entirely by `dos` verbs + the workspace's own `dos.toml` — no host-specific paths, lanes, or commit conventions. The DOS reference recursive-self-improvement loop (SKP Axis 5, docs/280).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dos-self-improve — the loop where DOS adjudicates its own improvement
|
|
7
|
+
|
|
8
|
+
> **The first self-improving work loop for DOS.** It proposes a change, checks it,
|
|
9
|
+
> measures it, and keeps it **only if a witness the change's author did not write
|
|
10
|
+
> confirms it improved** — the green suite on a clean worktree, the truth syscall,
|
|
11
|
+
> and a strictly-measured metric gain. Everything else is reverted. The keep
|
|
12
|
+
> decision is the kernel's `improve` verdict, not the loop's opinion of its own
|
|
13
|
+
> work. A run of candidates nothing accepts trips a breaker that hands the
|
|
14
|
+
> judgment back to a human.
|
|
15
|
+
|
|
16
|
+
This is the dispatch loop (`/dos-dispatch-loop`) **turned inward on a codebase's
|
|
17
|
+
own source**, with the one rule no prior auto-improver enforced:
|
|
18
|
+
|
|
19
|
+
> A self-improving loop's fatal failure mode is **grading its own homework** — the
|
|
20
|
+
> agent that wrote the change is the same one that says "yes, this is better," so it
|
|
21
|
+
> learns to *narrate* improvement instead of making it. `dos improve` closes that
|
|
22
|
+
> hole: the keep-bit is a pure function of facts the loop did not author, so the
|
|
23
|
+
> loop **cannot keep a change by claiming it is better.** The only path to KEEP is
|
|
24
|
+
> to actually move a metric the environment measures.
|
|
25
|
+
|
|
26
|
+
The recursive-self-improvement literature names verification as the gating
|
|
27
|
+
constraint ("requiring verification regimes enabling labs to confirm"; "human
|
|
28
|
+
judgment on which problems matter remains the bottleneck"). This loop *is* that
|
|
29
|
+
verification regime, with the human kept in the loop by construction — the breaker
|
|
30
|
+
escalates to a person exactly when the loop runs dry of witnessed improvements.
|
|
31
|
+
|
|
32
|
+
## What the kernel decides vs. what you do
|
|
33
|
+
|
|
34
|
+
| Step | Who | What |
|
|
35
|
+
|---|---|---|
|
|
36
|
+
| **Propose** one scoped change | YOU (a subagent) | the capable, *untrusted* step — the only place intelligence enters the loop |
|
|
37
|
+
| **Verify + measure** | `dos` verbs | run the suite, run the truth syscall, measure the metric — all on an isolated worktree |
|
|
38
|
+
| **Keep / revert / escalate** | `dos improve` | the kernel's typed verdict over the env-authored facts — NOT your opinion |
|
|
39
|
+
| **Merge / discard / escalate** | YOU | carry out the kernel's verdict |
|
|
40
|
+
|
|
41
|
+
The kernel contributes ZERO intelligence to the proposal — only the refusal to
|
|
42
|
+
keep an unwitnessed one. That asymmetry is the whole design.
|
|
43
|
+
|
|
44
|
+
## Inputs
|
|
45
|
+
|
|
46
|
+
- `--metric <name>` (required) — what "improvement" means for THIS workspace, as a
|
|
47
|
+
non-negative integer the environment measures, higher = better. The reference
|
|
48
|
+
metric is **`lint-clean` = a large constant minus the `dos lint` finding count**
|
|
49
|
+
(driving dead policy to zero); other honest metrics: a passing-property-test
|
|
50
|
+
count, a coverage percent, a negated wall-clock budget. The kernel does not know
|
|
51
|
+
the unit — it only compares magnitudes (the `productivity`/`efficiency` work-unit
|
|
52
|
+
split).
|
|
53
|
+
- `--max-cycles <N>` (default 5) — the backstop cap (the `ITERATION_CAP` analogue).
|
|
54
|
+
- `--max-reverts <N>` (default 3) — ESCALATE to a human after this many candidates
|
|
55
|
+
in a row that nothing accepted (the breaker).
|
|
56
|
+
- `--lane <name>` (optional) — the lane to take; a bare loop auto-picks a free one.
|
|
57
|
+
|
|
58
|
+
## Step 0 — Pre-flight: take a lane, record the GREEN baseline
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
dos doctor --workspace . --json
|
|
62
|
+
dos arbitrate --workspace . --lane <LANE>
|
|
63
|
+
```
|
|
64
|
+
|
|
65
|
+
Then establish the baseline — and this gate is non-negotiable:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
python -m pytest -q # MUST be green to start
|
|
69
|
+
<measure the metric> # e.g. dos lint --workspace . --json | (1000 - finding count)
|
|
70
|
+
```
|
|
71
|
+
|
|
72
|
+
**You cannot measure improvement from a red baseline.** If the suite is red, STOP
|
|
73
|
+
and surface it — fix the suite first (that itself is a separate, ordinary task,
|
|
74
|
+
not a self-improvement cycle). Record the baseline metric `B`.
|
|
75
|
+
|
|
76
|
+
## Step 1 — Per cycle: propose ONE candidate in an ISOLATED worktree
|
|
77
|
+
|
|
78
|
+
The candidate edit is the `SELF_MODIFY` / `global`-lane hazard
|
|
79
|
+
([[self-modification-hazard]]): editing the kernel's own running path is exactly
|
|
80
|
+
what the arbiter refuses, and what would let a candidate rewrite the kernel that is
|
|
81
|
+
adjudicating it. So work in an isolated git worktree, never the live tree:
|
|
82
|
+
|
|
83
|
+
```bash
|
|
84
|
+
git worktree add ../_si-candidate HEAD
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Spawn ONE subagent with a tight brief, working in that worktree:
|
|
88
|
+
|
|
89
|
+
> Improve exactly ONE thing in this codebase that will move `<metric>`. Make the
|
|
90
|
+
> SMALLEST diff that moves it. Do not touch tests to make them pass; do not weaken
|
|
91
|
+
> an assertion. Commit your change with a clear subject. Return what you changed
|
|
92
|
+
> and why. **If you cannot find a real improvement, say so — do not invent one.**
|
|
93
|
+
|
|
94
|
+
One candidate per cycle keeps the witness attributable (the `commit-audit` "one
|
|
95
|
+
commit, one claim, one diff" discipline). If the subagent returns "nothing to
|
|
96
|
+
improve," the cycle is a **skip** — not a revert; move on.
|
|
97
|
+
|
|
98
|
+
## Step 2 — Gather the env-authored witnesses (on the worktree)
|
|
99
|
+
|
|
100
|
+
Every fact the kernel reads is measured by the ENVIRONMENT, never taken from the
|
|
101
|
+
subagent's word:
|
|
102
|
+
|
|
103
|
+
```bash
|
|
104
|
+
# (1) the suite, on the candidate-only worktree — the runner authors the bit
|
|
105
|
+
cd ../_si-candidate && python -m pytest -q ; SUITE=$?
|
|
106
|
+
|
|
107
|
+
# (2) the truth syscall — git ancestry, the oracle authors the bit
|
|
108
|
+
dos commit-audit --workspace ../_si-candidate HEAD # claim vs its own diff
|
|
109
|
+
# (and, if the candidate claims a plan phase, dos verify it)
|
|
110
|
+
|
|
111
|
+
# (3) the metric, re-measured on the worktree AFTER the candidate
|
|
112
|
+
<measure the metric on ../_si-candidate> # → W
|
|
113
|
+
|
|
114
|
+
# (4) the tokens the subagent spent (the provider usage record) → T
|
|
115
|
+
```
|
|
116
|
+
|
|
117
|
+
A missing witness is a FAILING witness — if you cannot run the suite or the truth
|
|
118
|
+
syscall, treat it as red/dirty (fail-safe). Never substitute the subagent's "tests
|
|
119
|
+
pass" claim for the runner's exit code.
|
|
120
|
+
|
|
121
|
+
## Step 3 — Ask the kernel: KEEP / REVERT / ESCALATE (the kernel decides)
|
|
122
|
+
|
|
123
|
+
This is the load-bearing step: **the decision is a kernel mechanism, not prose.**
|
|
124
|
+
|
|
125
|
+
```bash
|
|
126
|
+
dos improve --workspace . \
|
|
127
|
+
$( [ "$SUITE" -eq 0 ] && echo --suite-passed ) \
|
|
128
|
+
$( <truth clean> && echo --truth-clean ) \
|
|
129
|
+
--work "$W" --baseline-work "$B" --tokens "$T" \
|
|
130
|
+
--consecutive-reverts "$REVERTS" --max-reverts <N> \
|
|
131
|
+
--narrated "<the subagent's description>" --json
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
The verdict IS the exit code — branch on it, do not re-read the prose:
|
|
135
|
+
|
|
136
|
+
- **`0` KEEP** — suite green, truth clean, `W > B` (a strict env-measured gain), and
|
|
137
|
+
not wasteful. The improvement is *witnessed*. Go to Step 4-KEEP.
|
|
138
|
+
- **`3` REVERT** — either a REGRESSION (suite red / truth dirty — the non-negotiable
|
|
139
|
+
floor) or a NO-OP (safe but `W` did not beat `B`). Go to Step 4-REVERT.
|
|
140
|
+
- **`4` ESCALATE** — the breaker is open (`--max-reverts` non-keeps in a row). Go to
|
|
141
|
+
Step 4-ESCALATE and STOP.
|
|
142
|
+
|
|
143
|
+
The `--narrated` text is carried for the operator and **parsed for nothing** — it
|
|
144
|
+
cannot move REVERT → KEEP (docs/234). Do not try to argue a candidate into a keep;
|
|
145
|
+
make the metric move or revert it.
|
|
146
|
+
|
|
147
|
+
## Step 4 — Carry out the verdict
|
|
148
|
+
|
|
149
|
+
- **KEEP** — merge the worktree commit onto the lane, then RAISE the baseline to
|
|
150
|
+
`W` (the ratchet — the next candidate must beat the *improved* tree, not the
|
|
151
|
+
original) and reset the revert count to 0:
|
|
152
|
+
```bash
|
|
153
|
+
git merge --ff-only <candidate-sha> # or cherry-pick onto the lane
|
|
154
|
+
B=$W ; REVERTS=0
|
|
155
|
+
```
|
|
156
|
+
- **REVERT** — discard the worktree candidate; the live tree is untouched. Bump the
|
|
157
|
+
revert count (`REVERTS=$((REVERTS+1))`). The baseline is unchanged.
|
|
158
|
+
```bash
|
|
159
|
+
git worktree remove --force ../_si-candidate
|
|
160
|
+
```
|
|
161
|
+
- **ESCALATE** — discard the candidate, then file a human decision and STOP the
|
|
162
|
+
loop (the loop has run dry of witnessed improvements; a person decides what
|
|
163
|
+
matters next):
|
|
164
|
+
```bash
|
|
165
|
+
dos decisions ... # surface the escalation with the kernel's reason
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
Then re-create a fresh worktree for the next cycle (off the now-possibly-advanced
|
|
169
|
+
lane HEAD) and return to Step 1, until KEEP/REVERT cycles reach `--max-cycles` or
|
|
170
|
+
an ESCALATE stops the loop.
|
|
171
|
+
|
|
172
|
+
## Step 5 — Archive + release
|
|
173
|
+
|
|
174
|
+
When the loop stops, write a loop record under `paths.runs` (the per-cycle
|
|
175
|
+
verdicts, the kept/reverted/skipped counts, the final baseline — the high-water
|
|
176
|
+
mark that measures how much the loop improved the codebase, and the stop reason),
|
|
177
|
+
and release the lane lease. Commit any kept improvements with a generic subject
|
|
178
|
+
read from config — no hardcoded prefix.
|
|
179
|
+
|
|
180
|
+
## Why this is the honest version of recursive self-improvement
|
|
181
|
+
|
|
182
|
+
- The keep-bit reads **four env-authored facts** — the suite exit, the truth
|
|
183
|
+
syscall, the metric before, the metric after — and **zero loop-authored bytes**.
|
|
184
|
+
A loop that learns to write "great improvement" in every commit gains exactly
|
|
185
|
+
zero keep-probability, because the claim is not in the decision.
|
|
186
|
+
- The loop's default action on an unwitnessed candidate is **undo**, not keep — the
|
|
187
|
+
abstention-first discipline at loop scale.
|
|
188
|
+
- The breaker **escalates to a human** precisely when the loop cannot find a
|
|
189
|
+
witnessed improvement — the RSI literature's irreducible bottleneck, made a
|
|
190
|
+
kernel rule rather than a hope.
|
|
191
|
+
|
|
192
|
+
## What this skill deliberately does NOT do (no silent gap)
|
|
193
|
+
|
|
194
|
+
- **No open-ended autonomy.** The bound is the breaker + the cap; the loop
|
|
195
|
+
terminates into a human decision, by construction. It does not run unbounded.
|
|
196
|
+
- **No metric the loop can game.** The metric must be measured by the environment
|
|
197
|
+
on the worktree, not reported by the subagent. A metric the subagent computes
|
|
198
|
+
about itself is back to grading its own homework — `log` and refuse such a metric.
|
|
199
|
+
- **No test-weakening.** A candidate that makes the suite pass by deleting an
|
|
200
|
+
assertion REGRESSES the truth syscall / will be caught by a metric that counts
|
|
201
|
+
real coverage; the brief forbids it and the green-suite floor is on the FULL
|
|
202
|
+
suite, not a subset.
|
|
203
|
+
|
|
204
|
+
## Anti-patterns
|
|
205
|
+
|
|
206
|
+
- ❌ Believing the subagent's "it's better" — re-measure every fact; only `dos
|
|
207
|
+
improve` over env-authored witnesses decides KEEP.
|
|
208
|
+
- ❌ Editing the live tree — always work in an isolated worktree; the kernel
|
|
209
|
+
adjudicating a candidate must not be the kernel being rewritten by it.
|
|
210
|
+
- ❌ Measuring improvement from a red baseline — fix the suite first; you cannot
|
|
211
|
+
measure a gain you cannot see.
|
|
212
|
+
- ❌ Re-running a candidate the kernel reverted with a better-sounding commit
|
|
213
|
+
message — the message is not in the decision; make the metric move.
|
|
@@ -0,0 +1,180 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: dos-supervise-loop
|
|
3
|
+
description: Keep a target population of worker dispatch-loops alive across a workspace's lane roster — the supervisor cadence (the init/PID-1 analogy for a fleet). Each tick reads the active lane taxonomy from `dos doctor --json`, asks the kernel for a spawn/reap/flag plan via `dos loop --target N --json`, launches one `/dos-dispatch-loop` per SPAWN, scavenges only STALLED leases, and SURFACES (never kills) a SPINNING worker. The spawn/reap/flag decision is the kernel's typed `supervise()` verdict, not inline prose — the supervisor only carries out the plan. Driven entirely by `dos` verbs + the workspace's `dos.toml`. The DOS reference supervisor workflow (SKP Axis 5).
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# dos-supervise-loop — the generic worker-population supervisor
|
|
7
|
+
|
|
8
|
+
> **The init/PID-1 of a dispatch fleet.** It keeps `--target` worker
|
|
9
|
+
> dispatch-loops alive across the lane roster: each tick it counts live lane
|
|
10
|
+
> leases, classifies each worker's liveness, and fills the roster up to target by
|
|
11
|
+
> launching one `/dos-dispatch-loop` per free admissible lane. The *what to do*
|
|
12
|
+
> is a typed kernel verdict — `dos loop` emits a spawn/reap/flag plan; this skill
|
|
13
|
+
> only carries it out. It reaps a worker ONLY when the kernel says STALLED, never
|
|
14
|
+
> a healthy one, and it FLAGs a SPINNING worker to the operator rather than
|
|
15
|
+
> killing it (acting on a spin is not the supervisor's job).
|
|
16
|
+
|
|
17
|
+
The supervisor's whole contract is one rule the kernel owns: **the population is
|
|
18
|
+
filled from the plan, not from a guess.** A tick is `gather evidence → ask
|
|
19
|
+
`dos loop` → carry out spawn/reap/flag`. The four dispositions are the kernel's:
|
|
20
|
+
|
|
21
|
+
1. **SPAWN** — a free, admissible lane below target: launch one worker on it.
|
|
22
|
+
2. **REAP** — a STALLED lease: scavenge it so the lane is free to refill.
|
|
23
|
+
3. **HOLD** — an ADVANCING (or alive-counted SPINNING) worker: leave it alone.
|
|
24
|
+
4. **FLAG** — a SPINNING worker (advisory) or an excess over target: surface it,
|
|
25
|
+
do not kill it.
|
|
26
|
+
|
|
27
|
+
## Inputs
|
|
28
|
+
|
|
29
|
+
- `--target <N>` (default 1) — the desired live-worker population. The kernel
|
|
30
|
+
caps the achievable population at the *admissible* count (how many roster lanes
|
|
31
|
+
can simultaneously hold a worker given their disjointness); a `--target` above
|
|
32
|
+
that yields a TARGET_UNREACHABLE verdict naming the fix.
|
|
33
|
+
- `--max-concurrency <N>` (optional, docs/283) — the **derived-claim concurrency
|
|
34
|
+
budget**. On a DYNAMIC-CLAIM workspace (`concurrent = []`, where a lane is a
|
|
35
|
+
HANDLE whose disjointness is enforced per-pick at acquire time, not by a fixed
|
|
36
|
+
tree), the static admissible count is 1, so a `--target` above 1 is structurally
|
|
37
|
+
unreachable. Declaring this budget lets the supervisor keep up to N workers alive
|
|
38
|
+
on a fungible auto-pick handle WITHOUT pre-enumerating N disjoint trees — the
|
|
39
|
+
arbiter still narrows each worker's per-pick claim at its Step 0. Declare ONE
|
|
40
|
+
number, not N trees. Set it standing in `dos.toml [supervise] max_concurrency`,
|
|
41
|
+
or pass `--max-concurrency` for a one-off run. Off by default (admissible stays
|
|
42
|
+
the static disjoint-lane count — byte-for-byte today's).
|
|
43
|
+
- `--interval <seconds>` (long default) — the wakeup cadence between ticks. A
|
|
44
|
+
supervisor wakes rarely; it is a watchdog, not a busy-loop.
|
|
45
|
+
- `--max-ticks <N>` (optional) — stop after N ticks. Omit for an open-ended run
|
|
46
|
+
that stops only on an operator interrupt.
|
|
47
|
+
|
|
48
|
+
## Step 0 — Read the taxonomy, compute the plan
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
dos doctor --workspace . --json
|
|
52
|
+
dos loop --workspace . --target N --json
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
The doctor report carries the active lane roster (the concurrent + exclusive
|
|
56
|
+
lanes and their trees) — **read it, never assume a lane name.** `dos loop` then
|
|
57
|
+
gathers the evidence (the live lane leases from the journal + each lease's
|
|
58
|
+
liveness) and returns the typed plan: a `verdict` (AT_TARGET / FILLING /
|
|
59
|
+
OVER_TARGET / TARGET_UNREACHABLE), the `alive`/`admissible`/`target` tally, and
|
|
60
|
+
the `spawn`/`reap`/`flag` lane lists. **This plan is the kernel's decision; the
|
|
61
|
+
remaining steps only enact it.** If the verdict is TARGET_UNREACHABLE, read its
|
|
62
|
+
reason (the roster cannot reach the number) and stop — see the anti-patterns.
|
|
63
|
+
|
|
64
|
+
## Step 1 — Launch one worker per SPAWN
|
|
65
|
+
|
|
66
|
+
For each lane in the plan's `spawn` list, launch a worker dispatch-loop focused
|
|
67
|
+
on that lane:
|
|
68
|
+
|
|
69
|
+
```
|
|
70
|
+
/dos-dispatch-loop --lane <LANE>
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
The worker takes its own lane lease via `dos arbitrate` at its Step 0 and
|
|
74
|
+
**journals its ACQUIRE early** — that early write is what shrinks the
|
|
75
|
+
double-spawn window: by the next tick the lease is visible in the journal, so
|
|
76
|
+
the supervisor counts it alive and does not launch a second worker on the same
|
|
77
|
+
lane. The supervisor itself never takes a lease; it only counts them and fills
|
|
78
|
+
the gap. Launch exactly the lanes the plan named — no more, no fewer.
|
|
79
|
+
|
|
80
|
+
## Step 2 — Per REAP scavenge, per FLAG surface
|
|
81
|
+
|
|
82
|
+
For each lane in the plan's `reap` list (a STALLED worker): release/scavenge its
|
|
83
|
+
lease so the lane is free to refill on the next tick. The worker is not making
|
|
84
|
+
progress by the kernel's temporal verdict, so its claim on the lane is the only
|
|
85
|
+
thing being reclaimed — the lane returns to the roster as a spawn candidate.
|
|
86
|
+
|
|
87
|
+
For each lane in the plan's `flag` list (a SPINNING worker, or an excess over
|
|
88
|
+
target): **surface it to the operator and move on.** Do NOT kill a SPINNING
|
|
89
|
+
worker and do NOT reap an excess healthy one — a flag is advisory. Acting on a
|
|
90
|
+
spin (deciding a busy-but-not-advancing worker should be stopped) is an open
|
|
91
|
+
question the supervisor deliberately leaves to a human; its job is to make the
|
|
92
|
+
spin visible, not to adjudicate it.
|
|
93
|
+
|
|
94
|
+
## Step 3 — Sleep, re-tick, stop on interrupt or --max-ticks
|
|
95
|
+
|
|
96
|
+
Sleep `--interval` seconds, then re-run from Step 0: re-read the taxonomy,
|
|
97
|
+
recompute the plan, enact it. Each tick is independent and idempotent — it
|
|
98
|
+
re-derives the whole plan from the current journal state, so a missed or extra
|
|
99
|
+
tick self-corrects. A lane launched within the last cooldown window is treated
|
|
100
|
+
as *pending* (alive-or-coming) for the next tick, so a slow ACQUIRE does not
|
|
101
|
+
trigger a re-spawn.
|
|
102
|
+
|
|
103
|
+
Stop when the operator interrupts the run, or when `--max-ticks` is reached.
|
|
104
|
+
There is no "all done" terminal state — a supervisor's job is to *stay up*; it
|
|
105
|
+
ends only on an explicit bound or an interrupt.
|
|
106
|
+
|
|
107
|
+
## What this skill deliberately does NOT do (no silent gap, `CLAUDE.md` heavy tier)
|
|
108
|
+
|
|
109
|
+
- **No auto-kill of a SPINNING worker.** A spin is FLAGged (advisory) and
|
|
110
|
+
surfaced; the supervisor never terminates a busy worker. Acting on a spin is
|
|
111
|
+
open research, deliberately left to the operator.
|
|
112
|
+
- **No reap of a healthy worker to hit a number.** A REAP fires ONLY on the
|
|
113
|
+
kernel's STALLED verdict. An ADVANCING (or alive-counted SPINNING) worker is
|
|
114
|
+
HELD even when the population is over target — the excess is FLAGged, not
|
|
115
|
+
killed.
|
|
116
|
+
- **No hardcoded lane or trunk.** Every host fact — which lanes exist, their
|
|
117
|
+
trees, the ship grammar — comes from `dos doctor --json` and the workspace's
|
|
118
|
+
`dos.toml`. The supervisor names the generic roster the kernel reports, nothing
|
|
119
|
+
else.
|
|
120
|
+
- **No value-aware spawn ranking.** It fills free admissible lanes in roster
|
|
121
|
+
order; a yield-greedy "spawn the highest-value lane first" picker is a driver
|
|
122
|
+
concern outside this loop.
|
|
123
|
+
|
|
124
|
+
## Worked example (live transcript)
|
|
125
|
+
|
|
126
|
+
> A supervisor tick, hand-run with real `dos` verbs against this workspace
|
|
127
|
+
> (`dos doctor` reports `is_kernel_repo: true`, 11 runtime files). The verdicts
|
|
128
|
+
> below are live-captured; the per-run digest is the antidote to re-reading state.
|
|
129
|
+
|
|
130
|
+
Step 0 — read the roster, then ask the kernel who is alive:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
$ dos doctor --workspace . --json
|
|
134
|
+
# lanes.concurrent = [benchmark, docs, examples, scripts, spikes, src, tests]
|
|
135
|
+
# lanes.exclusive = [global] stamp.style = grep overlap_policy.active = prefix
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
A worker's lease is what the supervisor counts — and the arbiter never double-books:
|
|
139
|
+
|
|
140
|
+
```bash
|
|
141
|
+
$ dos arbitrate --workspace . --lane src
|
|
142
|
+
{"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 busy)."}
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
You asked for `src`; a live lease made it contended, so the arbiter redirected to
|
|
146
|
+
`benchmark` — exit `0` (acquire). The redirect IS admission refusing a busy region.
|
|
147
|
+
|
|
148
|
+
Per run, fold ONE digest instead of re-reading state files (no `claimed` field):
|
|
149
|
+
|
|
150
|
+
```bash
|
|
151
|
+
$ dos status RUN_ID --json # ILLUSTRATIVE shape — folds liveness+ledger+lease+resume
|
|
152
|
+
# {"liveness":"SPINNING", ...} exit 3 (SPINNING) → this run is the FLAG candidate
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
`dos status`/`dos liveness` share the liveness exit codes — `0` ADVANCING (HOLD),
|
|
156
|
+
`3` SPINNING (FLAG, advisory), `4` STALLED (REAP). On SPINNING the supervisor records
|
|
157
|
+
an OP_HALT **proposal** and surfaces it; it never signals the process. A worker can
|
|
158
|
+
be paused for clean re-entry instead:
|
|
159
|
+
|
|
160
|
+
```bash
|
|
161
|
+
$ dos halt --resumable # ILLUSTRATIVE — SUSPEND op; run-dir retained, dos resume continues it
|
|
162
|
+
```
|
|
163
|
+
|
|
164
|
+
## Anti-patterns
|
|
165
|
+
|
|
166
|
+
- ❌ Re-spawning a pending lane — a worker launched last tick whose ACQUIRE has
|
|
167
|
+
not yet journalled is alive-or-coming; the kernel marks it pending and the plan
|
|
168
|
+
omits it. Honor that; do not double-launch.
|
|
169
|
+
- ❌ Reaping an ADVANCING worker — only a STALLED lease is a REAP. A worker that
|
|
170
|
+
is moving keeps its lane; trust the temporal verdict, do not second-guess it.
|
|
171
|
+
- ❌ Killing a SPINNING worker — it is a FLAG, not a REAP. Surface it; let the
|
|
172
|
+
operator decide.
|
|
173
|
+
- ❌ Running the supervisor where the roster cannot reach `--target` — a
|
|
174
|
+
TARGET_UNREACHABLE verdict means no further disjoint concurrent lanes exist to
|
|
175
|
+
fill. Two honest fixes: (a) on a STATIC-tree roster, declare more disjoint
|
|
176
|
+
concurrent lanes in `dos.toml [lanes]`; (b) on a DYNAMIC-CLAIM roster
|
|
177
|
+
(`concurrent = []`, per-pick disjointness), declare a `--max-concurrency` budget
|
|
178
|
+
(docs/283) so the supervisor rides a fungible auto-pick handle up to N workers —
|
|
179
|
+
one number instead of N trees. Do NOT force the number by inventing fake disjoint
|
|
180
|
+
trees a worker would over-claim.
|