briefloop 0.11.12__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (424) hide show
  1. briefloop-0.11.12.dist-info/METADATA +473 -0
  2. briefloop-0.11.12.dist-info/RECORD +424 -0
  3. briefloop-0.11.12.dist-info/WHEEL +5 -0
  4. briefloop-0.11.12.dist-info/entry_points.txt +3 -0
  5. briefloop-0.11.12.dist-info/licenses/LICENSE +22 -0
  6. briefloop-0.11.12.dist-info/top_level.txt +1 -0
  7. multi_agent_brief/__init__.py +36 -0
  8. multi_agent_brief/analysis_blocks/__init__.py +11 -0
  9. multi_agent_brief/analysis_blocks/builder.py +206 -0
  10. multi_agent_brief/analysis_blocks/renderer.py +237 -0
  11. multi_agent_brief/analysis_blocks/schemas.py +52 -0
  12. multi_agent_brief/analysis_modules/__init__.py +8 -0
  13. multi_agent_brief/analysis_modules/base.py +87 -0
  14. multi_agent_brief/analysis_modules/market_competitor/__init__.py +68 -0
  15. multi_agent_brief/analysis_modules/market_competitor/auditor.py +290 -0
  16. multi_agent_brief/analysis_modules/market_competitor/config.py +187 -0
  17. multi_agent_brief/analysis_modules/market_competitor/event_builder.py +226 -0
  18. multi_agent_brief/analysis_modules/market_competitor/renderer.py +199 -0
  19. multi_agent_brief/analysis_modules/market_competitor/schemas.py +518 -0
  20. multi_agent_brief/analysis_modules/policy_regulatory/__init__.py +7 -0
  21. multi_agent_brief/analysis_modules/policy_regulatory/audit.py +195 -0
  22. multi_agent_brief/analysis_modules/policy_regulatory/module.py +387 -0
  23. multi_agent_brief/analysis_modules/policy_regulatory/schemas.py +129 -0
  24. multi_agent_brief/analysis_modules/registry.py +73 -0
  25. multi_agent_brief/audience/__init__.py +19 -0
  26. multi_agent_brief/audience/profiles.py +246 -0
  27. multi_agent_brief/audience_memory/__init__.py +23 -0
  28. multi_agent_brief/audience_memory/profile.py +358 -0
  29. multi_agent_brief/audit/__init__.py +36 -0
  30. multi_agent_brief/audit/case_applicability.py +181 -0
  31. multi_agent_brief/audit/deterministic.py +471 -0
  32. multi_agent_brief/audit/editorial_governance.py +404 -0
  33. multi_agent_brief/audit/final_quality.py +764 -0
  34. multi_agent_brief/audit/harness.py +242 -0
  35. multi_agent_brief/audit/interfaces.py +96 -0
  36. multi_agent_brief/audit/limitation_hygiene.py +238 -0
  37. multi_agent_brief/audit/proposal_boundary.py +34 -0
  38. multi_agent_brief/audit/redaction.py +27 -0
  39. multi_agent_brief/audit/rule_packs.py +96 -0
  40. multi_agent_brief/audit/semantic.py +435 -0
  41. multi_agent_brief/capabilities/__init__.py +22 -0
  42. multi_agent_brief/capabilities/catalog.py +215 -0
  43. multi_agent_brief/capabilities/detect.py +199 -0
  44. multi_agent_brief/capabilities/models.py +60 -0
  45. multi_agent_brief/capabilities/recommend.py +206 -0
  46. multi_agent_brief/cli/__init__.py +2 -0
  47. multi_agent_brief/cli/analysis_commands.py +140 -0
  48. multi_agent_brief/cli/approval_commands.py +107 -0
  49. multi_agent_brief/cli/audit_commands.py +59 -0
  50. multi_agent_brief/cli/capability_commands.py +548 -0
  51. multi_agent_brief/cli/claude_commands.py +159 -0
  52. multi_agent_brief/cli/competitors_commands.py +182 -0
  53. multi_agent_brief/cli/controls_commands.py +137 -0
  54. multi_agent_brief/cli/deliver_commands.py +942 -0
  55. multi_agent_brief/cli/eval_cases_commands.py +99 -0
  56. multi_agent_brief/cli/experiments_commands.py +395 -0
  57. multi_agent_brief/cli/feedback_commands.py +192 -0
  58. multi_agent_brief/cli/finalize_commands.py +153 -0
  59. multi_agent_brief/cli/gates_commands.py +174 -0
  60. multi_agent_brief/cli/hermes_commands.py +356 -0
  61. multi_agent_brief/cli/improve_commands.py +224 -0
  62. multi_agent_brief/cli/init_commands.py +564 -0
  63. multi_agent_brief/cli/init_wizard.py +1473 -0
  64. multi_agent_brief/cli/input_commands.py +237 -0
  65. multi_agent_brief/cli/main.py +288 -0
  66. multi_agent_brief/cli/onboard_commands.py +193 -0
  67. multi_agent_brief/cli/product_commands.py +1449 -0
  68. multi_agent_brief/cli/provenance_commands.py +100 -0
  69. multi_agent_brief/cli/release_commands.py +68 -0
  70. multi_agent_brief/cli/repair_commands.py +169 -0
  71. multi_agent_brief/cli/run_commands.py +292 -0
  72. multi_agent_brief/cli/runtime_commands.py +81 -0
  73. multi_agent_brief/cli/secrets_commands.py +232 -0
  74. multi_agent_brief/cli/semantic_support_commands.py +80 -0
  75. multi_agent_brief/cli/sources_commands.py +647 -0
  76. multi_agent_brief/cli/start_commands.py +8 -0
  77. multi_agent_brief/cli/state_commands.py +446 -0
  78. multi_agent_brief/cli/status_commands.py +26 -0
  79. multi_agent_brief/cli/workbuddy_commands.py +103 -0
  80. multi_agent_brief/configs/artifact_contracts.yaml +514 -0
  81. multi_agent_brief/configs/orchestrator_contract.yaml +181 -0
  82. multi_agent_brief/configs/policy_packs/default.yaml +65 -0
  83. multi_agent_brief/configs/policy_profiles/evidence_extract_default.yaml +58 -0
  84. multi_agent_brief/configs/policy_profiles/finance_default.yaml +44 -0
  85. multi_agent_brief/configs/policy_profiles/internet_default.yaml +44 -0
  86. multi_agent_brief/configs/policy_profiles/manufacturing_default.yaml +33 -0
  87. multi_agent_brief/configs/policy_profiles/solar_manufacturing_default.yaml +64 -0
  88. multi_agent_brief/configs/report_packs/evidence_extract.yaml +48 -0
  89. multi_agent_brief/configs/report_packs/management_monthly.yaml +36 -0
  90. multi_agent_brief/configs/report_packs/market_weekly.yaml +36 -0
  91. multi_agent_brief/configs/report_packs/solar_industry_periodic.yaml +50 -0
  92. multi_agent_brief/configs/report_templates/evidence_extract.yaml +55 -0
  93. multi_agent_brief/configs/report_templates/management_monthly.yaml +48 -0
  94. multi_agent_brief/configs/report_templates/market_weekly.yaml +49 -0
  95. multi_agent_brief/configs/report_templates/solar_industry_periodic.yaml +75 -0
  96. multi_agent_brief/configs/stage_specs.yaml +180 -0
  97. multi_agent_brief/contracts/__init__.py +41 -0
  98. multi_agent_brief/contracts/base.py +99 -0
  99. multi_agent_brief/contracts/errors.py +41 -0
  100. multi_agent_brief/contracts/migrations/__init__.py +5 -0
  101. multi_agent_brief/contracts/migrations/claim_v1_to_v2.py +33 -0
  102. multi_agent_brief/contracts/registry.py +159 -0
  103. multi_agent_brief/contracts/role_topology.py +25 -0
  104. multi_agent_brief/contracts/schemas/__init__.py +35 -0
  105. multi_agent_brief/contracts/schemas/analysis_pack.py +135 -0
  106. multi_agent_brief/contracts/schemas/atomic_claim_graph.py +304 -0
  107. multi_agent_brief/contracts/schemas/audit_report.py +80 -0
  108. multi_agent_brief/contracts/schemas/candidate_item.py +51 -0
  109. multi_agent_brief/contracts/schemas/claim.py +197 -0
  110. multi_agent_brief/contracts/schemas/claim_draft.py +386 -0
  111. multi_agent_brief/contracts/schemas/claim_support_matrix.py +334 -0
  112. multi_agent_brief/contracts/schemas/evidence_span_registry.py +270 -0
  113. multi_agent_brief/contracts/schemas/policy_profile.py +247 -0
  114. multi_agent_brief/contracts/schemas/report_spec.py +257 -0
  115. multi_agent_brief/contracts/schemas/semantic_assessment_report.py +480 -0
  116. multi_agent_brief/contracts/schemas/source_evidence_pack_manifest.py +233 -0
  117. multi_agent_brief/contracts/schemas/source_item.py +96 -0
  118. multi_agent_brief/contracts/semantic_assessment_status.py +12 -0
  119. multi_agent_brief/contracts/source_metadata.py +252 -0
  120. multi_agent_brief/contracts/target_contract.py +460 -0
  121. multi_agent_brief/contracts/validator.py +225 -0
  122. multi_agent_brief/controls/__init__.py +23 -0
  123. multi_agent_brief/controls/contract.py +106 -0
  124. multi_agent_brief/controls/switchboard.py +1076 -0
  125. multi_agent_brief/core/__init__.py +2 -0
  126. multi_agent_brief/core/citations.py +14 -0
  127. multi_agent_brief/core/claim_ledger.py +94 -0
  128. multi_agent_brief/core/config.py +191 -0
  129. multi_agent_brief/core/env.py +69 -0
  130. multi_agent_brief/core/previous.py +83 -0
  131. multi_agent_brief/core/schemas.py +181 -0
  132. multi_agent_brief/core/selection.py +189 -0
  133. multi_agent_brief/delivery/__init__.py +6 -0
  134. multi_agent_brief/delivery/base.py +36 -0
  135. multi_agent_brief/delivery/feishu.py +204 -0
  136. multi_agent_brief/delivery/gws.py +237 -0
  137. multi_agent_brief/evaluation_cases/__init__.py +15 -0
  138. multi_agent_brief/evaluation_cases/contract.py +429 -0
  139. multi_agent_brief/evaluation_cases/fixtures/cases/approved_guidance_materialized/workspace/config.yaml +18 -0
  140. multi_agent_brief/evaluation_cases/fixtures/cases/approved_guidance_materialized/workspace/improvement/ledger.jsonl +2 -0
  141. multi_agent_brief/evaluation_cases/fixtures/cases/approved_guidance_materialized/workspace/sources.yaml +2 -0
  142. multi_agent_brief/evaluation_cases/fixtures/cases/approved_guidance_materialized/workspace/user.md +4 -0
  143. multi_agent_brief/evaluation_cases/fixtures/cases/company_event_missing_latest_official_check/workspace/config.yaml +13 -0
  144. multi_agent_brief/evaluation_cases/fixtures/cases/company_event_missing_latest_official_check/workspace/sources.yaml +9 -0
  145. multi_agent_brief/evaluation_cases/fixtures/cases/company_event_missing_latest_official_check/workspace/user.md +4 -0
  146. multi_agent_brief/evaluation_cases/fixtures/cases/control_switchboard_selection_is_not_execution/workspace/config.yaml +12 -0
  147. multi_agent_brief/evaluation_cases/fixtures/cases/control_switchboard_selection_is_not_execution/workspace/sources.yaml +6 -0
  148. multi_agent_brief/evaluation_cases/fixtures/cases/control_switchboard_selection_is_not_execution/workspace/user.md +4 -0
  149. multi_agent_brief/evaluation_cases/fixtures/cases/feedback_triage_required/workspace/config.yaml +6 -0
  150. multi_agent_brief/evaluation_cases/fixtures/cases/feedback_triage_required/workspace/input/human_feedback.md +1 -0
  151. multi_agent_brief/evaluation_cases/fixtures/cases/feedback_triage_required/workspace/sources.yaml +2 -0
  152. multi_agent_brief/evaluation_cases/fixtures/cases/feedback_triage_required/workspace/user.md +3 -0
  153. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/config.yaml +8 -0
  154. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/output/brief.md +14 -0
  155. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/output/intermediate/audit_report.json +1 -0
  156. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/output/intermediate/audited_brief.md +5 -0
  157. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/output/intermediate/candidate_claims.json +1 -0
  158. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/output/intermediate/claim_ledger.json +1 -0
  159. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/output/intermediate/screened_candidates.json +1 -0
  160. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/sources.yaml +2 -0
  161. multi_agent_brief/evaluation_cases/fixtures/cases/final_abstract_quality_warning_surface/workspace/user.md +3 -0
  162. multi_agent_brief/evaluation_cases/fixtures/cases/formal_release_missing_human_approval/workspace/config.yaml +13 -0
  163. multi_agent_brief/evaluation_cases/fixtures/cases/formal_release_missing_human_approval/workspace/sources.yaml +9 -0
  164. multi_agent_brief/evaluation_cases/fixtures/cases/formal_release_missing_human_approval/workspace/user.md +4 -0
  165. multi_agent_brief/evaluation_cases/fixtures/cases/guidance_manifestation_not_observable/workspace/config.yaml +4 -0
  166. multi_agent_brief/evaluation_cases/fixtures/cases/guidance_manifestation_not_observable/workspace/sources.yaml +2 -0
  167. multi_agent_brief/evaluation_cases/fixtures/cases/guidance_manifestation_not_observable/workspace/user.md +3 -0
  168. multi_agent_brief/evaluation_cases/fixtures/cases/media_only_legal_policy_blocks_research_review/workspace/config.yaml +13 -0
  169. multi_agent_brief/evaluation_cases/fixtures/cases/media_only_legal_policy_blocks_research_review/workspace/sources.yaml +9 -0
  170. multi_agent_brief/evaluation_cases/fixtures/cases/media_only_legal_policy_blocks_research_review/workspace/user.md +4 -0
  171. multi_agent_brief/evaluation_cases/fixtures/cases/mixed_metric_scope_support_blocker/workspace/config.yaml +13 -0
  172. multi_agent_brief/evaluation_cases/fixtures/cases/mixed_metric_scope_support_blocker/workspace/sources.yaml +9 -0
  173. multi_agent_brief/evaluation_cases/fixtures/cases/mixed_metric_scope_support_blocker/workspace/user.md +5 -0
  174. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/config.yaml +6 -0
  175. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/output/intermediate/audited_brief.md +3 -0
  176. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/output/intermediate/candidate_claims.json +1 -0
  177. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/output/intermediate/claim_ledger.json +1 -0
  178. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/output/intermediate/feedback_issues.json +25 -0
  179. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/output/intermediate/repair_plan.json +27 -0
  180. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/output/intermediate/screened_candidates.json +1 -0
  181. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/sources.yaml +2 -0
  182. multi_agent_brief/evaluation_cases/fixtures/cases/planned_blocking_issue_cannot_continue/workspace/user.md +3 -0
  183. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/config.yaml +8 -0
  184. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/output/intermediate/audit_report.json +1 -0
  185. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/output/intermediate/audited_brief.md +3 -0
  186. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/output/intermediate/candidate_claims.json +1 -0
  187. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/output/intermediate/claim_ledger.json +11 -0
  188. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/output/intermediate/quality_gate_report.json +22 -0
  189. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/output/intermediate/screened_candidates.json +1 -0
  190. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/sources.yaml +2 -0
  191. multi_agent_brief/evaluation_cases/fixtures/cases/provenance_projection_minimal/workspace/user.md +3 -0
  192. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/config.yaml +13 -0
  193. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/output/intermediate/audit_report.json +1 -0
  194. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/output/intermediate/audited_brief.md +5 -0
  195. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/output/intermediate/candidate_claims.json +1 -0
  196. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/output/intermediate/claim_ledger.json +40 -0
  197. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/output/intermediate/screened_candidates.json +1 -0
  198. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/sources.yaml +3 -0
  199. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_source_appendix/workspace/user.md +3 -0
  200. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/config.yaml +8 -0
  201. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/output/brief.md +3 -0
  202. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/output/intermediate/audit_report.json +1 -0
  203. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/output/intermediate/audited_brief.md +3 -0
  204. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/output/intermediate/candidate_claims.json +1 -0
  205. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/output/intermediate/claim_ledger.json +13 -0
  206. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/output/intermediate/screened_candidates.json +1 -0
  207. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/sources.yaml +2 -0
  208. multi_agent_brief/evaluation_cases/fixtures/cases/reader_facing_target_relevance/workspace/user.md +3 -0
  209. multi_agent_brief/evaluation_cases/fixtures/cases/release_readiness_forged_event_blocker/workspace/config.yaml +13 -0
  210. multi_agent_brief/evaluation_cases/fixtures/cases/release_readiness_forged_event_blocker/workspace/output/intermediate/release_readiness_report.json +31 -0
  211. multi_agent_brief/evaluation_cases/fixtures/cases/release_readiness_forged_event_blocker/workspace/sources.yaml +9 -0
  212. multi_agent_brief/evaluation_cases/fixtures/cases/release_readiness_forged_event_blocker/workspace/user.md +4 -0
  213. multi_agent_brief/evaluation_cases/fixtures/cases/reverted_entry_removed_from_next_snapshot/workspace/config.yaml +18 -0
  214. multi_agent_brief/evaluation_cases/fixtures/cases/reverted_entry_removed_from_next_snapshot/workspace/improvement/ledger.jsonl +3 -0
  215. multi_agent_brief/evaluation_cases/fixtures/cases/reverted_entry_removed_from_next_snapshot/workspace/improvement/memory.md +3 -0
  216. multi_agent_brief/evaluation_cases/fixtures/cases/reverted_entry_removed_from_next_snapshot/workspace/output/intermediate/improvement_memory_snapshot.md +3 -0
  217. multi_agent_brief/evaluation_cases/fixtures/cases/reverted_entry_removed_from_next_snapshot/workspace/sources.yaml +2 -0
  218. multi_agent_brief/evaluation_cases/fixtures/cases/reverted_entry_removed_from_next_snapshot/workspace/user.md +4 -0
  219. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/config.yaml +12 -0
  220. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/input/sources/source-001.txt +1 -0
  221. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/brief.md +37 -0
  222. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/delivery/brief.md +37 -0
  223. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/atomic_claim_graph.json +17 -0
  224. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/audit_report.json +5 -0
  225. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/audited_brief.md +37 -0
  226. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/claim_ledger.json +20 -0
  227. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/evidence_span_registry.json +20 -0
  228. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/finalize_report.json +40 -0
  229. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/gates/auditor_quality_gate_report.json +42 -0
  230. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/gates/finalize_quality_gate_report.json +42 -0
  231. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/intermediate/screened_candidates.json +33 -0
  232. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/source_appendix.md +12 -0
  233. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/output/source_appendix_trace.md +10 -0
  234. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/report_spec.yaml +24 -0
  235. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/sources.yaml +4 -0
  236. multi_agent_brief/evaluation_cases/fixtures/cases/same_evidence_reader_quality_regression/workspace/user.md +3 -0
  237. multi_agent_brief/evaluation_cases/fixtures/cases/source_evidence_pack_blocks_non_evidence_file/workspace/config.yaml +13 -0
  238. multi_agent_brief/evaluation_cases/fixtures/cases/source_evidence_pack_blocks_non_evidence_file/workspace/input/sources/README.md +4 -0
  239. multi_agent_brief/evaluation_cases/fixtures/cases/source_evidence_pack_blocks_non_evidence_file/workspace/output/intermediate/source_evidence_pack_manifest.json +26 -0
  240. multi_agent_brief/evaluation_cases/fixtures/cases/source_evidence_pack_blocks_non_evidence_file/workspace/sources.yaml +9 -0
  241. multi_agent_brief/evaluation_cases/fixtures/cases/source_evidence_pack_blocks_non_evidence_file/workspace/user.md +4 -0
  242. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/config.yaml +9 -0
  243. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/output/intermediate/audit_report.json +1 -0
  244. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/output/intermediate/audited_brief.md +3 -0
  245. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/output/intermediate/candidate_claims.json +1 -0
  246. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/output/intermediate/claim_ledger.json +13 -0
  247. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/output/intermediate/screened_candidates.json +1 -0
  248. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/sources.yaml +2 -0
  249. multi_agent_brief/evaluation_cases/fixtures/cases/stale_current_claim/workspace/user.md +3 -0
  250. multi_agent_brief/evaluation_cases/fixtures/cases/third_party_price_snapshot_formal_block/workspace/config.yaml +13 -0
  251. multi_agent_brief/evaluation_cases/fixtures/cases/third_party_price_snapshot_formal_block/workspace/sources.yaml +9 -0
  252. multi_agent_brief/evaluation_cases/fixtures/cases/third_party_price_snapshot_formal_block/workspace/user.md +4 -0
  253. multi_agent_brief/evaluation_cases/fixtures/cases/trajectory_retry_budget_exhausted/workspace/config.yaml +4 -0
  254. multi_agent_brief/evaluation_cases/fixtures/cases/trajectory_retry_budget_exhausted/workspace/sources.yaml +2 -0
  255. multi_agent_brief/evaluation_cases/fixtures/cases/trajectory_retry_budget_exhausted/workspace/user.md +3 -0
  256. multi_agent_brief/evaluation_cases/fixtures/cases/unapproved_entry_not_materialized/workspace/config.yaml +18 -0
  257. multi_agent_brief/evaluation_cases/fixtures/cases/unapproved_entry_not_materialized/workspace/improvement/ledger.jsonl +1 -0
  258. multi_agent_brief/evaluation_cases/fixtures/cases/unapproved_entry_not_materialized/workspace/sources.yaml +2 -0
  259. multi_agent_brief/evaluation_cases/fixtures/cases/unapproved_entry_not_materialized/workspace/user.md +4 -0
  260. multi_agent_brief/evaluation_cases/fixtures/cases/unauthorized_institution_branding_blocks_release/workspace/config.yaml +18 -0
  261. multi_agent_brief/evaluation_cases/fixtures/cases/unauthorized_institution_branding_blocks_release/workspace/sources.yaml +9 -0
  262. multi_agent_brief/evaluation_cases/fixtures/cases/unauthorized_institution_branding_blocks_release/workspace/user.md +5 -0
  263. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/config.yaml +8 -0
  264. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/output/intermediate/audit_report.json +1 -0
  265. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/output/intermediate/audited_brief.md +8 -0
  266. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/output/intermediate/candidate_claims.json +1 -0
  267. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/output/intermediate/claim_ledger.json +1 -0
  268. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/output/intermediate/screened_candidates.json +1 -0
  269. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/sources.yaml +2 -0
  270. multi_agent_brief/evaluation_cases/fixtures/cases/unsupported_material_fact/workspace/user.md +3 -0
  271. multi_agent_brief/evaluation_cases/fixtures/manifest.yaml +861 -0
  272. multi_agent_brief/evaluation_cases/fixtures.py +20 -0
  273. multi_agent_brief/evaluation_cases/runner.py +1603 -0
  274. multi_agent_brief/experiments/__init__.py +45 -0
  275. multi_agent_brief/experiments/experiment_080.py +5835 -0
  276. multi_agent_brief/experiments/schemas.py +63 -0
  277. multi_agent_brief/experiments/target_contract.py +10 -0
  278. multi_agent_brief/feedback/__init__.py +17 -0
  279. multi_agent_brief/feedback/feedback_contract.py +482 -0
  280. multi_agent_brief/feedback/feedback_state.py +898 -0
  281. multi_agent_brief/hermes/__init__.py +25 -0
  282. multi_agent_brief/hermes/adapter.py +832 -0
  283. multi_agent_brief/improvement/__init__.py +83 -0
  284. multi_agent_brief/improvement/contract.py +1114 -0
  285. multi_agent_brief/improvement/memory.py +451 -0
  286. multi_agent_brief/improvement/product_definition.py +228 -0
  287. multi_agent_brief/improvement/state.py +961 -0
  288. multi_agent_brief/inputs/__init__.py +2 -0
  289. multi_agent_brief/inputs/classifier.py +322 -0
  290. multi_agent_brief/inputs/contracts.py +59 -0
  291. multi_agent_brief/inputs/extractor.py +310 -0
  292. multi_agent_brief/install/__init__.py +2 -0
  293. multi_agent_brief/install/writer.py +97 -0
  294. multi_agent_brief/onboarding/__init__.py +11 -0
  295. multi_agent_brief/onboarding/io.py +103 -0
  296. multi_agent_brief/onboarding/mapper.py +484 -0
  297. multi_agent_brief/onboarding/schema.py +46 -0
  298. multi_agent_brief/orchestrator/__init__.py +2 -0
  299. multi_agent_brief/orchestrator/fact_layer_import.py +352 -0
  300. multi_agent_brief/orchestrator/handoff.py +2209 -0
  301. multi_agent_brief/orchestrator/role_topology.py +42 -0
  302. multi_agent_brief/orchestrator/run_archive.py +888 -0
  303. multi_agent_brief/orchestrator/run_integrity.py +346 -0
  304. multi_agent_brief/orchestrator/runtime_state/__init__.py +70 -0
  305. multi_agent_brief/orchestrator/runtime_state/_io.py +167 -0
  306. multi_agent_brief/orchestrator/runtime_state/_transactions.py +298 -0
  307. multi_agent_brief/orchestrator/runtime_state/artifact_registry.py +1825 -0
  308. multi_agent_brief/orchestrator/runtime_state/atomic_claim_graph.py +96 -0
  309. multi_agent_brief/orchestrator/runtime_state/claim_ledger_freeze.py +510 -0
  310. multi_agent_brief/orchestrator/runtime_state/claim_metadata_enrichment.py +836 -0
  311. multi_agent_brief/orchestrator/runtime_state/claim_support_matrix.py +582 -0
  312. multi_agent_brief/orchestrator/runtime_state/completion_gates.py +672 -0
  313. multi_agent_brief/orchestrator/runtime_state/contracts_loader.py +66 -0
  314. multi_agent_brief/orchestrator/runtime_state/decisions.py +239 -0
  315. multi_agent_brief/orchestrator/runtime_state/errors.py +61 -0
  316. multi_agent_brief/orchestrator/runtime_state/event_log.py +256 -0
  317. multi_agent_brief/orchestrator/runtime_state/evidence_span_registry.py +233 -0
  318. multi_agent_brief/orchestrator/runtime_state/fact_layer.py +755 -0
  319. multi_agent_brief/orchestrator/runtime_state/identity.py +90 -0
  320. multi_agent_brief/orchestrator/runtime_state/lifecycle.py +675 -0
  321. multi_agent_brief/orchestrator/runtime_state/manifest.py +82 -0
  322. multi_agent_brief/orchestrator/runtime_state/operations.py +224 -0
  323. multi_agent_brief/orchestrator/runtime_state/paths.py +38 -0
  324. multi_agent_brief/orchestrator/runtime_state/repair.py +984 -0
  325. multi_agent_brief/orchestrator/runtime_state/safety_surfaces.py +147 -0
  326. multi_agent_brief/orchestrator/runtime_state/semantic_assessment_report.py +692 -0
  327. multi_agent_brief/orchestrator/runtime_state/semantic_support_acceptance.py +683 -0
  328. multi_agent_brief/orchestrator/runtime_state/source_evidence_pack.py +131 -0
  329. multi_agent_brief/orchestrator/runtime_state/stage_completion.py +1320 -0
  330. multi_agent_brief/orchestrator/runtime_state/trajectory.py +200 -0
  331. multi_agent_brief/orchestrator/runtime_state/workflow.py +350 -0
  332. multi_agent_brief/orchestrator/source_evidence.py +43 -0
  333. multi_agent_brief/orchestrator/timing.py +410 -0
  334. multi_agent_brief/orchestrator_contract.py +96 -0
  335. multi_agent_brief/outputs/__init__.py +2 -0
  336. multi_agent_brief/outputs/atomic_reader_projection.py +288 -0
  337. multi_agent_brief/outputs/docx.py +32 -0
  338. multi_agent_brief/outputs/finalize.py +1036 -0
  339. multi_agent_brief/outputs/ib_docx.py +983 -0
  340. multi_agent_brief/outputs/naming.py +38 -0
  341. multi_agent_brief/outputs/pdf.py +20 -0
  342. multi_agent_brief/outputs/reader_final_gate.py +509 -0
  343. multi_agent_brief/outputs/reader_projection.py +397 -0
  344. multi_agent_brief/outputs/source_appendix.py +753 -0
  345. multi_agent_brief/outputs/templates/__init__.py +112 -0
  346. multi_agent_brief/product/__init__.py +49 -0
  347. multi_agent_brief/product/bundle_projection.py +686 -0
  348. multi_agent_brief/product/citation_profile.py +145 -0
  349. multi_agent_brief/product/guidance_manifestation.py +421 -0
  350. multi_agent_brief/product/materiality_selection.py +472 -0
  351. multi_agent_brief/product/policy_gate_adapter.py +116 -0
  352. multi_agent_brief/product/policy_profile.py +39 -0
  353. multi_agent_brief/product/policy_projection.py +161 -0
  354. multi_agent_brief/product/policy_registry.py +83 -0
  355. multi_agent_brief/product/policy_resolver.py +225 -0
  356. multi_agent_brief/product/quality_closeout.py +188 -0
  357. multi_agent_brief/product/quality_panel.py +2217 -0
  358. multi_agent_brief/product/release_approval.py +1034 -0
  359. multi_agent_brief/product/report_pack.py +130 -0
  360. multi_agent_brief/product/report_pack_aliases.py +68 -0
  361. multi_agent_brief/product/report_registry.py +101 -0
  362. multi_agent_brief/product/report_spec.py +181 -0
  363. multi_agent_brief/product/support_wording.py +525 -0
  364. multi_agent_brief/product/template_conformance.py +516 -0
  365. multi_agent_brief/product/template_projection.py +123 -0
  366. multi_agent_brief/product/template_registry.py +244 -0
  367. multi_agent_brief/product/template_render_plan.py +315 -0
  368. multi_agent_brief/product/template_renderer.py +224 -0
  369. multi_agent_brief/product/trajectory_regulation.py +441 -0
  370. multi_agent_brief/provenance/__init__.py +5 -0
  371. multi_agent_brief/provenance/builder.py +841 -0
  372. multi_agent_brief/provenance/contract.py +21 -0
  373. multi_agent_brief/provenance/io.py +144 -0
  374. multi_agent_brief/provenance/model.py +110 -0
  375. multi_agent_brief/provenance/references.py +43 -0
  376. multi_agent_brief/provenance/validator.py +135 -0
  377. multi_agent_brief/quality_gates/__init__.py +19 -0
  378. multi_agent_brief/quality_gates/contract.py +581 -0
  379. multi_agent_brief/quality_gates/state.py +2498 -0
  380. multi_agent_brief/repair/__init__.py +5 -0
  381. multi_agent_brief/repair/router.py +842 -0
  382. multi_agent_brief/runtime_assets.py +431 -0
  383. multi_agent_brief/sources/__init__.py +16 -0
  384. multi_agent_brief/sources/api_filings.py +236 -0
  385. multi_agent_brief/sources/api_news.py +174 -0
  386. multi_agent_brief/sources/base.py +142 -0
  387. multi_agent_brief/sources/cached_package.py +119 -0
  388. multi_agent_brief/sources/cli_provider.py +263 -0
  389. multi_agent_brief/sources/coverage.py +336 -0
  390. multi_agent_brief/sources/decider.py +756 -0
  391. multi_agent_brief/sources/doctor.py +373 -0
  392. multi_agent_brief/sources/evidence_pack.py +364 -0
  393. multi_agent_brief/sources/feishu_provider.py +326 -0
  394. multi_agent_brief/sources/filing_resolver.py +400 -0
  395. multi_agent_brief/sources/industry_packs.py +130 -0
  396. multi_agent_brief/sources/join.py +206 -0
  397. multi_agent_brief/sources/local_signal.py +81 -0
  398. multi_agent_brief/sources/local_signal_planner.py +636 -0
  399. multi_agent_brief/sources/manual.py +259 -0
  400. multi_agent_brief/sources/mcp_provider.py +309 -0
  401. multi_agent_brief/sources/mineru_provider.py +601 -0
  402. multi_agent_brief/sources/normalizer.py +95 -0
  403. multi_agent_brief/sources/opencli_provider.py +282 -0
  404. multi_agent_brief/sources/planner.py +178 -0
  405. multi_agent_brief/sources/registry.py +367 -0
  406. multi_agent_brief/sources/rss.py +190 -0
  407. multi_agent_brief/sources/search_backends/__init__.py +31 -0
  408. multi_agent_brief/sources/search_backends/base.py +51 -0
  409. multi_agent_brief/sources/search_backends/brave.py +192 -0
  410. multi_agent_brief/sources/search_backends/capabilities.py +94 -0
  411. multi_agent_brief/sources/search_backends/exa.py +180 -0
  412. multi_agent_brief/sources/search_backends/firecrawl.py +164 -0
  413. multi_agent_brief/sources/search_backends/serper.py +241 -0
  414. multi_agent_brief/sources/search_backends/tavily.py +124 -0
  415. multi_agent_brief/sources/sourcehub.py +505 -0
  416. multi_agent_brief/sources/web_search.py +267 -0
  417. multi_agent_brief/status.py +966 -0
  418. multi_agent_brief/tools/__init__.py +3 -0
  419. multi_agent_brief/tools/draft_cleanup.py +198 -0
  420. multi_agent_brief/workbuddy/__init__.py +1 -0
  421. multi_agent_brief/workbuddy/diagnose.py +569 -0
  422. multi_agent_brief/workbuddy/skill_pack.py +309 -0
  423. multi_agent_brief/workspace/__init__.py +1 -0
  424. multi_agent_brief/workspace/init_profile.py +45 -0
@@ -0,0 +1,100 @@
1
+ """Provenance projection CLI commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ from typing import Any
8
+
9
+ from multi_agent_brief.orchestrator.runtime_state import RuntimeStateError
10
+ from multi_agent_brief.provenance.builder import (
11
+ build_provenance_workspace,
12
+ show_provenance_workspace,
13
+ validate_provenance_workspace,
14
+ )
15
+ from multi_agent_brief.provenance.model import ProvenanceError
16
+
17
+
18
+ def register(subparsers: argparse._SubParsersAction) -> None:
19
+ provenance_parser = subparsers.add_parser(
20
+ "provenance",
21
+ help="Build and inspect deterministic workspace provenance projections.",
22
+ )
23
+ actions = provenance_parser.add_subparsers(dest="provenance_action", required=True)
24
+
25
+ build_parser = actions.add_parser(
26
+ "build",
27
+ help="Build output/intermediate/provenance_graph.json from existing control files.",
28
+ )
29
+ build_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
30
+ build_parser.add_argument("--repo-workdir", help="Repository or packaged contract base.")
31
+ build_parser.add_argument("--strict", action="store_true", help="Fail when provenance warnings exist.")
32
+ build_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
33
+
34
+ show_parser = actions.add_parser(
35
+ "show",
36
+ help="Show provenance graph summary.",
37
+ )
38
+ show_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
39
+ show_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
40
+
41
+ validate_parser = actions.add_parser(
42
+ "validate",
43
+ help="Validate output/intermediate/provenance_graph.json.",
44
+ )
45
+ validate_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
46
+ validate_parser.add_argument("--strict", action="store_true", help="Fail when provenance warnings exist.")
47
+ validate_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
48
+
49
+
50
+ def handle(args: argparse.Namespace) -> int:
51
+ try:
52
+ if args.provenance_action == "build":
53
+ state = build_provenance_workspace(
54
+ workspace=args.workspace,
55
+ repo_workdir=getattr(args, "repo_workdir", None),
56
+ strict=getattr(args, "strict", False),
57
+ )
58
+ _print_state("provenance build", state, as_json=getattr(args, "json", False))
59
+ return 0 if state.get("ok") else 1
60
+
61
+ if args.provenance_action == "show":
62
+ state = show_provenance_workspace(workspace=args.workspace)
63
+ _print_state("provenance show", state, as_json=getattr(args, "json", False))
64
+ return 0 if state.get("ok") else 1
65
+
66
+ if args.provenance_action == "validate":
67
+ state = validate_provenance_workspace(
68
+ workspace=args.workspace,
69
+ strict=getattr(args, "strict", False),
70
+ )
71
+ _print_state("provenance validate", state, as_json=getattr(args, "json", False))
72
+ return 0 if state.get("ok") else 1
73
+ except (ProvenanceError, RuntimeStateError) as exc:
74
+ _print_error(exc, as_json=getattr(args, "json", False))
75
+ return 1
76
+ return 1
77
+
78
+
79
+ def _print_state(label: str, state: dict[str, Any], *, as_json: bool) -> None:
80
+ if as_json:
81
+ print(json.dumps(state, ensure_ascii=False, indent=2, sort_keys=True))
82
+ return
83
+ validation = state.get("validation") or {}
84
+ summary = (state.get("provenance_graph") or {}).get("summary") or state.get("summary") or {}
85
+ print(f"[{label}] ok: {state.get('ok')}")
86
+ print(f"[{label}] graph: {state.get('provenance_graph_path')}")
87
+ print(f"[{label}] nodes: {summary.get('node_count', validation.get('node_count', 0))}")
88
+ print(f"[{label}] edges: {summary.get('edge_count', validation.get('edge_count', 0))}")
89
+ print(f"[{label}] warnings: {summary.get('warning_count', validation.get('warning_count', 0))}")
90
+ print(f"[{label}] errors: {summary.get('error_count', validation.get('error_count', 0))}")
91
+ for error in validation.get("errors") or []:
92
+ print(f" - {error}")
93
+
94
+
95
+ def _print_error(exc: Exception, *, as_json: bool) -> None:
96
+ payload = exc.to_dict() if hasattr(exc, "to_dict") else {"ok": False, "error": str(exc)}
97
+ if as_json:
98
+ print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
99
+ else:
100
+ print(f"[provenance] {exc}")
@@ -0,0 +1,68 @@
1
+ """Release readiness check CLI commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ from typing import Any
8
+
9
+ from multi_agent_brief.orchestrator.runtime_state.errors import RuntimeStateError
10
+ from multi_agent_brief.product.release_approval import (
11
+ ReleaseApprovalError,
12
+ check_release_readiness,
13
+ )
14
+
15
+
16
+ def register(subparsers: argparse._SubParsersAction) -> None:
17
+ parser = subparsers.add_parser(
18
+ "release",
19
+ help="Check internal review readiness without authorizing public release.",
20
+ )
21
+ actions = parser.add_subparsers(dest="release_action", required=True)
22
+ check_parser = actions.add_parser("check", help="Write a release readiness report.")
23
+ check_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
24
+ check_parser.add_argument("--mode", required=True, help="Release mode, for example ir_draft.")
25
+ check_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
26
+
27
+
28
+ def handle(args: argparse.Namespace) -> int:
29
+ action = getattr(args, "release_action", "")
30
+ try:
31
+ if action == "check":
32
+ result = check_release_readiness(workspace=args.workspace, mode=args.mode)
33
+ payload = dict(result.payload)
34
+ payload["ok"] = payload.get("status") == "pass"
35
+ payload["report_path"] = "output/intermediate/release_readiness_report.json"
36
+ _print_payload("release check", payload, as_json=getattr(args, "json", False))
37
+ return 0 if payload["ok"] else 1
38
+ except (ReleaseApprovalError, RuntimeStateError, OSError, json.JSONDecodeError) as exc:
39
+ payload = {"ok": False, "error": str(exc)}
40
+ _print_payload("release check", payload, as_json=getattr(args, "json", False))
41
+ return 1
42
+ raise AssertionError(f"Unhandled release action: {action}")
43
+
44
+
45
+ def _print_payload(label: str, payload: dict[str, Any], *, as_json: bool) -> None:
46
+ if as_json:
47
+ print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
48
+ return
49
+ print(label)
50
+ for key in (
51
+ "ok",
52
+ "mode",
53
+ "status",
54
+ "approval_required",
55
+ "missing_roles",
56
+ "blockers",
57
+ "branding_context",
58
+ "authorization",
59
+ "next_step",
60
+ "report_path",
61
+ ):
62
+ if key not in payload:
63
+ continue
64
+ value = payload[key]
65
+ if isinstance(value, (dict, list)):
66
+ print(f"{key}: {json.dumps(value, ensure_ascii=False, sort_keys=True)}")
67
+ else:
68
+ print(f"{key}: {value}")
@@ -0,0 +1,169 @@
1
+ """Repair routing CLI commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ from typing import Any
8
+
9
+ from multi_agent_brief.orchestrator.runtime_state import (
10
+ RuntimeStateError,
11
+ complete_repair_transaction,
12
+ start_repair_transaction,
13
+ )
14
+ from multi_agent_brief.repair.router import route_repair
15
+
16
+
17
+ def register(subparsers: argparse._SubParsersAction) -> None:
18
+ repair_parser = subparsers.add_parser(
19
+ "repair",
20
+ help="Route and execute deterministic owner-stage repair transactions.",
21
+ )
22
+ actions = repair_parser.add_subparsers(dest="repair_action", required=True)
23
+ route_parser = actions.add_parser(
24
+ "route",
25
+ help="Show allowed repair owner/artifacts for the current workspace issue.",
26
+ )
27
+ route_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
28
+ route_parser.add_argument(
29
+ "--route-index",
30
+ type=int,
31
+ help="0-based route index to inspect explicitly.",
32
+ )
33
+ route_parser.add_argument(
34
+ "--finding-id",
35
+ help="Finding ID to inspect explicitly.",
36
+ )
37
+ route_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
38
+ start_parser = actions.add_parser(
39
+ "start",
40
+ help="Start the deterministic owner-stage repair transaction for the current route.",
41
+ )
42
+ start_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
43
+ start_parser.add_argument(
44
+ "--repo-workdir",
45
+ help="Repository or packaged contract base (default: auto-detect).",
46
+ )
47
+ start_parser.add_argument(
48
+ "--actor",
49
+ default="orchestrator",
50
+ choices=("cli", "orchestrator", "runtime", "system"),
51
+ help="Actor recorded in event_log.jsonl.",
52
+ )
53
+ start_parser.add_argument(
54
+ "--route-index",
55
+ type=int,
56
+ help="0-based route index from `repair route --json` to start explicitly.",
57
+ )
58
+ start_parser.add_argument(
59
+ "--finding-id",
60
+ help="Finding ID from `repair route --json` to start explicitly.",
61
+ )
62
+ start_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
63
+ complete_parser = actions.add_parser(
64
+ "complete",
65
+ help="Complete the active owner-stage repair transaction.",
66
+ )
67
+ complete_parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
68
+ complete_parser.add_argument("--reason", required=True, help="Short repair completion reason summary.")
69
+ complete_parser.add_argument(
70
+ "--repo-workdir",
71
+ help="Repository or packaged contract base (default: auto-detect).",
72
+ )
73
+ complete_parser.add_argument(
74
+ "--actor",
75
+ default="orchestrator",
76
+ choices=("cli", "orchestrator", "runtime", "system"),
77
+ help="Actor recorded in event_log.jsonl.",
78
+ )
79
+ complete_parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
80
+
81
+
82
+ def handle(args: argparse.Namespace) -> int:
83
+ try:
84
+ if args.repair_action == "route":
85
+ payload = route_repair(
86
+ workspace=args.workspace,
87
+ route_index=getattr(args, "route_index", None),
88
+ finding_id=getattr(args, "finding_id", None),
89
+ )
90
+ if getattr(args, "json", False):
91
+ print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
92
+ else:
93
+ _print_route(payload)
94
+ return 0 if payload.get("ok") else 1
95
+ if args.repair_action == "start":
96
+ payload = start_repair_transaction(
97
+ workspace=args.workspace,
98
+ repo_workdir=getattr(args, "repo_workdir", None),
99
+ actor=getattr(args, "actor", "orchestrator"),
100
+ route_index=getattr(args, "route_index", None),
101
+ finding_id=getattr(args, "finding_id", None),
102
+ )
103
+ if getattr(args, "json", False):
104
+ print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
105
+ else:
106
+ _print_repair_state("repair start", payload)
107
+ return 0
108
+ if args.repair_action == "complete":
109
+ payload = complete_repair_transaction(
110
+ workspace=args.workspace,
111
+ reason=args.reason,
112
+ repo_workdir=getattr(args, "repo_workdir", None),
113
+ actor=getattr(args, "actor", "orchestrator"),
114
+ )
115
+ if getattr(args, "json", False):
116
+ print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
117
+ else:
118
+ _print_repair_state("repair complete", payload)
119
+ return 0
120
+ except RuntimeStateError as exc:
121
+ if getattr(args, "json", False):
122
+ print(json.dumps(exc.to_dict(), ensure_ascii=False, indent=2, sort_keys=True))
123
+ else:
124
+ print(f"[repair] {exc}")
125
+ return 1
126
+ return 1
127
+
128
+
129
+ def _print_route(payload: dict[str, Any]) -> None:
130
+ if not payload.get("ok"):
131
+ print(f"[repair route] Error: {payload.get('message') or payload.get('error')}")
132
+ return
133
+ print(f"[repair route] owner: {payload.get('repair_owner')}")
134
+ print(f"[repair route] must_rerun_from: {payload.get('must_rerun_from') or 'none'}")
135
+ print(f"[repair route] reason: {payload.get('reason')}")
136
+ if payload.get("default_selected") is True:
137
+ source = payload.get("source") if isinstance(payload.get("source"), dict) else {}
138
+ finding_id = source.get("finding_id") or source.get("finding_type") or "selected route"
139
+ print(
140
+ f"[repair route] default: {finding_id} -> {payload.get('repair_owner')} "
141
+ f"-> {', '.join(payload.get('allowed_artifacts') or []) or 'none'}"
142
+ )
143
+ print("[repair route] allowed_artifacts:")
144
+ for artifact in payload.get("allowed_artifacts") or []:
145
+ print(f" - {artifact}")
146
+ blocked = payload.get("blocked_direct_edits") or []
147
+ if blocked:
148
+ print("[repair route] blocked_direct_edits:")
149
+ for artifact in blocked:
150
+ print(f" - {artifact}")
151
+
152
+
153
+ def _print_repair_state(label: str, payload: dict[str, Any]) -> None:
154
+ workflow = payload.get("workflow_state") or {}
155
+ repair = payload.get("repair") or workflow.get("active_repair") or {}
156
+ print(f"[{label}] current_stage: {workflow.get('current_stage')}")
157
+ print(f"[{label}] repair_owner: {repair.get('repair_owner')}")
158
+ print(f"[{label}] must_rerun_from: {repair.get('must_rerun_from') or repair.get('next_stage') or 'none'}")
159
+ allowed = repair.get("allowed_artifacts") or []
160
+ if allowed:
161
+ print(f"[{label}] allowed_artifacts:")
162
+ for artifact in allowed:
163
+ print(f" - {artifact}")
164
+ effect = repair.get("run_integrity_effect")
165
+ if isinstance(effect, dict) and effect.get("reference_eligible") is False:
166
+ print(f"[{label}] reference_eligible: false")
167
+ reason = effect.get("reason")
168
+ if reason:
169
+ print(f"[{label}] run_integrity_note: {reason}")
@@ -0,0 +1,292 @@
1
+ """run / start / handoff / prepare — runtime handoff launcher commands."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import sys
7
+ from pathlib import Path
8
+
9
+ from multi_agent_brief.orchestrator.handoff import (
10
+ RUNTIME_RECIPE_FAST_RERUN,
11
+ VALID_RUNTIMES,
12
+ VALID_RUNTIME_RECIPES,
13
+ build_handoff,
14
+ legacy_runtime_alias_warning,
15
+ render_handoff_cli,
16
+ write_handoff_and_state,
17
+ )
18
+ from multi_agent_brief.orchestrator.fact_layer_import import require_fast_rerun_handoff_ready
19
+ from multi_agent_brief.orchestrator_contract import resolve_repo_workdir
20
+
21
+
22
+ def register(subparsers: argparse._SubParsersAction) -> None:
23
+ """Register run, start, handoff, and prepare subparsers."""
24
+
25
+ run_parser = subparsers.add_parser(
26
+ "run",
27
+ help="Run a workspace through the selected agent runtime handoff.",
28
+ )
29
+ run_parser.add_argument(
30
+ "--workspace", help="Path to workspace directory."
31
+ )
32
+ run_parser.add_argument(
33
+ "--config",
34
+ help="Path to workspace config.yaml (convenience alias for --workspace).",
35
+ )
36
+ run_parser.add_argument(
37
+ "--runtime",
38
+ default="auto",
39
+ choices=list(VALID_RUNTIMES),
40
+ help="Target runtime for handoff (default: auto, resolves to hermes; manual is a legacy alias for operator).",
41
+ )
42
+ run_parser.add_argument(
43
+ "--recipe",
44
+ default="full",
45
+ choices=list(VALID_RUNTIME_RECIPES),
46
+ help="Runtime handoff recipe: full or fast-rerun (guidance only, not a Python pipeline).",
47
+ )
48
+ run_parser.add_argument(
49
+ "--repo-workdir",
50
+ help="Repository workdir (default: auto-detect source repo).",
51
+ )
52
+ run_parser.add_argument(
53
+ "--venv", help="Virtual env path (default: auto-detect)."
54
+ )
55
+ run_parser.add_argument(
56
+ "--skip-doctor", action="store_true", help="Skip doctor check."
57
+ )
58
+ prepare_parser = subparsers.add_parser(
59
+ "prepare",
60
+ help="[legacy] Replaced by 'briefloop run'.",
61
+ )
62
+ prepare_parser.add_argument(
63
+ "--config", required=True, help="Path to config.yaml in the workspace."
64
+ )
65
+ prepare_parser.add_argument("--input", help="Override input directory.")
66
+ prepare_parser.add_argument("--output", help="Override output directory.")
67
+
68
+ start_parser = subparsers.add_parser(
69
+ "start",
70
+ help="Alias for run: create runtime handoff for the current agent.",
71
+ )
72
+ start_parser.add_argument(
73
+ "--workspace", help="Path to workspace directory."
74
+ )
75
+ start_parser.add_argument(
76
+ "--runtime",
77
+ default="auto",
78
+ choices=list(VALID_RUNTIMES),
79
+ help="Target runtime for handoff (default: auto, resolves to hermes; manual is a legacy alias for operator).",
80
+ )
81
+ start_parser.add_argument(
82
+ "--recipe",
83
+ default="full",
84
+ choices=list(VALID_RUNTIME_RECIPES),
85
+ help="Runtime handoff recipe: full or fast-rerun (guidance only, not a Python pipeline).",
86
+ )
87
+ start_parser.add_argument(
88
+ "--repo-workdir",
89
+ help="Repository workdir (default: auto-detect source repo).",
90
+ )
91
+ start_parser.add_argument(
92
+ "--venv", help="Virtual env path (default: auto-detect)."
93
+ )
94
+ start_parser.add_argument(
95
+ "--skip-doctor", action="store_true", help="Skip doctor check."
96
+ )
97
+ handoff_parser = subparsers.add_parser(
98
+ "handoff",
99
+ help="Generate a runtime handoff artifact from a workspace config.",
100
+ )
101
+ handoff_parser.add_argument(
102
+ "--config", required=True, help="Path to workspace config.yaml."
103
+ )
104
+ handoff_parser.add_argument(
105
+ "--runtime",
106
+ default="auto",
107
+ choices=list(VALID_RUNTIMES),
108
+ help="Target runtime for handoff (default: auto, resolves to hermes; manual is a legacy alias for operator).",
109
+ )
110
+ handoff_parser.add_argument(
111
+ "--recipe",
112
+ default="full",
113
+ choices=list(VALID_RUNTIME_RECIPES),
114
+ help="Runtime handoff recipe: full or fast-rerun (guidance only, not a Python pipeline).",
115
+ )
116
+ handoff_parser.add_argument(
117
+ "--repo-workdir",
118
+ help="Repository workdir (default: auto-detect source repo).",
119
+ )
120
+ handoff_parser.add_argument(
121
+ "--venv", help="Virtual env path (default: auto-detect)."
122
+ )
123
+ handoff_parser.add_argument(
124
+ "--skip-doctor", action="store_true", help="Skip doctor check."
125
+ )
126
+
127
+ def handle(args: argparse.Namespace) -> int:
128
+ """Dispatch run / start / handoff / prepare commands."""
129
+ if args.command == "prepare":
130
+ return _run_prepare(args)
131
+ if args.command == "handoff":
132
+ return _run_handoff(args)
133
+ # run and start both use the launcher
134
+ return _run_launcher(args)
135
+
136
+
137
+ def _resolve_workspace(args: argparse.Namespace) -> Path | None:
138
+ """Resolve workspace path from --workspace, --config, or CWD auto-detect."""
139
+ workspace = getattr(args, "workspace", None)
140
+ config_path = getattr(args, "config", None)
141
+
142
+ if config_path and not workspace:
143
+ cp = Path(config_path).resolve()
144
+ if cp.is_file():
145
+ workspace = str(cp.parent)
146
+ elif cp.is_dir():
147
+ workspace = str(cp)
148
+
149
+ if not workspace:
150
+ cwd = Path.cwd()
151
+ if (cwd / "config.yaml").exists() and (cwd / "user.md").exists():
152
+ workspace = str(cwd)
153
+
154
+ if not workspace:
155
+ return None
156
+
157
+ ws_path = Path(workspace).resolve()
158
+ if not (ws_path / "config.yaml").exists():
159
+ return None
160
+ return ws_path
161
+
162
+
163
+ def _run_launcher(args: argparse.Namespace) -> int:
164
+ """run — standard runtime handoff launcher."""
165
+ prefix = (
166
+ "[start]" if getattr(args, "command", None) == "start" else "[run]"
167
+ )
168
+
169
+ workspace_path = _resolve_workspace(args)
170
+ if workspace_path is None:
171
+ print(f"{prefix} No workspace found.")
172
+ print()
173
+ print("For a real workspace:")
174
+ print(" briefloop onboard")
175
+ print(" briefloop init <workspace> --from-onboarding onboarding.json")
176
+ print()
177
+ print("For a demo only:")
178
+ print(" briefloop init <workspace> --demo")
179
+ return 1
180
+
181
+ try:
182
+ repo_workdir = resolve_repo_workdir(
183
+ getattr(args, "repo_workdir", None),
184
+ workspace=workspace_path,
185
+ )
186
+ except ValueError as exc:
187
+ print(f"{prefix} {exc}")
188
+ return 1
189
+
190
+ recipe = getattr(args, "recipe", "full")
191
+ if recipe == RUNTIME_RECIPE_FAST_RERUN:
192
+ try:
193
+ require_fast_rerun_handoff_ready(workspace_path)
194
+ except ValueError as exc:
195
+ print(f"{prefix} {exc}")
196
+ return 1
197
+
198
+ try:
199
+ handoff = build_handoff(
200
+ workspace=workspace_path,
201
+ repo_workdir=repo_workdir,
202
+ runtime=args.runtime,
203
+ recipe=recipe,
204
+ venv=getattr(args, "venv", None),
205
+ run_doctor=not getattr(args, "skip_doctor", False),
206
+ )
207
+ except ValueError as exc:
208
+ print(f"{prefix} {exc}")
209
+ return 1
210
+ _print_runtime_alias_warning(prefix, getattr(args, "runtime", ""))
211
+
212
+ written = write_handoff_and_state(
213
+ handoff=handoff,
214
+ workspace=workspace_path,
215
+ repo_workdir=repo_workdir,
216
+ prefix=prefix,
217
+ )
218
+ if written is None:
219
+ return 1
220
+ md_path, json_path = written
221
+ print(render_handoff_cli(handoff))
222
+ print(f"{prefix} Handoff written: {md_path}")
223
+ print(f"{prefix} Handoff JSON: {json_path}")
224
+ return 0
225
+
226
+
227
+ def _run_prepare(args: argparse.Namespace) -> int:
228
+ """[legacy] prepare — replaced by the runtime handoff launcher."""
229
+ print(
230
+ "[legacy] prepare has been replaced by:"
231
+ " briefloop run --workspace <workspace>"
232
+ )
233
+ return 1
234
+
235
+
236
+ def _run_handoff(args: argparse.Namespace) -> int:
237
+ """handoff — generate runtime handoff from workspace config."""
238
+ config_path = Path(args.config).resolve()
239
+ if not config_path.exists():
240
+ print(f"[error] config.yaml not found: {config_path}")
241
+ return 1
242
+ workspace = config_path.parent
243
+ try:
244
+ repo_workdir = resolve_repo_workdir(
245
+ getattr(args, "repo_workdir", None),
246
+ workspace=workspace,
247
+ )
248
+ except ValueError as exc:
249
+ print(f"[handoff] {exc}")
250
+ return 1
251
+
252
+ recipe = getattr(args, "recipe", "full")
253
+ if recipe == RUNTIME_RECIPE_FAST_RERUN:
254
+ try:
255
+ require_fast_rerun_handoff_ready(workspace)
256
+ except ValueError as exc:
257
+ print(f"[handoff] {exc}")
258
+ return 1
259
+
260
+ try:
261
+ handoff = build_handoff(
262
+ workspace=workspace,
263
+ repo_workdir=repo_workdir,
264
+ runtime=args.runtime,
265
+ recipe=recipe,
266
+ venv=getattr(args, "venv", None),
267
+ run_doctor=not getattr(args, "skip_doctor", False),
268
+ )
269
+ except ValueError as exc:
270
+ print(f"[handoff] {exc}")
271
+ return 1
272
+ _print_runtime_alias_warning("[handoff]", getattr(args, "runtime", ""))
273
+
274
+ written = write_handoff_and_state(
275
+ handoff=handoff,
276
+ workspace=workspace,
277
+ repo_workdir=repo_workdir,
278
+ prefix="[handoff]",
279
+ )
280
+ if written is None:
281
+ return 1
282
+ md_path, json_path = written
283
+ print(render_handoff_cli(handoff))
284
+ print(f"[handoff] Written: {md_path}")
285
+ print(f"[handoff] JSON: {json_path}")
286
+ return 0
287
+
288
+
289
+ def _print_runtime_alias_warning(prefix: str, runtime: str) -> None:
290
+ warning = legacy_runtime_alias_warning(runtime)
291
+ if warning:
292
+ print(f"{prefix} WARNING: {warning}", file=sys.stderr)