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.
Files changed (178) hide show
  1. dos/__init__.py +261 -0
  2. dos/_bin/dos-hook.exe +0 -0
  3. dos/_filelock.py +255 -0
  4. dos/_job_policy.py +97 -0
  5. dos/_tree.py +145 -0
  6. dos/admission.py +433 -0
  7. dos/answer_shape.py +299 -0
  8. dos/arbiter.py +859 -0
  9. dos/archive_lock.py +266 -0
  10. dos/arg_provenance.py +814 -0
  11. dos/attest.py +472 -0
  12. dos/breaker.py +311 -0
  13. dos/churn.py +226 -0
  14. dos/claim_extract.py +229 -0
  15. dos/claim_ttl.py +150 -0
  16. dos/cli.py +8721 -0
  17. dos/commit_audit.py +666 -0
  18. dos/completion.py +466 -0
  19. dos/concurrency_class.py +154 -0
  20. dos/config.py +1380 -0
  21. dos/config_lint.py +464 -0
  22. dos/cooldown.py +390 -0
  23. dos/coverage.py +387 -0
  24. dos/dangling_intent.py +287 -0
  25. dos/data_class.py +397 -0
  26. dos/decisions.py +1274 -0
  27. dos/decisions_tui.py +251 -0
  28. dos/dispatch_top.py +740 -0
  29. dos/dispatch_top_tui.py +116 -0
  30. dos/drivers/__init__.py +40 -0
  31. dos/drivers/ci_status.py +630 -0
  32. dos/drivers/citation_resolve.py +703 -0
  33. dos/drivers/decision_stop.py +98 -0
  34. dos/drivers/export_file.py +173 -0
  35. dos/drivers/export_otlp.py +275 -0
  36. dos/drivers/export_statsd.py +242 -0
  37. dos/drivers/hook_dialects.py +391 -0
  38. dos/drivers/job.py +47 -0
  39. dos/drivers/llm_judge.py +360 -0
  40. dos/drivers/memory_recall.py +1231 -0
  41. dos/drivers/notify_slack.py +373 -0
  42. dos/drivers/notify_webhook.py +251 -0
  43. dos/drivers/operator_judge.py +114 -0
  44. dos/drivers/os_acceptance.py +228 -0
  45. dos/drivers/paste_log.py +132 -0
  46. dos/drivers/plan_scope.py +133 -0
  47. dos/drivers/self_improve.py +375 -0
  48. dos/drivers/similarity_judge.py +249 -0
  49. dos/drivers/state_diff.py +274 -0
  50. dos/drivers/supervisor.py +347 -0
  51. dos/drivers/watchdog.py +363 -0
  52. dos/drivers/workshop.py +160 -0
  53. dos/durable_schema.py +344 -0
  54. dos/effect_witness.py +393 -0
  55. dos/efficiency.py +318 -0
  56. dos/enforce.py +414 -0
  57. dos/enumerate.py +776 -0
  58. dos/env_print.py +378 -0
  59. dos/event_severity.py +258 -0
  60. dos/evidence.py +692 -0
  61. dos/exec_capability.py +256 -0
  62. dos/export_cursor.py +143 -0
  63. dos/exporter.py +320 -0
  64. dos/firing_label.py +353 -0
  65. dos/fleet_roll.py +226 -0
  66. dos/gate_classify.py +827 -0
  67. dos/gh4_coverage.py +179 -0
  68. dos/git_delta.py +122 -0
  69. dos/guard.py +215 -0
  70. dos/health.py +552 -0
  71. dos/help_summary.py +519 -0
  72. dos/home.py +934 -0
  73. dos/hook_binary.py +194 -0
  74. dos/hook_dialect.py +271 -0
  75. dos/hook_exit.py +191 -0
  76. dos/hook_install.py +437 -0
  77. dos/id_alloc.py +304 -0
  78. dos/improve.py +499 -0
  79. dos/intent_ledger.py +635 -0
  80. dos/interpret.py +176 -0
  81. dos/intervention.py +769 -0
  82. dos/intervention_eval.py +371 -0
  83. dos/journal_delta.py +308 -0
  84. dos/judge_eval.py +328 -0
  85. dos/judges.py +366 -0
  86. dos/lane_infer.py +127 -0
  87. dos/lane_journal.py +1001 -0
  88. dos/lane_lease.py +952 -0
  89. dos/lane_overlap.py +228 -0
  90. dos/lease_health.py +282 -0
  91. dos/lifecycle.py +211 -0
  92. dos/liveness.py +352 -0
  93. dos/lock_modes.py +185 -0
  94. dos/log_source.py +395 -0
  95. dos/loop_decide.py +1746 -0
  96. dos/marker_gate.py +254 -0
  97. dos/marker_sensor.py +396 -0
  98. dos/noop_streak.py +280 -0
  99. dos/notify.py +479 -0
  100. dos/observe.py +175 -0
  101. dos/oracle.py +1661 -0
  102. dos/overlap_eval.py +214 -0
  103. dos/overlap_policy.py +342 -0
  104. dos/packet_sidecar.py +267 -0
  105. dos/phase_shipped.py +1985 -0
  106. dos/pick_priority.py +225 -0
  107. dos/pickable.py +369 -0
  108. dos/picker_oracle.py +1037 -0
  109. dos/plan_board.py +513 -0
  110. dos/plan_board_tui.py +113 -0
  111. dos/plan_source.py +455 -0
  112. dos/posttool_sensor.py +528 -0
  113. dos/precursor_gate.py +499 -0
  114. dos/precursor_gate_eval.py +239 -0
  115. dos/preflight.py +825 -0
  116. dos/pretool_sensor.py +490 -0
  117. dos/proc_delta.py +181 -0
  118. dos/productivity.py +296 -0
  119. dos/provider_limit.py +242 -0
  120. dos/py.typed +4 -0
  121. dos/reason_morphology.py +299 -0
  122. dos/reasons.py +449 -0
  123. dos/reconcile.py +173 -0
  124. dos/recurring_wedge.py +206 -0
  125. dos/render.py +393 -0
  126. dos/result_state.py +468 -0
  127. dos/resume.py +578 -0
  128. dos/resume_evidence.py +293 -0
  129. dos/retention.py +344 -0
  130. dos/reward.py +372 -0
  131. dos/rewind.py +587 -0
  132. dos/rewind_evidence.py +168 -0
  133. dos/rewind_tokens.py +252 -0
  134. dos/run_id.py +342 -0
  135. dos/scope.py +520 -0
  136. dos/scope_source.py +382 -0
  137. dos/scout.py +982 -0
  138. dos/self_modify.py +209 -0
  139. dos/sibling_scan.py +569 -0
  140. dos/skills/EXAMPLES.md +584 -0
  141. dos/skills/dos-class-cycle/SKILL.md +107 -0
  142. dos/skills/dos-dispatch/SKILL.md +177 -0
  143. dos/skills/dos-dispatch-loop/SKILL.md +254 -0
  144. dos/skills/dos-goal-gate/SKILL.md +269 -0
  145. dos/skills/dos-next-up/SKILL.md +231 -0
  146. dos/skills/dos-promote/SKILL.md +114 -0
  147. dos/skills/dos-replan/SKILL.md +159 -0
  148. dos/skills/dos-replan-loop/SKILL.md +114 -0
  149. dos/skills/dos-self-improve/SKILL.md +213 -0
  150. dos/skills/dos-supervise-loop/SKILL.md +180 -0
  151. dos/skills/dos-unstick/SKILL.md +108 -0
  152. dos/skills/dos-witness-claim/SKILL.md +251 -0
  153. dos/stamp.py +1002 -0
  154. dos/state_health.py +387 -0
  155. dos/status.py +114 -0
  156. dos/stop_policy.py +334 -0
  157. dos/supervise.py +1014 -0
  158. dos/testwitness.py +392 -0
  159. dos/timeline.py +1027 -0
  160. dos/tokens.py +485 -0
  161. dos/tool_stream.py +393 -0
  162. dos/tool_stream_eval.py +226 -0
  163. dos/trace.py +524 -0
  164. dos/verdict.py +140 -0
  165. dos/verdict_cli.py +189 -0
  166. dos/verdict_journal.py +497 -0
  167. dos/verdict_rollup.py +217 -0
  168. dos/verdicts.py +181 -0
  169. dos/wedge_reason.py +282 -0
  170. dos_kernel-0.22.0.dist-info/METADATA +859 -0
  171. dos_kernel-0.22.0.dist-info/RECORD +178 -0
  172. dos_kernel-0.22.0.dist-info/WHEEL +5 -0
  173. dos_kernel-0.22.0.dist-info/entry_points.txt +39 -0
  174. dos_kernel-0.22.0.dist-info/licenses/LICENSE +21 -0
  175. dos_kernel-0.22.0.dist-info/top_level.txt +2 -0
  176. dos_mcp/__init__.py +52 -0
  177. dos_mcp/py.typed +2 -0
  178. dos_mcp/server.py +779 -0
@@ -0,0 +1,269 @@
1
+ ---
2
+ name: dos-goal-gate
3
+ description: 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`.
4
+ ---
5
+
6
+ # dos-goal-gate — gate "I'm done" on a witness, not on self-report
7
+
8
+ > **A completion condition the agent checks against its own narration is the
9
+ > exact failure DOS exists to fix.** When an agent decides "the goal is met" by
10
+ > re-reading what it just wrote, the part deciding ground truth *is* the part
11
+ > being judged — that is **consistency, not grounding** (docs/138). This skill
12
+ > never decides done-ness by re-reading the transcript. It turns the goal into a
13
+ > set of checkable EFFECT claims, then wires the Stop decision so the agent
14
+ > cannot stop until a read-back whose **byte-author is not the agent** (git
15
+ > ancestry, an OS exit code, a fresh state read) corroborates each effect. The
16
+ > kernel decides; the skill narrates.
17
+
18
+ The shape is domain-free: **state the goal as effects → wire the Stop gate →
19
+ on each stop, witness every effect → stop only when all are corroborated.** The
20
+ *policy* (which plan grammar, which lanes, where state lives) is data read from
21
+ `dos doctor --json`, never literals this screenplay hardcodes.
22
+
23
+ **Why this is not just "ask the model if it's done."** A harness stop-condition
24
+ ("keep going until X") is evaluated by a model reading the session — so a
25
+ confident, fluent narration of an X that the world does not corroborate ends the
26
+ work early (the silent fail of docs/177). The gate below replaces that judgment
27
+ with a verdict over evidence the agent did not write: a phase is done when *git*
28
+ says a commit backs it, not when the agent says it committed; a file exists when
29
+ a *fresh read* finds it, not when the agent says it wrote it.
30
+
31
+ ## When to use this (and when not)
32
+
33
+ - **Use it** when a single agent self-paces toward a stated goal and you want its
34
+ "done" to be unfalsifiable-by-narration — a `/loop` worker, a self-stopping
35
+ task agent, or any run where the operator stated a completion condition.
36
+ - **Use `dos-witness-claim` instead** when many workers' results are folded at a
37
+ `parallel()`/`pipeline()` barrier — that skill is the *fan-out fold* analogue;
38
+ this one is the *single-agent self-stop* analogue. Same witness discipline,
39
+ different site.
40
+ - **This is advisory (a PDP, not a PEP — docs/99).** It computes a Stop verdict
41
+ and lets the runtime act on it via the user-owned hook seam. It blocks a *false*
42
+ done; it never blocks a *true* one, and it never enforces beyond the Stop hook.
43
+
44
+ ## Inputs
45
+
46
+ - The operator's **goal** — the completion condition in plain words ("the auth
47
+ refactor is shipped and the suite is green", "the migration plan's phases are
48
+ all landed"). Free prose is the *input*, never the *test*.
49
+ - Optionally, a **transcript path** for the running session (the Stop event
50
+ carries it; you rarely pass it by hand).
51
+
52
+ ## Step 0 — Discover the workspace layout (one call)
53
+
54
+ Run the doctor verb and read the result. **Every path / lane / exit-code below
55
+ comes from here, never a literal.**
56
+
57
+ ```bash
58
+ dos doctor --workspace . --json
59
+ ```
60
+
61
+ The fields this skill uses:
62
+
63
+ - `exit_codes.verify` — `{shipped, not_shipped, contract_error}`. Branch on these
64
+ for a **git-phase** effect (Step 2a), never on parsing prose.
65
+ - `exit_codes."verify-result"` — `{healthy, unreadable, dead, contract_error}`
66
+ (`dead=3`). Branch on these for the **terminal-state** witness when a transcript
67
+ is in play.
68
+ - `paths.plans_glob` / `lanes` / `stamp` — the host's plan grammar, lane taxonomy,
69
+ and ship-stamp convention, if a goal names a `(plan, phase)`.
70
+ - `git` — if `false`, the git-existence witness (Step 2a) has no history; every
71
+ git-phase effect resolves `source="none"`. Say so; do not silently pass it.
72
+ - `runtime_hooks` — which runtimes already have a `dos hook …` Stop entry wired
73
+ (so you know whether Step 1 still needs doing).
74
+
75
+ ## Step 1 — Wire the Stop gate (once per workspace)
76
+
77
+ The gate is `dos hook stop`: a Stop / SubagentStop hook that refuses to let the
78
+ agent stop while a confidently-CLAIMED phase is NOT corroborated by git. Wire it
79
+ into the runtime's settings — idempotent, merged into any existing hooks, never
80
+ clobbering the operator's own:
81
+
82
+ ```bash
83
+ dos init --with-hooks --workspace . # Claude Code (the default runtime)
84
+ # cross-runtime: dos init --hooks <runtime> --workspace . (preview with --dry-run)
85
+ ```
86
+
87
+ This binds three hooks; the load-bearing one here is **Stop → `dos hook stop`**.
88
+ On every stop it extracts the `(plan, phase)` the agent claimed and refuses the
89
+ stop (feeding the verdict back as the next instruction) if git does not back it.
90
+ That refusal IS the grounded form of "keep working until the goal is met": the
91
+ work cannot end on the agent's word that a phase shipped.
92
+
93
+ > **Two Stop hooks, opposite triggers — do not conflate them.** `dos hook stop`
94
+ > blocks a *false done* (the agent claimed a phase, git disagrees). `dos hook
95
+ > marker` (docs/259) blocks a *premature give-up while a keep-alive budget is
96
+ > unspent*, then gets out of the way. A host may wire both; this skill is about
97
+ > the first. If your goal is "don't stop polling yet," that is `dos hook marker`,
98
+ > not this gate.
99
+
100
+ ### Step 1a — How this composes with the harness `/goal` command
101
+
102
+ The Claude Code `/goal <condition>` command is itself a **session-scoped Stop
103
+ hook — but a *model-evaluated* one**: a fast model re-reads the session after each
104
+ turn and rules on whether the condition holds. That is precisely the
105
+ consistency-not-grounding shape this skill exists to fix — the judge is a model
106
+ reading the agent's own narration, with no witness the agent did not author.
107
+
108
+ You do **not** replace `/goal`; you wire `dos hook stop` (Step 1) **alongside**
109
+ it, and the harness combines them for you. Claude Code runs every matching Stop
110
+ hook in parallel and applies an **ANY-block** rule: *the stop is refused if **any**
111
+ hook blocks it* (a `{"decision":"block",…}` at exit 0, or exit 2). So with both
112
+ active, the agent may stop only when the `/goal` model-judge **AND** the grounded
113
+ git gate both allow it — a logical AND of "the narration reads done" and "ground
114
+ truth backs it." The grounded gate can only ever *add* a refusal the model-judge
115
+ missed; it never loosens `/goal`. That is the whole win: keep using `/goal` for
116
+ its fluent, free, prose-level check, and let `dos hook stop` veto the case where
117
+ the prose says done but git does not corroborate it.
118
+
119
+ > **The two hooks are independent — the gate does not read the goal text.** A
120
+ > settings.json Stop hook receives the session/transcript, not the `/goal`
121
+ > condition string (the harness exposes no goal field to hooks). So `dos hook
122
+ > stop` does not "check the goal"; it independently checks that every phase the
123
+ > agent *claimed shipped* is backed by git. The alignment between the two is the
124
+ > operator's job: state the goal as the same checkable effects the gate verifies
125
+ > (Step 2), so "the model thinks it's done" and "git backs every claimed phase"
126
+ > converge on the same finish line. Do not write the gate as if it parses the
127
+ > goal — it parses the agent's claims and asks git.
128
+
129
+ ## Step 2 — State the goal as checkable effects (the decomposition)
130
+
131
+ A goal is met when its **effects** are present in the world. Translate the prose
132
+ goal into a list of named, checkable effects — and **abstain rather than invent**.
133
+ An effect you cannot name an identifier for is not a passable goal; it is a
134
+ **NO_CLAIM** to surface for the operator, never a test you fabricate (docs/134).
135
+
136
+ Map each effect to its witness rung:
137
+
138
+ | Effect the goal asserts | Witness (byte-author ≠ agent) | Verb today |
139
+ |---|---|---|
140
+ | "(plan, phase) is shipped" | git ancestry + ship-stamp grammar | `dos verify` (Step 2a) — SHIPPED |
141
+ | "this terminal result is real" (a transcript is in play) | harness authorship marker | `dos verify-result` — SHIPPED |
142
+ | "I created file X / inserted row Y / sent message Z / deployed" | a fresh GET / state-diff / OS exit / counterparty record | **no CLI verb** (Step 2b) — Python-API gap |
143
+
144
+ The first two are shipped CLI verbs. The third is the open seam — handled
145
+ honestly in Step 2b. The goal's "done" is the **conjunction** of all its effects'
146
+ witnesses: every one CONFIRMED/SHIPPED, or the goal is not met.
147
+
148
+ ### Step 2a — git-phase effects: ask the truth syscall
149
+
150
+ For each `(plan, phase)` the goal names, never trust "I committed it" and never
151
+ grep commit subjects yourself:
152
+
153
+ ```bash
154
+ dos verify --workspace . <PLAN> <PHASE> --json
155
+ echo "exit=$?"
156
+ ```
157
+
158
+ Read the `ShipVerdict` `{shipped, source, sha?}`, branch on `exit_codes.verify`,
159
+ and **read the rung**:
160
+
161
+ - `source: "registry"` — the strongest git ship; a ship row exists. Effect met.
162
+ - `source: "grep-subject"` — a commit *subject* carried the phase token. SHIPPED,
163
+ but weaker (a subject can flip the verdict even if little was built). Met, but
164
+ mark the rung; do not treat it as equal to `registry`.
165
+ - `source: "none"` — no positive git evidence. The agent CLAIMED the phase but git
166
+ does not corroborate it. **The effect is NOT met** — this is the narrated
167
+ success the world does not back. The goal is unmet; keep working.
168
+
169
+ This is grounding because git is a witness the agent did not author: a commit's
170
+ existence in ancestry is a fact about the repository, not about the agent's prose.
171
+
172
+ ### Step 2b — created-file / DB-row / sent-message effects: the read-back gap
173
+
174
+ **There is NO `dos verify-effect` (or `dos witness`) CLI verb.** The
175
+ effect-witness join is shipped in the kernel as a **Python API**, not a command
176
+ (exactly as `tool_stream` has no `dos tool-stream` verb — see EXAMPLES.md Recipe
177
+ 5). So for any effect outside git, document the pattern and **log the gap at
178
+ runtime**, rather than pretending a verb exists:
179
+
180
+ ```python
181
+ from dos.claim_extract import extract_claims # (a) abstain, never invent
182
+ from dos.effect_witness import EffectClaim, witness_effect
183
+ from dos.evidence import gather_evidence, resolve_evidence_source # (b) read-back
184
+
185
+ # (a) Extract the claim from the agent's terminal text. extract_claims fires only
186
+ # on an explicit ID-shaped token or a DOS-CLAIM: marker — free prose yields [].
187
+ # That [] is a NO_CLAIM (surface it), not a met effect.
188
+
189
+ # (b) Gather a read-back from a witness the agent did not author. A real witness
190
+ # (a fresh HTTP GET, an OS exit code, a state-snapshot diff) lives in a driver
191
+ # registered under the `dos.evidence_sources` entry-point group; resolve it by
192
+ # name and run it at the boundary:
193
+ source = resolve_evidence_source("<your-witness-name>") # built-in `null` if none wired
194
+ facts = gather_evidence(source, subject="<effect key>", config=cfg)
195
+
196
+ # (c) The effect is met ONLY on CONFIRMED — the join is capped by the read-back's
197
+ # accountability (believe_under_floor): a forgeable same-surface read-back
198
+ # (AGENT_AUTHORED) is recorded but structurally CANNOT grant belief.
199
+ verdict = witness_effect(EffectClaim(key="<effect key>", narrated="<what agent said>"),
200
+ (facts,))
201
+ # verdict.verdict -> CONFIRMED | REFUTED | UNWITNESSED | NO_CLAIM
202
+ # verdict.believe -> True ONLY on CONFIRMED
203
+ ```
204
+
205
+ The load-bearing rule, enforced structurally by `believe_under_floor`: a read-back
206
+ on the forgeable floor (`AGENT_AUTHORED` — the agent re-reading its own surface, a
207
+ pasted receipt, an mtime) is recorded but **structurally incapable** of granting
208
+ belief. So the worst a lying same-surface read-back can do is be ignored, never
209
+ manufacture a CONFIRMED. **Log the gap, never silently skip it:** the first time a
210
+ non-git effect needs witnessing and no `dos.evidence_sources` driver is wired,
211
+ emit a one-line `log` naming the unwitnessed effect — surface it up, never launder
212
+ it into "goal met."
213
+
214
+ ## Step 3 — The gate's verdict is the stop decision
215
+
216
+ With the gate wired (Step 1), the runtime already enforces the git-phase rung on
217
+ every stop. Your job in the screenplay is to keep the agent's claimed effects and
218
+ the goal's effect-list aligned, and to read the gate's verdict honestly:
219
+
220
+ - **All effects CONFIRMED / SHIPPED** → the goal is met. The Stop hook emits
221
+ nothing (`{"checked": N, "ok": true}` under `--json`) and the agent stops. This
222
+ is the only path to "done."
223
+ - **Any effect `source: "none"` / REFUTED** → the goal is unmet. `dos hook stop`
224
+ emits `{"decision": "block", "reason": "…"}`, the runtime declines to stop, and
225
+ the reason is fed back as the next instruction — *keep working*. The agent does
226
+ not get to overrule this by asserting completion again.
227
+ - **Any effect UNWITNESSED / NO_CLAIM** → you cannot say the goal is met. Surface
228
+ it for the operator; do not let the agent stop on an effect no accountable
229
+ witness reached. (The git-phase rung fails *safe* — a `source:"none"` is treated
230
+ as not-shipped, so the gate keeps working rather than passing an unproven claim.)
231
+
232
+ You can check the gate's reasoning out-of-band, before relying on it, by feeding a
233
+ synthetic Stop event:
234
+
235
+ ```bash
236
+ echo '{"transcript_path":"<session.jsonl>"}' | dos hook stop --workspace . --json
237
+ # {"ok": false, "reason": "DOS verify: you claimed … shipped, but git has no commit backing it …", "results": [...]}
238
+ # ok:false → the goal is NOT met; the agent will be kept working.
239
+ # ok:true → every claimed phase is corroborated; the agent may stop.
240
+ ```
241
+
242
+ This is the same out-of-loop check as `dos plan --once` / `dos commit-audit`: a
243
+ verdict over ground truth, run from outside the loop that wrote the claim.
244
+
245
+ ## Anti-patterns
246
+
247
+ - ❌ Deciding "the goal is met" by re-reading the transcript / the agent's last
248
+ message. That is consistency, not grounding — the agent judging its own bytes.
249
+ Decompose into effects and witness each one.
250
+ - ❌ Treating "I committed the phase" as the phase shipping. Run `dos verify`; a
251
+ `source:"none"` means git does not back the claim, regardless of the narration.
252
+ - ❌ Grepping commit subjects yourself to confirm a ship. The ship-stamp grammar
253
+ is `dos.toml` `[stamp]` data the oracle reads — ask `dos verify`, do not
254
+ re-implement the rung (a subject is forgeable; let the oracle weigh the rung).
255
+ - ❌ Letting the agent stop on an UNWITNESSED / NO_CLAIM effect "because it
256
+ probably worked." Abstain surfaces it; it is never a met effect.
257
+ - ❌ Wiring `dos hook marker` when you mean this gate (or vice versa). Marker
258
+ bounds keep-alive polling; this gate refuses a false done. Opposite triggers.
259
+ - ❌ Naming a specific lane, plan dir, ship prefix, or witness backend as a
260
+ literal — read the active layout from `dos doctor --json` and resolve witnesses
261
+ by name.
262
+
263
+ ## The one rule under this skill
264
+
265
+ "The goal is met" is a **claim with a byte-author**. Let the agent stop only when
266
+ a witness whose byte-author is *not the agent* corroborates every effect the goal
267
+ named. The agent's confidence and its fluent description of success are irrelevant
268
+ to that gate — which is the whole point: the part that decides the goal is done is
269
+ never the part being judged.
@@ -0,0 +1,231 @@
1
+ ---
2
+ name: dos-next-up
3
+ description: 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.
4
+ ---
5
+
6
+ # dos-next-up — the generic plan-and-ship snapshot
7
+
8
+ > **This is the baseline screenplay DOS ships, not a prerequisite.** It drives the
9
+ > kernel syscalls (`verify`, `gate`) against *any* repo whose layout lives in
10
+ > `dos.toml`. It names no host directory, no host lane, and no host commit
11
+ > convention — every host specific comes from `dos doctor --json` (paths/lanes,
12
+ > via WCR) or `dos.toml [stamp]` (the ship grammar, via SCV). Copy it into your
13
+ > own skills dir, point `dos` at your workspace, and it runs.
14
+
15
+ The shape is domain-free: **discover the layout → walk the plans → audit each
16
+ pick against the truth syscall → render a packet → gate the empty case.** The
17
+ *policy* (which lanes, which plan grammar, where output lands) is data the
18
+ screenplay reads, never literals it hardcodes.
19
+
20
+ ## Inputs
21
+
22
+ - `--scope <name>` (repeatable, optional) — narrow candidates to one lane (a
23
+ name from the active `[lanes]` taxonomy) or one plan id. Omitted = all plans.
24
+ - `--limit <N>` (optional, default 5) — how many top picks to render.
25
+
26
+ ## Step 0 — Discover the workspace layout (one call)
27
+
28
+ Run the doctor verb and read the result. **This is the WCR on-ramp: every
29
+ path/lane below comes from here, never a literal.**
30
+
31
+ ```bash
32
+ dos doctor --workspace . --json
33
+ ```
34
+
35
+ Parse the JSON object. The fields you use:
36
+
37
+ - `paths.plans_glob` — the glob to walk for plan docs (whatever the workspace
38
+ declared). **Use this value; never assume a fixed plans directory.**
39
+ - `paths.next_packets` — where the rendered packet is written (the configured
40
+ output dir; `.dos/verdicts` under the generic default).
41
+ - `lanes.concurrent` / `lanes.exclusive` / `lanes.trees` — the active lane
42
+ taxonomy, if you need to group picks by lane or honor a `--scope`.
43
+ - `stamp` — the active ship-subject grammar (informational; `dos verify` applies
44
+ it for you — you never grep subjects yourself).
45
+
46
+ If `git` is `false`, warn the operator: `dos verify`'s git rung has no history to
47
+ read, so every pick will report `source="none"` unless a registry exists.
48
+
49
+ ## Step 1 — Walk the plans glob → candidate picks
50
+
51
+ List the plan docs under `paths.plans_glob` (relative to `paths.root`). For each
52
+ plan doc, read its phase headings to extract `(plan_id, phase_id)` candidate
53
+ pairs — the next not-yet-shipped phases. Keep this generic: a "phase" is a
54
+ heading the doc marks as a unit of work; you do not need the job's exact
55
+ frontmatter. If a `--scope` was given, keep only plans/lanes that match it.
56
+
57
+ Collect a flat list of candidate `(plan, phase)` picks. Do not rank by any
58
+ host-specific signal — order by plan-doc order, then truncate later.
59
+
60
+ ## Step 2 — Audit each candidate against the truth syscall
61
+
62
+ For **each** candidate pick, ask the kernel whether it already shipped — never
63
+ trust the plan doc's own stamp, and never grep commit subjects yourself:
64
+
65
+ ```bash
66
+ dos verify --workspace . <PLAN> <PHASE> --json
67
+ ```
68
+
69
+ Read the `ShipVerdict` JSON: `{shipped, source, sha?, plan, phase}`. `source`
70
+ tells you *how* the kernel knows: `registry` (a ship row), `grep` (a commit
71
+ subject under the active `[stamp]` grammar), or `none` (no positive evidence).
72
+ This is the SCV payoff — a foreign repo whose commits read `AUTH2: …` is
73
+ recognized iff its `dos.toml` declares the matching `[stamp]`.
74
+
75
+ Classify each pick into one of three dispositions — this is what the gate reads:
76
+
77
+ - **`shipped: false, source: "none"`** → **live**: a real next pick. Disposition
78
+ `{phase, live: true}`.
79
+ - **`shipped: true, source: "registry"`** → **done, cleanly**: a ship row exists.
80
+ Disposition `{phase, live: false, drop_reason: "shipped"}` — drop it.
81
+ - **`shipped: true, source: "grep"`** → a real **git ship**. Now check the plan
82
+ doc: does its heading for this phase carry a SHIPPED stamp? If **yes**, drop it
83
+ as a clean ship (as above). If **no**, this is a **stale stamp** — the work
84
+ shipped in git but the plan doc lags — and you must encode it so the gate can
85
+ catch the false-drain: `{phase, live: false, drop_reason: "shipped",
86
+ "ship_via": "direct", "plan_doc_stamped": false}`.
87
+
88
+ The `ship_via: "direct"` + `plan_doc_stamped: false` pair is the *exact* shape
89
+ `dos gate` classifies as STALE-STAMP (a `grep` ship the plan doc doesn't reflect).
90
+ **Do not put verify's `source` value into `ship_via`** — `ship_via` is the gate's
91
+ own direct-ship marker, set to the literal `"direct"` only for an unstamped git
92
+ ship; a `registry` hit is a clean `shipped` drop, never STALE-STAMP.
93
+
94
+ Keep the first `--limit` live picks as the packet's dispatch list.
95
+
96
+ ## Step 3 — Render the dispatch packet
97
+
98
+ Assemble a self-contained markdown packet **yourself** (DOS ships no packet
99
+ template in the kernel — see the friction log: the `[render]` packet-template
100
+ seam is a named open axis). Write it under `paths.next_packets`, named
101
+ `next-up-<UTC-date>-<N>.md`. The packet has, generically:
102
+
103
+ 1. **Header** — the workspace root, the active lane taxonomy, the run timestamp.
104
+ 2. **Portfolio snapshot** — one row per plan: plan id, how many phases, how many
105
+ verified shipped (from Step 2), the next live phase.
106
+ 3. **Dispatch list** — for each live pick, a self-contained prompt another agent
107
+ could be launched with: the plan id, the phase id, the plan-doc path, and the
108
+ one-line goal. Keep each prompt standalone (no shared context).
109
+ 4. **Already shipped** — the picks Step 2 found `shipped: true`, with `source`/`sha`.
110
+
111
+ Alongside the packet, emit the gate sidecar so Step 4 can classify it — write
112
+ `<paths.next_packets>/.dispositions-<tag>.json` with the kernel's contract. One
113
+ entry per pick the packet considered, using the Step-2 classification:
114
+
115
+ ```json
116
+ {
117
+ "schema": "oc3-dispositions-v1",
118
+ "tag": "<tag>",
119
+ "dispositions": [
120
+ {"phase": "AUTH2", "live": true},
121
+ {"phase": "AUTH1", "live": false, "drop_reason": "shipped"},
122
+ {"phase": "AUTH3", "live": false, "drop_reason": "shipped",
123
+ "ship_via": "direct", "plan_doc_stamped": false}
124
+ ]
125
+ }
126
+ ```
127
+
128
+ In this example: `AUTH2` is live (a dispatch-list pick); `AUTH1` is a clean ship
129
+ (verify `source` was `registry`, or `grep` with the plan doc stamped) — a plain
130
+ `shipped` drop; `AUTH3` is a **stale stamp** (verify `source` was `grep` but the
131
+ plan doc is unstamped) — `ship_via: "direct"` + `plan_doc_stamped: false` is what
132
+ makes `dos gate` return STALE-STAMP for it. A clean ship omits both fields (it
133
+ must NOT carry `ship_via: "direct"`, or it would be misread as stale).
134
+
135
+ ## Step 4 — Gate the packet (typed verdict)
136
+
137
+ Classify the packet through the kernel so the outcome is a typed verdict, not a
138
+ prose guess:
139
+
140
+ ```bash
141
+ dos gate --workspace . <paths.next_packets>/.dispositions-<tag>.json
142
+ ```
143
+
144
+ Read the exit code (the verdict IS the code):
145
+
146
+ - `0` **LIVE** — the packet has dispatchable work; report the packet path and the
147
+ dispatch count. This is the success case.
148
+ - `3` **DRAIN** — no live picks: a genuine empty backlog. Report "nothing to
149
+ dispatch — the portfolio is drained."
150
+ - `4` **STALE-STAMP** — phases shipped in git but the plan docs lag. Report the
151
+ drift (the operator should reconcile the stamps); this is NOT an empty backlog.
152
+ - `5` **BLOCKED** — picks exist but are blocked (a sibling claim / quota). Surface.
153
+ - `6` **RACE** — a concurrent render lost a lock race; retry once.
154
+ - `2` — a contract error (the sidecar was malformed). Fix the sidecar; do not
155
+ treat it as DRAIN.
156
+
157
+ ## Step 5 — Return
158
+
159
+ Print the packet path and the gate verdict. **Return the packet path** as the
160
+ final line so a caller (e.g. `dos-dispatch`) can chain it:
161
+
162
+ ```
163
+ Saved: <paths.next_packets>/next-up-<date>-<N>.md (verdict=<VERDICT>)
164
+ ```
165
+
166
+ ## What this skill deliberately does NOT do (no silent gap)
167
+
168
+ - **No soft-claim leasing.** It does not register per-pick soft-claims (the heavy
169
+ lease core stays host-side, `CLAUDE.md` heavy tier). `dos-dispatch` takes a
170
+ *lane* lease via `dos arbitrate`; the per-pick soft-claim is out of scope.
171
+ - **No host evidence sources.** It does not read a host's curated ranking file or
172
+ a postmortem stream — those are host gardening inputs (an evidence-source hook
173
+ is a named open seam). It ranks by plan-doc order, audited by `dos verify`.
174
+ - **No host packet template.** It assembles a generic packet; the exact section
175
+ grammar / commit subject a host wants is the `[render]` template seam (open).
176
+
177
+ **Log the gap, never silently skip it.** The first time the skill would have used
178
+ one of these (a soft-claim, a host evidence source), emit a one-line `log` naming
179
+ what it is not doing and why — so the capability gap is surfaced at runtime, not
180
+ just documented here.
181
+
182
+ ## Worked example (live transcript)
183
+
184
+ > **The shape, run for real against a `dos` workspace.** Copy-pasteable verbs,
185
+ > actual captured output. The whole point is the last gloss on each block:
186
+ > **read the RUNG**, not the bare `shipped` boolean.
187
+
188
+ Step 0 — discover the layout (the WCR on-ramp):
189
+
190
+ ```bash
191
+ $ dos doctor --workspace . --json
192
+ # dos_version 0.22.0; git true; stamp.style "grep" (generic, any/no dir prefix)
193
+ # paths.plans_glob "docs/**/*-plan.md"; paths.next_packets ".dos/verdicts"
194
+ # lanes.concurrent [benchmark, docs, examples, scripts, spikes, src, tests]
195
+ ```
196
+ ↳ every path/lane below is read from this object — never a literal.
197
+
198
+ Step 2 — audit a pick that DID ship. Read the `source` rung, not just `shipped`:
199
+
200
+ ```bash
201
+ $ dos verify --workspace . docs/82_liveness-oracle-plan liveness --json
202
+ {"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"}
203
+ ```
204
+ ↳ RUNG `source="grep-subject"` (NOT bare `grep`): a commit SUBJECT carrying the
205
+ phase token flips this to SHIPPED even if little was built. Read the rung.
206
+
207
+ Step 2 — and a pick that has NOT shipped:
208
+
209
+ ```bash
210
+ $ dos verify --workspace . docs/99_runtime-validation-and-the-actuation-boundary halt --json
211
+ {"phase":"halt","plan":"docs/99_runtime-validation-and-the-actuation-boundary","shipped":false,"source":"none"}
212
+ ```
213
+ ↳ RUNG `source="none"`: no positive git/registry evidence → a live pick.
214
+
215
+ Step 4 — gate the packet; the verdict IS the exit code:
216
+
217
+ ```bash
218
+ $ dos gate --workspace . .dos/verdicts/.dispositions-<tag>.json ; echo "exit=$?"
219
+ exit=0 # LIVE — dispatchable work (3=DRAIN, 4=STALE-STAMP, 5=BLOCKED, 6=RACE, 2=contract-error)
220
+ ```
221
+ ↳ exit-code `0` carried the verdict — LIVE, not a prose guess.
222
+
223
+ ## Anti-patterns
224
+
225
+ - ❌ Hardcoding a plans directory or an output directory — read both from
226
+ `dos doctor --json` (the `paths` object).
227
+ - ❌ Greping commit subjects for a ship marker yourself — call `dos verify` (it
228
+ applies the active `[stamp]` grammar for you).
229
+ - ❌ Treating a 0-pick packet as "drained" without `dos gate` — a STALE-STAMP is a
230
+ false drain, and only the typed gate distinguishes it.
231
+ - ❌ Naming a specific lane as a literal — read the active `lanes` from doctor.
@@ -0,0 +1,114 @@
1
+ ---
2
+ name: dos-promote
3
+ description: The visibility-inverse of lifecycle-demote. Run `dos pickable` over every declared unit; for each HELD unit, surface it with its typed HoldReason and the derived unblock action (DRAFT_CLASS→promote-to-active, UNPARSEABLE→inspect-the-deriver, OPERATOR_GATED→raise-a-decision, SOAK_OPEN→wait, DEPENDENCY_UNMET→ship-the-prerequisite). The only auto-applied action is a safe mechanical reclassify (gated, one commit); everything else is surfaced for a human via `dos decisions`. Every path/lane/class comes from `dos doctor --json`. Use when units are stuck un-pickable and you want each one's typed reason + the right unblock move. The operator-facing half of the shipped `pickable` gate (SKP Axis 5, docs/207 Phase 5b).
4
+ ---
5
+
6
+ # dos-promote — surface every held unit + its unblock action
7
+
8
+ > **Make the invisible pickable.** The picker silently drops a unit it cannot
9
+ > offer; `/dos-promote` does the inverse — it runs the **pre-dispatch gate**
10
+ > (`dos pickable`) over every declared unit, and for each one that is HELD it
11
+ > surfaces the unit, its *typed* hold reason, and the derived unblock action. The
12
+ > hold reason → action routing is data, not a guess: a `DRAFT_CLASS` hold wants a
13
+ > promotion, a `SOAK_OPEN` hold wants the clock, an `OPERATOR_GATED` hold wants a
14
+ > decision. This is the operator-facing half of the shipped `pickable` primitive.
15
+
16
+ The shape: **enumerate the units → gate each → route each hold to its action →
17
+ auto-enact only the safe mechanical reclassify → surface the rest.** The gate and
18
+ the enumeration are kernel verbs (`dos pickable`, `dos enumerate`); the
19
+ reason→action routing is derivable from the `HoldReason` itself.
20
+
21
+ ## Inputs
22
+
23
+ - `--scope <lane>` (optional) — limit to one lane from the active `[lanes]`.
24
+ Omitted = every declared unit the workspace can see.
25
+
26
+ ## Step 0 — Discover the layout
27
+
28
+ ```bash
29
+ dos doctor --workspace . --json
30
+ ```
31
+
32
+ Read `paths.plans_glob` (where the plan docs live), `lanes` (the taxonomy), and
33
+ `lifecycle.classes` (the declared class set — which class is the workspace's
34
+ "draft" / "active"). **Use these; never hardcode a plan path or a class name.**
35
+
36
+ ## Step 1 — Enumerate the declared units
37
+
38
+ For each plan doc under `paths.plans_glob`, enumerate the units it declares:
39
+
40
+ ```bash
41
+ dos enumerate <plan-doc> --json
42
+ ```
43
+
44
+ Read `units` (the universe), `remaining` (the not-yet-shipped), and `drift` — a
45
+ `drift[kind=unparseable]` is itself a held-by-UNPARSEABLE signal (the
46
+ picker-invisibility cure: a typed refusal, never a silent drop). Collect the
47
+ remaining units across all plans as the candidate set.
48
+
49
+ ## Step 2 — Gate each candidate (the pre-dispatch verdict)
50
+
51
+ For each remaining unit, run the pre-dispatch gate over the unit's host-gathered
52
+ state (its plan class, soak index, live claims):
53
+
54
+ ```bash
55
+ dos pickable <UNIT> --state '<json>' --json
56
+ ```
57
+
58
+ Branch on the exit code (the verdict IS the code — distinct per hold):
59
+
60
+ - `0` **OFFERABLE** → a worker could pick it up now; NOT surfaced (it is not stuck).
61
+ - `10` **DRAFT_CLASS** → the plan is draft-class; the unblock is a **promotion**.
62
+ - `11` **OPERATOR_GATED** → blocked on a decision; raise it.
63
+ - `12` **SOAK_OPEN** → a soak deadline; **wait** (never promote — time un-gates it).
64
+ - `13` **DEPENDENCY_UNMET** → ship the prerequisite first.
65
+ - `24` **UNPARSEABLE** → inspect/fix the deriver or the doc; the unit is invisible.
66
+ - `20`–`23` **IN_FLIGHT / SOFT_CLAIMED / STALE_CLAIM / COOLDOWN** → a live/transient
67
+ hold that clears on its own; surface as info, no action.
68
+
69
+ ## Step 3 — Route each hold to its unblock action (data, not a guess)
70
+
71
+ The action is derived from the typed `HoldReason`, not re-discovered per unit:
72
+
73
+ | Hold | Unblock action |
74
+ |---|---|
75
+ | `DRAFT_CLASS` | promote the plan draft→active (the workspace's `lifecycle` default→next class) |
76
+ | `OPERATOR_GATED` | raise an operator decision (`dos decisions add`) |
77
+ | `SOAK_OPEN` | wait for the soak to close — surface the deadline, do NOT promote |
78
+ | `DEPENDENCY_UNMET` | ship the named prerequisite first |
79
+ | `UNPARSEABLE` | inspect the deriver / backfill the doc's phase grammar |
80
+
81
+ A host may declare a richer reason→action map in `dos.toml`; absent one, this
82
+ default routing (documented on the `HoldReason` enum) is used.
83
+
84
+ ## Step 4 — Auto-enact ONLY the safe mechanical reclassify
85
+
86
+ The single auto-applied action is the **DRAFT→active promotion** of a plan whose
87
+ draft phases are demonstrably wanted — a mechanical plan-meta `classification:`
88
+ edit + ONE commit, gated. Read the trunk + ship grammar from `dos doctor --json`'s
89
+ `stamp`; **do not hardcode a commit prefix.** Everything else — a decision, a
90
+ soak wait, a dependency, an unparseable doc — is surfaced for a human, never
91
+ auto-applied (those are real judgment calls).
92
+
93
+ ## Step 5 — Surface the rest
94
+
95
+ ```bash
96
+ dos decisions add # one row per held unit that needs a human
97
+ ```
98
+
99
+ ## What this skill deliberately does NOT do (no silent gap)
100
+
101
+ - **No auto-decision / auto-dependency-ship.** Only the mechanical reclassify is
102
+ auto; an OPERATOR_GATED / DEPENDENCY_UNMET hold is a human's call.
103
+ - **No soak fast-forward.** A SOAK_OPEN hold is surfaced with its deadline; the
104
+ loop NEVER promotes past a soak (time is the only thing that un-gates it).
105
+ - **No host class taxonomy.** The draft/active classes come from
106
+ `lifecycle.classes`; a 2-class repo and a job-shaped repo both run this skill.
107
+
108
+ ## Anti-patterns
109
+
110
+ - ❌ Promoting a SOAK_OPEN unit — a soak is un-gated by the clock, not a promotion;
111
+ promoting it re-introduces the very drain-trap the typed hold prevents.
112
+ - ❌ Auto-resolving an OPERATOR_GATED hold — that decision is the operator's.
113
+ - ❌ Hardcoding "DRAFT"/"ACTIVE" — read the class set from `dos doctor --json`'s
114
+ `lifecycle.classes`.