alphacouncil-agent 0.9.2 → 1.0.0

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 (493) hide show
  1. package/.claude/commands/alpha.md +22 -3
  2. package/.claude-plugin/marketplace.json +3 -3
  3. package/.claude-plugin/plugin.json +2 -2
  4. package/.codex-plugin/plugin.json +4 -4
  5. package/.grok/commands/alpha.md +22 -3
  6. package/.opencode/command/alpha.md +22 -3
  7. package/AGENTS.md +42 -4
  8. package/CHANGELOG.md +164 -0
  9. package/CLAUDE.md +59 -7
  10. package/README.ja.md +25 -11
  11. package/README.md +44 -12
  12. package/README.zh-CN.md +37 -12
  13. package/commands/alpha.md +22 -3
  14. package/data/authored/core-seats.mjs +808 -0
  15. package/data/authored/growth-seats.mjs +581 -0
  16. package/data/authored/index.mjs +114 -0
  17. package/data/authored/quant-seats.mjs +564 -0
  18. package/data/authored/value-seats.mjs +663 -0
  19. package/data/build-profile.v1.json +2 -1
  20. package/data/council-evaluation-protocol.v1.json +7 -4
  21. package/data/master-selector-method-locales.v1.mjs +296 -0
  22. package/data/persona-v3-ai-assisted-solo-profile.v1.json +2 -2
  23. package/data/persona-v3-build-specs.v1.mjs +60 -3
  24. package/docs/INSTALL.md +43 -6
  25. package/docs/personas.md +2 -1
  26. package/docs/plans/v1.0-roadmap.md +487 -0
  27. package/docs/releases/v0.9.3.md +86 -0
  28. package/docs/releases/v0.9.4.md +79 -0
  29. package/docs/releases/v0.9.5.md +96 -0
  30. package/docs/releases/v1.0.0.md +164 -0
  31. package/docs/report-contract.md +75 -2
  32. package/knowledge/ai-assisted-solo/experiments/runs/a.json +13 -13
  33. package/knowledge/ai-assisted-solo/experiments/runs/b.json +2 -2
  34. package/knowledge/ai-assisted-solo/experiments/runs/c.json +2 -2
  35. package/knowledge/ai-assisted-solo/experiments/runs/d13.json +126 -126
  36. package/knowledge/ai-assisted-solo/experiments/runs/d26.json +274 -254
  37. package/knowledge/ai-assisted-solo/experiments/runs/e-d13.json +129 -129
  38. package/knowledge/ai-assisted-solo/experiments/runs/e-d26.json +277 -257
  39. package/knowledge/ai-assisted-solo/experiments/runs/h_ai_reference.json +278 -258
  40. package/knowledge/ai-assisted-solo/experiments/simulation-input.json +7278 -556
  41. package/knowledge/ai-assisted-solo/experiments/simulation-manifest.json +22 -22
  42. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_ackman/reviews/{change_value_bridge.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  43. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_ackman/reviews/{power_map.ai-review.json → owner_earnings_yield.ai-review.json} +46 -46
  44. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_aschenbrenner/reviews/{compute_power_bridge.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  45. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_aschenbrenner/reviews/{timeline_reverse_valuation.ai-review.json → price_implied_cash_yield.ai-review.json} +46 -46
  46. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_asness/reviews/{crowding_cost_stress.ai-review.json → nominal_earnings_yield_gap.ai-review.json} +49 -49
  47. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_asness/reviews/{factor_decomposer.ai-review.json → real_earnings_yield_gap.ai-review.json} +49 -49
  48. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_bogle/reviews/expected_return_over_long_bond.ai-review.json +277 -0
  49. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_bogle/reviews/fundamental_expected_return.ai-review.json +277 -0
  50. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_buffett/reviews/{incremental_returns.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  51. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_buffett/reviews/{owner_earnings_rebuilder.ai-review.json → owner_earnings_yield.ai-review.json} +46 -46
  52. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_burry/reviews/{mispricing_carry.ai-review.json → net_current_asset_surplus_per_share.ai-review.json} +49 -49
  53. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_burry/reviews/{capital_structure_reader.ai-review.json → net_current_asset_value_per_share.ai-review.json} +46 -46
  54. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_cathie_wood/reviews/{cost_adoption_curve.ai-review.json → current_cash_yield.ai-review.json} +46 -46
  55. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_cathie_wood/reviews/{capture_valuation_bridge.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  56. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_dalio/reviews/{debt_driver_stress.ai-review.json → policy_real_rate.ai-review.json} +49 -49
  57. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_dalio/reviews/{regime_classifier.ai-review.json → real_curve_slope.ai-review.json} +49 -49
  58. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_damodaran/reviews/{reverse_valuation.ai-review.json → implied_equity_risk_premium.ai-review.json} +49 -49
  59. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_damodaran/reviews/{story_dcf.ai-review.json → premium_versus_long_run_average.ai-review.json} +49 -49
  60. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_druckenmiller/reviews/{liquidity_revision_map.ai-review.json → liquidity_curve_impulse.ai-review.json} +49 -49
  61. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_druckenmiller/reviews/{inflection_payoff.ai-review.json → policy_real_rate.ai-review.json} +49 -49
  62. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_duan_yongping/reviews/{opportunity_cost.ai-review.json → five_year_opportunity_cost.ai-review.json} +46 -46
  63. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_duan_yongping/reviews/{user_value_evidence.ai-review.json → margin_retention.ai-review.json} +46 -46
  64. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_fisher/reviews/{research_productivity.ai-review.json → margin_retention.ai-review.json} +46 -46
  65. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_fisher/reviews/{scuttlebutt_graph.ai-review.json → reinvestment_spread.ai-review.json} +49 -49
  66. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_forensic_short/reviews/{borrow_catalyst.ai-review.json → cash_conversion_gap.ai-review.json} +49 -49
  67. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_forensic_short/reviews/{accounting_rebuilder.ai-review.json → cash_cover_of_leverage.ai-review.json} +46 -46
  68. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_graham/reviews/{asset_floor.ai-review.json → defensive_hurdle_base.ai-review.json} +46 -46
  69. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_graham/reviews/{normalized_earnings.ai-review.json → half_normalised_earnings_yield.ai-review.json} +46 -46
  70. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_jhunjhunwala/reviews/{penetration_liquidity.ai-review.json → cash_quality_gap.ai-review.json} +49 -49
  71. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_jhunjhunwala/reviews/{promoter_governance.ai-review.json → real_structural_growth.ai-review.json} +49 -49
  72. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_klarman/reviews/{recovery_waterfall.ai-review.json → downside_asset_coverage.ai-review.json} +46 -46
  73. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_klarman/reviews/{cash_catalyst_compare.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  74. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_li_lu/reviews/{promise_integrity_ledger.ai-review.json → cash_backed_decade_return.ai-review.json} +46 -46
  75. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_li_lu/reviews/{ten_year_return_bridge.ai-review.json → decade_return_over_long_bond.ai-review.json} +49 -49
  76. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_lynch/reviews/{story_numbers_check.ai-review.json → growth_justified_capitalisation.ai-review.json} +46 -46
  77. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_lynch/reviews/{category_classifier.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  78. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_marks/reviews/{cycle_temperature.ai-review.json → credit_cycle_position.ai-review.json} +49 -49
  79. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_marks/reviews/{implied_expectations.ai-review.json → equity_over_corporate_debt.ai-review.json} +49 -49
  80. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_munger/reviews/{failure_path_graph.ai-review.json → debt_service_cushion.ai-review.json} +49 -49
  81. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_munger/reviews/{incentive_map.ai-review.json → reported_earnings_cash_gap.ai-review.json} +49 -49
  82. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_natenberg/reviews/{surface_builder.ai-review.json → normalised_skew.ai-review.json} +46 -46
  83. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_natenberg/reviews/{greeks_payoff.ai-review.json → round_trip_cost.ai-review.json} +46 -46
  84. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_pabrai/reviews/{downside_floor.ai-review.json → downside_floor_coverage.ai-review.json} +46 -46
  85. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_pabrai/reviews/{discrete_payoff.ai-review.json → market_capitalisation.ai-review.json} +46 -46
  86. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_simons/reviews/{oos_cost_test.ai-review.json → absolute_session_move.ai-review.json} +42 -42
  87. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_simons/reviews/{leakage_audit.ai-review.json → session_move_over_implied.ai-review.json} +46 -46
  88. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_sinclair/reviews/{realized_vol_forecast.ai-review.json → round_trip_cost.ai-review.json} +46 -46
  89. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_sinclair/reviews/{net_edge_sizer.ai-review.json → volatility_per_unit_of_width.ai-review.json} +46 -46
  90. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_soros/reviews/{reversal_monitor.ai-review.json → credit_cycle_position.ai-review.json} +49 -49
  91. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_soros/reviews/{reflexivity_graph.ai-review.json → financing_burden.ai-review.json} +46 -46
  92. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_taleb/reviews/{tail_friction.ai-review.json → debt_service_cushion.ai-review.json} +49 -49
  93. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_taleb/reviews/{payoff_ruin.ai-review.json → normalised_skew.ai-review.json} +46 -46
  94. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_thorp/reviews/{edge_recalculator.ai-review.json → edge_per_unit_of_volatility.ai-review.json} +46 -46
  95. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/master_thorp/reviews/{fractional_kelly.ai-review.json → net_edge.ai-review.json} +49 -49
  96. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-formula-reviews/review-manifest.json +288 -270
  97. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-semantic-adjudications/index.json +2 -2
  98. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-semantic-extractions/index.json +2 -2
  99. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-semantic-skeptic-reviews/index.json +2 -2
  100. package/knowledge/ai-assisted-solo/reviews/persona-v3-ai-source-prereviews/index.json +6 -2
  101. package/knowledge/solo-test/masters/master_ackman/decision_policy.json +122 -11
  102. package/knowledge/solo-test/masters/master_ackman/doctrine.jsonl +2 -2
  103. package/knowledge/solo-test/masters/master_ackman/manifest.json +27 -10
  104. package/knowledge/solo-test/masters/master_ackman/provisional-index.json +3 -3
  105. package/knowledge/solo-test/masters/master_ackman/sources.jsonl +1 -1
  106. package/knowledge/solo-test/masters/master_ackman/tools.json +56 -30
  107. package/knowledge/solo-test/masters/master_aschenbrenner/decision_policy.json +101 -10
  108. package/knowledge/solo-test/masters/master_aschenbrenner/doctrine.jsonl +2 -2
  109. package/knowledge/solo-test/masters/master_aschenbrenner/manifest.json +26 -8
  110. package/knowledge/solo-test/masters/master_aschenbrenner/provisional-index.json +3 -3
  111. package/knowledge/solo-test/masters/master_aschenbrenner/sources.jsonl +1 -1
  112. package/knowledge/solo-test/masters/master_aschenbrenner/tools.json +56 -30
  113. package/knowledge/solo-test/masters/master_asness/decision_policy.json +89 -10
  114. package/knowledge/solo-test/masters/master_asness/doctrine.jsonl +2 -2
  115. package/knowledge/solo-test/masters/master_asness/manifest.json +25 -8
  116. package/knowledge/solo-test/masters/master_asness/provisional-index.json +3 -3
  117. package/knowledge/solo-test/masters/master_asness/sources.jsonl +1 -1
  118. package/knowledge/solo-test/masters/master_asness/tools.json +56 -30
  119. package/knowledge/solo-test/masters/master_bogle/counterfactuals.jsonl +0 -0
  120. package/knowledge/solo-test/masters/master_bogle/decision_cases.jsonl +0 -0
  121. package/knowledge/solo-test/masters/master_bogle/decision_policy.json +170 -0
  122. package/knowledge/solo-test/masters/master_bogle/doctrine.jsonl +14 -0
  123. package/knowledge/solo-test/masters/master_bogle/evaluation/calibration_cases.jsonl +0 -0
  124. package/knowledge/solo-test/masters/master_bogle/evaluation/experiments.json +5 -0
  125. package/knowledge/solo-test/masters/master_bogle/evaluation/golden_cases.jsonl +0 -0
  126. package/knowledge/solo-test/masters/master_bogle/evaluation/pairwise_cases.jsonl +0 -0
  127. package/knowledge/solo-test/masters/master_bogle/failures.jsonl +0 -0
  128. package/knowledge/solo-test/masters/master_bogle/manifest.json +141 -0
  129. package/knowledge/solo-test/masters/master_bogle/memory_policy.json +5 -0
  130. package/knowledge/solo-test/masters/master_bogle/provisional-index.json +41 -0
  131. package/knowledge/solo-test/masters/master_bogle/research_policy.json +11 -0
  132. package/knowledge/solo-test/masters/master_bogle/sources.jsonl +1 -0
  133. package/knowledge/solo-test/masters/master_bogle/tools.json +120 -0
  134. package/knowledge/solo-test/masters/master_bogle/voice.en.md +7 -0
  135. package/knowledge/solo-test/masters/master_bogle/voice.zh.md +7 -0
  136. package/knowledge/solo-test/masters/master_buffett/decision_policy.json +102 -11
  137. package/knowledge/solo-test/masters/master_buffett/doctrine.jsonl +2 -2
  138. package/knowledge/solo-test/masters/master_buffett/manifest.json +24 -8
  139. package/knowledge/solo-test/masters/master_buffett/provisional-index.json +3 -3
  140. package/knowledge/solo-test/masters/master_buffett/sources.jsonl +1 -1
  141. package/knowledge/solo-test/masters/master_buffett/tools.json +55 -29
  142. package/knowledge/solo-test/masters/master_burry/decision_policy.json +102 -12
  143. package/knowledge/solo-test/masters/master_burry/doctrine.jsonl +2 -2
  144. package/knowledge/solo-test/masters/master_burry/manifest.json +26 -10
  145. package/knowledge/solo-test/masters/master_burry/provisional-index.json +3 -3
  146. package/knowledge/solo-test/masters/master_burry/sources.jsonl +1 -1
  147. package/knowledge/solo-test/masters/master_burry/tools.json +56 -30
  148. package/knowledge/solo-test/masters/master_cathie_wood/decision_policy.json +74 -12
  149. package/knowledge/solo-test/masters/master_cathie_wood/doctrine.jsonl +2 -2
  150. package/knowledge/solo-test/masters/master_cathie_wood/manifest.json +26 -10
  151. package/knowledge/solo-test/masters/master_cathie_wood/provisional-index.json +3 -3
  152. package/knowledge/solo-test/masters/master_cathie_wood/sources.jsonl +1 -1
  153. package/knowledge/solo-test/masters/master_cathie_wood/tools.json +56 -30
  154. package/knowledge/solo-test/masters/master_dalio/decision_policy.json +123 -16
  155. package/knowledge/solo-test/masters/master_dalio/doctrine.jsonl +2 -2
  156. package/knowledge/solo-test/masters/master_dalio/manifest.json +24 -8
  157. package/knowledge/solo-test/masters/master_dalio/provisional-index.json +3 -3
  158. package/knowledge/solo-test/masters/master_dalio/sources.jsonl +1 -1
  159. package/knowledge/solo-test/masters/master_dalio/tools.json +56 -30
  160. package/knowledge/solo-test/masters/master_damodaran/decision_policy.json +58 -10
  161. package/knowledge/solo-test/masters/master_damodaran/doctrine.jsonl +2 -2
  162. package/knowledge/solo-test/masters/master_damodaran/manifest.json +23 -8
  163. package/knowledge/solo-test/masters/master_damodaran/provisional-index.json +3 -3
  164. package/knowledge/solo-test/masters/master_damodaran/sources.jsonl +1 -1
  165. package/knowledge/solo-test/masters/master_damodaran/tools.json +54 -28
  166. package/knowledge/solo-test/masters/master_druckenmiller/decision_policy.json +89 -10
  167. package/knowledge/solo-test/masters/master_druckenmiller/doctrine.jsonl +2 -2
  168. package/knowledge/solo-test/masters/master_druckenmiller/manifest.json +25 -8
  169. package/knowledge/solo-test/masters/master_druckenmiller/provisional-index.json +3 -3
  170. package/knowledge/solo-test/masters/master_druckenmiller/sources.jsonl +1 -1
  171. package/knowledge/solo-test/masters/master_druckenmiller/tools.json +55 -29
  172. package/knowledge/solo-test/masters/master_duan_yongping/decision_policy.json +138 -13
  173. package/knowledge/solo-test/masters/master_duan_yongping/doctrine.jsonl +2 -2
  174. package/knowledge/solo-test/masters/master_duan_yongping/manifest.json +31 -11
  175. package/knowledge/solo-test/masters/master_duan_yongping/provisional-index.json +3 -3
  176. package/knowledge/solo-test/masters/master_duan_yongping/sources.jsonl +1 -1
  177. package/knowledge/solo-test/masters/master_duan_yongping/tools.json +82 -30
  178. package/knowledge/solo-test/masters/master_fisher/decision_policy.json +102 -11
  179. package/knowledge/solo-test/masters/master_fisher/doctrine.jsonl +2 -2
  180. package/knowledge/solo-test/masters/master_fisher/manifest.json +27 -10
  181. package/knowledge/solo-test/masters/master_fisher/provisional-index.json +3 -3
  182. package/knowledge/solo-test/masters/master_fisher/sources.jsonl +1 -1
  183. package/knowledge/solo-test/masters/master_fisher/tools.json +58 -32
  184. package/knowledge/solo-test/masters/master_forensic_short/decision_policy.json +93 -14
  185. package/knowledge/solo-test/masters/master_forensic_short/doctrine.jsonl +2 -2
  186. package/knowledge/solo-test/masters/master_forensic_short/manifest.json +20 -8
  187. package/knowledge/solo-test/masters/master_forensic_short/provisional-index.json +3 -3
  188. package/knowledge/solo-test/masters/master_forensic_short/sources.jsonl +1 -1
  189. package/knowledge/solo-test/masters/master_forensic_short/tools.json +53 -27
  190. package/knowledge/solo-test/masters/master_graham/decision_policy.json +103 -12
  191. package/knowledge/solo-test/masters/master_graham/doctrine.jsonl +2 -2
  192. package/knowledge/solo-test/masters/master_graham/manifest.json +26 -8
  193. package/knowledge/solo-test/masters/master_graham/provisional-index.json +3 -3
  194. package/knowledge/solo-test/masters/master_graham/sources.jsonl +1 -1
  195. package/knowledge/solo-test/masters/master_graham/tools.json +67 -28
  196. package/knowledge/solo-test/masters/master_jhunjhunwala/decision_policy.json +77 -12
  197. package/knowledge/solo-test/masters/master_jhunjhunwala/doctrine.jsonl +2 -2
  198. package/knowledge/solo-test/masters/master_jhunjhunwala/manifest.json +25 -10
  199. package/knowledge/solo-test/masters/master_jhunjhunwala/provisional-index.json +3 -3
  200. package/knowledge/solo-test/masters/master_jhunjhunwala/sources.jsonl +1 -1
  201. package/knowledge/solo-test/masters/master_jhunjhunwala/tools.json +54 -28
  202. package/knowledge/solo-test/masters/master_klarman/decision_policy.json +105 -14
  203. package/knowledge/solo-test/masters/master_klarman/doctrine.jsonl +2 -2
  204. package/knowledge/solo-test/masters/master_klarman/manifest.json +22 -6
  205. package/knowledge/solo-test/masters/master_klarman/provisional-index.json +3 -3
  206. package/knowledge/solo-test/masters/master_klarman/sources.jsonl +1 -1
  207. package/knowledge/solo-test/masters/master_klarman/tools.json +55 -29
  208. package/knowledge/solo-test/masters/master_li_lu/decision_policy.json +101 -10
  209. package/knowledge/solo-test/masters/master_li_lu/doctrine.jsonl +2 -2
  210. package/knowledge/solo-test/masters/master_li_lu/manifest.json +27 -10
  211. package/knowledge/solo-test/masters/master_li_lu/provisional-index.json +3 -3
  212. package/knowledge/solo-test/masters/master_li_lu/sources.jsonl +1 -1
  213. package/knowledge/solo-test/masters/master_li_lu/tools.json +58 -32
  214. package/knowledge/solo-test/masters/master_lynch/decision_policy.json +127 -16
  215. package/knowledge/solo-test/masters/master_lynch/doctrine.jsonl +2 -2
  216. package/knowledge/solo-test/masters/master_lynch/manifest.json +28 -10
  217. package/knowledge/solo-test/masters/master_lynch/provisional-index.json +3 -3
  218. package/knowledge/solo-test/masters/master_lynch/sources.jsonl +1 -1
  219. package/knowledge/solo-test/masters/master_lynch/tools.json +67 -28
  220. package/knowledge/solo-test/masters/master_marks/decision_policy.json +71 -9
  221. package/knowledge/solo-test/masters/master_marks/doctrine.jsonl +2 -2
  222. package/knowledge/solo-test/masters/master_marks/manifest.json +25 -10
  223. package/knowledge/solo-test/masters/master_marks/provisional-index.json +3 -3
  224. package/knowledge/solo-test/masters/master_marks/sources.jsonl +1 -1
  225. package/knowledge/solo-test/masters/master_marks/tools.json +54 -28
  226. package/knowledge/solo-test/masters/master_munger/decision_policy.json +141 -16
  227. package/knowledge/solo-test/masters/master_munger/doctrine.jsonl +2 -2
  228. package/knowledge/solo-test/masters/master_munger/manifest.json +24 -10
  229. package/knowledge/solo-test/masters/master_munger/provisional-index.json +3 -3
  230. package/knowledge/solo-test/masters/master_munger/sources.jsonl +1 -1
  231. package/knowledge/solo-test/masters/master_munger/tools.json +52 -26
  232. package/knowledge/solo-test/masters/master_natenberg/decision_policy.json +59 -11
  233. package/knowledge/solo-test/masters/master_natenberg/doctrine.jsonl +2 -2
  234. package/knowledge/solo-test/masters/master_natenberg/manifest.json +23 -10
  235. package/knowledge/solo-test/masters/master_natenberg/provisional-index.json +3 -3
  236. package/knowledge/solo-test/masters/master_natenberg/sources.jsonl +1 -1
  237. package/knowledge/solo-test/masters/master_natenberg/tools.json +50 -24
  238. package/knowledge/solo-test/masters/master_pabrai/decision_policy.json +125 -14
  239. package/knowledge/solo-test/masters/master_pabrai/doctrine.jsonl +2 -2
  240. package/knowledge/solo-test/masters/master_pabrai/manifest.json +22 -6
  241. package/knowledge/solo-test/masters/master_pabrai/provisional-index.json +3 -3
  242. package/knowledge/solo-test/masters/master_pabrai/sources.jsonl +1 -1
  243. package/knowledge/solo-test/masters/master_pabrai/tools.json +55 -29
  244. package/knowledge/solo-test/masters/master_simons/decision_policy.json +59 -11
  245. package/knowledge/solo-test/masters/master_simons/doctrine.jsonl +2 -2
  246. package/knowledge/solo-test/masters/master_simons/manifest.json +22 -8
  247. package/knowledge/solo-test/masters/master_simons/provisional-index.json +3 -3
  248. package/knowledge/solo-test/masters/master_simons/sources.jsonl +1 -1
  249. package/knowledge/solo-test/masters/master_simons/tools.json +43 -30
  250. package/knowledge/solo-test/masters/master_sinclair/decision_policy.json +59 -11
  251. package/knowledge/solo-test/masters/master_sinclair/doctrine.jsonl +2 -2
  252. package/knowledge/solo-test/masters/master_sinclair/manifest.json +22 -10
  253. package/knowledge/solo-test/masters/master_sinclair/provisional-index.json +3 -3
  254. package/knowledge/solo-test/masters/master_sinclair/sources.jsonl +1 -1
  255. package/knowledge/solo-test/masters/master_sinclair/tools.json +54 -28
  256. package/knowledge/solo-test/masters/master_soros/decision_policy.json +98 -10
  257. package/knowledge/solo-test/masters/master_soros/doctrine.jsonl +2 -2
  258. package/knowledge/solo-test/masters/master_soros/manifest.json +24 -11
  259. package/knowledge/solo-test/masters/master_soros/provisional-index.json +3 -3
  260. package/knowledge/solo-test/masters/master_soros/sources.jsonl +1 -1
  261. package/knowledge/solo-test/masters/master_soros/tools.json +54 -28
  262. package/knowledge/solo-test/masters/master_taleb/decision_policy.json +124 -13
  263. package/knowledge/solo-test/masters/master_taleb/doctrine.jsonl +2 -2
  264. package/knowledge/solo-test/masters/master_taleb/manifest.json +23 -9
  265. package/knowledge/solo-test/masters/master_taleb/provisional-index.json +3 -3
  266. package/knowledge/solo-test/masters/master_taleb/sources.jsonl +1 -1
  267. package/knowledge/solo-test/masters/master_taleb/tools.json +50 -24
  268. package/knowledge/solo-test/masters/master_thorp/decision_policy.json +61 -13
  269. package/knowledge/solo-test/masters/master_thorp/doctrine.jsonl +2 -2
  270. package/knowledge/solo-test/masters/master_thorp/manifest.json +25 -10
  271. package/knowledge/solo-test/masters/master_thorp/provisional-index.json +3 -3
  272. package/knowledge/solo-test/masters/master_thorp/sources.jsonl +1 -1
  273. package/knowledge/solo-test/masters/master_thorp/tools.json +56 -30
  274. package/knowledge/solo-test/persona-v3-solo-test-formulas/compilation-manifest.json +290 -264
  275. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_ackman/components/tools.json +58 -32
  276. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_ackman/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  277. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_ackman/provisional-derivations/owner_earnings_yield.derived-proxy-evidence.json +76 -0
  278. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_aschenbrenner/components/tools.json +58 -32
  279. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_aschenbrenner/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  280. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_aschenbrenner/provisional-derivations/price_implied_cash_yield.derived-proxy-evidence.json +76 -0
  281. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_asness/components/tools.json +58 -32
  282. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_asness/provisional-derivations/nominal_earnings_yield_gap.derived-proxy-evidence.json +76 -0
  283. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_asness/provisional-derivations/real_earnings_yield_gap.derived-proxy-evidence.json +76 -0
  284. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_bogle/components/tools.json +120 -0
  285. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_bogle/provisional-derivations/expected_return_over_long_bond.derived-proxy-evidence.json +77 -0
  286. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_bogle/provisional-derivations/fundamental_expected_return.derived-proxy-evidence.json +76 -0
  287. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_buffett/components/tools.json +57 -31
  288. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_buffett/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  289. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_buffett/provisional-derivations/owner_earnings_yield.derived-proxy-evidence.json +76 -0
  290. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_burry/components/tools.json +58 -32
  291. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_burry/provisional-derivations/net_current_asset_surplus_per_share.derived-proxy-evidence.json +77 -0
  292. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_burry/provisional-derivations/net_current_asset_value_per_share.derived-proxy-evidence.json +76 -0
  293. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_cathie_wood/components/tools.json +58 -32
  294. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_cathie_wood/provisional-derivations/current_cash_yield.derived-proxy-evidence.json +76 -0
  295. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_cathie_wood/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  296. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_dalio/components/tools.json +58 -32
  297. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_dalio/provisional-derivations/policy_real_rate.derived-proxy-evidence.json +76 -0
  298. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_dalio/provisional-derivations/real_curve_slope.derived-proxy-evidence.json +76 -0
  299. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_damodaran/components/tools.json +56 -30
  300. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_damodaran/provisional-derivations/implied_equity_risk_premium.derived-proxy-evidence.json +76 -0
  301. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_damodaran/provisional-derivations/{reverse_valuation.derived-proxy-evidence.json → premium_versus_long_run_average.derived-proxy-evidence.json} +29 -16
  302. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_druckenmiller/components/tools.json +57 -31
  303. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_druckenmiller/provisional-derivations/liquidity_curve_impulse.derived-proxy-evidence.json +76 -0
  304. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_druckenmiller/provisional-derivations/policy_real_rate.derived-proxy-evidence.json +76 -0
  305. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_duan_yongping/components/tools.json +84 -32
  306. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_duan_yongping/provisional-derivations/five_year_opportunity_cost.derived-proxy-evidence.json +102 -0
  307. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_duan_yongping/provisional-derivations/margin_retention.derived-proxy-evidence.json +76 -0
  308. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_fisher/components/tools.json +60 -34
  309. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_fisher/provisional-derivations/margin_retention.derived-proxy-evidence.json +76 -0
  310. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_fisher/provisional-derivations/reinvestment_spread.derived-proxy-evidence.json +76 -0
  311. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_forensic_short/components/tools.json +55 -29
  312. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_forensic_short/provisional-derivations/{accounting_rebuilder.derived-proxy-evidence.json → cash_conversion_gap.derived-proxy-evidence.json} +28 -15
  313. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_forensic_short/provisional-derivations/cash_cover_of_leverage.derived-proxy-evidence.json +76 -0
  314. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_graham/components/tools.json +69 -30
  315. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_graham/provisional-derivations/defensive_hurdle_base.derived-proxy-evidence.json +89 -0
  316. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_graham/provisional-derivations/half_normalised_earnings_yield.derived-proxy-evidence.json +76 -0
  317. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_jhunjhunwala/components/tools.json +56 -30
  318. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_jhunjhunwala/provisional-derivations/cash_quality_gap.derived-proxy-evidence.json +76 -0
  319. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_jhunjhunwala/provisional-derivations/real_structural_growth.derived-proxy-evidence.json +76 -0
  320. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_klarman/components/tools.json +57 -31
  321. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_klarman/provisional-derivations/downside_asset_coverage.derived-proxy-evidence.json +76 -0
  322. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_klarman/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  323. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_li_lu/components/tools.json +60 -34
  324. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_li_lu/provisional-derivations/cash_backed_decade_return.derived-proxy-evidence.json +76 -0
  325. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_li_lu/provisional-derivations/decade_return_over_long_bond.derived-proxy-evidence.json +76 -0
  326. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_lynch/components/tools.json +69 -30
  327. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_lynch/provisional-derivations/growth_justified_capitalisation.derived-proxy-evidence.json +89 -0
  328. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_lynch/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  329. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_marks/components/tools.json +56 -30
  330. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_marks/provisional-derivations/credit_cycle_position.derived-proxy-evidence.json +76 -0
  331. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_marks/provisional-derivations/equity_over_corporate_debt.derived-proxy-evidence.json +76 -0
  332. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_munger/components/tools.json +54 -28
  333. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_munger/provisional-derivations/debt_service_cushion.derived-proxy-evidence.json +76 -0
  334. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_munger/provisional-derivations/reported_earnings_cash_gap.derived-proxy-evidence.json +76 -0
  335. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_natenberg/components/tools.json +52 -26
  336. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_natenberg/provisional-derivations/{surface_builder.derived-proxy-evidence.json → normalised_skew.derived-proxy-evidence.json} +27 -14
  337. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_natenberg/provisional-derivations/round_trip_cost.derived-proxy-evidence.json +76 -0
  338. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_pabrai/components/tools.json +57 -31
  339. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_pabrai/provisional-derivations/downside_floor_coverage.derived-proxy-evidence.json +76 -0
  340. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_pabrai/provisional-derivations/market_capitalisation.derived-proxy-evidence.json +76 -0
  341. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_simons/components/tools.json +45 -32
  342. package/knowledge/solo-test/persona-v3-solo-test-formulas/{master_natenberg/provisional-derivations/greeks_payoff.derived-proxy-evidence.json → master_simons/provisional-derivations/absolute_session_move.derived-proxy-evidence.json} +17 -17
  343. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_simons/provisional-derivations/session_move_over_implied.derived-proxy-evidence.json +77 -0
  344. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_sinclair/components/tools.json +56 -30
  345. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_sinclair/provisional-derivations/round_trip_cost.derived-proxy-evidence.json +76 -0
  346. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_sinclair/provisional-derivations/volatility_per_unit_of_width.derived-proxy-evidence.json +76 -0
  347. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_soros/components/tools.json +56 -30
  348. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_soros/provisional-derivations/credit_cycle_position.derived-proxy-evidence.json +76 -0
  349. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_soros/provisional-derivations/financing_burden.derived-proxy-evidence.json +76 -0
  350. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_taleb/components/tools.json +52 -26
  351. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_taleb/provisional-derivations/debt_service_cushion.derived-proxy-evidence.json +76 -0
  352. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_taleb/provisional-derivations/{tail_friction.derived-proxy-evidence.json → normalised_skew.derived-proxy-evidence.json} +27 -14
  353. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_thorp/components/tools.json +58 -32
  354. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_thorp/provisional-derivations/edge_per_unit_of_volatility.derived-proxy-evidence.json +77 -0
  355. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_thorp/provisional-derivations/net_edge.derived-proxy-evidence.json +76 -0
  356. package/mcp/lib/breadth.mjs +122 -0
  357. package/mcp/lib/codex.mjs +3 -3
  358. package/mcp/lib/constants.mjs +76 -25
  359. package/mcp/lib/council-options.mjs +95 -40
  360. package/mcp/lib/council-selection.mjs +95 -9
  361. package/mcp/lib/damodaran.mjs +119 -0
  362. package/mcp/lib/fred.mjs +246 -0
  363. package/mcp/lib/fund-holdings-parsers.mjs +297 -0
  364. package/mcp/lib/fundamentals.mjs +801 -0
  365. package/mcp/lib/funds.mjs +750 -0
  366. package/mcp/lib/gates.mjs +149 -15
  367. package/mcp/lib/grounding.mjs +188 -36
  368. package/mcp/lib/index-aggregate.mjs +718 -0
  369. package/mcp/lib/insider-ownership.mjs +149 -0
  370. package/mcp/lib/instrument-facts.mjs +557 -0
  371. package/mcp/lib/instruments.mjs +191 -0
  372. package/mcp/lib/lang.mjs +109 -2
  373. package/mcp/lib/markdown.mjs +620 -138
  374. package/mcp/lib/master-catalog.mjs +32 -3
  375. package/mcp/lib/orchestrator.mjs +1121 -290
  376. package/mcp/lib/packets.mjs +227 -21
  377. package/mcp/lib/personas/engine.mjs +44 -31
  378. package/mcp/lib/personas-v3/compiler.mjs +2 -0
  379. package/mcp/lib/personas-v3/deterministic-executor.mjs +13 -2
  380. package/mcp/lib/personas-v3/ga-external-evidence.mjs +3 -2
  381. package/mcp/lib/personas-v3/ga-gate.mjs +2 -1
  382. package/mcp/lib/personas-v3/ga-package-evidence.mjs +5 -4
  383. package/mcp/lib/personas-v3/grounding-adapter.mjs +309 -2
  384. package/mcp/lib/personas-v3/loader.mjs +10 -7
  385. package/mcp/lib/personas-v3/production-root.mjs +5 -4
  386. package/mcp/lib/personas-v3/release-formula-evidence.mjs +14 -7
  387. package/mcp/lib/personas-v3/release-source-evidence.mjs +2 -1
  388. package/mcp/lib/personas-v3/releases.mjs +5 -4
  389. package/mcp/lib/personas-v3/runtime-release-integrity.mjs +6 -5
  390. package/mcp/lib/personas-v3/semantic-source-adjudication.mjs +2 -1
  391. package/mcp/lib/personas-v3/semantic-source-extraction.mjs +2 -1
  392. package/mcp/lib/personas-v3/semantic-source-skeptic-review.mjs +2 -1
  393. package/mcp/lib/personas-v3/source-acquisition.mjs +10 -3
  394. package/mcp/lib/personas-v3/source-review-operations.mjs +3 -2
  395. package/mcp/lib/personas-v3/staging.mjs +22 -3
  396. package/mcp/lib/prompts.mjs +119 -2
  397. package/mcp/lib/quotes.mjs +5 -0
  398. package/mcp/lib/rpc.mjs +101 -42
  399. package/mcp/lib/run-store.mjs +28 -3
  400. package/mcp/lib/sec.mjs +32 -0
  401. package/mcp/lib/tables.mjs +11 -0
  402. package/mcp/lib/voice.mjs +122 -0
  403. package/mcp/lib/xbrl-aggregates.mjs +153 -0
  404. package/mcp/lib/xbrl-series.mjs +339 -0
  405. package/mcp/lib/xlsx.mjs +155 -0
  406. package/package.json +5 -5
  407. package/personas/masters/masters-value/bogle.md +145 -0
  408. package/schemas/council-evaluation-protocol-v1.schema.json +2 -2
  409. package/schemas/persona-v3-ai-assisted-solo-profile-v1.schema.json +2 -2
  410. package/schemas/persona-v3-ai-machine-simulation-v1.schema.json +1 -1
  411. package/schemas/persona-v3-build-spec-v1.schema.json +3 -3
  412. package/schemas/persona-v3-release-formula-review-evidence-v1.schema.json +3 -3
  413. package/schemas/persona-v3-release-manifest-v1.schema.json +6 -6
  414. package/schemas/persona-v3-release-source-review-evidence-v1.schema.json +3 -3
  415. package/schemas/persona-v3-tool-graph-v1.schema.json +1 -1
  416. package/schemas/persona-v3.schema.json +37 -2
  417. package/schemas/source-review-batch-v1.schema.json +9 -9
  418. package/scripts/assemble-persona-v3-release.mjs +3 -2
  419. package/scripts/build-persona-v3-solo-test-packs.mjs +6 -8
  420. package/scripts/check-persona-v3-ga.mjs +1 -1
  421. package/scripts/check-persona-v3-production-candidates.mjs +1 -1
  422. package/scripts/compile-persona-v3-formulas.mjs +19 -18
  423. package/scripts/doctor.mjs +11 -9
  424. package/scripts/export-persona-source-review-batch.mjs +1 -1
  425. package/scripts/generate-persona-v3-drafts.mjs +2 -2
  426. package/scripts/lib/build-profile.mjs +24 -0
  427. package/scripts/lib/council-evaluation-protocol.mjs +7 -6
  428. package/scripts/lib/host-capabilities.mjs +2 -1
  429. package/scripts/lib/packaged-host-parity.mjs +63 -8
  430. package/scripts/lib/persona-v3-ai-assisted-solo-status.mjs +6 -4
  431. package/scripts/lib/persona-v3-ai-formula-review.mjs +6 -5
  432. package/scripts/lib/persona-v3-ai-machine-simulations.mjs +32 -4
  433. package/scripts/lib/persona-v3-build-specs.mjs +3 -2
  434. package/scripts/lib/persona-v3-draft-packs.mjs +2 -2
  435. package/scripts/lib/persona-v3-formula-pipeline.mjs +11 -10
  436. package/scripts/lib/persona-v3-production-candidates.mjs +10 -9
  437. package/scripts/lib/persona-v3-solo-formula-pipeline.mjs +182 -16
  438. package/scripts/lib/persona-v3-solo-test-packs.mjs +143 -16
  439. package/scripts/package-smoke.mjs +32 -12
  440. package/scripts/report-persona-corpus-gaps.mjs +4 -1
  441. package/scripts/review-persona-v3-solo-formulas.mjs +12 -8
  442. package/scripts/run-tests.mjs +23 -2
  443. package/scripts/scaffold-persona-v3-staging.mjs +1 -1
  444. package/skills/agent-skills-governance/SKILL.md +8 -2
  445. package/skills/alphacouncil-agent/SKILL.md +60 -9
  446. package/skills/public-equity-investing/SKILL.md +17 -0
  447. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_ackman/provisional-derivations/change_value_bridge.derived-proxy-evidence.json +0 -64
  448. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_ackman/provisional-derivations/power_map.derived-proxy-evidence.json +0 -64
  449. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_aschenbrenner/provisional-derivations/compute_power_bridge.derived-proxy-evidence.json +0 -64
  450. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_aschenbrenner/provisional-derivations/timeline_reverse_valuation.derived-proxy-evidence.json +0 -64
  451. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_asness/provisional-derivations/crowding_cost_stress.derived-proxy-evidence.json +0 -64
  452. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_asness/provisional-derivations/factor_decomposer.derived-proxy-evidence.json +0 -64
  453. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_buffett/provisional-derivations/incremental_returns.derived-proxy-evidence.json +0 -64
  454. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_buffett/provisional-derivations/owner_earnings_rebuilder.derived-proxy-evidence.json +0 -64
  455. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_burry/provisional-derivations/capital_structure_reader.derived-proxy-evidence.json +0 -64
  456. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_burry/provisional-derivations/mispricing_carry.derived-proxy-evidence.json +0 -64
  457. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_cathie_wood/provisional-derivations/capture_valuation_bridge.derived-proxy-evidence.json +0 -64
  458. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_cathie_wood/provisional-derivations/cost_adoption_curve.derived-proxy-evidence.json +0 -64
  459. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_dalio/provisional-derivations/debt_driver_stress.derived-proxy-evidence.json +0 -64
  460. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_dalio/provisional-derivations/regime_classifier.derived-proxy-evidence.json +0 -64
  461. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_damodaran/provisional-derivations/story_dcf.derived-proxy-evidence.json +0 -64
  462. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_druckenmiller/provisional-derivations/inflection_payoff.derived-proxy-evidence.json +0 -64
  463. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_druckenmiller/provisional-derivations/liquidity_revision_map.derived-proxy-evidence.json +0 -64
  464. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_duan_yongping/provisional-derivations/opportunity_cost.derived-proxy-evidence.json +0 -64
  465. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_duan_yongping/provisional-derivations/user_value_evidence.derived-proxy-evidence.json +0 -64
  466. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_fisher/provisional-derivations/research_productivity.derived-proxy-evidence.json +0 -64
  467. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_fisher/provisional-derivations/scuttlebutt_graph.derived-proxy-evidence.json +0 -64
  468. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_forensic_short/provisional-derivations/borrow_catalyst.derived-proxy-evidence.json +0 -64
  469. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_graham/provisional-derivations/asset_floor.derived-proxy-evidence.json +0 -64
  470. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_graham/provisional-derivations/normalized_earnings.derived-proxy-evidence.json +0 -64
  471. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_jhunjhunwala/provisional-derivations/penetration_liquidity.derived-proxy-evidence.json +0 -64
  472. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_jhunjhunwala/provisional-derivations/promoter_governance.derived-proxy-evidence.json +0 -64
  473. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_klarman/provisional-derivations/cash_catalyst_compare.derived-proxy-evidence.json +0 -64
  474. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_klarman/provisional-derivations/recovery_waterfall.derived-proxy-evidence.json +0 -64
  475. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_li_lu/provisional-derivations/promise_integrity_ledger.derived-proxy-evidence.json +0 -64
  476. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_li_lu/provisional-derivations/ten_year_return_bridge.derived-proxy-evidence.json +0 -64
  477. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_lynch/provisional-derivations/category_classifier.derived-proxy-evidence.json +0 -64
  478. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_lynch/provisional-derivations/story_numbers_check.derived-proxy-evidence.json +0 -64
  479. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_marks/provisional-derivations/cycle_temperature.derived-proxy-evidence.json +0 -64
  480. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_marks/provisional-derivations/implied_expectations.derived-proxy-evidence.json +0 -64
  481. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_munger/provisional-derivations/failure_path_graph.derived-proxy-evidence.json +0 -64
  482. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_munger/provisional-derivations/incentive_map.derived-proxy-evidence.json +0 -64
  483. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_pabrai/provisional-derivations/discrete_payoff.derived-proxy-evidence.json +0 -64
  484. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_pabrai/provisional-derivations/downside_floor.derived-proxy-evidence.json +0 -64
  485. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_simons/provisional-derivations/leakage_audit.derived-proxy-evidence.json +0 -64
  486. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_simons/provisional-derivations/oos_cost_test.derived-proxy-evidence.json +0 -64
  487. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_sinclair/provisional-derivations/net_edge_sizer.derived-proxy-evidence.json +0 -64
  488. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_sinclair/provisional-derivations/realized_vol_forecast.derived-proxy-evidence.json +0 -64
  489. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_soros/provisional-derivations/reflexivity_graph.derived-proxy-evidence.json +0 -64
  490. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_soros/provisional-derivations/reversal_monitor.derived-proxy-evidence.json +0 -64
  491. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_taleb/provisional-derivations/payoff_ruin.derived-proxy-evidence.json +0 -64
  492. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_thorp/provisional-derivations/edge_recalculator.derived-proxy-evidence.json +0 -64
  493. package/knowledge/solo-test/persona-v3-solo-test-formulas/master_thorp/provisional-derivations/fractional_kelly.derived-proxy-evidence.json +0 -64
@@ -1,53 +1,63 @@
1
1
  import { writeFileSync } from "node:fs";
2
2
  import { join } from "node:path";
3
- import { DEBATE_ROLES, REPORT_SECTIONS } from "./constants.mjs";
3
+ import { DEBATE_ROLES, RECORDED_BENCH_MARKER_PREFIX, RECORDED_INSTRUMENT_MARKER_PREFIX, REPORT_SECTIONS } from "./constants.mjs";
4
4
  import { writeJson } from "./fsutil.mjs";
5
5
  import { headingIncludesAlias, normalizeHeading, parseHeadings } from "./headings.mjs";
6
- import { isChineseLanguage } from "./lang.mjs";
6
+ import { isChineseLanguage, languageKey, localized } from "./lang.mjs";
7
7
  import { sha256 } from "./personas-v3/canonical.mjs";
8
+ import { compiledPersonaPacks } from "./personas-v3/registry.mjs";
8
9
  import { bullets, clip, clipAtBoundary, fence } from "./text.mjs";
9
10
  import { completenessStatus, validateFinalReport, verificationStatus, withCompletenessBanner, withDisclaimer, withVerificationBanner } from "./gates.mjs";
11
+ import { isFundOrIndex } from "./instruments.mjs";
12
+ import { intentLabel, VOICE_FIELDS, voiceDisclaimer, voiceFieldLabel } from "./voice.mjs";
10
13
  import { agentState, appendEvent, artifactPaths, runPath, taskState } from "./run-store.mjs";
11
14
  import { personaTitle, registry } from "./personas/registry.mjs";
12
15
 
13
- export function renderPacketMarkdown(packet, index) {
16
+ export function renderPacketMarkdown(packet, index = 0, language = packet?.language) {
17
+ const key = languageKey(language);
18
+ const label = {
19
+ zh: { title: "证据分析子代理", symbol: "代码", asOf: "截至", confidence: "置信度", richness: "信息丰富度", summary: "摘要", claims: "论断", evidence: "证据", sources: "来源", metrics: "指标", questions: "未决问题", raw: "原始 worker 响应(仅供审计)", none: "无" },
20
+ en: { title: "Evidence Analyst Subagent", symbol: "Symbol", asOf: "As-of", confidence: "Confidence", richness: "Information richness", summary: "Summary", claims: "Claims", evidence: "Evidence", sources: "Sources", metrics: "Metrics", questions: "Open Questions", raw: "Raw Worker Response (audit only)", none: "None" },
21
+ ja: { title: "証拠分析サブエージェント", symbol: "銘柄コード", asOf: "基準日", confidence: "信頼度", richness: "情報充足度", summary: "要約", claims: "主張", evidence: "根拠", sources: "出典", metrics: "指標", questions: "未解決事項", raw: "ワーカーの生応答(監査専用)", none: "なし" },
22
+ ko: { title: "증거 분석 하위 에이전트", symbol: "종목 코드", asOf: "기준일", confidence: "신뢰도", richness: "정보 충실도", summary: "요약", claims: "주장", evidence: "근거", sources: "출처", metrics: "지표", questions: "미해결 질문", raw: "원본 워커 응답(감사 전용)", none: "없음" },
23
+ }[key];
14
24
  const claims = packet.claims.length
15
25
  ? packet.claims.map((claim, claimIndex) => [
16
26
  `${claimIndex + 1}. ${claim.claim || ""}`,
17
- ` - Evidence: ${claim.evidence || ""}`,
18
- ` - Confidence: ${claim.confidence || "low"}`,
19
- ` - Sources: ${(claim.source_ids || []).join(", ") || "None"}`,
27
+ ` - ${label.evidence}: ${claim.evidence || ""}`,
28
+ ` - ${label.confidence}: ${claim.confidence || "low"}`,
29
+ ` - ${label.sources}: ${(claim.source_ids || []).join(", ") || label.none}`,
20
30
  ].join("\n")).join("\n")
21
- : "No claims.";
31
+ : `${label.none}.`;
22
32
  const sources = packet.sources.length
23
33
  ? packet.sources.map((source) => `- ${source.id || "S?"}: ${source.title || ""} (${source.published_at || "unknown"}) ${source.url || ""}`).join("\n")
24
- : "- None";
34
+ : `- ${label.none}`;
25
35
  return [
26
- `## Evidence Subagent ${index + 1}: ${packet.task}`,
36
+ `## ${label.title} ${index + 1}: ${packet.task}`,
27
37
  "",
28
- `- Symbol: ${packet.symbol}`,
29
- `- As-of: ${packet.as_of}`,
38
+ `- ${label.symbol}: ${packet.symbol}`,
39
+ `- ${label.asOf}: ${packet.as_of}`,
30
40
  packet.thread_id ? `- Visible thread ID: ${packet.thread_id}` : "",
31
41
  packet.thread_title ? `- Visible thread title: ${packet.thread_title}` : "",
32
- `- Confidence: ${packet.confidence}`,
33
- `- Information richness: ${packet.information_richness || "unrated"}`,
42
+ `- ${label.confidence}: ${packet.confidence}`,
43
+ `- ${label.richness}: ${packet.information_richness || "unrated"}`,
34
44
  "",
35
- "### Summary",
45
+ `### ${label.summary}`,
36
46
  packet.summary || "",
37
47
  "",
38
- "### Claims",
48
+ `### ${label.claims}`,
39
49
  claims,
40
50
  "",
41
- "### Metrics",
51
+ `### ${label.metrics}`,
42
52
  fence(packet.metrics || {}, "json"),
43
53
  "",
44
- "### Sources",
54
+ `### ${label.sources}`,
45
55
  sources,
46
56
  "",
47
- "### Open Questions",
57
+ `### ${label.questions}`,
48
58
  bullets(packet.open_questions),
49
59
  "",
50
- "### Raw Output / Prompt",
60
+ `### ${label.raw}`,
51
61
  fence(packet.raw_text || "", "text"),
52
62
  ].join("\n");
53
63
  }
@@ -63,35 +73,126 @@ export function renderPacketMarkdown(packet, index) {
63
73
  export function renderMasterMarkdown(opinion, lang) {
64
74
  if (!opinion) return "";
65
75
  const title = masterTitle(opinion.master, lang);
76
+ const labels = {
77
+ zh: { statement: "本轮方法席终局陈词(不是大师本人引语)", stance: "立场", verdict: "冻结判断", confidence: "置信度", worker: "陈词来源", summary: "方法席说明", findings: "关键发现", disagreements: "与分析师的分歧", disqualifiers: "触发的排除条件", change: "改变判断所需证据", sources: "来源" },
78
+ en: { statement: "Final Method-Seat Statement (not a quote from the named person)", stance: "Stance", verdict: "Frozen verdict", confidence: "Confidence", worker: "Statement source", summary: "Method-seat explanation", findings: "Key Findings", disagreements: "Disagreements With The Analysts", disqualifiers: "Disqualifiers Triggered", change: "What Would Change The View", sources: "Sources" },
79
+ ja: { statement: "メソッド席の最終見解(本人の発言・引用ではありません)", stance: "スタンス", verdict: "凍結済み判定", confidence: "信頼度", worker: "見解の生成元", summary: "メソッド席の説明", findings: "主な所見", disagreements: "分析担当との相違", disqualifiers: "発動した除外条件", change: "判断が変わる条件", sources: "出典" },
80
+ ko: { statement: "방법론 좌석 최종 발언(본인의 실제 발언이나 인용이 아님)", stance: "입장", verdict: "동결된 판단", confidence: "신뢰도", worker: "발언 출처", summary: "방법론 좌석 설명", findings: "핵심 발견", disagreements: "분석가와의 이견", disqualifiers: "발동된 제외 조건", change: "판단 변경 조건", sources: "출처" },
81
+ }[languageKey(lang)];
66
82
  return [
67
83
  `## ${title}`,
68
84
  "",
69
85
  `- ID: ${opinion.master}`,
70
- `- Stance: ${opinion.stance || "unknown"}`,
71
- `- Verdict: ${opinion.verdict || ""}`,
72
- `- Confidence: ${opinion.confidence || "low"}`,
86
+ `- ${labels.stance}: ${opinion.stance || "unknown"}`,
87
+ `- ${labels.verdict}: ${opinion.verdict || ""}`,
88
+ `- ${labels.confidence}: ${opinion.confidence || "low"}`,
89
+ `- ${labels.worker}: ${opinion.dedicated_worker?.status || opinion.voice_status || "not_recorded"}${opinion.dedicated_worker?.pid ? ` (pid ${opinion.dedicated_worker.pid})` : ""}`,
73
90
  opinion.thread_id ? `- Visible thread ID: ${opinion.thread_id}` : "",
74
91
  "",
75
- "### Summary",
76
- opinion.summary || "",
92
+ `### ${labels.statement}`,
93
+ opinion.voice_statement || opinion.summary || "",
77
94
  "",
78
- "### Key Findings",
95
+ `### ${labels.summary}`,
96
+ opinion.deterministic_summary || opinion.summary || "",
97
+ "",
98
+ `### ${labels.findings}`,
79
99
  bullets(opinion.key_findings),
80
100
  "",
81
- "### Disagreements With The Analysts",
101
+ `### ${labels.disagreements}`,
82
102
  bullets(opinion.disagreements),
83
103
  "",
84
- "### Disqualifiers Triggered",
104
+ `### ${labels.disqualifiers}`,
85
105
  bullets(opinion.disqualifiers_triggered),
86
106
  "",
87
- "### What Would Change My Mind",
107
+ `### ${labels.change}`,
88
108
  bullets(opinion.what_would_change_my_mind),
89
109
  "",
90
- "### Sources",
110
+ `### ${labels.sources}`,
91
111
  (opinion.source_ids || []).length ? (opinion.source_ids || []).map((id) => `- ${id}`).join("\n") : "- None",
92
112
  ].filter((line) => line !== "").join("\n");
93
113
  }
94
114
 
115
+ /** Reader-facing labels for the method-seat section, one entry per supported run language. */
116
+ const MASTER_STATEMENT_COPY = Object.freeze({
117
+ zh: {
118
+ heading: "\u9010\u5e2d\u65b9\u6cd5\u8f93\u51fa", acted: "\u6709\u5224\u65ad\u7684\u5e2d\u4f4d", abstained: "\u8bf4\u8fd9\u4e0d\u5f52\u5b83\u7ba1\u7684\u5e2d\u4f4d",
119
+ stance: "\u7acb\u573a", intent: "\u610f\u5411", origin: "\u9648\u8bcd\u6765\u6e90", statement: "\u672c\u8f6e\u53d1\u8a00\uff08\u4e0d\u662f\u672c\u4eba\u5f15\u8bed\uff09",
120
+ findings: "\u5173\u952e\u53d1\u73b0", disagreements: "\u4e0e\u5206\u6790\u5e08\u5206\u6b67", change: "\u6539\u53d8\u5224\u65ad\u6761\u4ef6", sources: "\u6765\u6e90\u6216\u660e\u786e\u7f3a\u53e3",
121
+ abstainLead: (n) => `\u53e6\u6709 ${n} \u5e2d\u5728\u672c\u8f6e\u4e0d\u7ed9\u65b9\u5411\uff0c\u5404\u81ea\u7f3a\u7684\u662f\u65b9\u6cd5\u5fc5\u9700\u7684\u8f93\u5165\uff0c\u8fd9\u4e0d\u662f\u770b\u7a7a\u7968\uff1a`,
122
+ },
123
+ en: {
124
+ heading: "Method-Seat Outputs", acted: "Seats with a view", abstained: "Seats that say this is not theirs to call",
125
+ stance: "Stance", intent: "Intent", origin: "Statement source", statement: "Recorded statement (not a quote)",
126
+ findings: "Key findings", disagreements: "Disagreements", change: "What would change the view", sources: "Sources or explicit gaps",
127
+ abstainLead: (n) => `A further ${n} seat(s) issue no direction this round, each missing a method-critical input. These are not bearish votes:`,
128
+ },
129
+ ja: {
130
+ heading: "\u30e1\u30bd\u30c3\u30c9\u5e2d\u3054\u3068\u306e\u51fa\u529b", acted: "\u5224\u65ad\u3092\u793a\u3057\u305f\u5e2d", abstained: "\u81ea\u5206\u306e\u62c5\u5f53\u3067\u306f\u306a\u3044\u3068\u3057\u305f\u5e2d",
131
+ stance: "\u30b9\u30bf\u30f3\u30b9", intent: "\u610f\u5411", origin: "\u898b\u89e3\u306e\u751f\u6210\u5143", statement: "\u4eca\u56de\u306e\u767a\u8a00\uff08\u672c\u4eba\u306e\u5f15\u7528\u3067\u306f\u3042\u308a\u307e\u305b\u3093\uff09",
132
+ findings: "\u4e3b\u306a\u6240\u898b", disagreements: "\u5206\u6790\u62c5\u5f53\u3068\u306e\u76f8\u9055", change: "\u5224\u65ad\u304c\u5909\u308f\u308b\u6761\u4ef6", sources: "\u51fa\u5178\u307e\u305f\u306f\u660e\u793a\u7684\u306a\u6b20\u843d",
133
+ abstainLead: (n) => `\u4ed6\u306b ${n} \u5e2d\u306f\u4eca\u56de\u65b9\u5411\u6027\u3092\u793a\u3057\u307e\u305b\u3093\u3002\u3044\u305a\u308c\u3082\u30e1\u30bd\u30c3\u30c9\u306b\u5fc5\u8981\u306a\u5165\u529b\u3092\u6b20\u3044\u3066\u304a\u308a\u3001\u5f31\u6c17\u7968\u3067\u306f\u3042\u308a\u307e\u305b\u3093\uff1a`,
134
+ },
135
+ ko: {
136
+ heading: "\ubc29\ubc95\ub860 \uc88c\uc11d\ubcc4 \ucd9c\ub825", acted: "\ud310\ub2e8\uc744 \ub0b8 \uc88c\uc11d", abstained: "\uc790\uae30 \uc18c\uad00\uc774 \uc544\ub2c8\ub77c\uace0 \ubc1d\ud78c \uc88c\uc11d",
137
+ stance: "\uc785\uc7a5", intent: "\uc758\ud5a5", origin: "\ubc1c\uc5b8 \ucd9c\ucc98", statement: "\uc774\ubc88 \ubc1c\uc5b8(\ubcf8\uc778 \uc778\uc6a9\uc774 \uc544\ub2d8)",
138
+ findings: "\ud575\uc2ec \ubc1c\uacac", disagreements: "\ubd84\uc11d\uac00\uc640\uc758 \uc774\uacac", change: "\ud310\ub2e8 \ubcc0\uacbd \uc870\uac74", sources: "\ucd9c\ucc98 \ub610\ub294 \uba85\uc2dc\uc801 \ub370\uc774\ud130 \uacf5\ubc31",
139
+ abstainLead: (n) => `\uadf8 \uc678 ${n}\uac1c \uc88c\uc11d\uc740 \uc774\ubc88 \ud68c\ucc28\uc5d0 \ubc29\ud5a5\uc744 \uc81c\uc2dc\ud558\uc9c0 \uc54a\uc2b5\ub2c8\ub2e4. \uac01\uac01 \ubc29\ubc95\ub860\uc5d0 \ud544\uc694\ud55c \uc785\ub825\uc774 \uc5c6\uc73c\uba70 \uc57d\uc138 \ud22c\ud45c\uac00 \uc544\ub2d9\ub2c8\ub2e4:`,
140
+ },
141
+ });
142
+
143
+ /**
144
+ * Seats that reached a decision are what a reader came for; seats that could not are context.
145
+ *
146
+ * The previous layout gave both the same weight, so a run where twenty-five seats abstained
147
+ * printed twenty-five near-identical rows and buried the one seat that had a view. Deciding
148
+ * seats now get room to speak and abstaining seats collapse into one readable paragraph.
149
+ * Every selected stable ID still appears in this section: the publication gate checks for
150
+ * exactly that, and it is also the honest requirement -- no seat may quietly vanish.
151
+ */
152
+ function renderMasterStatements(run) {
153
+ const key = languageKey(run?.language);
154
+ const copy = MASTER_STATEMENT_COPY[key] || MASTER_STATEMENT_COPY.en;
155
+ const voiced = (run?.master_opinions || []).filter((opinion) => Boolean(opinion.voice_statement));
156
+ if (!voiced.length) return "";
157
+ const acted = voiced.filter((opinion) => opinion.stance && opinion.stance !== "out_of_scope");
158
+ const abstained = voiced.filter((opinion) => !opinion.stance || opinion.stance === "out_of_scope");
159
+
160
+ const seatBlock = (opinion) => {
161
+ const intent = opinion.position_intent ? intentLabel(opinion.position_intent, run.language) : null;
162
+ const lines = [
163
+ `##### ${masterTitle(opinion.master, run.language)} (\`${opinion.master}\`)`,
164
+ `- ${copy.stance}: ${opinion.stance || "unknown"}${intent ? ` \u2014 ${copy.intent}: *${intent}*` : ""}`,
165
+ `- ${copy.origin}: ${opinion.dedicated_worker?.status || opinion.voice_status || "not_recorded"}`,
166
+ ];
167
+ // The five-field voice reads as prose; a legacy flat statement keeps its single line.
168
+ if (opinion.voice && typeof opinion.voice === "object") {
169
+ for (const field of VOICE_FIELDS) {
170
+ const text = String(opinion.voice[field] ?? "").trim();
171
+ if (text) lines.push(`- **${voiceFieldLabel(field, run.language)}**: ${text}`);
172
+ }
173
+ } else {
174
+ lines.push(`- ${copy.statement}: ${opinion.voice_statement || opinion.verdict || opinion.summary || ""}`);
175
+ }
176
+ lines.push(`- ${copy.findings}: ${(opinion.key_findings || []).slice(0, 4).join("\uFF1B") || "\u2014"}`);
177
+ lines.push(`- ${copy.disagreements}: ${(opinion.disagreements || []).slice(0, 3).join("\uFF1B") || "\u2014"}`);
178
+ lines.push(`- ${copy.change}: ${(opinion.what_would_change_my_mind || []).slice(0, 3).join("\uFF1B") || "\u2014"}`);
179
+ lines.push(`- ${copy.sources}: ${(opinion.source_ids || []).join(", ") || (opinion.disqualifiers_triggered || []).join(", ") || "\u2014"}`);
180
+ return lines.join("\n");
181
+ };
182
+
183
+ const sections = [`### ${copy.heading}`, voiceDisclaimer(run.language)];
184
+ if (acted.length) sections.push(`#### ${copy.acted}`, acted.map(seatBlock).join("\n\n"));
185
+ if (abstained.length) {
186
+ // One paragraph, not one row per seat. The stable IDs stay visible so the gate and the
187
+ // reader can both account for every selected seat without twenty-five identical lines.
188
+ const merged = abstained
189
+ .map((opinion) => `${masterTitle(opinion.master, run.language)} (\`${opinion.master}\`) \u2014 ${opinion.voice_statement}`)
190
+ .join(" ");
191
+ sections.push(`#### ${copy.abstained}`, `${copy.abstainLead(abstained.length)}\n\n${merged}`);
192
+ }
193
+ return sections.join("\n\n");
194
+ }
195
+
95
196
  /**
96
197
  * Printed above every rendered bench, in the report's language.
97
198
  *
@@ -110,19 +211,31 @@ export function masterCorrelationNote(run) {
110
211
  stances.set(key, (stances.get(key) || 0) + 1);
111
212
  }
112
213
  const spread = [...stances.entries()].map(([stance, n]) => `${stance}=${n}`).join(", ");
113
- const zh = isChineseLanguage(run?.language);
114
- return zh
115
- ? [
214
+ const key = languageKey(run?.language);
215
+ return {
216
+ zh: [
116
217
  "> **这些席位不是独立样本。** 它们共享同一个基础模型、同一份证据简报和同一个上下文,",
117
218
  `> 因此错误是相关的。本次立场分布(${spread})**不能当作票数来计算**:一致本身是预期结果,`,
118
219
  "> 不是发现。有信息量的是分歧席位,以及它的分歧来自信息差还是方法差。",
119
220
  ].join("\n")
120
- : [
221
+ ,
222
+ en: [
121
223
  "> **These seats are not independent samples.** They share a base model, an evidence",
122
224
  `> brief and a context window, so their errors are correlated. The stance spread (${spread})`,
123
225
  "> **is not a vote count**: agreement is the expected outcome, not a finding. The",
124
226
  "> informative seat is the dissenting one, and why it dissents.",
125
- ].join("\n");
227
+ ].join("\n"),
228
+ ja: [
229
+ "> **これらの席は独立標本ではありません。** 同じ基盤モデル、証拠要約、コンテキストを共有するため、",
230
+ `> 誤りも相関します。立場の分布(${spread})を**投票数として数えてはいけません**。一致は予想される結果であり、発見ではありません。`,
231
+ "> 情報量が高いのは反対する席と、その相違が情報差か方法差かという点です。",
232
+ ].join("\n"),
233
+ ko: [
234
+ "> **이 좌석들은 독립 표본이 아닙니다.** 동일한 기반 모델, 증거 요약, 컨텍스트를 공유하므로 오류도 상관되어 있습니다.",
235
+ `> 입장 분포(${spread})를 **투표수로 계산하면 안 됩니다**. 일치는 예상되는 결과이지 새로운 발견이 아닙니다.`,
236
+ "> 정보량이 높은 부분은 반대 좌석과 그 차이가 정보 차이인지 방법론 차이인지입니다.",
237
+ ].join("\n"),
238
+ }[key];
126
239
  }
127
240
 
128
241
  /**
@@ -137,7 +250,7 @@ export function masterCorrelationNote(run) {
137
250
  export function renderBenchSummary(run) {
138
251
  const opinions = run?.master_opinions || [];
139
252
  if (!opinions.length) return "";
140
- const zh = isChineseLanguage(run?.language);
253
+ const key = languageKey(run?.language);
141
254
  const counts = new Map();
142
255
  for (const o of opinions) counts.set(o.stance || "unknown", (counts.get(o.stance || "unknown") || 0) + 1);
143
256
  const ranked = [...counts.entries()].sort((a, b) => b[1] - a[1]);
@@ -145,19 +258,24 @@ export function renderBenchSummary(run) {
145
258
  const minority = opinions.filter((o) => (o.stance || "unknown") !== majority);
146
259
  const concurring = opinions.filter((o) => (o.stance || "unknown") === majority);
147
260
 
148
- const row = (o) => `| ${masterTitle(o.master, run?.language)} (\`${o.master}\`) | ${o.stance || "unknown"} | ${o.confidence || "low"} | ${clip(o.verdict || o.summary || "", 90)} |`;
149
- const head = zh
150
- ? ["| 方法 | 立场 | 置信度 | 判断 |", "|---|---|---|---|"]
151
- : ["| Method | Stance | Confidence | Verdict |", "|---|---|---|---|"];
261
+ // The table is the frozen deterministic judgment; the dedicated worker statement is
262
+ // rendered once in the per-seat detail block below. Keeping them separate prevents a
263
+ // fluent explanation from being mistaken for, or duplicating, the frozen method result.
264
+ const row = (o) => `| ${masterTitle(o.master, run?.language)} (\`${o.master}\`) | ${o.stance || "unknown"} | ${o.confidence || "low"} | ${clip(o.verdict || o.deterministic_summary || o.summary || o.voice_statement || "", 140)} |`;
265
+ const copy = {
266
+ zh: { head: ["| 方法 | 立场 | 置信度 | 判断 |", "|---|---|---|---|"], minority: "### 少数派(先读这个)", minorityNone: "### 少数派:无\n\n所有席位立场一致。鉴于它们共享模型与证据,一致是预期结果而非确认——本轮没有产生任何独立的反对意见。", divergence: `${minority.length} 席与多数不同。分歧席位是本轮信息量最高的部分——请先判断分歧来自信息差还是方法差。`, rest: "### 其余席位" },
267
+ en: { head: ["| Method | Stance | Confidence | Verdict |", "|---|---|---|---|"], minority: "### Minority report (read this first)", minorityNone: "### Minority report: none\n\nEvery seat agreed. Given a shared model and a shared brief, agreement is the expected outcome rather than confirmation: this run produced no independent dissent.", divergence: `${minority.length} seat(s) diverge. Divergence is the highest-information part of this run: establish whether it comes from the evidence slice or from the method.`, rest: "### Concurring seats" },
268
+ ja: { head: ["| メソッド | スタンス | 信頼度 | 判定 |", "|---|---|---|---|"], minority: "### 少数意見(最初に読む)", minorityNone: "### 少数意見:なし\n\n全席が一致しました。同じモデルと証拠を共有するため、一致は確認ではなく予想される結果です。本輪では独立した反対意見が出ませんでした。", divergence: `${minority.length}席が多数と異なります。最も情報量が高い部分なので、相違が証拠範囲と方法のどちらに由来するか確認してください。`, rest: "### その他の席" },
269
+ ko: { head: ["| 방법론 | 입장 | 신뢰도 | 판단 |", "|---|---|---|---|"], minority: "### 소수 의견(먼저 확인)", minorityNone: "### 소수 의견: 없음\n\n모든 좌석이 일치했습니다. 동일한 모델과 증거를 공유하므로 일치는 확인이 아니라 예상되는 결과입니다. 이번 실행에는 독립적인 반대 의견이 없었습니다.", divergence: `${minority.length}개 좌석이 다수와 다릅니다. 가장 정보량이 높은 부분이므로 차이가 증거 범위와 방법론 중 어디에서 비롯됐는지 확인하십시오.`, rest: "### 나머지 좌석" },
270
+ }[key];
271
+ const head = copy.head;
152
272
 
153
273
  const sections = [masterCorrelationNote(run), ""];
154
274
  if (minority.length) {
155
275
  sections.push(
156
- zh ? "### 少数派(先读这个)" : "### Minority report (read this first)",
276
+ copy.minority,
157
277
  "",
158
- zh
159
- ? `${minority.length} 席与多数不同。分歧席位是本次运行里信息量最高的部分——请先判断分歧来自信息差还是方法差。`
160
- : `${minority.length} seat(s) diverge. Divergence is the highest-information part of this run: establish whether it comes from the evidence slice or from the method.`,
278
+ copy.divergence,
161
279
  "",
162
280
  ...head,
163
281
  ...minority.map(row),
@@ -165,14 +283,12 @@ export function renderBenchSummary(run) {
165
283
  );
166
284
  } else {
167
285
  sections.push(
168
- zh
169
- ? "### 少数派:无\n\n所有席位立场一致。鉴于它们共享模型与证据,一致是预期结果而非确认——本次运行没有产生任何独立的反对意见。"
170
- : "### Minority report: none\n\nEvery seat agreed. Given a shared model and a shared brief, agreement is the expected outcome rather than confirmation: this run produced no independent dissent.",
286
+ copy.minorityNone,
171
287
  "",
172
288
  );
173
289
  }
174
290
  sections.push(
175
- zh ? "### 其余席位" : "### Concurring seats",
291
+ copy.rest,
176
292
  "",
177
293
  ...head,
178
294
  ...concurring.map(row),
@@ -211,92 +327,133 @@ export function renderDecisionTable(decisions, lang) {
211
327
  }
212
328
 
213
329
  /** Registry title when the persona resolves, the raw id when it does not. */
330
+ /**
331
+ * Maturity vocabulary belongs in metadata, not in a heading a reader has to parse.
332
+ *
333
+ * `admitted_label` carries the governance suffix ("... Provisional Operator Lens") so that an
334
+ * internal artifact can never be mistaken for a validated method model. A reader scanning a
335
+ * report does not need that phrase repeated on all twenty-six headings; the section already
336
+ * carries a disclaimer and the admission level travels with the pack. Strip it for display
337
+ * only -- the label itself, and every hash over it, is untouched.
338
+ */
339
+ const MATURITY_SUFFIX = /[\s\u3000]*(provisional operator lens|\u4e34\u65f6\u64cd\u4f5c\u89c6\u89d2|\u66ab\u5b9a\u30aa\u30da\u30ec\u30fc\u30bf\u30fc\u30ec\u30f3\u30ba|\uc784\uc2dc \uc624\ud37c\ub808\uc774\ud130 \ub80c\uc988)[\s\u3000]*$/iu;
340
+
341
+ export function displayMasterLabel(label) {
342
+ const text = String(label || "").trim();
343
+ const stripped = text.replace(MATURITY_SUFFIX, "").trim();
344
+ return stripped || text;
345
+ }
346
+
214
347
  function masterTitle(id, lang) {
215
348
  if (!id) return "Master";
216
349
  try {
350
+ const v3 = compiledPersonaPacks().get(id);
351
+ const v3Title = v3?.admitted_label?.[languageKey(lang)];
352
+ if (v3Title) return displayMasterLabel(v3Title);
217
353
  const persona = registry().get(id);
218
354
  const title = personaTitle(persona, lang);
219
- return title && title !== id ? `${title} (${id})` : id;
355
+ return title && title !== id ? title : id;
220
356
  } catch {
221
357
  return id;
222
358
  }
223
359
  }
224
360
 
225
- export function renderDebateRounds(rounds) {
361
+ export function renderDebateRounds(rounds, language = "English") {
226
362
  if (!Array.isArray(rounds) || rounds.length === 0) return "";
363
+ const key = languageKey(language);
364
+ const label = {
365
+ zh: { round: "轮次", long: "多头论据", short: "空头论据", questions: "提出的问题", answered: "逐题回答", raw: "原始 worker 响应(仅供审计)", title: "辩论轮次" },
366
+ en: { round: "Round", long: "Long Thesis", short: "Short Thesis", questions: "Questions", answered: "Questions Answered", raw: "Raw Worker Response (audit only)", title: "Debate Rounds" },
367
+ ja: { round: "ラウンド", long: "強気論拠", short: "弱気論拠", questions: "質問", answered: "質問への回答", raw: "ワーカーの生応答(監査専用)", title: "討論ラウンド" },
368
+ ko: { round: "라운드", long: "강세 논거", short: "약세 논거", questions: "질문", answered: "질문별 답변", raw: "원본 워커 응답(감사 전용)", title: "토론 라운드" },
369
+ }[key];
227
370
  const blocks = rounds.map((round) => [
228
- `#### Round ${round.round}`,
371
+ `#### ${label.round} ${round.round}`,
229
372
  "",
230
373
  round.summary || "",
231
374
  "",
232
- "##### Long Thesis",
375
+ `##### ${label.long}`,
233
376
  bullets(round.long_thesis),
234
377
  "",
235
- "##### Short Thesis",
378
+ `##### ${label.short}`,
236
379
  bullets(round.short_thesis),
237
380
  "",
238
- "##### Questions",
381
+ `##### ${label.questions}`,
239
382
  bullets(round.questions),
240
383
  "",
241
- "##### Questions Answered",
384
+ `##### ${label.answered}`,
242
385
  bullets(round.questions_answered),
243
386
  "",
244
- "##### Raw Output / Prompt",
387
+ `##### ${label.raw}`,
245
388
  fence(round.raw_text || "", "text"),
246
389
  ].join("\n"));
247
- return ["### Debate Rounds", "", ...blocks].join("\n\n");
390
+ return [`### ${label.title}`, "", ...blocks].join("\n\n");
248
391
  }
249
392
 
250
- export function renderDebateMarkdown(agent) {
393
+ export function renderDebateMarkdown(agent, language = agent?.language) {
251
394
  if (!agent) return "";
395
+ const key = languageKey(language);
396
+ const label = {
397
+ zh: { rating: "评级", winner: "胜方", verdict: "判断", confidence: "置信度", summary: "摘要", long: "多头论据", short: "空头论据", valuation: "估值区间", catalysts: "催化剂", risks: "风险", position: "仓位", invalidation: "失效条件", sources: "来源 ID", report: "报告正文", raw: "原始 worker 响应(仅供审计)", none: "无" },
398
+ en: { rating: "Rating", winner: "Winner", verdict: "Verdict", confidence: "Confidence", summary: "Summary", long: "Long Thesis", short: "Short Thesis", valuation: "Valuation Range", catalysts: "Catalysts", risks: "Risks", position: "Position", invalidation: "Invalidation", sources: "Source IDs", report: "Report Markdown", raw: "Raw Worker Response (audit only)", none: "None" },
399
+ ja: { rating: "評価", winner: "優勢側", verdict: "判断", confidence: "信頼度", summary: "要約", long: "強気論拠", short: "弱気論拠", valuation: "評価レンジ", catalysts: "カタリスト", risks: "リスク", position: "ポジション", invalidation: "無効化条件", sources: "出典 ID", report: "レポート本文", raw: "ワーカーの生応答(監査専用)", none: "なし" },
400
+ ko: { rating: "등급", winner: "우세 측", verdict: "판단", confidence: "신뢰도", summary: "요약", long: "강세 논거", short: "약세 논거", valuation: "가치평가 범위", catalysts: "촉매", risks: "위험", position: "포지션", invalidation: "무효화 조건", sources: "출처 ID", report: "보고서 본문", raw: "원본 워커 응답(감사 전용)", none: "없음" },
401
+ }[key];
252
402
  return [
253
403
  `## ${agent.role}`,
254
404
  "",
255
- `- Rating: ${agent.rating}`,
256
- `- Winner: ${agent.winner}`,
257
- `- Verdict: ${agent.verdict}`,
258
- `- Confidence: ${agent.confidence}`,
405
+ `- ${label.rating}: ${agent.rating}`,
406
+ `- ${label.winner}: ${agent.winner}`,
407
+ `- ${label.verdict}: ${agent.verdict}`,
408
+ `- ${label.confidence}: ${agent.confidence}`,
259
409
  agent.thread_id ? `- Visible thread ID: ${agent.thread_id}` : "",
260
410
  agent.thread_title ? `- Visible thread title: ${agent.thread_title}` : "",
261
411
  "",
262
- "### Summary",
412
+ `### ${label.summary}`,
263
413
  agent.summary || "",
264
414
  "",
265
- "### Long Thesis",
415
+ `### ${label.long}`,
266
416
  bullets(agent.long_thesis),
267
417
  "",
268
- "### Short Thesis",
418
+ `### ${label.short}`,
269
419
  bullets(agent.short_thesis),
270
420
  "",
271
- "### Valuation Range",
272
- agent.valuation_range || "None",
421
+ `### ${label.valuation}`,
422
+ agent.valuation_range || label.none,
273
423
  "",
274
- "### Catalysts",
424
+ `### ${label.catalysts}`,
275
425
  bullets(agent.catalysts),
276
426
  "",
277
- "### Risks",
427
+ `### ${label.risks}`,
278
428
  bullets(agent.risks),
279
429
  "",
280
- "### Position",
281
- agent.position || "None",
430
+ `### ${label.position}`,
431
+ agent.position || label.none,
282
432
  "",
283
- "### Invalidation",
433
+ `### ${label.invalidation}`,
284
434
  bullets(agent.invalidation),
285
435
  "",
286
- "### Source IDs",
436
+ `### ${label.sources}`,
287
437
  bullets(agent.source_ids),
288
438
  "",
289
- "### Report Markdown",
439
+ `### ${label.report}`,
290
440
  agent.report_markdown || "",
291
441
  "",
292
- renderDebateRounds(agent.debate_rounds),
293
- "### Raw Output / Prompt",
442
+ renderDebateRounds(agent.debate_rounds, language),
443
+ `### ${label.raw}`,
294
444
  fence(agent.raw_text || "", "text"),
295
445
  ].filter(Boolean).join("\n");
296
446
  }
297
447
 
298
448
  export function writeAllAgentsMarkdown(run, debate = {}) {
299
449
  const dir = runPath(run.run_id);
450
+ const key = languageKey(run.language);
451
+ const label = {
452
+ zh: { title: "全部代理审计追踪", metadata: "运行元数据", runId: "运行 ID", symbol: "代码", asOf: "截至", language: "语言", execution: "执行模式", visibility: "要求可见", dry: "演练", status: "状态", phase: "阶段", started: "开始", updated: "更新", completed: "完成", tasks: "任务", taskStatus: "证据席状态", debateStatus: "辩论席状态", evidence: "证据分析子代理", masters: "方法席", debate: "多空辩论与组合经理", none: "无" },
453
+ en: { title: "Full Agent Audit Trace", metadata: "Run Metadata", runId: "Run ID", symbol: "Symbol", asOf: "As-of", language: "Language", execution: "Execution mode", visibility: "Visibility required", dry: "Dry run", status: "Status", phase: "Phase", started: "Started", updated: "Updated", completed: "Completed", tasks: "Tasks", taskStatus: "Evidence-Seat Status", debateStatus: "Debate-Seat Status", evidence: "Evidence Analyst Subagents", masters: "Method-Seat Bench", debate: "Bull/Bear Debate and Portfolio Manager", none: "None" },
454
+ ja: { title: "全エージェント監査トレース", metadata: "実行メタデータ", runId: "実行 ID", symbol: "銘柄コード", asOf: "基準日", language: "言語", execution: "実行モード", visibility: "可視性要件", dry: "ドライラン", status: "状態", phase: "フェーズ", started: "開始", updated: "更新", completed: "完了", tasks: "タスク", taskStatus: "証拠席の状態", debateStatus: "討論席の状態", evidence: "証拠分析サブエージェント", masters: "メソッド席", debate: "強気・弱気討論とポートフォリオ管理者", none: "なし" },
455
+ ko: { title: "전체 에이전트 감사 추적", metadata: "실행 메타데이터", runId: "실행 ID", symbol: "종목 코드", asOf: "기준일", language: "언어", execution: "실행 모드", visibility: "가시성 요구", dry: "드라이런", status: "상태", phase: "단계", started: "시작", updated: "갱신", completed: "완료", tasks: "작업", taskStatus: "증거 좌석 상태", debateStatus: "토론 좌석 상태", evidence: "증거 분석 하위 에이전트", masters: "방법론 좌석", debate: "강세·약세 토론 및 포트폴리오 관리자", none: "없음" },
456
+ }[key];
300
457
  const taskStatus = run.tasks.map((task) => {
301
458
  const state = taskState(run, task);
302
459
  return `- ${task}: ${state.status}${state.output ? ` (${state.output})` : ""}${state.error ? ` - ${state.error}` : ""}`;
@@ -306,41 +463,41 @@ export function writeAllAgentsMarkdown(run, debate = {}) {
306
463
  return `- ${role}: ${state.status}${state.output ? ` (${state.output})` : ""}${state.error ? ` - ${state.error}` : ""}`;
307
464
  }).join("\n");
308
465
  const sections = [
309
- `# AlphaCouncil Agent Full Agent Trace: ${run.symbol}`,
466
+ `# AlphaCouncil Agent ${label.title}: ${run.symbol}`,
310
467
  "",
311
- "## Run Metadata",
468
+ `## ${label.metadata}`,
312
469
  "",
313
- `- Run ID: ${run.run_id}`,
314
- `- Symbol: ${run.symbol}`,
315
- `- As-of: ${run.as_of}`,
316
- `- Language: ${run.language || "auto"}`,
317
- `- Execution mode: ${run.execution_mode || "background_codex_exec"}`,
318
- `- Visibility required: ${run.visibility_required || false}`,
319
- `- Dry run: ${run.dry_run}`,
320
- `- Status: ${run.status || "unknown"}`,
321
- `- Phase: ${run.phase || "unknown"}`,
322
- `- Started: ${run.started_at}`,
323
- `- Updated: ${run.updated_at || ""}`,
324
- `- Completed: ${run.completed_at || ""}`,
325
- `- Tasks: ${run.tasks.join(", ")}`,
470
+ `- ${label.runId}: ${run.run_id}`,
471
+ `- ${label.symbol}: ${run.symbol}`,
472
+ `- ${label.asOf}: ${run.as_of}`,
473
+ `- ${label.language}: ${run.language || "auto"}`,
474
+ `- ${label.execution}: ${run.execution_mode || "background_codex_exec"}`,
475
+ `- ${label.visibility}: ${run.visibility_required || false}`,
476
+ `- ${label.dry}: ${run.dry_run}`,
477
+ `- ${label.status}: ${run.status || "unknown"}`,
478
+ `- ${label.phase}: ${run.phase || "unknown"}`,
479
+ `- ${label.started}: ${run.started_at}`,
480
+ `- ${label.updated}: ${run.updated_at || ""}`,
481
+ `- ${label.completed}: ${run.completed_at || ""}`,
482
+ `- ${label.tasks}: ${run.tasks.join(", ")}`,
326
483
  "",
327
- "## Task Status",
484
+ `## ${label.taskStatus}`,
328
485
  "",
329
- taskStatus || "- None",
486
+ taskStatus || `- ${label.none}`,
330
487
  "",
331
- "## Analyst Status",
488
+ `## ${label.debateStatus}`,
332
489
  "",
333
- agentStatus || "- None",
490
+ agentStatus || `- ${label.none}`,
334
491
  "",
335
- "# Evidence Subagents",
492
+ `# ${label.evidence}`,
336
493
  "",
337
- ...run.packets.map(renderPacketMarkdown),
494
+ ...run.packets.map((packet, index) => renderPacketMarkdown(packet, index, run.language)),
338
495
  ];
339
496
  const opinions = run.master_opinions || [];
340
497
  if (opinions.length) {
341
498
  sections.push(
342
499
  "",
343
- "# Master Bench",
500
+ `# ${label.masters}`,
344
501
  "",
345
502
  renderBenchSummary(run),
346
503
  "",
@@ -350,13 +507,13 @@ export function writeAllAgentsMarkdown(run, debate = {}) {
350
507
  if (debate.bull || debate.bear || debate.manager) {
351
508
  sections.push(
352
509
  "",
353
- "# Analyst Debate And Portfolio Manager",
510
+ `# ${label.debate}`,
354
511
  "",
355
- renderDebateMarkdown(debate.bull),
512
+ renderDebateMarkdown(debate.bull, run.language),
356
513
  "",
357
- renderDebateMarkdown(debate.bear),
514
+ renderDebateMarkdown(debate.bear, run.language),
358
515
  "",
359
- renderDebateMarkdown(debate.manager),
516
+ renderDebateMarkdown(debate.manager, run.language),
360
517
  );
361
518
  }
362
519
  const path = join(dir, "all_agents.md");
@@ -367,7 +524,7 @@ export function writeAllAgentsMarkdown(run, debate = {}) {
367
524
  export function writeAnalystMarkdownFiles(run, debate = {}) {
368
525
  const dir = runPath(run.run_id);
369
526
  for (const [index, packet] of (run.packets || []).entries()) {
370
- writeFileSync(join(dir, `${packet.task}.md`), `${renderPacketMarkdown(packet, index)}\n`);
527
+ writeFileSync(join(dir, `${packet.task}.md`), `${renderPacketMarkdown(packet, index, run.language)}\n`);
371
528
  }
372
529
  const debateFiles = [
373
530
  ["bull_researcher", debate.bull],
@@ -375,7 +532,7 @@ export function writeAnalystMarkdownFiles(run, debate = {}) {
375
532
  ["portfolio_manager", debate.manager],
376
533
  ];
377
534
  for (const [role, packet] of debateFiles) {
378
- if (packet) writeFileSync(join(dir, `${role}.md`), `${renderDebateMarkdown({ ...packet, role })}\n`);
535
+ if (packet) writeFileSync(join(dir, `${role}.md`), `${renderDebateMarkdown({ ...packet, role }, run.language)}\n`);
379
536
  }
380
537
  for (const opinion of run.master_opinions || []) {
381
538
  writeFileSync(join(dir, `${opinion.master}.md`), `${renderMasterMarkdown(opinion, run.language)}\n`);
@@ -389,7 +546,8 @@ export function writeReportQuality(run, markdown) {
389
546
  return quality;
390
547
  }
391
548
 
392
- const RECORDED_BENCH_MARKER_PREFIX = "alphacouncil:recorded-master-bench:v1:";
549
+ // Shared with the quality gate through constants so the gate can find the system-owned
550
+ // section by anchor instead of by heading text. See the note next to the constants.
393
551
 
394
552
  function recordedBenchMarker(run) {
395
553
  const subject = (run?.master_opinions || []).map((opinion) => ({
@@ -398,6 +556,8 @@ function recordedBenchMarker(run) {
398
556
  stance: String(opinion?.stance || "unknown"),
399
557
  summary: String(opinion?.summary || ""),
400
558
  verdict: String(opinion?.verdict || ""),
559
+ voice_statement: String(opinion?.voice_statement || ""),
560
+ voice_status: String(opinion?.voice_status || ""),
401
561
  }));
402
562
  return `<!-- ${RECORDED_BENCH_MARKER_PREFIX}${sha256(subject)} -->`;
403
563
  }
@@ -408,6 +568,91 @@ function isMasterBenchHeading(title) {
408
568
  return Boolean(normalized && section?.aliases.some((alias) => headingIncludesAlias(title, alias)));
409
569
  }
410
570
 
571
+ function isInstrumentStructureHeading(title) {
572
+ const normalized = normalizeHeading(title);
573
+ const section = REPORT_SECTIONS.find(({ id }) => id === "instrument_structure");
574
+ return Boolean(normalized && section?.aliases.some((alias) => headingIncludesAlias(title, alias)));
575
+ }
576
+
577
+ /**
578
+ * Own the ETF/index structure section at the deterministic system boundary.
579
+ *
580
+ * PM prose may discuss a fund, but it cannot turn a fund into an operating company. The
581
+ * classifier owns the research route and any PM-authored section is retained as commentary.
582
+ */
583
+ function withRecordedInstrumentStructure(run, markdown) {
584
+ const instrument = run?.grounding?.instrument;
585
+ if (!isFundOrIndex(instrument)) return String(markdown || "");
586
+ const body = String(markdown || "");
587
+ const lines = body.split(/\r?\n/);
588
+ const headings = parseHeadings(body);
589
+ const removals = [];
590
+ const commentaryTitle = localized(run.language, {
591
+ zh: "PM 对资产研究路径的叙述(非系统记录)",
592
+ en: "PM Commentary on the Instrument Research Path (non-authoritative)",
593
+ ja: "PMによる銘柄調査経路の説明(非公式記録)",
594
+ ko: "PM의 종목 조사 경로 설명(비공식 기록)",
595
+ });
596
+ for (const [index, heading] of headings.entries()) {
597
+ if (heading.level > 2 || !isInstrumentStructureHeading(heading.title)) continue;
598
+ const next = headings.slice(index + 1).find((candidate) => candidate.level <= heading.level);
599
+ const start = heading.line - 1;
600
+ const end = next ? next.line - 1 : lines.length;
601
+ if (heading.body.includes(`<!-- ${RECORDED_INSTRUMENT_MARKER_PREFIX}`)) removals.push([start, end]);
602
+ else lines[start] = `${"#".repeat(heading.level)} ${commentaryTitle}`;
603
+ }
604
+ for (const [start, end] of removals.sort((left, right) => right[0] - left[0])) {
605
+ lines.splice(start, end - start);
606
+ }
607
+
608
+ const copy = {
609
+ zh: {
610
+ heading: "## 基金与指数结构", asset: "资产类型", model: "研究模型", source: "分类依据", raw: "数据源原始类型", company: "经营公司财务路径", noCompany: "不适用;不得把基金或指数当作经营公司读取营收、公司 EPS、管理层指引或 Form 4", required: "强制研究项目", requirements: instrument.index_like
611
+ ? "指数方法、带时点的成分与权重、集中度、行业/因子暴露、广度、再平衡、聚合盈利与估值口径、宏观敏感度,以及可用的衍生品定位"
612
+ : "跟踪指数与方法、带时点的持仓和权重、前十大及行业集中度、费用率、规模、流动性、溢折价或跟踪差、资金流、借贷/衍生品、再平衡、税务结构与持仓穿透基本面",
613
+ aggregation: "聚合纪律", aggregationRule: "必须披露同日口径和覆盖权重;不得把少数成分股相加成基金或指数自身的营收、EPS或现金流", notApplicable: "明确不适用项",
614
+ },
615
+ en: {
616
+ heading: "## Fund and Index Structure", asset: "Asset type", model: "Research model", source: "Classification source", raw: "Raw feed type", company: "Operating-company financial route", noCompany: "not applicable; do not treat a fund or index as a company with its own revenue, company EPS, management guidance or Form 4 activity", required: "Required research", requirements: instrument.index_like
617
+ ? "index methodology, dated constituents and weights, concentration, sector/factor exposures, breadth, rebalances, aggregate earnings and valuation methodology, macro sensitivity, and listed-derivative positioning when available"
618
+ : "tracked index and methodology, dated holdings and weights, top-ten and sector concentration, fee, AUM, liquidity, premium/discount or tracking difference, flows, lending/derivatives, rebalances, tax structure, and holdings-level fundamental look-through",
619
+ aggregation: "Aggregation discipline", aggregationRule: "state one-date methodology and coverage weight; never add a few constituents into fund or index revenue, EPS, or cash flow", notApplicable: "Explicitly not applicable",
620
+ },
621
+ ja: {
622
+ heading: "## ファンドと指数の構造", asset: "資産タイプ", model: "調査モデル", source: "分類根拠", raw: "データ源の原分類", company: "事業会社の財務経路", noCompany: "適用外。ファンドや指数を、固有の売上高・企業EPS・経営陣ガイダンス・Form 4を持つ事業会社として扱わない", required: "必須調査項目", requirements: instrument.index_like
623
+ ? "指数算出方法、基準日付き構成銘柄とウェイト、集中度、業種・ファクター、ブレッドス、リバランス、集計利益・評価方法、マクロ感応度、利用可能なデリバティブ需給"
624
+ : "連動指数と方法、基準日付き保有銘柄とウェイト、上位10銘柄・業種集中度、経費率、純資産、流動性、乖離・トラッキング差、資金フロー、貸株・デリバティブ、リバランス、税制、保有銘柄ルックスルー",
625
+ aggregation: "集計規律", aggregationRule: "同一基準日の方法とカバーウェイトを明記し、一部構成銘柄を足してファンド・指数固有の売上高、EPS、CFにしない", notApplicable: "明示的な適用外項目",
626
+ },
627
+ ko: {
628
+ heading: "## 펀드와 지수 구조", asset: "자산 유형", model: "조사 모델", source: "분류 근거", raw: "데이터 소스 원본 유형", company: "영업회사 재무 경로", noCompany: "적용되지 않음. 펀드나 지수를 자체 매출, 기업 EPS, 경영진 가이던스 또는 Form 4가 있는 영업회사로 취급하지 않음", required: "필수 조사 항목", requirements: instrument.index_like
629
+ ? "지수 방법론, 기준일이 있는 구성 종목과 비중, 집중도, 섹터·팩터 노출, 시장 폭, 리밸런싱, 집계 이익·밸류에이션 방법, 거시 민감도 및 가능한 파생상품 포지셔닝"
630
+ : "추종 지수와 방법론, 기준일이 있는 보유 종목과 비중, 상위 10개·섹터 집중도, 보수, AUM, 유동성, 괴리율·추적 차이, 자금 흐름, 대차·파생상품, 리밸런싱, 세금 구조 및 보유 종목 룩스루",
631
+ aggregation: "집계 원칙", aggregationRule: "동일 기준일 방법론과 커버 비중을 밝히며 일부 구성 종목을 더해 펀드·지수 자체 매출, EPS 또는 현금흐름으로 만들지 않음", notApplicable: "명시적 적용 제외",
632
+ },
633
+ }[languageKey(run.language)];
634
+ const notApplicable = (run?.grounding?.not_applicable || []).length
635
+ ? run.grounding.not_applicable.map((item) => ` - ${item}`).join("\n")
636
+ : " - —";
637
+ const marker = `<!-- ${RECORDED_INSTRUMENT_MARKER_PREFIX}${sha256({ instrument, not_applicable: run?.grounding?.not_applicable || [] })} -->`;
638
+ const systemSection = [
639
+ copy.heading,
640
+ "",
641
+ marker,
642
+ `- ${copy.asset}: ${instrument.asset_type}`,
643
+ `- ${copy.model}: ${instrument.research_model}`,
644
+ `- ${copy.source}: ${instrument.classification_source}`,
645
+ `- ${copy.raw}: ${instrument.raw_instrument_type || "unknown"}`,
646
+ `- ${copy.company}: ${copy.noCompany}`,
647
+ `- ${copy.required}: ${copy.requirements}`,
648
+ `- ${copy.aggregation}: ${copy.aggregationRule}`,
649
+ `- ${copy.notApplicable}:`,
650
+ notApplicable,
651
+ ].join("\n");
652
+ const cleaned = lines.join("\n").trimEnd();
653
+ return `${cleaned ? `${cleaned}\n\n` : ""}${systemSection}\n`;
654
+ }
655
+
411
656
  /**
412
657
  * Make the recorded Master Bench a system-owned section.
413
658
  *
@@ -422,12 +667,18 @@ function withRecordedMasterBench(run, markdown) {
422
667
  const lines = body.split(/\r?\n/);
423
668
  const headings = parseHeadings(body);
424
669
  const removals = [];
425
- const commentaryTitle = isChineseLanguage(run.language)
426
- ? "PM 对方法席位的叙述(非系统记录)"
427
- : "PM Commentary on Method Seats (non-authoritative)";
670
+ const commentaryTitle = localized(run.language, {
671
+ zh: "PM 对方法席位的叙述(非系统记录)",
672
+ en: "PM Commentary on Method Seats (non-authoritative)",
673
+ ja: "PMによるメソッド席の説明(非公式記録)",
674
+ ko: "PM의 방법론 좌석 설명(비공식 기록)",
675
+ });
428
676
 
429
677
  for (const [index, heading] of headings.entries()) {
430
- if (!isMasterBenchHeading(heading.title)) continue;
678
+ // Only a publication section can own the bench. Localized per-seat subheadings such as
679
+ // Japanese "メソッド席" may contain a bench alias, but they are level 3+ details and
680
+ // must not be scheduled for a second overlapping removal during idempotent assembly.
681
+ if (heading.level > 2 || !isMasterBenchHeading(heading.title)) continue;
431
682
  const next = headings.slice(index + 1).find((candidate) => candidate.level <= heading.level);
432
683
  const start = heading.line - 1;
433
684
  const end = next ? next.line - 1 : lines.length;
@@ -442,11 +693,52 @@ function withRecordedMasterBench(run, markdown) {
442
693
  lines.splice(start, end - start);
443
694
  }
444
695
  const cleaned = lines.join("\n").trimEnd();
445
- const heading = isChineseLanguage(run.language) ? "## 大师席位 / Master Bench" : "## Master Bench";
446
- const systemBench = `${heading}\n\n${recordedBenchMarker(run)}\n\n${renderBenchSummary(run)}`;
696
+ const heading = localized(run.language, {
697
+ zh: "## 大师席位",
698
+ en: "## Master Bench",
699
+ ja: "## マスター・ベンチ",
700
+ ko: "## 마스터 벤치",
701
+ });
702
+ const systemBench = `${heading}\n\n${recordedBenchMarker(run)}\n\n${renderBenchSummary(run)}\n\n${renderMasterStatements(run)}`;
447
703
  return `${cleaned ? `${cleaned}\n\n` : ""}${systemBench}\n`;
448
704
  }
449
705
 
706
+ function withRecordedPriceSnapshot(run, markdown) {
707
+ const markerStart = "<!-- alphacouncil:recorded-price-snapshot:v1:begin -->";
708
+ const markerEnd = "<!-- alphacouncil:recorded-price-snapshot:v1:end -->";
709
+ let cleaned = String(markdown || "");
710
+ let start = cleaned.indexOf(markerStart);
711
+ while (start !== -1) {
712
+ const end = cleaned.indexOf(markerEnd, start + markerStart.length);
713
+ cleaned = end === -1
714
+ ? cleaned.slice(0, start)
715
+ : `${cleaned.slice(0, start)}${cleaned.slice(end + markerEnd.length)}`;
716
+ start = cleaned.indexOf(markerStart);
717
+ }
718
+ const quote = run?.grounding?.quote;
719
+ const key = languageKey(run?.language);
720
+ const heading = { zh: "## 系统记录价格快照", en: "## System-Recorded Price Snapshot", ja: "## システム記録価格スナップショット", ko: "## 시스템 기록 가격 스냅샷" }[key];
721
+ const unavailable = { zh: "本轮未取得可验证报价;不得补造价格。", en: "No verifiable quote was retrieved; no price was invented.", ja: "検証可能な価格を取得できなかったため、価格は補完していません。", ko: "검증 가능한 시세를 가져오지 못했으며 가격을 임의로 만들지 않았습니다." }[key];
722
+ const label = {
723
+ zh: { symbol: "代码", price: "价格", change: "涨跌", time: "报价时间", exchange: "交易所", feed: "数据源", source: "原始链接", unknown: "未知", unavailable: "不可用", delayed: "延迟数据" },
724
+ en: { symbol: "Symbol", price: "Price", change: "Change", time: "Quote time", exchange: "Exchange", feed: "Feed", source: "Source", unknown: "unknown", unavailable: "unavailable", delayed: "delayed data" },
725
+ ja: { symbol: "銘柄コード", price: "価格", change: "騰落", time: "価格時刻", exchange: "取引所", feed: "データ源", source: "原典リンク", unknown: "不明", unavailable: "取得不可", delayed: "遅延データ" },
726
+ ko: { symbol: "종목 코드", price: "가격", change: "등락", time: "시세 시각", exchange: "거래소", feed: "데이터 소스", source: "원문 링크", unknown: "알 수 없음", unavailable: "확인 불가", delayed: "지연 데이터" },
727
+ }[key];
728
+ const body = quote && Number.isFinite(Number(quote.price))
729
+ ? [
730
+ `- ${label.symbol}: ${quote.symbol || run.symbol}`,
731
+ `- ${label.price}: ${quote.price} ${quote.currency || ""}`.trimEnd(),
732
+ `- ${label.change}: ${quote.change ?? label.unavailable} (${quote.change_pct ?? label.unavailable}%)`,
733
+ `- ${label.time}: ${quote.quote_time || label.unknown}`,
734
+ `- ${label.exchange}: ${quote.exchange || label.unknown}`,
735
+ `- ${label.feed}: ${quote.source || label.unknown}; ${quote.note || label.delayed}`,
736
+ `- ${label.source}: ${quote.source_url || label.unavailable}`,
737
+ ].join("\n")
738
+ : `- ${unavailable}`;
739
+ return `${cleaned.trimEnd()}\n\n${markerStart}\n${heading}\n\n${body}\n${markerEnd}\n`;
740
+ }
741
+
450
742
  function withDegradedLedger(run, markdown, completeness) {
451
743
  const markerStart = "<!-- alphacouncil:degraded-ledger:v1:begin -->";
452
744
  const markerEnd = "<!-- alphacouncil:degraded-ledger:v1:end -->";
@@ -462,20 +754,27 @@ function withDegradedLedger(run, markdown, completeness) {
462
754
  const tasks = completeness.degraded_evidence || [];
463
755
  const roles = completeness.degraded_debate || [];
464
756
  if (!tasks.length && !roles.length) return cleaned;
465
- const chinese = isChineseLanguage(run.language);
757
+ const key = languageKey(run.language);
758
+ const unavailable = { zh: "证据不可用", en: "evidence unavailable", ja: "証拠を取得できません", ko: "증거를 확보하지 못함" }[key];
759
+ const debateUnavailable = { zh: "辩论席不可用", en: "debate seat unavailable", ja: "討論席を利用できません", ko: "토론 좌석을 사용할 수 없음" }[key];
760
+ const deadlineText = { zh: "全局时限耗尽", en: "global deadline exhausted", ja: "全体期限を超過", ko: "전체 기한 소진" }[key];
466
761
  const rows = [
467
762
  ...tasks.map((task) => {
468
763
  const state = taskState(run, task);
469
- return `- ${task}: ${state.status}; ${state.error || (chinese ? "证据不可用" : "evidence unavailable")}${state.deadline_exhausted ? "; global deadline exhausted" : ""}`;
764
+ return `- ${task}: ${state.status}; ${state.error || unavailable}${state.deadline_exhausted ? `; ${deadlineText}` : ""}`;
470
765
  }),
471
766
  ...roles.map((role) => {
472
767
  const state = agentState(run, role);
473
- return `- ${role}: ${state.status}; ${state.error || (chinese ? "辩论席不可用" : "debate seat unavailable")}`;
768
+ return `- ${role}: ${state.status}; ${state.error || debateUnavailable}`;
474
769
  }),
475
770
  ].join("\n");
476
- const banner = chinese
477
- ? `> [!WARNING]\n> **DEGRADED QUICK RUN — 部分席位失败。** 报告结构可能通过质量检查,但以下席位没有提供可用证据,不能把本轮当作完整覆盖:\n>\n${rows.split("\n").map((line) => `> ${line}`).join("\n")}`
478
- : `> [!WARNING]\n> **DEGRADED QUICK RUN — one or more seats failed.** The report structure may pass quality checks, but the following seats supplied no usable evidence and this run is not full coverage:\n>\n${rows.split("\n").map((line) => `> ${line}`).join("\n")}`;
771
+ const intro = {
772
+ zh: "**QUICK 运行已降级——一个或多个席位失败。** 报告结构可能通过质量检查,但下列席位没有提供可用证据;本轮不代表完整覆盖:",
773
+ en: "**DEGRADED QUICK RUN — one or more seats failed.** The report structure may pass quality checks, but the following seats supplied no usable evidence and this run is not full coverage:",
774
+ ja: "**QUICK 実行は縮退しました——1つ以上の席が失敗しました。** レポート構造が品質検査を通っても、次の席は利用可能な証拠を提供していないため、完全な網羅ではありません:",
775
+ ko: "**QUICK 실행 성능 저하—하나 이상의 좌석이 실패했습니다.** 보고서 구조가 품질 검사를 통과해도 다음 좌석은 사용 가능한 증거를 제공하지 않았으므로 전체 범위를 대표하지 않습니다:",
776
+ }[key];
777
+ const banner = `> [!WARNING]\n> ${intro}\n>\n${rows.split("\n").map((line) => `> ${line}`).join("\n")}`;
479
778
  return `${markerStart}\n${banner}\n${markerEnd}\n\n${cleaned.trimStart()}`;
480
779
  }
481
780
 
@@ -492,16 +791,26 @@ function withQuickScope(run, markdown) {
492
791
  start = cleaned.indexOf(markerStart);
493
792
  }
494
793
  if (run.council_mode !== "quick") return cleaned;
495
- const banner = isChineseLanguage(run.language)
496
- ? "> [!NOTE]\n> **QUICK_V1 范围。** 本轮不是 full council:固定 4 个核心证据席、1–4 个方法席、一次并行多空陈述和短 PM;没有三轮交叉问答或对抗 verifier。`full_council_equivalent=false`。"
497
- : "> [!NOTE]\n> **QUICK_V1 SCOPE.** This is not a full council: four fixed core evidence seats, one to four method seats, one parallel bull/bear statement and a short PM; no three-round cross-exam or adversarial verifier. `full_council_equivalent=false`.";
794
+ const copy = {
795
+ zh: "**QUICK_V1 范围。** 本轮不是 full council:固定 4 个核心证据席、1–4 个方法席、一次并行多空陈述和短 PM;没有三轮交叉问答或对抗核验。`full_council_equivalent=false`。",
796
+ en: "**QUICK_V1 SCOPE.** This is not a full council: four fixed core evidence seats, one to four method seats, one parallel bull/bear statement and a short PM; no three-round cross-exam or adversarial verifier. `full_council_equivalent=false`.",
797
+ ja: "**QUICK_V1 の範囲。** full council ではありません。固定4つの中核証拠席、1〜4のメソッド席、強気・弱気の並列1ラウンド、短いPMのみで、3ラウンドの交差質問や対抗検証はありません。`full_council_equivalent=false`。",
798
+ ko: "**QUICK_V1 범위.** full council이 아닙니다. 고정된 4개 핵심 증거 좌석, 1~4개 방법론 좌석, 병렬 강세·약세 1라운드와 짧은 PM만 실행하며 3라운드 교차 질문이나 적대적 검증은 없습니다. `full_council_equivalent=false`.",
799
+ }[languageKey(run.language)];
800
+ const banner = `> [!NOTE]\n> ${copy}`;
498
801
  return `${markerStart}\n${banner}\n${markerEnd}\n\n${cleaned.trimStart()}`;
499
802
  }
500
803
 
501
804
  export function finalReportMarkdown(run, manager) {
502
805
  const gate = verificationStatus(run);
503
806
  const completeness = completenessStatus(run);
504
- const reportBody = withRecordedMasterBench(run, manager.report_markdown || manager.summary);
807
+ const reportBody = withRecordedMasterBench(
808
+ run,
809
+ withRecordedInstrumentStructure(
810
+ run,
811
+ withRecordedPriceSnapshot(run, manager.report_markdown || manager.summary),
812
+ ),
813
+ );
505
814
  return withDisclaimer(
506
815
  withCompletenessBanner(
507
816
  withQuickScope(
@@ -517,33 +826,40 @@ export function finalReportMarkdown(run, manager) {
517
826
 
518
827
  export function writeArtifactIndex(run, debate = {}) {
519
828
  const artifacts = artifactPaths(run);
829
+ const key = languageKey(run.language);
830
+ const label = {
831
+ zh: { title: "AlphaCouncil 工件索引", run: "运行 ID", status: "状态", quality: "报告质量", main: "主要文件", final: "最终报告", handoff: "聊天交接摘要", trace: "全部代理审计追踪", evidence: "证据 JSON", decision: "决策 JSON", sources: "来源清单", statusFile: "状态", events: "事件", qualityFile: "报告质量", analysts: "分析师 Markdown 文件", masters: "方法席 Markdown 文件" },
832
+ en: { title: "AlphaCouncil Artifact Index", run: "Run ID", status: "Status", quality: "Report quality", main: "Main Files", final: "Final report", handoff: "Chat handoff summary", trace: "Full agent audit trace", evidence: "Evidence JSON", decision: "Decision JSON", sources: "Source manifest", statusFile: "Status", events: "Events", qualityFile: "Report quality", analysts: "Analyst Markdown Files", masters: "Method-Seat Markdown Files" },
833
+ ja: { title: "AlphaCouncil 成果物索引", run: "実行 ID", status: "状態", quality: "レポート品質", main: "主要ファイル", final: "最終レポート", handoff: "チャット引継ぎ要約", trace: "全エージェント監査トレース", evidence: "証拠 JSON", decision: "判断 JSON", sources: "出典一覧", statusFile: "状態", events: "イベント", qualityFile: "レポート品質", analysts: "分析担当 Markdown ファイル", masters: "メソッド席 Markdown ファイル" },
834
+ ko: { title: "AlphaCouncil 산출물 색인", run: "실행 ID", status: "상태", quality: "보고서 품질", main: "주요 파일", final: "최종 보고서", handoff: "채팅 인계 요약", trace: "전체 에이전트 감사 추적", evidence: "증거 JSON", decision: "판단 JSON", sources: "출처 목록", statusFile: "상태", events: "이벤트", qualityFile: "보고서 품질", analysts: "분석가 Markdown 파일", masters: "방법론 좌석 Markdown 파일" },
835
+ }[key];
520
836
  const lines = [
521
- `# ${run.symbol} AlphaCouncil Artifacts`,
837
+ `# ${run.symbol} ${label.title}`,
522
838
  "",
523
- `- Run ID: ${run.run_id}`,
524
- `- Status: ${run.status}`,
525
- `- Report quality: ${run.report_quality?.status || "not_checked"}`,
839
+ `- ${label.run}: ${run.run_id}`,
840
+ `- ${label.status}: ${run.status}`,
841
+ `- ${label.quality}: ${run.report_quality?.status || "not_checked"}`,
526
842
  "",
527
- "## Main Files",
843
+ `## ${label.main}`,
528
844
  "",
529
- `- Final report: ${artifacts.final_report_md}`,
530
- `- Chat handoff summary: ${artifacts.user_response_md}`,
531
- `- Full agent trace: ${artifacts.all_agents_md}`,
532
- `- Evidence JSON: ${artifacts.evidence_json}`,
533
- `- Decision JSON: ${artifacts.decision_json}`,
534
- `- Source manifest: ${artifacts.source_manifest_json}`,
535
- `- Status: ${artifacts.status_json}`,
536
- `- Events: ${artifacts.events_jsonl}`,
537
- `- Report quality: ${artifacts.report_quality_json}`,
845
+ `- ${label.final}: ${artifacts.final_report_md}`,
846
+ `- ${label.handoff}: ${artifacts.user_response_md}`,
847
+ `- ${label.trace}: ${artifacts.all_agents_md}`,
848
+ `- ${label.evidence}: ${artifacts.evidence_json}`,
849
+ `- ${label.decision}: ${artifacts.decision_json}`,
850
+ `- ${label.sources}: ${artifacts.source_manifest_json}`,
851
+ `- ${label.statusFile}: ${artifacts.status_json}`,
852
+ `- ${label.events}: ${artifacts.events_jsonl}`,
853
+ `- ${label.qualityFile}: ${artifacts.report_quality_json}`,
538
854
  "",
539
- "## Analyst Markdown Files",
855
+ `## ${label.analysts}`,
540
856
  "",
541
857
  ...(run.tasks || []).map((task) => `- ${task}: ${artifacts.analyst_markdown[task]}`),
542
858
  debate.bull ? `- bull_researcher: ${artifacts.analyst_markdown.bull_researcher}` : "",
543
859
  debate.bear ? `- bear_researcher: ${artifacts.analyst_markdown.bear_researcher}` : "",
544
860
  debate.manager ? `- portfolio_manager: ${artifacts.analyst_markdown.portfolio_manager}` : "",
545
861
  ...((run.master_opinions || []).length
546
- ? ["", "## Master Bench Markdown Files", "",
862
+ ? ["", `## ${label.masters}`, "",
547
863
  ...(run.master_opinions || []).map((o) => `- ${o.master} (${o.stance || "unknown"}): ${join(runPath(run.run_id), `${o.master}.md`)}`)]
548
864
  : []),
549
865
  ].filter(Boolean);
@@ -559,7 +875,7 @@ function quickUserResponse(run, manager, artifacts, chinese) {
559
875
  const managerCompleted = agentState(run, "portfolio_manager").status === "completed"
560
876
  && manager?.decision_available !== false;
561
877
  const masters = (run.master_opinions || []).map((opinion) =>
562
- `- ${masterTitle(opinion.master, run.language)} (\`${opinion.master}\`) — ${opinion.stance || "unknown"}, ${opinion.confidence || "low"}: ${clipAtBoundary(opinion.verdict || opinion.summary, 360)}`,
878
+ `- ${masterTitle(opinion.master, run.language)} (\`${opinion.master}\`) — ${opinion.stance || "unknown"}, ${opinion.confidence || "low"}: ${clipAtBoundary(opinion.voice_statement || opinion.summary || opinion.verdict, 360)}`,
563
879
  ).join("\n") || (chinese ? "- 没有已记录的方法席结论。" : "- No recorded method-seat conclusion.");
564
880
  const analysts = (run.tasks || []).map((task) => {
565
881
  const packet = (run.packets || []).find((item) => item.task === task);
@@ -670,7 +986,7 @@ function quickUserResponse(run, manager, artifacts, chinese) {
670
986
  ].join("\n");
671
987
  }
672
988
 
673
- export function userResponseMarkdown(run, manager) {
989
+ function legacyUserResponseMarkdown(run, manager) {
674
990
  const chinese = isChineseLanguage(run.language);
675
991
  const artifacts = artifactPaths(run);
676
992
  const decisionAvailable = manager?.decision_available !== false;
@@ -732,6 +1048,172 @@ export function userResponseMarkdown(run, manager) {
732
1048
  ].join("\n");
733
1049
  }
734
1050
 
1051
+ function handoffCopy(language) {
1052
+ return {
1053
+ zh: {
1054
+ title: "AlphaCouncil 运行摘要", status: "运行状态与时限", statusLabel: "状态", contract: "报告契约", scope: "执行范围", elapsed: "耗时", deadline: "硬截止时间", deadlineMet: "是否在截止前落盘",
1055
+ fullScope: "full_v2:8 个证据席、全部已选方法席的可审计终局陈词、三轮多空交叉问答和 PM;插件托管运行硬上限 30 分钟。", quickScope: "quick_v1:4 个证据席、1–4 个方法席、单轮多空和短 PM;不等同 full council。",
1056
+ price: "系统记录价格", noPrice: "未取得可验证报价;没有补造价格。", delayed: "延迟行情", instrument: "资产识别与研究路径", assetType: "资产类型", researchModel: "研究模型", classifiedBy: "识别来源", conclusion: "结论", rating: "评级", winner: "多空胜负", confidence: "置信度", judgment: "判断", noDecision: "NEEDS_MANAGER_REVIEW;工具或 PM 失败不能转换成投资评级。",
1057
+ masters: "结尾:逐席方法陈词(不是本人引语)", analysts: "分析师逐席内容", worker: "陈词来源", record: "冻结记录", key: "关键内容", earnings: "最新财报", forward: "前瞻门槛", news: "新闻/行业信号", recentNews: "近期公司与行业新闻", newsSummary: "新闻席摘要", noDatedNews: "本轮没有取得 as_of 之前 120 天内且带日期的新闻来源。", newsExcluded: "新闻时间门禁排除", valuation: "估值/价位", position: "仓位", gaps: "数据缺口与失败席", invalidation: "失效条件", files: "文件位置", report: "完整报告", index: "代理工件索引", trace: "全部代理追踪", quality: "报告质量检查", missing: "未覆盖。", noGaps: "未记录额外缺口。", noInvalidation: "没有正式失效条件。",
1058
+ },
1059
+ en: {
1060
+ title: "AlphaCouncil Run Summary", status: "Run Status and Deadline", statusLabel: "Status", contract: "Report contract", scope: "Execution scope", elapsed: "Elapsed", deadline: "Hard deadline", deadlineMet: "Persisted before deadline",
1061
+ fullScope: "full_v2: eight evidence seats, an auditable final statement for every selected method seat, three-round cross-examination and PM; plugin-managed runs have a hard thirty-minute ceiling.", quickScope: "quick_v1: four evidence seats, one to four method seats, one debate round and short PM; not equivalent to full council.",
1062
+ price: "System-Recorded Price", noPrice: "No verifiable quote was retrieved; no price was invented.", delayed: "delayed quote", instrument: "Instrument Classification and Research Path", assetType: "Asset type", researchModel: "Research model", classifiedBy: "Classified by", conclusion: "Conclusion", rating: "Rating", winner: "Debate winner", confidence: "Confidence", judgment: "Judgment", noDecision: "NEEDS_MANAGER_REVIEW; a tool or PM failure cannot be converted into an investment rating.",
1063
+ masters: "Final Per-Seat Method Statements (not quotes from the named people)", analysts: "Analyst Views by Seat", worker: "statement source", record: "Frozen record", key: "Key Content", earnings: "Latest earnings", forward: "Forward thresholds", news: "News / industry signal", recentNews: "Recent Company and Industry News", newsSummary: "News-seat summary", noDatedNews: "No dated news source inside the 120 days through as_of was retrieved.", newsExcluded: "Recent-news gate excluded", valuation: "Valuation / price range", position: "Position", gaps: "Data Gaps and Failed Seats", invalidation: "Invalidation", files: "File Locations", report: "Full report", index: "Agent artifact index", trace: "Full agent trace", quality: "Report quality check", missing: "Not covered.", noGaps: "No additional gap was recorded.", noInvalidation: "No formal invalidation conditions are available.",
1064
+ },
1065
+ ja: {
1066
+ title: "AlphaCouncil 実行サマリー", status: "実行状況と期限", statusLabel: "状態", contract: "レポート契約", scope: "実行範囲", elapsed: "所要時間", deadline: "ハード期限", deadlineMet: "期限内に保存", fullScope: "full_v2:8つの証拠席、選択された全メソッド席の監査可能な最終見解、3ラウンドの多空質疑、PM。プラグイン管理実行は30分で必ず終端状態になります。", quickScope: "quick_v1:4つの証拠席、1–4のメソッド席、1ラウンドの多空議論、短いPM。full council相当ではありません。", price: "システム記録価格", noPrice: "検証可能な価格を取得できず、価格は補完していません。", delayed: "遅延価格", instrument: "銘柄分類と調査経路", assetType: "資産タイプ", researchModel: "調査モデル", classifiedBy: "分類根拠", conclusion: "結論", rating: "評価", winner: "勝者", confidence: "信頼度", judgment: "判断", noDecision: "NEEDS_MANAGER_REVIEW。ツールまたはPMの失敗を投資評価に変換できません。", masters: "最後:メソッド席ごとの最終見解(本人の発言・引用ではありません)", analysts: "分析担当ごとの内容", worker: "見解の生成元", record: "凍結済み記録", key: "主要内容", earnings: "直近決算", forward: "先行条件", news: "ニュース・業界シグナル", recentNews: "直近の企業・業界ニュース", newsSummary: "ニュース席の要約", noDatedNews: "as_of までの120日間にある日付付きニュース出典を取得できませんでした。", newsExcluded: "ニュース時刻ゲートで除外", valuation: "評価レンジ・価格条件", position: "ポジション", gaps: "データ欠落と失敗した席", invalidation: "無効化条件", files: "ファイル", report: "完全レポート", index: "代理成果物一覧", trace: "全代理トレース", quality: "レポート品質検査", missing: "未取得。", noGaps: "追加の欠落は記録されていません。", noInvalidation: "正式な無効化条件はありません。",
1067
+ },
1068
+ ko: {
1069
+ title: "AlphaCouncil 실행 요약", status: "실행 상태 및 기한", statusLabel: "상태", contract: "보고서 계약", scope: "실행 범위", elapsed: "소요 시간", deadline: "하드 기한", deadlineMet: "기한 내 저장", fullScope: "full_v2: 8개 증거 좌석, 선택된 모든 방법론 좌석의 감사 가능한 최종 발언, 3라운드 롱/숏 질의응답, PM. 플러그인 관리 실행은 30분 안에 반드시 종단 상태가 됩니다.", quickScope: "quick_v1: 4개 증거 좌석, 1–4개 방법론 좌석, 단일 롱/숏 라운드, 짧은 PM. full council과 동등하지 않습니다.", price: "시스템 기록 가격", noPrice: "검증 가능한 시세를 가져오지 못했으며 가격을 임의로 만들지 않았습니다.", delayed: "지연 시세", instrument: "종목 분류 및 조사 경로", assetType: "자산 유형", researchModel: "조사 모델", classifiedBy: "분류 근거", conclusion: "결론", rating: "등급", winner: "토론 승자", confidence: "신뢰도", judgment: "판단", noDecision: "NEEDS_MANAGER_REVIEW. 도구 또는 PM 실패를 투자 등급으로 바꿀 수 없습니다.", masters: "마지막: 방법론 좌석별 최종 발언(본인의 실제 발언이나 인용이 아님)", analysts: "분석가 좌석별 내용", worker: "발언 출처", record: "동결 기록", key: "핵심 내용", earnings: "최근 실적", forward: "선행 조건", news: "뉴스·산업 신호", recentNews: "최근 기업 및 산업 뉴스", newsSummary: "뉴스 좌석 요약", noDatedNews: "as_of까지 120일 이내의 날짜가 있는 뉴스 출처를 확보하지 못했습니다.", newsExcluded: "뉴스 시간 게이트에서 제외", valuation: "가치평가 범위·가격 조건", position: "포지션", gaps: "데이터 공백 및 실패 좌석", invalidation: "무효화 조건", files: "파일 위치", report: "전체 보고서", index: "에이전트 산출물 색인", trace: "전체 에이전트 추적", quality: "보고서 품질 검사", missing: "미확보.", noGaps: "추가 공백이 기록되지 않았습니다.", noInvalidation: "공식 무효화 조건이 없습니다.",
1070
+ },
1071
+ }[languageKey(language)];
1072
+ }
1073
+
1074
+ function localizedFailure(error, language) {
1075
+ const value = String(error || "");
1076
+ const key = languageKey(language);
1077
+ const labels = {
1078
+ zh: { parse_failed: "返回格式无法修复", timeout: "超时", timed_out: "超时", global_deadline: "全局时限耗尽", qna_incomplete: "问答不完整", unexpected_error: "意外工具错误", failed: "子代理未成功返回", skipped: "因上游门禁未运行", degraded: "降级", pending: "尚未运行", missing: "缺失" },
1079
+ en: { parse_failed: "response format could not be repaired", timeout: "timed out", timed_out: "timed out", global_deadline: "global deadline exhausted", qna_incomplete: "Q&A was incomplete", unexpected_error: "unexpected tool error", failed: "subagent did not return successfully", skipped: "not run because an upstream gate failed", degraded: "degraded", pending: "not started", missing: "missing" },
1080
+ ja: { parse_failed: "応答形式を修復できませんでした", timeout: "タイムアウト", timed_out: "タイムアウト", global_deadline: "全体期限を超過", qna_incomplete: "質疑応答が不完全", unexpected_error: "予期しないツールエラー", failed: "サブエージェントが正常に応答しませんでした", skipped: "上流ゲートの失敗により未実行", degraded: "縮退", pending: "未開始", missing: "欠落" },
1081
+ ko: { parse_failed: "응답 형식을 복구하지 못함", timeout: "시간 초과", timed_out: "시간 초과", global_deadline: "전체 기한 소진", qna_incomplete: "질의응답 불완전", unexpected_error: "예기치 않은 도구 오류", failed: "하위 에이전트가 정상 응답하지 못함", skipped: "상위 게이트 실패로 실행하지 않음", degraded: "성능 저하", pending: "시작 전", missing: "누락" },
1082
+ }[key];
1083
+ if (value.startsWith("exit code")) return labels.failed;
1084
+ if (value.includes("gate_failed") || value.startsWith("global_deadline_before")) return labels.skipped;
1085
+ return labels[value] || labels.missing;
1086
+ }
1087
+
1088
+ function recentNewsHandoff(run, copy) {
1089
+ const packet = (run.packets || []).find((item) => item.task === "news_industry_management");
1090
+ const asOfTime = Date.parse(`${String(run.as_of || "").slice(0, 10)}T23:59:59.999Z`);
1091
+ const cutoff = Number.isFinite(asOfTime) ? asOfTime - (120 * 24 * 60 * 60 * 1000) : -Infinity;
1092
+ const excluded = { undated: 0, future: 0, stale: 0 };
1093
+ const eligible = (packet?.sources || []).filter((source) => {
1094
+ const published = Date.parse(source?.published_at || "");
1095
+ if (!Number.isFinite(published)) { excluded.undated += 1; return false; }
1096
+ if (Number.isFinite(asOfTime) && published > asOfTime) { excluded.future += 1; return false; }
1097
+ if (Number.isFinite(asOfTime) && published < cutoff) { excluded.stale += 1; return false; }
1098
+ return true;
1099
+ }).sort((a, b) => String(b.published_at || "").localeCompare(String(a.published_at || ""))).slice(0, 6);
1100
+ const sources = eligible.length
1101
+ ? eligible.map((source) => `- ${source.published_at} — ${clipAtBoundary(source.title || "", 240)}${source.url ? ` — ${source.url}` : ""}`).join("\n")
1102
+ : `- ${copy.noDatedNews}`;
1103
+ const totalExcluded = excluded.undated + excluded.future + excluded.stale;
1104
+ const exclusion = totalExcluded ? {
1105
+ zh: `- ${copy.newsExcluded} ${totalExcluded} 个来源:无日期 ${excluded.undated}、晚于 as_of ${excluded.future}、早于 120 天窗口 ${excluded.stale}。`,
1106
+ en: `- ${copy.newsExcluded} ${totalExcluded}: undated=${excluded.undated}, after_as_of=${excluded.future}, older_than_120d=${excluded.stale}.`,
1107
+ ja: `- ${copy.newsExcluded}:合計 ${totalExcluded} 件(日付なし ${excluded.undated}、as_of 後 ${excluded.future}、120日超 ${excluded.stale})。`,
1108
+ ko: `- ${copy.newsExcluded}: 총 ${totalExcluded}개(날짜 없음 ${excluded.undated}, as_of 이후 ${excluded.future}, 120일 초과 ${excluded.stale}).`,
1109
+ }[languageKey(run.language)] : "";
1110
+ return { packet, sources, exclusion };
1111
+ }
1112
+
1113
+ function localizedDisplayValue(value, language) {
1114
+ const key = languageKey(language);
1115
+ const token = value === true ? "true" : value === false ? "false" : String(value || "unknown");
1116
+ const maps = {
1117
+ zh: { unknown: "未知", unavailable: "不可用", true: "是", false: "否", pending: "待运行", running: "运行中", waiting: "等待中", completed: "已完成", complete: "完整", failed: "失败", degraded: "降级", incomplete: "不完整", skipped: "未运行", declined: "不适用", constructive: "建设性", cautious: "谨慎", opposed: "反对", out_of_scope: "证据范围外", deterministic_fallback: "确定性方法规则", completed_worker: "隔离方法席代理", recorded: "已记录", high: "高", medium: "中", low: "低", Buy: "买入", Overweight: "增持", Hold: "持有", Underweight: "减持", Sell: "卖出", bull: "多方", bear: "空方", balanced: "平衡" },
1118
+ en: { unknown: "unknown", unavailable: "unavailable", true: "yes", false: "no", deterministic_fallback: "deterministic method policy", completed_worker: "isolated method-seat worker", recorded: "recorded" },
1119
+ ja: { unknown: "不明", unavailable: "取得不可", true: "はい", false: "いいえ", pending: "待機中", running: "実行中", waiting: "待機中", completed: "完了", complete: "完了", failed: "失敗", degraded: "縮退", incomplete: "不完全", skipped: "未実行", declined: "適用外", constructive: "前向き", cautious: "慎重", opposed: "反対", out_of_scope: "証拠範囲外", deterministic_fallback: "決定論的メソッド規則", completed_worker: "分離メソッド席ワーカー", recorded: "記録済み", high: "高", medium: "中", low: "低", Buy: "買い", Overweight: "オーバーウェイト", Hold: "中立", Underweight: "アンダーウェイト", Sell: "売り", bull: "強気", bear: "弱気", balanced: "均衡" },
1120
+ ko: { unknown: "알 수 없음", unavailable: "확인 불가", true: "예", false: "아니요", pending: "대기 중", running: "실행 중", waiting: "대기 중", completed: "완료", complete: "완료", failed: "실패", degraded: "성능 저하", incomplete: "불완전", skipped: "미실행", declined: "적용 범위 밖", constructive: "긍정적", cautious: "신중", opposed: "반대", out_of_scope: "증거 범위 밖", deterministic_fallback: "결정론적 방법 규칙", completed_worker: "격리 방법론 좌석 워커", recorded: "기록됨", high: "높음", medium: "중간", low: "낮음", Buy: "매수", Overweight: "비중 확대", Hold: "보유", Underweight: "비중 축소", Sell: "매도", bull: "강세", bear: "약세", balanced: "균형" },
1121
+ };
1122
+ return maps[key]?.[token] || token;
1123
+ }
1124
+
1125
+ export function userResponseMarkdown(run, manager) {
1126
+ const artifacts = artifactPaths(run);
1127
+ const copy = handoffCopy(run.language);
1128
+ const news = recentNewsHandoff(run, copy);
1129
+ const decisionAvailable = manager?.decision_available !== false;
1130
+ const quote = run?.grounding?.quote;
1131
+ const priceLine = quote && Number.isFinite(Number(quote.price))
1132
+ ? `${quote.price} ${quote.currency || ""}; ${quote.quote_time || localizedDisplayValue("unknown", run.language)}; ${quote.exchange || localizedDisplayValue("unknown", run.language)}; ${copy.delayed}; ${quote.source_url || localizedDisplayValue("unavailable", run.language)}`
1133
+ : copy.noPrice;
1134
+ const masterLines = (run.masters || []).map((id) => {
1135
+ const opinion = (run.master_opinions || []).find((item) => item.master === id);
1136
+ const state = run.master_status?.[id] || { status: "pending" };
1137
+ if (!opinion) return `- ${masterTitle(id, run.language)} (\`${id}\`) [${localizedDisplayValue(state.status, run.language)}]: ${localizedFailure(state.error, run.language) || copy.missing}`;
1138
+ const statementSource = opinion.dedicated_worker?.status || opinion.voice_status || "unknown";
1139
+ const frozenRecord = opinion.statement_origin || opinion.reason || opinion.engine || "recorded";
1140
+ return `- ${masterTitle(id, run.language)} (\`${id}\`) — ${clipAtBoundary(opinion.voice_statement || opinion.summary || opinion.verdict, 520)} [${copy.record}: ${localizedDisplayValue(opinion.stance, run.language)}/${localizedDisplayValue(opinion.confidence || "low", run.language)}; ${copy.worker}: ${localizedDisplayValue(statementSource, run.language)}; ${frozenRecord}]`;
1141
+ }).join("\n") || `- ${copy.missing}`;
1142
+ const analystLines = (run.tasks || []).map((task) => {
1143
+ const packet = (run.packets || []).find((item) => item.task === task);
1144
+ const state = taskState(run, task);
1145
+ return `- \`${task}\` [${localizedDisplayValue(state.status, run.language)}/${localizedDisplayValue(packet?.confidence || "low", run.language)}]: ${clipAtBoundary(packet?.summary || "", 520) || localizedFailure(state.error, run.language) || copy.missing}`;
1146
+ }).join("\n") || `- ${copy.missing}`;
1147
+ const gaps = [...new Set([
1148
+ ...(run.tasks || []).filter((task) => taskState(run, task).status !== "completed")
1149
+ .map((task) => `${task}: ${localizedFailure(taskState(run, task).error || taskState(run, task).status, run.language)}`),
1150
+ ...(run.masters || []).filter((id) => !(run.master_opinions || []).some((opinion) => opinion.master === id))
1151
+ .map((id) => `${id}: ${localizedFailure(run.master_status?.[id]?.error || run.master_status?.[id]?.status, run.language)}`),
1152
+ ...(run.packets || []).flatMap((packet) => packet.open_questions || []),
1153
+ ])].slice(0, 12).map((item) => `- ${clipAtBoundary(item, 360)}`).join("\n") || `- ${copy.noGaps}`;
1154
+ const invalidation = decisionAvailable
1155
+ ? (manager.invalidation || []).slice(0, 3).map((item) => `- ${clipAtBoundary(item, 260)}`).join("\n") || `- ${copy.noInvalidation}`
1156
+ : `- ${copy.noInvalidation}`;
1157
+ const elapsed = run.started_at
1158
+ ? Math.max(0, Date.parse(run.completed_at || new Date().toISOString()) - Date.parse(run.started_at))
1159
+ : localizedDisplayValue("unknown", run.language);
1160
+ return [
1161
+ `# ${run.symbol} ${copy.title}`,
1162
+ "",
1163
+ `## ${copy.status}`,
1164
+ `- ${copy.statusLabel}: ${localizedDisplayValue(run.status, run.language)}`,
1165
+ `- ${copy.contract}: ${run.council_mode === "quick" ? "quick_v1" : "full_v2"}`,
1166
+ `- ${copy.scope}: ${run.council_mode === "quick" ? copy.quickScope : copy.fullScope}`,
1167
+ `- ${copy.elapsed}: ${elapsed} ms`,
1168
+ `- ${copy.deadline}: ${run.deadline_at || localizedDisplayValue("unknown", run.language)}`,
1169
+ `- ${copy.deadlineMet}: ${localizedDisplayValue(run.deadline_at && run.completed_at ? Date.parse(run.completed_at) <= Date.parse(run.deadline_at) : "unknown", run.language)}`,
1170
+ "",
1171
+ `## ${copy.price}`,
1172
+ `- ${priceLine}`,
1173
+ "",
1174
+ `## ${copy.instrument}`,
1175
+ `- ${copy.assetType}: ${run?.grounding?.instrument?.asset_type || localizedDisplayValue("unknown", run.language)}`,
1176
+ `- ${copy.researchModel}: ${run?.grounding?.instrument?.research_model || localizedDisplayValue("unknown", run.language)}`,
1177
+ `- ${copy.classifiedBy}: ${run?.grounding?.instrument?.classification_source || localizedDisplayValue("unknown", run.language)}`,
1178
+ "",
1179
+ `## ${copy.conclusion}`,
1180
+ `- ${copy.rating}: ${localizedDisplayValue(decisionAvailable ? manager.rating : "unavailable", run.language)}`,
1181
+ `- ${copy.winner}: ${localizedDisplayValue(decisionAvailable ? (manager.winner || "unknown") : "unavailable", run.language)}`,
1182
+ `- ${copy.confidence}: ${localizedDisplayValue(decisionAvailable ? (manager.confidence || "low") : "unavailable", run.language)}`,
1183
+ `- ${copy.judgment}: ${decisionAvailable ? clipAtBoundary(manager.verdict || manager.summary, 720) : copy.noDecision}`,
1184
+ "",
1185
+ `## ${copy.analysts}`,
1186
+ analystLines,
1187
+ "",
1188
+ `## ${copy.recentNews}`,
1189
+ `- ${copy.newsSummary}: ${clipAtBoundary(news.packet?.summary || "", 620) || copy.missing}`,
1190
+ news.sources,
1191
+ news.exclusion,
1192
+ "",
1193
+ `## ${copy.key}`,
1194
+ `- ${copy.earnings}: ${clipAtBoundary(packetSummary(run, "earnings_deep_dive"), 520) || copy.missing}`,
1195
+ `- ${copy.forward}: ${clipAtBoundary(packetSummary(run, "forward_expectations"), 520) || copy.missing}`,
1196
+ `- ${copy.news}: ${clipAtBoundary(packetSummary(run, "news_industry_management"), 620) || copy.missing}`,
1197
+ `- ${copy.valuation}: ${decisionAvailable ? (clipAtBoundary(manager.valuation_range, 620) || copy.missing) : localizedDisplayValue("unavailable", run.language)}`,
1198
+ `- ${copy.position}: ${decisionAvailable ? (clipAtBoundary(manager.position, 520) || copy.missing) : localizedDisplayValue("unavailable", run.language)}`,
1199
+ "",
1200
+ `## ${copy.gaps}`,
1201
+ gaps,
1202
+ "",
1203
+ `## ${copy.invalidation}`,
1204
+ invalidation,
1205
+ "",
1206
+ `## ${copy.files}`,
1207
+ `- ${copy.report}: ${artifacts.final_report_md}`,
1208
+ `- ${copy.index}: ${artifacts.artifact_index_md}`,
1209
+ `- ${copy.trace}: ${artifacts.all_agents_md}`,
1210
+ `- ${copy.quality}: ${artifacts.report_quality_json}`,
1211
+ "",
1212
+ `## ${copy.masters} — ${(run.masters || []).length}`,
1213
+ masterLines,
1214
+ ].join("\n");
1215
+ }
1216
+
735
1217
  export function writeUserResponse(run, manager) {
736
1218
  const markdown = userResponseMarkdown(run, manager);
737
1219
  writeFileSync(artifactPaths(run).user_response_md, `${markdown}\n`);