@zergai/ztc 0.4.0-beta.1 → 0.5.0-beta.1

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 (718) hide show
  1. package/README.md +398 -45
  2. package/RUST_THIRD_PARTY_LICENSES.txt +1080 -822
  3. package/THIRD_PARTY_NOTICES.md +273 -12
  4. package/bin/zmux-darwin-arm64 +0 -0
  5. package/bin/ztc-audio-darwin-arm64 +0 -0
  6. package/bin/ztc-capture-darwin-arm64 +0 -0
  7. package/bin/ztc-computer-darwin-arm64 +0 -0
  8. package/bin/ztc-llm-darwin-arm64 +0 -0
  9. package/bin/ztc-tts-darwin-arm64 +0 -0
  10. package/bin/ztc-tui-darwin-arm64 +0 -0
  11. package/bin/ztc-zlicky-overlay-darwin-arm64 +0 -0
  12. package/bin/zterm-darwin-arm64 +0 -0
  13. package/dist/App.js +1206 -209
  14. package/dist/agent/agent.d.ts +74 -8
  15. package/dist/agent/agent.js +1073 -184
  16. package/dist/agent/backends/account_rotation.d.ts +4 -0
  17. package/dist/agent/backends/account_rotation.js +8 -2
  18. package/dist/agent/backends/anthropic.d.ts +13 -0
  19. package/dist/agent/backends/anthropic.js +169 -28
  20. package/dist/agent/backends/claude_cli.js +18 -8
  21. package/dist/agent/backends/codex_app_server.d.ts +1 -0
  22. package/dist/agent/backends/codex_app_server.js +55 -3
  23. package/dist/agent/backends/codex_auth.d.ts +1 -0
  24. package/dist/agent/backends/codex_auth.js +67 -13
  25. package/dist/agent/backends/codex_buffered_recovery.d.ts +27 -0
  26. package/dist/agent/backends/codex_buffered_recovery.js +293 -0
  27. package/dist/agent/backends/gemini.js +3 -1
  28. package/dist/agent/backends/http_error.d.ts +26 -0
  29. package/dist/agent/backends/http_error.js +221 -0
  30. package/dist/agent/backends/index.d.ts +9 -2
  31. package/dist/agent/backends/index.js +22 -2
  32. package/dist/agent/backends/openai.d.ts +0 -6
  33. package/dist/agent/backends/openai.js +5 -2
  34. package/dist/agent/backends/openai_compatible.d.ts +5 -4
  35. package/dist/agent/backends/openai_compatible.js +26 -19
  36. package/dist/agent/backends/openai_responses.d.ts +8 -3
  37. package/dist/agent/backends/openai_responses.js +77 -33
  38. package/dist/agent/backends/provider_ids.d.ts +1 -0
  39. package/dist/agent/backends/provider_ids.js +4 -0
  40. package/dist/agent/backends/request_metrics.js +12 -2
  41. package/dist/agent/backends/types.d.ts +109 -6
  42. package/dist/agent/backends/types.js +5 -1
  43. package/dist/agent/backends/zrouter_stream.d.ts +6 -1
  44. package/dist/agent/backends/zrouter_stream.js +160 -42
  45. package/dist/agent/background_registry.d.ts +2 -0
  46. package/dist/agent/background_registry.js +1 -0
  47. package/dist/agent/claim_observation.d.ts +6 -0
  48. package/dist/agent/claim_observation.js +54 -0
  49. package/dist/agent/commands/accounts.js +46 -177
  50. package/dist/agent/commands/attention.d.ts +2 -0
  51. package/dist/agent/commands/attention.js +67 -0
  52. package/dist/agent/commands/auth.js +18 -2
  53. package/dist/agent/commands/board.d.ts +2 -0
  54. package/dist/agent/commands/board.js +169 -0
  55. package/dist/agent/commands/clipboard.js +50 -1
  56. package/dist/agent/commands/compact.js +21 -13
  57. package/dist/agent/commands/config.js +4 -1
  58. package/dist/agent/commands/context.js +6 -1
  59. package/dist/agent/commands/desktop.d.ts +2 -0
  60. package/dist/agent/commands/desktop.js +29 -0
  61. package/dist/agent/commands/effort.js +14 -6
  62. package/dist/agent/commands/environment.d.ts +3 -0
  63. package/dist/agent/commands/environment.js +109 -0
  64. package/dist/agent/commands/evidence.d.ts +2 -0
  65. package/dist/agent/commands/evidence.js +9 -0
  66. package/dist/agent/commands/fork.js +4 -3
  67. package/dist/agent/commands/goal.d.ts +33 -1
  68. package/dist/agent/commands/goal.js +174 -14
  69. package/dist/agent/commands/goal_exit.d.ts +36 -0
  70. package/dist/agent/commands/goal_exit.js +120 -0
  71. package/dist/agent/commands/help.js +3 -1
  72. package/dist/agent/commands/history.js +3 -1
  73. package/dist/agent/commands/inbox.d.ts +2 -0
  74. package/dist/agent/commands/inbox.js +148 -0
  75. package/dist/agent/commands/index.js +16 -1
  76. package/dist/agent/commands/input_mode.js +8 -6
  77. package/dist/agent/commands/job.d.ts +2 -0
  78. package/dist/agent/commands/job.js +93 -0
  79. package/dist/agent/commands/keybindings.js +4 -1
  80. package/dist/agent/commands/label.d.ts +2 -0
  81. package/dist/agent/commands/label.js +77 -0
  82. package/dist/agent/commands/layout.d.ts +2 -0
  83. package/dist/agent/commands/layout.js +20 -0
  84. package/dist/agent/commands/mirror.js +16 -1
  85. package/dist/agent/commands/model.js +12 -2
  86. package/dist/agent/commands/permissions.d.ts +3 -1
  87. package/dist/agent/commands/permissions.js +79 -89
  88. package/dist/agent/commands/plan.js +5 -15
  89. package/dist/agent/commands/profile.js +21 -2
  90. package/dist/agent/commands/provider_selection.js +20 -1
  91. package/dist/agent/commands/rename.js +1 -1
  92. package/dist/agent/commands/resources.d.ts +2 -0
  93. package/dist/agent/commands/resources.js +67 -0
  94. package/dist/agent/commands/rewind.d.ts +3 -0
  95. package/dist/agent/commands/rewind.js +16 -0
  96. package/dist/agent/commands/runbooks.d.ts +2 -0
  97. package/dist/agent/commands/runbooks.js +73 -0
  98. package/dist/agent/commands/runbooks_lazy.d.ts +2 -0
  99. package/dist/agent/commands/runbooks_lazy.js +8 -0
  100. package/dist/agent/commands/sessions.d.ts +1 -1
  101. package/dist/agent/commands/sessions.js +33 -5
  102. package/dist/agent/commands/settings.js +185 -39
  103. package/dist/agent/commands/setup.d.ts +2 -0
  104. package/dist/agent/commands/setup.js +78 -0
  105. package/dist/agent/commands/share.d.ts +2 -0
  106. package/dist/agent/commands/share.js +64 -0
  107. package/dist/agent/commands/status.js +14 -2
  108. package/dist/agent/commands/types.d.ts +99 -6
  109. package/dist/agent/commands/update.js +8 -0
  110. package/dist/agent/commands/usage.d.ts +2 -0
  111. package/dist/agent/commands/usage.js +8 -0
  112. package/dist/agent/factory.d.ts +11 -0
  113. package/dist/agent/factory.js +113 -88
  114. package/dist/agent/loop_policy.d.ts +6 -3
  115. package/dist/agent/loop_policy.js +12 -3
  116. package/dist/agent/measurement_guidance.d.ts +2 -0
  117. package/dist/agent/measurement_guidance.js +5 -0
  118. package/dist/agent/request_encoder.d.ts +8 -1
  119. package/dist/agent/request_encoder.js +95 -23
  120. package/dist/agent/runtime/benchmark_comparison.d.ts +30 -0
  121. package/dist/agent/runtime/benchmark_comparison.js +94 -0
  122. package/dist/agent/runtime/benchmark_contract.d.ts +48 -0
  123. package/dist/agent/runtime/benchmark_contract.js +90 -0
  124. package/dist/agent/runtime/checked_commands.d.ts +32 -0
  125. package/dist/agent/runtime/checked_commands.js +119 -0
  126. package/dist/agent/runtime/command_execution_policy.d.ts +26 -0
  127. package/dist/agent/runtime/command_execution_policy.js +91 -0
  128. package/dist/agent/runtime/command_jobs.d.ts +36 -18
  129. package/dist/agent/runtime/command_jobs.js +151 -13
  130. package/dist/agent/runtime/command_panes.d.ts +59 -0
  131. package/dist/agent/runtime/command_panes.js +398 -0
  132. package/dist/agent/runtime/command_wait.d.ts +19 -0
  133. package/dist/agent/runtime/command_wait.js +167 -0
  134. package/dist/agent/runtime/cpu_benchmark.d.ts +30 -0
  135. package/dist/agent/runtime/cpu_benchmark.js +126 -0
  136. package/dist/agent/runtime/delegated_evidence.d.ts +26 -0
  137. package/dist/agent/runtime/delegated_evidence.js +80 -0
  138. package/dist/agent/runtime/evidence.d.ts +127 -0
  139. package/dist/agent/runtime/evidence.js +468 -0
  140. package/dist/agent/runtime/execution_context.d.ts +7 -0
  141. package/dist/agent/runtime/execution_context.js +39 -3
  142. package/dist/agent/runtime/json_verifier_recipe.d.ts +8 -0
  143. package/dist/agent/runtime/json_verifier_recipe.js +66 -0
  144. package/dist/agent/runtime/measurements.d.ts +110 -0
  145. package/dist/agent/runtime/measurements.js +317 -0
  146. package/dist/agent/runtime/policy.d.ts +4 -0
  147. package/dist/agent/runtime/policy.js +31 -20
  148. package/dist/agent/runtime/provider_native_evidence.d.ts +20 -0
  149. package/dist/agent/runtime/provider_native_evidence.js +86 -0
  150. package/dist/agent/runtime/recovery.d.ts +2 -0
  151. package/dist/agent/runtime/recovery.js +45 -2
  152. package/dist/agent/runtime/remote_broker_transport.d.ts +10 -0
  153. package/dist/agent/runtime/remote_broker_transport.js +84 -0
  154. package/dist/agent/runtime/remote_deletion_receipts.d.ts +3 -0
  155. package/dist/agent/runtime/remote_deletion_receipts.js +43 -0
  156. package/dist/agent/runtime/remote_journal_replay.d.ts +13 -0
  157. package/dist/agent/runtime/remote_journal_replay.js +233 -0
  158. package/dist/agent/runtime/remote_mutation_journal.d.ts +25 -0
  159. package/dist/agent/runtime/remote_mutation_journal.js +208 -0
  160. package/dist/agent/runtime/remote_resource_endpoint.d.ts +7 -0
  161. package/dist/agent/runtime/remote_resource_endpoint.js +6 -0
  162. package/dist/agent/runtime/remote_resource_errors.d.ts +5 -0
  163. package/dist/agent/runtime/remote_resource_errors.js +9 -0
  164. package/dist/agent/runtime/remote_resource_script.d.ts +2 -0
  165. package/dist/agent/runtime/remote_resource_script.js +1009 -0
  166. package/dist/agent/runtime/remote_resources.d.ts +29 -0
  167. package/dist/agent/runtime/remote_resources.js +160 -0
  168. package/dist/agent/runtime/source_verification.d.ts +12 -0
  169. package/dist/agent/runtime/source_verification.js +210 -0
  170. package/dist/agent/runtime/source_verification_contract.d.ts +75 -0
  171. package/dist/agent/runtime/source_verification_contract.js +203 -0
  172. package/dist/agent/runtime/tool_checkpoints.d.ts +11 -0
  173. package/dist/agent/runtime/tool_checkpoints.js +26 -0
  174. package/dist/agent/runtime/tool_effects.d.ts +5 -0
  175. package/dist/agent/runtime/tool_progress.d.ts +12 -0
  176. package/dist/agent/runtime/tool_progress.js +76 -0
  177. package/dist/agent/runtime/tool_runtime.d.ts +16 -1
  178. package/dist/agent/runtime/tool_runtime.js +204 -10
  179. package/dist/agent/runtime/tracing.d.ts +1 -1
  180. package/dist/agent/runtime/verifier_capture.d.ts +9 -0
  181. package/dist/agent/runtime/verifier_capture.js +100 -0
  182. package/dist/agent/runtime/verifier_contract.d.ts +24 -0
  183. package/dist/agent/runtime/verifier_contract.js +41 -0
  184. package/dist/agent/subagent.d.ts +20 -10
  185. package/dist/agent/subagent.js +266 -29
  186. package/dist/agent/tool_response_directory.d.ts +24 -0
  187. package/dist/agent/tool_response_directory.js +61 -0
  188. package/dist/agent/tool_response_source.d.ts +8 -0
  189. package/dist/agent/tool_response_source.js +49 -0
  190. package/dist/agent/tool_response_store.d.ts +75 -4
  191. package/dist/agent/tool_response_store.js +583 -64
  192. package/dist/agent/tools/ask_user.d.ts +3 -1
  193. package/dist/agent/tools/ask_user.js +30 -11
  194. package/dist/agent/tools/background.js +1 -0
  195. package/dist/agent/tools/benchmark_cpu.d.ts +2 -0
  196. package/dist/agent/tools/benchmark_cpu.js +102 -0
  197. package/dist/agent/tools/compare_benchmarks.d.ts +2 -0
  198. package/dist/agent/tools/compare_benchmarks.js +53 -0
  199. package/dist/agent/tools/deferred.js +1 -0
  200. package/dist/agent/tools/delegate.js +18 -2
  201. package/dist/agent/tools/helper_requirements.d.ts +7 -0
  202. package/dist/agent/tools/helper_requirements.js +19 -0
  203. package/dist/agent/tools/index.d.ts +1 -0
  204. package/dist/agent/tools/index.js +3 -0
  205. package/dist/agent/tools/measurement_report.d.ts +22 -0
  206. package/dist/agent/tools/measurement_report.js +190 -0
  207. package/dist/agent/tools/pane.d.ts +0 -7
  208. package/dist/agent/tools/pane.js +5 -4
  209. package/dist/agent/tools/project_context.d.ts +3 -0
  210. package/dist/agent/tools/project_context.js +45 -0
  211. package/dist/agent/tools/recall_tool_response.d.ts +3 -5
  212. package/dist/agent/tools/recall_tool_response.js +19 -29
  213. package/dist/agent/tools/registry.d.ts +1 -0
  214. package/dist/agent/tools/registry.js +23 -0
  215. package/dist/agent/tools/related_sessions.d.ts +2 -0
  216. package/dist/agent/tools/related_sessions.js +156 -0
  217. package/dist/agent/tools/routine.js +13 -3
  218. package/dist/agent/tools/session_evidence.d.ts +3 -0
  219. package/dist/agent/tools/session_evidence.js +72 -0
  220. package/dist/agent/tools/shell.d.ts +4 -3
  221. package/dist/agent/tools/shell.js +174 -47
  222. package/dist/agent/tools/tool_search.js +3 -2
  223. package/dist/agent/tools/types.d.ts +28 -0
  224. package/dist/agent/tools/verify_artifact.d.ts +2 -0
  225. package/dist/agent/tools/verify_artifact.js +60 -0
  226. package/dist/agent/tools/workflow.js +1 -0
  227. package/dist/app/activity.d.ts +6 -1
  228. package/dist/app/activity.js +81 -12
  229. package/dist/app/agent_runner.d.ts +6 -1
  230. package/dist/app/agent_runner.js +34 -19
  231. package/dist/app/command_context.js +106 -10
  232. package/dist/app/controller.d.ts +15 -4
  233. package/dist/app/controller.js +29 -3
  234. package/dist/app/escape_stop.d.ts +11 -0
  235. package/dist/app/escape_stop.js +15 -0
  236. package/dist/app/liveness.d.ts +6 -4
  237. package/dist/app/liveness.js +13 -3
  238. package/dist/app/model_catalog_cache.d.ts +5 -0
  239. package/dist/app/model_catalog_cache.js +138 -0
  240. package/dist/app/ordered_transcript.js +43 -4
  241. package/dist/app/prompt_turn.d.ts +14 -0
  242. package/dist/app/prompt_turn.js +53 -0
  243. package/dist/app/recap.d.ts +3 -0
  244. package/dist/app/recap.js +9 -3
  245. package/dist/app/restart.d.ts +3 -2
  246. package/dist/app/restart.js +22 -7
  247. package/dist/app/rewind.d.ts +3 -3
  248. package/dist/app/rewind.js +3 -3
  249. package/dist/app/selection_completion.d.ts +17 -2
  250. package/dist/app/selection_completion.js +84 -9
  251. package/dist/app/session_manager.d.ts +38 -6
  252. package/dist/app/session_manager.js +263 -60
  253. package/dist/app/session_messages.d.ts +3 -0
  254. package/dist/app/session_messages.js +60 -0
  255. package/dist/app/task_scope_router.d.ts +20 -0
  256. package/dist/app/task_scope_router.js +173 -0
  257. package/dist/app/transcript_window.d.ts +2 -0
  258. package/dist/app/transcript_window.js +4 -0
  259. package/dist/app/workspace_admission_details.d.ts +3 -0
  260. package/dist/app/workspace_admission_details.js +26 -0
  261. package/dist/app/workspace_layout_controller.d.ts +11 -0
  262. package/dist/app/workspace_layout_controller.js +88 -0
  263. package/dist/app/workspace_monitor.d.ts +1 -0
  264. package/dist/app/workspace_monitor.js +216 -0
  265. package/dist/app/workspace_presets.d.ts +29 -0
  266. package/dist/app/workspace_presets.js +192 -0
  267. package/dist/attention/queue.d.ts +37 -0
  268. package/dist/attention/queue.js +183 -0
  269. package/dist/bench/rf_shared.d.ts +2 -0
  270. package/dist/board/binding.d.ts +42 -0
  271. package/dist/board/binding.js +38 -0
  272. package/dist/board/client.d.ts +42 -0
  273. package/dist/board/client.js +60 -0
  274. package/dist/cli.js +1 -1
  275. package/dist/cli_args.js +19 -17
  276. package/dist/cli_main.js +110 -13
  277. package/dist/cli_ratatui.d.ts +183 -16
  278. package/dist/cli_ratatui.js +3989 -1255
  279. package/dist/components/ActivityLine.d.ts +3 -2
  280. package/dist/components/ActivityLine.js +2 -2
  281. package/dist/components/InputArea.d.ts +19 -1
  282. package/dist/components/InputArea.js +264 -190
  283. package/dist/components/MessageList.d.ts +2 -0
  284. package/dist/components/MessageList.js +3 -1
  285. package/dist/components/SingleMessage.d.ts +2 -0
  286. package/dist/components/SingleMessage.js +4 -2
  287. package/dist/components/StatusBar.d.ts +4 -2
  288. package/dist/components/StatusBar.js +3 -1
  289. package/dist/conductor_branch.js +3 -0
  290. package/dist/config/api_retry.d.ts +6 -1
  291. package/dist/config/api_retry.js +19 -1
  292. package/dist/config/defaults.d.ts +2 -1
  293. package/dist/config/defaults.js +9 -2
  294. package/dist/config/message_display.d.ts +1 -0
  295. package/dist/config/message_display.js +17 -2
  296. package/dist/config/permissions.d.ts +21 -0
  297. package/dist/config/permissions.js +89 -0
  298. package/dist/config/resolved.d.ts +2 -2
  299. package/dist/config/types.d.ts +32 -5
  300. package/dist/config.d.ts +38 -4
  301. package/dist/config.js +290 -42
  302. package/dist/context/project_intelligence.d.ts +44 -0
  303. package/dist/context/project_intelligence.js +246 -0
  304. package/dist/desktop/cli_launch.d.ts +8 -0
  305. package/dist/desktop/cli_launch.js +6 -0
  306. package/dist/desktop/cli_shim.d.ts +8 -0
  307. package/dist/desktop/cli_shim.js +120 -0
  308. package/dist/desktop/runtime.d.ts +16 -0
  309. package/dist/desktop/runtime.js +161 -0
  310. package/dist/desktop/worker_launch.d.ts +7 -0
  311. package/dist/desktop/worker_launch.js +7 -0
  312. package/dist/diagnostics/cargo_mutants_selection.d.ts +27 -0
  313. package/dist/diagnostics/cargo_mutants_selection.js +48 -0
  314. package/dist/diagnostics/native_terminal_benchmark.d.ts +58 -0
  315. package/dist/diagnostics/native_terminal_benchmark.js +1247 -0
  316. package/dist/diagnostics/session_evidence_package.d.ts +40 -0
  317. package/dist/diagnostics/session_evidence_package.js +234 -0
  318. package/dist/diagnostics/session_export.d.ts +93 -0
  319. package/dist/diagnostics/session_export.js +634 -0
  320. package/dist/emulation/tool_adapters.js +48 -18
  321. package/dist/emulation/ztc_addendum.d.ts +1 -0
  322. package/dist/emulation/ztc_addendum.js +13 -12
  323. package/dist/environment/service_runner.d.ts +1 -0
  324. package/dist/environment/service_runner.js +68 -0
  325. package/dist/environment/store.d.ts +120 -0
  326. package/dist/environment/store.js +387 -0
  327. package/dist/events.d.ts +40 -1
  328. package/dist/events.js +10 -17
  329. package/dist/goal_contract.d.ts +25 -0
  330. package/dist/goal_contract.js +44 -0
  331. package/dist/headless.d.ts +31 -0
  332. package/dist/headless.js +578 -70
  333. package/dist/headless_cli.js +8 -0
  334. package/dist/headless_cli_args.d.ts +1 -0
  335. package/dist/headless_cli_args.js +1 -0
  336. package/dist/intake/cli.d.ts +1 -0
  337. package/dist/intake/cli.js +33 -0
  338. package/dist/intake/format.d.ts +2 -0
  339. package/dist/intake/format.js +14 -0
  340. package/dist/intake/notifications.d.ts +16 -0
  341. package/dist/intake/notifications.js +132 -0
  342. package/dist/intake/store.d.ts +56 -0
  343. package/dist/intake/store.js +238 -0
  344. package/dist/library.d.ts +8 -0
  345. package/dist/library.js +19 -10
  346. package/dist/mcp/client.d.ts +1 -0
  347. package/dist/mcp/client.js +20 -0
  348. package/dist/modes/builtin/plan.yaml +2 -2
  349. package/dist/modes/handlers.js +1 -1
  350. package/dist/onboarding/first_run.d.ts +3 -0
  351. package/dist/onboarding/first_run.js +33 -25
  352. package/dist/onboarding/setup.d.ts +32 -0
  353. package/dist/onboarding/setup.js +133 -0
  354. package/dist/onboarding/setup_agent_health.d.ts +17 -0
  355. package/dist/onboarding/setup_agent_health.js +79 -0
  356. package/dist/onboarding/setup_environment.d.ts +66 -0
  357. package/dist/onboarding/setup_environment.js +219 -0
  358. package/dist/onboarding/setup_workspace.d.ts +17 -0
  359. package/dist/onboarding/setup_workspace.js +129 -0
  360. package/dist/optimize/adapters/index.d.ts +4 -1
  361. package/dist/optimize/adapters/index.js +7 -0
  362. package/dist/optimize/adapters/kernelbench.js +14 -5
  363. package/dist/optimize/adapters/popcorn.js +3 -2
  364. package/dist/optimize/adapters/profile_benchmark.js +13 -7
  365. package/dist/optimize/adapters/rfbench.js +25 -14
  366. package/dist/optimize/adapters/types.d.ts +3 -0
  367. package/dist/optimize/adapters/zergpod.js +5 -2
  368. package/dist/optimize/baseline.js +10 -21
  369. package/dist/optimize/branch.js +9 -12
  370. package/dist/optimize/combine.js +2 -3
  371. package/dist/optimize/executor.js +34 -48
  372. package/dist/optimize/measurements.d.ts +55 -0
  373. package/dist/optimize/measurements.js +173 -0
  374. package/dist/optimize/results.d.ts +1 -0
  375. package/dist/optimize/results.js +11 -33
  376. package/dist/optimize/tge.js +2 -1
  377. package/dist/panes/initial_input.d.ts +19 -0
  378. package/dist/panes/initial_input.js +206 -0
  379. package/dist/panes/labels.d.ts +16 -0
  380. package/dist/panes/labels.js +42 -0
  381. package/dist/panes/model_catalog.d.ts +3 -3
  382. package/dist/panes/model_catalog.js +28 -4
  383. package/dist/panes/pane_registry.js +6 -2
  384. package/dist/panes/types.d.ts +3 -0
  385. package/dist/panes/ztc_launch.js +19 -0
  386. package/dist/plugin/optimization.d.ts +2 -0
  387. package/dist/plugin/optimization.js +1 -0
  388. package/dist/plugin/runtime.d.ts +2 -0
  389. package/dist/plugin/simulation.d.ts +6 -1
  390. package/dist/plugin/simulation_contract.d.ts +836 -1
  391. package/dist/plugin/simulation_documents.d.ts +22 -0
  392. package/dist/plugin/simulation_documents.js +1 -0
  393. package/dist/plugin/simulation_interventions.d.ts +103 -0
  394. package/dist/plugin/simulation_interventions.js +1 -0
  395. package/dist/plugin/simulation_living.d.ts +1 -0
  396. package/dist/plugin/simulation_living.js +3 -0
  397. package/dist/plugin/simulation_meetings.d.ts +121 -0
  398. package/dist/plugin/simulation_meetings.js +1 -0
  399. package/dist/plugin/simulation_story_review.d.ts +111 -0
  400. package/dist/plugin/simulation_story_review.js +1 -0
  401. package/dist/plugin/simulation_storyteller.d.ts +91 -0
  402. package/dist/plugin/simulation_storyteller.js +1 -0
  403. package/dist/plugin/simulation_structured.d.ts +2 -0
  404. package/dist/plugin/simulation_structured.js +2 -0
  405. package/dist/plugin/simulation_toolkit.d.ts +21 -0
  406. package/dist/plugin/simulation_toolkit.js +24 -0
  407. package/dist/prompts/tool_delegate_task.j2 +1 -1
  408. package/dist/remote-broker/Dockerfile +10 -0
  409. package/dist/remote-broker/archive.py +1227 -0
  410. package/dist/remote-broker/cutover.py +761 -0
  411. package/dist/remote-broker/requirements.txt +5 -0
  412. package/dist/remote-broker/resources.json +6 -0
  413. package/dist/remote-broker/resources.write-staging.example.json +18 -0
  414. package/dist/remote-broker/retained.py +686 -0
  415. package/dist/remote-broker/retained_cleanup.py +550 -0
  416. package/dist/remote-broker/server.py +648 -0
  417. package/dist/remote-broker/worker.py +1007 -0
  418. package/dist/router_auth.d.ts +31 -0
  419. package/dist/router_auth.js +155 -9
  420. package/dist/runbooks/catalog.d.ts +3 -0
  421. package/dist/runbooks/catalog.js +26 -0
  422. package/dist/runbooks/library.d.ts +11 -0
  423. package/dist/runbooks/library.js +95 -0
  424. package/dist/runbooks/package.d.ts +43 -0
  425. package/dist/runbooks/package.js +102 -0
  426. package/dist/session.d.ts +65 -13
  427. package/dist/session.js +548 -43
  428. package/dist/session_handoff.d.ts +25 -0
  429. package/dist/session_handoff.js +322 -0
  430. package/dist/session_handoff_contract.d.ts +89 -0
  431. package/dist/session_handoff_contract.js +179 -0
  432. package/dist/session_media.d.ts +41 -0
  433. package/dist/session_media.js +357 -0
  434. package/dist/session_ownership.d.ts +16 -0
  435. package/dist/session_ownership.js +221 -0
  436. package/dist/session_public.d.ts +10 -2
  437. package/dist/session_public.js +6 -1
  438. package/dist/simulation/dynamic_history.d.ts +42 -0
  439. package/dist/simulation/dynamic_history.js +173 -0
  440. package/dist/simulation/engines/swarm/pane_manager.js +7 -6
  441. package/dist/simulation/inference.d.ts +3 -1
  442. package/dist/simulation/inference.js +19 -1
  443. package/dist/simulation/intervention_generation.d.ts +27 -0
  444. package/dist/simulation/intervention_generation.js +246 -0
  445. package/dist/simulation/intervention_material.d.ts +4 -0
  446. package/dist/simulation/intervention_material.js +81 -0
  447. package/dist/simulation/living/context.d.ts +3130 -0
  448. package/dist/simulation/living/context.js +944 -0
  449. package/dist/simulation/living/definer.d.ts +12 -0
  450. package/dist/simulation/living/definer.js +223 -0
  451. package/dist/simulation/living/definition.d.ts +257 -0
  452. package/dist/simulation/living/definition.js +341 -0
  453. package/dist/simulation/living/frame.d.ts +259 -0
  454. package/dist/simulation/living/frame.js +223 -0
  455. package/dist/simulation/living/identifiers.d.ts +2 -0
  456. package/dist/simulation/living/identifiers.js +12 -0
  457. package/dist/simulation/living/index.d.ts +15 -0
  458. package/dist/simulation/living/index.js +15 -0
  459. package/dist/simulation/living/inference.d.ts +219 -0
  460. package/dist/simulation/living/inference.js +576 -0
  461. package/dist/simulation/living/mechanics.d.ts +54 -0
  462. package/dist/simulation/living/mechanics.js +588 -0
  463. package/dist/simulation/living/model-input.d.ts +25 -0
  464. package/dist/simulation/living/model-input.js +215 -0
  465. package/dist/simulation/living/open-world.d.ts +257 -0
  466. package/dist/simulation/living/open-world.js +102 -0
  467. package/dist/simulation/living/projection.d.ts +7 -0
  468. package/dist/simulation/living/projection.js +31 -0
  469. package/dist/simulation/living/recall.d.ts +17 -0
  470. package/dist/simulation/living/recall.js +25 -0
  471. package/dist/simulation/living/reduce.d.ts +15 -0
  472. package/dist/simulation/living/reduce.js +1853 -0
  473. package/dist/simulation/living/replay.d.ts +6 -0
  474. package/dist/simulation/living/replay.js +22 -0
  475. package/dist/simulation/living/runtime.d.ts +140 -0
  476. package/dist/simulation/living/runtime.js +3020 -0
  477. package/dist/simulation/living/shared-kinds.d.ts +24 -0
  478. package/dist/simulation/living/shared-kinds.js +96 -0
  479. package/dist/simulation/living/types.d.ts +2785 -0
  480. package/dist/simulation/living/types.js +669 -0
  481. package/dist/simulation/llm.d.ts +3 -1
  482. package/dist/simulation/llm.js +90 -30
  483. package/dist/simulation/memory/embedding.d.ts +1 -1
  484. package/dist/simulation/memory/embedding.js +9 -3
  485. package/dist/simulation/memory/filesystem.d.ts +2 -0
  486. package/dist/simulation/memory/filesystem.js +5 -1
  487. package/dist/simulation/memory/filesystem_file_tree.d.ts +4 -1
  488. package/dist/simulation/memory/filesystem_file_tree.js +41 -10
  489. package/dist/simulation/memory/filesystem_invariants.js +1 -2
  490. package/dist/simulation/memory/filesystem_types.d.ts +1 -0
  491. package/dist/simulation/memory/memory.d.ts +2 -0
  492. package/dist/simulation/memory/memory.js +5 -1
  493. package/dist/simulation/orchestration/intent.js +0 -2
  494. package/dist/simulation/orchestration/lifecycle.js +0 -2
  495. package/dist/simulation/plugin_host.d.ts +25 -1
  496. package/dist/simulation/plugin_host.js +334 -17
  497. package/dist/simulation/session_documents.d.ts +20 -0
  498. package/dist/simulation/session_documents.js +62 -0
  499. package/dist/simulation/session_input_validation.d.ts +43 -0
  500. package/dist/simulation/session_input_validation.js +364 -0
  501. package/dist/simulation/session_inputs.d.ts +32 -0
  502. package/dist/simulation/session_inputs.js +154 -0
  503. package/dist/simulation/telemetry.d.ts +11 -14
  504. package/dist/simulation/telemetry.js +177 -54
  505. package/dist/simulation/toolkit/bounded_turns.d.ts +13 -0
  506. package/dist/simulation/toolkit/bounded_turns.js +80 -0
  507. package/dist/simulation/toolkit/dynamic_agents.d.ts +25 -0
  508. package/dist/simulation/toolkit/dynamic_agents.js +218 -0
  509. package/dist/simulation/toolkit/dynamic_digest.d.ts +1 -0
  510. package/dist/simulation/toolkit/dynamic_digest.js +8 -0
  511. package/dist/simulation/toolkit/dynamic_documents.d.ts +7 -0
  512. package/dist/simulation/toolkit/dynamic_documents.js +71 -0
  513. package/dist/simulation/toolkit/dynamic_driver.d.ts +8 -0
  514. package/dist/simulation/toolkit/dynamic_driver.js +269 -0
  515. package/dist/simulation/toolkit/dynamic_game.d.ts +53 -0
  516. package/dist/simulation/toolkit/dynamic_game.js +805 -0
  517. package/dist/simulation/toolkit/dynamic_knowledge.d.ts +15 -0
  518. package/dist/simulation/toolkit/dynamic_knowledge.js +91 -0
  519. package/dist/simulation/toolkit/dynamic_mechanics.d.ts +22 -0
  520. package/dist/simulation/toolkit/dynamic_mechanics.js +910 -0
  521. package/dist/simulation/toolkit/dynamic_meetings.d.ts +239 -0
  522. package/dist/simulation/toolkit/dynamic_meetings.js +350 -0
  523. package/dist/simulation/toolkit/dynamic_progress.d.ts +131 -0
  524. package/dist/simulation/toolkit/dynamic_progress.js +214 -0
  525. package/dist/simulation/toolkit/dynamic_projection.d.ts +9 -0
  526. package/dist/simulation/toolkit/dynamic_projection.js +219 -0
  527. package/dist/simulation/toolkit/dynamic_runtime.d.ts +412 -0
  528. package/dist/simulation/toolkit/dynamic_runtime.js +6536 -0
  529. package/dist/simulation/toolkit/dynamic_state.d.ts +111 -0
  530. package/dist/simulation/toolkit/dynamic_state.js +1967 -0
  531. package/dist/simulation/toolkit/dynamic_story_review.d.ts +508 -0
  532. package/dist/simulation/toolkit/dynamic_story_review.js +333 -0
  533. package/dist/simulation/toolkit/dynamic_storyteller.d.ts +77 -0
  534. package/dist/simulation/toolkit/dynamic_storyteller.js +114 -0
  535. package/dist/simulation/toolkit/dynamic_storyteller_runtime.d.ts +26 -0
  536. package/dist/simulation/toolkit/dynamic_storyteller_runtime.js +126 -0
  537. package/dist/simulation/toolkit/dynamic_world.d.ts +22 -0
  538. package/dist/simulation/toolkit/dynamic_world.js +377 -0
  539. package/dist/simulation/toolkit/structured_output.d.ts +5 -0
  540. package/dist/simulation/toolkit/structured_output.js +321 -0
  541. package/dist/simulation/types/world.d.ts +2 -0
  542. package/dist/simulation/world/artifact_store.js +1 -1
  543. package/dist/simulation/world/memory_manager.d.ts +5 -0
  544. package/dist/simulation/world/memory_manager.js +17 -2
  545. package/dist/simulation/world/state.d.ts +3 -2
  546. package/dist/simulation/world/state.js +15 -5
  547. package/dist/skills/bundled/measurement-validation/SKILL.md +144 -0
  548. package/dist/terminal_attach.d.ts +1 -0
  549. package/dist/terminal_attach.js +113 -0
  550. package/dist/tool_progress.d.ts +3 -0
  551. package/dist/tool_progress.js +27 -0
  552. package/dist/types.d.ts +145 -10
  553. package/dist/types.js +3 -0
  554. package/dist/ui/core/input.d.ts +3 -0
  555. package/dist/ui/core/input_segments.d.ts +18 -1
  556. package/dist/ui/core/input_segments.js +131 -47
  557. package/dist/ui/core/input_state.d.ts +12 -0
  558. package/dist/ui/core/layout_yoga.d.ts +1 -1
  559. package/dist/ui/core/turn_metadata.d.ts +5 -0
  560. package/dist/ui/core/turn_metadata.js +22 -0
  561. package/dist/ui/ink/render.d.ts +2 -1
  562. package/dist/ui/ink/render.js +6 -5
  563. package/dist/ui/ratatui/headless_pane_manager.d.ts +14 -1
  564. package/dist/ui/ratatui/headless_pane_manager.js +293 -104
  565. package/dist/ui/ratatui/index.d.ts +1 -0
  566. package/dist/ui/ratatui/input.d.ts +4 -0
  567. package/dist/ui/ratatui/input.js +15 -0
  568. package/dist/ui/ratatui/ipc_path.d.ts +2 -0
  569. package/dist/ui/ratatui/ipc_path.js +29 -1
  570. package/dist/ui/ratatui/mux_persistence.d.ts +3 -1
  571. package/dist/ui/ratatui/mux_persistence.js +139 -1
  572. package/dist/ui/ratatui/pane_relay.d.ts +1 -1
  573. package/dist/ui/ratatui/pane_relay.js +55 -27
  574. package/dist/ui/ratatui/process.d.ts +17 -1
  575. package/dist/ui/ratatui/process.js +80 -7
  576. package/dist/ui/ratatui/protocol.d.ts +236 -1
  577. package/dist/ui/ratatui/protocol.js +90 -0
  578. package/dist/ui/scrollback.d.ts +2 -1
  579. package/dist/ui/scrollback.js +9 -4
  580. package/dist/ui/stream_typewriter.d.ts +8 -3
  581. package/dist/ui/stream_typewriter.js +30 -1
  582. package/dist/ui/streaming_scrollback.d.ts +1 -0
  583. package/dist/ui/streaming_scrollback.js +1 -1
  584. package/dist/ui/transcript_render_cache.js +10 -0
  585. package/dist/ui/views/activity_line.d.ts +5 -3
  586. package/dist/ui/views/activity_line.js +65 -7
  587. package/dist/ui/views/app.d.ts +6 -3
  588. package/dist/ui/views/app.js +17 -6
  589. package/dist/ui/views/completion_menu.js +10 -5
  590. package/dist/ui/views/input_area.d.ts +7 -3
  591. package/dist/ui/views/input_area.js +15 -9
  592. package/dist/ui/views/message_list.d.ts +4 -1
  593. package/dist/ui/views/message_list.js +89 -19
  594. package/dist/ui/views/queue_panel.d.ts +3 -1
  595. package/dist/ui/views/queue_panel.js +9 -2
  596. package/dist/ui/views/status_bar.d.ts +4 -2
  597. package/dist/ui/views/status_bar.js +28 -13
  598. package/dist/ui/views/theme.d.ts +2 -0
  599. package/dist/ui/views/theme.js +2 -0
  600. package/dist/ui/widgets/color_panel.js +18 -0
  601. package/dist/ui/widgets/form.js +8 -0
  602. package/dist/ui/widgets/log_view.js +7 -0
  603. package/dist/ui/widgets/navigator_panel.js +8 -0
  604. package/dist/ui/widgets/prompt_viewer.js +2 -0
  605. package/dist/ui/widgets/questionnaire.d.ts +2 -0
  606. package/dist/ui/widgets/questionnaire.js +79 -16
  607. package/dist/ui/widgets/resume_panel.d.ts +2 -0
  608. package/dist/ui/widgets/resume_panel.js +26 -15
  609. package/dist/ui/widgets/rewind_panel.d.ts +2 -2
  610. package/dist/ui/widgets/rewind_panel.js +4 -2
  611. package/dist/ui/widgets/select.js +16 -27
  612. package/dist/ui/widgets/settings_panel.js +16 -0
  613. package/dist/ui/widgets/status_line_panel.d.ts +1 -0
  614. package/dist/ui/widgets/status_line_panel.js +30 -4
  615. package/dist/ui/widgets/text_input.d.ts +2 -0
  616. package/dist/ui/widgets/text_input.js +15 -1
  617. package/dist/ui/widgets/types.d.ts +2 -0
  618. package/dist/usage_projection.d.ts +24 -0
  619. package/dist/usage_projection.js +130 -0
  620. package/dist/usage_snapshot.d.ts +36 -0
  621. package/dist/usage_snapshot.js +131 -0
  622. package/dist/utils/assistant_message.d.ts +2 -0
  623. package/dist/utils/assistant_message.js +5 -0
  624. package/dist/utils/atomic_write.d.ts +6 -2
  625. package/dist/utils/atomic_write.js +29 -4
  626. package/dist/utils/checked_shell.d.ts +25 -0
  627. package/dist/utils/checked_shell.js +107 -0
  628. package/dist/utils/compaction.d.ts +4 -1
  629. package/dist/utils/compaction.js +31 -7
  630. package/dist/utils/context.d.ts +4 -4
  631. package/dist/utils/context.js +14 -12
  632. package/dist/utils/deepseek.d.ts +2 -2
  633. package/dist/utils/deepseek.js +13 -5
  634. package/dist/utils/ephemeral.js +4 -0
  635. package/dist/utils/ephemeral_tools.d.ts +18 -0
  636. package/dist/utils/ephemeral_tools.js +97 -0
  637. package/dist/utils/jev_client.d.ts +4 -0
  638. package/dist/utils/jev_client.js +15 -0
  639. package/dist/utils/model_cache.d.ts +15 -0
  640. package/dist/utils/model_cache.js +143 -0
  641. package/dist/utils/models.d.ts +4 -2
  642. package/dist/utils/models.js +12 -16
  643. package/dist/utils/reasoning.d.ts +8 -1
  644. package/dist/utils/reasoning.js +31 -11
  645. package/dist/utils/router_catalog.d.ts +49 -0
  646. package/dist/utils/router_catalog.js +271 -0
  647. package/dist/utils/sandbox.d.ts +9 -0
  648. package/dist/utils/sandbox.js +118 -15
  649. package/dist/utils/shell.d.ts +7 -0
  650. package/dist/utils/shell.js +98 -34
  651. package/dist/utils/subprocess_env.d.ts +3 -0
  652. package/dist/utils/subprocess_env.js +27 -1
  653. package/dist/web/accounts_mirror.d.ts +3 -1
  654. package/dist/web/accounts_mirror.js +13 -9
  655. package/dist/web/child_publication.d.ts +17 -0
  656. package/dist/web/child_publication.js +45 -0
  657. package/dist/web/mirror_authenticator.d.ts +31 -11
  658. package/dist/web/mirror_authenticator.js +67 -17
  659. package/dist/web/mirror_client.d.ts +31 -4
  660. package/dist/web/mirror_client.js +189 -23
  661. package/dist/web/mirror_stream.d.ts +84 -22
  662. package/dist/web/mirror_stream.js +676 -95
  663. package/dist/web/observer_query_redaction.d.ts +6 -0
  664. package/dist/web/observer_query_redaction.js +58 -0
  665. package/dist/web/pane_registry.d.ts +2 -0
  666. package/dist/web/pane_registry.js +86 -22
  667. package/dist/web/tool_image.d.ts +6 -0
  668. package/dist/web/tool_image.js +17 -0
  669. package/dist/web/view_plugin.d.ts +14 -0
  670. package/dist/web/view_plugin.js +23 -1
  671. package/dist/worker/executor.js +31 -12
  672. package/dist/worker/index.d.ts +1 -0
  673. package/dist/worker/toolsets.js +3 -1
  674. package/dist/worker/types.d.ts +12 -1
  675. package/dist/workflows/registry.js +1 -0
  676. package/dist/workflows/registry_handle.d.ts +2 -0
  677. package/dist/workflows/runtime.d.ts +2 -0
  678. package/dist/workflows/runtime.js +1 -0
  679. package/dist/workspace_agent.d.ts +7 -0
  680. package/dist/workspace_agent.js +36 -0
  681. package/dist/workspace_collision.d.ts +76 -0
  682. package/dist/workspace_collision.js +688 -0
  683. package/dist/workspace_layout.d.ts +18 -0
  684. package/dist/workspace_layout.js +121 -0
  685. package/dist/workspace_runtime.d.ts +44 -0
  686. package/dist/workspace_runtime.js +82 -0
  687. package/dist/workspace_session_context.d.ts +62 -0
  688. package/dist/workspace_session_context.js +160 -0
  689. package/dist/zlm-embed.mjs +32518 -9615
  690. package/dist/zlm.js +1 -0
  691. package/node_modules/@zerg/model-contracts/LICENSE.md +375 -0
  692. package/node_modules/@zerg/model-contracts/README.md +90 -0
  693. package/node_modules/@zerg/model-contracts/index.d.ts +20 -0
  694. package/node_modules/@zerg/model-contracts/index.js +223 -0
  695. package/node_modules/@zerg/model-contracts/package.json +8 -0
  696. package/node_modules/glob/node_modules/brace-expansion/index.js +78 -22
  697. package/node_modules/glob/node_modules/brace-expansion/package.json +1 -1
  698. package/node_modules/readdir-glob/node_modules/brace-expansion/index.js +78 -22
  699. package/node_modules/readdir-glob/node_modules/brace-expansion/package.json +1 -1
  700. package/package.json +45 -24
  701. package/packages/model-contracts/LICENSE.md +375 -0
  702. package/packages/model-contracts/README.md +90 -0
  703. package/packages/model-contracts/index.d.ts +20 -0
  704. package/packages/model-contracts/index.js +223 -0
  705. package/packages/model-contracts/package.json +8 -0
  706. package/remote-broker/Dockerfile +10 -0
  707. package/remote-broker/README.md +308 -0
  708. package/remote-broker/archive.py +1227 -0
  709. package/remote-broker/cutover.py +761 -0
  710. package/remote-broker/requirements.txt +5 -0
  711. package/remote-broker/resources.example.json +6 -0
  712. package/remote-broker/resources.write-staging.example.json +18 -0
  713. package/remote-broker/retained.py +686 -0
  714. package/remote-broker/retained_cleanup.py +550 -0
  715. package/remote-broker/server.py +648 -0
  716. package/scripts/build-remote-broker.mjs +13 -0
  717. package/scripts/ensure-local-packages.mjs +6 -0
  718. package/scripts/node-pty-helpers.mjs +103 -0
@@ -0,0 +1,333 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ import { evaluateChapterStanding } from './dynamic_progress.js';
4
+ import { dynamicHistory } from '../dynamic_history.js';
5
+ import { compileStrictSimulationSchema } from './structured_output.js';
6
+ import { assertDynamicInferenceKnowledge, dynamicPrivateKnowledge, dynamicPublishedKnowledge } from './dynamic_knowledge.js';
7
+ export const STORY_REVIEW_INTERVAL = 5;
8
+ export const STORY_REVIEW_INPUT_BYTES = 65_536;
9
+ export const STORY_REVIEW_TIMEOUT_MS = 30_000;
10
+ export const STORY_REVIEW_MAX_TOKENS = 2_048;
11
+ const hash = (value) => createHash('sha256').update(value).digest('hex');
12
+ function canonicalJson(value) {
13
+ return JSON.stringify(value, (_key, item) => item !== null && typeof item === 'object' && !Array.isArray(item)
14
+ ? Object.fromEntries(Object.entries(item).sort(([left], [right]) => left.localeCompare(right))) : item);
15
+ }
16
+ function requestBytes(packet) {
17
+ const request = storyReviewCall(packet);
18
+ const { responseSchema, ...facts } = JSON.parse(request.input);
19
+ const outputSchema = compileStrictSimulationSchema(responseSchema);
20
+ return Math.max(Buffer.byteLength(request.system + request.input), Buffer.byteLength(request.system + JSON.stringify(facts) + JSON.stringify(outputSchema)));
21
+ }
22
+ const id = z.string().min(1).max(128);
23
+ const sha = z.string().regex(/^[a-f0-9]{64}$/u);
24
+ const text = (maximum) => z.string().trim().min(1).max(maximum);
25
+ const evidenceSchema = z.object({
26
+ eventIds: z.array(id).min(1).max(16),
27
+ objects: z.array(z.object({ objectId: id, version: z.number().int().positive() }).strict()).max(16),
28
+ resources: z.array(z.object({ resourceId: id, value: z.number().finite() }).strict()).max(32),
29
+ }).strict();
30
+ const identityShape = { version: z.literal(1), reviewId: sha, basedOnRevision: z.number().int().positive(),
31
+ evidenceDigest: sha, explanation: text(600), evidence: evidenceSchema };
32
+ export const storyReviewDecisionSchema = z.discriminatedUnion('kind', [
33
+ z.object({ ...identityShape, kind: z.literal('close'), title: text(160), narrative: text(2_000),
34
+ outcome: z.enum(['triumph', 'mixed', 'collapse']), unresolvedStakes: z.array(text(400)).max(8) }).strict(),
35
+ z.object({ ...identityShape, kind: z.literal('continue'), unresolvedStake: text(400) }).strict(),
36
+ z.object({ ...identityShape, kind: z.literal('stalled'), unresolvedStake: text(400), requestPressure: z.boolean() }).strict(),
37
+ ]);
38
+ export const storyReviewReceiptSchema = z.object({
39
+ version: z.literal(1), revision: z.number().int().positive(), acceptedBeat: z.number().int().positive(),
40
+ reviewId: sha, evidenceDigest: sha, model: z.enum(['gpt-5.6-sol', 'modal/deepseek-v4.1-flash']), reasoningEffort: z.literal('none'),
41
+ inputDigest: sha, outputDigest: sha, outputBytes: z.number().int().min(0).max(Number.MAX_SAFE_INTEGER),
42
+ requested: z.boolean(), status: z.enum(['accepted', 'rejected']), decision: storyReviewDecisionSchema.nullable(), failureCode: id.optional(),
43
+ }).strict().refine(value => value.status === 'accepted'
44
+ ? value.requested && value.decision !== null && value.failureCode === undefined
45
+ : value.decision === null && value.failureCode !== undefined);
46
+ const share = z.number().min(0).max(1);
47
+ const chapterStandingSchema = z.object({ act: z.number().int().min(1).max(3), acts: z.number().int().min(1).max(3),
48
+ decisions: z.number().int().min(0), workingDecisions: z.number().int().min(0), decisionsLeft: z.number().int().min(0),
49
+ goals: z.array(z.object({ id, label: text(160), met: z.boolean(), share }).strict()).min(1).max(32), score: share,
50
+ dangers: z.array(z.object({ resourceId: id, label: text(160), value: z.number().finite(), bound: z.number().finite(), room: share }).strict()).max(64),
51
+ result: z.enum(['open', 'win', 'mixed', 'loss']),
52
+ lossCause: z.union([z.null(), z.object({ kind: z.literal('meter'), resourceId: id, label: text(160) }).strict(), z.object({ kind: z.literal('out-of-decisions') }).strict()]) }).strict();
53
+ const chapterResultsSchema = z.array(z.object({ act: z.number().int().min(1).max(3), result: z.enum(['win', 'mixed', 'loss']),
54
+ revision: z.number().int().positive(), title: text(160), narrative: text(2_000) }).strict()).max(3);
55
+ export const storyReviewViewSchema = z.object({ version: z.literal(1), acceptedBeats: z.number().int().min(0),
56
+ nextReviewAtAcceptedBeat: z.number().int().positive(), last: storyReviewReceiptSchema.nullable(),
57
+ chapter: chapterStandingSchema.optional(), results: chapterResultsSchema.optional() }).strict();
58
+ export const storyEpisodeSchema = (world) => z.object({ version: z.literal(1),
59
+ origin: z.object({ objective: text(2_000), world }).strict(), acceptedBeats: z.number().int().min(0),
60
+ lastReview: storyReviewReceiptSchema.nullable(),
61
+ chapter: z.object({ startRevision: z.number().int().min(0), startResources: z.record(id, z.number().finite()), standing: chapterStandingSchema }).strict().optional(),
62
+ results: chapterResultsSchema.optional() }).strict();
63
+ export class StoryReviewError extends Error {
64
+ code;
65
+ request;
66
+ constructor(code, message, request) {
67
+ super(message);
68
+ this.code = code;
69
+ this.request = request;
70
+ this.name = 'StoryReviewError';
71
+ }
72
+ }
73
+ function publicStoryObject(object, visibleIds) {
74
+ return { ...structuredClone(object), links: object.links.filter(link => link.targetType !== 'object' || visibleIds.has(link.targetId)).map(link => ({ ...link })) };
75
+ }
76
+ export function publicStoryWorld(world, policy) {
77
+ const objects = world.domainObjects.filter(object => object.visibility.scope === 'world');
78
+ const visibleIds = new Set(objects.map(object => object.id));
79
+ return { resources: Object.fromEntries(policy.resources.filter(resource => resource.visibility !== 'private')
80
+ .map(resource => [resource.id, world.resources[resource.id]])), facts: [...world.facts],
81
+ domainObjects: objects.map(object => publicStoryObject(object, visibleIds)) };
82
+ }
83
+ function chapterStanding(policy, world, act, decisions, workingDecisions, revision, startResources) {
84
+ const open = publicStoryWorld(world, policy);
85
+ return evaluateChapterStanding({ rules: policy.milestones ?? [], act, decisions, workingDecisions, startResources,
86
+ frame: { revision, world: policy.resources.filter(resource => resource.visibility !== 'private').map(resource => ({ id: resource.id, label: resource.label,
87
+ value: open.resources[resource.id], minimum: resource.minimum, maximum: resource.maximum, initial: resource.initial, dangerDirection: resource.dangerDirection })),
88
+ domainObjects: open.domainObjects.map(object => ({ id: object.id, kind: object.kind, label: object.label, status: object.status, version: object.version,
89
+ ownerActorId: object.ownerActorId, data: {}, links: [], updatedRevision: object.provenance.updatedRevision })) } });
90
+ }
91
+ export function initialStoryEpisode(world, policy) {
92
+ const origin = publicStoryWorld(world, policy);
93
+ return { version: 1, origin: { objective: policy.definition.objective, world: origin }, acceptedBeats: 0, lastReview: null,
94
+ ...(policy.chapterVersion !== 1 ? {} : { chapter: { startRevision: 0, startResources: origin.resources,
95
+ standing: chapterStanding(policy, world, 1, 0, 0, 0, origin.resources) }, results: [] }) };
96
+ }
97
+ /** Every committed turn moves the episode the same way, live and in replay. A chapter result latches once it is no longer open. */
98
+ export function advanceStoryEpisode(episode, policy, entry, world) {
99
+ const next = { ...episode, acceptedBeats: episode.acceptedBeats + (entry.usedFallback ? 0 : 1) };
100
+ const chapter = episode.chapter;
101
+ if (policy.chapterVersion !== 1 || chapter === undefined || chapter.standing.result !== 'open')
102
+ return next;
103
+ const decided = !entry.usedFallback && entry.playerActionId !== null;
104
+ // Real work: the rules accepted an action that came from the player's pick, and it was not an abandonment.
105
+ const worked = decided && entry.gmProposal.domainActions.some(action => action.sourcePlayerActionId === entry.playerActionId
106
+ && action.mechanic !== 'abandon-work' && entry.acceptedActionIds.includes(action.id));
107
+ return { ...next, chapter: { ...chapter, standing: chapterStanding(policy, world, chapter.standing.act, chapter.standing.decisions + (decided ? 1 : 0), chapter.standing.workingDecisions + (worked ? 1 : 0), entry.revision, chapter.startResources) } };
108
+ }
109
+ const CHAPTER_OUTCOME = { win: 'triumph', mixed: 'mixed', loss: 'collapse' };
110
+ /** The words code uses when the model's closing words are missing or refused. */
111
+ export function plainChapterEnding(standing) {
112
+ const open = standing.goals.filter(goal => !goal.met).map(goal => goal.label).join('; ');
113
+ const met = standing.goals.filter(goal => goal.met).map(goal => goal.label).join('; ');
114
+ if (standing.result === 'win')
115
+ return { title: `Chapter ${standing.act} won`, narrative: `You met every goal: ${met}.` };
116
+ if (standing.result === 'mixed')
117
+ return { title: `Chapter ${standing.act}: a mixed result`, narrative: `You ran out of decisions part way.${met === '' ? '' : ` Met: ${met}.`} Still open: ${open}.` };
118
+ return { title: `Chapter ${standing.act} lost`, narrative: standing.lossCause?.kind === 'meter'
119
+ ? `${standing.lossCause.label} reached its limit. That ended the chapter.${open === '' ? '' : ` Still open: ${open}.`}`
120
+ : `You ran out of decisions. Still open: ${open}.` };
121
+ }
122
+ /**
123
+ * Applies a settled review to a chapter. Code has already decided the result; the receipt only supplies the words.
124
+ * A loss or the last act ends the run. Any other result is recorded and the next act opens in the same world.
125
+ */
126
+ export function closeStoryChapter(episode, policy, receipt, world, eventId) {
127
+ const chapter = episode.chapter;
128
+ if (policy.chapterVersion !== 1 || chapter === undefined || receipt.failureCode === STORY_REVIEW_INPUT_PENDING)
129
+ return null;
130
+ const { standing } = chapter;
131
+ const result = standing.result;
132
+ if (result === 'open')
133
+ return null;
134
+ const decision = receipt.status === 'accepted' && receipt.decision?.kind === 'close' ? receipt.decision : null;
135
+ const words = decision === null ? plainChapterEnding(standing) : { title: decision.title, narrative: decision.narrative };
136
+ const results = [...(episode.results ?? []), { act: standing.act, result, revision: receipt.revision, ...words }];
137
+ const ends = result === 'loss' || standing.act >= standing.acts;
138
+ const startResources = publicStoryWorld(world, policy).resources;
139
+ return { ends, ending: { ...words, outcome: CHAPTER_OUTCOME[result], causalEventIds: [...new Set([...(decision?.evidence.eventIds ?? []), eventId])] },
140
+ episode: { ...episode, lastReview: receipt, results, chapter: ends ? chapter
141
+ : { startRevision: receipt.revision, startResources, standing: chapterStanding(policy, world, standing.act + 1, 0, 0, receipt.revision, startResources) } } };
142
+ }
143
+ export function storyReviewView(episode) {
144
+ return { version: 1, acceptedBeats: episode.acceptedBeats,
145
+ nextReviewAtAcceptedBeat: (Math.floor(episode.acceptedBeats / STORY_REVIEW_INTERVAL) + 1) * STORY_REVIEW_INTERVAL,
146
+ last: episode.lastReview,
147
+ ...(episode.chapter === undefined ? {} : { chapter: episode.chapter.standing, results: episode.results ?? [] }) };
148
+ }
149
+ /** A close would strand accepted player input, so the engine keeps the receipt and a later review may close. */
150
+ export const STORY_REVIEW_INPUT_PENDING = 'story-review-input-pending';
151
+ export function deferStoryReviewClose(receipt) {
152
+ if (receipt.decision?.kind !== 'close')
153
+ return receipt;
154
+ return { ...receipt, status: 'rejected', decision: null, failureCode: STORY_REVIEW_INPUT_PENDING };
155
+ }
156
+ export function storyReviewFailed(state) {
157
+ // Under chapter rules a refused ending is replaced by plain words from code, so the player sees no failure.
158
+ return state.episode?.chapter === undefined && state.episode?.lastReview?.revision === state.revision && state.episode.lastReview.status === 'rejected'
159
+ && state.episode.lastReview.failureCode !== STORY_REVIEW_INPUT_PENDING;
160
+ }
161
+ export function storyReviewDue(state) {
162
+ if (state.episode === undefined || state.status !== 'active')
163
+ return false;
164
+ // Under chapter rules the model is asked for closing words only when code has already settled the result.
165
+ if (state.episode.chapter !== undefined)
166
+ return state.episode.chapter.standing.result !== 'open'
167
+ && state.episode.lastReview?.revision !== state.history.at(-1)?.revision;
168
+ return state.history.at(-1)?.usedFallback === false
169
+ && state.episode.acceptedBeats > 0 && state.episode.acceptedBeats % STORY_REVIEW_INTERVAL === 0
170
+ && state.episode.lastReview?.acceptedBeat !== state.episode.acceptedBeats;
171
+ }
172
+ const objectSchema = (properties) => ({ type: 'object', additionalProperties: false,
173
+ required: Object.keys(properties), properties });
174
+ const stringSchema = (maximum) => ({ type: 'string', minLength: 1, maxLength: maximum });
175
+ function responseSchema(reviewId, revision, evidenceDigest, settledOutcome) {
176
+ const array = (items, maximum, minimum = 0) => ({ type: 'array', items, minItems: minimum, maxItems: maximum });
177
+ const common = { version: { const: 1 }, reviewId: { const: reviewId }, basedOnRevision: { const: revision },
178
+ evidenceDigest: { const: evidenceDigest }, explanation: stringSchema(600), evidence: objectSchema({
179
+ eventIds: array(stringSchema(128), 16, 1),
180
+ objects: array(objectSchema({ objectId: stringSchema(128), version: { type: 'integer', minimum: 1 } }), 16),
181
+ resources: array(objectSchema({ resourceId: stringSchema(128), value: { type: 'number' } }), 32),
182
+ }) };
183
+ // Code has settled this chapter: the model may only close it, with the outcome code computed.
184
+ if (settledOutcome !== undefined)
185
+ return objectSchema({ decision: objectSchema({ kind: { const: 'close' }, ...common, title: stringSchema(160),
186
+ narrative: stringSchema(2_000), outcome: { const: settledOutcome }, unresolvedStakes: array(stringSchema(400), 8) }) });
187
+ return objectSchema({ decision: { anyOf: [objectSchema({ kind: { const: 'close' }, ...common, title: stringSchema(160), narrative: stringSchema(2_000),
188
+ outcome: { enum: ['triumph', 'mixed', 'collapse'] }, unresolvedStakes: array(stringSchema(400), 8) }),
189
+ objectSchema({ kind: { const: 'continue' }, ...common, unresolvedStake: stringSchema(400) }),
190
+ objectSchema({ kind: { const: 'stalled' }, ...common, unresolvedStake: stringSchema(400), requestPressure: { type: 'boolean' } })] } });
191
+ }
192
+ export function makeDynamicStoryReviewRequest(input) {
193
+ const { state, policy } = input;
194
+ if (policy.storyReviewVersion !== 1 || !state.episode || !storyReviewDue(state))
195
+ throw new StoryReviewError('story-review-not-due', 'This candidate is not due for a story review');
196
+ const history = dynamicHistory(state);
197
+ const current = publicStoryWorld(state.world, policy);
198
+ const available = current.domainObjects.length;
199
+ const visibleIds = new Set(current.domainObjects.map(object => object.id));
200
+ const objects = [...current.domainObjects].sort((a, b) => b.provenance.updatedRevision - a.provenance.updatedRevision || a.id.localeCompare(b.id)).slice(0, 16);
201
+ const prior = state.episode.lastReview;
202
+ const priorCauses = prior?.decision?.evidence.eventIds ?? [];
203
+ const recent = history.slice(-8);
204
+ const older = history.slice(0, -8).filter(entry => priorCauses.includes(entry.eventId) || entry.revision === 1).slice(-8);
205
+ const selected = [...older, ...recent];
206
+ const events = selected.map(entry => ({ eventId: entry.eventId, revision: entry.revision,
207
+ accepted: !entry.usedFallback, digest: hash(canonicalJson({ eventId: entry.eventId, revision: entry.revision,
208
+ event: entry.gmProposal.event, effects: entry.effects.filter(effect => effect.operation === 'resource.change'
209
+ ? Object.hasOwn(current.resources, effect.resourceId) : effect.operation === 'object.put' && effect.object.visibility.scope === 'world')
210
+ .map(effect => {
211
+ if (effect.operation !== 'object.put')
212
+ return effect;
213
+ const { sceneRetention: _retirement, ...visibleEffect } = effect;
214
+ return { ...visibleEffect, object: publicStoryObject(effect.object, visibleIds) };
215
+ }) })) }));
216
+ const originObjects = state.episode.origin.world.domainObjects.slice(0, 16);
217
+ const standing = policy.chapterVersion === 1 ? state.episode.chapter?.standing : undefined;
218
+ const settled = standing === undefined || standing.result === 'open' ? undefined : CHAPTER_OUTCOME[standing.result];
219
+ const evidence = { ...(standing === undefined ? {} : { chapter: { act: standing.act, acts: standing.acts, result: standing.result, decisions: standing.decisions,
220
+ goals: standing.goals.map(goal => ({ label: goal.label, met: goal.met })), lossCause: standing.lossCause } }),
221
+ origin: { ...state.episode.origin, world: { ...state.episode.origin.world, domainObjects: originObjects } },
222
+ current: { ...current, domainObjects: objects }, events, priorReview: prior,
223
+ coverage: { totalAcceptedBeats: state.episode.acceptedBeats, totalHistoryBeats: history.length,
224
+ includedRevisions: selected.map(entry => entry.revision), omittedHistoryBeats: history.length - selected.length,
225
+ narrativeEventIds: [], omittedNarrativeRecords: selected.length,
226
+ currentObjectsIncluded: objects.length, currentObjectsOmitted: available - objects.length,
227
+ originObjectsIncluded: originObjects.length, originObjectsOmitted: state.episode.origin.world.domainObjects.length - originObjects.length,
228
+ meaning: 'Only selected public records are shown. Omitted records remain stored and are unknown, not absent.' } };
229
+ const evidenceDigest = hash(canonicalJson(evidence));
230
+ const reviewId = hash(canonicalJson([state.gameKind, state.rulesVersion, state.seed, state.revision, state.episode.acceptedBeats, evidenceDigest]));
231
+ const packet = { version: 1, phase: 'story-review', game: { kind: state.gameKind, rulesVersion: state.rulesVersion },
232
+ reviewId, basedOnRevision: state.revision, acceptedBeat: state.episode.acceptedBeats, evidenceDigest,
233
+ ...evidence, recentDevelopments: [],
234
+ responseSchema: responseSchema(reviewId, state.revision, evidenceDigest, settled) };
235
+ if (requestBytes(packet) > STORY_REVIEW_INPUT_BYTES)
236
+ throw new StoryReviewError('story-review-budget-exceeded', 'Required story evidence exceeds its byte budget', storyReviewCall(packet));
237
+ for (const entry of [...selected].reverse()) {
238
+ const item = { eventId: entry.eventId, ...entry.gmProposal.event };
239
+ const recentDevelopments = [item, ...packet.recentDevelopments];
240
+ const coverage = { ...packet.coverage, narrativeEventIds: recentDevelopments.map(event => event.eventId),
241
+ omittedNarrativeRecords: selected.length - recentDevelopments.length };
242
+ const candidate = { ...packet, recentDevelopments, coverage };
243
+ if (requestBytes(candidate) <= STORY_REVIEW_INPUT_BYTES) {
244
+ packet.recentDevelopments = recentDevelopments;
245
+ packet.coverage = coverage;
246
+ }
247
+ }
248
+ packet.evidenceDigest = hash(canonicalJson({ ...evidence, coverage: packet.coverage }));
249
+ packet.reviewId = hash(canonicalJson([state.gameKind, state.rulesVersion, state.seed, state.revision, state.episode.acceptedBeats, packet.evidenceDigest]));
250
+ packet.responseSchema = responseSchema(packet.reviewId, state.revision, packet.evidenceDigest, settled);
251
+ return storyReviewCall(packet);
252
+ }
253
+ const EPISODE_REVIEW_SYSTEM = 'Assess this episode from the supplied public evidence. Close when its central situation reaches a meaningful conclusion; success or world perfection is not required. Preserve unresolved duties honestly. Continue for a concrete unresolved stake; quiet activity can be meaningful. Mark stalled only when the story lacks meaningful movement, not because characters choose silence. You may request a lawful environmental opportunity, never compel a character or invent effects, fulfilled promises, or achievements. Citations ground your judgment; the engine validates identity and authority. Return the supplied schema.';
254
+ const CHAPTER_ENDING_SYSTEM = 'The rules have already decided how this chapter ended: read chapter.result, chapter.goals and chapter.lossCause. Write the ending for the player: a short title and a narrative of two to four plain sentences that says what the player did, which goals they met or missed, and why the chapter ended this way. Use only the supplied public evidence. Do not explain your reasoning, do not judge whether the story should end, and do not change the outcome. Return kind close with the outcome given in the schema.';
255
+ function storyReviewCall(packet) {
256
+ const { responseSchema, ...facts } = packet;
257
+ return { role: 'game-master', model: 'gpt-5.6-sol', reasoningEffort: 'none', timeoutMs: STORY_REVIEW_TIMEOUT_MS,
258
+ maxTokens: STORY_REVIEW_MAX_TOKENS,
259
+ system: packet.chapter !== undefined ? CHAPTER_ENDING_SYSTEM : EPISODE_REVIEW_SYSTEM,
260
+ input: JSON.stringify({ ...JSON.parse(canonicalJson(facts)), responseSchema }) };
261
+ }
262
+ export function validateStoryReviewDecision(request, value) {
263
+ const parsed = storyReviewDecisionSchema.safeParse(value);
264
+ if (!parsed.success)
265
+ throw new StoryReviewError('story-review-invalid', 'The story decision does not match its strict contract');
266
+ const decision = parsed.data;
267
+ const packet = JSON.parse(request.input);
268
+ if (decision.reviewId !== packet.reviewId || decision.basedOnRevision !== packet.basedOnRevision || decision.evidenceDigest !== packet.evidenceDigest)
269
+ throw new StoryReviewError('story-review-identity-invalid', 'The story decision does not match its candidate evidence');
270
+ if (packet.chapter !== undefined && (decision.kind !== 'close' || decision.outcome !== CHAPTER_OUTCOME[packet.chapter.result]))
271
+ throw new StoryReviewError('story-review-outcome-invalid', 'Code settled this chapter; the ending must close it with that outcome');
272
+ const { evidence } = decision;
273
+ if (new Set(evidence.eventIds).size !== evidence.eventIds.length
274
+ || new Set(evidence.objects.map(item => item.objectId)).size !== evidence.objects.length
275
+ || new Set(evidence.resources.map(item => item.resourceId)).size !== evidence.resources.length
276
+ || evidence.eventIds.some(eventId => !packet.events.some((event) => event.eventId === eventId && event.accepted))
277
+ || evidence.objects.some(item => !packet.current.domainObjects.some((object) => object.id === item.objectId && object.version === item.version))
278
+ || evidence.resources.some(item => !Object.hasOwn(packet.current.resources, item.resourceId) || packet.current.resources[item.resourceId] !== item.value))
279
+ throw new StoryReviewError('story-review-evidence-invalid', 'The story decision cites unavailable or different public evidence');
280
+ return decision;
281
+ }
282
+ export function replayDynamicStoryReview(input) {
283
+ const request = makeDynamicStoryReviewRequest(input);
284
+ if (Buffer.byteLength(input.output) > 32_768)
285
+ throw new StoryReviewError('story-review-invalid', 'The story decision exceeds its response budget');
286
+ let value;
287
+ try {
288
+ value = JSON.parse(input.output);
289
+ }
290
+ catch {
291
+ throw new StoryReviewError('story-review-invalid', 'The story decision is not JSON');
292
+ }
293
+ const envelope = z.object({ decision: storyReviewDecisionSchema }).strict().safeParse(value);
294
+ if (!envelope.success)
295
+ throw new StoryReviewError('story-review-invalid', 'The story response does not match its strict decision envelope');
296
+ assertDynamicInferenceKnowledge({ request: JSON.stringify(request), output: input.output,
297
+ privateKnowledge: dynamicPrivateKnowledge(input.state), publishedKnowledge: dynamicPublishedKnowledge(input.state) });
298
+ const decision = validateStoryReviewDecision(request, envelope.data.decision);
299
+ return storyReviewReceipt(request, input.output, decision);
300
+ }
301
+ export function storyReviewReceipt(request, output, decision, failureCode, requested = true) {
302
+ const packet = JSON.parse(request.input);
303
+ return { version: 1, revision: packet.basedOnRevision, acceptedBeat: packet.acceptedBeat, reviewId: packet.reviewId,
304
+ evidenceDigest: packet.evidenceDigest, model: 'gpt-5.6-sol', reasoningEffort: 'none', inputDigest: hash(request.input),
305
+ outputDigest: hash(output), outputBytes: Buffer.byteLength(output), requested, status: decision === null ? 'rejected' : 'accepted', decision,
306
+ ...(failureCode === undefined ? {} : { failureCode }) };
307
+ }
308
+ export function validateStoredStoryReview(state, policy, receipt) {
309
+ let request;
310
+ let constructionFailure;
311
+ try {
312
+ request = makeDynamicStoryReviewRequest({ state, policy });
313
+ }
314
+ catch (error) {
315
+ if (!(error instanceof StoryReviewError) || error.request === undefined)
316
+ throw error;
317
+ request = error.request;
318
+ constructionFailure = error.code;
319
+ }
320
+ if (receipt.requested !== (constructionFailure === undefined) || (constructionFailure !== undefined
321
+ && (receipt.status !== 'rejected' || receipt.failureCode !== constructionFailure || receipt.outputBytes !== 0 || receipt.outputDigest !== hash(''))))
322
+ throw new StoryReviewError('story-review-receipt-invalid', 'Request dispatch differs from its retained construction outcome');
323
+ const packet = JSON.parse(request.input);
324
+ if (!storyReviewReceiptSchema.safeParse(receipt).success || receipt.revision !== state.revision
325
+ || receipt.acceptedBeat !== state.episode?.acceptedBeats || receipt.reviewId !== packet.reviewId
326
+ || receipt.evidenceDigest !== packet.evidenceDigest || receipt.inputDigest !== hash(request.input))
327
+ throw new StoryReviewError('story-review-receipt-invalid', 'The stored review differs from its reconstructed candidate');
328
+ if (receipt.status === 'accepted') {
329
+ assertDynamicInferenceKnowledge({ request: JSON.stringify(request), output: canonicalJson(receipt.decision),
330
+ privateKnowledge: dynamicPrivateKnowledge(state), publishedKnowledge: dynamicPublishedKnowledge(state) });
331
+ validateStoryReviewDecision(request, receipt.decision);
332
+ }
333
+ }
@@ -0,0 +1,77 @@
1
+ import { z } from 'zod';
2
+ import type { DynamicInitialization, DynamicInitializationV1, StorytellerDecisionV1, StorytellerObservationV1, StorytellerReceiptV1, StorytellerSetbackV2 } from '../../plugin/simulation_storyteller.js';
3
+ export declare const storytellerSelectionSchema: z.ZodObject<{
4
+ policyVersion: z.ZodEnum<{
5
+ "storyteller-1": "storyteller-1";
6
+ "storyteller-2": "storyteller-2";
7
+ }>;
8
+ personality: z.ZodEnum<{
9
+ "rising-tension": "rising-tension";
10
+ "spacious-recovery": "spacious-recovery";
11
+ }>;
12
+ }, z.core.$strict>;
13
+ export declare const dynamicSelectionSchema: z.ZodObject<{
14
+ policyVersion: z.ZodLiteral<"selection-1">;
15
+ gameKind: z.ZodString;
16
+ rulesVersion: z.ZodString;
17
+ scenarioId: z.ZodString;
18
+ roleId: z.ZodString;
19
+ }, z.core.$strict>;
20
+ export declare const dynamicInitializationSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
21
+ version: z.ZodLiteral<1>;
22
+ storyteller: z.ZodObject<{
23
+ policyVersion: z.ZodEnum<{
24
+ "storyteller-1": "storyteller-1";
25
+ "storyteller-2": "storyteller-2";
26
+ }>;
27
+ personality: z.ZodEnum<{
28
+ "rising-tension": "rising-tension";
29
+ "spacious-recovery": "spacious-recovery";
30
+ }>;
31
+ }, z.core.$strict>;
32
+ }, z.core.$strict>, z.ZodObject<{
33
+ version: z.ZodLiteral<2>;
34
+ documents: z.ZodOptional<z.ZodObject<{
35
+ policyVersion: z.ZodLiteral<"document-stream-1">;
36
+ authoredRevision: z.ZodOptional<z.ZodLiteral<2>>;
37
+ }, z.core.$strict>>;
38
+ selection: z.ZodObject<{
39
+ policyVersion: z.ZodLiteral<"selection-1">;
40
+ gameKind: z.ZodString;
41
+ rulesVersion: z.ZodString;
42
+ scenarioId: z.ZodString;
43
+ roleId: z.ZodString;
44
+ }, z.core.$strict>;
45
+ storyteller: z.ZodObject<{
46
+ policyVersion: z.ZodEnum<{
47
+ "storyteller-1": "storyteller-1";
48
+ "storyteller-2": "storyteller-2";
49
+ }>;
50
+ personality: z.ZodEnum<{
51
+ "rising-tension": "rising-tension";
52
+ "spacious-recovery": "spacious-recovery";
53
+ }>;
54
+ }, z.core.$strict>;
55
+ }, z.core.$strict>], "version">;
56
+ export declare const STORYTELLER_OPTIONS: readonly [{
57
+ readonly id: "rising-tension";
58
+ readonly label: "Rising tension";
59
+ }, {
60
+ readonly id: "spacious-recovery";
61
+ readonly label: "Spacious recovery";
62
+ }];
63
+ export declare const DEFAULT_DYNAMIC_INITIALIZATION: DynamicInitializationV1;
64
+ export declare function parseDynamicInitialization(value: unknown): DynamicInitialization;
65
+ export declare function storytellerMemory(initialization: DynamicInitialization, receipts: readonly StorytellerReceiptV1[]): {
66
+ quiet: number;
67
+ major: number;
68
+ recovery: number;
69
+ setbacks: readonly number[];
70
+ };
71
+ export declare function planStoryteller(input: {
72
+ readonly initialization: DynamicInitialization;
73
+ readonly revision: number;
74
+ readonly observation: StorytellerObservationV1;
75
+ readonly receipts: readonly StorytellerReceiptV1[];
76
+ }): StorytellerDecisionV1;
77
+ export declare function pendingStorytellerSetbacks(receipts: readonly StorytellerReceiptV1[]): StorytellerSetbackV2[];
@@ -0,0 +1,114 @@
1
+ import { createHash } from 'node:crypto';
2
+ import { z } from 'zod';
3
+ export const storytellerSelectionSchema = z.object({
4
+ policyVersion: z.enum(['storyteller-1', 'storyteller-2']),
5
+ personality: z.enum(['rising-tension', 'spacious-recovery']),
6
+ }).strict();
7
+ const legacyInitializationSchema = z.object({
8
+ version: z.literal(1),
9
+ storyteller: storytellerSelectionSchema,
10
+ }).strict();
11
+ export const dynamicSelectionSchema = z.object({
12
+ policyVersion: z.literal('selection-1'),
13
+ gameKind: z.string().min(1).max(64).regex(/^[a-z0-9-]+$/),
14
+ rulesVersion: z.string().min(1).max(128),
15
+ scenarioId: z.string().min(1).max(64).regex(/^[a-z0-9-]+$/),
16
+ roleId: z.string().min(1).max(64).regex(/^[a-z0-9-]+$/),
17
+ }).strict();
18
+ export const dynamicInitializationSchema = z.discriminatedUnion('version', [
19
+ legacyInitializationSchema,
20
+ z.object({ version: z.literal(2), documents: z.object({ policyVersion: z.literal('document-stream-1'), authoredRevision: z.literal(2).optional() }).strict().optional(), selection: dynamicSelectionSchema, storyteller: storytellerSelectionSchema }).strict(),
21
+ ]);
22
+ export const STORYTELLER_OPTIONS = [
23
+ { id: 'rising-tension', label: 'Rising tension' },
24
+ { id: 'spacious-recovery', label: 'Spacious recovery' },
25
+ ];
26
+ export const DEFAULT_DYNAMIC_INITIALIZATION = {
27
+ version: 1, storyteller: { policyVersion: 'storyteller-1', personality: 'rising-tension' },
28
+ };
29
+ export function parseDynamicInitialization(value) {
30
+ const result = dynamicInitializationSchema.safeParse(value);
31
+ if (!result.success)
32
+ throw new Error('Storyteller selection is invalid');
33
+ return result.data;
34
+ }
35
+ export function storytellerMemory(initialization, receipts) {
36
+ if (initialization.storyteller.policyVersion === 'storyteller-2')
37
+ receipts = publicStorytellerReceipts(receipts);
38
+ const spacious = initialization.storyteller.personality === 'spacious-recovery';
39
+ let quiet = 0;
40
+ let major = 0;
41
+ let recovery = 0;
42
+ const setbacks = new Set();
43
+ for (const receipt of receipts) {
44
+ quiet = receipt.acceptedPressureActionIds.length > 0 ? 0 : quiet + 1;
45
+ major = receipt.majorCrisis ? major + 1 : 0;
46
+ recovery = Math.max(0, recovery - 1);
47
+ if (receipt.acceptedPressureActionIds.length > 0)
48
+ recovery = Math.max(recovery, spacious ? 3 : 1);
49
+ for (const revision of receipt.recoveryForRevisions)
50
+ setbacks.delete(revision);
51
+ if (receipt.setbackResourceIds.length > 0) {
52
+ setbacks.add(receipt.decision.basedOnRevision + 1);
53
+ recovery = Math.max(recovery, spacious ? 4 : 2);
54
+ }
55
+ }
56
+ return { quiet, major, recovery, setbacks: [...setbacks] };
57
+ }
58
+ export function planStoryteller(input) {
59
+ const initialization = parseDynamicInitialization(input.initialization);
60
+ const { observation, revision } = input;
61
+ const receipts = initialization.storyteller.policyVersion === 'storyteller-2' ? publicStorytellerReceipts(input.receipts) : input.receipts;
62
+ if (!Number.isSafeInteger(revision) || revision < 0
63
+ || (initialization.storyteller.policyVersion === 'storyteller-1' && revision > 100)
64
+ || observation.headroom.length === 0 || observation.headroom.length > 32
65
+ || [...observation.headroom, observation.progress].some(value => !Number.isSafeInteger(value) || value < 0 || value > 1000)
66
+ || !Number.isSafeInteger(observation.activeThreats) || observation.activeThreats < 0) {
67
+ throw new Error('Storyteller observation is invalid');
68
+ }
69
+ const memory = storytellerMemory(initialization, input.receipts);
70
+ const quietLimit = initialization.storyteller.personality === 'spacious-recovery' ? 6 : 3;
71
+ const recentSetback = receipts.slice(-2).some(receipt => receipt.setbackResourceIds.length > 0);
72
+ const headroom = observation.headroom.reduce((sum, value) => sum + value, 0) / observation.headroom.length;
73
+ let comfort = Math.max(0, Math.min(1000, Math.floor(0.7 * headroom + 0.3 * observation.progress - 50 * Math.min(4, observation.activeThreats) - (recentSetback ? 250 : 0))));
74
+ if (Math.min(...observation.headroom) < 150)
75
+ comfort = Math.min(comfort, 250);
76
+ const offerRecovery = memory.recovery > 0 || memory.setbacks.length > 0;
77
+ const due = memory.quiet >= quietLimit - 1;
78
+ const tier = comfort < 400 ? 1 : comfort < 700 ? 2 : 3;
79
+ return {
80
+ basedOnRevision: revision,
81
+ mode: due ? 'pressure' : offerRecovery ? 'recovery' : 'quiet',
82
+ strengthTier: due ? (memory.recovery > 0 || memory.major >= 2 ? 1 : tier) : 0,
83
+ offerRecovery,
84
+ quietLimit,
85
+ inputDigest: createHash('sha256').update(JSON.stringify({ initialization, revision, observation, receipts })).digest('hex'),
86
+ };
87
+ }
88
+ export function pendingStorytellerSetbacks(receipts) {
89
+ const pending = new Map();
90
+ for (const receipt of receipts) {
91
+ for (const opportunity of receipt.recovery?.opportunities ?? [])
92
+ pending.delete(opportunity.causeId);
93
+ for (const cause of receipt.recovery?.setbacks ?? [])
94
+ pending.set(cause.id, cause);
95
+ }
96
+ return [...pending.values()];
97
+ }
98
+ /** Scheduling sees only public causal evidence; trusted private audit remains in history. */
99
+ function publicStorytellerReceipts(receipts) {
100
+ const publicCauses = receipts.flatMap(receipt => receipt.recovery?.setbacks ?? []).filter(cause => !cause.private);
101
+ const addressed = new Set();
102
+ return receipts.map(receipt => {
103
+ const causes = (receipt.recovery?.setbacks ?? []).filter(cause => !cause.private);
104
+ for (const opportunity of receipt.recovery?.opportunities ?? []) {
105
+ if (publicCauses.some(cause => cause.id === opportunity.causeId))
106
+ addressed.add(opportunity.causeId);
107
+ }
108
+ const completed = [...new Set(publicCauses.filter(cause => cause.revision < receipt.decision.basedOnRevision + 1
109
+ && publicCauses.filter(other => other.revision === cause.revision).every(other => addressed.has(other.id))).map(cause => cause.revision))];
110
+ return { decision: receipt.decision, proposedPressure: receipt.proposedPressure, proposedRecovery: receipt.proposedRecovery,
111
+ acceptedPressureActionIds: receipt.acceptedPressureActionIds, majorCrisis: causes.some(cause => cause.major),
112
+ setbackResourceIds: causes.map(cause => cause.id), recoveryChoiceIds: [], recoveryForRevisions: completed };
113
+ });
114
+ }
@@ -0,0 +1,26 @@
1
+ import type { SimulationDomainActionProposalV1, SimulationDynamicHistoryEntryV1, SimulationDynamicPlayerActionV1, SimulationDynamicWorldEffectV1 } from '../../plugin/simulation_contract.js';
2
+ import type { StorytellerSetbackV2, StorytellerOpportunityV2, StorytellerDecisionV1, StorytellerObservationV1, StorytellerReceiptV1 } from '../../plugin/simulation_storyteller.js';
3
+ import type { DynamicDomainPolicy, DynamicDomainPolicyState } from './dynamic_runtime.js';
4
+ export interface DynamicStorytellerAdapter {
5
+ setbacks?(state: DynamicDomainPolicyState, actions: readonly SimulationDomainActionProposalV1[], effects: readonly SimulationDynamicWorldEffectV1[]): readonly StorytellerSetbackV2[];
6
+ opportunity?(state: DynamicDomainPolicyState, choice: SimulationDynamicPlayerActionV1, cause: StorytellerSetbackV2): StorytellerOpportunityV2 | null;
7
+ relief?(before: DynamicDomainPolicyState, after: DynamicDomainPolicyState, action: SimulationDomainActionProposalV1, effects: readonly SimulationDynamicWorldEffectV1[], cause: StorytellerSetbackV2): StorytellerOpportunityV2 | null;
8
+ observe(state: DynamicDomainPolicyState): StorytellerObservationV1;
9
+ pressure(state: DynamicDomainPolicyState, tier: number): readonly SimulationDomainActionProposalV1[];
10
+ isPressure(action: SimulationDomainActionProposalV1): boolean;
11
+ classify(state: DynamicDomainPolicyState, actions: readonly SimulationDomainActionProposalV1[], effects: readonly SimulationDynamicWorldEffectV1[]): {
12
+ readonly pressureActionIds: readonly string[];
13
+ readonly major: boolean;
14
+ readonly setbackResourceIds: readonly string[];
15
+ };
16
+ recoveryActions(state: DynamicDomainPolicyState): readonly SimulationDomainActionProposalV1[];
17
+ recovery(state: DynamicDomainPolicyState): readonly SimulationDynamicPlayerActionV1[];
18
+ recoveryResources(state: DynamicDomainPolicyState, choice: SimulationDynamicPlayerActionV1): readonly string[];
19
+ }
20
+ export declare function storytellerPlan(state: DynamicDomainPolicyState, policy: DynamicDomainPolicy): {
21
+ decision: StorytellerDecisionV1;
22
+ pressure: readonly SimulationDomainActionProposalV1[];
23
+ recovery: readonly SimulationDomainActionProposalV1[];
24
+ } | null;
25
+ export declare function makeStorytellerReceipt(before: DynamicDomainPolicyState, after: DynamicDomainPolicyState, policy: DynamicDomainPolicy, entry: Pick<SimulationDynamicHistoryEntryV1, 'gmProposal' | 'effects'>, choices: readonly SimulationDynamicPlayerActionV1[]): StorytellerReceiptV1 | undefined;
26
+ export declare function assertStorytellerReceipt(before: DynamicDomainPolicyState, after: DynamicDomainPolicyState, policy: DynamicDomainPolicy, entry: SimulationDynamicHistoryEntryV1): void;