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,429 @@
1
+ """Evaluation-case contracts and public-safe fixture scanning."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import json
6
+ import re
7
+ from pathlib import Path, PurePosixPath, PureWindowsPath
8
+ from typing import Any
9
+ from urllib.parse import urlparse
10
+
11
+ import yaml
12
+
13
+
14
+ EVALUATION_CASES_SCHEMA = "multi-agent-brief-evaluation-cases/v1"
15
+
16
+ WORKSPACE_CASE = "workspace"
17
+ STATIC_CONTRACT_CASE = "static_contract"
18
+ CASE_TYPES = {WORKSPACE_CASE, STATIC_CONTRACT_CASE}
19
+
20
+ ALLOWED_ACTIONS = {
21
+ "controls.build_switchboard",
22
+ "controls.select",
23
+ "controls.show",
24
+ "controls.validate",
25
+ "feedback.ingest",
26
+ "feedback.plan",
27
+ "feedback.validate",
28
+ "finalize",
29
+ "gates.check",
30
+ "gates.show",
31
+ "gates.validate",
32
+ "guidance_manifestation.seed_report",
33
+ "packs.bundle",
34
+ "provenance.build",
35
+ "provenance.show",
36
+ "provenance.validate",
37
+ "quality.summarize",
38
+ "runtime.run_handoff",
39
+ "release.check",
40
+ "status.show",
41
+ "state.check",
42
+ "state.decide",
43
+ "state.finalize_complete",
44
+ "state.stage_complete",
45
+ "static.hermes_no_skip_finalize",
46
+ "synthetic.seed_claim_support_case",
47
+ }
48
+
49
+ ALLOWED_EXPECTED_KEYS = {
50
+ "artifacts_absent",
51
+ "artifacts_exist",
52
+ "artifact_statuses",
53
+ "contains_text",
54
+ "absent_text",
55
+ "exit_code",
56
+ "expected_actions",
57
+ "findings_absent",
58
+ "findings_any",
59
+ "graph_absent_text",
60
+ "graph_edges_any",
61
+ "graph_nodes_any",
62
+ "issues_any",
63
+ "manifest_improvement",
64
+ "workflow_state",
65
+ }
66
+
67
+ URL_RE = re.compile(r"\bhttps?://[^\s\]\)\"']+", re.IGNORECASE)
68
+ EMAIL_RE = re.compile(r"\b[A-Z0-9._%+-]+@([A-Z0-9.-]+\.[A-Z]{2,})\b", re.IGNORECASE)
69
+ WINDOWS_USER_PATH_RE = re.compile(r"[A-Za-z]:\\Users\\")
70
+ SECRET_RE = re.compile(
71
+ r"(-----BEGIN (?:OPENSSH|RSA|DSA|EC|PRIVATE) KEY-----|"
72
+ r"\bsk-[A-Za-z0-9]{20,}|\bghp_[A-Za-z0-9]{20,}|\bxox[baprs]-[A-Za-z0-9-]{20,}|\bAKIA[A-Z0-9]{16})"
73
+ )
74
+ PROMPT_LABEL_RE = re.compile(
75
+ r"\b(system prompt|developer prompt|private feedback|raw prompt)\b",
76
+ re.IGNORECASE,
77
+ )
78
+
79
+
80
+ class EvaluationCaseContractError(Exception):
81
+ """Raised when evaluation cases violate the public-safe contract."""
82
+
83
+ def __init__(self, message: str, *, details: dict[str, Any] | None = None) -> None:
84
+ super().__init__(message)
85
+ self.details = details or {}
86
+
87
+ def to_dict(self) -> dict[str, Any]:
88
+ return {
89
+ "ok": False,
90
+ "error": str(self),
91
+ "details": self.details,
92
+ }
93
+
94
+
95
+ def load_manifest(root: str | Path) -> dict[str, Any]:
96
+ path = Path(root).expanduser().resolve() / "manifest.yaml"
97
+ try:
98
+ data = yaml.safe_load(path.read_text(encoding="utf-8")) or {}
99
+ except yaml.YAMLError as exc:
100
+ raise EvaluationCaseContractError(
101
+ f"Invalid evaluation case manifest: {path}",
102
+ details={"path": str(path), "reason": str(exc)},
103
+ ) from exc
104
+ except OSError as exc:
105
+ raise EvaluationCaseContractError(
106
+ f"Failed to read evaluation case manifest: {path}",
107
+ details={"path": str(path), "reason": str(exc)},
108
+ ) from exc
109
+ if not isinstance(data, dict):
110
+ raise EvaluationCaseContractError(
111
+ f"Evaluation case manifest must contain a mapping: {path}",
112
+ details={"path": str(path)},
113
+ )
114
+ return data
115
+
116
+
117
+ def case_definitions(root: str | Path) -> list[dict[str, Any]]:
118
+ manifest = load_manifest(root)
119
+ cases = manifest.get("cases") or []
120
+ return [case for case in cases if isinstance(case, dict)]
121
+
122
+
123
+ def _path_is_absolute_any_platform(value: str) -> bool:
124
+ return (
125
+ Path(value).is_absolute()
126
+ or PurePosixPath(value).is_absolute()
127
+ or PureWindowsPath(value).is_absolute()
128
+ )
129
+
130
+
131
+ def _path_has_traversal_any_platform(value: str) -> bool:
132
+ return (
133
+ ".." in Path(value).parts
134
+ or ".." in PurePosixPath(value).parts
135
+ or ".." in PureWindowsPath(value).parts
136
+ )
137
+
138
+
139
+ def validate_case_contract(root: str | Path) -> dict[str, Any]:
140
+ resolved = Path(root).expanduser().resolve()
141
+ errors: list[str] = []
142
+ try:
143
+ manifest = load_manifest(resolved)
144
+ except EvaluationCaseContractError as exc:
145
+ return {"ok": False, "errors": [str(exc)], "case_count": 0}
146
+
147
+ if manifest.get("schema_version") != EVALUATION_CASES_SCHEMA:
148
+ errors.append("manifest.yaml has an unsupported schema_version.")
149
+ if manifest.get("synthetic") is not True:
150
+ errors.append("manifest.yaml must declare synthetic: true.")
151
+
152
+ cases = manifest.get("cases")
153
+ if not isinstance(cases, list):
154
+ errors.append("manifest.yaml cases must be a list.")
155
+ cases = []
156
+
157
+ seen: set[str] = set()
158
+ for idx, case in enumerate(cases):
159
+ prefix = f"cases[{idx}]"
160
+ if not isinstance(case, dict):
161
+ errors.append(f"{prefix} must be an object.")
162
+ continue
163
+ case_id = str(case.get("case_id") or "")
164
+ case_type = str(case.get("case_type") or WORKSPACE_CASE)
165
+ if not case_id:
166
+ errors.append(f"{prefix}.case_id is required.")
167
+ elif case_id in seen:
168
+ errors.append(f"{prefix}.case_id is duplicated: {case_id}.")
169
+ seen.add(case_id)
170
+ if case_type not in CASE_TYPES:
171
+ errors.append(f"{prefix}.case_type must be one of {sorted(CASE_TYPES)}.")
172
+ if case.get("synthetic") is not True:
173
+ errors.append(f"{prefix}.synthetic must be true.")
174
+ if case_type == WORKSPACE_CASE:
175
+ if not str(case.get("initial_stage") or ""):
176
+ errors.append(f"{prefix}.initial_stage is required for workspace cases.")
177
+ workspace = resolved / "cases" / case_id / "workspace"
178
+ if case_id and not workspace.exists():
179
+ errors.append(f"{prefix} workspace fixture is missing: {workspace}.")
180
+ else:
181
+ expected = case.get("expected")
182
+ if isinstance(expected, dict) and expected.get("artifact_statuses") is not None:
183
+ errors.append(
184
+ f"{prefix}.expected.artifact_statuses requires a workspace case."
185
+ )
186
+
187
+ commands = case.get("commands") or []
188
+ if not isinstance(commands, list):
189
+ errors.append(f"{prefix}.commands must be a list.")
190
+ commands = []
191
+ for command_idx, command in enumerate(commands):
192
+ command_prefix = f"{prefix}.commands[{command_idx}]"
193
+ if isinstance(command, str):
194
+ errors.append(f"{command_prefix} must be a structured action, not a shell string.")
195
+ continue
196
+ if not isinstance(command, dict):
197
+ errors.append(f"{command_prefix} must be an object.")
198
+ continue
199
+ action = str(command.get("action") or "")
200
+ if action not in ALLOWED_ACTIONS:
201
+ errors.append(f"{command_prefix}.action is not allowlisted: {action}.")
202
+ continue_on_failure = command.get("continue_on_failure")
203
+ if continue_on_failure is not None and not isinstance(continue_on_failure, bool):
204
+ errors.append(f"{command_prefix}.continue_on_failure must be a boolean.")
205
+ args = command.get("args") or {}
206
+ if not isinstance(args, dict):
207
+ errors.append(f"{command_prefix}.args must be an object.")
208
+ args = {}
209
+ errors.extend(_validate_command_args(prefix=command_prefix, action=action, args=args))
210
+
211
+ expected = case.get("expected") or {}
212
+ if not isinstance(expected, dict):
213
+ errors.append(f"{prefix}.expected must be an object.")
214
+ else:
215
+ unknown = sorted(set(expected) - ALLOWED_EXPECTED_KEYS)
216
+ if unknown:
217
+ errors.append(f"{prefix}.expected has unsupported keys: {unknown}.")
218
+ errors.extend(_validate_expected_contract(prefix=prefix, expected=expected))
219
+
220
+ errors.extend(scan_public_safe_fixtures(resolved, manifest=manifest))
221
+ return {
222
+ "ok": not errors,
223
+ "errors": errors,
224
+ "case_count": len([case for case in cases if isinstance(case, dict)]),
225
+ "cases": [str(case.get("case_id")) for case in cases if isinstance(case, dict) and case.get("case_id")],
226
+ }
227
+
228
+
229
+ def scan_public_safe_fixtures(root: Path, *, manifest: dict[str, Any]) -> list[str]:
230
+ errors: list[str] = []
231
+ allowed_hosts = {"example.com"}
232
+ for host in manifest.get("public_url_allowlist") or []:
233
+ if isinstance(host, str) and host.strip():
234
+ allowed_hosts.add(host.strip().lower())
235
+
236
+ for path in sorted(root.rglob("*")):
237
+ if not path.is_file():
238
+ continue
239
+ try:
240
+ text = path.read_text(encoding="utf-8")
241
+ except UnicodeDecodeError:
242
+ errors.append(f"{path.relative_to(root)} is not UTF-8 text.")
243
+ continue
244
+ except OSError as exc:
245
+ errors.append(f"Failed to read {path.relative_to(root)}: {exc}.")
246
+ continue
247
+ rel = path.relative_to(root).as_posix()
248
+ errors.extend(_scan_text(rel=rel, text=text, allowed_hosts=allowed_hosts))
249
+ if path.name == "claim_ledger.json":
250
+ errors.extend(_scan_claim_ledger_ids(rel=rel, text=text))
251
+ return errors
252
+
253
+
254
+ def _scan_text(*, rel: str, text: str, allowed_hosts: set[str]) -> list[str]:
255
+ errors: list[str] = []
256
+ if "file://" in text.lower():
257
+ errors.append(f"{rel} contains a file:// reference.")
258
+ for marker in ("/Users/", "/home/", "/private/", "/var/folders/"):
259
+ if marker in text:
260
+ errors.append(f"{rel} contains local path marker {marker}.")
261
+ if WINDOWS_USER_PATH_RE.search(text):
262
+ errors.append(f"{rel} contains a Windows user path.")
263
+ if SECRET_RE.search(text):
264
+ errors.append(f"{rel} contains a token or private-key shaped value.")
265
+ if PROMPT_LABEL_RE.search(text):
266
+ errors.append(f"{rel} contains raw prompt/private prompt labels.")
267
+
268
+ for match in URL_RE.finditer(text):
269
+ host = (urlparse(match.group(0)).hostname or "").lower()
270
+ if not _url_host_allowed(host, allowed_hosts):
271
+ errors.append(f"{rel} contains non-public-safe URL host: {host}.")
272
+ for match in EMAIL_RE.finditer(text):
273
+ host = match.group(1).lower()
274
+ if not _url_host_allowed(host, allowed_hosts):
275
+ errors.append(f"{rel} contains non-public-safe email domain: {host}.")
276
+ return errors
277
+
278
+
279
+ def _url_host_allowed(host: str, allowed_hosts: set[str]) -> bool:
280
+ if not host:
281
+ return False
282
+ if host in allowed_hosts:
283
+ return True
284
+ if host.endswith(".example.com"):
285
+ return True
286
+ if host.endswith(".invalid"):
287
+ return True
288
+ return False
289
+
290
+
291
+ def _validate_expected_contract(*, prefix: str, expected: dict[str, Any]) -> list[str]:
292
+ errors: list[str] = []
293
+ expected_actions = expected.get("expected_actions")
294
+ if expected_actions is not None:
295
+ if not isinstance(expected_actions, list):
296
+ errors.append(f"{prefix}.expected.expected_actions must be a list.")
297
+ else:
298
+ for idx, item in enumerate(expected_actions):
299
+ item_prefix = f"{prefix}.expected.expected_actions[{idx}]"
300
+ if not isinstance(item, dict):
301
+ errors.append(f"{item_prefix} must be an object.")
302
+ continue
303
+ action = str(item.get("action") or "")
304
+ if action not in ALLOWED_ACTIONS:
305
+ errors.append(f"{item_prefix}.action is not allowlisted: {action}.")
306
+ exit_code = item.get("exit_code")
307
+ if not isinstance(exit_code, int):
308
+ errors.append(f"{item_prefix}.exit_code must be an integer.")
309
+ error_contains = item.get("error_contains")
310
+ if error_contains is not None and not (
311
+ isinstance(error_contains, str)
312
+ or (
313
+ isinstance(error_contains, list)
314
+ and all(isinstance(value, str) for value in error_contains)
315
+ )
316
+ ):
317
+ errors.append(
318
+ f"{item_prefix}.error_contains must be a string or list of strings."
319
+ )
320
+ result_contains = item.get("result_contains")
321
+ if result_contains is not None and not isinstance(result_contains, dict):
322
+ errors.append(f"{item_prefix}.result_contains must be an object.")
323
+
324
+ contains_text = expected.get("contains_text")
325
+ if contains_text is not None:
326
+ if not isinstance(contains_text, list):
327
+ errors.append(f"{prefix}.expected.contains_text must be a list.")
328
+ else:
329
+ for idx, item in enumerate(contains_text):
330
+ item_prefix = f"{prefix}.expected.contains_text[{idx}]"
331
+ if not isinstance(item, dict):
332
+ errors.append(f"{item_prefix} must be an object.")
333
+ continue
334
+ scope = item.get("scope", "cases")
335
+ if scope not in {"cases", "repo", "workspace"}:
336
+ errors.append(f"{item_prefix}.scope must be cases, repo, or workspace.")
337
+ rel_path = item.get("file")
338
+ if not isinstance(rel_path, str) or not rel_path.strip():
339
+ errors.append(f"{item_prefix}.file is required.")
340
+ continue
341
+ if _path_is_absolute_any_platform(rel_path):
342
+ errors.append(f"{item_prefix}.file must be relative, not absolute.")
343
+ if _path_has_traversal_any_platform(rel_path):
344
+ errors.append(f"{item_prefix}.file must not contain path traversal.")
345
+ absent_text = expected.get("absent_text")
346
+ if absent_text is not None:
347
+ if not isinstance(absent_text, list):
348
+ errors.append(f"{prefix}.expected.absent_text must be a list.")
349
+ else:
350
+ for idx, item in enumerate(absent_text):
351
+ item_prefix = f"{prefix}.expected.absent_text[{idx}]"
352
+ if not isinstance(item, dict):
353
+ errors.append(f"{item_prefix} must be an object.")
354
+ continue
355
+ scope = item.get("scope", "cases")
356
+ if scope not in {"cases", "repo", "workspace"}:
357
+ errors.append(f"{item_prefix}.scope must be cases, repo, or workspace.")
358
+ rel_path = item.get("file")
359
+ if not isinstance(rel_path, str) or not rel_path.strip():
360
+ errors.append(f"{item_prefix}.file is required.")
361
+ continue
362
+ if _path_is_absolute_any_platform(rel_path):
363
+ errors.append(f"{item_prefix}.file must be relative, not absolute.")
364
+ if _path_has_traversal_any_platform(rel_path):
365
+ errors.append(f"{item_prefix}.file must not contain path traversal.")
366
+ artifact_statuses = expected.get("artifact_statuses")
367
+ if artifact_statuses is not None:
368
+ if not isinstance(artifact_statuses, list):
369
+ errors.append(f"{prefix}.expected.artifact_statuses must be a list.")
370
+ else:
371
+ for idx, item in enumerate(artifact_statuses):
372
+ item_prefix = f"{prefix}.expected.artifact_statuses[{idx}]"
373
+ if not isinstance(item, dict):
374
+ errors.append(f"{item_prefix} must be an object.")
375
+ continue
376
+ artifact_id = item.get("artifact_id")
377
+ if not isinstance(artifact_id, str) or not artifact_id.strip():
378
+ errors.append(f"{item_prefix}.artifact_id is required.")
379
+ for field in ("status", "validation_result", "validation_result_contains"):
380
+ value = item.get(field)
381
+ if value is not None and not isinstance(value, str):
382
+ errors.append(f"{item_prefix}.{field} must be a string.")
383
+ return errors
384
+
385
+
386
+ def _validate_command_args(*, prefix: str, action: str, args: dict[str, Any]) -> list[str]:
387
+ errors: list[str] = []
388
+ if action == "feedback.ingest":
389
+ feedback = args.get("feedback")
390
+ if not isinstance(feedback, str) or not feedback.strip():
391
+ errors.append(f"{prefix}.args.feedback is required.")
392
+ elif _path_is_absolute_any_platform(feedback):
393
+ errors.append(f"{prefix}.args.feedback must be relative, not absolute.")
394
+ elif _path_has_traversal_any_platform(feedback):
395
+ errors.append(f"{prefix}.args.feedback must not contain path traversal.")
396
+ if action == "release.check":
397
+ mode = args.get("mode")
398
+ if not isinstance(mode, str) or not mode.strip():
399
+ errors.append(f"{prefix}.args.mode is required.")
400
+ if action == "synthetic.seed_claim_support_case":
401
+ scenario = args.get("scenario")
402
+ if not isinstance(scenario, str) or not scenario.strip():
403
+ errors.append(f"{prefix}.args.scenario is required.")
404
+ return errors
405
+
406
+
407
+ def _scan_claim_ledger_ids(*, rel: str, text: str) -> list[str]:
408
+ errors: list[str] = []
409
+ try:
410
+ data = json.loads(text)
411
+ except json.JSONDecodeError:
412
+ return errors
413
+ _scan_json_ids(data, path=rel, errors=errors)
414
+ return errors
415
+
416
+
417
+ def _scan_json_ids(data: Any, *, path: str, errors: list[str]) -> None:
418
+ if isinstance(data, dict):
419
+ claim_id = data.get("claim_id")
420
+ source_id = data.get("source_id")
421
+ if isinstance(claim_id, str) and claim_id and not claim_id.startswith("SYN_CLAIM_"):
422
+ errors.append(f"{path}.claim_id must use SYN_CLAIM_ synthetic IDs.")
423
+ if isinstance(source_id, str) and source_id and not source_id.startswith("SYN_SRC_"):
424
+ errors.append(f"{path}.source_id must use SYN_SRC_ synthetic IDs.")
425
+ for key, value in data.items():
426
+ _scan_json_ids(value, path=f"{path}.{key}", errors=errors)
427
+ elif isinstance(data, list):
428
+ for idx, value in enumerate(data):
429
+ _scan_json_ids(value, path=f"{path}[{idx}]", errors=errors)
@@ -0,0 +1,18 @@
1
+ project:
2
+ name: "Synthetic Improvement Approved Case"
3
+ company: "Demo Holdings Ltd"
4
+ industry: "synthetic testing"
5
+ language: "en"
6
+ audience: "management"
7
+ report:
8
+ cadence: "weekly"
9
+ input:
10
+ path: "input"
11
+ output:
12
+ path: "output"
13
+ source_strategy:
14
+ enabled_providers:
15
+ - manual
16
+ manual:
17
+ enabled: true
18
+ sources: []
@@ -0,0 +1,2 @@
1
+ {"change":{"category":"structure","guidance_text":"Start with the operational implication before implementation detail.","scope":"brief"},"created_at":"2026-06-10T00:00:00Z","entry_id":"AG-0001","level":2,"previous_revision_sha256":null,"revision":1,"schema_version":"multi-agent-brief-improvement-ledger/v1","source_evidence":[{"issue_id":null,"run_id":null,"source_type":"human_feedback","summary":"Operator-created synthetic preference for public eval."}],"status":"proposed","target_kind":"audience_guidance"}
2
+ {"approved_at":"2026-06-10T00:01:00Z","approved_by":"eval_operator","change":{"category":"structure","guidance_text":"Start with the operational implication before implementation detail.","scope":"brief"},"created_at":"2026-06-10T00:00:00Z","entry_id":"AG-0001","level":2,"previous_revision_sha256":"b9a4115cc471b8a11216d80e022ddb2fc02b658934f535e6c3913b26421f7128","revision":2,"schema_version":"multi-agent-brief-improvement-ledger/v1","source_evidence":[{"issue_id":null,"run_id":null,"source_type":"human_feedback","summary":"Operator-created synthetic preference for public eval."}],"status":"approved","target_kind":"audience_guidance"}
@@ -0,0 +1,4 @@
1
+ # Synthetic User Context
2
+
3
+ This public-safe fixture verifies that approved human-authored improvement
4
+ guidance is frozen into a per-run runtime snapshot.
@@ -0,0 +1,13 @@
1
+ project:
2
+ name: "Synthetic Company Event Official Check Case"
3
+ company: "Synthetic Demo Company"
4
+ industry: "synthetic testing"
5
+ language: "en"
6
+ audience: "operator"
7
+ report:
8
+ date: "2026-06-30"
9
+ cadence: "weekly"
10
+ input:
11
+ path: "input"
12
+ output:
13
+ path: "output"
@@ -0,0 +1,9 @@
1
+ source_strategy:
2
+ enabled_providers:
3
+ - manual
4
+ manual:
5
+ enabled: true
6
+ sources: []
7
+ web_search:
8
+ enabled: false
9
+ mode: disabled
@@ -0,0 +1,4 @@
1
+ # Synthetic Company Event Official Check Case
2
+
3
+ This public-safe fixture represents an explicit support record where a company
4
+ event claim lacks the latest official filing or announcement check.
@@ -0,0 +1,12 @@
1
+ project:
2
+ name: "Synthetic Control Switchboard Case"
3
+ company: "Demo Holdings Ltd"
4
+ industry: "synthetic testing"
5
+ language: "en"
6
+ audience: "management"
7
+ report:
8
+ cadence: "weekly"
9
+ input:
10
+ path: "input"
11
+ output:
12
+ path: "output"
@@ -0,0 +1,6 @@
1
+ source_strategy:
2
+ enabled_providers:
3
+ - manual
4
+ manual:
5
+ enabled: true
6
+ sources: []
@@ -0,0 +1,4 @@
1
+ # Synthetic User Context
2
+
3
+ Prepare a management-facing synthetic brief. This fixture only tests the
4
+ Orchestrator control switchboard and must not execute quality gates.
@@ -0,0 +1,6 @@
1
+ project:
2
+ name: "Synthetic TargetCo"
3
+ output:
4
+ path: "output"
5
+ input:
6
+ path: "input"
@@ -0,0 +1 @@
1
+ The brief does not answer the executive question clearly enough.
@@ -0,0 +1,3 @@
1
+ # User
2
+
3
+ Target: Synthetic TargetCo
@@ -0,0 +1,8 @@
1
+ project:
2
+ name: Final Abstract Quality Warning Surface
3
+ report:
4
+ cadence: weekly
5
+ output:
6
+ path: output
7
+ input:
8
+ path: input
@@ -0,0 +1,14 @@
1
+ # Monthly Synthetic Market Brief
2
+
3
+ ## Executive Summary
4
+
5
+ Final Abstract Quality Warning Surface tracks the SyntheticCo market brief.
6
+ SyntheticCo is the leading regional benchmark and should outperform peers next quarter.
7
+
8
+ ## Key Cases
9
+
10
+ - SyntheticCo pilot expansion: pilot expanded regionally.
11
+
12
+ ## Source Appendix
13
+
14
+ - [S1] Synthetic market source.
@@ -0,0 +1 @@
1
+ {"audit_status": "pass", "audit_score": 100, "findings": [], "metadata": {}}
@@ -0,0 +1,5 @@
1
+ # Weekly Synthetic Market Brief
2
+
3
+ ## Executive Summary
4
+
5
+ Final Abstract Quality Warning Surface tracks the SyntheticCo market brief.
@@ -0,0 +1,3 @@
1
+ # User
2
+
3
+ Prepare a weekly synthetic market brief for public-safe evaluation fixtures.
@@ -0,0 +1,13 @@
1
+ project:
2
+ name: "Synthetic Formal Release Approval Case"
3
+ company: "Synthetic Demo Company"
4
+ industry: "synthetic testing"
5
+ language: "en"
6
+ audience: "operator"
7
+ report:
8
+ date: "2026-06-30"
9
+ cadence: "weekly"
10
+ input:
11
+ path: "input"
12
+ output:
13
+ path: "output"
@@ -0,0 +1,9 @@
1
+ source_strategy:
2
+ enabled_providers:
3
+ - manual
4
+ manual:
5
+ enabled: true
6
+ sources: []
7
+ web_search:
8
+ enabled: false
9
+ mode: disabled
@@ -0,0 +1,4 @@
1
+ # Synthetic Formal Release Approval Case
2
+
3
+ This public-safe fixture checks that formal release-candidate readiness remains
4
+ blocked when required human approval roles are missing.
@@ -0,0 +1,4 @@
1
+ project:
2
+ name: Guidance Manifestation Fixture
3
+ brief_quality:
4
+ min_items: 3
@@ -0,0 +1,3 @@
1
+ # Guidance Manifestation Fixture
2
+
3
+ Synthetic public-safe fixture for approved guidance manifestation diagnostics.
@@ -0,0 +1,13 @@
1
+ project:
2
+ name: "Synthetic Media-Only Legal Policy Case"
3
+ company: "Synthetic Demo Company"
4
+ industry: "synthetic testing"
5
+ language: "en"
6
+ audience: "operator"
7
+ report:
8
+ date: "2026-06-30"
9
+ cadence: "weekly"
10
+ input:
11
+ path: "input"
12
+ output:
13
+ path: "output"