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,356 @@
1
+ """hermes — Hermes Agent skill / cron plan / prompt 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.hermes import (
10
+ build_hermes_cron_plan,
11
+ install_hermes_skill,
12
+ render_hermes_cron_commands,
13
+ render_hermes_cron_markdown,
14
+ render_hermes_prompt,
15
+ render_hermes_skill,
16
+ )
17
+ from multi_agent_brief.hermes.adapter import sync_cached_package_source, write_json
18
+
19
+
20
+ def register(subparsers: argparse._SubParsersAction) -> None:
21
+ """Register the hermes subcommand group."""
22
+ hermes_parser = subparsers.add_parser(
23
+ "hermes",
24
+ help="Generate Hermes Agent skill and cron plans for scheduled briefs.",
25
+ )
26
+ hermes_sub = hermes_parser.add_subparsers(
27
+ dest="hermes_action", required=True
28
+ )
29
+
30
+ hermes_skill = hermes_sub.add_parser(
31
+ "skill", help="Write the Hermes SKILL.md for MABW cron jobs."
32
+ )
33
+ hermes_skill.add_argument(
34
+ "--output",
35
+ help="Output SKILL.md path"
36
+ " (default: .agents/hermes-skills/multi-agent-brief-hermes/SKILL.md).",
37
+ )
38
+
39
+ hermes_plan = hermes_sub.add_parser(
40
+ "cron-plan",
41
+ help="Generate a Hermes cron plan JSON/Markdown for a workspace.",
42
+ )
43
+ hermes_plan.add_argument(
44
+ "--config", required=True, help="Path to workspace config.yaml."
45
+ )
46
+ hermes_plan.add_argument(
47
+ "--repo-workdir",
48
+ help="Repository workdir for Hermes cron --workdir"
49
+ " (default: current directory).",
50
+ )
51
+ hermes_plan.add_argument(
52
+ "--cadence",
53
+ help="Comma-separated cadences: weekly,monthly,daily."
54
+ " Defaults to config cadence or weekly.",
55
+ )
56
+ hermes_plan.add_argument(
57
+ "--deliver",
58
+ default="local",
59
+ help="Hermes delivery target, e.g. local, feishu, telegram.",
60
+ )
61
+ hermes_plan.add_argument(
62
+ "--profile",
63
+ default="",
64
+ help="Optional existing Hermes profile name.",
65
+ )
66
+ hermes_plan.add_argument(
67
+ "--output",
68
+ help="Output JSON path"
69
+ " (default: workspace/output/intermediate/hermes_cron_plan.json).",
70
+ )
71
+ hermes_plan.add_argument(
72
+ "--markdown", help="Optional Markdown output path."
73
+ )
74
+
75
+ hermes_commands = hermes_sub.add_parser(
76
+ "cron-commands",
77
+ help="Print Hermes cron create commands for a workspace.",
78
+ )
79
+ hermes_commands.add_argument(
80
+ "--config", required=True, help="Path to workspace config.yaml."
81
+ )
82
+ hermes_commands.add_argument(
83
+ "--repo-workdir",
84
+ help="Repository workdir for Hermes cron --workdir"
85
+ " (default: current directory).",
86
+ )
87
+ hermes_commands.add_argument(
88
+ "--cadence",
89
+ help="Comma-separated cadences: weekly,monthly,daily."
90
+ " Defaults to config cadence or weekly.",
91
+ )
92
+ hermes_commands.add_argument(
93
+ "--deliver",
94
+ default="local",
95
+ help="Hermes delivery target, e.g. local, feishu, telegram.",
96
+ )
97
+ hermes_commands.add_argument(
98
+ "--profile",
99
+ default="",
100
+ help="Optional existing Hermes profile name.",
101
+ )
102
+
103
+ hermes_sync = hermes_sub.add_parser(
104
+ "sync-sources",
105
+ help="Enable cached_package input/hermes_cache in workspace"
106
+ " sources.yaml.",
107
+ )
108
+ hermes_sync.add_argument(
109
+ "--config", required=True, help="Path to workspace config.yaml."
110
+ )
111
+ hermes_sync.add_argument(
112
+ "--cache-dir",
113
+ default="input/hermes_cache",
114
+ help="Cache path written into sources.yaml.",
115
+ )
116
+ hermes_sync.add_argument(
117
+ "--dry-run",
118
+ action="store_true",
119
+ help="Show changes without writing.",
120
+ )
121
+
122
+ hermes_install = hermes_sub.add_parser(
123
+ "install-skill",
124
+ help="Install the MABW Hermes skill to a Hermes-discoverable"
125
+ " directory.",
126
+ )
127
+ hermes_install.add_argument(
128
+ "--target",
129
+ help="Target skill directory (auto-detected if omitted).",
130
+ )
131
+
132
+ hermes_plugin = hermes_sub.add_parser(
133
+ "install-plugin",
134
+ help="Install the MABW Hermes plugin to ~/.hermes/plugins/mabw.",
135
+ )
136
+
137
+ hermes_prompt = hermes_sub.add_parser(
138
+ "prompt",
139
+ help="Generate a Hermes run prompt for a workspace.",
140
+ )
141
+ hermes_prompt.add_argument(
142
+ "--config", required=True, help="Path to workspace config.yaml."
143
+ )
144
+ hermes_prompt.add_argument(
145
+ "--repo-workdir",
146
+ help="Repository workdir (default: current directory).",
147
+ )
148
+ hermes_prompt.add_argument(
149
+ "--venv",
150
+ help="Virtual env path"
151
+ " (default: <repo>/.venv/{bin,Scripts}/activate).",
152
+ )
153
+
154
+
155
+ def handle(args: argparse.Namespace) -> int:
156
+ """Dispatch hermes subcommands."""
157
+ if args.hermes_action == "skill":
158
+ return _hermes_skill(args)
159
+ if args.hermes_action == "cron-plan":
160
+ return _hermes_cron_plan(args)
161
+ if args.hermes_action == "cron-commands":
162
+ return _hermes_cron_commands(args)
163
+ if args.hermes_action == "sync-sources":
164
+ return _hermes_sync_sources(args)
165
+ if args.hermes_action == "install-skill":
166
+ return _hermes_install_skill(args)
167
+ if args.hermes_action == "install-plugin":
168
+ return _hermes_install_plugin(args)
169
+ if args.hermes_action == "prompt":
170
+ return _hermes_prompt(args)
171
+ return 1
172
+
173
+
174
+ def _build_hermes_plan_from_args(args: argparse.Namespace):
175
+ from multi_agent_brief.core.config import load_config
176
+
177
+ config_path = Path(args.config).resolve()
178
+ if not config_path.exists():
179
+ print(f"[error] config.yaml not found: {config_path}")
180
+ return None
181
+ config = load_config(config_path)
182
+ cadences = None
183
+ if getattr(args, "cadence", None):
184
+ cadences = [
185
+ c.strip() for c in args.cadence.split(",") if c.strip()
186
+ ]
187
+ repo_workdir = (
188
+ Path(args.repo_workdir).resolve()
189
+ if getattr(args, "repo_workdir", None)
190
+ else Path.cwd().resolve()
191
+ )
192
+ return build_hermes_cron_plan(
193
+ config=config,
194
+ workspace=config_path.parent,
195
+ repo_workdir=repo_workdir,
196
+ cadences=cadences,
197
+ deliver=getattr(args, "deliver", "local"),
198
+ profile=getattr(args, "profile", ""),
199
+ )
200
+
201
+
202
+ def _hermes_skill(args: argparse.Namespace) -> int:
203
+ output = (
204
+ Path(args.output)
205
+ if args.output
206
+ else Path(
207
+ ".agents/hermes-skills/multi-agent-brief-hermes/SKILL.md"
208
+ )
209
+ )
210
+ output.parent.mkdir(parents=True, exist_ok=True)
211
+ output.write_text(render_hermes_skill(), encoding="utf-8")
212
+ print(f"[hermes] Wrote Hermes skill: {output}")
213
+ print(
214
+ "[hint] Run 'multi-agent-brief hermes install-skill' to install to"
215
+ " a Hermes-discoverable directory."
216
+ )
217
+ return 0
218
+
219
+
220
+ def _hermes_cron_plan(args: argparse.Namespace) -> int:
221
+ plan = _build_hermes_plan_from_args(args)
222
+ if plan is None:
223
+ return 1
224
+ workspace = Path(plan.workspace)
225
+ output = (
226
+ Path(args.output)
227
+ if args.output
228
+ else workspace / "output" / "intermediate" / "hermes_cron_plan.json"
229
+ )
230
+ write_json(output, plan.to_dict())
231
+ print(f"[hermes] Wrote cron plan: {output}")
232
+ if args.markdown:
233
+ md_path = Path(args.markdown)
234
+ md_path.parent.mkdir(parents=True, exist_ok=True)
235
+ md_path.write_text(
236
+ render_hermes_cron_markdown(plan), encoding="utf-8"
237
+ )
238
+ print(f"[hermes] Wrote cron plan Markdown: {md_path}")
239
+ print(
240
+ "[hint] Run 'multi-agent-brief hermes cron-commands"
241
+ " --config <workspace>/config.yaml' to print install commands."
242
+ )
243
+ return 0
244
+
245
+
246
+ def _hermes_cron_commands(args: argparse.Namespace) -> int:
247
+ plan = _build_hermes_plan_from_args(args)
248
+ if plan is None:
249
+ return 1
250
+ print(render_hermes_cron_commands(plan), end="")
251
+ return 0
252
+
253
+
254
+ def _hermes_sync_sources(args: argparse.Namespace) -> int:
255
+ config_path = Path(args.config).resolve()
256
+ sources_path = config_path.parent / "sources.yaml"
257
+ try:
258
+ result = sync_cached_package_source(
259
+ sources_path=sources_path,
260
+ cache_dir=args.cache_dir,
261
+ dry_run=args.dry_run,
262
+ )
263
+ except Exception as exc:
264
+ print(f"[error] {exc}")
265
+ return 1
266
+ action = (
267
+ "would update"
268
+ if args.dry_run and result["changed"]
269
+ else "updated"
270
+ if result["changed"]
271
+ else "already configured"
272
+ )
273
+ print(f"[hermes] sources.yaml {action}: {sources_path}")
274
+ print(f"[hermes] cached_package path: {result['cache_dir']}")
275
+ print(
276
+ "[hermes] enabled providers:"
277
+ f" {', '.join(result['enabled_providers'])}"
278
+ )
279
+ return 0
280
+
281
+
282
+ def _hermes_install_skill(args: argparse.Namespace) -> int:
283
+ result = install_hermes_skill(target_dir=args.target)
284
+ print(f"[hermes] Installed skill: {result['skill_path']}")
285
+ if result["auto_detected"]:
286
+ print(
287
+ "[hermes] Auto-detected Hermes skill directory:"
288
+ f" {result['skill_dir']}"
289
+ )
290
+ if result["hint"]:
291
+ print(f"[hint] {result['hint']}")
292
+ print()
293
+ print(
294
+ "[hermes] Next: generate a run prompt for your workspace:"
295
+ )
296
+ print(
297
+ " multi-agent-brief hermes prompt"
298
+ " --config <workspace>/config.yaml"
299
+ )
300
+ print(
301
+ "[hermes] Then paste the prompt into Hermes to start the delegated"
302
+ " brief workflow."
303
+ )
304
+ return 0
305
+
306
+
307
+ def _hermes_install_plugin(_args: argparse.Namespace) -> int:
308
+ import shutil
309
+
310
+ repo_root = Path.cwd().resolve()
311
+ source = repo_root / "integrations" / "hermes-plugin" / "mabw"
312
+ target = Path.home() / ".hermes" / "plugins" / "mabw"
313
+
314
+ if not source.exists():
315
+ print(
316
+ f"[error] Plugin source not found: {source}"
317
+ )
318
+ print(
319
+ "[hint] Run this command from the MABW source repo root."
320
+ )
321
+ return 1
322
+
323
+ if target.exists():
324
+ shutil.rmtree(target)
325
+
326
+ shutil.copytree(source, target)
327
+ print(f"Plugin installed: {target}")
328
+ print(
329
+ "Next: restart Hermes or run `hermes plugins enable mabw`"
330
+ )
331
+ return 0
332
+
333
+
334
+ def _hermes_prompt(args: argparse.Namespace) -> int:
335
+ config_path = Path(args.config).resolve()
336
+ workspace = config_path.parent
337
+ repo_workdir = (
338
+ Path(args.repo_workdir).resolve()
339
+ if getattr(args, "repo_workdir", None)
340
+ else Path.cwd().resolve()
341
+ )
342
+ if args.venv:
343
+ venv_activate = str(Path(args.venv).resolve())
344
+ else:
345
+ venv = repo_workdir / ".venv"
346
+ if sys.platform == "win32":
347
+ venv_activate = str(venv / "Scripts" / "activate")
348
+ else:
349
+ venv_activate = str(venv / "bin" / "activate")
350
+ prompt = render_hermes_prompt(
351
+ workspace=workspace,
352
+ repo_workdir=repo_workdir,
353
+ venv_path=venv_activate,
354
+ )
355
+ print(prompt, end="")
356
+ return 0
@@ -0,0 +1,224 @@
1
+ """Improvement Ledger 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.improvement.contract import (
10
+ ALLOWED_STATUSES,
11
+ AUDIENCE_GUIDANCE_CATEGORIES,
12
+ AUDIENCE_GUIDANCE_SCOPES,
13
+ )
14
+ from multi_agent_brief.improvement.memory import rebuild_improvement_memory
15
+ from multi_agent_brief.improvement.state import (
16
+ ImprovementLedgerError,
17
+ approve_improvement,
18
+ improvement_stats,
19
+ list_improvements,
20
+ propose_improvement,
21
+ reject_improvement,
22
+ revert_improvement,
23
+ show_improvement,
24
+ validate_improvement_ledger,
25
+ )
26
+
27
+
28
+ def register(subparsers: argparse._SubParsersAction) -> None:
29
+ improve_parser = subparsers.add_parser(
30
+ "improve",
31
+ help="Manage the append-only Improvement Ledger.",
32
+ )
33
+ actions = improve_parser.add_subparsers(dest="improve_action", required=True)
34
+
35
+ propose_parser = actions.add_parser(
36
+ "propose",
37
+ help="Append a proposed audience-guidance improvement.",
38
+ )
39
+ _add_workspace(propose_parser)
40
+ propose_parser.add_argument("--guidance", required=True, help="Bounded audience guidance text.")
41
+ propose_parser.add_argument("--category", required=True, choices=sorted(AUDIENCE_GUIDANCE_CATEGORIES))
42
+ propose_parser.add_argument("--scope", required=True, choices=sorted(AUDIENCE_GUIDANCE_SCOPES))
43
+ propose_parser.add_argument("--source-summary", help="Required for explicit human proposals.")
44
+ propose_parser.add_argument("--from-issue", help="Feedback issue id to freeze as source evidence.")
45
+ propose_parser.add_argument("--supersedes", help="Approved materializable entry id replaced by this proposal.")
46
+ _add_json(propose_parser)
47
+
48
+ list_parser = actions.add_parser(
49
+ "list",
50
+ help="List current Improvement Ledger entries.",
51
+ )
52
+ _add_workspace(list_parser)
53
+ list_parser.add_argument("--status", choices=sorted(ALLOWED_STATUSES), help="Filter by current status.")
54
+ _add_json(list_parser)
55
+
56
+ show_parser = actions.add_parser(
57
+ "show",
58
+ help="Show one Improvement Ledger entry and its revisions.",
59
+ )
60
+ _add_workspace(show_parser)
61
+ show_parser.add_argument("--entry-id", required=True, help="Improvement entry id, such as AG-0001.")
62
+ _add_json(show_parser)
63
+
64
+ approve_parser = actions.add_parser(
65
+ "approve",
66
+ help="Approve a proposed Improvement Ledger entry without applying it.",
67
+ )
68
+ _add_workspace(approve_parser)
69
+ approve_parser.add_argument("--entry-id", required=True, help="Improvement entry id.")
70
+ approve_parser.add_argument("--by", required=True, help="Operator id approving this entry.")
71
+ _add_json(approve_parser)
72
+
73
+ reject_parser = actions.add_parser(
74
+ "reject",
75
+ help="Reject a proposed Improvement Ledger entry.",
76
+ )
77
+ _add_workspace(reject_parser)
78
+ reject_parser.add_argument("--entry-id", required=True, help="Improvement entry id.")
79
+ reject_parser.add_argument("--by", required=True, help="Operator id rejecting this entry.")
80
+ reject_parser.add_argument("--reason", required=True, help="Short rejection reason.")
81
+ _add_json(reject_parser)
82
+
83
+ revert_parser = actions.add_parser(
84
+ "revert",
85
+ help="Revert an approved Improvement Ledger entry.",
86
+ )
87
+ _add_workspace(revert_parser)
88
+ revert_parser.add_argument("--entry-id", required=True, help="Improvement entry id.")
89
+ revert_parser.add_argument("--by", required=True, help="Operator id reverting this entry.")
90
+ revert_parser.add_argument("--reason", required=True, help="Short revert reason.")
91
+ _add_json(revert_parser)
92
+
93
+ stats_parser = actions.add_parser(
94
+ "stats",
95
+ help="Summarize ledger-only Improvement counts.",
96
+ )
97
+ _add_workspace(stats_parser)
98
+ _add_json(stats_parser)
99
+
100
+ validate_parser = actions.add_parser(
101
+ "validate",
102
+ help="Validate the Improvement Ledger without writing files.",
103
+ )
104
+ _add_workspace(validate_parser)
105
+ _add_json(validate_parser)
106
+
107
+ rebuild_parser = actions.add_parser(
108
+ "rebuild",
109
+ help="Rebuild deterministic improvement/memory.md without touching runtime state.",
110
+ )
111
+ _add_workspace(rebuild_parser)
112
+ _add_json(rebuild_parser)
113
+
114
+
115
+ def handle(args: argparse.Namespace) -> int:
116
+ try:
117
+ if args.improve_action == "propose":
118
+ state = propose_improvement(
119
+ workspace=args.workspace,
120
+ guidance=args.guidance,
121
+ category=args.category,
122
+ scope=args.scope,
123
+ source_summary=getattr(args, "source_summary", None),
124
+ from_issue=getattr(args, "from_issue", None),
125
+ supersedes=getattr(args, "supersedes", None),
126
+ )
127
+ _print_state("improve propose", state, as_json=getattr(args, "json", False))
128
+ return 0
129
+
130
+ if args.improve_action == "list":
131
+ state = list_improvements(
132
+ workspace=args.workspace,
133
+ status=getattr(args, "status", None),
134
+ )
135
+ _print_state("improve list", state, as_json=getattr(args, "json", False))
136
+ return 0
137
+
138
+ if args.improve_action == "show":
139
+ state = show_improvement(workspace=args.workspace, entry_id=args.entry_id)
140
+ _print_state("improve show", state, as_json=getattr(args, "json", False))
141
+ return 0
142
+
143
+ if args.improve_action == "approve":
144
+ state = approve_improvement(
145
+ workspace=args.workspace,
146
+ entry_id=args.entry_id,
147
+ approved_by=args.by,
148
+ )
149
+ _print_state("improve approve", state, as_json=getattr(args, "json", False))
150
+ return 0
151
+
152
+ if args.improve_action == "reject":
153
+ state = reject_improvement(
154
+ workspace=args.workspace,
155
+ entry_id=args.entry_id,
156
+ rejected_by=args.by,
157
+ reason=args.reason,
158
+ )
159
+ _print_state("improve reject", state, as_json=getattr(args, "json", False))
160
+ return 0
161
+
162
+ if args.improve_action == "revert":
163
+ state = revert_improvement(
164
+ workspace=args.workspace,
165
+ entry_id=args.entry_id,
166
+ reverted_by=args.by,
167
+ reason=args.reason,
168
+ )
169
+ _print_state("improve revert", state, as_json=getattr(args, "json", False))
170
+ return 0
171
+
172
+ if args.improve_action == "stats":
173
+ state = improvement_stats(workspace=args.workspace)
174
+ _print_state("improve stats", state, as_json=getattr(args, "json", False))
175
+ return 0
176
+
177
+ if args.improve_action == "validate":
178
+ state = validate_improvement_ledger(workspace=args.workspace)
179
+ _print_state("improve validate", state, as_json=getattr(args, "json", False))
180
+ return 0 if state.get("ok") else 1
181
+
182
+ if args.improve_action == "rebuild":
183
+ state = rebuild_improvement_memory(workspace=args.workspace)
184
+ _print_state("improve rebuild", state, as_json=getattr(args, "json", False))
185
+ return 0
186
+ except ImprovementLedgerError as exc:
187
+ _print_error(exc, as_json=getattr(args, "json", False))
188
+ return 1
189
+ return 1
190
+
191
+
192
+ def _add_workspace(parser: argparse.ArgumentParser) -> None:
193
+ parser.add_argument("--workspace", required=True, help="Path to workspace directory.")
194
+
195
+
196
+ def _add_json(parser: argparse.ArgumentParser) -> None:
197
+ parser.add_argument("--json", action="store_true", help="Emit machine-readable JSON.")
198
+
199
+
200
+ def _print_state(label: str, state: dict[str, Any], *, as_json: bool) -> None:
201
+ if as_json:
202
+ print(json.dumps(state, ensure_ascii=False, indent=2, sort_keys=True))
203
+ return
204
+ print(f"[{label}] ok: {state.get('ok')}")
205
+ print(f"[{label}] ledger: {state.get('ledger_path')}")
206
+ if "entry_id" in state:
207
+ print(f"[{label}] entry: {state.get('entry_id')}")
208
+ elif isinstance(state.get("entry"), dict):
209
+ print(f"[{label}] entry: {state['entry'].get('entry_id')}")
210
+ print(f"[{label}] entries: {state.get('entry_count', 0)}")
211
+ for diagnostic in state.get("diagnostics") or []:
212
+ print(f" - {diagnostic.get('severity')}: {diagnostic.get('message')}")
213
+ for warning in state.get("warnings") or []:
214
+ print(f" - warning: {warning.get('message')}")
215
+ if state.get("event_recorded") is False:
216
+ print(f"[{label}] event: {state.get('event_reason')}")
217
+
218
+
219
+ def _print_error(exc: Exception, *, as_json: bool) -> None:
220
+ payload = exc.to_dict() if hasattr(exc, "to_dict") else {"ok": False, "error": str(exc)}
221
+ if as_json:
222
+ print(json.dumps(payload, ensure_ascii=False, indent=2, sort_keys=True))
223
+ else:
224
+ print(f"[improve] {exc}")