dos-kernel 0.28.0__tar.gz → 0.29.0__tar.gz

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 (639) hide show
  1. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/PKG-INFO +17 -2
  2. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/README.md +16 -1
  3. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/pyproject.toml +1 -1
  4. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/__init__.py +1 -1
  5. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/account_auth.py +30 -0
  6. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/admission.py +27 -20
  7. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/answer_shape.py +100 -5
  8. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/arbiter.py +41 -30
  9. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/cli.py +930 -225
  10. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/config.py +26 -27
  11. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/account_switcher.py +210 -0
  12. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/hook_dialects.py +13 -0
  13. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/notify_slack.py +22 -3
  14. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/notify_webhook.py +7 -0
  15. dos_kernel-0.29.0/src/dos/drivers/sealed_acceptance.py +307 -0
  16. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/supervisor.py +79 -20
  17. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/hook_install.py +49 -0
  18. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lane_lease.py +8 -0
  19. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lane_overlap.py +7 -1
  20. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lock_modes.py +1 -1
  21. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/native_canonical.py +12 -0
  22. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/notify.py +83 -3
  23. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/overlap_policy.py +104 -8
  24. dos_kernel-0.29.0/src/dos/rotation_handoff.py +230 -0
  25. dos_kernel-0.29.0/src/dos/salience.py +537 -0
  26. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/EXAMPLES.md +2 -2
  27. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-class-cycle/SKILL.md +1 -1
  28. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-dispatch/SKILL.md +2 -2
  29. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-dispatch-loop/SKILL.md +1 -1
  30. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-enforce-tune/SKILL.md +1 -1
  31. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-goal-fleet/SKILL.md +37 -18
  32. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-goal-gate/SKILL.md +1 -1
  33. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-next-up/SKILL.md +2 -2
  34. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-plan-price/SKILL.md +1 -1
  35. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-promote/SKILL.md +1 -1
  36. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-replan/SKILL.md +1 -1
  37. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-replan-loop/SKILL.md +1 -1
  38. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-self-improve/SKILL.md +1 -1
  39. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-skillify/SKILL.md +1 -1
  40. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-supervise-loop/SKILL.md +1 -1
  41. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-unstick/SKILL.md +1 -1
  42. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skills/dos-witness-claim/SKILL.md +1 -1
  43. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/stamp.py +121 -0
  44. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/supervise.py +67 -25
  45. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_kernel.egg-info/PKG-INFO +17 -2
  46. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_kernel.egg-info/SOURCES.txt +9 -0
  47. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_mcp/server.py +73 -11
  48. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_account_auth.py +36 -0
  49. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_account_ledger.py +39 -1
  50. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_account_switcher.py +139 -0
  51. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_answer_shape.py +211 -0
  52. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_arbiter.py +51 -0
  53. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_burn_in_farm_playbook.py +6 -3
  54. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cleanup_sweep.py +41 -2
  55. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cli_ergonomics.py +11 -5
  56. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cli_loop.py +122 -4
  57. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_doctor_json.py +5 -0
  58. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drivers_supervisor.py +108 -20
  59. dos_kernel-0.29.0/tests/test_go_account_parity.py +43 -0
  60. dos_kernel-0.29.0/tests/test_init_default_on.py +186 -0
  61. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_init_hooks_auto.py +25 -1
  62. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_init_hooks_crossvendor.py +40 -4
  63. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_mcp_server.py +15 -3
  64. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_native_canonical.py +30 -11
  65. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_notify.py +57 -0
  66. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_notify_cli.py +78 -2
  67. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_notify_slack.py +22 -2
  68. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_notify_webhook.py +20 -1
  69. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_overlap_policy.py +42 -17
  70. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_plugin_manifest.py +90 -17
  71. dos_kernel-0.29.0/tests/test_proc_reaper.py +219 -0
  72. dos_kernel-0.29.0/tests/test_rotation_handoff.py +127 -0
  73. dos_kernel-0.29.0/tests/test_salience.py +445 -0
  74. dos_kernel-0.29.0/tests/test_sealed_acceptance.py +276 -0
  75. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_session_digest.py +36 -0
  76. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stamp_doctor.py +176 -0
  77. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_supervise.py +36 -2
  78. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_vendor_agnostic_kernel.py +4 -4
  79. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/LICENSE +0 -0
  80. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/setup.cfg +0 -0
  81. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/_demo_story.py +0 -0
  82. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/_filelock.py +0 -0
  83. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/_job_policy.py +0 -0
  84. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/_tree.py +0 -0
  85. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/account_ledger.py +0 -0
  86. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/apply_gate.py +0 -0
  87. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/archive_lock.py +0 -0
  88. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/arg_provenance.py +0 -0
  89. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/attest.py +0 -0
  90. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/breaker.py +0 -0
  91. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/call_shape.py +0 -0
  92. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/chat_control.py +0 -0
  93. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/child_refusals.py +0 -0
  94. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/churn.py +0 -0
  95. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/claim_extract.py +0 -0
  96. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/claim_ttl.py +0 -0
  97. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/commit_audit.py +0 -0
  98. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/completion.py +0 -0
  99. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/concurrency_class.py +0 -0
  100. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/config_lint.py +0 -0
  101. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/cooldown.py +0 -0
  102. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/coverage.py +0 -0
  103. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/dangling_intent.py +0 -0
  104. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/data_class.py +0 -0
  105. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/decisions.py +0 -0
  106. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/decisions_tui.py +0 -0
  107. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/deprecation.py +0 -0
  108. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/dispatch_top.py +0 -0
  109. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/dispatch_top_tui.py +0 -0
  110. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/__init__.py +0 -0
  111. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/_effect_gate.py +0 -0
  112. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/agent_auth/__init__.py +0 -0
  113. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/agent_auth/claude.py +0 -0
  114. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/agent_auth/codex.py +0 -0
  115. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/agent_auth/gemini.py +0 -0
  116. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/agt_backend.py +0 -0
  117. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/ci_status.py +0 -0
  118. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/citation_resolve.py +0 -0
  119. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/content_diff.py +0 -0
  120. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/crewai_guardrail.py +0 -0
  121. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/decision_stop.py +0 -0
  122. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/design_doc_plan.py +0 -0
  123. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/enforce_tune.py +0 -0
  124. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/export_file.py +0 -0
  125. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/export_otlp.py +0 -0
  126. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/export_statsd.py +0 -0
  127. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/fs_artifact.py +0 -0
  128. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/http_probe.py +0 -0
  129. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/job.py +0 -0
  130. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/llm_judge.py +0 -0
  131. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/memory_mem0.py +0 -0
  132. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/memory_recall.py +0 -0
  133. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/merge_gate.py +0 -0
  134. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/model_reroute.py +0 -0
  135. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/nemo_action.py +0 -0
  136. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/notify_whatsapp.py +0 -0
  137. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/openai_agents_guardrail.py +0 -0
  138. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/operator_judge.py +0 -0
  139. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/os_acceptance.py +0 -0
  140. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/os_process.py +0 -0
  141. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/paste_log.py +0 -0
  142. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/plan_scope.py +0 -0
  143. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/pre_commit.py +0 -0
  144. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/provider_ledger.py +0 -0
  145. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/self_improve.py +0 -0
  146. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/similarity_judge.py +0 -0
  147. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/slack_approval.py +0 -0
  148. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/state_diff.py +0 -0
  149. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/visual_witness.py +0 -0
  150. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/watchdog.py +0 -0
  151. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/whatsapp_bridge.py +0 -0
  152. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/witnessed_leak_test.py +0 -0
  153. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers/workshop.py +0 -0
  154. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/drivers_seam.py +0 -0
  155. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/durable_schema.py +0 -0
  156. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/effect_kind.py +0 -0
  157. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/effect_witness.py +0 -0
  158. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/efficiency.py +0 -0
  159. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/efficiency_advice.py +0 -0
  160. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/efficiency_trend.py +0 -0
  161. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/enforce.py +0 -0
  162. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/enforce_outcomes.py +0 -0
  163. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/enumerate.py +0 -0
  164. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/env_print.py +0 -0
  165. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/event_severity.py +0 -0
  166. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/evidence.py +0 -0
  167. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/exec_capability.py +0 -0
  168. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/export_cursor.py +0 -0
  169. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/exporter.py +0 -0
  170. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/firing_label.py +0 -0
  171. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/fleet_roll.py +0 -0
  172. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/freshness.py +0 -0
  173. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/gate_classify.py +0 -0
  174. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/gh4_coverage.py +0 -0
  175. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/git_delta.py +0 -0
  176. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/guard.py +0 -0
  177. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/health.py +0 -0
  178. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/help_summary.py +0 -0
  179. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/home.py +0 -0
  180. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/hook_binary.py +0 -0
  181. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/hook_dialect.py +0 -0
  182. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/hook_exit.py +0 -0
  183. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/hook_observation.py +0 -0
  184. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/id_alloc.py +0 -0
  185. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/improve.py +0 -0
  186. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/intent_ledger.py +0 -0
  187. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/interpret.py +0 -0
  188. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/intervention.py +0 -0
  189. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/intervention_eval.py +0 -0
  190. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/journal_delta.py +0 -0
  191. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/judge_eval.py +0 -0
  192. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/judges.py +0 -0
  193. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lane_infer.py +0 -0
  194. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lane_journal.py +0 -0
  195. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lease_health.py +0 -0
  196. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/lifecycle.py +0 -0
  197. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/liveness.py +0 -0
  198. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/log_source.py +0 -0
  199. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/loop_decide.py +0 -0
  200. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/loop_trace.py +0 -0
  201. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/marker_gate.py +0 -0
  202. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/marker_sensor.py +0 -0
  203. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/memory_stores.py +0 -0
  204. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/mergegate.py +0 -0
  205. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/model_call.py +0 -0
  206. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/model_health.py +0 -0
  207. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/named_lock.py +0 -0
  208. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/noop_streak.py +0 -0
  209. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/observe.py +0 -0
  210. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/oracle.py +0 -0
  211. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/overlap_eval.py +0 -0
  212. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/override_facts.py +0 -0
  213. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/packet_sidecar.py +0 -0
  214. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/phase_shipped.py +0 -0
  215. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/pick_priority.py +0 -0
  216. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/pickable.py +0 -0
  217. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/picker_oracle.py +0 -0
  218. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/plan_board.py +0 -0
  219. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/plan_board_tui.py +0 -0
  220. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/plan_source.py +0 -0
  221. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/plugins.py +0 -0
  222. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/posttool_sensor.py +0 -0
  223. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/precursor_gate.py +0 -0
  224. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/precursor_gate_eval.py +0 -0
  225. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/preflight.py +0 -0
  226. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/pretool_sensor.py +0 -0
  227. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/proc_delta.py +0 -0
  228. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/productivity.py +0 -0
  229. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/provider_limit.py +0 -0
  230. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/pulse.py +0 -0
  231. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/py.typed +0 -0
  232. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/queue_saturation.py +0 -0
  233. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/reason_morphology.py +0 -0
  234. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/reasons.py +0 -0
  235. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/reconcile.py +0 -0
  236. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/recurring_wedge.py +0 -0
  237. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/render.py +0 -0
  238. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/residual_review.py +0 -0
  239. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/result_state.py +0 -0
  240. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/resume.py +0 -0
  241. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/resume_evidence.py +0 -0
  242. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/retention.py +0 -0
  243. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/retire.py +0 -0
  244. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/reward.py +0 -0
  245. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/rewind.py +0 -0
  246. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/rewind_evidence.py +0 -0
  247. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/rewind_tokens.py +0 -0
  248. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/run_id.py +0 -0
  249. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/rung_occupancy.py +0 -0
  250. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/scope.py +0 -0
  251. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/scope_source.py +0 -0
  252. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/scout.py +0 -0
  253. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/self_modify.py +0 -0
  254. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/session_digest.py +0 -0
  255. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/sibling_scan.py +0 -0
  256. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/skill_grade.py +0 -0
  257. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/spend.py +0 -0
  258. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/state_health.py +0 -0
  259. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/status.py +0 -0
  260. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/stop_failure_sensor.py +0 -0
  261. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/stop_policy.py +0 -0
  262. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/testing/__init__.py +0 -0
  263. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/testing/doubles.py +0 -0
  264. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/testing/suite.py +0 -0
  265. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/testing/tester.py +0 -0
  266. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/testwitness.py +0 -0
  267. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/timeline.py +0 -0
  268. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/tokens.py +0 -0
  269. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/tool_stream.py +0 -0
  270. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/tool_stream_eval.py +0 -0
  271. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/tool_trace.py +0 -0
  272. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/trace.py +0 -0
  273. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/transcript_view.py +0 -0
  274. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/vcs.py +0 -0
  275. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verdict.py +0 -0
  276. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verdict_census.py +0 -0
  277. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verdict_cli.py +0 -0
  278. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verdict_journal.py +0 -0
  279. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verdict_rollup.py +0 -0
  280. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verdicts.py +0 -0
  281. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/verified.py +0 -0
  282. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/wedge_reason.py +0 -0
  283. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos/work_account.py +0 -0
  284. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_kernel.egg-info/dependency_links.txt +0 -0
  285. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_kernel.egg-info/entry_points.txt +0 -0
  286. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_kernel.egg-info/requires.txt +0 -0
  287. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_kernel.egg-info/top_level.txt +0 -0
  288. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_mcp/__init__.py +0 -0
  289. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_mcp/answers.py +0 -0
  290. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/src/dos_mcp/py.typed +0 -0
  291. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_accounts_cli.py +0 -0
  292. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_admission.py +0 -0
  293. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_aeo_tracker.py +0 -0
  294. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_agent_kind_config.py +0 -0
  295. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_agent_surface.py +0 -0
  296. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_agenthallu_replay.py +0 -0
  297. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_agentprocessbench_replay.py +0 -0
  298. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_agt_backend.py +0 -0
  299. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_answers.py +0 -0
  300. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_answers_index.py +0 -0
  301. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_apply_cli.py +0 -0
  302. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_apply_gate.py +0 -0
  303. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_apply_gate_fence.py +0 -0
  304. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_archive_lock.py +0 -0
  305. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_arg_provenance.py +0 -0
  306. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_attest.py +0 -0
  307. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_backflow_ledger.py +0 -0
  308. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_backlog_triage.py +0 -0
  309. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_beat_cli.py +0 -0
  310. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_bench_layering.py +0 -0
  311. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_braintrust_scorer_example.py +0 -0
  312. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_breaker.py +0 -0
  313. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_build_scoreboard_pages.py +0 -0
  314. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_build_skill_dos_page.py +0 -0
  315. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_build_wheels_binary_format.py +0 -0
  316. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_call_shape.py +0 -0
  317. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_canonical_example_lockstep.py +0 -0
  318. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_caught_lie_cast.py +0 -0
  319. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_central_index.py +0 -0
  320. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_chat_control.py +0 -0
  321. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_check_published_site.py +0 -0
  322. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_child_refusals.py +0 -0
  323. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_churn.py +0 -0
  324. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_ci_status.py +0 -0
  325. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_citation_resolve.py +0 -0
  326. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_claim_extract.py +0 -0
  327. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_claim_ttl.py +0 -0
  328. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_claims_lint.py +0 -0
  329. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cli_completion_verb.py +0 -0
  330. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cli_enforce_tune.py +0 -0
  331. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cli_pickable_enumerate.py +0 -0
  332. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cli_witness.py +0 -0
  333. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_clobber_demo_contract.py +0 -0
  334. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cmd_status.py +0 -0
  335. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_commit_audit.py +0 -0
  336. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_completion.py +0 -0
  337. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_concurrency_class.py +0 -0
  338. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_config_lint.py +0 -0
  339. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_conformance_plugin_examples.py +0 -0
  340. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_conformance_suite.py +0 -0
  341. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_content_diff.py +0 -0
  342. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cooldown.py +0 -0
  343. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_coverage.py +0 -0
  344. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_crewai_guardrail.py +0 -0
  345. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_cross_host_continuity.py +0 -0
  346. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dangling_intent.py +0 -0
  347. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_data_class.py +0 -0
  348. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_decisions.py +0 -0
  349. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_deprecation.py +0 -0
  350. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_design_doc_plan_source.py +0 -0
  351. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dev_runner.py +0 -0
  352. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_discoverability_inventory.py +0 -0
  353. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dispatch_loop_substrate.py +0 -0
  354. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dispatch_top.py +0 -0
  355. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_docs_links.py +0 -0
  356. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_docs_version_drift.py +0 -0
  357. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dogfood_goal_gate.py +0 -0
  358. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dos_market.py +0 -0
  359. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_dos_react_terminal_error.py +0 -0
  360. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drift_scoreboard.py +0 -0
  361. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drivers_merge_gate.py +0 -0
  362. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drivers_seam.py +0 -0
  363. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drivers_self_improve.py +0 -0
  364. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drivers_watchdog.py +0 -0
  365. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_drivers_workshop.py +0 -0
  366. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_duplicate_plan_numbers.py +0 -0
  367. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_durable_schema.py +0 -0
  368. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_effect_gate.py +0 -0
  369. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_effect_kind_axis.py +0 -0
  370. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_effect_witness.py +0 -0
  371. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_efficiency.py +0 -0
  372. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_efficiency_advice.py +0 -0
  373. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_efficiency_trend.py +0 -0
  374. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_efficiency_trend_cli.py +0 -0
  375. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_enforce.py +0 -0
  376. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_enforce_outcomes.py +0 -0
  377. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_enforce_tune_driver.py +0 -0
  378. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_ensure_home.py +0 -0
  379. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_enterpriseops_harness.py +0 -0
  380. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_enumerate.py +0 -0
  381. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_env_print.py +0 -0
  382. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_event_severity.py +0 -0
  383. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_evidence.py +0 -0
  384. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_exec_capability.py +0 -0
  385. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_export_cli.py +0 -0
  386. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_export_cursor.py +0 -0
  387. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_export_otlp.py +0 -0
  388. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_export_statsd.py +0 -0
  389. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_exporter.py +0 -0
  390. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_fault_injection_journal.py +0 -0
  391. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_feasibility_split.py +0 -0
  392. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_filelock.py +0 -0
  393. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_filepath_backstop_batch.py +0 -0
  394. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_firing_label.py +0 -0
  395. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_fleet_framework_examples.py +0 -0
  396. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_fleet_roll.py +0 -0
  397. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_forge_arena_bench.py +0 -0
  398. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_forge_page.py +0 -0
  399. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_freshness.py +0 -0
  400. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_fs_artifact.py +0 -0
  401. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_gate_cli.py +0 -0
  402. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_gemini_extension.py +0 -0
  403. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_gh4_coverage.py +0 -0
  404. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_git_cleanup.py +0 -0
  405. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_git_hygiene.py +0 -0
  406. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_gitignore_hygiene.py +0 -0
  407. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_gitlab_ci_template.py +0 -0
  408. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_gitlab_component.py +0 -0
  409. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_go_hook_parity.py +0 -0
  410. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_guard.py +0 -0
  411. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_health.py +0 -0
  412. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_heartbeats_config.py +0 -0
  413. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_help_summary.py +0 -0
  414. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hermes_integration_example.py +0 -0
  415. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_home_layering.py +0 -0
  416. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_home_no_temp_pollution.py +0 -0
  417. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_ask_posture.py +0 -0
  418. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_assist_posture.py +0 -0
  419. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_binaries_bundled.py +0 -0
  420. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_binary_locator.py +0 -0
  421. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_dialect.py +0 -0
  422. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_exit.py +0 -0
  423. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_observation.py +0 -0
  424. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_pretool.py +0 -0
  425. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hook_stop.py +0 -0
  426. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_hosts_verb.py +0 -0
  427. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_http_probe.py +0 -0
  428. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_id_alloc.py +0 -0
  429. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_improve.py +0 -0
  430. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_init_hooks.py +0 -0
  431. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_init_posture.py +0 -0
  432. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_init_skills.py +0 -0
  433. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_install_drift.py +0 -0
  434. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_install_levels.py +0 -0
  435. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_intent_ledger.py +0 -0
  436. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_interpret_parity.py +0 -0
  437. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_intervention.py +0 -0
  438. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_intervention_cli.py +0 -0
  439. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_intervention_eval.py +0 -0
  440. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_journal_delta.py +0 -0
  441. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_judge.py +0 -0
  442. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_judge_eval.py +0 -0
  443. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_judges.py +0 -0
  444. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_kernel_charts.py +0 -0
  445. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_kernel_keep_gate_example.py +0 -0
  446. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_kernel_keep_gate_real_kernelbench.py +0 -0
  447. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_adopt.py +0 -0
  448. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_halt.py +0 -0
  449. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_infer.py +0 -0
  450. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_journal.py +0 -0
  451. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_lease.py +0 -0
  452. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_lease_expiry.py +0 -0
  453. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_lease_mutex.py +0 -0
  454. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lane_overlap.py +0 -0
  455. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_leak_scan.py +0 -0
  456. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lease_health.py +0 -0
  457. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_legalcite_live.py +0 -0
  458. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lifecycle.py +0 -0
  459. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_liveness.py +0 -0
  460. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_llm_judge_vendor_seam.py +0 -0
  461. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_llms_full.py +0 -0
  462. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_llms_txt.py +0 -0
  463. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_lock_modes.py +0 -0
  464. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_log_source.py +0 -0
  465. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_loop_economics_toml.py +0 -0
  466. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_loop_trace.py +0 -0
  467. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_marker_gate.py +0 -0
  468. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_marker_sensor.py +0 -0
  469. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_mcp_answer.py +0 -0
  470. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_mcp_tools_plugin.py +0 -0
  471. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_memory_admit.py +0 -0
  472. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_memory_fossils.py +0 -0
  473. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_memory_integrity_bench.py +0 -0
  474. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_memory_mem0.py +0 -0
  475. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_memory_recall.py +0 -0
  476. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_memory_stores.py +0 -0
  477. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_mergegate.py +0 -0
  478. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_model_call.py +0 -0
  479. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_model_health.py +0 -0
  480. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_model_reroute.py +0 -0
  481. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_named_lock.py +0 -0
  482. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_nemo_action.py +0 -0
  483. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_noop_streak.py +0 -0
  484. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_notify_whatsapp.py +0 -0
  485. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_observe.py +0 -0
  486. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_openai_agents_guardrail.py +0 -0
  487. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_operator_judge.py +0 -0
  488. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_oracle.py +0 -0
  489. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_oracle_and_loop.py +0 -0
  490. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_oracle_forgeability_provenance.py +0 -0
  491. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_oracle_grep_in_process.py +0 -0
  492. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_os_acceptance.py +0 -0
  493. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_os_process.py +0 -0
  494. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_override_window.py +0 -0
  495. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_packet_sidecar.py +0 -0
  496. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_phase_labels.py +0 -0
  497. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_pick_priority.py +0 -0
  498. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_pickable.py +0 -0
  499. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_plan_board.py +0 -0
  500. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_plan_source.py +0 -0
  501. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_plugins_verb.py +0 -0
  502. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_poisoned_pool_bench.py +0 -0
  503. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_poisoned_pool_lineage.py +0 -0
  504. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_poisoned_pool_p2.py +0 -0
  505. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_poisoned_pool_policies.py +0 -0
  506. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_posttool_sensor.py +0 -0
  507. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_posture_observation.py +0 -0
  508. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_pre_commit_hook.py +0 -0
  509. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_precursor_gate.py +0 -0
  510. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_precursor_gate_eval.py +0 -0
  511. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_preflight_sidecar.py +0 -0
  512. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_proc_delta.py +0 -0
  513. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_productivity.py +0 -0
  514. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_arbiter_wal.py +0 -0
  515. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_breaker.py +0 -0
  516. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_cooldown.py +0 -0
  517. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_efficiency.py +0 -0
  518. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_install_wrappers.py +0 -0
  519. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_overlap_soundness.py +0 -0
  520. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_productivity.py +0 -0
  521. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_reconcile.py +0 -0
  522. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_reward_nonforgeability.py +0 -0
  523. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_prop_tree.py +0 -0
  524. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_provider_ledger.py +0 -0
  525. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_provider_limit.py +0 -0
  526. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_pulse.py +0 -0
  527. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_queue_saturation.py +0 -0
  528. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_readme_assembly.py +0 -0
  529. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_readme_test_count_band.py +0 -0
  530. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_reconcile.py +0 -0
  531. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_recurring_wedge.py +0 -0
  532. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_refusal_and_tokens.py +0 -0
  533. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_reindex.py +0 -0
  534. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_release_bump.py +0 -0
  535. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_release_cadence_workflow.py +0 -0
  536. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_release_cut.py +0 -0
  537. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_release_decide.py +0 -0
  538. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_render.py +0 -0
  539. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_replan_skip.py +0 -0
  540. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_residual_review.py +0 -0
  541. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_result_state.py +0 -0
  542. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_resume.py +0 -0
  543. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_resume_cli.py +0 -0
  544. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_resume_evidence.py +0 -0
  545. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_resume_reachability.py +0 -0
  546. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_retention.py +0 -0
  547. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_retire.py +0 -0
  548. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_reward.py +0 -0
  549. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_rewind.py +0 -0
  550. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_rewind_cli.py +0 -0
  551. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_root_index_lane.py +0 -0
  552. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_rung_occupancy.py +0 -0
  553. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_rung_occupancy_backtest.py +0 -0
  554. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scope.py +0 -0
  555. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scope_gate.py +0 -0
  556. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scope_gate_cli.py +0 -0
  557. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scope_source.py +0 -0
  558. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scoreboard_charts.py +0 -0
  559. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scoreboard_copy.py +0 -0
  560. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scoreboard_index.py +0 -0
  561. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scoreboard_rollup.py +0 -0
  562. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scoreboard_surfaces.py +0 -0
  563. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_scout.py +0 -0
  564. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_seed_scoreboard_index.py +0 -0
  565. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_selfmodify_hook_probe.py +0 -0
  566. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_server_json_version.py +0 -0
  567. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_serverless_rl_example.py +0 -0
  568. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_si_cov_cycle1.py +0 -0
  569. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_si_cov_cycle2.py +0 -0
  570. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_si_cov_cycle3.py +0 -0
  571. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_sibling_scan.py +0 -0
  572. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_similarity_judge.py +0 -0
  573. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_single_filesystem_lease_boundary.py +0 -0
  574. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_grade.py +0 -0
  575. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_grounding_rail.py +0 -0
  576. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_pack_dispatch.py +0 -0
  577. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_pack_generic.py +0 -0
  578. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_pack_litmus.py +0 -0
  579. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_pack_operator_tier.py +0 -0
  580. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_skill_pack_replan.py +0 -0
  581. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_slack_approval.py +0 -0
  582. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_smartphone_tier_bench.py +0 -0
  583. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_smithery_yaml.py +0 -0
  584. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_social_card.py +0 -0
  585. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_sota_scan.py +0 -0
  586. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_source_census.py +0 -0
  587. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_spend.py +0 -0
  588. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_spend_cli.py +0 -0
  589. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_spend_evidence.py +0 -0
  590. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stability_policy.py +0 -0
  591. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stall_sim.py +0 -0
  592. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stamp_convention.py +0 -0
  593. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stamp_filepath_rung.py +0 -0
  594. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stamp_trailer.py +0 -0
  595. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_state_diff.py +0 -0
  596. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_state_health.py +0 -0
  597. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_state_health_doctor.py +0 -0
  598. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_state_home.py +0 -0
  599. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_status_digest.py +0 -0
  600. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stop_failure_sensor.py +0 -0
  601. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_stop_policy.py +0 -0
  602. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_subprocess_stdin_hygiene.py +0 -0
  603. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_testwitness.py +0 -0
  604. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_timeline_timing.py +0 -0
  605. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_tool_stream.py +0 -0
  606. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_tool_stream_cli.py +0 -0
  607. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_tool_trace.py +0 -0
  608. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_toolathlon_live_adapter.py +0 -0
  609. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_toolathlon_replay.py +0 -0
  610. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_toolathlon_rewind_ceiling.py +0 -0
  611. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_trace.py +0 -0
  612. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_trajectory_audit.py +0 -0
  613. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_transcript_view.py +0 -0
  614. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_tree_question_mark_soundness.py +0 -0
  615. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_troubleshooting_doc.py +0 -0
  616. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_two_hosts_one_gate_playbook.py +0 -0
  617. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_vcs.py +0 -0
  618. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_vcs_config.py +0 -0
  619. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_vcs_layering.py +0 -0
  620. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verdict_census.py +0 -0
  621. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verdict_cli.py +0 -0
  622. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verdict_contract.py +0 -0
  623. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verdict_journal.py +0 -0
  624. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verdict_rollup.py +0 -0
  625. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verdicts.py +0 -0
  626. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verified.py +0 -0
  627. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verify_color.py +0 -0
  628. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verify_demo_contract.py +0 -0
  629. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verify_no_plan.py +0 -0
  630. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verify_non_git_rung.py +0 -0
  631. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_verify_plugin_install.py +0 -0
  632. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_visual_witness.py +0 -0
  633. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_whatsapp_bridge.py +0 -0
  634. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_wiring_drift.py +0 -0
  635. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_witnessed_leak_test.py +0 -0
  636. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_work_account.py +0 -0
  637. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_workflow_yaml_parses.py +0 -0
  638. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_workspace_config.py +0 -0
  639. {dos_kernel-0.28.0 → dos_kernel-0.29.0}/tests/test_worktree_lifecycle_spike.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dos-kernel
3
- Version: 0.28.0
3
+ Version: 0.29.0
4
4
  Summary: Dispatch Operating System — the domain-free trust substrate for fleets of autonomous agents (verdict spine, ship oracle, structured refusal, lane arbiter, correlation spine).
5
5
  Author: Anthony Chaudhary
6
6
  License: MIT
@@ -128,7 +128,7 @@ install is one small Python package.
128
128
  > entries there undoes it. (No runtime detected? It says so and lists the
129
129
  > names to pick from — it never guesses.)
130
130
 
131
- <sub>**v0.28.0** · 5,600+ tests · CI: Python 3.11–3.13 on Linux + a Windows 3.13
131
+ <sub>**v0.29.0** · 5,600+ tests · CI: Python 3.11–3.13 on Linux + a Windows 3.13
132
132
  smoke run · the only runtime dependency is **PyYAML** · **MIT**.</sub>
133
133
 
134
134
  > 🧭 **Where to go next:** the [why & evidence](https://github.com/anthony-chaudhary/dos-kernel/blob/master/docs/guide/why-a-referee.md) (plain-words story, the 20-lines-of-bash answer, what's proven),
@@ -370,6 +370,21 @@ verdict vocabulary, from the agent's tool call to your dashboard.
370
370
 
371
371
  *Next level up — run it every day: [Operating a fleet](#operating-a-fleet).*
372
372
 
373
+ ## From the same team
374
+
375
+ DOS is one of three open tools from [Anthony Chaudhary](https://github.com/anthony-chaudhary)
376
+ for running AI agents you can actually trust — at three different moments:
377
+
378
+ - **[fak — the agent kernel](https://github.com/anthony-chaudhary/fak)** — DOS reads *what an
379
+ agent already did* (after the fact, from git and other witnesses it can't forge); `fak` governs
380
+ *what an agent is allowed to do* as it happens. A single static Go binary that fronts your token
381
+ engine and adjudicates every tool call at the boundary — capability gate, tool-result
382
+ quarantine, audit trail — the inline gate to DOS's out-of-loop referee. `go install
383
+ github.com/anthony-chaudhary/fak/cmd/fak@latest` · [docs](https://anthony-chaudhary.github.io/fak/).
384
+ - **[Diffgram](https://github.com/diffgram/diffgram)** — the AI datastore for human supervision of
385
+ AI *data* (labeling, workflow, catalog). Where DOS and `fak` supervise the *agents*, Diffgram
386
+ supervises the *data* they learn from and produce.
387
+
373
388
  ## Citation
374
389
 
375
390
  The ideas here are written up in a paper — *"Verification Is All You Need — But
@@ -74,7 +74,7 @@ install is one small Python package.
74
74
  > entries there undoes it. (No runtime detected? It says so and lists the
75
75
  > names to pick from — it never guesses.)
76
76
 
77
- <sub>**v0.28.0** · 5,600+ tests · CI: Python 3.11–3.13 on Linux + a Windows 3.13
77
+ <sub>**v0.29.0** · 5,600+ tests · CI: Python 3.11–3.13 on Linux + a Windows 3.13
78
78
  smoke run · the only runtime dependency is **PyYAML** · **MIT**.</sub>
79
79
 
80
80
  > 🧭 **Where to go next:** the [why & evidence](https://github.com/anthony-chaudhary/dos-kernel/blob/master/docs/guide/why-a-referee.md) (plain-words story, the 20-lines-of-bash answer, what's proven),
@@ -316,6 +316,21 @@ verdict vocabulary, from the agent's tool call to your dashboard.
316
316
 
317
317
  *Next level up — run it every day: [Operating a fleet](#operating-a-fleet).*
318
318
 
319
+ ## From the same team
320
+
321
+ DOS is one of three open tools from [Anthony Chaudhary](https://github.com/anthony-chaudhary)
322
+ for running AI agents you can actually trust — at three different moments:
323
+
324
+ - **[fak — the agent kernel](https://github.com/anthony-chaudhary/fak)** — DOS reads *what an
325
+ agent already did* (after the fact, from git and other witnesses it can't forge); `fak` governs
326
+ *what an agent is allowed to do* as it happens. A single static Go binary that fronts your token
327
+ engine and adjudicates every tool call at the boundary — capability gate, tool-result
328
+ quarantine, audit trail — the inline gate to DOS's out-of-loop referee. `go install
329
+ github.com/anthony-chaudhary/fak/cmd/fak@latest` · [docs](https://anthony-chaudhary.github.io/fak/).
330
+ - **[Diffgram](https://github.com/diffgram/diffgram)** — the AI datastore for human supervision of
331
+ AI *data* (labeling, workflow, catalog). Where DOS and `fak` supervise the *agents*, Diffgram
332
+ supervises the *data* they learn from and produce.
333
+
319
334
  ## Citation
320
335
 
321
336
  The ideas here are written up in a paper — *"Verification Is All You Need — But
@@ -9,7 +9,7 @@ build-backend = "setuptools.build_meta"
9
9
  # src/), and the console scripts stay `dos` / `dos-mcp` — only the pip-install /
10
10
  # dependency-pin name is `dos-kernel`. See SECURITY.md "Supply chain".
11
11
  name = "dos-kernel"
12
- version = "0.28.0"
12
+ version = "0.29.0"
13
13
  description = "Dispatch Operating System — the domain-free trust substrate for fleets of autonomous agents (verdict spine, ship oracle, structured refusal, lane arbiter, correlation spine)."
14
14
  # The PyPI project page renders this. Point it at the README so the page isn't
15
15
  # blank below the metadata (twine warns when it's missing). PyPI resolves
@@ -46,7 +46,7 @@ try:
46
46
 
47
47
  __version__ = _pkg_version("dos-kernel")
48
48
  except Exception: # pragma: no cover - source-tree / not-installed fallback
49
- __version__ = "0.28.0"
49
+ __version__ = "0.29.0"
50
50
 
51
51
  from dos import config # noqa: F401 (re-export the seam as the package entry)
52
52
  from dos.config import ( # noqa: F401
@@ -138,6 +138,36 @@ class AccountAuthSpec:
138
138
  out[self.token_env] = token
139
139
  return out
140
140
 
141
+ def launch_env(
142
+ self,
143
+ account: object | None = None,
144
+ *,
145
+ config_dir: str | None = None,
146
+ token: Optional[str] = None,
147
+ ) -> dict[str, str]:
148
+ """The env-override to (re)launch a worker as one seat of this agent.
149
+
150
+ The SINGLE builder every consumer uses — the launcher and the rotate-on-wall
151
+ handoff (docs/386 §4) — so neither branches on the agent NAME. It prefers this
152
+ spec's disk-aware ``launch_env_fn`` (a CAPABILITY, not a name: Claude's docs/380
153
+ ``env_for``, which defers to a fresh ``.credentials.json`` rather than freezing a
154
+ static token into a live session) when it is set AND an ``account`` object is
155
+ supplied; otherwise it falls to the pure ``env_overrides`` floor built from
156
+ ``config_dir`` (+ optional ``token``). A consumer reads ``spec.launch_env_fn``
157
+ ONLY through this method, never ``if kind == "claude"`` (the vendor-blindness
158
+ litmus).
159
+
160
+ Fail-LOUD by design: a ``launch_env_fn`` that raises (Claude's ``OriginError`` on
161
+ a missing/logged-out config dir) propagates — launching under the WRONG or empty
162
+ identity is the hazard this contract exists to prevent, so it must fail, never
163
+ emit a logged-out env. ``account`` is opaque (the callable's own type); the
164
+ kernel does not import it.
165
+ """
166
+ if self.launch_env_fn is not None and account is not None:
167
+ env = self.launch_env_fn(account)
168
+ return dict(env) if isinstance(env, dict) else {}
169
+ return self.env_overrides(config_dir or "", token=token)
170
+
141
171
 
142
172
  # --------------------------------------------------------------------------- #
143
173
  # By-name resolution — in-tree driver first, then the dos.account_auth group.
@@ -1,7 +1,7 @@
1
1
  """The admission-predicate seam — Axis 3 of hackability: pluggable safety hooks (ADM, docs/73).
2
2
 
3
- The arbiter's admission logic — `_lease_blocks` + the ≤30 % soft-overlap
4
- tree-disjointness rule (`lane_overlap.overlap_verdict`) — is the kernel's
3
+ The arbiter's admission logic — known-tree intersection plus shared/exclusive
4
+ lock compatibility, with the legacy ratio scorer still selectable by config — is the kernel's
5
5
  **safety element**: it is what stops two agents editing the same files
6
6
  concurrently. That logic used to be fixed. A workspace could not add its own
7
7
  admission rule ("refuse a new lease when over the monthly token budget,"
@@ -158,19 +158,18 @@ class AdmissionRequest:
158
158
  tree: tuple[str, ...]
159
159
  command: str = ""
160
160
  arg_values: tuple[str, ...] = ()
161
+ mode: str = ""
161
162
 
162
163
 
163
164
  class DisjointnessPredicate:
164
165
  """The built-in tree-disjointness predicate — today's fixed admission rule,
165
166
  now the FIRST registered predicate.
166
167
 
167
- Delegates the both-known scoring to a resolved `overlap_policy.OverlapPolicy`
168
- (default `PrefixOverlapPolicy`, AND-ed under the deterministic prefix floor),
169
- while owning the empty-tree asymmetry itself. With the default policy the
170
- floor-AND reproduces `lane_overlap.overlap_verdict` exactly, so routing the
171
- arbiter's collision check through `run_predicates([DisjointnessPredicate()])`
172
- stays byte-for-byte behavior-preserving (the load-bearing litmus: the entire
173
- existing arbiter/overlap suite is green through this path).
168
+ Delegates the both-known scoring to a resolved `overlap_policy.OverlapPolicy`.
169
+ The default is `LockModeOverlapPolicy`: EXCLUSIVE/EXCLUSIVE intersections
170
+ refuse at zero tolerance while SHARED/SHARED intersections admit. The legacy
171
+ `PrefixOverlapPolicy` is still selectable explicitly, where it is AND-ed under
172
+ the deterministic prefix floor.
174
173
 
175
174
  The **empty-tree rules** (asymmetric on the lease side) are owned HERE, not in
176
175
  the policy — they are soundness invariants about *unknown blast radius*, not a
@@ -184,13 +183,13 @@ class DisjointnessPredicate:
184
183
  * both known → delegate to the policy via `admissible_under_floor`.
185
184
 
186
185
  ``policy`` is the scorer for the both-known case. It defaults to the built-in
187
- `PrefixOverlapPolicy` (pure, no I/O so a `DisjointnessPredicate()` with no
188
- args is pure and byte-identical to the old inline rule). A boundary caller
186
+ `LockModeOverlapPolicy` (pure, no I/O). A boundary caller
189
187
  (`built_in_predicates`) resolves a workspace's declared `dos.overlap_policies`
190
188
  plugin and passes it in here — the resolve-at-the-boundary, I/O-free-hot-path
191
189
  discipline `SelfModifyPredicate`'s `runtime_files` already uses. Whatever the
192
- policy is, `admissible_under_floor` AND-s it under the unforgeable prefix floor,
193
- so a misbehaving policy can only refuse-more, never admit a collision.
190
+ non-lock policy is, `admissible_under_floor` AND-s it under the unforgeable
191
+ prefix floor, so a misbehaving scorer can only refuse-more, never admit a
192
+ legacy prefix collision.
194
193
  """
195
194
 
196
195
  name = "disjointness"
@@ -200,13 +199,13 @@ class DisjointnessPredicate:
200
199
  # same leaf `admission` already imports — no cycle, but keep it local so a
201
200
  # default-constructed predicate has zero extra import cost on the hot path).
202
201
  if policy is None:
203
- from dos.overlap_policy import PrefixOverlapPolicy
204
- policy = PrefixOverlapPolicy()
202
+ from dos.overlap_policy import LockModeOverlapPolicy
203
+ policy = LockModeOverlapPolicy()
205
204
  self._policy = policy
206
205
 
207
206
  def __call__(self, request: AdmissionRequest, live_lease: dict,
208
207
  config: object) -> AdmissionVerdict:
209
- from dos.overlap_policy import admissible_under_floor
208
+ from dos.overlap_policy import admissible_under_floor, lock_mode_decision
210
209
  requested_tree = list(request.tree)
211
210
  lease_tree = list(live_lease.get("tree") or [])
212
211
  if not lease_tree:
@@ -218,7 +217,15 @@ class DisjointnessPredicate:
218
217
  f"{live_lease.get('lane')!r} — unknown blast radius is never "
219
218
  f"safe to admit concurrently."
220
219
  )
221
- ov = admissible_under_floor(self._policy, requested_tree, lease_tree, config)
220
+ if getattr(self._policy, "name", "") == "lock_modes":
221
+ ov = lock_mode_decision(
222
+ requested_tree,
223
+ lease_tree,
224
+ requested_mode=request.mode,
225
+ lease_mode=live_lease.get("mode", live_lease.get("lock_mode", "")),
226
+ )
227
+ else:
228
+ ov = admissible_under_floor(self._policy, requested_tree, lease_tree, config)
222
229
  if ov.admissible:
223
230
  return AdmissionVerdict.admit()
224
231
  return AdmissionVerdict.refuse(
@@ -390,10 +397,10 @@ def built_in_predicates(*, workspace=None, config=None) -> list[AdmissionPredica
390
397
 
391
398
  The **overlap policy** (the both-known disjointness scorer) is resolved HERE
392
399
  too, at the boundary, and threaded into `DisjointnessPredicate(policy=…)` — so
393
- the pure `arbitrate` never does the discovery I/O that resolving a non-`prefix`
400
+ the pure `arbitrate` never does the discovery I/O that resolving a third-party
394
401
  policy needs. With no `config` (or a config naming no policy / the built-in
395
- `prefix`), `active_overlap_policy` returns `PrefixOverlapPolicy` with NO
396
- discovery, so the default predicate list is byte-identical to before the seam.
402
+ `lock_modes`), `active_overlap_policy` returns `LockModeOverlapPolicy` with NO
403
+ discovery, so the default predicate list uses the sound S/X lock-mode rule.
397
404
  A workspace that declares `dos.toml [overlap] policy = "import-graph"` (or sets
398
405
  `config.overlap_policy_name`) gets its plugin resolved and AND-ed under the
399
406
  deterministic prefix floor inside the predicate.
@@ -42,9 +42,13 @@ The three states (mutually exclusive):
42
42
  viability length, and matches no disqualifying marker. Shaped
43
43
  like an answer. (NOT a claim of correctness — see the boundary.)
44
44
  * ``NON_ANSWER`` — structurally disqualified: empty/whitespace-only, below the
45
- viability floor, OR matches a declared non-answer marker (a
45
+ viability floor, OVER the verbosity ceiling, degenerated into a
46
+ repeating loop, OR matches a declared non-answer marker (a
46
47
  process/CoT-log signature, a bare-refusal signature, a stub).
47
- The q_025 catch. The dangerous case a grounding gate misses.
48
+ The q_025 catch (the stub/CoT end) PLUS the opposite failures the
49
+ same shape guard should see — the runaway/padded dump and the
50
+ decode-degeneration loop (the verbosity/drift end). The dangerous
51
+ case a grounding gate misses.
48
52
  * ``INDETERMINATE`` — no policy supplied, or the text is non-trivial but the policy
49
53
  cannot disqualify it on shape — the abstain floor. The semantic
50
54
  "is it a good answer?" residue goes here, to a JUDGE / HUMAN.
@@ -116,6 +120,34 @@ class AnswerShapePolicy:
116
120
  (the RAG app's q_025 leaked-CoT was 5,780 chars, so length alone never catches that;
117
121
  the *markers* do — length catches the opposite failure, the empty/stub end).
118
122
 
123
+ ``max_viable_chars`` is the SYMMETRIC ceiling — the verbosity/bloat end the floor
124
+ can't see. Above it, a non-empty output is a runaway/padded generation, structurally
125
+ not a focused answer (the q_025 leaked-CoT was *long*; gross length is itself a
126
+ structural tell once a host declares its budget). Default ``0`` DISABLES the ceiling
127
+ (no upper bound) — exactly like the floor's default-1 only-empty behavior, the host
128
+ declares the threshold; the kernel never guesses a length budget (the "ceiling fixed
129
+ by the source, never inferred from content" rule, docs/156 §3.2). Still SHAPE, not
130
+ quality: a host setting a ceiling is declaring "in my domain an answer over N chars
131
+ is structurally a dump", the same kind of host call as setting ``min_viable_chars``.
132
+
133
+ ``max_repeat_ratio`` is the DEGENERATION guard — the drift-into-a-loop failure where
134
+ a generation collapses into repeating the same line/sentence (the classic decode
135
+ degeneration, and the most common *mechanism* of padded verbosity). It is the
136
+ fraction of repeated (non-distinct) units the output may carry before it is
137
+ structurally a non-answer: ``repeat_ratio = (n_units - n_distinct) / n_units`` over
138
+ the segmented units (see ``_repeat_ratio``). Above the threshold ⇒ NON_ANSWER.
139
+ Default ``0.0`` DISABLES it (the fail-safe UNDER-disqualify direction — the kernel
140
+ ships the *mechanism*, the host opts in with a threshold like ``0.5``). Mechanically
141
+ checkable and domain-free, so it stays inside the SHAPE boundary: a text that is
142
+ mostly the same sentence over and over is not an answer regardless of the topic.
143
+
144
+ ⚠ SCOPE IT TO PROSE. The metric is the fraction of EXACT (stripped+casefolded)
145
+ duplicate units — content-blind, not semantic. So a list/table/CSV/log channel whose
146
+ rows legitimately repeat a short literal (``- N/A`` ten times, a ``| --- |`` rule)
147
+ will read as high-ratio and be disqualified. That is WHY it defaults off and the host
148
+ opts in: point ``max_repeat_ratio`` at free-prose answer channels, not at structured
149
+ output, where exact-row repetition is a feature, not degeneration.
150
+
119
151
  ``non_answer_patterns`` is the host's closed set of disqualifying regexes — a
120
152
  process/CoT-log signature, a bare-refusal signature, a tool-call dump. Matched
121
153
  case-insensitively, in a `search` (anywhere in the text). The kernel ships a generic
@@ -133,6 +165,8 @@ class AnswerShapePolicy:
133
165
  """
134
166
 
135
167
  min_viable_chars: int = 1
168
+ max_viable_chars: int = 0
169
+ max_repeat_ratio: float = 0.0
136
170
  non_answer_patterns: tuple[str, ...] = ()
137
171
  answer_markers: tuple[str, ...] = ()
138
172
 
@@ -193,6 +227,35 @@ class AnswerShapeVerdict:
193
227
  }
194
228
 
195
229
 
230
+ # The minimum number of segmented units before a repeat ratio is meaningful. Below it
231
+ # there is too little signal to call degeneration, so the guard ABSTAINS (under-
232
+ # disqualify — the same fail-safe direction as `_safe_search`). A short Q&A like
233
+ # "Yes. No. Yes." must never trip the loop guard; a real degeneration repeats many times.
234
+ _MIN_REPEAT_UNITS = 4
235
+
236
+ # Segment on sentence terminators OR newlines, so a degeneration is caught whether it
237
+ # repeats one-unit-per-line or many-sentences-on-one-line.
238
+ _UNIT_SPLIT = re.compile(r"[.!?\n]+")
239
+
240
+
241
+ def _repeat_ratio(text: str) -> tuple[float, int]:
242
+ """The fraction of REPEATED (non-distinct) units in ``text``, and the unit count.
243
+
244
+ Splits ``text`` into units on sentence terminators / newlines, normalizes each
245
+ (stripped + casefolded), drops empties, and returns
246
+ ``((n_units - n_distinct) / n_units, n_units)``. A clean answer with all-distinct
247
+ units scores ~0; a generation that has collapsed into repeating one line/sentence
248
+ approaches 1. PURE; returns ``(0.0, n)`` when there are too few units to judge (the
249
+ caller's `_MIN_REPEAT_UNITS` floor makes that an abstain, never a disqualification).
250
+ """
251
+ units = [u.strip().casefold() for u in _UNIT_SPLIT.split(text)]
252
+ units = [u for u in units if u]
253
+ n = len(units)
254
+ if n < 2:
255
+ return 0.0, n
256
+ return (n - len(set(units))) / n, n
257
+
258
+
196
259
  def _safe_search(pattern: str, text: str) -> bool:
197
260
  """Case-insensitive `re.search`, fail-safe to False on a bad pattern.
198
261
 
@@ -224,12 +287,18 @@ def classify(
224
287
  2. ``text`` empty / whitespace-only → NON_ANSWER (nothing was delivered).
225
288
  3. ``len(text) < min_viable_chars`` → NON_ANSWER (below the viability floor — a
226
289
  stub / ack token, not an answer).
227
- 4. a ``non_answer_patterns`` hit → NON_ANSWER (a process/CoT-log / bare-refusal
290
+ 4. ``max_viable_chars`` set AND
291
+ ``len(text) > max_viable_chars`` → NON_ANSWER (over the verbosity/bloat ceiling
292
+ — a runaway/padded dump, not a focused answer).
293
+ 5. a ``non_answer_patterns`` hit → NON_ANSWER (a process/CoT-log / bare-refusal
228
294
  / tool-dump signature — the q_025 catch).
229
- 5. ``answer_markers`` non-empty AND
295
+ 6. ``max_repeat_ratio`` set AND the
296
+ repeat ratio exceeds it → NON_ANSWER (degenerated into a loop — the
297
+ same line/sentence over and over; drift).
298
+ 7. ``answer_markers`` non-empty AND
230
299
  none matched → INDETERMINATE (the strict host required a
231
300
  positive answer marker and found none; abstain).
232
- 6. otherwise → ANSWER_SHAPED (no disqualifier; shaped like
301
+ 8. otherwise → ANSWER_SHAPED (no disqualifier; shaped like
233
302
  an answer — NOT a claim of correctness).
234
303
 
235
304
  Returns an `AnswerShapeVerdict`; NEVER raises. Remember the boundary: a `NON_ANSWER`
@@ -268,6 +337,18 @@ def classify(
268
337
  f"answer (NON_ANSWER)"),
269
338
  )
270
339
 
340
+ ceiling = int(policy.max_viable_chars)
341
+ if ceiling > 0 and len(stripped) > ceiling:
342
+ return AnswerShapeVerdict(
343
+ state=AnswerShape.NON_ANSWER,
344
+ length=n,
345
+ matched="",
346
+ reason=(f"output is {len(stripped)} non-space chars, over the verbosity "
347
+ f"ceiling of {ceiling} — a runaway/padded dump, not a focused "
348
+ f"answer (NON_ANSWER; a SHAPE call on the host's length budget, "
349
+ f"not a correctness judgment)"),
350
+ )
351
+
271
352
  for pat in policy.non_answer_patterns:
272
353
  if _safe_search(pat, raw):
273
354
  return AnswerShapeVerdict(
@@ -279,6 +360,20 @@ def classify(
279
360
  f"answer (the grounded-but-not-an-answer catch, docs/156 §4)"),
280
361
  )
281
362
 
363
+ repeat_cap = float(policy.max_repeat_ratio)
364
+ if repeat_cap > 0.0:
365
+ ratio, units = _repeat_ratio(raw)
366
+ if units >= _MIN_REPEAT_UNITS and ratio > repeat_cap:
367
+ return AnswerShapeVerdict(
368
+ state=AnswerShape.NON_ANSWER,
369
+ length=n,
370
+ matched="",
371
+ reason=(f"output repeat ratio {ratio:.2f} over {units} units exceeds "
372
+ f"the degeneration cap of {repeat_cap:.2f} — collapsed into "
373
+ f"repeating the same line/sentence (NON_ANSWER; a structural "
374
+ f"loop/drift tell, not a correctness judgment)"),
375
+ )
376
+
282
377
  if policy.answer_markers:
283
378
  if not any(_safe_search(m, raw) for m in policy.answer_markers):
284
379
  return AnswerShapeVerdict(
@@ -23,13 +23,14 @@ would later stand on.
23
23
 
24
24
  What this arbiter *is*, named after its mechanism rather than the "lane" metaphor:
25
25
  a **lock manager whose granularity is a glob-set** — a lane is a *leased
26
- predicate-lock over a region of the workspace*, admitted by predicate-disjointness
27
- (`_tree.prefixes_collide` is the predicate-intersection test; the soft-overlap
28
- ratio in `lane_overlap` is a *loosened lock-compatibility function*, not a
29
- swim-lane fudge). The capability-lattice above is then **the same primitive over a
30
- richer predicate algebra than path-prefixes** a new `prefixes_collide`, not a new
31
- arbiter. See `docs/89_the-lane-is-a-region-lock.md` (which is also the forward
32
- litmus for what belongs in here: a region-lock property, never a swim-lane one).
26
+ predicate-lock over a region of the workspace*, admitted by predicate-intersection
27
+ plus lock compatibility (`lock_modes`: SHARED/SHARED may coexist; anything with
28
+ EXCLUSIVE needs tree-disjointness). The legacy soft-overlap ratio remains a
29
+ configurable scorer, but it is no longer the default admission floor. The
30
+ capability-lattice above is then **the same primitive over a richer predicate
31
+ algebra than path-prefixes** — a new `prefixes_collide`, not a new arbiter. See
32
+ `docs/89_the-lane-is-a-region-lock.md` (which is also the forward litmus for what
33
+ belongs in here: a region-lock property, never a swim-lane one).
33
34
  """
34
35
 
35
36
  from __future__ import annotations
@@ -98,9 +99,10 @@ def _lease_blocks(requested_tree: list[str], lease_tree: list[str]) -> bool:
98
99
  is never safe).
99
100
  * both empty → does NOT block (lone-loop safe).
100
101
 
101
- Both-known delegates to `dos.lane_overlap.overlap_verdict` — a ratio-only
102
- soft-overlap policy (admit when ≤30 % of the requested tree shares prefixes
103
- with the lease). Pure; tested in isolation.
102
+ Legacy helper: both-known delegates to `dos.lane_overlap.overlap_verdict`, the
103
+ explicit prefix/ratio scorer. The default admission path now runs through
104
+ `DisjointnessPredicate` and `lock_modes`; this remains for old exact callers
105
+ that deliberately ask the ratio question.
104
106
  """
105
107
  if not lease_tree:
106
108
  return False
@@ -112,26 +114,26 @@ def _lease_blocks(requested_tree: list[str], lease_tree: list[str]) -> bool:
112
114
  def _admission_verdict(
113
115
  *, lane: str, kind: str, tree: list[str], live_leases: list[dict],
114
116
  predicates: list[AdmissionPredicate], config: SubstrateConfig,
117
+ mode: str = "",
115
118
  ) -> AdmissionVerdict:
116
119
  """Run the FULL admission conjunction for a candidate lane (ADM Phase 1).
117
120
 
118
121
  The single seam every collision check in `arbitrate` now routes through: the
119
- built-in `DisjointnessPredicate` (a behavior-preserving wrap of the old inline
120
- `_lease_blocks` / `overlap_verdict`) PLUS `SelfModifyPredicate` PLUS any
121
- workspace-discovered predicate, composed conjunctively by
122
- `admission.run_predicates` (first refusal wins; all-admit admit; a predicate
123
- that raises is a fail-closed refuse). The disjointness predicate alone
124
- reproduces the legacy verdict exactly, so the existing suite stays green; the
125
- extra predicates can only ADD refusals (the conjunctive-only invariant), never
126
- loosen, so a disjoint job-lane pair still admits.
122
+ built-in `DisjointnessPredicate` (default S/X lock-mode compatibility) PLUS
123
+ `SelfModifyPredicate` PLUS any workspace-discovered predicate, composed
124
+ conjunctively by `admission.run_predicates` (first refusal wins; all-admit ⇒
125
+ admit; a predicate that raises is a fail-closed refuse). Extra predicates can
126
+ only ADD refusals (the conjunctive-only invariant), never loosen, so a
127
+ disjoint job-lane pair still admits.
127
128
  """
128
- request = AdmissionRequest(lane=lane, kind=kind, tree=tuple(tree or ()))
129
+ request = AdmissionRequest(lane=lane, kind=kind, tree=tuple(tree or ()), mode=mode)
129
130
  return run_predicates(predicates, request, live_leases, config)
130
131
 
131
132
 
132
133
  def _lease_collision(
133
134
  *, lane: str, kind: str, tree: list[str], live_leases: list[dict],
134
135
  predicates: list[AdmissionPredicate], config: SubstrateConfig,
136
+ mode: str = "",
135
137
  ) -> bool:
136
138
  """True iff admitting this candidate lane is refused by ANY predicate against
137
139
  ANY live lease — the boolean the auto-pick loops want (they only need "is this
@@ -139,7 +141,7 @@ def _lease_collision(
139
141
  `_admission_verdict` so the loops read like the old `any(_lease_blocks(...))`."""
140
142
  return not _admission_verdict(
141
143
  lane=lane, kind=kind, tree=tree, live_leases=live_leases,
142
- predicates=predicates, config=config,
144
+ predicates=predicates, config=config, mode=mode,
143
145
  ).admitted
144
146
 
145
147
 
@@ -160,6 +162,7 @@ def arbitrate(
160
162
  class_budgets: dict[str, int] | None = None,
161
163
  live_siblings: list[dict] | None = None,
162
164
  sibling_tree_lookup: Callable[[str], list[str] | None] | None = None,
165
+ requested_mode: str = "",
163
166
  ) -> LaneDecision:
164
167
  """PURE admission: decide whether a loop may start, and on which lane.
165
168
 
@@ -559,6 +562,7 @@ def arbitrate(
559
562
  verdict = _admission_verdict(
560
563
  lane=requested_lane or "global", kind=kind, tree=requested_tree,
561
564
  live_leases=live_leases, predicates=preds, config=cfg,
565
+ mode=requested_mode,
562
566
  )
563
567
  if not verdict.admitted:
564
568
  return LaneDecision(
@@ -600,6 +604,7 @@ def arbitrate(
600
604
  verdict = _admission_verdict(
601
605
  lane=requested_lane, kind="cluster", tree=tree,
602
606
  live_leases=live_leases, predicates=preds, config=cfg,
607
+ mode=requested_mode,
603
608
  )
604
609
  if verdict.admitted:
605
610
  return LaneDecision(
@@ -617,14 +622,15 @@ def arbitrate(
617
622
  _hint_refusal["reason"] = verdict.reason
618
623
 
619
624
  # Keyword request with a NON-EMPTY tree → run the admission conjunction
620
- # (disjointness + self-modify + any workspace predicate). First refusal wins;
621
- # the disjointness predicate reproduces the old soft-overlap verdict exactly,
622
- # so a disjoint keyword lane still admits while a self-modifying one now
623
- # refuses with the typed SELF_MODIFY reason it could not carry before.
625
+ # (lock-mode disjointness + self-modify + any workspace predicate). First
626
+ # refusal wins; a disjoint or shared/shared-compatible keyword lane admits,
627
+ # while a self-modifying one refuses with the typed SELF_MODIFY reason it
628
+ # could not carry before.
624
629
  if requested_kind == "keyword" and requested_tree:
625
630
  verdict = _admission_verdict(
626
631
  lane=requested_lane, kind="keyword", tree=requested_tree,
627
632
  live_leases=live_leases, predicates=preds, config=cfg,
633
+ mode=requested_mode,
628
634
  )
629
635
  if not verdict.admitted:
630
636
  reason = f"{verdict.reason} Use a free cluster lane instead."
@@ -635,7 +641,7 @@ def arbitrate(
635
641
  "acquire", lane=requested_lane, lane_kind="keyword",
636
642
  tree=requested_tree, auto_picked=False,
637
643
  reason=(f"keyword lane {requested_lane!r} admitted (disjoint or "
638
- f"under the soft-overlap threshold vs all "
644
+ f"lock-mode compatible vs all "
639
645
  f"{len(live_leases)} live lease(s))."),
640
646
  )
641
647
 
@@ -735,7 +741,8 @@ def arbitrate(
735
741
  _saw_non_budget_candidate = True
736
742
  if not _lease_collision(
737
743
  lane=name, kind=_cand_kind, tree=tree_list,
738
- live_leases=live_leases, predicates=preds, config=cfg):
744
+ live_leases=live_leases, predicates=preds, config=cfg,
745
+ mode=requested_mode):
739
746
  # FQ-449 first pass: also require sibling-disjointness. A candidate
740
747
  # that overlaps a live sibling is skipped here so a LATER ladder
741
748
  # lane (disjoint from both leases AND siblings) can win; the second
@@ -779,7 +786,8 @@ def arbitrate(
779
786
  cand_tree = _cluster_tree(cand)
780
787
  if not _lease_collision(
781
788
  lane=cand, kind="cluster", tree=cand_tree,
782
- live_leases=live_leases, predicates=preds, config=cfg):
789
+ live_leases=live_leases, predicates=preds, config=cfg,
790
+ mode=requested_mode):
783
791
  if not _admit_lane(cand, "cluster", cand_tree):
784
792
  continue
785
793
  return LaneDecision(
@@ -848,7 +856,8 @@ def arbitrate(
848
856
  cand_tree = _cluster_tree(cand)
849
857
  if not _lease_collision(
850
858
  lane=cand, kind="cluster", tree=cand_tree,
851
- live_leases=live_leases, predicates=preds, config=cfg):
859
+ live_leases=live_leases, predicates=preds, config=cfg,
860
+ mode=requested_mode):
852
861
  if unresolved_keyword:
853
862
  why = _unresolved_suffix.strip()
854
863
  elif requested_lane:
@@ -867,7 +876,8 @@ def arbitrate(
867
876
  continue
868
877
  if not _lease_collision(
869
878
  lane=name, kind="named", tree=tree_list,
870
- live_leases=live_leases, predicates=preds, config=cfg):
879
+ live_leases=live_leases, predicates=preds, config=cfg,
880
+ mode=requested_mode):
871
881
  return LaneDecision(
872
882
  "acquire", lane=name, lane_kind="named",
873
883
  tree=tree_list, auto_picked=True,
@@ -879,7 +889,8 @@ def arbitrate(
879
889
  continue
880
890
  if not _lease_collision(
881
891
  lane=plan_id, kind="derived", tree=list(tree_list),
882
- live_leases=live_leases, predicates=preds, config=cfg):
892
+ live_leases=live_leases, predicates=preds, config=cfg,
893
+ mode=requested_mode):
883
894
  return LaneDecision(
884
895
  "acquire", lane=plan_id, lane_kind="derived",
885
896
  tree=list(tree_list), auto_picked=True,