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
dos/fleet_roll.py ADDED
@@ -0,0 +1,226 @@
1
+ """fleet-roll — fold a whole `root_id` tree of run digests into ONE fleet verdict (docs/179 #3).
2
+
3
+ > **An HONEST AGGREGATOR, not a label factory.** It folds N per-run `StatusDigest`s
4
+ > (each already adjudicated, docs/120) into one fleet headline + a per-branch
5
+ > breakdown. It mints ZERO new ground-truth labels — every digest it folds was
6
+ > already computable by `dos status <run_id>`; this batches them into one operator
7
+ > call. That honesty is load-bearing: re-counting the N already-adjudicated digests
8
+ > as "N new labels" would be the consistency-not-grounding sin (docs/179's design
9
+ > law). The data-multiplier in the docs/179 set is `firing_label`, not this.**
10
+
11
+ What it IS: the missing cross-run fold (docs/120 Phase 2-4 — no verb folds N runs
12
+ into one `FleetState` today). A fan-out spawns many runs under one `root_id` (the
13
+ `run_id` spine's tree). An operator wants one answer — "of the 12 runs under this
14
+ root, 9 COMPLETE, 2 SPINNING, 1 DIVERGED; the failing branch is run X under parent
15
+ Y" — instead of 12 separate `dos status` calls. This is that fold.
16
+
17
+ Two honest design constraints the review pinned, both obeyed here:
18
+
19
+ 1. **Two disjoint enums must collapse to ONE FleetState before folding.** A digest
20
+ carries a `liveness` (`Liveness`: ADVANCING/SPINNING/STALLED) AND a `resume`
21
+ (`Resume`: RESUMABLE/COMPLETE/DIVERGED/UNRESUMABLE, None while live). The
22
+ worst-first rollup (`verdict_rollup`) ranks ONE status vocabulary, so each
23
+ digest is collapsed to a single `FleetState` string FIRST (`fleet_state_of`),
24
+ governed by the terminal `resume` verdict when the run has stopped, else by the
25
+ live `liveness`. `verdict_rollup` then contributes only the worst-first `min`
26
+ and the counts string — it interprets no status semantics.
27
+
28
+ 2. **Spawn-lineage ≠ logical dependency (the docs/179 corollary).** `parent_id` is
29
+ the run that SPAWNED this one (a process edge), NOT "this run depends on that
30
+ one." So the per-branch breakdown groups by spawn-parent for DISPLAY/attribution
31
+ only ("which subtree is failing") — it NEVER gates a refusal or deprioritizes a
32
+ lane on the strength of a parent→child edge. A failing child does not condemn its
33
+ parent; the grouping is a lens, not a dependency verdict.
34
+
35
+ The I/O is the CALLER'S (the docs/179 review's corrected cost model): gathering the
36
+ N digests is N+1 `build_trace`-class reads + N liveness/resume evidence gathers at
37
+ the CLI boundary — `trace.build_trace(root).descendants` returns run_id STRINGS, not
38
+ digests, so the boundary must build a digest per descendant. `fleet_roll` itself is
39
+ PURE: digests in, `FleetRoll` out, zero I/O — the `status.status_digest` /
40
+ `verdict_rollup.rollup` posture.
41
+
42
+ ⚓ Kernel discipline (the litmus): PURE Layer-1 leaf — imports only sibling kernel
43
+ modules (`status`, `verdict_rollup`) + stdlib, names no host/driver, carries no
44
+ policy (the severity order is a module constant, the closed-enum-as-data seam).
45
+ """
46
+
47
+ from __future__ import annotations
48
+
49
+ from dataclasses import dataclass
50
+ from typing import Optional
51
+
52
+ from dos.status import StatusDigest
53
+ from dos.verdict_rollup import StatusRank, VerdictRollup, rollup
54
+
55
+ # The durable_schema floor (docs/116 §6): a FleetRoll is a record a dashboard / peer
56
+ # reads, so it carries a schema tag.
57
+ FLEET_ROLL_SCHEMA = 1
58
+
59
+
60
+ # ---------------------------------------------------------------------------
61
+ # The collapsed FleetState — the ONE worst-first vocabulary the rollup ranks.
62
+ # Smaller rank == more severe (the `verdict_rollup.StatusRank` convention: the worst
63
+ # is the `min`). The order interleaves the two source enums by operator severity.
64
+ # ---------------------------------------------------------------------------
65
+ DIVERGED = "DIVERGED" # resume: ground truth moved past the resume point — needs a human
66
+ STALLED = "STALLED" # liveness: no heartbeat, no commits — dead/hung
67
+ UNRESUMABLE = "UNRESUMABLE" # resume: no intent / corrupt / too-new — cannot recover
68
+ SPINNING = "SPINNING" # liveness: alive but state not moving
69
+ RESUMABLE = "RESUMABLE" # resume: clean resume-point + residual — continue from here
70
+ ADVANCING = "ADVANCING" # liveness: ground-truth state moved — healthy, in flight
71
+ COMPLETE = "COMPLETE" # resume: every declared step verified — done
72
+ UNKNOWN = "UNKNOWN" # a malformed/unreadable digest — refuse, don't optimism
73
+
74
+ # Worst-first severity order (smaller = worse). The fold's headline is the worst
75
+ # FleetState across the tree, so a single DIVERGED branch dominates a sea of COMPLETE.
76
+ # COMPLETE is the LEAST-severe (highest rank) — `verdict_rollup.all_clean` treats the
77
+ # max-rank status as "nothing to act on", so a fleet is clean iff every run COMPLETE.
78
+ # UNKNOWN (a malformed/unreadable digest) is a genuine problem and ranks SEVERE
79
+ # (just below DIVERGED), never "clean" — an unreadable run is not a finished run.
80
+ _FLEET_ORDER = {
81
+ DIVERGED: 0,
82
+ UNKNOWN: 1,
83
+ STALLED: 2,
84
+ UNRESUMABLE: 3,
85
+ SPINNING: 4,
86
+ RESUMABLE: 5,
87
+ ADVANCING: 6,
88
+ COMPLETE: 7,
89
+ }
90
+
91
+ # The rank handed to `verdict_rollup`: UNKNOWN is both the unrankable fallback and
92
+ # the "requested but absent" status (a descendant we expected but got no digest for).
93
+ FLEET_RANK = StatusRank(order=_FLEET_ORDER, unknown_status=UNKNOWN, absent_status=UNKNOWN)
94
+
95
+
96
+ def fleet_state_of(digest: StatusDigest) -> str:
97
+ """Collapse one digest's two disjoint verdicts to a single FleetState string. PURE.
98
+
99
+ A STOPPED run (it has a `resume` verdict) is governed by that terminal verdict —
100
+ the resume verdict is the run's last word (COMPLETE/DIVERGED/RESUMABLE/UNRESUMABLE).
101
+ A LIVE run (resume is None) is governed by its `liveness` (ADVANCING/SPINNING/
102
+ STALLED). A digest whose verdict value is outside the known set degrades to
103
+ UNKNOWN (the fail-safe — an unranked status never masquerades as the worst).
104
+ """
105
+ if digest.resume is not None:
106
+ val = digest.resume.verdict.value
107
+ return val if val in _FLEET_ORDER else UNKNOWN
108
+ val = digest.liveness.verdict.value
109
+ return val if val in _FLEET_ORDER else UNKNOWN
110
+
111
+
112
+ # ---------------------------------------------------------------------------
113
+ # The per-branch breakdown + the fleet roll.
114
+ # ---------------------------------------------------------------------------
115
+ @dataclass(frozen=True)
116
+ class BranchRoll:
117
+ """One spawn-subtree's roll — the runs grouped under one spawn-parent (DISPLAY only).
118
+
119
+ `parent_id` is the spawn edge the runs share (NOT a dependency edge — docs/179
120
+ corollary). `subtree` is the worst-first rollup over that branch's FleetStates.
121
+ The attribution ("which subtree is failing") is a lens for the operator, never a
122
+ condemnation of the parent.
123
+ """
124
+
125
+ parent_id: str
126
+ subtree: VerdictRollup
127
+
128
+ @property
129
+ def worst_status(self) -> Optional[str]:
130
+ return self.subtree.worst_status
131
+
132
+ def to_dict(self) -> dict:
133
+ return {"parent_id": self.parent_id, "subtree": self.subtree.to_dict()}
134
+
135
+
136
+ @dataclass(frozen=True)
137
+ class FleetRoll:
138
+ """The whole `root_id` tree folded into one fleet verdict + per-branch breakdown.
139
+
140
+ `root_id` names the tree. `rollup` is the worst-first fold over EVERY run's
141
+ FleetState (the headline + counts). `branches` is the per-spawn-parent breakdown
142
+ (display attribution). `absent` lists descendants that were expected (in the
143
+ lineage) but produced no digest — surfaced as a first-class UNKNOWN, never a
144
+ silently-dropped row (the `verdict_rollup` anti-drift feature).
145
+ """
146
+
147
+ root_id: str
148
+ rollup: VerdictRollup
149
+ branches: tuple[BranchRoll, ...] = ()
150
+ absent: tuple[str, ...] = ()
151
+ schema: int = FLEET_ROLL_SCHEMA
152
+
153
+ @property
154
+ def worst_status(self) -> Optional[str]:
155
+ """The single most-severe FleetState across the whole tree."""
156
+ return self.rollup.worst_status
157
+
158
+ @property
159
+ def all_clean(self) -> bool:
160
+ """True iff every run is COMPLETE (the least-severe rank) — nothing to act on."""
161
+ return self.rollup.all_clean
162
+
163
+ def to_dict(self) -> dict:
164
+ return {
165
+ "schema": self.schema,
166
+ "root_id": self.root_id,
167
+ "worst_status": self.worst_status,
168
+ "all_clean": self.all_clean,
169
+ "reason": self.rollup.reason,
170
+ "rollup": self.rollup.to_dict(),
171
+ "branches": [b.to_dict() for b in self.branches],
172
+ "absent": list(self.absent),
173
+ }
174
+
175
+
176
+ def _item(digest: StatusDigest):
177
+ """A rollup item dict for one digest — its run_id keyed to its FleetState. PURE."""
178
+ return {
179
+ "key": digest.run_id,
180
+ "status": fleet_state_of(digest),
181
+ "reason": digest.liveness.reason if digest.resume is None else digest.resume.reason,
182
+ }
183
+
184
+
185
+ def fleet_roll(
186
+ digests,
187
+ *,
188
+ root_id: str = "",
189
+ parent_of=None,
190
+ absent=None,
191
+ ) -> FleetRoll:
192
+ """Fold a tree of run digests into one fleet verdict + per-branch breakdown. PURE.
193
+
194
+ `digests` is any iterable of `StatusDigest` (gathered at the caller boundary, one
195
+ per run in the tree). `root_id` names the tree (display). `parent_of` is an
196
+ optional `run_id -> parent_id` map for the per-branch grouping (the spawn edge,
197
+ display attribution only); when absent, no branch breakdown is produced (the
198
+ top-level rollup still folds every run). `absent` is the run_ids that were in the
199
+ lineage but produced no digest — surfaced as first-class UNKNOWN rows.
200
+
201
+ Returns a `FleetRoll` whose top `rollup` is the worst-first fold over every run's
202
+ FleetState. No I/O: the digests + the parent map are pre-gathered, the
203
+ `verdict_rollup.rollup` / `status` posture.
204
+ """
205
+ digests = list(digests)
206
+ absent = list(absent or ())
207
+ items = [_item(d) for d in digests]
208
+
209
+ top = rollup(items, rank=FLEET_RANK, label=f"fleet:{root_id or '?'}", absent=absent)
210
+
211
+ branches: list[BranchRoll] = []
212
+ if parent_of is not None:
213
+ by_parent: dict[str, list[dict]] = {}
214
+ for d in digests:
215
+ pid = str(parent_of(d.run_id) or "")
216
+ by_parent.setdefault(pid, []).append(_item(d))
217
+ for pid in sorted(by_parent):
218
+ sub = rollup(by_parent[pid], rank=FLEET_RANK, label=f"branch:{pid or '(root)'}")
219
+ branches.append(BranchRoll(parent_id=pid, subtree=sub))
220
+
221
+ return FleetRoll(
222
+ root_id=root_id,
223
+ rollup=top,
224
+ branches=tuple(branches),
225
+ absent=tuple(absent),
226
+ )