blun-king-cli 9.1.587 → 9.1.588

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 (436) hide show
  1. package/CHANGELOG.md +11 -185
  2. package/LIESMICH.txt +51 -13
  3. package/README.md +44 -47
  4. package/agent-spine-plugin/.codex-plugin/plugin.json +16 -4
  5. package/agent-spine-plugin/CHANGELOG.md +37 -5
  6. package/agent-spine-plugin/README.md +3 -3
  7. package/agent-spine-plugin/blun.plugin.json +45 -10
  8. package/agent-spine-plugin/docs/artifact-evaluation.md +93 -0
  9. package/agent-spine-plugin/docs/host-integration.md +42 -27
  10. package/agent-spine-plugin/docs/preflight-recall.md +4 -2
  11. package/agent-spine-plugin/docs/session-timeline.md +97 -236
  12. package/agent-spine-plugin/docs/world-model.md +25 -0
  13. package/agent-spine-plugin/hooks/codex.json +1 -1
  14. package/agent-spine-plugin/hooks/hooks.json +1 -1
  15. package/agent-spine-plugin/package.json +1 -3
  16. package/agent-spine-plugin/scripts/check-hosts.js +3 -3
  17. package/agent-spine-plugin/scripts/release-check.js +10 -5
  18. package/agent-spine-plugin/scripts/run-checks.js +4 -1
  19. package/agent-spine-plugin/scripts/run-tests-hermetic.js +32 -6
  20. package/agent-spine-plugin/src/cli-learning.js +15 -0
  21. package/agent-spine-plugin/src/cli.js +2 -0
  22. package/agent-spine-plugin/src/hook.js +32 -32
  23. package/agent-spine-plugin/src/lib/action-lesson-recall.js +73 -8
  24. package/agent-spine-plugin/src/lib/briefing.js +146 -36
  25. package/agent-spine-plugin/src/lib/channel-continuity.js +19 -0
  26. package/agent-spine-plugin/src/lib/delivery-agent-usage.js +14 -7
  27. package/agent-spine-plugin/src/lib/gateway-group-response.js +128 -0
  28. package/agent-spine-plugin/src/lib/gateway-runs.js +24 -15
  29. package/agent-spine-plugin/src/lib/hook-briefing-use.js +13 -3
  30. package/agent-spine-plugin/src/lib/hook-context.js +16 -3
  31. package/agent-spine-plugin/src/lib/hook-output.js +129 -5
  32. package/agent-spine-plugin/src/lib/hook-timeline.js +5 -3
  33. package/agent-spine-plugin/src/lib/indexed-memory.js +2 -2
  34. package/agent-spine-plugin/src/lib/learning-artifact-evaluator.js +114 -0
  35. package/agent-spine-plugin/src/lib/learning-context.js +11 -4
  36. package/agent-spine-plugin/src/lib/learning-measurements.js +2 -2
  37. package/agent-spine-plugin/src/lib/mcp-runtime.js +89 -3
  38. package/agent-spine-plugin/src/lib/mcp-source-context.js +12 -2
  39. package/agent-spine-plugin/src/lib/mcp-timeline-tools.js +91 -8
  40. package/agent-spine-plugin/src/lib/mcp-world-tools.js +2 -2
  41. package/agent-spine-plugin/src/lib/owned-file-lock.js +20 -1
  42. package/agent-spine-plugin/src/lib/persona-runtime.js +2 -2
  43. package/agent-spine-plugin/src/lib/preflight-delivery-id.js +27 -0
  44. package/agent-spine-plugin/src/lib/preflight.js +4 -4
  45. package/agent-spine-plugin/src/lib/session-timeline-codex.js +15 -0
  46. package/agent-spine-plugin/src/lib/session-timeline-contract.js +12 -4
  47. package/agent-spine-plugin/src/lib/session-timeline-event-extract.js +36 -7
  48. package/agent-spine-plugin/src/lib/session-timeline-host-origin.js +13 -10
  49. package/agent-spine-plugin/src/lib/session-timeline-invocation.js +1 -1
  50. package/agent-spine-plugin/src/lib/session-timeline-king.js +14 -0
  51. package/agent-spine-plugin/src/lib/session-timeline-prior.js +18 -12
  52. package/agent-spine-plugin/src/lib/session-timeline-provider.js +5 -0
  53. package/agent-spine-plugin/src/lib/session-timeline-query.js +2 -0
  54. package/agent-spine-plugin/src/lib/session-timeline-results.js +35 -10
  55. package/agent-spine-plugin/src/lib/session-timeline-source-open.js +30 -0
  56. package/agent-spine-plugin/src/lib/session-timeline.js +122 -75
  57. package/agent-spine-plugin/src/lib/source-roots.js +3 -2
  58. package/agent-spine-plugin/src/lib/task-knowledge-context.js +22 -1
  59. package/agent-spine-plugin/src/lib/timeline-continuation-update.js +100 -0
  60. package/agent-spine-plugin/src/lib/timeline-tool-guard.js +30 -7
  61. package/agent-spine-plugin/src/lib/timeline-user-feedback.js +217 -0
  62. package/agent-spine-plugin/src/lib/timeline-world-capture.js +233 -0
  63. package/agent-spine-plugin/src/lib/world-knowledge.js +59 -2
  64. package/agent-spine-plugin/src/lib/world-model.js +64 -9
  65. package/agent-spine-plugin/src/worker.js +13 -1
  66. package/bin/blun.js +43 -28
  67. package/bin/core-bootstrap.js +5 -4
  68. package/bin/king.js +43 -28
  69. package/bin/launcher-mode.js +1 -10
  70. package/bin/launcher-runtime.js +128 -295
  71. package/bin/managed-node.js +0 -0
  72. package/bin/managed-plugin-selection.cjs +0 -1
  73. package/bin/native-module-repair.js +0 -0
  74. package/bin/node-runtime.js +0 -0
  75. package/bin/node-version.js +0 -0
  76. package/bin/plugin-bootstrap.js +56 -120
  77. package/bin/private-paths.js +11 -34
  78. package/bin/standard-tools-bootstrap.js +34 -114
  79. package/bin/turn-thinking-policy.cjs +3 -11
  80. package/bin/update-copy.js +200 -0
  81. package/bin/update-lease.js +0 -0
  82. package/bin/update-notice.js +136 -289
  83. package/bin/verify-agent-behavior.cjs +122 -0
  84. package/bin/verify-agent-components.cjs +104 -0
  85. package/bin/verify-bundled-agent-sources.cjs +57 -0
  86. package/blun.mjs +143076 -135288
  87. package/bundled-agent-sources.json +701 -0
  88. package/package.json +12 -15
  89. package/standard-skills/translate-native/README.md +1293 -0
  90. package/standard-skills/translate-native/SKILL.md +172 -22
  91. package/standard-skills/translate-native/VERSION +1 -1
  92. package/standard-skills/translate-native/agents/openai.yaml +18 -0
  93. package/standard-skills/translate-native/assets/icon.svg +8 -0
  94. package/standard-skills/translate-native/docs/BLUN_CODE_INTEGRATION.md +76 -0
  95. package/standard-skills/translate-native/docs/PREMORTEM.md +489 -0
  96. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION.md +2035 -0
  97. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_API.md +1302 -0
  98. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_EVIDENCE_HTTP.md +136 -0
  99. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HEALTH_HTTP.md +130 -0
  100. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_HTTP_PROVIDER.md +175 -0
  101. package/standard-skills/translate-native/docs/WEBSITE_LOCALIZATION_RECEIPT_VERIFIER_HTTP.md +86 -0
  102. package/standard-skills/translate-native/integrations/AGENT_RULES.md +32 -0
  103. package/standard-skills/translate-native/integrations/adapters/blun-code-language-guard.js +514 -0
  104. package/standard-skills/translate-native/integrations/adapters/node-language-guard.js +230 -0
  105. package/standard-skills/translate-native/integrations/audit_log.py +327 -0
  106. package/standard-skills/translate-native/integrations/claude_language_hook.js +1536 -0
  107. package/standard-skills/translate-native/integrations/commercial_localization_profile.py +42 -0
  108. package/standard-skills/translate-native/integrations/delivery-policy.example.json +28 -0
  109. package/standard-skills/translate-native/integrations/enforced_delivery.py +543 -0
  110. package/standard-skills/translate-native/integrations/guard_service.py +435 -0
  111. package/standard-skills/translate-native/integrations/language_gateway.py +67 -0
  112. package/standard-skills/translate-native/integrations/mcp_auth_headers.py +198 -0
  113. package/standard-skills/translate-native/integrations/mcp_http_gateway.py +429 -0
  114. package/standard-skills/translate-native/integrations/non_language_html_entities.js +1485 -0
  115. package/standard-skills/translate-native/integrations/pre_output_guard.py +65 -0
  116. package/standard-skills/translate-native/integrations/task_router.py +101 -0
  117. package/standard-skills/translate-native/integrations/website_localization.py +401 -0
  118. package/standard-skills/translate-native/integrations/website_localization_api.py +581 -0
  119. package/standard-skills/translate-native/integrations/website_localization_benchmark.py +1885 -0
  120. package/standard-skills/translate-native/integrations/website_localization_benchmark_campaign.py +1772 -0
  121. package/standard-skills/translate-native/integrations/website_localization_benchmark_candidate.py +506 -0
  122. package/standard-skills/translate-native/integrations/website_localization_benchmark_http.py +400 -0
  123. package/standard-skills/translate-native/integrations/website_localization_benchmark_review_store.py +781 -0
  124. package/standard-skills/translate-native/integrations/website_localization_benchmark_reviewer_http.py +500 -0
  125. package/standard-skills/translate-native/integrations/website_localization_benchmark_runtime.py +1107 -0
  126. package/standard-skills/translate-native/integrations/website_localization_benchmark_suite.py +463 -0
  127. package/standard-skills/translate-native/integrations/website_localization_cms.py +2835 -0
  128. package/standard-skills/translate-native/integrations/website_localization_cms_client.py +875 -0
  129. package/standard-skills/translate-native/integrations/website_localization_cms_dispatch.py +805 -0
  130. package/standard-skills/translate-native/integrations/website_localization_cms_http.py +588 -0
  131. package/standard-skills/translate-native/integrations/website_localization_cms_lifecycle_monitor.py +991 -0
  132. package/standard-skills/translate-native/integrations/website_localization_cms_receiver.py +1441 -0
  133. package/standard-skills/translate-native/integrations/website_localization_cms_receiver_runtime.py +414 -0
  134. package/standard-skills/translate-native/integrations/website_localization_cms_receiver_store.py +1073 -0
  135. package/standard-skills/translate-native/integrations/website_localization_cms_removal_dispatch.py +865 -0
  136. package/standard-skills/translate-native/integrations/website_localization_cms_source_client.py +583 -0
  137. package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery.py +964 -0
  138. package/standard-skills/translate-native/integrations/website_localization_cms_source_delivery_runtime.py +665 -0
  139. package/standard-skills/translate-native/integrations/website_localization_cms_source_http.py +1153 -0
  140. package/standard-skills/translate-native/integrations/website_localization_cms_source_runtime.py +675 -0
  141. package/standard-skills/translate-native/integrations/website_localization_cms_source_service.py +1125 -0
  142. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification.py +674 -0
  143. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_http.py +444 -0
  144. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver.py +1469 -0
  145. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_notification_receiver_runtime.py +1142 -0
  146. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_processing_monitor.py +634 -0
  147. package/standard-skills/translate-native/integrations/website_localization_cms_terminal_receiver_client.py +804 -0
  148. package/standard-skills/translate-native/integrations/website_localization_deepl_baseline.py +922 -0
  149. package/standard-skills/translate-native/integrations/website_localization_evidence_http.py +482 -0
  150. package/standard-skills/translate-native/integrations/website_localization_health.py +1541 -0
  151. package/standard-skills/translate-native/integrations/website_localization_health_http.py +372 -0
  152. package/standard-skills/translate-native/integrations/website_localization_http_provider.py +297 -0
  153. package/standard-skills/translate-native/integrations/website_localization_native_reference_http.py +479 -0
  154. package/standard-skills/translate-native/integrations/website_localization_native_reference_intake.py +363 -0
  155. package/standard-skills/translate-native/integrations/website_localization_native_reference_queue.py +1449 -0
  156. package/standard-skills/translate-native/integrations/website_localization_native_reference_store.py +420 -0
  157. package/standard-skills/translate-native/integrations/website_localization_quality_profiles.py +235 -0
  158. package/standard-skills/translate-native/integrations/website_localization_queue.py +671 -0
  159. package/standard-skills/translate-native/integrations/website_localization_receipt_verifier_http.py +516 -0
  160. package/standard-skills/translate-native/integrations/website_localization_release.py +928 -0
  161. package/standard-skills/translate-native/integrations/website_localization_release_coordinator.py +1008 -0
  162. package/standard-skills/translate-native/integrations/website_localization_runner.py +276 -0
  163. package/standard-skills/translate-native/integrations/website_localization_runtime.py +862 -0
  164. package/standard-skills/translate-native/integrations/website_localization_service.py +350 -0
  165. package/standard-skills/translate-native/integrations/website_localization_supervisor.py +511 -0
  166. package/standard-skills/translate-native/integrations/website_localization_worker.py +663 -0
  167. package/standard-skills/translate-native/provenance.json +3 -4
  168. package/standard-skills/translate-native/references/commercial-localization.md +177 -0
  169. package/standard-skills/translate-native/scripts/blun_language_guard.py +7 -1
  170. package/standard-skills/translate-native/scripts/check_commercial_review.py +80 -0
  171. package/standard-skills/translate-native/scripts/commercial_localization_profile.py +333 -0
  172. package/standard-tools/language-guard/LICENSE +21 -0
  173. package/standard-tools/language-guard/VERSION +1 -0
  174. package/standard-tools/language-guard/blun_language_guard.py +7 -1
  175. package/standard-tools/language-guard/check_commercial_review.py +80 -0
  176. package/standard-tools/language-guard/commercial_localization_profile.py +333 -0
  177. package/standard-tools/language-guard/language_gateway.py +62 -0
  178. package/standard-tools/language-guard/pre_output_guard.py +64 -0
  179. package/standard-tools/language-guard/provenance.json +4 -11
  180. package/standard-tools/manifest.json +34 -11
  181. package/telegram-plugin/commands/access.md +2 -10
  182. package/telegram-plugin/dist/bridge.mjs +64041 -687
  183. package/telegram-plugin/dist/mcp-server.mjs +72810 -9027
  184. package/telegram-plugin/dist/noise.mjs +28 -63511
  185. package/agent-spine-plugin/CONTRIBUTING.md +0 -52
  186. package/agent-spine-plugin/SECURITY.md +0 -47
  187. package/agent-spine-plugin/docs/assignment-continuation.md +0 -48
  188. package/agent-spine-plugin/docs/releasing.md +0 -85
  189. package/agent-spine-plugin/docs/structured-completion.md +0 -67
  190. package/bin/abort-listener-policy.cjs +0 -43
  191. package/bin/active-steer-priority-policy.cjs +0 -24
  192. package/bin/agent-api-http-adapter.mjs +0 -446
  193. package/bin/agent-api-private-http-server.mjs +0 -288
  194. package/bin/agent-api-runtime.mjs +0 -252
  195. package/bin/agent-api-service-environment.mjs +0 -236
  196. package/bin/agent-api-service-host.mjs +0 -209
  197. package/bin/agent-api-service-process.mjs +0 -171
  198. package/bin/agent-api-session-registry.mjs +0 -428
  199. package/bin/agent-api-tool-broker.cjs +0 -248
  200. package/bin/agent-api-turn-controller.mjs +0 -461
  201. package/bin/agent-api-usage-journal.cjs +0 -259
  202. package/bin/agent-resume-snapshot.cjs +0 -241
  203. package/bin/agentspine-king-goal-inbox.mjs +0 -111
  204. package/bin/agentspine-king-goal-intake.mjs +0 -106
  205. package/bin/approval-rejection-stop.cjs +0 -15
  206. package/bin/assistant-message-offload-policy.cjs +0 -284
  207. package/bin/baseline-skill-performance-policy.cjs +0 -39
  208. package/bin/bash-search-scope-policy.cjs +0 -49
  209. package/bin/codebase-search-runtime.cjs +0 -23
  210. package/bin/cognitive-action-checkpoint.cjs +0 -1104
  211. package/bin/cognitive-attention-delivery.cjs +0 -76
  212. package/bin/cognitive-attention-policy.cjs +0 -143
  213. package/bin/cognitive-attention-runtime.cjs +0 -91
  214. package/bin/cognitive-context-projection.cjs +0 -73
  215. package/bin/cognitive-cross-portal-acceptance.cjs +0 -443
  216. package/bin/cognitive-effective-view.cjs +0 -77
  217. package/bin/cognitive-focus-projection.cjs +0 -206
  218. package/bin/cognitive-focus-scope.cjs +0 -37
  219. package/bin/cognitive-goal-autostart-policy.cjs +0 -72
  220. package/bin/cognitive-goal-time-trigger-controller.cjs +0 -146
  221. package/bin/cognitive-memory-adapter.cjs +0 -282
  222. package/bin/cognitive-memory-command.cjs +0 -293
  223. package/bin/cognitive-memory-provider.cjs +0 -92
  224. package/bin/cognitive-salience-policy.cjs +0 -159
  225. package/bin/cognitive-state-store.cjs +0 -508
  226. package/bin/cognitive-turn-lifecycle.cjs +0 -624
  227. package/bin/cognitive-work-focus.cjs +0 -180
  228. package/bin/compaction-history-archive.cjs +0 -166
  229. package/bin/compaction-history-startup.cjs +0 -50
  230. package/bin/compaction-model-policy.cjs +0 -31
  231. package/bin/compaction-stage-policy.cjs +0 -21
  232. package/bin/compaction-transaction-policy.cjs +0 -122
  233. package/bin/config-write-dedup-policy.cjs +0 -27
  234. package/bin/context-budget-ledger.cjs +0 -31
  235. package/bin/context-doctor-policy.cjs +0 -70
  236. package/bin/context-insight-policy.cjs +0 -36
  237. package/bin/context-performance-policy.cjs +0 -19
  238. package/bin/context-pressure-policy.cjs +0 -20
  239. package/bin/cron-run-output.cjs +0 -45
  240. package/bin/cron-run-store.cjs +0 -145
  241. package/bin/curiosity-scout-policy.cjs +0 -49
  242. package/bin/default-model-output-budget-policy.cjs +0 -28
  243. package/bin/durable-task-resume-policy.cjs +0 -130
  244. package/bin/durable-task-resume-runtime.cjs +0 -117
  245. package/bin/durable-task-resume-store.cjs +0 -88
  246. package/bin/editable-tool-approval-policy.cjs +0 -540
  247. package/bin/editable-tool-approval-runtime.cjs +0 -99
  248. package/bin/effective-system-prompt-cache-policy.cjs +0 -33
  249. package/bin/error-memory-performance-policy.cjs +0 -113
  250. package/bin/file-observation-policy.cjs +0 -133
  251. package/bin/foreground-output-capture-policy.cjs +0 -41
  252. package/bin/generated-source-health.cjs +0 -142
  253. package/bin/glob-pattern-policy.cjs +0 -13
  254. package/bin/goal-completion-evidence-policy.cjs +0 -120
  255. package/bin/grep-output-limit-policy.cjs +0 -39
  256. package/bin/historical-media-projection-policy.cjs +0 -48
  257. package/bin/history-offload-pressure-policy.cjs +0 -33
  258. package/bin/html-to-research-markdown.cjs +0 -147
  259. package/bin/identity-context-policy.cjs +0 -764
  260. package/bin/identity-journal-policy.cjs +0 -107
  261. package/bin/input-draft-persistence.cjs +0 -77
  262. package/bin/king-tui-function-contract.json +0 -33
  263. package/bin/launcher-restart-policy.cjs +0 -150
  264. package/bin/live-response-repetition-guard.cjs +0 -196
  265. package/bin/llm-config-log-dedup-policy.cjs +0 -76
  266. package/bin/loop-event-record-policy.cjs +0 -174
  267. package/bin/managed-context-startup-policy.cjs +0 -27
  268. package/bin/media-activity-layout-policy.cjs +0 -34
  269. package/bin/media-auto-retrieval-policy.cjs +0 -90
  270. package/bin/media-result-policy.cjs +0 -59
  271. package/bin/micro-compaction-policy.cjs +0 -145
  272. package/bin/mistake-relevance-policy.cjs +0 -319
  273. package/bin/model-retry-progress-policy.cjs +0 -46
  274. package/bin/native-large-file-io.cjs +0 -42
  275. package/bin/native-runtime-cache.cjs +0 -76
  276. package/bin/natural-presence-policy.cjs +0 -28
  277. package/bin/noninteractive-shell-env-policy.cjs +0 -19
  278. package/bin/observer-hooks.cjs +0 -14
  279. package/bin/outbound-claim-provenance.cjs +0 -150
  280. package/bin/oversized-context-offload-policy.cjs +0 -86
  281. package/bin/pending-media-policy.cjs +0 -182
  282. package/bin/pending-token-estimate-policy.cjs +0 -41
  283. package/bin/personal-memory-consent-policy.cjs +0 -72
  284. package/bin/personal-memory-performance-policy.cjs +0 -12
  285. package/bin/personality-choice-policy.cjs +0 -101
  286. package/bin/personality-memory-adapter.cjs +0 -379
  287. package/bin/personality-mode.cjs +0 -46
  288. package/bin/personality-setup-policy.cjs +0 -197
  289. package/bin/proactive-compaction-policy.cjs +0 -25
  290. package/bin/profile-identity-resolution.cjs +0 -136
  291. package/bin/profile-runtime.cjs +0 -318
  292. package/bin/profile-tool-exclusion-policy.cjs +0 -37
  293. package/bin/programmatic-context-isolation.cjs +0 -25
  294. package/bin/programmatic-tool-runtime.mjs +0 -627
  295. package/bin/provider-idle-timeout-policy.cjs +0 -14
  296. package/bin/provider-model-refresh-deadline.cjs +0 -53
  297. package/bin/provider-model-refresh-policy.cjs +0 -107
  298. package/bin/rate-limit-recovery-policy.cjs +0 -47
  299. package/bin/read-batch-policy.cjs +0 -32
  300. package/bin/read-continuation-policy.cjs +0 -59
  301. package/bin/recurring-cron-history-policy.cjs +0 -124
  302. package/bin/relationship-continuity-policy.cjs +0 -143
  303. package/bin/relationship-curiosity-policy.cjs +0 -107
  304. package/bin/relationship-learning-policy.cjs +0 -168
  305. package/bin/release-artifact-freeze-policy.cjs +0 -30
  306. package/bin/reload-plugin-bootstrap.cjs +0 -18
  307. package/bin/reload-queue-policy.cjs +0 -38
  308. package/bin/repeated-assistant-response-policy.cjs +0 -232
  309. package/bin/repeated-injection-projection.cjs +0 -107
  310. package/bin/repeated-user-message-projection.cjs +0 -8
  311. package/bin/research-page-result.cjs +0 -74
  312. package/bin/retry-checkpoint-policy.cjs +0 -13
  313. package/bin/runtime-exit-ledger.cjs +0 -144
  314. package/bin/scoped-cron-run-policy.cjs +0 -358
  315. package/bin/session-checkpoint-policy.cjs +0 -25
  316. package/bin/session-compaction-policy.cjs +0 -84
  317. package/bin/session-replay-policy.cjs +0 -20
  318. package/bin/session-replay-window-policy.cjs +0 -40
  319. package/bin/session-resume-checkpoint.cjs +0 -254
  320. package/bin/session-scrollback-archive.cjs +0 -229
  321. package/bin/skill-activation-performance-policy.cjs +0 -69
  322. package/bin/skill-listing-performance-policy.cjs +0 -92
  323. package/bin/soul-organization-policy.cjs +0 -78
  324. package/bin/soul-preservation-policy.cjs +0 -20
  325. package/bin/startup-preferences.cjs +0 -131
  326. package/bin/streaming-flush-performance-policy.cjs +0 -28
  327. package/bin/structured-agent-swarm-output.cjs +0 -325
  328. package/bin/structured-subagent-output.cjs +0 -252
  329. package/bin/subagent-context-fork-policy.cjs +0 -155
  330. package/bin/subagent-max-tokens-handoff-policy.cjs +0 -69
  331. package/bin/subagent-parent-responsiveness.cjs +0 -19
  332. package/bin/subagent-skill-policy.cjs +0 -206
  333. package/bin/subagent-timeout-policy.cjs +0 -182
  334. package/bin/subagent-tool-policy.cjs +0 -60
  335. package/bin/subagent-usage-rollup-policy.cjs +0 -29
  336. package/bin/system-prompt-context-policy.cjs +0 -124
  337. package/bin/system-prompt-token-cache-policy.cjs +0 -60
  338. package/bin/telegram-addressed-focus.cjs +0 -55
  339. package/bin/telegram-addressed-priority.cjs +0 -12
  340. package/bin/telegram-approval-relay.cjs +0 -290
  341. package/bin/telegram-bot-priority.cjs +0 -17
  342. package/bin/telegram-console-status-policy.cjs +0 -174
  343. package/bin/telegram-context-projection-policy.cjs +0 -141
  344. package/bin/telegram-delivery-lifecycle.cjs +0 -125
  345. package/bin/telegram-direct-focus-policy.cjs +0 -273
  346. package/bin/telegram-mcp-compatibility.cjs +0 -49
  347. package/bin/telegram-media-delivery-policy.cjs +0 -42
  348. package/bin/telegram-private-conversation-policy.cjs +0 -185
  349. package/bin/telegram-queue-handoff-policy.cjs +0 -73
  350. package/bin/telegram-remote-status-policy.cjs +0 -120
  351. package/bin/telegram-session-queue-runtime.mjs +0 -306
  352. package/bin/telegram-text-chunk-policy.cjs +0 -63
  353. package/bin/telegram-truncated-reply-policy.cjs +0 -37
  354. package/bin/telegram-urgent-policy.cjs +0 -45
  355. package/bin/telemetry-spool-policy.cjs +0 -57
  356. package/bin/thinking-activity-status-policy.cjs +0 -132
  357. package/bin/thinking-only-guard.cjs +0 -80
  358. package/bin/todo-list-turn-policy.cjs +0 -131
  359. package/bin/tool-call-loop-policy.cjs +0 -51
  360. package/bin/tool-file-persistence.cjs +0 -141
  361. package/bin/tool-result-offload-policy.cjs +0 -359
  362. package/bin/tool-result-offload-telemetry.cjs +0 -12
  363. package/bin/tool-schema-token-cache-policy.cjs +0 -41
  364. package/bin/tool-stream-preview-policy.cjs +0 -9
  365. package/bin/tui-functional-contract.cjs +0 -55
  366. package/bin/turn-tool-performance-policy.cjs +0 -486
  367. package/bin/usage-cache-efficiency-policy.cjs +0 -26
  368. package/bin/user-home-path-policy.cjs +0 -13
  369. package/bin/user-message-offload-policy.cjs +0 -103
  370. package/bin/user-prompt-hook-origin-policy.cjs +0 -34
  371. package/bin/user-tool-record-policy.cjs +0 -7
  372. package/bin/validated-learning-insight-policy.cjs +0 -58
  373. package/bin/validated-learning-outcome-trace.cjs +0 -107
  374. package/bin/validated-learning-performance-policy.cjs +0 -53
  375. package/bin/validated-learning-signal.cjs +0 -463
  376. package/bin/windows-bash-dialect-policy.cjs +0 -25
  377. package/bin/windows-node-crash-dump.cjs +0 -110
  378. package/bin/write-continuation-policy.cjs +0 -69
  379. package/codebase-index/README.md +0 -82
  380. package/codebase-index/codebase_index.py +0 -470
  381. package/standard-skills/agent-browser/SKILL.md +0 -19
  382. package/standard-skills/agent-browser/references/runtime.md +0 -8
  383. package/standard-skills/blun-session-inspector/SKILL.md +0 -41
  384. package/standard-skills/blun-session-inspector/scripts/inspect-session.cjs +0 -437
  385. package/standard-skills/design-taste-frontend/SKILL.md +0 -1206
  386. package/standard-skills/full-output-enforcement/SKILL.md +0 -49
  387. package/standard-skills/high-end-visual-design/SKILL.md +0 -98
  388. package/standard-skills/image-to-code/SKILL.md +0 -1228
  389. package/standard-skills/industrial-brutalist-ui/SKILL.md +0 -92
  390. package/standard-skills/minimalist-ui/SKILL.md +0 -85
  391. package/standard-skills/motion-design-taste/SKILL.md +0 -74
  392. package/standard-skills/playwright-testing/SKILL.md +0 -19
  393. package/standard-skills/playwright-testing/references/runtime.md +0 -7
  394. package/standard-skills/premortem/SKILL.md +0 -148
  395. package/standard-skills/redesign-existing-projects/SKILL.md +0 -178
  396. package/standard-skills/research-evidence/SKILL.md +0 -39
  397. package/standard-skills/research-evidence/references/evidence-format.md +0 -104
  398. package/standard-skills/research-evidence/scripts/evidence-collection.cjs +0 -260
  399. package/standard-skills/research-evidence/scripts/score-report.cjs +0 -130
  400. package/standard-skills/screenshot-lesen/SKILL.md +0 -52
  401. package/standard-skills/stitch-design-taste/DESIGN.md +0 -121
  402. package/standard-skills/stitch-design-taste/SKILL.md +0 -184
  403. package/standard-skills/telegram-channel/SKILL.md +0 -18
  404. package/standard-skills/telegram-channel/references/runtime.md +0 -7
  405. package/standard-skills/venture-flywheel/SKILL.md +0 -32
  406. package/standard-skills/venture-flywheel/identity/project-identity.cjs +0 -146
  407. package/standard-skills/venture-flywheel/policy/capability-engine.cjs +0 -114
  408. package/standard-skills/venture-flywheel/policy/repository-trust.cjs +0 -229
  409. package/standard-skills/venture-flywheel/references/BEISPIELE-phase0.md +0 -146
  410. package/standard-skills/venture-flywheel/references/CAPABILITY-MAP.md +0 -34
  411. package/standard-skills/venture-flywheel/references/SPEC-phase0-identity-trust.md +0 -77
  412. package/standard-skills/venture-flywheel/references/SPEC-phase0-state-events.md +0 -93
  413. package/standard-skills/venture-flywheel/schemas/capability-decision.schema.json +0 -13
  414. package/standard-skills/venture-flywheel/schemas/execution-event.schema.json +0 -44
  415. package/standard-skills/venture-flywheel/schemas/project-identity.schema.json +0 -32
  416. package/standard-skills/venture-flywheel/schemas/repository-trust.schema.json +0 -57
  417. package/standard-skills/venture-flywheel/schemas/run-transition.schema.json +0 -59
  418. package/standard-skills/venture-flywheel/state/execution-event.cjs +0 -191
  419. package/standard-skills/venture-flywheel/state/task-state-machine.cjs +0 -190
  420. package/standard-skills/web-lesen/SKILL.md +0 -73
  421. package/standard-skills/web-lesen/scripts/crawl_public.py +0 -379
  422. package/standard-skills/windows-mcp/SKILL.md +0 -19
  423. package/standard-skills/windows-mcp/references/runtime.md +0 -9
  424. package/telegram-plugin/DELIVERY.md +0 -36
  425. package/telegram-plugin/bin/telegram-approval-relay.cjs +0 -290
  426. package/telegram-plugin/bin/telegram-console-status-policy.cjs +0 -175
  427. package/telegram-plugin/bin/telegram-delivery-lifecycle.cjs +0 -125
  428. package/telegram-plugin/bin/telegram-direct-reply-policy.cjs +0 -48
  429. package/telegram-plugin/bin/telegram-launcher-status-queue.cjs +0 -122
  430. package/telegram-plugin/bin/telegram-private-conversation-policy.cjs +0 -186
  431. package/telegram-plugin/bin/telegram-remote-status-policy.cjs +0 -121
  432. package/telegram-plugin/bin/telegram-reply-parts.cjs +0 -149
  433. package/telegram-plugin/bin/telegram-text-chunk-policy.cjs +0 -63
  434. package/telegram-plugin/bin/telegram-typing-keepalive.cjs +0 -89
  435. package/telegram-plugin/compat/mcp-server-fa511cd1.mjs +0 -73825
  436. /package/{bin → scripts}/fix-node-pty-perms.js +0 -0
@@ -0,0 +1,511 @@
1
+ #!/usr/bin/env python3
2
+ """Durable single-instance supervisor for the localization service tick.
3
+
4
+ The host injects the already configured service tick, clock, and sleeper. The
5
+ supervisor persists only operational metadata and never stores customer text,
6
+ provider responses, signatures, credentials, or exception messages.
7
+ """
8
+
9
+ from __future__ import annotations
10
+
11
+ import math
12
+ import re
13
+ import secrets
14
+ import sqlite3
15
+ import time
16
+ from contextlib import contextmanager
17
+ from dataclasses import asdict, dataclass
18
+ from typing import Any, Callable, Mapping
19
+
20
+
21
+ SCHEMA = "blun.website-localization-supervisor.v1"
22
+ TICK_SCHEMA = "blun.website-localization-service-tick.v1"
23
+ ERROR_CODE = re.compile(r"^[a-z][a-z0-9_.-]{0,127}$")
24
+ TOKEN = re.compile(r"^[A-Za-z0-9_.:-]{1,256}$")
25
+ PHASES = {
26
+ "tombstone", "delivery", "ingress", "release", "translation", "benchmark",
27
+ "idle", "supervisor",
28
+ }
29
+ STATUSES = {
30
+ "idle", "succeeded", "retry_wait", "failed", "blocked", "approved",
31
+ "delivery_ready", "delivered", "enqueued", "superseded", "cancelled",
32
+ }
33
+ BLOCKED_STATUSES = {"retry_wait", "failed", "blocked"}
34
+ _COLUMNS = (
35
+ "singleton", "schema", "revision", "lease_owner", "lease_token",
36
+ "lease_expires_at", "next_tick_at", "consecutive_blocked",
37
+ "last_started_at", "last_finished_at", "last_phase", "last_status",
38
+ "last_error_code", "updated_at",
39
+ )
40
+
41
+
42
+ class LocalizationSupervisorBlocked(RuntimeError):
43
+ """Stable supervisor failure that contains no stored customer value."""
44
+
45
+ def __init__(self, code: str):
46
+ super().__init__(code)
47
+ self.code = code
48
+
49
+
50
+ @dataclass(frozen=True)
51
+ class SupervisorPolicy:
52
+ lease_seconds: float = 300.0
53
+ active_delay_seconds: float = 0.05
54
+ idle_delay_seconds: float = 1.0
55
+ blocked_base_seconds: float = 5.0
56
+ blocked_max_seconds: float = 300.0
57
+ stop_poll_seconds: float = 1.0
58
+
59
+ def validated(self) -> "SupervisorPolicy":
60
+ values = asdict(self)
61
+ for name, value in values.items():
62
+ if isinstance(value, bool) or not isinstance(value, (int, float)):
63
+ raise LocalizationSupervisorBlocked("supervisor.policy.invalid")
64
+ number = float(value)
65
+ if not math.isfinite(number) or number <= 0:
66
+ raise LocalizationSupervisorBlocked("supervisor.policy.invalid")
67
+ values[name] = number
68
+ if values["blocked_base_seconds"] > values["blocked_max_seconds"]:
69
+ raise LocalizationSupervisorBlocked("supervisor.policy.invalid")
70
+ return SupervisorPolicy(**values)
71
+
72
+
73
+ @dataclass(frozen=True)
74
+ class SupervisorStatus:
75
+ schema: str
76
+ status: str
77
+ revision: int
78
+ lease_active: bool
79
+ lease_expires_at: float | None
80
+ next_tick_at: float
81
+ consecutive_blocked: int
82
+ last_started_at: float | None
83
+ last_finished_at: float | None
84
+ last_phase: str | None
85
+ last_status: str | None
86
+ last_error_code: str | None
87
+
88
+ def as_payload(self) -> dict[str, Any]:
89
+ return asdict(self)
90
+
91
+
92
+ @dataclass(frozen=True)
93
+ class SupervisorRunOutcome:
94
+ schema: str
95
+ status: str
96
+ next_tick_at: float
97
+ tick: Mapping[str, Any] | None = None
98
+
99
+ def as_payload(self) -> dict[str, Any]:
100
+ return {
101
+ "schema": self.schema,
102
+ "status": self.status,
103
+ "next_tick_at": self.next_tick_at,
104
+ "tick": dict(self.tick) if self.tick is not None else None,
105
+ }
106
+
107
+
108
+ def _timestamp(value: Any) -> float:
109
+ if isinstance(value, bool) or not isinstance(value, (int, float)):
110
+ raise LocalizationSupervisorBlocked("supervisor.clock.invalid")
111
+ value = float(value)
112
+ if not math.isfinite(value) or value < 0:
113
+ raise LocalizationSupervisorBlocked("supervisor.clock.invalid")
114
+ return value
115
+
116
+
117
+ def _identifier(value: Any, code: str) -> str:
118
+ if not isinstance(value, str) or TOKEN.fullmatch(value) is None:
119
+ raise LocalizationSupervisorBlocked(code)
120
+ return value
121
+
122
+
123
+ @contextmanager
124
+ def _transaction(connection: sqlite3.Connection):
125
+ if connection.in_transaction:
126
+ raise LocalizationSupervisorBlocked("supervisor.state.transaction_active")
127
+ try:
128
+ connection.execute("BEGIN IMMEDIATE")
129
+ yield
130
+ connection.commit()
131
+ except Exception:
132
+ connection.rollback()
133
+ raise
134
+
135
+
136
+ def _tick_payload(value: Any) -> dict[str, Any]:
137
+ method = getattr(value, "as_payload", None)
138
+ if callable(method):
139
+ value = method()
140
+ if not isinstance(value, Mapping):
141
+ raise LocalizationSupervisorBlocked("supervisor.tick.result_invalid")
142
+ payload = dict(value)
143
+ expected = {
144
+ "schema", "phase", "status", "event_id", "plan_id", "job_id",
145
+ "target_locale", "delivery_id", "attempt", "error_code",
146
+ }
147
+ if set(payload) != expected or payload.get("schema") != TICK_SCHEMA:
148
+ raise LocalizationSupervisorBlocked("supervisor.tick.result_invalid")
149
+ phase = _identifier(payload.get("phase"), "supervisor.tick.result_invalid")
150
+ status = _identifier(payload.get("status"), "supervisor.tick.result_invalid")
151
+ if phase not in PHASES or status not in STATUSES:
152
+ raise LocalizationSupervisorBlocked("supervisor.tick.result_invalid")
153
+ for name in ("event_id", "plan_id", "job_id", "target_locale", "delivery_id"):
154
+ value = payload.get(name)
155
+ if value is not None:
156
+ _identifier(value, "supervisor.tick.result_invalid")
157
+ attempt = payload.get("attempt")
158
+ if attempt is not None and (
159
+ isinstance(attempt, bool) or not isinstance(attempt, int) or attempt < 1
160
+ ):
161
+ raise LocalizationSupervisorBlocked("supervisor.tick.result_invalid")
162
+ error_code = payload.get("error_code")
163
+ if error_code is not None and (
164
+ not isinstance(error_code, str) or ERROR_CODE.fullmatch(error_code) is None
165
+ ):
166
+ raise LocalizationSupervisorBlocked("supervisor.tick.result_invalid")
167
+ if (status in BLOCKED_STATUSES) != (error_code is not None):
168
+ raise LocalizationSupervisorBlocked("supervisor.tick.result_invalid")
169
+ del phase
170
+ return payload
171
+
172
+
173
+ class LocalizationServiceSupervisor:
174
+ """Lease and schedule a host-configured service tick durably."""
175
+
176
+ def __init__(
177
+ self,
178
+ connection: sqlite3.Connection,
179
+ tick: Callable[[], Any],
180
+ *,
181
+ worker_id: str,
182
+ policy: SupervisorPolicy = SupervisorPolicy(),
183
+ clock: Callable[[], float] = time.time,
184
+ token_factory: Callable[[], str] | None = None,
185
+ ):
186
+ if not isinstance(connection, sqlite3.Connection):
187
+ raise LocalizationSupervisorBlocked("supervisor.state.connection_invalid")
188
+ if not callable(tick) or not callable(clock):
189
+ raise LocalizationSupervisorBlocked("supervisor.dependency.invalid")
190
+ self.connection = connection
191
+ self.connection.row_factory = sqlite3.Row
192
+ self.connection.execute("PRAGMA busy_timeout = 5000")
193
+ self.tick = tick
194
+ self.worker_id = _identifier(worker_id, "supervisor.worker_id.invalid")
195
+ self.policy = policy.validated() if isinstance(policy, SupervisorPolicy) else None
196
+ if self.policy is None:
197
+ raise LocalizationSupervisorBlocked("supervisor.policy.invalid")
198
+ self.clock = clock
199
+ self.token_factory = token_factory or (lambda: secrets.token_hex(32))
200
+ self._active_token: str | None = None
201
+ self._create_schema()
202
+ self._verify_schema()
203
+
204
+ def _create_schema(self) -> None:
205
+ with _transaction(self.connection):
206
+ self.connection.execute(f"""
207
+ CREATE TABLE IF NOT EXISTS localization_service_supervisor (
208
+ singleton INTEGER PRIMARY KEY CHECK (singleton = 1),
209
+ schema TEXT NOT NULL CHECK (schema = '{SCHEMA}'),
210
+ revision INTEGER NOT NULL CHECK (revision >= 0),
211
+ lease_owner TEXT,
212
+ lease_token TEXT,
213
+ lease_expires_at REAL,
214
+ next_tick_at REAL NOT NULL,
215
+ consecutive_blocked INTEGER NOT NULL CHECK (consecutive_blocked >= 0),
216
+ last_started_at REAL,
217
+ last_finished_at REAL,
218
+ last_phase TEXT,
219
+ last_status TEXT,
220
+ last_error_code TEXT,
221
+ updated_at REAL NOT NULL,
222
+ CHECK (
223
+ (lease_owner IS NULL AND lease_token IS NULL AND lease_expires_at IS NULL)
224
+ OR
225
+ (lease_owner IS NOT NULL AND lease_token IS NOT NULL AND lease_expires_at IS NOT NULL)
226
+ )
227
+ )
228
+ """)
229
+ self.connection.execute("""
230
+ INSERT OR IGNORE INTO localization_service_supervisor (
231
+ singleton, schema, revision, next_tick_at,
232
+ consecutive_blocked, updated_at
233
+ ) VALUES (1, ?, 0, 0, 0, 0)
234
+ """, (SCHEMA,))
235
+
236
+ def _verify_schema(self) -> None:
237
+ columns = tuple(
238
+ row["name"] for row in self.connection.execute(
239
+ "PRAGMA table_info(localization_service_supervisor)"
240
+ )
241
+ )
242
+ if columns != _COLUMNS:
243
+ raise LocalizationSupervisorBlocked("supervisor.state.schema_altered")
244
+ rows = self.connection.execute(
245
+ "SELECT * FROM localization_service_supervisor"
246
+ ).fetchall()
247
+ if len(rows) != 1:
248
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
249
+ self._status_from_row(rows[0], 0)
250
+
251
+ @staticmethod
252
+ def _status_from_row(row: sqlite3.Row, now: float) -> SupervisorStatus:
253
+ if row["singleton"] != 1 or row["schema"] != SCHEMA:
254
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
255
+ revision = row["revision"]
256
+ blocked = row["consecutive_blocked"]
257
+ if any(
258
+ isinstance(value, bool) or not isinstance(value, int) or value < 0
259
+ for value in (revision, blocked)
260
+ ):
261
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
262
+ next_tick_at = _timestamp(row["next_tick_at"])
263
+ updated_at = _timestamp(row["updated_at"])
264
+ del updated_at
265
+ lease = (row["lease_owner"], row["lease_token"], row["lease_expires_at"])
266
+ if lease == (None, None, None):
267
+ lease_active = False
268
+ lease_expires_at = None
269
+ status = "waiting" if next_tick_at > now else "ready"
270
+ else:
271
+ _identifier(lease[0], "supervisor.state.invalid")
272
+ _identifier(lease[1], "supervisor.state.invalid")
273
+ lease_expires_at = _timestamp(lease[2])
274
+ lease_active = lease_expires_at > now
275
+ status = "leased" if lease_active else "recoverable"
276
+ times = []
277
+ for name in ("last_started_at", "last_finished_at"):
278
+ value = row[name]
279
+ times.append(None if value is None else _timestamp(value))
280
+ if times[1] is not None and times[0] is None:
281
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
282
+ if times[0] is not None and times[1] is not None and times[1] < times[0]:
283
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
284
+ last_phase, last_status, last_error = (
285
+ row["last_phase"], row["last_status"], row["last_error_code"]
286
+ )
287
+ if (last_phase is None) != (last_status is None):
288
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
289
+ if last_phase is not None:
290
+ _identifier(last_phase, "supervisor.state.invalid")
291
+ _identifier(last_status, "supervisor.state.invalid")
292
+ if last_phase not in PHASES or last_status not in STATUSES:
293
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
294
+ if last_error is not None and (
295
+ not isinstance(last_error, str) or ERROR_CODE.fullmatch(last_error) is None
296
+ ):
297
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
298
+ if last_status is None:
299
+ if last_error is not None or blocked != 0:
300
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
301
+ elif (last_status in BLOCKED_STATUSES) != (last_error is not None):
302
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
303
+ if (blocked > 0) != (last_status in BLOCKED_STATUSES):
304
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
305
+ return SupervisorStatus(
306
+ SCHEMA, status, revision, lease_active, lease_expires_at,
307
+ next_tick_at, blocked, times[0], times[1], last_phase,
308
+ last_status, last_error,
309
+ )
310
+
311
+ def status(self, *, now: float | int | None = None) -> SupervisorStatus:
312
+ now = _timestamp(self.clock() if now is None else now)
313
+ try:
314
+ self._verify_schema()
315
+ row = self.connection.execute(
316
+ "SELECT * FROM localization_service_supervisor WHERE singleton = 1"
317
+ ).fetchone()
318
+ if row is None:
319
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
320
+ return self._status_from_row(row, now)
321
+ except LocalizationSupervisorBlocked:
322
+ raise
323
+ except Exception:
324
+ raise LocalizationSupervisorBlocked("supervisor.state.unavailable") from None
325
+
326
+ def _claim(self, now: float) -> tuple[str | None, SupervisorRunOutcome | None]:
327
+ token = _identifier(
328
+ self.token_factory(), "supervisor.lease_token.invalid",
329
+ )
330
+ with _transaction(self.connection):
331
+ row = self.connection.execute(
332
+ "SELECT * FROM localization_service_supervisor WHERE singleton = 1"
333
+ ).fetchone()
334
+ if row is None:
335
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
336
+ status = self._status_from_row(row, now)
337
+ if status.lease_active:
338
+ return None, SupervisorRunOutcome(
339
+ SCHEMA, "leased", status.lease_expires_at or now,
340
+ )
341
+ if status.status == "waiting":
342
+ return None, SupervisorRunOutcome(
343
+ SCHEMA, "waiting", status.next_tick_at,
344
+ )
345
+ expires = now + self.policy.lease_seconds
346
+ updated = self.connection.execute("""
347
+ UPDATE localization_service_supervisor
348
+ SET revision = revision + 1,
349
+ lease_owner = ?, lease_token = ?, lease_expires_at = ?,
350
+ last_started_at = ?, last_finished_at = NULL, updated_at = ?
351
+ WHERE singleton = 1 AND revision = ?
352
+ """, (
353
+ self.worker_id, token, expires, now, now, status.revision,
354
+ ))
355
+ if updated.rowcount != 1:
356
+ raise LocalizationSupervisorBlocked("supervisor.state.conflict")
357
+ return token, None
358
+
359
+ def _finish(self, token: str, tick: dict[str, Any], now: float) -> float:
360
+ blocked = tick["status"] in BLOCKED_STATUSES
361
+ with _transaction(self.connection):
362
+ row = self.connection.execute(
363
+ "SELECT * FROM localization_service_supervisor WHERE singleton = 1"
364
+ ).fetchone()
365
+ if row is None:
366
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
367
+ status = self._status_from_row(row, now)
368
+ if (
369
+ row["lease_owner"] != self.worker_id
370
+ or row["lease_token"] != token
371
+ or row["lease_expires_at"] is None
372
+ or _timestamp(row["lease_expires_at"]) <= now
373
+ ):
374
+ raise LocalizationSupervisorBlocked("supervisor.lease_lost")
375
+ failures = status.consecutive_blocked + 1 if blocked else 0
376
+ if blocked:
377
+ delay = min(
378
+ self.policy.blocked_max_seconds,
379
+ self.policy.blocked_base_seconds * (2 ** min(failures - 1, 30)),
380
+ )
381
+ elif tick["phase"] == "idle" and tick["status"] == "idle":
382
+ delay = self.policy.idle_delay_seconds
383
+ else:
384
+ delay = self.policy.active_delay_seconds
385
+ next_tick_at = now + delay
386
+ updated = self.connection.execute("""
387
+ UPDATE localization_service_supervisor
388
+ SET revision = revision + 1,
389
+ lease_owner = NULL, lease_token = NULL, lease_expires_at = NULL,
390
+ next_tick_at = ?, consecutive_blocked = ?,
391
+ last_finished_at = ?, last_phase = ?, last_status = ?,
392
+ last_error_code = ?, updated_at = ?
393
+ WHERE singleton = 1 AND lease_owner = ? AND lease_token = ?
394
+ """, (
395
+ next_tick_at, failures, now, tick["phase"], tick["status"],
396
+ tick["error_code"], now, self.worker_id, token,
397
+ ))
398
+ if updated.rowcount != 1:
399
+ raise LocalizationSupervisorBlocked("supervisor.lease_lost")
400
+ return next_tick_at
401
+
402
+ def renew_active_lease(self, minimum_child_seconds: float | int) -> float:
403
+ """Renew the current outer lease immediately before child work."""
404
+ if (
405
+ isinstance(minimum_child_seconds, bool)
406
+ or not isinstance(minimum_child_seconds, (int, float))
407
+ ):
408
+ raise LocalizationSupervisorBlocked("supervisor.lease_guard.invalid")
409
+ minimum_child_seconds = float(minimum_child_seconds)
410
+ if (
411
+ not math.isfinite(minimum_child_seconds)
412
+ or minimum_child_seconds <= 0
413
+ or minimum_child_seconds >= self.policy.lease_seconds
414
+ ):
415
+ raise LocalizationSupervisorBlocked("supervisor.lease_guard.invalid")
416
+ token = self._active_token
417
+ if token is None:
418
+ raise LocalizationSupervisorBlocked("supervisor.lease_guard.inactive")
419
+ now = _timestamp(self.clock())
420
+ expires = now + self.policy.lease_seconds
421
+ with _transaction(self.connection):
422
+ row = self.connection.execute(
423
+ "SELECT * FROM localization_service_supervisor WHERE singleton = 1"
424
+ ).fetchone()
425
+ if row is None:
426
+ raise LocalizationSupervisorBlocked("supervisor.state.invalid")
427
+ status = self._status_from_row(row, now)
428
+ if (
429
+ not status.lease_active
430
+ or row["lease_owner"] != self.worker_id
431
+ or row["lease_token"] != token
432
+ ):
433
+ raise LocalizationSupervisorBlocked("supervisor.lease_lost")
434
+ updated = self.connection.execute("""
435
+ UPDATE localization_service_supervisor
436
+ SET revision = revision + 1, lease_expires_at = ?, updated_at = ?
437
+ WHERE singleton = 1 AND lease_owner = ? AND lease_token = ?
438
+ AND lease_expires_at > ? AND revision = ?
439
+ """, (
440
+ expires, now, self.worker_id, token, now, status.revision,
441
+ ))
442
+ if updated.rowcount != 1:
443
+ raise LocalizationSupervisorBlocked("supervisor.lease_lost")
444
+ return expires
445
+
446
+ def run_once(self, *, now: float | int | None = None) -> SupervisorRunOutcome:
447
+ started = _timestamp(self.clock() if now is None else now)
448
+ try:
449
+ token, skipped = self._claim(started)
450
+ except LocalizationSupervisorBlocked:
451
+ raise
452
+ except Exception:
453
+ raise LocalizationSupervisorBlocked("supervisor.state.unavailable") from None
454
+ if skipped is not None:
455
+ return skipped
456
+ assert token is not None
457
+ try:
458
+ self._active_token = token
459
+ try:
460
+ try:
461
+ tick = _tick_payload(self.tick())
462
+ except Exception:
463
+ tick = {
464
+ "schema": TICK_SCHEMA,
465
+ "phase": "supervisor",
466
+ "status": "blocked",
467
+ "event_id": None,
468
+ "plan_id": None,
469
+ "job_id": None,
470
+ "target_locale": None,
471
+ "delivery_id": None,
472
+ "attempt": None,
473
+ "error_code": "supervisor.tick.unhandled",
474
+ }
475
+ finally:
476
+ self._active_token = None
477
+ finished = _timestamp(self.clock())
478
+ if finished < started:
479
+ raise LocalizationSupervisorBlocked("supervisor.clock.invalid")
480
+ next_tick_at = self._finish(token, tick, finished)
481
+ return SupervisorRunOutcome(SCHEMA, "ran", next_tick_at, tick)
482
+ except LocalizationSupervisorBlocked:
483
+ raise
484
+ except Exception:
485
+ raise LocalizationSupervisorBlocked("supervisor.state.unavailable") from None
486
+
487
+ def run_forever(
488
+ self,
489
+ *,
490
+ stop_requested: Callable[[], bool],
491
+ sleeper: Callable[[float], Any] = time.sleep,
492
+ ) -> SupervisorStatus:
493
+ if not callable(stop_requested) or not callable(sleeper):
494
+ raise LocalizationSupervisorBlocked("supervisor.dependency.invalid")
495
+ while True:
496
+ try:
497
+ should_stop = stop_requested()
498
+ except Exception:
499
+ raise LocalizationSupervisorBlocked("supervisor.stop.invalid") from None
500
+ if should_stop is not False and should_stop is not True:
501
+ raise LocalizationSupervisorBlocked("supervisor.stop.invalid")
502
+ if should_stop:
503
+ return self.status()
504
+ outcome = self.run_once()
505
+ now = _timestamp(self.clock())
506
+ delay = min(
507
+ self.policy.stop_poll_seconds,
508
+ max(0.0, outcome.next_tick_at - now),
509
+ )
510
+ if delay > 0:
511
+ sleeper(delay)