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,7 +1,17 @@
1
1
  import { join } from "node:path";
2
2
  import { LIMITS, MASTER_STANCES, RATINGS } from "./constants.mjs";
3
- import { internalError } from "./errors.mjs";
4
- import { isChineseLanguage } from "./lang.mjs";
3
+ // A worker returning a malformed packet is a client contract violation, not a server bug:
4
+ // these three checks used to raise -32603 while the equivalent checks in the orchestrator
5
+ // correctly raised -32602.
6
+ import { internalError, invalidParams } from "./errors.mjs";
7
+ import { isChineseLanguage, languageKey, localized } from "./lang.mjs";
8
+ import {
9
+ composeVoiceStatement,
10
+ defaultIntentForStance,
11
+ intentsForStance,
12
+ isIntentAllowed,
13
+ VOICE_FIELDS,
14
+ } from "./voice.mjs";
5
15
  import { cleanLog, clip } from "./text.mjs";
6
16
  import { scopedSourceId } from "./gates.mjs";
7
17
  import { runPath } from "./run-store.mjs";
@@ -85,6 +95,7 @@ export function normalizeDebate(packet, role, run, raw = "") {
85
95
  questions_answered: Array.isArray(packet?.questions_answered) ? packet.questions_answered : [],
86
96
  debate_rounds: Array.isArray(packet?.debate_rounds) ? packet.debate_rounds : [],
87
97
  report_markdown: typeof packet?.report_markdown === "string" ? packet.report_markdown : "",
98
+ failure_kind: typeof packet?.failure_kind === "string" ? packet.failure_kind : undefined,
88
99
  thread_id: typeof packet?.thread_id === "string" ? packet.thread_id : undefined,
89
100
  thread_title: typeof packet?.thread_title === "string" ? packet.thread_title : undefined,
90
101
  execution_mode: typeof packet?.execution_mode === "string" ? packet.execution_mode : undefined,
@@ -92,6 +103,57 @@ export function normalizeDebate(packet, role, run, raw = "") {
92
103
  };
93
104
  }
94
105
 
106
+ export function debateFailurePacket(role, run, failureKind) {
107
+ const kind = ["global_deadline", "timeout", "exit", "parse_failed", "reader_language_mismatch", "unexpected_error"]
108
+ .includes(failureKind)
109
+ ? failureKind
110
+ : "unexpected_error";
111
+ const copy = localized(run.language, {
112
+ en: {
113
+ global_deadline: `${role} did not complete before the council's global deadline.`,
114
+ timeout: `${role} timed out and produced no usable debate statement.`,
115
+ exit: `${role} exited unsuccessfully and produced no usable debate statement.`,
116
+ parse_failed: `${role} returned output that violated the debate JSON contract.`,
117
+ reader_language_mismatch: `${role} returned reader-facing content in the wrong language.`,
118
+ unexpected_error: `${role} failed unexpectedly and produced no usable debate statement.`,
119
+ },
120
+ zh: {
121
+ global_deadline: `${role} 未能在委员会全局截止时间前完成。`,
122
+ timeout: `${role} 执行超时,未生成可用的辩论发言。`,
123
+ exit: `${role} 异常退出,未生成可用的辩论发言。`,
124
+ parse_failed: `${role} 的输出违反辩论 JSON 契约。`,
125
+ reader_language_mismatch: `${role} 返回了错误语言的读者内容。`,
126
+ unexpected_error: `${role} 意外失败,未生成可用的辩论发言。`,
127
+ },
128
+ ja: {
129
+ global_deadline: `${role} は委員会全体の期限までに完了しませんでした。`,
130
+ timeout: `${role} はタイムアウトし、利用可能な討論発言を生成しませんでした。`,
131
+ exit: `${role} は異常終了し、利用可能な討論発言を生成しませんでした。`,
132
+ parse_failed: `${role} の出力は討論 JSON 契約に違反しています。`,
133
+ reader_language_mismatch: `${role} は指定と異なる言語の読者向け内容を返しました。`,
134
+ unexpected_error: `${role} は予期せず失敗し、利用可能な討論発言を生成しませんでした。`,
135
+ },
136
+ ko: {
137
+ global_deadline: `${role}이 위원회 전체 마감 시간 전에 완료되지 않았습니다.`,
138
+ timeout: `${role}이 시간 초과되어 사용할 수 있는 토론 발언을 생성하지 못했습니다.`,
139
+ exit: `${role}이 비정상 종료되어 사용할 수 있는 토론 발언을 생성하지 못했습니다.`,
140
+ parse_failed: `${role}의 출력이 토론 JSON 계약을 위반했습니다.`,
141
+ reader_language_mismatch: `${role}이 지정과 다른 언어의 독자용 내용을 반환했습니다.`,
142
+ unexpected_error: `${role}이 예기치 않게 실패해 사용할 수 있는 토론 발언을 생성하지 못했습니다.`,
143
+ },
144
+ });
145
+ return normalizeDebate({
146
+ verdict: "FAILED",
147
+ decision_available: false,
148
+ rating: null,
149
+ winner: "unknown",
150
+ summary: copy[kind],
151
+ confidence: "low",
152
+ report_markdown: "",
153
+ failure_kind: kind,
154
+ }, role, run, "");
155
+ }
156
+
95
157
  export function dryPacket(task, symbol, asOfDate, prompt, language = "English") {
96
158
  const chinese = isChineseLanguage(language);
97
159
  return normalizePacket({
@@ -124,15 +186,41 @@ export function compactEvidence(run) {
124
186
  run_id: run.run_id,
125
187
  symbol: run.symbol,
126
188
  as_of: run.as_of,
127
- packets: run.packets.map((packet) => ({
128
- task: packet.task,
129
- summary: packet.summary,
130
- claims: packet.claims,
131
- metrics: packet.metrics,
132
- sources: packet.sources,
133
- open_questions: packet.open_questions,
134
- confidence: packet.confidence,
135
- })),
189
+ context_contract: "bounded_full_v1",
190
+ packets: (run.packets || []).map((packet) => {
191
+ const claims = (packet.claims || []).slice(0, 8);
192
+ const sourceById = new Map((packet.sources || []).map((source) => [source?.id, source]));
193
+ const referenced = [...new Set(claims.flatMap((claim) => claim?.source_ids || []))];
194
+ const selectedIds = referenced.filter((id) => sourceById.has(id)).slice(0, 12);
195
+ for (const source of packet.sources || []) {
196
+ if (selectedIds.length >= 12) break;
197
+ if (source?.id && !selectedIds.includes(source.id)) selectedIds.push(source.id);
198
+ }
199
+ const included = new Set(selectedIds);
200
+ return {
201
+ task: packet.task,
202
+ summary: clip(packet.summary || "", 1_800),
203
+ claims: claims.map((claim) => ({
204
+ claim: clip(claim?.claim || "", 700),
205
+ evidence: clip(claim?.evidence || "", 700),
206
+ confidence: claim?.confidence || "low",
207
+ source_ids: (claim?.source_ids || []).filter((id) => included.has(id)),
208
+ })),
209
+ metrics: compactValue(packet.metrics || {}),
210
+ sources: selectedIds.map((id) => sourceById.get(id)).filter(Boolean).map((source) => ({
211
+ id: source?.id,
212
+ title: clip(source?.title || "", 260),
213
+ url: source?.url || "",
214
+ published_at: source?.published_at || "unknown",
215
+ retrieved_at: source?.retrieved_at || run.as_of,
216
+ })),
217
+ omitted_claim_count: Math.max(0, (packet.claims || []).length - claims.length),
218
+ omitted_source_count: Math.max(0, (packet.sources || []).length - selectedIds.length),
219
+ open_questions: (packet.open_questions || []).slice(0, 8).map((item) => clip(item, 650)),
220
+ confidence: packet.confidence,
221
+ information_richness: packet.information_richness,
222
+ };
223
+ }),
136
224
  };
137
225
  }
138
226
 
@@ -239,21 +327,53 @@ export function compactDebateContext(packet) {
239
327
  }
240
328
 
241
329
  export function debateFromCodex(result, role, run, fallbackPrompt) {
242
- if (!result.ok) return dryDebate(role, run, cleanLog(result.stderr || result.text || fallbackPrompt));
330
+ if (!result.ok) {
331
+ const failureKind = result.deadline_exhausted
332
+ ? "global_deadline"
333
+ : result.timedOut
334
+ ? "timeout"
335
+ : Number.isInteger(result.code)
336
+ ? "exit"
337
+ : "unexpected_error";
338
+ return debateFailurePacket(role, run, failureKind);
339
+ }
243
340
  try {
244
341
  return normalizeDebate(extractJson(result.text), role, run, result.text);
245
- } catch {
246
- return normalizeDebate({
247
- verdict: "PARSE_FAILED",
248
- rating: "Hold",
249
- winner: "unknown",
250
- summary: `${role} returned non-JSON output.`,
251
- confidence: "low",
252
- report_markdown: cleanLog(result.text),
253
- }, role, run, cleanLog(result.text));
342
+ } catch (error) {
343
+ return debateFailurePacket(role, run, "parse_failed");
254
344
  }
255
345
  }
256
346
 
347
+ function asianManagerFallback(run, summary) {
348
+ const key = languageKey(run.language);
349
+ if (!new Set(["ja", "ko"]).has(key)) return null;
350
+ const c = localized(run.language, {
351
+ ja: {
352
+ title: "投資委員会ドラフト", conclusion: "結論", analyst: "アナリスト作業記録", debate: "強気・弱気討論記録", masters: "メソッド席", long: "強気論点", short: "弱気論点", market: "市場期待と織り込み条件", rating: "アナリスト評価と目標株価の変更", call: "決算説明会の経営シグナル", quant: "定量・ファクター視点", news: "ニュースと企業・業界シグナル", borrow: "空売り・貸株・オプション情報", transaction: "戦略取引・銀行イベント", valuation: "企業価値評価レンジ", price: "価格条件", catalysts: "主要カタリスト", risks: "主要リスク", position: "ポジション提案", shortTerm: "短期1–4週間の見通し", mediumTerm: "中期3–6か月の見通し", longTerm: "長期12か月の見通し", gaps: "データ欠落・利用不可データ", invalidation: "無効化条件", confidence: "信頼度", sources: "出典表",
353
+ unavailable: "今回の実行では同じ言語で確認できる情報を取得できませんでした。", managerMissing: "portfolio_manager の統合が完了していないため、正式な投資判断はありません。", draftOnly: "この文書はドラフトであり、正式なポジションを示しません。", noPackets: "証拠パケットは生成されませんでした。", noMaster: "完了したメソッド席はありません。", keyFindings: "主要所見", dataGaps: "データ欠落", packetSummary: "要約", packetConfidence: "信頼度", sourceCount: "出典数",
354
+ },
355
+ ko: {
356
+ title: "투자위원회 초안", conclusion: "결론", analyst: "분석가 작업 기록", debate: "강세·약세 토론 기록", masters: "방법론 좌석", long: "강세 논거", short: "약세 논거", market: "시장 기대와 내재 조건", rating: "애널리스트 등급 및 목표가 변경", call: "실적 발표 콜 경영진 신호", quant: "정량·팩터 관점", news: "뉴스 및 기업·산업 신호", borrow: "공매도·대차·옵션 정보", transaction: "전략적 거래·금융 이벤트", valuation: "가치평가 범위", price: "가격 조건", catalysts: "핵심 촉매", risks: "주요 위험", position: "포지션 제안", shortTerm: "단기 1–4주 전망", mediumTerm: "중기 3–6개월 전망", longTerm: "장기 12개월 전망", gaps: "데이터 공백·사용 불가 데이터", invalidation: "무효화 조건", confidence: "신뢰도", sources: "출처 표",
357
+ unavailable: "이번 실행에서는 같은 언어로 확인 가능한 정보를 확보하지 못했습니다.", managerMissing: "portfolio_manager 종합이 완료되지 않아 공식 투자 판단을 제공할 수 없습니다.", draftOnly: "이 문서는 초안이며 공식 포지션을 제시하지 않습니다.", noPackets: "증거 패킷이 생성되지 않았습니다.", noMaster: "완료된 방법론 좌석이 없습니다.", keyFindings: "핵심 발견", dataGaps: "데이터 공백", packetSummary: "요약", packetConfidence: "신뢰도", sourceCount: "출처 수",
358
+ },
359
+ });
360
+ const analystLog = run.packets.length
361
+ ? run.packets.map((packet) => {
362
+ const claims = (packet.claims || []).slice(0, 5).map((claim) => ` - ${claim.claim}`).join("\n");
363
+ const gaps = (packet.open_questions || []).slice(0, 3).map((item) => ` - ${item}`).join("\n");
364
+ return `### ${packet.task}\n- ${c.packetConfidence}: ${packet.confidence || "unknown"}\n- ${c.packetSummary}: ${packet.summary || c.unavailable}\n${claims ? `- ${c.keyFindings}:\n${claims}\n` : ""}${gaps ? `- ${c.dataGaps}:\n${gaps}\n` : ""}`;
365
+ }).join("\n\n")
366
+ : c.noPackets;
367
+ const masterLog = (run.master_opinions || []).length
368
+ ? run.master_opinions.map((opinion) => `- ${opinion.master}: ${opinion.stance} - ${opinion.summary || opinion.verdict || c.unavailable}`).join("\n")
369
+ : `- ${c.noMaster}`;
370
+ const long = summary.thesis.filter((claim) => claim.confidence !== "low").slice(0, 6).map((claim) => `- ${claim.claim}`).join("\n") || `- ${c.unavailable}`;
371
+ const short = summary.open_questions.slice(0, 6).map((item) => `- ${item}`).join("\n") || `- ${c.unavailable}`;
372
+ const gaps = summary.open_questions.length ? summary.open_questions.map((item) => `- ${item}`).join("\n") : `- ${c.unavailable}`;
373
+ const report = `# ${run.symbol} ${c.title}\n\n## ${c.conclusion}\n${summary.final_decision} — ${c.managerMissing}\n\n## ${c.analyst}\n${analystLog}\n\n## ${c.debate}\n${c.managerMissing}\n\n## ${c.masters}\n${masterLog}\n\n## ${c.long}\n${long}\n\n## ${c.short}\n${short}\n\n## ${c.market}\n${c.unavailable}\n\n## ${c.rating}\n${c.unavailable}\n\n## ${c.call}\n${c.unavailable}\n\n## ${c.quant}\n${c.unavailable}\n\n## ${c.news}\n${c.unavailable}\n\n## ${c.borrow}\n${c.unavailable}\n\n## ${c.transaction}\n${c.unavailable}\n\n## ${c.valuation}\n${c.unavailable}\n\n## ${c.price}\n${c.managerMissing} ${c.unavailable}\n\n## ${c.catalysts}\n${c.managerMissing}\n\n## ${c.risks}\n${short}\n\n## ${c.position}\n${c.draftOnly}\n\n## ${c.shortTerm}\n${c.managerMissing}\n\n## ${c.mediumTerm}\n${c.managerMissing}\n\n## ${c.longTerm}\n${c.managerMissing}\n\n## ${c.gaps}\n${gaps}\n\n## ${c.invalidation}\n${c.managerMissing} ${c.draftOnly}\n\n## ${c.confidence}\n${summary.confidence}\n\n## ${c.sources}\n- ${c.sourceCount}: ${summary.source_count}\n`;
374
+ return { copy: c, analystLog, masterLog, report };
375
+ }
376
+
257
377
  export function mergeDebateRounds(rounds) {
258
378
  const list = (rounds || []).filter(Boolean);
259
379
  if (list.length === 0) return null;
@@ -347,6 +467,20 @@ export function summarizeRun(run, userPrompt = "") {
347
467
 
348
468
  export function managerFallback(run, userPrompt = "") {
349
469
  const summary = summarizeRun(run, userPrompt);
470
+ const asian = asianManagerFallback(run, summary);
471
+ if (asian) {
472
+ return normalizeDebate({
473
+ verdict: summary.final_decision,
474
+ decision_available: false,
475
+ rating: null,
476
+ winner: "unknown",
477
+ summary: asian.copy.managerMissing,
478
+ long_thesis: summary.thesis.filter((claim) => claim.confidence !== "low").slice(0, 6).map((claim) => claim.claim),
479
+ short_thesis: summary.open_questions.slice(0, 6),
480
+ confidence: summary.confidence,
481
+ report_markdown: asian.report,
482
+ }, "portfolio_manager", run);
483
+ }
350
484
  const chinese = isChineseLanguage(run.language);
351
485
  const analystLog = run.packets.length
352
486
  ? run.packets.map((packet) => {
@@ -442,6 +576,78 @@ export function normalizeMasterOpinion(packet, masterId, run, raw = "") {
442
576
  };
443
577
  }
444
578
 
579
+ /**
580
+ * A dedicated v3 method worker explains an already frozen decision; it never gets to
581
+ * choose or rewrite the stance. Keeping this packet separate from normalizeMasterOpinion
582
+ * makes a persuasive narrative incapable of overriding deterministic policy output.
583
+ */
584
+ /**
585
+ * A worker statement is prose that gets interpolated into a system-owned report section.
586
+ * Left raw, a statement containing a line such as `## Conclusion` emits a real level-2
587
+ * heading inside that section; heading assignment keeps the richest body, so the injected
588
+ * block becomes the section the quality gate validates and the genuine PM conclusion drops
589
+ * out of the gate's view entirely. Escape structural markdown at the trust boundary rather
590
+ * than at each render site, so a new renderer cannot reintroduce the hole.
591
+ */
592
+ export function sanitizeStatementMarkdown(value) {
593
+ return String(value ?? "")
594
+ .replace(/\r\n?/gu, "\n")
595
+ .split("\n")
596
+ .map((line) => line
597
+ .replace(/^(\s*)(#{1,6})(\s)/u, "$1\\$2$3")
598
+ .replace(/^(\s*)(={3,}|-{3,}|\*{3,}|_{3,})\s*$/u, "$1\\$2"))
599
+ .join("\n")
600
+ .replace(/\n{2,}/gu, "\n")
601
+ .trim();
602
+ }
603
+
604
+ export function normalizeMasterVoice(packet, masterId, run, frozenOpinion, raw = "") {
605
+ // Every one of these is rendered into the system-owned bench, so all of them are escaped.
606
+ const list = (value) => (Array.isArray(value)
607
+ ? value.map(sanitizeStatementMarkdown).filter(Boolean)
608
+ : []);
609
+ if (packet?.master !== masterId) throw invalidParams(`dedicated method worker returned the wrong master id for ${masterId}`);
610
+ if (packet?.acknowledged_stance !== frozenOpinion?.stance) {
611
+ throw invalidParams(`dedicated method worker attempted to change frozen stance for ${masterId}`);
612
+ }
613
+ // The five-field voice is the current contract; a flat `statement` remains accepted so a
614
+ // legacy worker, or one that answered before the contract moved, is not a hard failure.
615
+ const voice = Object.fromEntries(VOICE_FIELDS
616
+ .map((field) => [field, sanitizeStatementMarkdown(packet?.voice?.[field])])
617
+ .filter(([, text]) => text));
618
+ const statement = Object.keys(voice).length
619
+ ? composeVoiceStatement(voice, run.language)
620
+ : sanitizeStatementMarkdown(packet?.statement);
621
+ if (!statement) throw invalidParams(`dedicated method worker returned no statement for ${masterId}`);
622
+
623
+ // Intent narrows the frozen stance; it never reopens it. Rejected the same way a changed
624
+ // stance is, so a worker cannot turn `opposed` into `would_buy` by choosing a label.
625
+ const requested = packet?.position_intent;
626
+ if (requested !== undefined && !isIntentAllowed(requested, frozenOpinion.stance)) {
627
+ throw invalidParams(
628
+ `dedicated method worker returned an intent outside the frozen stance for ${masterId}: `
629
+ + `${JSON.stringify(requested)} is not one of ${intentsForStance(frozenOpinion.stance).join(", ")}`,
630
+ );
631
+ }
632
+
633
+ return {
634
+ master: masterId,
635
+ symbol: run.symbol,
636
+ as_of: run.as_of,
637
+ acknowledged_stance: frozenOpinion.stance,
638
+ position_intent: requested ?? defaultIntentForStance(frozenOpinion.stance),
639
+ voice: Object.keys(voice).length ? voice : null,
640
+ statement,
641
+ key_findings: list(packet?.key_findings),
642
+ disagreements: list(packet?.disagreements),
643
+ what_would_change_my_mind: list(packet?.what_would_change_my_mind),
644
+ source_ids: list(packet?.source_ids),
645
+ confidence: ["high", "medium", "low"].includes(packet?.confidence) ? packet.confidence : frozenOpinion.confidence || "low",
646
+ language: run.language,
647
+ raw_text: raw,
648
+ };
649
+ }
650
+
445
651
  /** Compact master opinions for injection into the debate prompt. */
446
652
  export function compactMasterOpinions(run) {
447
653
  return (run.master_opinions || []).map((opinion) => ({
@@ -12,7 +12,7 @@ import { buildFactPack } from "../personas-v3/typed-facts.mjs";
12
12
  import { typedFactPackFromGrounding } from "../personas-v3/grounding-adapter.mjs";
13
13
  import { buildAnonymousPreDecision, freezeAnonymousDecision } from "../personas-v3/runtime.mjs";
14
14
  import { executeDeterministicPersonaPolicy } from "../personas-v3/deterministic-executor.mjs";
15
- import { isChineseLanguage } from "../lang.mjs";
15
+ import { languageKey, localized } from "../lang.mjs";
16
16
  import {
17
17
  declinedOpinion as v2DeclinedOpinion,
18
18
  planMasters as planLegacyMasters,
@@ -190,9 +190,15 @@ export function completedMasterOpinion(run, item) {
190
190
  throw new Error("completedMasterOpinion requires a completed v3 deterministic seat");
191
191
  }
192
192
  const result = item.frozenDecision.structured_decision.result;
193
- const zh = isChineseLanguage(run.language);
194
- const label = item.pack.admitted_label?.[zh ? "zh" : "en"]
193
+ const locale = languageKey(run.language);
194
+ const label = item.pack.admitted_label?.[locale]
195
195
  || item.pack.admitted_label?.en || item.id;
196
+ const copy = localized(run.language, {
197
+ en: { withheld: (pct) => `${pct}% coverage; score withheld`, unscored: "not scored", verdict: (stance, reason) => `${label} frozen decision: ${stance} (${reason})`, summary: (score) => `Using the ${label} method on ${run.symbol}, the PersonaPack v3 deterministic policy executed with score ${score}. Typed facts, hard vetoes, and score bands produced this stance; no language model selected it.`, hit: (id) => `score hit: ${id}`, miss: (id) => `score miss: ${id}`, eligibility: (id) => `eligibility condition ${id} becomes satisfied`, veto: (id) => `hard veto ${id} no longer triggers`, score: (id) => `score condition ${id} becomes satisfied` },
198
+ zh: { withheld: (pct) => `覆盖率 ${pct}%,分数被保留不发布`, unscored: "未评分", verdict: (stance, reason) => `${label}的冻结结论:${stance}(${reason})`, summary: (score) => `按${label}方法审视 ${run.symbol}:PersonaPack v3 确定性政策已执行,得分 ${score}。该立场由结构化事实、硬否决和评分带产生,没有让语言模型选择立场。`, hit: (id) => `评分命中:${id}`, miss: (id) => `评分未命中:${id}`, eligibility: (id) => `资格条件 ${id} 变为满足`, veto: (id) => `硬否决 ${id} 不再触发`, score: (id) => `评分条件 ${id} 变为满足` },
199
+ ja: { withheld: (pct) => `カバレッジ ${pct}% のためスコアは非公開`, unscored: "未採点", verdict: (stance, reason) => `${label}の凍結済み判断:${stance}(${reason})`, summary: (score) => `${label}の方法で ${run.symbol} を評価し、PersonaPack v3 の決定論的ポリシーを実行した結果、スコアは ${score}。構造化事実、ハード拒否条件、スコア帯がこの立場を生成しており、言語モデルは立場を選択していない。`, hit: (id) => `採点条件を満たす:${id}`, miss: (id) => `採点条件を満たさない:${id}`, eligibility: (id) => `適格条件 ${id} が満たされる`, veto: (id) => `ハード拒否条件 ${id} が解除される`, score: (id) => `採点条件 ${id} が満たされる` },
200
+ ko: { withheld: (pct) => `커버리지 ${pct}%로 점수를 공개하지 않음`, unscored: "미채점", verdict: (stance, reason) => `${label}의 동결된 판단: ${stance}(${reason})`, summary: (score) => `${label} 방법으로 ${run.symbol}을 검토하여 PersonaPack v3 결정론적 정책을 실행했으며 점수는 ${score}입니다. 구조화된 사실, 하드 거부 조건, 점수 구간이 이 입장을 만들었고 언어 모델은 입장을 선택하지 않았습니다.`, hit: (id) => `점수 조건 충족: ${id}`, miss: (id) => `점수 조건 미충족: ${id}`, eligibility: (id) => `적격 조건 ${id} 충족`, veto: (id) => `하드 거부 조건 ${id} 해제`, score: (id) => `점수 조건 ${id} 충족` },
201
+ });
196
202
  const vetoIds = (result.vetoes_triggered || []).map((veto) => veto.veto_id);
197
203
  const unmet = result.eligibility?.unmet_condition_ids || [];
198
204
  const hitIds = (result.score?.hits || []).map((rule) => rule.rule_id);
@@ -204,33 +210,32 @@ export function completedMasterOpinion(run, item) {
204
210
  ...(result.score?.misses || []).flatMap((rule) => rule.source_ids || []),
205
211
  ]);
206
212
  const scoreText = result.score?.status === "insufficient_coverage"
207
- ? zh
208
- ? `覆盖率 ${Math.round(result.score.coverage * 100)}%,分数被保留不发布`
209
- : `${Math.round(result.score.coverage * 100)}% coverage; score withheld`
213
+ ? copy.withheld(Math.round(result.score.coverage * 100))
210
214
  : result.score
211
215
  ? `${result.score.score}/${result.score.max_possible} (${Math.round((result.ratio || 0) * 100)}%)`
212
- : zh ? "未评分" : "not scored";
216
+ : copy.unscored;
217
+ const deterministicStatement = copy.summary(scoreText);
213
218
  return {
214
219
  master: item.id,
215
220
  symbol: run.symbol,
216
221
  as_of: run.as_of,
217
222
  stance: result.stance,
218
- verdict: zh
219
- ? `${label}的冻结结论:${result.stance}(${result.reason})`
220
- : `${label} frozen decision: ${result.stance} (${result.reason})`,
221
- summary: zh
222
- ? `PersonaPack v3 确定性政策已执行;得分 ${scoreText}。该立场由结构化事实、硬否决和评分带产生,没有让语言模型选择立场。`
223
- : `The PersonaPack v3 deterministic policy executed with score ${scoreText}. Typed facts, hard vetoes, and score bands produced this stance; no language model selected it.`,
223
+ verdict: copy.verdict(result.stance, result.reason),
224
+ summary: deterministicStatement,
225
+ voice_statement: deterministicStatement,
226
+ voice_status: "deterministic_fallback",
227
+ voice_language: run.language,
228
+ statement_origin: "deterministic_policy_fallback",
224
229
  key_findings: uniqueStrings([
225
- ...hitIds.map((id) => zh ? `评分命中:${id}` : `score hit: ${id}`),
226
- ...missIds.map((id) => zh ? `评分未命中:${id}` : `score miss: ${id}`),
230
+ ...hitIds.map(copy.hit),
231
+ ...missIds.map(copy.miss),
227
232
  ]),
228
233
  disagreements: [],
229
234
  disqualifiers_triggered: uniqueStrings([...unmet, ...vetoIds]),
230
235
  what_would_change_my_mind: uniqueStrings([
231
- ...unmet.map((id) => zh ? `资格条件 ${id} 变为满足` : `eligibility condition ${id} becomes satisfied`),
232
- ...vetoIds.map((id) => zh ? `硬否决 ${id} 不再触发` : `hard veto ${id} no longer triggers`),
233
- ...missIds.map((id) => zh ? `评分条件 ${id} 变为满足` : `score condition ${id} becomes satisfied`),
236
+ ...unmet.map(copy.eligibility),
237
+ ...vetoIds.map(copy.veto),
238
+ ...missIds.map(copy.score),
234
239
  ]),
235
240
  source_ids: sourceIds,
236
241
  confidence: result.common_projection?.confidence || "low",
@@ -257,27 +262,35 @@ export function completedMasterOpinion(run, item) {
257
262
  export function declinedMasterOpinion(run, item) {
258
263
  if (item?.engine !== "v3_method_runtime") return v2DeclinedOpinion(run, item.id, item.decision);
259
264
  const eligibility = item.preDecision.eligibility;
260
- const zh = isChineseLanguage(run.language);
261
- const label = item.pack.admitted_label?.[zh ? "zh" : "en"]
265
+ const locale = languageKey(run.language);
266
+ const label = item.pack.admitted_label?.[locale]
262
267
  || item.pack.admitted_label?.en || item.id;
263
- const missing = eligibility.missing_required_fact_types.join(", ") || (zh ? "无" : "none");
268
+ const instrument = run?.grounding?.instrument;
269
+ const fundOrIndex = instrument?.fund_like === true || instrument?.index_like === true
270
+ || ["etf", "mutual_fund", "index"].includes(instrument?.asset_type);
271
+ const copy = localized(run.language, {
272
+ en: { none: "none", verdict: `${label} cannot evaluate ${run.symbol}: ${eligibility.reason}`, summary: (missing) => `The v3 typed-fact gate returned ${eligibility.status}; missing: ${missing}. No legacy prompt or narrative decision layer was called.`, fundContext: fundOrIndex ? `${run.symbol} is classified as ${instrument.asset_type}; this method must use dated holdings or aggregate index evidence rather than treating the instrument as an operating company. ` : "", statement: (missing, context) => `${context}Using the ${label} method, I do not issue a directional view on ${run.symbol} in this run because the point-in-time record lacks ${missing}. This is neither bearish nor a vote against the asset. I would reassess only after those method-critical facts are available.`, available: (id) => `${id} becomes available from a point-in-time source` },
273
+ zh: { none: "无", verdict: `${label}无法评估 ${run.symbol}:${eligibility.reason}`, summary: (missing) => `v3 typed-fact 闸门返回 ${eligibility.status};缺失:${missing}。系统未调用旧提示词或叙述决策层。`, fundContext: fundOrIndex ? `${run.symbol} 已识别为 ${instrument.asset_type};该方法必须通过带时点的持仓穿透或指数聚合证据使用,不能把它当成经营公司。` : "", statement: (missing, context) => `${context}按${label}方法审视 ${run.symbol},本轮不作方向判断,因为时点一致的资料缺少:${missing}。这不是看空,也不是一张反对票;只有取得这些方法关键事实后,该席位才会重新评估。`, available: (id) => `${id} 可从时点一致的来源取得` },
274
+ ja: { none: "なし", verdict: `${label}は ${run.symbol} を評価できません:${eligibility.reason}`, summary: (missing) => `v3 typed-fact ゲートは ${eligibility.status} を返しました。欠落:${missing}。旧プロンプトや叙述型の判断層は呼び出していません。`, fundContext: fundOrIndex ? `${run.symbol} は ${instrument.asset_type} に分類されており、事業会社として扱わず、基準日付き保有銘柄のルックスルーまたは指数集計証拠を用いる必要があります。` : "", statement: (missing, context) => `${context}${label}の方法では、時点整合した資料に ${missing} が欠けているため、今回は ${run.symbol} の方向判断を出しません。弱気判断や反対票ではなく、これらの方法上重要な事実が揃った時点で再評価します。`, available: (id) => `${id} が時点整合した出典から利用可能になる` },
275
+ ko: { none: "없음", verdict: `${label}은 ${run.symbol}을 평가할 수 없습니다: ${eligibility.reason}`, summary: (missing) => `v3 typed-fact 게이트가 ${eligibility.status}을 반환했습니다. 누락: ${missing}. 기존 프롬프트나 서술형 판단 계층은 호출하지 않았습니다.`, fundContext: fundOrIndex ? `${run.symbol}은 ${instrument.asset_type}로 분류되므로 영업회사처럼 취급하지 않고 기준일이 있는 보유 종목 룩스루 또는 지수 집계 증거를 사용해야 합니다. ` : "", statement: (missing, context) => `${context}${label} 방법으로는 시점 일치 자료에 ${missing}이 없어 이번 실행에서 ${run.symbol}의 방향 판단을 내리지 않습니다. 이는 약세 판단이나 반대표가 아니며, 해당 핵심 사실이 확보된 뒤에만 재평가합니다.`, available: (id) => `${id}을 시점 일치 출처에서 확보할 수 있게 됨` },
276
+ });
277
+ const missing = eligibility.missing_required_fact_types.join(", ") || copy.none;
278
+ const deterministicStatement = copy.statement(missing, copy.fundContext);
264
279
  return {
265
280
  master: item.id,
266
281
  symbol: run.symbol,
267
282
  as_of: run.as_of,
268
283
  stance: "out_of_scope",
269
- verdict: zh
270
- ? `${label}无法评估 ${run.symbol}:${eligibility.reason}`
271
- : `${label} cannot evaluate ${run.symbol}: ${eligibility.reason}`,
272
- summary: zh
273
- ? `v3 typed-fact 闸门返回 ${eligibility.status};缺失:${missing}。系统未调用旧提示词或叙述决策层。`
274
- : `The v3 typed-fact gate returned ${eligibility.status}; missing: ${missing}. No legacy prompt or narrative decision layer was called.`,
275
- key_findings: [],
284
+ verdict: copy.verdict,
285
+ summary: copy.summary(missing),
286
+ voice_statement: deterministicStatement,
287
+ voice_status: "deterministic_fallback",
288
+ voice_language: run.language,
289
+ statement_origin: "deterministic_scope_fallback",
290
+ key_findings: [deterministicStatement],
276
291
  disagreements: [],
277
292
  disqualifiers_triggered: eligibility.missing_required_fact_types,
278
- what_would_change_my_mind: eligibility.missing_required_fact_types.map((id) => (
279
- zh ? `${id} 可从时点一致的来源取得` : `${id} becomes available from a point-in-time source`
280
- )),
293
+ what_would_change_my_mind: eligibility.missing_required_fact_types.map(copy.available),
281
294
  source_ids: [],
282
295
  // The refusal itself is deterministic, but the seat has insufficient evidence for an
283
296
  // investment judgment. Keep the reader-facing evidence confidence low so a mechanically
@@ -18,6 +18,8 @@ function candidateLabel(label) {
18
18
  return {
19
19
  en: /candidate/i.test(label.en) ? label.en : `${label.en} candidate`,
20
20
  zh: /候选/.test(label.zh) ? label.zh : `${label.zh}候选`,
21
+ ...(label.ja ? { ja: /候補/.test(label.ja) ? label.ja : `${label.ja}候補` } : {}),
22
+ ...(label.ko ? { ko: /후보/.test(label.ko) ? label.ko : `${label.ko} 후보` } : {}),
21
23
  };
22
24
  }
23
25
 
@@ -227,7 +227,7 @@ function validatePeriodContract(period, path, errors) {
227
227
  if (!exactFields(period, path, fields, [...fields], errors)) return;
228
228
  if (!["instant", "duration", "forecast_horizon", "not_applicable"].includes(period.basis)) add(errors, `${path}.basis`, "is invalid");
229
229
  if (!["exact", "same_period", "as_of", "not_applicable"].includes(period.alignment)) add(errors, `${path}.alignment`, "is invalid");
230
- if (period.window !== null && (typeof period.window !== "string" || !/^P[1-9]\d*[DMY]$/u.test(period.window))) add(errors, `${path}.window`, "must be null or P<n>D, P<n>M, or P<n>Y");
230
+ if (period.window !== null && (typeof period.window !== "string" || !/^(P[1-9]\d*[DMY]|ANY)$/u.test(period.window))) add(errors, `${path}.window`, "must be null, ANY, or P<n>D, P<n>M, or P<n>Y");
231
231
  if (["instant", "not_applicable"].includes(period.basis) && period.window !== null) add(errors, `${path}.window`, `must be null for ${period.basis}`);
232
232
  if (["duration", "forecast_horizon"].includes(period.basis) && period.window === null) add(errors, `${path}.window`, `is required for ${period.basis}`);
233
233
  if (period.basis === "not_applicable" && period.alignment !== "not_applicable") add(errors, `${path}.alignment`, "must be not_applicable");
@@ -532,18 +532,29 @@ function periodTuple(fact) {
532
532
  return [fact.period_start, fact.period_end, fact.fiscal_year];
533
533
  }
534
534
 
535
+ /** Window token for a duration whose length is set by data availability, not by the method. */
536
+ export const ANY_REPORTING_INTERVAL = "ANY";
537
+
535
538
  function periodWindowMatches(fact, window) {
536
539
  if (!fact.period_start || !fact.period_end) return false;
537
540
  const start = Date.parse(fact.period_start);
538
541
  const end = Date.parse(fact.period_end);
539
542
  if (!Number.isFinite(start) || !Number.isFinite(end) || end < start) return false;
543
+ // Some aggregates cover as many periods as the filings supplied rather than a fixed span --
544
+ // interest coverage is three years for one issuer and one for the next. Pinning a count there
545
+ // would reject the fact for being honest about its own coverage; what still has to hold is
546
+ // that it carries a real interval rather than a stray observation date.
547
+ if (window === ANY_REPORTING_INTERVAL) return true;
540
548
  const match = /^P([1-9]\d*)([DMY])$/u.exec(window || "");
541
549
  if (!match) return false;
542
550
  const count = Number(match[1]);
543
551
  const elapsedDays = (end - start) / 86_400_000;
544
552
  if (match[2] === "D") return elapsedDays === count;
545
553
  if (match[2] === "M") return elapsedDays >= count * 27 && elapsedDays <= count * 32;
546
- return elapsedDays >= count * 365 - 1 && elapsedDays <= count * 366 + 1;
554
+ // A fiscal year is 52 or 53 weeks, not 365 days, and it is measured between two fiscal
555
+ // year-end dates -- so a real one-year filing span is routinely 363 or 364 days. Demanding
556
+ // 365 rejected every issuer whose year ends on a weekday.
557
+ return elapsedDays >= count * 364 - 2 && elapsedDays <= count * 366 + 1;
547
558
  }
548
559
 
549
560
  function assertFactInputContract(fact, contract, factPackAsOf, path) {
@@ -1,3 +1,4 @@
1
+ import { CANONICAL_MASTER_COUNT } from "./staging.mjs";
1
2
  import { createHash } from "node:crypto";
2
3
  import {
3
4
  existsSync,
@@ -441,8 +442,8 @@ export function inspectGaExternalEvidence({
441
442
  const releaseIds = manifest.canonical_master_ids || [];
442
443
  const releasePackHashes = (manifest.packs || []).map((pack) => pack.pack_hash);
443
444
  const releaseVersions = (manifest.packs || []).map((pack) => pack.pack_version);
444
- if (releaseVersions.length !== 26 || releaseVersions.some((version) => version !== expectedVersion)) {
445
- errors.push(`all 26 immutable release pack versions must equal ${expectedVersion}`);
445
+ if (releaseVersions.length !== CANONICAL_MASTER_COUNT || releaseVersions.some((version) => version !== expectedVersion)) {
446
+ errors.push(`all ${CANONICAL_MASTER_COUNT} immutable release pack versions must equal ${expectedVersion}`);
446
447
  }
447
448
  if (packageEvidence?.artifact) {
448
449
  if (!same(packageEvidence.derived_catalog?.selected_master_ids, releaseIds)) errors.push("installed package selected master IDs/order differ from the release manifest");
@@ -19,9 +19,10 @@ import { verifyPersonaRelease } from "./releases.mjs";
19
19
  import { inspectSourceAcquisitions } from "./source-acquisition.mjs";
20
20
  import { inspectSourceAdjudications } from "./source-adjudication.mjs";
21
21
  import { defaultStagingRoot, inspectPersonaV3Staging } from "./staging.mjs";
22
+ import { CANONICAL_MASTER_COUNT } from "./staging.mjs";
22
23
 
23
24
  export const GA_REPORT_SCHEMA_VERSION = 1;
24
- export const GA_DEFAULT_COUNT = 26;
25
+ export const GA_DEFAULT_COUNT = CANONICAL_MASTER_COUNT;
25
26
  export const GA_DEFAULT_MIN_ADMISSION = "operational";
26
27
  export const GA_TARGET_VERSION = "0.9.0";
27
28
 
@@ -1,3 +1,4 @@
1
+ import { CANONICAL_MASTER_COUNT } from "./staging.mjs";
1
2
  import { createHash } from "node:crypto";
2
3
  import { spawnSync } from "node:child_process";
3
4
  import {
@@ -219,9 +220,9 @@ function safelyInstallAndDerive(tarball, { packageName, releaseId }) {
219
220
  const releaseFile = containedPhysicalFile(installedRoot, join("knowledge", "persona-releases", releaseId, "manifest.json"), "installed release manifest");
220
221
  const release = parseJson(releaseFile.bytes, "installed release manifest");
221
222
  if (release.artifact_kind !== "persona_v3_release_manifest" || release.release_id !== releaseId) throw new Error("installed release manifest identity differs from the package artifact");
222
- if (release.canonical_master_count !== 26 || !Array.isArray(release.canonical_master_ids)
223
- || release.canonical_master_ids.length !== 26 || new Set(release.canonical_master_ids).size !== 26
224
- || !Array.isArray(release.packs) || release.packs.length !== 26) throw new Error("installed release manifest does not contain exactly 26 canonical packs");
223
+ if (release.canonical_master_count !== CANONICAL_MASTER_COUNT || !Array.isArray(release.canonical_master_ids)
224
+ || release.canonical_master_ids.length !== CANONICAL_MASTER_COUNT || new Set(release.canonical_master_ids).size !== CANONICAL_MASTER_COUNT
225
+ || !Array.isArray(release.packs) || release.packs.length !== CANONICAL_MASTER_COUNT) throw new Error(`installed release manifest does not contain exactly ${CANONICAL_MASTER_COUNT} canonical packs`);
225
226
  const selectedPackHashes = release.packs.map((pack, index) => {
226
227
  if (pack?.persona_id !== release.canonical_master_ids[index] || !HASH.test(pack?.pack_hash || "")) throw new Error(`installed release manifest pack ${index} does not bind canonical ID/order/hash`);
227
228
  return pack.pack_hash;
@@ -323,7 +324,7 @@ export function checkGaPackageArtifactFile(file, { packageJsonPath, expectedVers
323
324
  if (artifact.package?.[field] !== sourcePackage?.[field]) errors.push(`package artifact ${field} differs from repository package.json`);
324
325
  if (artifact.package?.[field] !== tarballPackage?.[field]) errors.push(`package artifact ${field} differs from tarball package.json`);
325
326
  }
326
- if (artifact.catalog?.selected_master_ids?.length === 26) {
327
+ if (artifact.catalog?.selected_master_ids?.length === CANONICAL_MASTER_COUNT) {
327
328
  installedMetadata = safelyInstallAndDerive(tarballFile.absolute, {
328
329
  packageName: tarballPackage.name,
329
330
  releaseId: artifact.release_id,