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,482 @@
1
+ #!/usr/bin/env python3
2
+ """Request-bound HTTPS transport for one localization quality-evidence job."""
3
+
4
+ from __future__ import annotations
5
+
6
+ import hashlib
7
+ import json
8
+ import re
9
+ import socket
10
+ import unicodedata
11
+ import urllib.error
12
+ import urllib.parse
13
+ import urllib.request
14
+ from dataclasses import dataclass
15
+ from typing import Any, Callable, Mapping, Protocol
16
+
17
+
18
+ REQUEST_SCHEMA = "blun.localization-quality-evidence-http-request.v1"
19
+ RESPONSE_SCHEMA = "blun.localization-quality-evidence-http-response.v1"
20
+ EVIDENCE_REQUEST_SCHEMA = "blun.localization-quality-evidence-request.v5"
21
+ EVIDENCE_RESPONSE_SCHEMA = "blun.localization-quality-evidence-response.v2"
22
+ MAX_ENDPOINT_LENGTH = 2048
23
+ MAX_HEADER_VALUE_LENGTH = 4096
24
+ MAX_TEXT_BYTES = 2_000_000
25
+ MAX_REQUEST_BYTES = 8_500_000
26
+ MAX_RESPONSE_BYTES = 1_000_000
27
+ HEADER_NAME = re.compile(r"^[!#$%&'*+.^_`|~0-9A-Za-z-]{1,128}$")
28
+ REQUEST_ID = re.compile(r"^blun-l10n-evidence-[0-9a-f]{64}$")
29
+ SHA256 = re.compile(r"^[0-9a-f]{64}$")
30
+ TOKEN = re.compile(r"^[A-Za-z0-9_.:-]{1,256}$")
31
+ ERROR_CODE = re.compile(r"^[a-z][a-z0-9_.-]{0,127}$")
32
+ COMMERCIAL_REVIEW_SUMMARY_SCHEMA = "translate-native.commercial-review-summary.v1"
33
+ COMMERCIAL_DIMENSIONS = (
34
+ "amount_currency", "discount_basis", "qualifiers", "tax_status",
35
+ "billing_interval", "commitment", "renewal", "cancellation",
36
+ "conditions", "offer_assignment",
37
+ )
38
+ REQUEST_FIELDS = {
39
+ "schema", "request_id", "evidence_revision", "event_id", "plan_id",
40
+ "job_id", "result_sha256", "source_sha256", "target_sha256",
41
+ "source_locale", "target_locale", "content_type", "glossary_version",
42
+ "policy_version", "provider", "software_version", "source_text",
43
+ "target_text", "review_confidence", "quality_profile",
44
+ "commercial_profile", "commercial_review", "human_review_required",
45
+ "independent_review_required",
46
+ }
47
+ EVIDENCE_FIELDS = {
48
+ "schema", "request_id", "result_sha256", "quality_receipt",
49
+ "human_review_receipt", "independent_model_review",
50
+ }
51
+ RESERVED_HEADERS = {
52
+ "accept", "accept-encoding", "connection", "content-length",
53
+ "content-type", "host", "idempotency-key", "transfer-encoding",
54
+ "x-localization-evidence-request-id",
55
+ "x-localization-evidence-request-sha256",
56
+ }
57
+
58
+
59
+ class HTTPEvidenceProviderFailed(RuntimeError):
60
+ """Content-free adapter failure understood by release coordination."""
61
+
62
+ localization_evidence_failure = True
63
+
64
+ def __init__(self, code: str, *, retryable: bool):
65
+ if not isinstance(code, str) or ERROR_CODE.fullmatch(code) is None:
66
+ raise ValueError("HTTP evidence error code is invalid")
67
+ if not isinstance(retryable, bool):
68
+ raise ValueError("HTTP evidence retryability must be boolean")
69
+ super().__init__(code)
70
+ self.code = code
71
+ self.retryable = retryable
72
+
73
+
74
+ @dataclass(frozen=True)
75
+ class HTTPResult:
76
+ status: int
77
+ headers: tuple[tuple[str, str], ...]
78
+ body: bytes
79
+
80
+
81
+ class HTTPTransport(Protocol):
82
+ def post(
83
+ self,
84
+ url: str,
85
+ headers: Mapping[str, str],
86
+ body: bytes,
87
+ *,
88
+ timeout: float,
89
+ ) -> HTTPResult: ...
90
+
91
+
92
+ class _NoRedirect(urllib.request.HTTPRedirectHandler):
93
+ def redirect_request(self, req, fp, code, msg, headers, newurl):
94
+ return None
95
+
96
+
97
+ class URLTransport:
98
+ """Perform one bounded HTTP request without following redirects."""
99
+
100
+ def __init__(self):
101
+ self._opener = urllib.request.build_opener(_NoRedirect)
102
+
103
+ def post(
104
+ self,
105
+ url: str,
106
+ headers: Mapping[str, str],
107
+ body: bytes,
108
+ *,
109
+ timeout: float,
110
+ ) -> HTTPResult:
111
+ request = urllib.request.Request(
112
+ url, data=body, headers=dict(headers), method="POST",
113
+ )
114
+ try:
115
+ response = self._opener.open(request, timeout=timeout)
116
+ except urllib.error.HTTPError as error:
117
+ response_headers = tuple(error.headers.items()) if error.headers else ()
118
+ return HTTPResult(int(error.code), response_headers, b"")
119
+ except (urllib.error.URLError, TimeoutError, socket.timeout, OSError):
120
+ raise HTTPEvidenceProviderFailed("network", retryable=True) from None
121
+ try:
122
+ response_body = response.read(MAX_RESPONSE_BYTES + 1)
123
+ return HTTPResult(
124
+ int(response.status), tuple(response.headers.items()), response_body,
125
+ )
126
+ except (TimeoutError, socket.timeout, OSError):
127
+ raise HTTPEvidenceProviderFailed("network", retryable=True) from None
128
+ finally:
129
+ response.close()
130
+
131
+
132
+ def _canonical_json(value: Any, *, code: str, maximum: int) -> bytes:
133
+ try:
134
+ encoded = json.dumps(
135
+ value,
136
+ ensure_ascii=False,
137
+ allow_nan=False,
138
+ sort_keys=True,
139
+ separators=(",", ":"),
140
+ ).encode("utf-8")
141
+ except (TypeError, ValueError, UnicodeEncodeError, RecursionError):
142
+ raise HTTPEvidenceProviderFailed(code, retryable=False) from None
143
+ if not encoded or len(encoded) > maximum:
144
+ raise HTTPEvidenceProviderFailed(code, retryable=False)
145
+ return encoded
146
+
147
+
148
+ def _pairs(items):
149
+ result = {}
150
+ for key, value in items:
151
+ if key in result:
152
+ raise ValueError("duplicate JSON key")
153
+ result[key] = value
154
+ return result
155
+
156
+
157
+ def _constant(value):
158
+ raise ValueError("non-finite JSON number")
159
+
160
+
161
+ def _endpoint(value: Any, allow_loopback_http: bool) -> str:
162
+ if (
163
+ not isinstance(value, str)
164
+ or value != value.strip()
165
+ or not value
166
+ or not value.isascii()
167
+ or len(value) > MAX_ENDPOINT_LENGTH
168
+ or any(ord(character) <= 32 or ord(character) == 127 for character in value)
169
+ ):
170
+ raise ValueError("endpoint is invalid")
171
+ try:
172
+ parsed = urllib.parse.urlsplit(value)
173
+ hostname = parsed.hostname
174
+ port = parsed.port
175
+ except ValueError:
176
+ raise ValueError("endpoint is invalid") from None
177
+ if (
178
+ not hostname
179
+ or not hostname.isascii()
180
+ or parsed.username is not None
181
+ or parsed.password is not None
182
+ or parsed.query
183
+ or parsed.fragment
184
+ or not parsed.path.startswith("/")
185
+ or parsed.path.startswith("//")
186
+ ):
187
+ raise ValueError("endpoint is invalid")
188
+ if parsed.scheme == "https":
189
+ pass
190
+ elif (
191
+ parsed.scheme == "http"
192
+ and allow_loopback_http
193
+ and hostname.lower() in {"localhost", "127.0.0.1", "::1"}
194
+ ):
195
+ pass
196
+ else:
197
+ raise ValueError("endpoint must use HTTPS")
198
+ if port is not None and not 1 <= port <= 65535:
199
+ raise ValueError("endpoint is invalid")
200
+ return value
201
+
202
+
203
+ def _authentication_headers(
204
+ provider: Callable[[], Mapping[str, str]],
205
+ ) -> dict[str, str]:
206
+ try:
207
+ supplied = provider()
208
+ except Exception:
209
+ raise HTTPEvidenceProviderFailed("authentication", retryable=False) from None
210
+ if not isinstance(supplied, Mapping) or not supplied:
211
+ raise HTTPEvidenceProviderFailed("authentication", retryable=False)
212
+ result: dict[str, str] = {}
213
+ normalized_names: set[str] = set()
214
+ for name, value in supplied.items():
215
+ normalized = name.lower() if isinstance(name, str) else ""
216
+ if (
217
+ not isinstance(name, str)
218
+ or HEADER_NAME.fullmatch(name) is None
219
+ or normalized in RESERVED_HEADERS
220
+ or normalized in normalized_names
221
+ or not isinstance(value, str)
222
+ or not value
223
+ or not value.isascii()
224
+ or len(value) > MAX_HEADER_VALUE_LENGTH
225
+ or "\r" in value
226
+ or "\n" in value
227
+ or any(ord(character) < 32 or ord(character) == 127 for character in value)
228
+ ):
229
+ raise HTTPEvidenceProviderFailed("authentication", retryable=False)
230
+ normalized_names.add(normalized)
231
+ result[name] = value
232
+ return result
233
+
234
+
235
+ def _response_headers(value: Any) -> dict[str, str]:
236
+ if not isinstance(value, tuple):
237
+ raise HTTPEvidenceProviderFailed("transport_invalid", retryable=True)
238
+ result: dict[str, str] = {}
239
+ for item in value:
240
+ if (
241
+ not isinstance(item, tuple)
242
+ or len(item) != 2
243
+ or not all(isinstance(part, str) for part in item)
244
+ ):
245
+ raise HTTPEvidenceProviderFailed("transport_invalid", retryable=True)
246
+ name, content = item[0].lower(), item[1].strip()
247
+ if name in {"content-type", "content-length"}:
248
+ if name in result:
249
+ raise HTTPEvidenceProviderFailed("response_headers", retryable=True)
250
+ result[name] = content
251
+ return result
252
+
253
+
254
+ def _token(value: Any) -> bool:
255
+ return isinstance(value, str) and TOKEN.fullmatch(value) is not None
256
+
257
+
258
+ def _safe_text(value: Any) -> bool:
259
+ return (
260
+ isinstance(value, str)
261
+ and bool(value.strip())
262
+ and "\x00" not in value
263
+ and unicodedata.is_normalized("NFC", value)
264
+ and len(value.encode("utf-8")) <= MAX_TEXT_BYTES
265
+ )
266
+
267
+
268
+ def _request_payload(request: Any) -> tuple[dict[str, Any], bytes]:
269
+ try:
270
+ payload = request.as_payload()
271
+ request_id = request.request_id
272
+ except Exception:
273
+ raise HTTPEvidenceProviderFailed("request_invalid", retryable=False) from None
274
+ if (
275
+ not isinstance(payload, dict)
276
+ or set(payload) != REQUEST_FIELDS
277
+ or payload.get("schema") != EVIDENCE_REQUEST_SCHEMA
278
+ or payload.get("request_id") != request_id
279
+ or not isinstance(request_id, str)
280
+ or REQUEST_ID.fullmatch(request_id) is None
281
+ ):
282
+ raise HTTPEvidenceProviderFailed("request_invalid", retryable=False)
283
+ token_fields = (
284
+ "evidence_revision", "event_id", "plan_id", "job_id",
285
+ "source_locale", "target_locale", "content_type", "glossary_version",
286
+ "policy_version", "software_version",
287
+ )
288
+ if any(not _token(payload[field]) for field in token_fields):
289
+ raise HTTPEvidenceProviderFailed("request_invalid", retryable=False)
290
+ for field in ("result_sha256", "source_sha256", "target_sha256"):
291
+ if not isinstance(payload[field], str) or SHA256.fullmatch(payload[field]) is None:
292
+ raise HTTPEvidenceProviderFailed("request_invalid", retryable=False)
293
+ source_text = payload["source_text"]
294
+ target_text = payload["target_text"]
295
+ if (
296
+ not _safe_text(source_text)
297
+ or not _safe_text(target_text)
298
+ or hashlib.sha256(source_text.encode("utf-8")).hexdigest() != payload["source_sha256"]
299
+ or hashlib.sha256(target_text.encode("utf-8")).hexdigest() != payload["target_sha256"]
300
+ ):
301
+ raise HTTPEvidenceProviderFailed("request_invalid", retryable=False)
302
+ provider = payload["provider"]
303
+ confidence = payload["review_confidence"]
304
+ profile = payload["quality_profile"]
305
+ commercial_review = payload["commercial_review"]
306
+ if (
307
+ not isinstance(provider, dict)
308
+ or set(provider) != {"id", "model_id", "model_version"}
309
+ or any(not _token(provider[field]) for field in provider)
310
+ or not isinstance(confidence, dict)
311
+ or set(confidence) != {"target_native", "source_fidelity"}
312
+ or any(value not in {"high", "low"} for value in confidence.values())
313
+ or not isinstance(profile, dict)
314
+ or set(profile) != {"locale", "version", "sha256"}
315
+ or profile["locale"] != payload["target_locale"]
316
+ or not _token(profile["version"])
317
+ or not isinstance(profile["sha256"], str)
318
+ or SHA256.fullmatch(profile["sha256"]) is None
319
+ or type(payload["human_review_required"]) is not bool
320
+ or type(payload["independent_review_required"]) is not bool
321
+ or (
322
+ payload["commercial_profile"] is not None
323
+ and not _token(payload["commercial_profile"])
324
+ )
325
+ or ((payload["commercial_profile"] is None) != (commercial_review is None))
326
+ or (
327
+ commercial_review is not None
328
+ and (
329
+ not isinstance(commercial_review, dict)
330
+ or set(commercial_review) != {
331
+ "schema", "profile", "status",
332
+ "review_required_dimensions", "evidence_sha256",
333
+ }
334
+ or commercial_review["schema"] != COMMERCIAL_REVIEW_SUMMARY_SCHEMA
335
+ or commercial_review["profile"] != payload["commercial_profile"]
336
+ or commercial_review["status"] not in {
337
+ "verified", "review_required",
338
+ }
339
+ or not isinstance(
340
+ commercial_review["review_required_dimensions"], list,
341
+ )
342
+ or commercial_review["review_required_dimensions"] != [
343
+ name for name in COMMERCIAL_DIMENSIONS
344
+ if name in commercial_review["review_required_dimensions"]
345
+ ]
346
+ or len(commercial_review["review_required_dimensions"])
347
+ != len(set(commercial_review["review_required_dimensions"]))
348
+ or (
349
+ commercial_review["status"] == "verified"
350
+ and commercial_review["review_required_dimensions"]
351
+ )
352
+ or (
353
+ commercial_review["status"] == "review_required"
354
+ and (
355
+ not commercial_review["review_required_dimensions"]
356
+ or not payload["independent_review_required"]
357
+ )
358
+ )
359
+ or not isinstance(commercial_review["evidence_sha256"], str)
360
+ or SHA256.fullmatch(commercial_review["evidence_sha256"]) is None
361
+ )
362
+ )
363
+ ):
364
+ raise HTTPEvidenceProviderFailed("request_invalid", retryable=False)
365
+ return payload, _canonical_json(
366
+ payload, code="request_invalid", maximum=MAX_REQUEST_BYTES,
367
+ )
368
+
369
+
370
+ class HTTPEvidenceProviderAdapter:
371
+ """Perform one HTTPS attempt for one leased quality-evidence request."""
372
+
373
+ def __init__(
374
+ self,
375
+ endpoint: str,
376
+ authentication_headers: Callable[[], Mapping[str, str]],
377
+ *,
378
+ transport: HTTPTransport | None = None,
379
+ timeout: float = 60.0,
380
+ allow_loopback_http: bool = False,
381
+ ):
382
+ if not isinstance(allow_loopback_http, bool):
383
+ raise TypeError("allow_loopback_http must be boolean")
384
+ self.endpoint = _endpoint(endpoint, allow_loopback_http)
385
+ if not callable(authentication_headers):
386
+ raise TypeError("authentication_headers must be callable")
387
+ if (
388
+ isinstance(timeout, bool)
389
+ or not isinstance(timeout, (int, float))
390
+ or not 0 < timeout <= 300
391
+ ):
392
+ raise ValueError("timeout is outside the supported range")
393
+ self.authentication_headers = authentication_headers
394
+ self.transport = URLTransport() if transport is None else transport
395
+ if not callable(getattr(self.transport, "post", None)):
396
+ raise TypeError("transport must provide post")
397
+ self.timeout = float(timeout)
398
+
399
+ def obtain(self, request: Any) -> Mapping[str, Any]:
400
+ payload, request_bytes = _request_payload(request)
401
+ request_hash = hashlib.sha256(request_bytes).hexdigest()
402
+ envelope = {
403
+ "schema": REQUEST_SCHEMA,
404
+ "request_id": payload["request_id"],
405
+ "request_sha256": request_hash,
406
+ "request": payload,
407
+ }
408
+ body = _canonical_json(
409
+ envelope, code="request_invalid", maximum=MAX_REQUEST_BYTES,
410
+ )
411
+ headers = _authentication_headers(self.authentication_headers)
412
+ headers.update({
413
+ "Accept": "application/json",
414
+ "Content-Type": "application/json; charset=utf-8",
415
+ "Idempotency-Key": payload["request_id"],
416
+ "X-Localization-Evidence-Request-Id": payload["request_id"],
417
+ "X-Localization-Evidence-Request-Sha256": request_hash,
418
+ })
419
+ try:
420
+ result = self.transport.post(
421
+ self.endpoint, headers, body, timeout=self.timeout,
422
+ )
423
+ except HTTPEvidenceProviderFailed:
424
+ raise
425
+ except Exception:
426
+ raise HTTPEvidenceProviderFailed("network", retryable=True) from None
427
+ if (
428
+ not isinstance(result, HTTPResult)
429
+ or isinstance(result.status, bool)
430
+ or not isinstance(result.status, int)
431
+ or not 100 <= result.status <= 599
432
+ ):
433
+ raise HTTPEvidenceProviderFailed("transport_invalid", retryable=True)
434
+ if result.status != 200:
435
+ if 300 <= result.status <= 399:
436
+ raise HTTPEvidenceProviderFailed("redirect", retryable=False)
437
+ retryable = result.status in {408, 425, 429} or 500 <= result.status <= 599
438
+ raise HTTPEvidenceProviderFailed("http_status", retryable=retryable)
439
+ response_headers = _response_headers(result.headers)
440
+ content_type = response_headers.get("content-type", "").lower().replace(" ", "")
441
+ if content_type not in {"application/json", "application/json;charset=utf-8"}:
442
+ raise HTTPEvidenceProviderFailed("response_content_type", retryable=True)
443
+ if (
444
+ not isinstance(result.body, bytes)
445
+ or not result.body
446
+ or len(result.body) > MAX_RESPONSE_BYTES
447
+ ):
448
+ raise HTTPEvidenceProviderFailed("response_size", retryable=True)
449
+ declared = response_headers.get("content-length")
450
+ if declared is not None and (
451
+ not declared.isascii()
452
+ or not declared.isdecimal()
453
+ or int(declared) != len(result.body)
454
+ ):
455
+ raise HTTPEvidenceProviderFailed("response_size", retryable=True)
456
+ try:
457
+ text = result.body.decode("utf-8")
458
+ if text.startswith("\ufeff"):
459
+ raise ValueError("BOM rejected")
460
+ response_envelope = json.loads(
461
+ text, object_pairs_hook=_pairs, parse_constant=_constant,
462
+ )
463
+ except (UnicodeDecodeError, json.JSONDecodeError, ValueError, RecursionError):
464
+ raise HTTPEvidenceProviderFailed("response_json", retryable=True) from None
465
+ if not isinstance(response_envelope, dict) or set(response_envelope) != {
466
+ "schema", "request_id", "request_sha256", "result_sha256", "evidence",
467
+ }:
468
+ raise HTTPEvidenceProviderFailed("response_binding", retryable=False)
469
+ evidence = response_envelope["evidence"]
470
+ if (
471
+ response_envelope["schema"] != RESPONSE_SCHEMA
472
+ or response_envelope["request_id"] != payload["request_id"]
473
+ or response_envelope["request_sha256"] != request_hash
474
+ or response_envelope["result_sha256"] != payload["result_sha256"]
475
+ or not isinstance(evidence, dict)
476
+ or set(evidence) != EVIDENCE_FIELDS
477
+ or evidence.get("schema") != EVIDENCE_RESPONSE_SCHEMA
478
+ or evidence.get("request_id") != payload["request_id"]
479
+ or evidence.get("result_sha256") != payload["result_sha256"]
480
+ ):
481
+ raise HTTPEvidenceProviderFailed("response_binding", retryable=False)
482
+ return evidence