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,518 @@
1
+ """Market & Competitor Intelligence — core data contracts.
2
+
3
+ All dataclasses in this module are the canonical schema for the
4
+ Market & Competitor Analysis Module. They are used by the Python
5
+ deterministic layer (event builder, renderer, auditor) and by
6
+ LLM subagents (planner, analyst, auditor).
7
+
8
+ Design constraints
9
+ ------------------
10
+ - MarketEvent.supporting_claim_ids MUST be non-empty (every event
11
+ must be traceable to at least one Claim Ledger entry).
12
+ - AnalysisCard.supporting_claim_ids MUST have ≥1 claim (no orphan
13
+ analysis judgments).
14
+ - AnalysisCard MUST NOT expose a free-text ``statement`` or ``text``
15
+ field — analytical narrative belongs in the final brief, not here.
16
+ Use ``headline`` + ``observation`` + ``implication_for_target`` instead.
17
+ """
18
+
19
+ from __future__ import annotations
20
+
21
+ from dataclasses import dataclass, field
22
+ from typing import Any, Literal, get_args
23
+
24
+
25
+ # ── Enums -------------------------------------------------------------------
26
+
27
+ EventType = Literal[
28
+ "capacity_expansion",
29
+ "capacity_delay",
30
+ "plant_opening",
31
+ "plant_closure",
32
+ "product_launch",
33
+ "technology_change",
34
+ "price_change",
35
+ "customer_win",
36
+ "partnership",
37
+ "supply_agreement",
38
+ "fundraising",
39
+ "acquisition",
40
+ "asset_sale",
41
+ "earnings_change",
42
+ "guidance_change",
43
+ "policy_exposure",
44
+ "trade_action",
45
+ "litigation",
46
+ "patent_action",
47
+ "management_change",
48
+ "other",
49
+ ]
50
+ EVENT_TYPES: tuple[str, ...] = tuple(get_args(EventType))
51
+
52
+ EventStatus = Literal[
53
+ "rumored",
54
+ "announced",
55
+ "planned",
56
+ "under_construction",
57
+ "commissioning",
58
+ "operational",
59
+ "cancelled",
60
+ "delayed",
61
+ "",
62
+ ]
63
+
64
+ Dimension = Literal[
65
+ "capacity",
66
+ "technology",
67
+ "customers_partnerships",
68
+ "financials",
69
+ "policy_compliance",
70
+ "market_demand",
71
+ "price",
72
+ "supply_chain",
73
+ "management",
74
+ "other",
75
+ ]
76
+
77
+ EntityRelation = Literal[
78
+ "direct_competitor",
79
+ "adjacent_competitor",
80
+ "technology_substitute",
81
+ "benchmark_company",
82
+ "customer",
83
+ "supplier",
84
+ "regulator",
85
+ "market_actor",
86
+ ]
87
+
88
+ ChangeStatus = Literal[
89
+ "new",
90
+ "changed",
91
+ "unchanged",
92
+ "resolved",
93
+ "cancelled",
94
+ ]
95
+
96
+ FindingType = Literal[
97
+ "relative_position_change",
98
+ "opportunity",
99
+ "risk",
100
+ "evidence_gap",
101
+ "follow_up",
102
+ "market_shift",
103
+ "other",
104
+ ]
105
+ FINDING_TYPES: tuple[str, ...] = tuple(get_args(FindingType))
106
+
107
+ TimeHorizon = Literal[
108
+ "immediate",
109
+ "3-6_months",
110
+ "6-12_months",
111
+ "12-24_months",
112
+ "long_term",
113
+ ]
114
+
115
+ ModuleMode = Literal[
116
+ "weekly_monitor",
117
+ "competitor_deep_dive",
118
+ "market_landscape",
119
+ ]
120
+
121
+ Confidence = Literal["low", "medium", "high"]
122
+ Materiality = Literal["low", "medium", "high"]
123
+ Priority = Literal["primary", "secondary", "tertiary"]
124
+
125
+
126
+ # ── Entity / Universe -------------------------------------------------------
127
+
128
+
129
+ @dataclass
130
+ class CompetitorEntity:
131
+ """A single tracked entity (competitor, benchmark, regulator, etc.)."""
132
+
133
+ entity_id: str
134
+ name: str
135
+ aliases: list[str] = field(default_factory=list)
136
+ relation: EntityRelation = "direct_competitor"
137
+ priority: Priority = "primary"
138
+ geographies: list[str] = field(default_factory=list)
139
+ technologies: list[str] = field(default_factory=list)
140
+
141
+
142
+ @dataclass
143
+ class CompetitorUniverse:
144
+ """Full competitive landscape for a workspace — loaded from
145
+ ``competitor_universe.yaml``."""
146
+
147
+ target: CompetitorEntity
148
+ market_scope: dict[str, list[str]] = field(default_factory=dict)
149
+ entities: list[CompetitorEntity] = field(default_factory=list)
150
+ mode: ModuleMode = "weekly_monitor"
151
+ enabled: bool = False
152
+
153
+ @property
154
+ def primary_competitors(self) -> list[CompetitorEntity]:
155
+ return [e for e in self.entities if e.priority == "primary"]
156
+
157
+ @property
158
+ def all_competitors(self) -> list[CompetitorEntity]:
159
+ return [e for e in self.entities if e.relation in (
160
+ "direct_competitor", "adjacent_competitor", "technology_substitute",
161
+ )]
162
+
163
+ def get_entity(self, entity_id: str) -> CompetitorEntity | None:
164
+ if self.target.entity_id == entity_id:
165
+ return self.target
166
+ for ent in self.entities:
167
+ if ent.entity_id == entity_id:
168
+ return ent
169
+ return None
170
+
171
+ def match_name(self, name: str) -> str | None:
172
+ """Return entity_id if ``name`` matches any entity name/alias (case-insensitive).
173
+
174
+ Returns None if no match.
175
+ """
176
+ normalized = name.strip().lower()
177
+ candidates = [self.target] + self.entities
178
+ for ent in candidates:
179
+ if ent.name.strip().lower() == normalized:
180
+ return ent.entity_id
181
+ for alias in ent.aliases:
182
+ if alias.strip().lower() == normalized:
183
+ return ent.entity_id
184
+ return None
185
+
186
+ def to_dict(self) -> dict[str, Any]:
187
+ return {
188
+ "target": {
189
+ "entity_id": self.target.entity_id,
190
+ "name": self.target.name,
191
+ "aliases": self.target.aliases,
192
+ "relation": self.target.relation,
193
+ "priority": self.target.priority,
194
+ "geographies": self.target.geographies,
195
+ "technologies": self.target.technologies,
196
+ },
197
+ "market_scope": self.market_scope,
198
+ "entities": [
199
+ {
200
+ "entity_id": ent.entity_id,
201
+ "name": ent.name,
202
+ "aliases": ent.aliases,
203
+ "relation": ent.relation,
204
+ "priority": ent.priority,
205
+ "geographies": ent.geographies,
206
+ "technologies": ent.technologies,
207
+ }
208
+ for ent in self.entities
209
+ ],
210
+ "mode": self.mode,
211
+ "enabled": self.enabled,
212
+ }
213
+
214
+
215
+ # ── MarketEvent -------------------------------------------------------------
216
+
217
+
218
+ @dataclass
219
+ class MarketEvent:
220
+ """A structured, source-grounded competitive intelligence event.
221
+
222
+ Events are built deterministically from Claim Ledger entries that carry
223
+ entity tags. Every event MUST reference at least one Claim ID.
224
+ """
225
+
226
+ event_id: str
227
+ entity_ids: list[str]
228
+ event_type: EventType
229
+ dimension: Dimension = "other"
230
+ status: EventStatus = ""
231
+ geography: str = ""
232
+ event_date: str = ""
233
+ summary: str = ""
234
+ supporting_claim_ids: list[str] = field(default_factory=list)
235
+ source_count: int = 0
236
+ confidence: Confidence = "medium"
237
+ materiality: Materiality = "medium"
238
+ change_status: ChangeStatus = "new"
239
+
240
+ def __post_init__(self) -> None:
241
+ if not self.supporting_claim_ids:
242
+ raise ValueError(
243
+ f"MarketEvent '{self.event_id}' must have at least one "
244
+ f"supporting_claim_ids entry."
245
+ )
246
+ if self.source_count < 1:
247
+ self.source_count = len(self.supporting_claim_ids)
248
+
249
+ def to_dict(self) -> dict[str, Any]:
250
+ return {
251
+ "event_id": self.event_id,
252
+ "entity_ids": self.entity_ids,
253
+ "event_type": self.event_type,
254
+ "dimension": self.dimension,
255
+ "status": self.status,
256
+ "geography": self.geography,
257
+ "event_date": self.event_date,
258
+ "summary": self.summary,
259
+ "supporting_claim_ids": self.supporting_claim_ids,
260
+ "source_count": self.source_count,
261
+ "confidence": self.confidence,
262
+ "materiality": self.materiality,
263
+ "change_status": self.change_status,
264
+ }
265
+
266
+
267
+ # ── AnalysisCard ------------------------------------------------------------
268
+
269
+
270
+ @dataclass
271
+ class AnalysisCard:
272
+ """A structured analytical judgment backed by one or more Claim Ledger entries.
273
+
274
+ IMPORTANT: AnalysisCards MUST NOT contain free-form narrative text that
275
+ could be mistaken for source facts. Use ``headline``, ``observation``,
276
+ and ``implication_for_target`` to express analytical judgments clearly
277
+ separated from source evidence. The final management-facing prose belongs
278
+ in the brief, not here.
279
+
280
+ Every AnalysisCard MUST reference at least one Claim ID via
281
+ ``supporting_claim_ids``. Single-source interpretations MUST set
282
+ ``confidence = "low"``.
283
+ """
284
+
285
+ analysis_id: str
286
+ finding_type: FindingType
287
+ headline: str
288
+ observation: str
289
+ implication_for_target: str = ""
290
+ time_horizon: TimeHorizon = "immediate"
291
+ confidence: Confidence = "medium"
292
+ supporting_claim_ids: list[str] = field(default_factory=list)
293
+ counterevidence_claim_ids: list[str] = field(default_factory=list)
294
+ evidence_gaps: list[str] = field(default_factory=list)
295
+ follow_up_questions: list[str] = field(default_factory=list)
296
+
297
+ def __post_init__(self) -> None:
298
+ if not self.supporting_claim_ids:
299
+ raise ValueError(
300
+ f"AnalysisCard '{self.analysis_id}' must have at least one "
301
+ f"supporting_claim_ids entry."
302
+ )
303
+ if len(self.supporting_claim_ids) == 1 and self.confidence not in ("low",):
304
+ raise ValueError(
305
+ f"AnalysisCard '{self.analysis_id}' has only one supporting claim "
306
+ f"but confidence is '{self.confidence}' — single-source "
307
+ f"interpretations must set confidence='low'."
308
+ )
309
+
310
+ def to_dict(self) -> dict[str, Any]:
311
+ return {
312
+ "analysis_id": self.analysis_id,
313
+ "finding_type": self.finding_type,
314
+ "headline": self.headline,
315
+ "observation": self.observation,
316
+ "implication_for_target": self.implication_for_target,
317
+ "time_horizon": self.time_horizon,
318
+ "confidence": self.confidence,
319
+ "supporting_claim_ids": self.supporting_claim_ids,
320
+ "counterevidence_claim_ids": self.counterevidence_claim_ids,
321
+ "evidence_gaps": self.evidence_gaps,
322
+ "follow_up_questions": self.follow_up_questions,
323
+ }
324
+
325
+
326
+ # ── CompetitorMatrix --------------------------------------------------------
327
+
328
+
329
+ @dataclass
330
+ class CompetitorMatrixCell:
331
+ """One cell in the competitor matrix — entity × dimension."""
332
+
333
+ entity_id: str
334
+ dimension: Dimension
335
+ summary: str = ""
336
+ evidence_claim_ids: list[str] = field(default_factory=list)
337
+ status: str = ""
338
+
339
+
340
+ @dataclass
341
+ class CompetitorMatrix:
342
+ """Entity × dimension comparison table.
343
+
344
+ Dimensions are rows, entities are columns (or vice versa depending on
345
+ the rendering context).
346
+ """
347
+
348
+ entities: list[str] = field(default_factory=list)
349
+ dimensions: list[Dimension] = field(default_factory=list)
350
+ cells: list[CompetitorMatrixCell] = field(default_factory=list)
351
+ report_date: str = ""
352
+
353
+ def to_dict(self) -> dict[str, Any]:
354
+ return {
355
+ "entities": self.entities,
356
+ "dimensions": self.dimensions,
357
+ "cells": [
358
+ {
359
+ "entity_id": cell.entity_id,
360
+ "dimension": cell.dimension,
361
+ "summary": cell.summary,
362
+ "evidence_claim_ids": cell.evidence_claim_ids,
363
+ "status": cell.status,
364
+ }
365
+ for cell in self.cells
366
+ ],
367
+ "report_date": self.report_date,
368
+ }
369
+
370
+
371
+ # ── CoverageReport ----------------------------------------------------------
372
+
373
+
374
+ @dataclass
375
+ class CoverageReport:
376
+ """Entity and dimension coverage gaps for the current reporting period."""
377
+
378
+ primary_competitors_total: int = 0
379
+ primary_competitors_with_recent_evidence: int = 0
380
+ missing_entities: list[str] = field(default_factory=list)
381
+ undercovered_dimensions: list[str] = field(default_factory=list)
382
+ absence_of_evidence_entities: list[str] = field(default_factory=list)
383
+ generated_at: str = ""
384
+
385
+ def to_dict(self) -> dict[str, Any]:
386
+ return {
387
+ "primary_competitors_total": self.primary_competitors_total,
388
+ "primary_competitors_with_recent_evidence": (
389
+ self.primary_competitors_with_recent_evidence
390
+ ),
391
+ "missing_entities": self.missing_entities,
392
+ "undercovered_dimensions": self.undercovered_dimensions,
393
+ "absence_of_evidence_entities": self.absence_of_evidence_entities,
394
+ "generated_at": self.generated_at,
395
+ }
396
+
397
+
398
+ # ── Watchlist ---------------------------------------------------------------
399
+
400
+
401
+ @dataclass
402
+ class WatchlistItem:
403
+ """A single cross-period tracking item."""
404
+
405
+ item_id: str
406
+ description: str
407
+ entity_id: str = ""
408
+ status: Literal["open", "resolved", "carry_forward"] = "open"
409
+ last_updated: str = ""
410
+ related_claim_ids: list[str] = field(default_factory=list)
411
+
412
+
413
+ @dataclass
414
+ class Watchlist:
415
+ """Cross-period tracking list — items that need verification in future cycles."""
416
+
417
+ items: list[WatchlistItem] = field(default_factory=list)
418
+ generated_at: str = ""
419
+
420
+ def to_dict(self) -> dict[str, Any]:
421
+ return {
422
+ "items": [
423
+ {
424
+ "item_id": item.item_id,
425
+ "description": item.description,
426
+ "entity_id": item.entity_id,
427
+ "status": item.status,
428
+ "last_updated": item.last_updated,
429
+ "related_claim_ids": item.related_claim_ids,
430
+ }
431
+ for item in self.items
432
+ ],
433
+ "generated_at": self.generated_at,
434
+ }
435
+
436
+
437
+ # ── ModuleConfig ------------------------------------------------------------
438
+
439
+ _DEFAULT_DIMENSIONS: list[Dimension] = [
440
+ "market_demand", "price", "capacity", "technology",
441
+ "customers_partnerships", "financials", "policy_compliance",
442
+ ]
443
+
444
+ _DEFAULT_EVENT_TYPES: list[EventType] = [
445
+ "capacity_expansion", "product_launch", "customer_win",
446
+ "partnership", "acquisition", "earnings_change",
447
+ "trade_action", "litigation",
448
+ ]
449
+
450
+
451
+ @dataclass
452
+ class ModuleConfig:
453
+ """Configuration for the Market & Competitor Intelligence module.
454
+
455
+ Deserialized from config.yaml's ``modules.market_competitor`` section
456
+ (if present) and from ``competitor_universe.yaml``.
457
+ """
458
+
459
+ enabled: bool = False
460
+ mode: ModuleMode = "weekly_monitor"
461
+ universe_path: str = "competitor_universe.yaml"
462
+
463
+ dimensions: list[Dimension] = field(
464
+ default_factory=lambda: list(_DEFAULT_DIMENSIONS)
465
+ )
466
+
467
+ event_types: list[EventType] = field(
468
+ default_factory=lambda: list(_DEFAULT_EVENT_TYPES)
469
+ )
470
+
471
+ max_events: int = 20
472
+ max_events_per_entity: int = 4
473
+ require_primary_competitor_coverage: bool = True
474
+ prefer_changes_since_previous_report: bool = True
475
+ require_implication_for_target: bool = True
476
+ require_evidence_gaps: bool = True
477
+ require_counterevidence_check: bool = True
478
+ interpretations_min_supporting_claims: int = 2
479
+ comparisons_require_evidence_for_each_entity: bool = True
480
+ require_capacity_status: bool = True
481
+ require_metric_period_and_unit: bool = True
482
+
483
+ @classmethod
484
+ def from_dict(cls, data: dict[str, Any] | None) -> "ModuleConfig":
485
+ if data is None:
486
+ return cls()
487
+ return cls(
488
+ enabled=bool(data.get("enabled", False)),
489
+ mode=data.get("mode", "weekly_monitor"),
490
+ universe_path=data.get("universe_path", "competitor_universe.yaml"),
491
+ dimensions=data.get("dimensions", _DEFAULT_DIMENSIONS),
492
+ event_types=data.get("event_types", _DEFAULT_EVENT_TYPES),
493
+ max_events=int(data.get("max_events", 20)),
494
+ max_events_per_entity=int(data.get("max_events_per_entity", 4)),
495
+ require_primary_competitor_coverage=bool(
496
+ data.get("require_primary_competitor_coverage", True)
497
+ ),
498
+ prefer_changes_since_previous_report=bool(
499
+ data.get("prefer_changes_since_previous_report", True)
500
+ ),
501
+ require_implication_for_target=bool(
502
+ data.get("require_implication_for_target", True)
503
+ ),
504
+ require_evidence_gaps=bool(data.get("require_evidence_gaps", True)),
505
+ require_counterevidence_check=bool(
506
+ data.get("require_counterevidence_check", True)
507
+ ),
508
+ interpretations_min_supporting_claims=int(
509
+ data.get("interpretations_min_supporting_claims", 2)
510
+ ),
511
+ comparisons_require_evidence_for_each_entity=bool(
512
+ data.get("comparisons_require_evidence_for_each_entity", True)
513
+ ),
514
+ require_capacity_status=bool(data.get("require_capacity_status", True)),
515
+ require_metric_period_and_unit=bool(
516
+ data.get("require_metric_period_and_unit", True)
517
+ ),
518
+ )
@@ -0,0 +1,7 @@
1
+ """Policy & Regulatory Risk Analysis Module."""
2
+
3
+ from multi_agent_brief.analysis_modules.policy_regulatory.module import (
4
+ PolicyRegulatoryModule,
5
+ )
6
+
7
+ __all__ = ["PolicyRegulatoryModule"]