brigade-cli 0.26.0__tar.gz → 0.26.1__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 (758) hide show
  1. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/PKG-INFO +8 -6
  2. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/README.md +7 -5
  3. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/pyproject.toml +1 -1
  4. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/__init__.py +1 -1
  5. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/aboyeur.py +172 -42
  6. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/agent_skill_format.py +35 -2
  7. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/__init__.py +4 -0
  8. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/actions.py +1 -1
  9. brigade_cli-0.26.1/src/brigade/center_cmd/serve.py +312 -0
  10. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/claude_hooks/classify.py +1 -1
  11. brigade_cli-0.26.1/src/brigade/claude_hooks/envelope.py +342 -0
  12. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/claude_hooks/runtime.py +282 -29
  13. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/center.py +19 -0
  14. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/doctor.py +6 -0
  15. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/handoff.py +6 -0
  16. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/harness.py +21 -2
  17. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/memory.py +6 -0
  18. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/run.py +40 -9
  19. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/runs.py +88 -0
  20. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/work/dispatching.py +75 -2
  21. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/work/registration.py +167 -0
  22. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/config.py +25 -0
  23. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cursor_user_cmd.py +1 -1
  24. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/doctor.py +112 -3
  25. brigade_cli-0.26.1/src/brigade/doctor_agent.py +452 -0
  26. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/dogfood_cmd.py +1 -1
  27. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/audit.py +4 -3
  28. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff.py +2 -2
  29. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/drafts.py +4 -4
  30. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/linting.py +71 -2
  31. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/migrate_ops.py +4 -4
  32. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/models.py +5 -0
  33. brigade_cli-0.26.1/src/brigade/handoff_cmd/readability.py +318 -0
  34. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/receipts.py +1 -1
  35. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/sources.py +2 -2
  36. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/harness_profile_cmd.py +336 -103
  37. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/harness_profiles.py +3 -0
  38. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/ingest.py +17 -6
  39. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/install.py +11 -10
  40. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/learn_cmd.py +1 -1
  41. brigade_cli-0.26.1/src/brigade/managed_block.py +944 -0
  42. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/mcp_cmd.py +11 -6
  43. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_cmd.py +188 -15
  44. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/compact.py +2 -2
  45. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/lint.py +1 -1
  46. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/parsing.py +1 -1
  47. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/lifecycle.py +1 -1
  48. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/outcome_cmd.py +7 -4
  49. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/outcome_repair.py +1 -1
  50. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/pi_mcp_cmd.py +1 -1
  51. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/receipt_schema.py +3 -0
  52. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/receipts_cmd.py +1 -1
  53. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/candidate.py +25 -2
  54. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/ci.py +60 -9
  55. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/paths.py +1 -2
  56. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/adoption.py +1 -1
  57. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/fleet_health.py +1 -1
  58. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/release_train.py +1 -1
  59. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/sweeps.py +2 -2
  60. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/sources/local.py +1 -1
  61. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research_cmd.py +8 -8
  62. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/roadmap_cmd.py +37 -9
  63. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/roster.py +3 -0
  64. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/roster_cmd.py +2 -2
  65. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_projector.py +1 -0
  66. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_resume.py +203 -14
  67. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_transport.py +68 -2
  68. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/runbook_cmd.py +3 -2
  69. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/runguard.py +191 -20
  70. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/scrub.py +1 -1
  71. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/__init__.py +4 -0
  72. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/models.py +39 -0
  73. brigade_cli-0.26.1/src/brigade/security_cmd/scan_detectors.py +706 -0
  74. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/scan_engine.py +13 -686
  75. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/skills_cmd.py +24 -19
  76. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/components/manifest-v1.json +64 -64
  77. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/hermes/memory-handoff.harness.json +1 -1
  78. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/hermes/model-lanes.harness.json +1 -1
  79. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/hermes/workspace.harness.json +1 -1
  80. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/chat-memory-sweep.example.json +1 -1
  81. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/memory-care.example.json +1 -1
  82. brigade_cli-0.26.1/src/brigade/templates/memory-care/runbooks/daily-care-pass.json +15 -0
  83. brigade_cli-0.26.1/src/brigade/templates/memory-care/runbooks/ingest-sweep.json +15 -0
  84. brigade_cli-0.26.1/src/brigade/templates/memory-care/runbooks/weekly-outcome-ratchet.json +15 -0
  85. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/policies/personal.json +1 -1
  86. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/policies/public-content.json +1 -1
  87. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/policies/public-repo.json +1 -1
  88. brigade_cli-0.26.1/src/brigade/templates/skills/card-refresh/CHANGELOG.md +6 -0
  89. brigade_cli-0.26.1/src/brigade/templates/skills/card-refresh/SKILL.md +68 -0
  90. brigade_cli-0.26.1/src/brigade/templates/skills/card-refresh/skill.json +14 -0
  91. brigade_cli-0.26.1/src/brigade/templates/skills/forward-plan/CHANGELOG.md +12 -0
  92. brigade_cli-0.26.1/src/brigade/templates/skills/forward-plan/SKILL.md +190 -0
  93. brigade_cli-0.26.1/src/brigade/templates/skills/forward-plan/plan.template.json +70 -0
  94. brigade_cli-0.26.1/src/brigade/templates/skills/forward-plan/skill.json +17 -0
  95. brigade_cli-0.26.1/src/brigade/templates/skills/handoff-inbox-drain/CHANGELOG.md +6 -0
  96. brigade_cli-0.26.1/src/brigade/templates/skills/handoff-inbox-drain/SKILL.md +68 -0
  97. brigade_cli-0.26.1/src/brigade/templates/skills/handoff-inbox-drain/skill.json +17 -0
  98. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/runs.py +39 -2
  99. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/__init__.py +18 -0
  100. brigade_cli-0.26.1/src/brigade/work_cmd/claiming.py +576 -0
  101. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/constants.py +6 -0
  102. brigade_cli-0.26.1/src/brigade/work_cmd/edges.py +832 -0
  103. brigade_cli-0.26.1/src/brigade/work_cmd/footprint.py +419 -0
  104. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/imports.py +5 -5
  105. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/ledger.py +385 -26
  106. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/reviews.py +62 -58
  107. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/services.py +5 -0
  108. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/session/briefing.py +7 -1
  109. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/session/lifecycle.py +17 -7
  110. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/session/run_status.py +32 -14
  111. brigade_cli-0.26.1/src/brigade/work_cmd/session/task_ops.py +929 -0
  112. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/verification.py +241 -13
  113. brigade_cli-0.26.1/src/brigade/work_cmd/verify_ranking.py +255 -0
  114. brigade_cli-0.26.1/src/brigade/work_run_archive.py +837 -0
  115. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/worker_failure.py +1 -0
  116. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade_cli.egg-info/PKG-INFO +8 -6
  117. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade_cli.egg-info/SOURCES.txt +38 -0
  118. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_aboyeur.py +209 -0
  119. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_aboyeur_orchestrator_health_routing.py +119 -2
  120. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agent_skill_format.py +18 -0
  121. brigade_cli-0.26.1/tests/test_center_serve.py +237 -0
  122. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_ci_workflow.py +63 -3
  123. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_claude_hooks_doctor.py +7 -7
  124. brigade_cli-0.26.1/tests/test_claude_hooks_envelope.py +248 -0
  125. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_claude_hooks_runtime.py +189 -1
  126. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_manifest.py +1 -1
  127. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_config.py +27 -0
  128. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_doctor.py +21 -0
  129. brigade_cli-0.26.1/tests/test_doctor_agent.py +295 -0
  130. brigade_cli-0.26.1/tests/test_error_refusal_copy.py +284 -0
  131. brigade_cli-0.26.1/tests/test_forward_plan_skill.py +228 -0
  132. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_handoff_cmd.py +24 -0
  133. brigade_cli-0.26.1/tests/test_handoff_readability.py +192 -0
  134. brigade_cli-0.26.1/tests/test_harness_profile_cmd.py +133 -0
  135. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_harness_user_scope.py +58 -2
  136. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_harness_user_scope_slice2.py +1 -1
  137. brigade_cli-0.26.1/tests/test_managed_block.py +282 -0
  138. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_integration.py +4 -2
  139. brigade_cli-0.26.1/tests/test_memory_care_skills.py +189 -0
  140. brigade_cli-0.26.1/tests/test_memory_cmd.py +1312 -0
  141. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_repair.py +6 -2
  142. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_phase257_facades.py +1 -0
  143. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_publish_workflow.py +140 -0
  144. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_cmd.py +199 -2
  145. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_metadata.py +18 -16
  146. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_roadmap_cmd.py +111 -0
  147. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_roster_cmd.py +4 -2
  148. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_cli.py +70 -3
  149. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_projector.py +2 -1
  150. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_resume.py +182 -0
  151. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_transport_dag.py +78 -0
  152. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_runguard.py +298 -1
  153. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_security_cmd.py +143 -0
  154. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_skill_templates_metadata.py +8 -1
  155. brigade_cli-0.26.1/tests/test_tool_output_compaction.py +139 -0
  156. brigade_cli-0.26.1/tests/test_work_cmd_claim.py +399 -0
  157. brigade_cli-0.26.1/tests/test_work_cmd_edges.py +572 -0
  158. brigade_cli-0.26.1/tests/test_work_cmd_footprint.py +201 -0
  159. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_imports.py +19 -0
  160. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_ledger.py +15 -3
  161. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_verification.py +183 -4
  162. brigade_cli-0.26.1/tests/test_work_cmd_verify_ranking.py +341 -0
  163. brigade_cli-0.26.1/tests/test_work_run_archive.py +301 -0
  164. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_worker_failure.py +1 -0
  165. brigade_cli-0.26.0/src/brigade/work_cmd/session/task_ops.py +0 -371
  166. brigade_cli-0.26.0/tests/test_harness_profile_cmd.py +0 -55
  167. brigade_cli-0.26.0/tests/test_memory_cmd.py +0 -612
  168. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/LICENSE +0 -0
  169. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/MANIFEST.in +0 -0
  170. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/QUICKSTART.md +0 -0
  171. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/THIRD_PARTY_NOTICES.md +0 -0
  172. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/setup.cfg +0 -0
  173. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/__main__.py +0 -0
  174. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/acpx_adapter.py +0 -0
  175. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/actionqueue.py +0 -0
  176. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/add.py +0 -0
  177. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/agents.py +0 -0
  178. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/budgets.py +0 -0
  179. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/budgets_cmd.py +0 -0
  180. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/core.py +0 -0
  181. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/readiness.py +0 -0
  182. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/report_review_ops.py +0 -0
  183. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/reports.py +0 -0
  184. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/center_cmd/schema_ops.py +0 -0
  185. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/chat_cmd.py +0 -0
  186. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/claude_hooks/__init__.py +0 -0
  187. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/claude_hooks/install_cmd.py +0 -0
  188. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/claude_hooks/package.py +0 -0
  189. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/claude_hooks/paths.py +0 -0
  190. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/__init__.py +0 -0
  191. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/_common.py +0 -0
  192. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/add.py +0 -0
  193. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/budgets.py +0 -0
  194. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/chat.py +0 -0
  195. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/code.py +0 -0
  196. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/completions.py +0 -0
  197. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/context.py +0 -0
  198. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/daily.py +0 -0
  199. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/dogfood.py +0 -0
  200. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/evidence.py +0 -0
  201. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/extras.py +0 -0
  202. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/friction.py +0 -0
  203. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/guard.py +0 -0
  204. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/handoff_template.py +0 -0
  205. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/hermes_fragments.py +0 -0
  206. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/ingest.py +0 -0
  207. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/init.py +0 -0
  208. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/learn.py +0 -0
  209. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/mcp.py +0 -0
  210. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/model.py +0 -0
  211. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/notifications.py +0 -0
  212. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/openclaw_fragments.py +0 -0
  213. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/operator.py +0 -0
  214. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/outcome.py +0 -0
  215. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/pantry.py +0 -0
  216. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/profiles.py +0 -0
  217. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/projects.py +0 -0
  218. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/receipts.py +0 -0
  219. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/reconfigure.py +0 -0
  220. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/release.py +0 -0
  221. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/repos.py +0 -0
  222. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/research.py +0 -0
  223. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/roadmap.py +0 -0
  224. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/roster.py +0 -0
  225. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/route.py +0 -0
  226. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/runbook.py +0 -0
  227. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/scrub.py +0 -0
  228. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/search.py +0 -0
  229. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/security.py +0 -0
  230. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/setup.py +0 -0
  231. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/skills.py +0 -0
  232. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/stations.py +0 -0
  233. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/status.py +0 -0
  234. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/tokens.py +0 -0
  235. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/tools.py +0 -0
  236. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/untrusted.py +0 -0
  237. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/update.py +0 -0
  238. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/version.py +0 -0
  239. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/work/__init__.py +0 -0
  240. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/work/phases.py +0 -0
  241. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/cli/workflow.py +0 -0
  242. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/code_cmd.py +0 -0
  243. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/code_references.py +0 -0
  244. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/codex_appserver.py +0 -0
  245. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/codex_cloud.py +0 -0
  246. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/completions.py +0 -0
  247. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/component_bins.py +0 -0
  248. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/component_install.py +0 -0
  249. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/component_manifest.py +0 -0
  250. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/component_paths.py +0 -0
  251. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/component_report.py +0 -0
  252. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/component_state.py +0 -0
  253. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/context_cmd.py +0 -0
  254. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/context_eval.py +0 -0
  255. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/__init__.py +0 -0
  256. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/approvals.py +0 -0
  257. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/candidates.py +0 -0
  258. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/closeout_ops.py +0 -0
  259. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/config.py +0 -0
  260. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/hardening.py +0 -0
  261. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/run_loop.py +0 -0
  262. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/status_plan.py +0 -0
  263. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/daily_cmd/telemetry_ops.py +0 -0
  264. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/evidence_brief.py +0 -0
  265. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/evidence_cmd.py +0 -0
  266. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/evidence_runtime.py +0 -0
  267. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/extras.py +0 -0
  268. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/fixtures/provenance-envelope.v1.golden.json +0 -0
  269. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/fixtures/trust-policy.v1.json +0 -0
  270. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/fragments.py +0 -0
  271. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/friction_cmd.py +0 -0
  272. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/graphtrail_delta.py +0 -0
  273. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/__init__.py +0 -0
  274. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/__main__.py +0 -0
  275. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/allowlist.py +0 -0
  276. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/baseline.py +0 -0
  277. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/cli.py +0 -0
  278. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/detectors/__init__.py +0 -0
  279. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/detectors/opf.py +0 -0
  280. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/engine.py +0 -0
  281. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/examples/n8n-validation/blocked-local-service.json +0 -0
  282. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/examples/n8n-validation/blocked-secret-token.json +0 -0
  283. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/examples/n8n-validation/clean-blog-post.json +0 -0
  284. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/examples/n8n-validation/clean-social-post.json +0 -0
  285. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/examples/n8n-validation/warn-review-email.json +0 -0
  286. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/git_commits.py +0 -0
  287. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/git_scan.py +0 -0
  288. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/n8n_advisory.py +0 -0
  289. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/n8n_validate.py +0 -0
  290. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/policies/in-house-repo.json +0 -0
  291. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/policies/openclaw-message.json +0 -0
  292. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/policies/pr-draft.json +0 -0
  293. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/policies/public-content.json +0 -0
  294. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/policies/public-repo.json +0 -0
  295. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/policy.py +0 -0
  296. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/pr_draft.py +0 -0
  297. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/pr_prepare.py +0 -0
  298. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/publish_check.py +0 -0
  299. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/report.py +0 -0
  300. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/rev_range.py +0 -0
  301. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/rules.py +0 -0
  302. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/guard/types.py +0 -0
  303. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/__init__.py +0 -0
  304. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/inspect_ops.py +0 -0
  305. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_cmd/issue_ops.py +0 -0
  306. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/handoff_content.py +0 -0
  307. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/hermes_adapter.py +0 -0
  308. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/localio.py +0 -0
  309. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/managed.py +0 -0
  310. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/managed_snapshot.py +0 -0
  311. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/mcp_adapters.py +0 -0
  312. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/mcp_runtime.py +0 -0
  313. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/mcp_server.py +0 -0
  314. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/__init__.py +0 -0
  315. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/__main__.py +0 -0
  316. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/cli.py +0 -0
  317. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/git.py +0 -0
  318. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/init_git.py +0 -0
  319. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/paths.py +0 -0
  320. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/safety.py +0 -0
  321. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor/status.py +0 -0
  322. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/memory_doctor_cmd.py +0 -0
  323. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/model_inventory.py +0 -0
  324. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/model_scorecard.py +0 -0
  325. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/model_trials.py +0 -0
  326. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/notifications_cmd.py +0 -0
  327. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/__init__.py +0 -0
  328. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/adoption.py +0 -0
  329. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/guide.py +0 -0
  330. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/health.py +0 -0
  331. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/migration.py +0 -0
  332. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/operator_cmd/surfaces.py +0 -0
  333. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/outcome.py +0 -0
  334. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/pantry_cmd.py +0 -0
  335. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/pantry_compat.py +0 -0
  336. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/phases_cmd/__init__.py +0 -0
  337. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/phases_cmd/checks_actions.py +0 -0
  338. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/phases_cmd/constants.py +0 -0
  339. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/phases_cmd/session_lifecycle.py +0 -0
  340. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/phases_cmd/session_ops.py +0 -0
  341. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/pi_mcp_bridge.py +0 -0
  342. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/proc.py +0 -0
  343. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/profiles.py +0 -0
  344. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/profiles_cmd.py +0 -0
  345. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/projects_cmd.py +0 -0
  346. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/prompt.py +0 -0
  347. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/provenance.py +0 -0
  348. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/py.typed +0 -0
  349. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/receipt_signing.py +0 -0
  350. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/reconfigure.py +0 -0
  351. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/registry.py +0 -0
  352. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/__init__.py +0 -0
  353. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/candidate_audit_ops.py +0 -0
  354. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/commands.py +0 -0
  355. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/evidence.py +0 -0
  356. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/install_smoke.py +0 -0
  357. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/schema_ops.py +0 -0
  358. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_cmd/version_guard.py +0 -0
  359. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/release_version_sync.py +0 -0
  360. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/render.py +0 -0
  361. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/reportstore.py +0 -0
  362. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/__init__.py +0 -0
  363. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/actions_dispatch.py +0 -0
  364. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/constants.py +0 -0
  365. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/fleet.py +0 -0
  366. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/friction_fleet.py +0 -0
  367. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/repos_cmd/release_ops.py +0 -0
  368. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/__init__.py +0 -0
  369. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/config.py +0 -0
  370. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/engine.py +0 -0
  371. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/extract.py +0 -0
  372. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/handoff.py +0 -0
  373. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/llm.py +0 -0
  374. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/registry.py +0 -0
  375. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/report.py +0 -0
  376. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/sources/__init__.py +0 -0
  377. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/sources/cli.py +0 -0
  378. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/sources/web.py +0 -0
  379. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/research/types.py +0 -0
  380. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/result_integrity.py +0 -0
  381. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/route_catalog.py +0 -0
  382. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/route_policy.py +0 -0
  383. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/route_receipts.py +0 -0
  384. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/router.py +0 -0
  385. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_audit.py +0 -0
  386. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_checkpoint.py +0 -0
  387. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_control.py +0 -0
  388. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_control_journal.py +0 -0
  389. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_event_cursor.py +0 -0
  390. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_events.py +0 -0
  391. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_journal.py +0 -0
  392. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_lifecycle.py +0 -0
  393. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_receipts.py +0 -0
  394. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_redaction.py +0 -0
  395. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/run_shadow.py +0 -0
  396. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/runs_cmd.py +0 -0
  397. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/scorecard.py +0 -0
  398. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/search_cmd.py +0 -0
  399. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/seat_health.py +0 -0
  400. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/commands.py +0 -0
  401. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/config.py +0 -0
  402. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/enrichment.py +0 -0
  403. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/reports.py +0 -0
  404. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/suppression.py +0 -0
  405. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/security_cmd/template_audit_ops.py +0 -0
  406. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/selection.py +0 -0
  407. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/station.py +0 -0
  408. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/station_health.py +0 -0
  409. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/station_manifest.py +0 -0
  410. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/stations_cmd.py +0 -0
  411. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/status.py +0 -0
  412. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/telemetry_export.py +0 -0
  413. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/adal/memory-handoffs/TEMPLATE.md +0 -0
  414. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/aider/memory-handoffs/TEMPLATE.md +0 -0
  415. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/amp/memory-handoffs/TEMPLATE.md +0 -0
  416. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/antigravity/memory-handoffs/TEMPLATE.md +0 -0
  417. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/claude/memory-handoffs/TEMPLATE.md +0 -0
  418. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/codex/memory-handoffs/TEMPLATE.md +0 -0
  419. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/continue/memory-handoffs/TEMPLATE.md +0 -0
  420. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/copilot/memory-handoffs/TEMPLATE.md +0 -0
  421. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/crush/memory-handoffs/TEMPLATE.md +0 -0
  422. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/cursor/memory-handoffs/TEMPLATE.md +0 -0
  423. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/depth/repo.json +0 -0
  424. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/depth/workspace.json +0 -0
  425. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/failed-verification/cases/acknowledge-broken-receipt.prompt.md +0 -0
  426. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/failed-verification/cases/report-failing-tests.prompt.md +0 -0
  427. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/failed-verification/manifest.json +0 -0
  428. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/prompt-injection/cases/disregard-system-prompt.prompt.md +0 -0
  429. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/prompt-injection/cases/fake-system-block.prompt.md +0 -0
  430. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/prompt-injection/cases/handoff-lint-regression.prompt.md +0 -0
  431. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/prompt-injection/fixtures/handoff-lint-regression.md +0 -0
  432. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/prompt-injection/manifest.json +0 -0
  433. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/unsafe-command/cases/refuse-destructive-shell.prompt.md +0 -0
  434. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/unsafe-command/cases/refuse-force-push.prompt.md +0 -0
  435. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/unsafe-command/manifest.json +0 -0
  436. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/untrusted-evidence/cases/benign-quoted-payload.prompt.md +0 -0
  437. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/untrusted-evidence/cases/hostile-tool-output.prompt.md +0 -0
  438. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/evals/adversarial/untrusted-evidence/manifest.json +0 -0
  439. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/generic/harness-adapter-checklist.md +0 -0
  440. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/generic/memory-contract.md +0 -0
  441. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/goose/memory-handoffs/TEMPLATE.md +0 -0
  442. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/grok/hooks/brigade-work.json +0 -0
  443. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/grok/hooks/brigade-work.sh +0 -0
  444. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/grok/memory-handoffs/TEMPLATE.md +0 -0
  445. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/handoff/handoff-sources.example.json +0 -0
  446. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/handoff/openclaw-ingest-receipt.example.json +0 -0
  447. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/adal.json +0 -0
  448. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/aider.json +0 -0
  449. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/amp.json +0 -0
  450. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/antigravity.json +0 -0
  451. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/claude.json +0 -0
  452. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/codex.json +0 -0
  453. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/continue.json +0 -0
  454. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/copilot.json +0 -0
  455. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/crush.json +0 -0
  456. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/cursor.json +0 -0
  457. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/goose.json +0 -0
  458. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/grok.json +0 -0
  459. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/hermes.json +0 -0
  460. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/kimi.json +0 -0
  461. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/openclaw.json +0 -0
  462. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/opencode.json +0 -0
  463. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/openhands.json +0 -0
  464. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/pi.json +0 -0
  465. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/harnesses/qwen.json +0 -0
  466. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/hermes/README.md +0 -0
  467. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/hermes/memory-handoffs/TEMPLATE.md +0 -0
  468. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/hooks/pre-push +0 -0
  469. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/includes/publisher.json +0 -0
  470. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/includes/repo-extras.json +0 -0
  471. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/kimi/memory-handoffs/TEMPLATE.md +0 -0
  472. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/backup-restic.md +0 -0
  473. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/chat-surface-crawlers.md +0 -0
  474. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/content-safety.md +0 -0
  475. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/handoff-flow.md +0 -0
  476. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/memory-architecture.md +0 -0
  477. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/memory-care-staleness.md +0 -0
  478. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/memory-scanner.md +0 -0
  479. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/multi-workspace-handoff-admin.md +0 -0
  480. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/obsidian-notes.md +0 -0
  481. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/pipeline-standups.md +0 -0
  482. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/memory/cards/token-glace-output-compaction.md +0 -0
  483. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/openclaw/README.md +0 -0
  484. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/openclaw/acp-escalation.openclaw.json +0 -0
  485. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/openclaw/memory-sweep-cron.openclaw.json +0 -0
  486. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/openclaw/model-aliases.openclaw.json +0 -0
  487. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/openclaw/ollama-memory-search.openclaw.json +0 -0
  488. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/opencode/memory-handoffs/TEMPLATE.md +0 -0
  489. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/openhands/memory-handoffs/TEMPLATE.md +0 -0
  490. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/pi/extensions/brigade-mcp-bridge.js +0 -0
  491. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/pi/memory-handoffs/TEMPLATE.md +0 -0
  492. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/qwen/memory-handoffs/TEMPLATE.md +0 -0
  493. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/repo/AGENTS.md +0 -0
  494. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/repo/CLAUDE.md +0 -0
  495. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/repo/INSTALL_FOR_AGENTS.md +0 -0
  496. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/rosters/budget-open-weight.toml +0 -0
  497. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/rosters/full-multi-lane.toml +0 -0
  498. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/rosters/minimal-single-cli.toml +0 -0
  499. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/rosters/review-heavy.toml +0 -0
  500. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/scripts/backup-restic.sh +0 -0
  501. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/brigade-work/CHANGELOG.md +0 -0
  502. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/brigade-work/SKILL.md +0 -0
  503. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/brigade-work/skill.json +0 -0
  504. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/note/CHANGELOG.md +0 -0
  505. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/note/SKILL.md +0 -0
  506. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/note/skill.json +0 -0
  507. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/ultra-work-scout/CHANGELOG.md +0 -0
  508. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/ultra-work-scout/SKILL.md +0 -0
  509. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/skills/ultra-work-scout/skill.json +0 -0
  510. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/stations/managed-snapshot.json +0 -0
  511. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/AGENTS.md +0 -0
  512. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/CLAUDE.md +0 -0
  513. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/HEARTBEAT.md +0 -0
  514. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/IDENTITY.md +0 -0
  515. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/INSTALL_FOR_AGENTS.md +0 -0
  516. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/MEMORY.md +0 -0
  517. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/SAFETY_RULES.md +0 -0
  518. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/SOUL.md +0 -0
  519. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/TOOLS.md +0 -0
  520. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/USER.md +0 -0
  521. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/rules/acceptance-driven-work.md +0 -0
  522. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates/workspace/rules/issue-tdd-loop.md +0 -0
  523. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/templates.py +0 -0
  524. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tokens_cmd.py +0 -0
  525. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/toml_compat.py +0 -0
  526. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/__init__.py +0 -0
  527. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/calls.py +0 -0
  528. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/catalog_health.py +0 -0
  529. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/catalog_manage.py +0 -0
  530. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/checkpoint_store.py +0 -0
  531. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/checkpoints.py +0 -0
  532. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/config.py +0 -0
  533. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/constants.py +0 -0
  534. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/helpers.py +0 -0
  535. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/issues.py +0 -0
  536. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/mcp.py +0 -0
  537. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/packs.py +0 -0
  538. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/paths.py +0 -0
  539. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/projections.py +0 -0
  540. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/runtimes.py +0 -0
  541. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/safety.py +0 -0
  542. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/tools_cmd/status.py +0 -0
  543. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/untrusted.py +0 -0
  544. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/untrusted_cmd.py +0 -0
  545. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/update_cmd.py +0 -0
  546. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/update_notify.py +0 -0
  547. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/verify_manifest.py +0 -0
  548. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/verify_trial.py +0 -0
  549. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/version_cmd.py +0 -0
  550. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/wiring.py +0 -0
  551. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/backup.py +0 -0
  552. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/config.py +0 -0
  553. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/helpers.py +0 -0
  554. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/scanners.py +0 -0
  555. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/session/__init__.py +0 -0
  556. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/work_cmd/sweeps.py +0 -0
  557. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade/workflow_cmd.py +0 -0
  558. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade_cli.egg-info/dependency_links.txt +0 -0
  559. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade_cli.egg-info/entry_points.txt +0 -0
  560. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade_cli.egg-info/requires.txt +0 -0
  561. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/src/brigade_cli.egg-info/top_level.txt +0 -0
  562. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_aboyeur_seat_health_probe.py +0 -0
  563. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_aboyeur_status.py +0 -0
  564. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_acpx_adapter.py +0 -0
  565. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_actionqueue.py +0 -0
  566. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_add.py +0 -0
  567. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agent_notify_station_contracts.py +0 -0
  568. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agent_write_probes.py +0 -0
  569. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agents.py +0 -0
  570. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agents_model_pin.py +0 -0
  571. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agents_oracle.py +0 -0
  572. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_agents_windows_executable.py +0 -0
  573. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_budgets.py +0 -0
  574. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_center_actions_cmd.py +0 -0
  575. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_center_readiness_cmd.py +0 -0
  576. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_center_report_cmd.py +0 -0
  577. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_claude_hooks_settings_merge.py +0 -0
  578. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_claude_hooks_user_scope.py +0 -0
  579. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_cli_help.py +0 -0
  580. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_cli_setup.py +0 -0
  581. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_cli_update.py +0 -0
  582. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_code_reference_schema.py +0 -0
  583. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_code_verbs_and_target.py +0 -0
  584. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_codex_appserver.py +0 -0
  585. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_codex_appserver_integration.py +0 -0
  586. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_codex_cloud.py +0 -0
  587. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_completions.py +0 -0
  588. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_bins.py +0 -0
  589. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_install.py +0 -0
  590. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_manifest_provenance.py +0 -0
  591. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_paths.py +0 -0
  592. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_report.py +0 -0
  593. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_component_state.py +0 -0
  594. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_context_cmd.py +0 -0
  595. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_context_learning_closeout_cmd.py +0 -0
  596. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_cursor_install_state_migration.py +0 -0
  597. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_cursor_user_cmd.py +0 -0
  598. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_daily_driver_cmd.py +0 -0
  599. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_dogfood_cmd.py +0 -0
  600. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_evidence_branded_surface.py +0 -0
  601. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_evidence_cmd.py +0 -0
  602. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_evidence_runtime.py +0 -0
  603. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_extras_gate.py +0 -0
  604. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_fleet_action_dispatch_cmd.py +0 -0
  605. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_fragments.py +0 -0
  606. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_friction_cmd.py +0 -0
  607. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_gitignore.py +0 -0
  608. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_graphtrail_delta.py +0 -0
  609. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_grok_hook_runtime.py +0 -0
  610. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_handoff.py +0 -0
  611. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_handoff_injection_lint.py +0 -0
  612. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_harness_conformance_probe.py +0 -0
  613. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_ingest.py +0 -0
  614. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_init.py +0 -0
  615. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_install.py +0 -0
  616. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_issue266_benchmark.py +0 -0
  617. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_issue266_work_status_memory.py +0 -0
  618. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_issue362_code_evidence_facades.py +0 -0
  619. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_localio.py +0 -0
  620. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_managed.py +0 -0
  621. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_managed_snapshot.py +0 -0
  622. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_adapters.py +0 -0
  623. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_cmd.py +0 -0
  624. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_runtime.py +0 -0
  625. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_server.py +0 -0
  626. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_url_only_import.py +0 -0
  627. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_mcp_user_scope.py +0 -0
  628. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_memory_search_mcp.py +0 -0
  629. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_model_inventory.py +0 -0
  630. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_model_scorecard.py +0 -0
  631. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_model_trials.py +0 -0
  632. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_model_trials_adversarial_fixtures.py +0 -0
  633. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_neutrality.py +0 -0
  634. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_notifications_cmd.py +0 -0
  635. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_operator_checkup.py +0 -0
  636. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_operator_cmd.py +0 -0
  637. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome.py +0 -0
  638. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_activegraph.py +0 -0
  639. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_backfill_scorecard.py +0 -0
  640. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_cmd.py +0 -0
  641. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_execute.py +0 -0
  642. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_infrastructure_attribution.py +0 -0
  643. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_outcome_reused_receipt_dedup.py +0 -0
  644. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_pantry_cmd.py +0 -0
  645. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_pantry_compat.py +0 -0
  646. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_parity_backlog.py +0 -0
  647. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_phase_ledger_session_cmd.py +0 -0
  648. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_phases_cmd_facade.py +0 -0
  649. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_pi_mcp_bridge.py +0 -0
  650. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_pre_push_hook.py +0 -0
  651. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_privacy_regression.py +0 -0
  652. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_proc.py +0 -0
  653. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_profiles.py +0 -0
  654. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_prompt.py +0 -0
  655. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_provenance_envelope.py +0 -0
  656. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_published_artifact_acceptance.py +0 -0
  657. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_read_only_enforcement.py +0 -0
  658. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_receipt_schema_audit.py +0 -0
  659. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_receipt_signing.py +0 -0
  660. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_receipts_cmd.py +0 -0
  661. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_reconfigure.py +0 -0
  662. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_registry.py +0 -0
  663. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_checklist.py +0 -0
  664. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_ci_health_cmd.py +0 -0
  665. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_manifest_generator.py +0 -0
  666. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_readiness_hygiene_cmd.py +0 -0
  667. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_reconcile_evidence_cmd.py +0 -0
  668. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_smoke_health_cmd.py +0 -0
  669. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_train_evidence_cmd.py +0 -0
  670. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_version_guard.py +0 -0
  671. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_version_sync.py +0 -0
  672. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_release_waivers_manifest_cmd.py +0 -0
  673. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repeat_watch_approval_runner.py +0 -0
  674. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_report_review_closeout_cmd.py +0 -0
  675. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_reportstore.py +0 -0
  676. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_actions_cmd.py +0 -0
  677. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_adoption_cmd.py +0 -0
  678. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_cmd.py +0 -0
  679. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_cmd_facade.py +0 -0
  680. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_friction_cmd.py +0 -0
  681. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_release_train_cmd.py +0 -0
  682. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_repos_sweep_health_cmd.py +0 -0
  683. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_cli_sources.py +0 -0
  684. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_cmd.py +0 -0
  685. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_config.py +0 -0
  686. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_engine.py +0 -0
  687. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_extract.py +0 -0
  688. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_handoff.py +0 -0
  689. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_llm.py +0 -0
  690. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_local_sources.py +0 -0
  691. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_registry.py +0 -0
  692. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_report.py +0 -0
  693. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_types.py +0 -0
  694. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_research_web.py +0 -0
  695. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_roadmap_inventory_cmd.py +0 -0
  696. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_roster.py +0 -0
  697. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_route_policy.py +0 -0
  698. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_route_receipts.py +0 -0
  699. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_router.py +0 -0
  700. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_router_properties.py +0 -0
  701. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_audit.py +0 -0
  702. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_checkpoint.py +0 -0
  703. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_control.py +0 -0
  704. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_detach.py +0 -0
  705. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_event_cursor.py +0 -0
  706. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_events.py +0 -0
  707. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_events_cursor_control.py +0 -0
  708. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_journal.py +0 -0
  709. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_journal_measurement.py +0 -0
  710. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_lifecycle.py +0 -0
  711. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_redaction.py +0 -0
  712. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_shadow.py +0 -0
  713. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_transport_env.py +0 -0
  714. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_transport_failfast.py +0 -0
  715. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_run_transport_recovery.py +0 -0
  716. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_runbook_cmd.py +0 -0
  717. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_runbook_import.py +0 -0
  718. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_runs_cmd.py +0 -0
  719. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_runs_watch.py +0 -0
  720. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_scorecard.py +0 -0
  721. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_scorecard_reconcile.py +0 -0
  722. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_scrub.py +0 -0
  723. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_search_cmd.py +0 -0
  724. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_seat_health.py +0 -0
  725. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_security_diff.py +0 -0
  726. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_security_template_audit_cmd.py +0 -0
  727. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_selection.py +0 -0
  728. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_skills_cmd.py +0 -0
  729. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_station.py +0 -0
  730. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_station_manifest.py +0 -0
  731. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_stations_discover.py +0 -0
  732. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_stations_verify.py +0 -0
  733. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_status.py +0 -0
  734. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_subprocess_guards.py +0 -0
  735. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_surface_aware_install.py +0 -0
  736. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_telemetry_export.py +0 -0
  737. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_test_fixture_contract.py +0 -0
  738. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_thread_sync.py +0 -0
  739. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_tokens_cmd.py +0 -0
  740. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_toml_compat.py +0 -0
  741. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_tools_cmd_facade.py +0 -0
  742. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_untrusted.py +0 -0
  743. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_untrusted_cmd.py +0 -0
  744. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_update_cmd.py +0 -0
  745. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_update_notify.py +0 -0
  746. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_verify_script.py +0 -0
  747. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_verify_trial.py +0 -0
  748. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_version_sync_script.py +0 -0
  749. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_waiver_policy_health_cmd.py +0 -0
  750. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_wiring_resolve_target.py +0 -0
  751. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_backup.py +0 -0
  752. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_facade.py +0 -0
  753. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_reviews.py +0 -0
  754. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_scanners.py +0 -0
  755. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_services.py +0 -0
  756. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_session.py +0 -0
  757. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_work_cmd_sweeps.py +0 -0
  758. {brigade_cli-0.26.0 → brigade_cli-0.26.1}/tests/test_workflow_cmd.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: brigade-cli
3
- Version: 0.26.0
3
+ Version: 0.26.1
4
4
  Summary: Your agents run loops. Brigade keeps the receipts. Local control plane for multi-agent coding: share MCP/tools/memory, remember via handoffs, prove with file receipts, improve by promoting skills only on real exit codes. Claude Code, Codex, Grok, Hermes, OpenClaw, and more. Stations for evidence, code graph, pantry, skills. pipx install brigade-cli.
5
5
  Author-email: Solomon Neas <me@solomonneas.dev>
6
6
  License: MIT
@@ -50,14 +50,15 @@ Dynamic: license-file
50
50
  <h1 align="center">Brigade</h1>
51
51
 
52
52
  <p align="center">
53
- <strong>Your agents run loops. Brigade keeps the receipts.</strong>
53
+ <strong>One command to start. One command to keep it maintained.</strong>
54
54
  </p>
55
55
 
56
56
  <p align="center">
57
57
  <strong>Built for coding agents to run end to end</strong> (install, setup, verify, handoffs), not as a human day-to-day terminal app.
58
58
  When an agent says tests passed, you get a file with the real exit code, a <strong>code graph</strong> of what changed (<code>brigade code</code>), and an <strong>evidence log</strong> you can search later (<code>brigade evidence</code>).
59
59
  Optional: one MCP and tools catalog across agents, and shared notes with a review gate.
60
- Local files. No daemon. No lock-in.
60
+ Brigade owns the memory-care primitives and runbooks. An external scheduler (cron, systemd, CI, your agent cron) invokes them. Local files. No daemon. No lock-in.
61
+ Boundary: <a href="docs/execution-model.md">execution model</a>.
61
62
  </p>
62
63
 
63
64
  <p align="center">
@@ -287,7 +288,7 @@ Beyond the daily loop, the same review-and-receipt pattern covers cross-model ru
287
288
  - **Native harness memory** is a per-tool silo. It does not cross harnesses, and it writes without review. Brigade gives every tool one shared format and one canonical owner, with a review gate in between.
288
289
  - **Already running Hermes, or any self-improving agent?** Keep it. Brigade is the verification layer on top: it promotes a skill only when a real signal confirms it, keeps every learned skill as portable markdown in your git, and runs one loop across your whole fleet.
289
290
  - **A plain CLAUDE.md / AGENTS.md** works great until it bloats past the context budget and goes stale. Brigade keeps bootstrap files slim, moves detail into indexed cards, and flags staleness instead of trusting last month's facts forever.
290
- - **A daemon or hosted service** would be simpler to demo and worse to trust. Brigade writes local files when you run a command, and that is all it does.
291
+ - **A daemon or hosted service** would be simpler to demo and worse to trust. Brigade writes local files when you run a command, and that is all it does. See the [execution model](docs/execution-model.md).
291
292
 
292
293
  | | Across harnesses | MCP, tools, and memory in one source | Review gate + receipts | Local files, no daemon |
293
294
  |---|:---:|:---:|:---:|:---:|
@@ -298,7 +299,7 @@ Beyond the daily loop, the same review-and-receipt pattern covers cross-model ru
298
299
 
299
300
  ## What Brigade is not
300
301
 
301
- Brigade is not a hosted memory service, a daemon, or an automatic release bot. It does not run in the background or install schedulers (one scoped exception: `brigade tools runtime start` launches a local runtime process, only when you start it, until you stop it). It does not push to GitHub, publish packages, save every note automatically, or skip review for ambiguous, risky, or failed notes. `brigade work brief` and related status surfaces may report notification readiness or suggest installing the notifications station, but Brigade never sends a message unless the operator uses an explicit send action such as `brigade pantry expiry-alert --send`. That pause is the point: agent memory should be useful, not noisy.
302
+ Brigade is not a hosted memory service, a daemon, or an automatic release bot. It does not run in the background. Scheduling stays with the operator (see the [execution model](docs/execution-model.md)). It does not push to GitHub, publish packages, save every note automatically, or skip review for ambiguous, risky, or failed notes. `brigade work brief` and related status surfaces may report notification readiness or suggest installing the notifications station, but Brigade never sends a message unless the operator uses an explicit send action such as `brigade pantry expiry-alert --send`. That pause is the point: agent memory should be useful, not noisy.
302
303
 
303
304
  And it is not the other projects that share the name. This Brigade is the AI-agent operator CLI from [`escoffier-labs/brigade`](https://github.com/escoffier-labs/brigade), installed with `pipx install brigade-cli`. It is not the CNCF/Microsoft Brigade for Kubernetes event scripting (archived 2022), the Spinabot Brigade agent crew, or the 2017 `brigade` Python package that became Nornir.
304
305
 
@@ -334,7 +335,8 @@ Nineteen harnesses get handoff inboxes and ingest coverage, from Codex, Claude C
334
335
  ## Docs
335
336
 
336
337
  - [First 10 minutes](docs/first-10-minutes.md) · [Overview](docs/overview.md) · [Technical guide](docs/technical-guide.md)
337
- - [MCP sync](docs/mcp-sync.md) · [Security and Content Guard](docs/security.md) · [Handoff promotion](docs/handoff-promotion.md)
338
+ - [Execution model](docs/execution-model.md) · [Memory care](docs/memory-care.md) · [MCP sync](docs/mcp-sync.md)
339
+ - [Security and Content Guard](docs/security.md) · [Handoff promotion](docs/handoff-promotion.md)
338
340
  - [Command inventory](docs/command-inventory.md) · [Station contract](docs/station-contract.md)
339
341
  - [Maintainers](MAINTAINERS.md) · [Governance](GOVERNANCE.md) · [Security](SECURITY.md) · [Contributing](CONTRIBUTING.md) · [Roadmap](ROADMAP.md)
340
342
 
@@ -5,14 +5,15 @@
5
5
  <h1 align="center">Brigade</h1>
6
6
 
7
7
  <p align="center">
8
- <strong>Your agents run loops. Brigade keeps the receipts.</strong>
8
+ <strong>One command to start. One command to keep it maintained.</strong>
9
9
  </p>
10
10
 
11
11
  <p align="center">
12
12
  <strong>Built for coding agents to run end to end</strong> (install, setup, verify, handoffs), not as a human day-to-day terminal app.
13
13
  When an agent says tests passed, you get a file with the real exit code, a <strong>code graph</strong> of what changed (<code>brigade code</code>), and an <strong>evidence log</strong> you can search later (<code>brigade evidence</code>).
14
14
  Optional: one MCP and tools catalog across agents, and shared notes with a review gate.
15
- Local files. No daemon. No lock-in.
15
+ Brigade owns the memory-care primitives and runbooks. An external scheduler (cron, systemd, CI, your agent cron) invokes them. Local files. No daemon. No lock-in.
16
+ Boundary: <a href="docs/execution-model.md">execution model</a>.
16
17
  </p>
17
18
 
18
19
  <p align="center">
@@ -242,7 +243,7 @@ Beyond the daily loop, the same review-and-receipt pattern covers cross-model ru
242
243
  - **Native harness memory** is a per-tool silo. It does not cross harnesses, and it writes without review. Brigade gives every tool one shared format and one canonical owner, with a review gate in between.
243
244
  - **Already running Hermes, or any self-improving agent?** Keep it. Brigade is the verification layer on top: it promotes a skill only when a real signal confirms it, keeps every learned skill as portable markdown in your git, and runs one loop across your whole fleet.
244
245
  - **A plain CLAUDE.md / AGENTS.md** works great until it bloats past the context budget and goes stale. Brigade keeps bootstrap files slim, moves detail into indexed cards, and flags staleness instead of trusting last month's facts forever.
245
- - **A daemon or hosted service** would be simpler to demo and worse to trust. Brigade writes local files when you run a command, and that is all it does.
246
+ - **A daemon or hosted service** would be simpler to demo and worse to trust. Brigade writes local files when you run a command, and that is all it does. See the [execution model](docs/execution-model.md).
246
247
 
247
248
  | | Across harnesses | MCP, tools, and memory in one source | Review gate + receipts | Local files, no daemon |
248
249
  |---|:---:|:---:|:---:|:---:|
@@ -253,7 +254,7 @@ Beyond the daily loop, the same review-and-receipt pattern covers cross-model ru
253
254
 
254
255
  ## What Brigade is not
255
256
 
256
- Brigade is not a hosted memory service, a daemon, or an automatic release bot. It does not run in the background or install schedulers (one scoped exception: `brigade tools runtime start` launches a local runtime process, only when you start it, until you stop it). It does not push to GitHub, publish packages, save every note automatically, or skip review for ambiguous, risky, or failed notes. `brigade work brief` and related status surfaces may report notification readiness or suggest installing the notifications station, but Brigade never sends a message unless the operator uses an explicit send action such as `brigade pantry expiry-alert --send`. That pause is the point: agent memory should be useful, not noisy.
257
+ Brigade is not a hosted memory service, a daemon, or an automatic release bot. It does not run in the background. Scheduling stays with the operator (see the [execution model](docs/execution-model.md)). It does not push to GitHub, publish packages, save every note automatically, or skip review for ambiguous, risky, or failed notes. `brigade work brief` and related status surfaces may report notification readiness or suggest installing the notifications station, but Brigade never sends a message unless the operator uses an explicit send action such as `brigade pantry expiry-alert --send`. That pause is the point: agent memory should be useful, not noisy.
257
258
 
258
259
  And it is not the other projects that share the name. This Brigade is the AI-agent operator CLI from [`escoffier-labs/brigade`](https://github.com/escoffier-labs/brigade), installed with `pipx install brigade-cli`. It is not the CNCF/Microsoft Brigade for Kubernetes event scripting (archived 2022), the Spinabot Brigade agent crew, or the 2017 `brigade` Python package that became Nornir.
259
260
 
@@ -289,7 +290,8 @@ Nineteen harnesses get handoff inboxes and ingest coverage, from Codex, Claude C
289
290
  ## Docs
290
291
 
291
292
  - [First 10 minutes](docs/first-10-minutes.md) · [Overview](docs/overview.md) · [Technical guide](docs/technical-guide.md)
292
- - [MCP sync](docs/mcp-sync.md) · [Security and Content Guard](docs/security.md) · [Handoff promotion](docs/handoff-promotion.md)
293
+ - [Execution model](docs/execution-model.md) · [Memory care](docs/memory-care.md) · [MCP sync](docs/mcp-sync.md)
294
+ - [Security and Content Guard](docs/security.md) · [Handoff promotion](docs/handoff-promotion.md)
293
295
  - [Command inventory](docs/command-inventory.md) · [Station contract](docs/station-contract.md)
294
296
  - [Maintainers](MAINTAINERS.md) · [Governance](GOVERNANCE.md) · [Security](SECURITY.md) · [Contributing](CONTRIBUTING.md) · [Roadmap](ROADMAP.md)
295
297
 
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "brigade-cli"
7
- version = "0.26.0"
7
+ version = "0.26.1"
8
8
  description = "Your agents run loops. Brigade keeps the receipts. Local control plane for multi-agent coding: share MCP/tools/memory, remember via handoffs, prove with file receipts, improve by promoting skills only on real exit codes. Claude Code, Codex, Grok, Hermes, OpenClaw, and more. Stations for evidence, code graph, pantry, skills. pipx install brigade-cli."
9
9
  readme = "README.md"
10
10
  requires-python = ">=3.10"
@@ -1,3 +1,3 @@
1
1
  """Brigade: local operator-system CLI for agent workspaces."""
2
2
 
3
- __version__ = "0.26.0"
3
+ __version__ = "0.26.1"
@@ -44,7 +44,7 @@ from .run_receipts import (
44
44
  write_agent_logs as _write_agent_logs,
45
45
  write_worker_logs as _write_worker_logs,
46
46
  )
47
- from .run_transport import Assignment, WorkerResult
47
+ from .run_transport import Assignment, WorkerResult, dag_cycle_members
48
48
  from .roster import Agent, Roster, is_cli_allowed, read_only_capability_error, timeout_for, workers
49
49
  from .route_catalog import RouteBrief, route_brief, uncovered_stages, unknown_covers
50
50
  from .route_policy import (
@@ -1329,6 +1329,14 @@ def _unknown_covers(route: RouteBrief | None, assignments: list[Assignment]) ->
1329
1329
  return unknown_covers(route, assignments)
1330
1330
 
1331
1331
 
1332
+ def _validate_plan_dependencies(route: RouteBrief | None, assignments: list[Assignment]) -> None:
1333
+ if route is None or not route.attached:
1334
+ return
1335
+ members = dag_cycle_members(assignments, route.dependencies)
1336
+ if members:
1337
+ raise ValueError(f"plan has a dependency cycle involving: {', '.join(members)}")
1338
+
1339
+
1332
1340
  def _orchestrator_hides_write_tools(
1333
1341
  roster: Roster,
1334
1342
  *,
@@ -1394,6 +1402,7 @@ def plan(
1394
1402
  raise RuntimeError(f"orchestrator failed during plan: {first.detail}")
1395
1403
  try:
1396
1404
  assignments = parse_plan(first.text, roster, read_only=read_only, skill_policy=skill_policy)
1405
+ _validate_plan_dependencies(route, assignments)
1397
1406
  _record_plan_attempt(
1398
1407
  attempts,
1399
1408
  stage="initial",
@@ -1433,6 +1442,7 @@ def plan(
1433
1442
  raise RuntimeError(f"orchestrator failed during plan correction: {second.detail}") from exc
1434
1443
  try:
1435
1444
  assignments = parse_plan(second.text, roster, read_only=read_only, skill_policy=skill_policy)
1445
+ _validate_plan_dependencies(route, assignments)
1436
1446
  _record_plan_attempt(
1437
1447
  attempts,
1438
1448
  stage="correction",
@@ -1487,6 +1497,7 @@ def plan(
1487
1497
  return assignments
1488
1498
  try:
1489
1499
  revised = parse_plan(revised_result.text, roster, read_only=read_only, skill_policy=skill_policy)
1500
+ _validate_plan_dependencies(route, revised)
1490
1501
  except ValueError as exc:
1491
1502
  _record_plan_attempt(attempts, stage="coverage-correction", result=revised_result, parse_error=str(exc))
1492
1503
  return assignments
@@ -2708,6 +2719,8 @@ def _run_payload(
2708
2719
  payload["run_journal_authority_requested"] = True
2709
2720
  if resolution := _roster_resolution_payload(roster):
2710
2721
  payload["roster"] = resolution
2722
+ if roster.seat_routing:
2723
+ payload["seat_routing"] = [dict(decision) for decision in roster.seat_routing]
2711
2724
  if lock_workspace is not None:
2712
2725
  payload["lock_workspace"] = str(lock_workspace)
2713
2726
  if route is not None:
@@ -3006,6 +3019,7 @@ class OrchestratorHealthRoutingDecision:
3006
3019
  abort_detail: str | None = None
3007
3020
  abort_failure_phase: str = "preflight"
3008
3021
  abort_failure_kind: str = "unclassified"
3022
+ abort_seat: str | None = None
3009
3023
  receipt: dict[str, object] | None = None
3010
3024
 
3011
3025
 
@@ -3030,61 +3044,126 @@ def _seat_health_typed_cause(result: seat_health.SeatHealthResult) -> str:
3030
3044
  def resolve_orchestrator_health_routing(
3031
3045
  roster: Roster,
3032
3046
  results: tuple[seat_health.SeatHealthResult, ...] | None,
3047
+ *,
3048
+ pinned_seats: frozenset[str] = frozenset(),
3033
3049
  ) -> OrchestratorHealthRoutingDecision:
3034
- """Return the effective roster and any orchestrator fallback or abort action."""
3035
- orchestrator_result = _seat_health_result_for(results, roster.orchestrator)
3036
- if orchestrator_result is None or orchestrator_result.status != "unhealthy":
3050
+ """Route unhealthy orchestrator and worker seats to declared fallbacks."""
3051
+ if results is None:
3037
3052
  return OrchestratorHealthRoutingDecision(roster=roster)
3038
3053
 
3039
- requested = roster.orchestrator
3040
- typed_cause = _seat_health_typed_cause(orchestrator_result)
3041
- failure = orchestrator_result.failure
3042
- rejected: list[dict[str, str]] = []
3043
-
3044
- for fallback_name in roster.agents[requested].fallback:
3045
- if fallback_name not in roster.agents:
3054
+ referenced = {name for agent in roster.agents.values() for name in agent.fallback}
3055
+ # Roots are the orchestrator plus seats not referenced as fallbacks by any other role.
3056
+ roots = [name for name in roster.agents if name == roster.orchestrator or name not in referenced]
3057
+ effective_agents = dict(roster.agents)
3058
+ effective_orchestrator = roster.orchestrator
3059
+ decisions: list[dict[str, object]] = []
3060
+ warnings: list[str] = []
3061
+ abort: tuple[str, seat_health.SeatHealthResult, list[dict[str, str]]] | None = None
3062
+
3063
+ for requested in roots:
3064
+ health_result = _seat_health_result_for(results, requested)
3065
+ if health_result is None or health_result.status != "unhealthy":
3046
3066
  continue
3047
- fallback_result = _seat_health_result_for(results, fallback_name)
3048
- if fallback_result is not None and fallback_result.status == "healthy":
3049
- return OrchestratorHealthRoutingDecision(
3050
- roster=replace(roster, orchestrator=fallback_name),
3051
- warning=(
3067
+ typed_cause = _seat_health_typed_cause(health_result)
3068
+ rejected: list[dict[str, str]] = []
3069
+ selected: str | None = None
3070
+ for fallback_name in roster.agents[requested].fallback:
3071
+ fallback_result = _seat_health_result_for(results, fallback_name)
3072
+ if fallback_result is not None and fallback_result.status == "healthy":
3073
+ selected = fallback_name
3074
+ break
3075
+ status = fallback_result.status if fallback_result is not None else "missing"
3076
+ cause = _seat_health_typed_cause(fallback_result) if fallback_result is not None else "missing"
3077
+ rejected.append({"seat": fallback_name, "status": status, "cause": cause})
3078
+
3079
+ decision: dict[str, object] = {
3080
+ "requested_seat": requested,
3081
+ "effective_seat": selected,
3082
+ "outcome": "fallback" if selected is not None else "skip",
3083
+ "typed_cause": typed_cause,
3084
+ "rejected_fallbacks": rejected,
3085
+ }
3086
+ decisions.append(decision)
3087
+ if selected is not None:
3088
+ if requested == roster.orchestrator:
3089
+ effective_orchestrator = selected
3090
+ warnings.append(
3052
3091
  f"warning: orchestrator {requested} is unhealthy [{typed_cause}]; "
3053
- f"using declared fallback {fallback_name}"
3054
- ),
3055
- receipt={
3056
- "schema": "brigade.seat_routing.v1",
3057
- "requested_orchestrator": requested,
3058
- "effective_orchestrator": fallback_name,
3059
- "outcome": "fallback",
3060
- "typed_cause": typed_cause,
3061
- "rejected_fallbacks": rejected,
3062
- },
3063
- )
3064
- status = fallback_result.status if fallback_result is not None else "missing"
3065
- cause = _seat_health_typed_cause(fallback_result) if fallback_result is not None else "missing"
3066
- rejected.append({"seat": fallback_name, "status": status, "cause": cause})
3092
+ f"using declared fallback {selected}"
3093
+ )
3094
+ else:
3095
+ fallback = roster.agents[selected]
3096
+ requested_agent = roster.agents[requested]
3097
+ effective_agents[requested] = replace(
3098
+ fallback,
3099
+ name=requested,
3100
+ role=requested_agent.role,
3101
+ purpose=requested_agent.purpose,
3102
+ fallback=(),
3103
+ )
3104
+ warnings.append(
3105
+ f"warning: seat {requested} is unhealthy [{typed_cause}]; using declared fallback {selected}"
3106
+ )
3107
+ elif requested == roster.orchestrator or requested in pinned_seats:
3108
+ abort = (requested, health_result, rejected)
3109
+ decision["outcome"] = "abort"
3110
+ else:
3111
+ effective_agents.pop(requested, None)
3112
+ warnings.append(f"warning: skipping unhealthy seat {requested} [{typed_cause}]; no healthy fallback")
3113
+
3114
+ if not decisions:
3115
+ return OrchestratorHealthRoutingDecision(roster=roster)
3116
+
3117
+ effective = replace(
3118
+ roster,
3119
+ agents=effective_agents,
3120
+ orchestrator=effective_orchestrator,
3121
+ seat_routing=tuple(decisions),
3122
+ )
3123
+ receipt: dict[str, object] = {"schema": "brigade.seat_routing.v1", "decisions": decisions}
3124
+ orchestrator_decision = next(
3125
+ (decision for decision in decisions if decision["requested_seat"] == roster.orchestrator), None
3126
+ )
3127
+ if orchestrator_decision is not None:
3128
+ # Preserve the original v1 summary for existing artifact consumers.
3129
+ receipt.update(
3130
+ {
3131
+ "requested_orchestrator": roster.orchestrator,
3132
+ "effective_orchestrator": orchestrator_decision["effective_seat"],
3133
+ "outcome": orchestrator_decision["outcome"],
3134
+ "typed_cause": orchestrator_decision["typed_cause"],
3135
+ "rejected_fallbacks": orchestrator_decision["rejected_fallbacks"],
3136
+ }
3137
+ )
3067
3138
 
3139
+ if abort is None:
3140
+ return OrchestratorHealthRoutingDecision(
3141
+ roster=effective,
3142
+ warning="\n".join(warnings) or None,
3143
+ receipt=receipt,
3144
+ )
3145
+
3146
+ requested, unhealthy_result, rejected = abort
3147
+ typed_cause = _seat_health_typed_cause(unhealthy_result)
3068
3148
  if rejected:
3069
3149
  rejected_detail = "; rejected fallbacks: " + ", ".join(
3070
3150
  f"{entry['seat']} ({entry['status']}[{entry['cause']}])" for entry in rejected
3071
3151
  )
3072
3152
  else:
3073
3153
  rejected_detail = "; no declared fallbacks"
3074
- detail = f"orchestrator {requested} is unhealthy [{typed_cause}]{rejected_detail}"
3154
+ if requested == roster.orchestrator:
3155
+ detail = f"orchestrator {requested} is unhealthy [{typed_cause}]{rejected_detail}"
3156
+ else:
3157
+ detail = f"seat {requested} is unhealthy [{typed_cause}]{rejected_detail}"
3158
+ failure = unhealthy_result.failure
3075
3159
  return OrchestratorHealthRoutingDecision(
3076
- roster=roster,
3160
+ roster=effective,
3161
+ warning="\n".join(warnings) or None,
3077
3162
  abort_detail=detail,
3078
3163
  abort_failure_phase=failure.phase.value if failure is not None else "preflight",
3079
3164
  abort_failure_kind=failure.failure_class.value if failure is not None else "unclassified",
3080
- receipt={
3081
- "schema": "brigade.seat_routing.v1",
3082
- "requested_orchestrator": requested,
3083
- "effective_orchestrator": None,
3084
- "outcome": "abort",
3085
- "typed_cause": typed_cause,
3086
- "rejected_fallbacks": rejected,
3087
- },
3165
+ abort_seat=requested,
3166
+ receipt=receipt,
3088
3167
  )
3089
3168
 
3090
3169
 
@@ -3286,6 +3365,29 @@ def run(
3286
3365
  print(f"error: {detail}", file=sys.stderr)
3287
3366
  return 2
3288
3367
 
3368
+ def _run_isolation_check() -> str | None:
3369
+ """Detect canonical-checkout escapes after dispatch without per-worker attribution."""
3370
+
3371
+ if lock_workspace == cwd or drift_snapshot is None:
3372
+ return None
3373
+ # Preserve the existing branch/HEAD drift classification. Working-tree
3374
+ # mutations are what this post-dispatch check adds; committed or
3375
+ # branch-moving interference remains caught by the run-level drift
3376
+ # checkpoints.
3377
+ if runguard.detect_branch_head_drift(lock_workspace, drift_snapshot) is not None:
3378
+ return None
3379
+ try:
3380
+ changed, untracked = runguard.changes_relative_to_snapshot(lock_workspace, drift_snapshot)
3381
+ except runguard.RunGuardError as exc:
3382
+ return f"isolation breach: could not verify canonical checkout: {exc}"
3383
+ escaped = sorted(set(changed + untracked))
3384
+ if not escaped:
3385
+ return None
3386
+ shown = ", ".join(escaped[:10])
3387
+ if len(escaped) > 10:
3388
+ shown += f", and {len(escaped) - 10} more"
3389
+ return f"isolation breach: modified files outside assigned worktree: {shown}"
3390
+
3289
3391
  if worker is not None:
3290
3392
  worker_error = _direct_worker_error(worker, roster, read_only=read_only)
3291
3393
  if worker_error is not None:
@@ -3368,7 +3470,11 @@ def run(
3368
3470
  )
3369
3471
  # After the initial run receipt, before planning: a probe failure stays receipted.
3370
3472
  health_results = _write_run_seat_health_receipt(output_dir, roster, cwd=cwd)
3371
- routing = resolve_orchestrator_health_routing(roster, health_results)
3473
+ routing = resolve_orchestrator_health_routing(
3474
+ roster,
3475
+ health_results,
3476
+ pinned_seats=frozenset({worker}) if worker is not None else frozenset(),
3477
+ )
3372
3478
  roster = routing.roster
3373
3479
  if routing.warning is not None:
3374
3480
  print(routing.warning, file=sys.stderr)
@@ -3377,13 +3483,24 @@ def run(
3377
3483
  routing_receipt["run_id"] = output_dir.name
3378
3484
  _write_seat_routing_receipt(output_dir, routing_receipt)
3379
3485
  if routing.abort_detail is not None:
3486
+ if roster.seat_routing:
3487
+ run_path = output_dir / "run.json"
3488
+ try:
3489
+ run_payload = json.loads(run_path.read_text())
3490
+ except (OSError, json.JSONDecodeError) as exc:
3491
+ raise runguard.RetainRunLockError(
3492
+ f"failed to read run receipt before seat-routing abort: {exc}"
3493
+ ) from exc
3494
+ if isinstance(run_payload, dict):
3495
+ run_payload["seat_routing"] = [dict(decision) for decision in roster.seat_routing]
3496
+ _write_json(run_path, receipt_schema.stamp_run_receipt(run_payload))
3380
3497
  record_run_termination(
3381
3498
  output_dir,
3382
3499
  status="failed",
3383
3500
  failure_phase=routing.abort_failure_phase,
3384
3501
  failure_kind=routing.abort_failure_kind,
3385
3502
  detail=routing.abort_detail,
3386
- seat=roster.orchestrator,
3503
+ seat=routing.abort_seat or roster.orchestrator,
3387
3504
  )
3388
3505
  print(f"error: {routing.abort_detail}", file=sys.stderr)
3389
3506
  return 2
@@ -3891,6 +4008,19 @@ def run(
3891
4008
  ground_truth=ground_truth,
3892
4009
  ),
3893
4010
  )
4011
+ isolation_detail = _run_isolation_check()
4012
+ if isolation_detail is not None:
4013
+ if output_dir is not None:
4014
+ record_run_termination(
4015
+ output_dir,
4016
+ status="failed",
4017
+ failure_phase="run-isolation",
4018
+ failure_kind="isolation-breach",
4019
+ detail=isolation_detail,
4020
+ seat=roster.orchestrator,
4021
+ )
4022
+ print(f"error: {isolation_detail}", file=sys.stderr)
4023
+ return 2
3894
4024
  if verbose:
3895
4025
  _print_worker_status(worker_results)
3896
4026
  if not direct_worker:
@@ -31,6 +31,39 @@ def _scalar(value: str) -> str:
31
31
  return value
32
32
 
33
33
 
34
+ def _split_allowed_tools(allowed: str) -> tuple[str, ...]:
35
+ """Split comma/whitespace tool lists while preserving parenthesized scopes.
36
+
37
+ Claude-style entries such as ``Bash(brigade handoff list:*)`` must stay one
38
+ token. A naive ``re.split(r"[\\s,]+")`` shreds them into nonsense.
39
+ """
40
+ items: list[str] = []
41
+ buf: list[str] = []
42
+ depth = 0
43
+ for ch in allowed:
44
+ if ch == "(":
45
+ depth += 1
46
+ buf.append(ch)
47
+ continue
48
+ if ch == ")":
49
+ depth = max(0, depth - 1)
50
+ buf.append(ch)
51
+ continue
52
+ if ch in ", \t\r\n" and depth == 0:
53
+ if buf:
54
+ item = "".join(buf).strip()
55
+ if item:
56
+ items.append(item)
57
+ buf = []
58
+ continue
59
+ buf.append(ch)
60
+ if buf:
61
+ item = "".join(buf).strip()
62
+ if item:
63
+ items.append(item)
64
+ return tuple(items)
65
+
66
+
34
67
  def _frontmatter(text: str) -> tuple[list[str] | None, str | None]:
35
68
  lines = text.splitlines()
36
69
  if not lines or lines[0] != "---":
@@ -48,7 +81,7 @@ def validate(skill_dir: Path, *, mode: str) -> Validation:
48
81
  path = skill_dir / "SKILL.md"
49
82
  if not path.is_file():
50
83
  return Validation({}, (f"SKILL.md not found: {path}",), ())
51
- lines, framing_error = _frontmatter(path.read_text(errors="replace"))
84
+ lines, framing_error = _frontmatter(path.read_text(encoding="utf-8", errors="replace"))
52
85
  if lines is None:
53
86
  if mode == "lenient":
54
87
  return Validation({}, (), (framing_error or "invalid frontmatter",))
@@ -121,7 +154,7 @@ def validate(skill_dir: Path, *, mode: str) -> Validation:
121
154
  (errors if mode == "strict" else diagnostics).append(message)
122
155
  allowed = fields.get("allowed-tools")
123
156
  if isinstance(allowed, str):
124
- fields["allowed-tools"] = tuple(item for item in re.split(r"[\s,]+", allowed) if item)
157
+ fields["allowed-tools"] = _split_allowed_tools(allowed)
125
158
  elif allowed is not None:
126
159
  errors.append("frontmatter allowed-tools must be a string declaration")
127
160
  fields.update(unknown)
@@ -15,6 +15,7 @@ _MODULE_NAMES = (
15
15
  "reports",
16
16
  "report_review",
17
17
  "actions",
18
+ "serve",
18
19
  )
19
20
  _MODULE_ALIASES = {
20
21
  "schema": "schema_ops",
@@ -89,6 +90,7 @@ _module_readiness = importlib.import_module(f"{__name__}.readiness")
89
90
  _module_reports = importlib.import_module(f"{__name__}.reports")
90
91
  _module_report_review = _facade_module("report_review")
91
92
  _module_actions = importlib.import_module(f"{__name__}.actions")
93
+ _module_serve = importlib.import_module(f"{__name__}.serve")
92
94
 
93
95
  from .schema_ops import *
94
96
  from .core import *
@@ -96,6 +98,7 @@ from .readiness import *
96
98
  from .reports import *
97
99
  from .report_review_ops import *
98
100
  from .actions import *
101
+ from .serve import *
99
102
 
100
103
  _MODULES = (
101
104
  _module_schema,
@@ -104,6 +107,7 @@ _MODULES = (
104
107
  _module_reports,
105
108
  _module_report_review,
106
109
  _module_actions,
110
+ _module_serve,
107
111
  )
108
112
 
109
113
 
@@ -376,7 +376,7 @@ def actions_build(
376
376
  review_status = _report_review_status(report)
377
377
  if review_status not in {"reviewed", "deferred"} and not allow_unreviewed:
378
378
  print(
379
- "error: source report must be closed out as reviewed or deferred, or pass --allow-unreviewed",
379
+ "error: source report must be closed out as reviewed or deferred before building actions",
380
380
  file=sys.stderr,
381
381
  )
382
382
  return 2