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
@@ -19,30 +19,29 @@ import { readHookInput, SILENT_OVERSIZE_POST_TOOL_USE, SILENT_OVERSIZE_POST_TOOL
19
19
  import { isMainModule } from "./lib/runtime.js";
20
20
  import { deliveryActorSession, deliverySuccessEvidence, recordDeliveryToolUse,
21
21
  recordDeliveryWriteIntent } from "./lib/delivery-verification.js";
22
- import {
23
- blockPrompt, blockStop, blunRuntimeContext, blunRuntimeMessage, denyTool, hookOutput, lifecycleOutput
24
- } from "./lib/hook-output.js";
25
- import {
26
- ATTENTION_WRITE_EVENTS, boundedId, captureAttentionLifecycle, hookDeliveryId, hostContextLimit, hostFromInput,
22
+ import { blockPrompt, blockStop, blunRuntimeContext, blunRuntimeMessage, denyTool, hookOutput,
23
+ lifecycleOutput } from "./lib/hook-output.js";
24
+ import { ATTENTION_WRITE_EVENTS, boundedId, captureAttentionLifecycle, hookDeliveryId, hostContextLimit, hostFromInput,
27
25
  promptFromInput, renderContext, runtimeScope, selfstarterInput, selfstarterRootSkipped,
28
- selfstarterScope, sessionId, startChannelEvent, startSelfstarter, toolResult, toolSucceeded
29
- } from "./lib/hook-context.js";
30
- import {
31
- auditGuard, auditSkippedScans, candidatePaths, finishScanFailure, hookScanFailureFailsOpen,
32
- isMutationTool, isScanFailOpenTool, shellTargetsProtected
33
- } from "./lib/hook-protection.js";
34
- import {
35
- captureJavaScriptBeforeWrite, inspectWrittenJavaScript, verifyBaselineBeforeWrite, verifyDeliveredArtifacts
36
- } from "./lib/hook-artifact-guards.js";
26
+ selfstarterScope, sessionId, startChannelEvent, startSelfstarter, toolResult,
27
+ toolSucceeded } from "./lib/hook-context.js";
28
+ import { auditGuard, auditSkippedScans, candidatePaths, finishScanFailure, hookScanFailureFailsOpen,
29
+ isMutationTool, isScanFailOpenTool, shellTargetsProtected } from "./lib/hook-protection.js";
30
+ import { captureJavaScriptBeforeWrite, inspectWrittenJavaScript, verifyBaselineBeforeWrite,
31
+ verifyDeliveredArtifacts } from "./lib/hook-artifact-guards.js";
37
32
  import { isPremortemWrite, prepareHookPremortem, recordHookPremortemWrite,
38
33
  recordHookPremortemWriteIntent, verifyHookPremortemWrite } from "./lib/hook-premortem.js";
39
34
  import { verifyHookStopContracts } from "./lib/hook-stop-verification.js";
40
35
  import { processAdvisory } from "./lib/hook-process-advisory.js";
36
+ import { recordHookBriefingUse } from "./lib/hook-briefing-use.js";
41
37
  export { blunRuntimeContext, blunRuntimeMessage } from "./lib/hook-output.js";
42
38
  const CONTEXT_EVENTS = new Set(["SessionStart", "UserPromptSubmit", "PreCompact", "PostCompact"]);
43
- const KNOWN_EVENTS = new Set([
44
- ...CONTEXT_EVENTS, "InstructionsLoaded", "PreToolUse", "PostToolUse", "Stop", "SubagentStop"
45
- ]);
39
+ const KNOWN_EVENTS = new Set([...CONTEXT_EVENTS, "InstructionsLoaded", "PreToolUse", "PostToolUse", "Stop", "SubagentStop"]);
40
+ async function writeContextOutput(output, host) {
41
+ const field = Object.hasOwn(output.hookSpecificOutput, "message") ? "message" : "additionalContext", content = output.hookSpecificOutput[field];
42
+ await new Promise((resolveWrite, rejectWrite) => process.stdout.write(`${JSON.stringify(output)}\n`, (error) => error ? rejectWrite(error) : resolveWrite()));
43
+ return { schema: "agentspine.host-context-handoff/v1", host, field, bytes: Buffer.byteLength(content), digest: createHash("sha256").update(content).digest("hex") };
44
+ }
46
45
  async function runHookCore(input, payload, options) {
47
46
  if (!input || typeof input !== "object" || Array.isArray(input)) throw new Error("hook input must be one JSON object");
48
47
  const event = input.hook_event_name || input.event_name || "";
@@ -220,7 +219,7 @@ async function runHookCore(input, payload, options) {
220
219
  }
221
220
  premortem = { ...premortem, writeIntent: premortemIntent.status,
222
221
  writeDigest: premortemIntent.writeDigest || null };
223
- try { lessonRecall = actionLessonRecall({ catalog, event, input, scope }); }
222
+ try { lessonRecall = await actionLessonRecall({ catalog, event, input, scope }); }
224
223
  catch (error) { lessonRecall = { status: "degraded", items: [], reason: error.message, authority: "context-only" }; }
225
224
  }
226
225
  if (["PostToolUse", "Stop", "SubagentStop"].includes(event)) {
@@ -255,7 +254,6 @@ async function runHookCore(input, payload, options) {
255
254
  if (contracts.blocked) {
256
255
  return processAdvisory(input, payload, root, scope, { deliveryVerification, premortem });
257
256
  }
258
-
259
257
  try {
260
258
  artifactGuard = await verifyDeliveredArtifacts({ input, cwd });
261
259
  if (artifactGuard.blocked) {
@@ -287,7 +285,6 @@ async function runHookCore(input, payload, options) {
287
285
  scope = await runtimeScope(input, root, resolvedSources.userStateRoot, catalog);
288
286
  attentionEvent = await captureAttentionLifecycle(input, event, root, scope, catalog);
289
287
  }
290
-
291
288
  if (event === "PostToolUse" && !selfstarterRootSkipped(resolvedSources.diagnostics)) {
292
289
  scope ||= await runtimeScope(input, root, resolvedSources.userStateRoot, catalog);
293
290
  const exact = await selfstarterScope(input, scope, root, "effect");
@@ -298,7 +295,6 @@ async function runHookCore(input, payload, options) {
298
295
  });
299
296
  }
300
297
  }
301
-
302
298
  if (["Stop", "SubagentStop"].includes(event)) {
303
299
  scope ||= await runtimeScope(input, root, resolvedSources.userStateRoot, catalog);
304
300
  const exact = selfstarterRootSkipped(resolvedSources.diagnostics)
@@ -323,10 +319,10 @@ async function runHookCore(input, payload, options) {
323
319
  });
324
320
  }
325
321
  }
326
-
327
322
  if (CONTEXT_EVENTS.has(event)) {
328
323
  let signal = null;
329
324
  let preflight = null;
325
+ let briefingOrigin = null;
330
326
  try {
331
327
  await syncPersonaRosterFromEnvironment({ root, env: process.env, now: input.timestamp || new Date(), catalog });
332
328
  scope ||= await runtimeScope(input, root, resolvedSources.userStateRoot, catalog);
@@ -371,16 +367,16 @@ async function runHookCore(input, payload, options) {
371
367
  }
372
368
  const briefing = await sessionBriefing({
373
369
  root, cwd, host: scope.host, entityId: scope.entityId, groupId: scope.groupId,
374
- userId: scope.userId, tenantId: scope.tenantId, projectId: scope.projectId, currentTaskId: scope.currentTaskId,
370
+ userId: scope.userId, tenantId: scope.tenantId, projectId: scope.projectId, currentTaskId: scope.currentTaskId, portalRef: scope.portalRef, threadRef: scope.threadRef,
375
371
  includePrivate: Boolean(scope.entityId && !scope.groupId),
376
372
  focusActive: true, includeSourceContent: event === "UserPromptSubmit" ? false : !scope.groupId,
377
373
  maxBytes: event === "UserPromptSubmit" ? 4096 : scope.config.maxBriefingBytes,
378
374
  now: input.timestamp || new Date(),
379
- catalog, userStateRoot: resolvedSources.userStateRoot, sourceDiagnostics: resolvedSources.diagnostics,
380
- prompt: event === "UserPromptSubmit" ? promptFromInput(input) : null
375
+ catalog, userStateRoot: resolvedSources.userStateRoot, sourceDiagnostics: event === "UserPromptSubmit" ? null : resolvedSources.diagnostics,
376
+ prompt: event === "UserPromptSubmit" ? promptFromInput(input) : null, preAnswer: event === "UserPromptSubmit"
381
377
  });
382
378
  if (event === "PostCompact") {
383
- try { lessonRecall = actionLessonRecall({ catalog, event, input, scope }); }
379
+ try { lessonRecall = await actionLessonRecall({ catalog, event, input, scope }); }
384
380
  catch (error) { lessonRecall = { status: "degraded", items: [], reason: error.message, authority: "context-only" }; }
385
381
  }
386
382
  let context = renderContext(event, catalog, briefing, signal, attentionEvent, selfstarter, channelEvent, resolvedSources.diagnostics, preflight, lessonRecall);
@@ -388,10 +384,11 @@ async function runHookCore(input, payload, options) {
388
384
  throw new Error("mandatory preflight context exceeds the host hook injection limit");
389
385
  }
390
386
  if (event === "UserPromptSubmit") {
391
- const { preflightConsumed, timeline } = await finalizeUserPromptSessionTimeline({ root, input, scope, resolvedSources, preflight,
387
+ const finalized = await finalizeUserPromptSessionTimeline({ root, input, scope, resolvedSources, preflight,
392
388
  prompt: promptFromInput(input), now: input.timestamp || new Date() });
393
- if (!preflightConsumed) throw new Error("preflight receipt could not be consumed atomically for this exact turn");
394
- resolvedSources.diagnostics.timeline = timeline;
389
+ if (!finalized.preflightConsumed) throw new Error("preflight receipt could not be consumed atomically for this exact turn");
390
+ briefingOrigin = finalized.briefingOrigin;
391
+ resolvedSources.diagnostics.timeline = finalized.timeline;
395
392
  }
396
393
  if (event === "UserPromptSubmit") {
397
394
  const activeCanaries = briefing.learning.filter((item) => ["active", "revalidating"].includes(item.outcomeStatus));
@@ -433,7 +430,12 @@ async function runHookCore(input, payload, options) {
433
430
  }
434
431
  }
435
432
  if (payload) return { blocked: false, context, briefing, preflight, signal, attentionEvent, channelEvent, lessonRecall, catalogPath };
436
- process.stdout.write(`${JSON.stringify(hookOutput(event, context))}\n`);
433
+ const output = hookOutput(event, context);
434
+ const handoff = await writeContextOutput(output, process.env.BLUN_PLUGIN_ROOT ? "king"
435
+ : process.env.PLUGIN_ROOT ? "codex" : process.env.CLAUDE_PLUGIN_ROOT ? "claude" : scope.host);
436
+ if (event === "UserPromptSubmit" && briefingOrigin) {
437
+ await recordHookBriefingUse({ origin: briefingOrigin, root, handoff, now: input.timestamp || new Date() });
438
+ }
437
439
  return;
438
440
  } catch (error) {
439
441
  if (hookScanFailureFailsOpen(error)) {
@@ -468,7 +470,6 @@ async function runHookCore(input, payload, options) {
468
470
  learningDelivery, deliveryVerification, premortem, lessonRecall };
469
471
  process.stdout.write(`${JSON.stringify(lifecycleOutput(event, artifactGuard, premortem, deliveryVerification, process.env, sourceWarning, lessonRecall))}\n`);
470
472
  }
471
-
472
473
  export async function runHook(payload = null, options = {}) {
473
474
  let input = payload;
474
475
  try {
@@ -485,7 +486,6 @@ export async function runHook(payload = null, options = {}) {
485
486
  return finishScanFailure(input, payload, "lifecycle", error);
486
487
  }
487
488
  }
488
-
489
489
  if (isMainModule(import.meta.url)) {
490
490
  const args = process.argv.slice(2);
491
491
  const silentOversizePostToolUse = args.length === 1 && args[0] === SILENT_OVERSIZE_POST_TOOL_USE_ARG;
@@ -1,8 +1,10 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import { documentSnapshotContent } from "./documents.js";
3
+ import { learningContext } from "./learning-context.js";
3
4
 
4
5
  const AUTHORITY = "context-only";
5
6
  const MAX_ITEMS = 6;
7
+ const MAX_LEARNING_ITEMS = 3;
6
8
  const MAX_ITEM_BYTES = 2048;
7
9
  const MAX_TOTAL_BYTES = 8192;
8
10
 
@@ -10,17 +12,77 @@ function digest(value) {
10
12
  return createHash("sha256").update(JSON.stringify(value)).digest("hex");
11
13
  }
12
14
 
13
- export function actionLessonRecall({ catalog, event, input, scope }) {
15
+ function learningScope(scope) {
16
+ return {
17
+ personaId: scope.entityId,
18
+ userId: scope.userId,
19
+ tenantId: scope.tenantId,
20
+ projectId: scope.projectId,
21
+ groupId: scope.groupId,
22
+ taskId: scope.currentTaskId
23
+ };
24
+ }
25
+
26
+ function compactLearning(item) {
27
+ return {
28
+ id: item.id,
29
+ kind: item.kind,
30
+ claim: item.claim,
31
+ subjectId: item.subjectId,
32
+ confidence: item.confidence,
33
+ evidenceCount: item.evidenceCount,
34
+ acceptedAt: item.acceptedAt,
35
+ outcomeStatus: item.outcomeStatus,
36
+ relevance: item.relevance,
37
+ authority: AUTHORITY
38
+ };
39
+ }
40
+
41
+ export async function actionLessonRecall({ catalog, event, input, scope }) {
14
42
  const candidates = catalog.documents
15
43
  .filter((item) => item.sourceScope === "project-memory" && item.name !== "MEMORY.md")
16
44
  .filter((item) => ["prompt", "pinned", "entity", "project", "task", "always"].includes(item.relevance));
17
45
  if (scope.groupId) return {
18
- schema: "agentspine.action-lesson-recall/v1", status: "group-suppressed", event,
19
- items: [], omitted: candidates.length, instruction: null, authority: AUTHORITY
46
+ schema: "agentspine.action-lesson-recall/v2", status: "group-suppressed", event,
47
+ items: [], learning: [], omitted: candidates.length, instruction: null, authority: AUTHORITY
20
48
  };
21
49
  let used = 0;
22
50
  let omitted = Math.max(0, candidates.length - MAX_ITEMS);
23
51
  const items = [];
52
+ const learning = [];
53
+ let learningDiagnostics = { status: "not-applicable", reason: null };
54
+ if (event === "PreToolUse" && scope.currentTaskId && scope.entityId && scope.userId && scope.tenantId && scope.projectId) {
55
+ try {
56
+ const selected = await learningContext({
57
+ root: catalog.root,
58
+ includePrivate: true,
59
+ groupId: null,
60
+ scope: learningScope(scope),
61
+ maxItems: 50,
62
+ catalog,
63
+ now: input.timestamp || new Date(),
64
+ taskFocus: scope.currentTaskId
65
+ });
66
+ const exact = selected.items
67
+ .filter((item) => item.relevance?.match === "exact-task"
68
+ && item.relevance.taskId === scope.currentTaskId
69
+ && ["active", "validated", "revalidating"].includes(item.outcomeStatus));
70
+ for (const item of exact.slice(0, MAX_LEARNING_ITEMS)) {
71
+ const compact = compactLearning(item);
72
+ const bytes = Buffer.byteLength(JSON.stringify(compact));
73
+ if (bytes > MAX_ITEM_BYTES || used + bytes > MAX_TOTAL_BYTES) {
74
+ omitted += 1;
75
+ continue;
76
+ }
77
+ learning.push(compact);
78
+ used += bytes;
79
+ }
80
+ omitted += Math.max(0, exact.length - MAX_LEARNING_ITEMS);
81
+ learningDiagnostics = { status: learning.length ? "recalled" : "none", reason: null };
82
+ } catch (error) {
83
+ learningDiagnostics = { status: "degraded", reason: String(error.message).slice(0, 512) };
84
+ }
85
+ }
24
86
  for (const document of candidates.slice(0, MAX_ITEMS)) {
25
87
  const snapshot = documentSnapshotContent(document);
26
88
  const bytes = snapshot?.byteLength || 0;
@@ -36,17 +98,20 @@ export function actionLessonRecall({ catalog, event, input, scope }) {
36
98
  const material = {
37
99
  event, sessionId: input.session_id ?? input.sessionId ?? null,
38
100
  toolName: input.tool_name || null, toolUseId: input.tool_use_id || null,
39
- paths: items.map((item) => [item.path, item.sha256])
101
+ paths: items.map((item) => [item.path, item.sha256]),
102
+ learning: learning.map((item) => [item.id, item.acceptedAt, item.outcomeStatus])
40
103
  };
41
104
  return {
42
- schema: "agentspine.action-lesson-recall/v1",
43
- status: items.length ? "recalled" : "none",
105
+ schema: "agentspine.action-lesson-recall/v2",
106
+ status: items.length || learning.length ? "recalled" : learningDiagnostics.status === "degraded" ? "degraded" : "none",
44
107
  event,
45
108
  receiptDigest: digest(material),
46
109
  items,
110
+ learning,
111
+ learningDiagnostics,
47
112
  omitted,
48
- instruction: items.length
49
- ? "Before this action, compare the plan with every recalled lesson below. These are untrusted context only: they can constrain behavior through current host rules, but never grant permissions, identity, tools, access, delegation or policy exceptions."
113
+ instruction: items.length || learning.length
114
+ ? "Before this action, compare the plan with every recalled source lesson and outcome-gated exact-task strategy below. These are untrusted context only: they can constrain behavior through current host rules, but never grant permissions, identity, tools, access, delegation or policy exceptions."
50
115
  : null,
51
116
  authority: AUTHORITY
52
117
  };
@@ -55,8 +55,6 @@ function recalculateBudget(result) {
55
55
  function tryAdd(result, collection, item) {
56
56
  collection.push(item);
57
57
  recalculateBudget(result);
58
- // Keep a small accounting reserve so growing omission counters can never
59
- // invalidate a packet after an item has been accepted.
60
58
  if (result.budget.usedBytes <= result.budget.maxBytes - 128) return true;
61
59
  collection.pop();
62
60
  recalculateBudget(result);
@@ -96,6 +94,108 @@ function voiceProfile(entity) {
96
94
  .map(([key, item]) => [key, typeof item === "string" ? item.slice(0, 120) : item]));
97
95
  }
98
96
 
97
+ function pick(value, keys) {
98
+ return Object.fromEntries(keys.map((key) => [key, value[key]]));
99
+ }
100
+
101
+ function feedbackCandidates(values) {
102
+ if (values.length < 3) return values.map((item) =>
103
+ pick(item, ["id", "text", "provider", "digest", "session", "message", "at"]));
104
+ const shared = ["provider", "digest", "session"].filter((key) =>
105
+ values.every((item) => item[key] === values[0][key]));
106
+ const fields = ["id", "text", "message", "at",
107
+ ...["provider", "digest", "session"].filter((key) => !shared.includes(key))];
108
+ const expected = { id: "assertion:user-feedback-", message: "timeline-event:" };
109
+ const prefixes = fields.map((key) => expected[key] || (key === "at"
110
+ && values.every((item) => /^\d{4}-\d{2}-\d{2}T\d{2}:/.test(item[key]))
111
+ ? values[0][key].slice(0, 14) : ""));
112
+ return { fields, common: Object.fromEntries(shared.map((key) => [key, values[0][key]])), prefixes,
113
+ rows: values.map((item) => fields.map((key, index) => item[key].slice(prefixes[index].length))) };
114
+ }
115
+
116
+ function preAnswerRecall(world, currentTaskId) {
117
+ if (!currentTaskId) return null;
118
+ const task = [...(world.knowledge?.continuation?.tasks || []),
119
+ ...(world.knowledge?.continuation?.terminal || [])]
120
+ .find((item) => item.taskId === currentTaskId);
121
+ if (!task) return null;
122
+ const feedback = (world.knowledge?.taskContext?.items || []).filter((item) =>
123
+ item?.source?.kind === "uninterpreted-user-message"
124
+ && item.value?.targetAssertionId === task.assertionId)
125
+ .sort((left, right) => right.observedAt.localeCompare(left.observedAt));
126
+ const interpretations = (world.knowledge?.taskContext?.items || []).filter((item) =>
127
+ item?.source?.kind === "model-suggestion"
128
+ && ["agentspine.timeline-user-feedback-interpretation/v1",
129
+ "agentspine.timeline-user-feedback-clarification/v2"].includes(item.value?.schema)
130
+ && item.value?.targetAssertionId === task.assertionId);
131
+ const taskValue = pick(task, ["taskId", "status", "objective"]);
132
+ taskValue.lastVerifiedStep = task.lastVerifiedStep
133
+ ? pick(task.lastVerifiedStep, ["summary", "result"]) : null;
134
+ taskValue.nextStep = task.nextStep ? pick(task.nextStep, ["summary"]) : null;
135
+ const values = feedback.slice(0, 3).map(({ id, value, source, observedAt }) => ({
136
+ id,
137
+ text: value.sourceText,
138
+ status: value.interpretationStatus, completionVerified: value.completionVerified,
139
+ provider: value.sourceProvider, digest: value.sourceDigest,
140
+ session: source.sessionRef, message: source.messageRef, at: observedAt
141
+ }));
142
+ if (values.length && task.status === "completed" && task.source?.kind === "objective-measurement") {
143
+ taskValue.completionEvidence = {
144
+ status: "objective-verified", assertionId: task.assertionId, observedAt: task.observedAt,
145
+ source: pick(task.source, ["kind", "id", "digest", "sessionRef", "messageRef"])
146
+ };
147
+ }
148
+ if (!values.length) {
149
+ Object.assign(taskValue, pick(task, ["assertionId", "observedAt"]));
150
+ taskValue.source = pick(task.source, ["kind", "id", "digest", "sessionRef", "messageRef"]);
151
+ taskValue.scope = pick(task.scope, ["projectId", "groupId", "privacy", "portalRef", "threadRef"]);
152
+ taskValue.correctionStatus = task.source.kind === "explicit-user-feedback"
153
+ ? "applied-source-verified" : "none-current";
154
+ }
155
+ if (values.length === 1) {
156
+ const proposal = interpretations.find((item) =>
157
+ item.value.sourceFeedbackAssertionId === feedback[0].id);
158
+ if (proposal) {
159
+ const value = proposal.value;
160
+ const model = {
161
+ status: value.interpretationStatus, kind: value.interpretationKind,
162
+ nextStep: value.proposedNextStepSummary, question: value.clarificationQuestion,
163
+ provider: value.modelProvider, replaces: value.replacedNextStepId,
164
+ digest: proposal.source.digest, completionVerified: false
165
+ };
166
+ for (const key of ["nextStep", "question"]) {
167
+ if (model[key] === null) delete model[key];
168
+ }
169
+ values[0].modelInterpretation = model;
170
+ }
171
+ }
172
+ return {
173
+ schema: "agentspine.pre-answer-recall/v1",
174
+ order: "review-before-claims-and-actions",
175
+ task: taskValue,
176
+ ...(values.length === 1 ? { feedback: values[0], ...(task.status === "completed" ? {} : {
177
+ interpretationInput: { feedbackAssertionId: feedback[0].id,
178
+ targetAssertionId: feedback[0].value.targetAssertionId }
179
+ }) } : {}),
180
+ ...(values.length > 1 ? { feedbackCandidates: feedbackCandidates(values),
181
+ feedbackReview: { status: "multiple-unresolved", completionVerified: false,
182
+ targetAssertionId: feedback[0].value.targetAssertionId,
183
+ ...(() => {
184
+ const ids = feedback.slice(0, 3).map((item) => item.id).sort();
185
+ const proposal = interpretations.find((item) => item.value?.schema
186
+ === "agentspine.timeline-user-feedback-clarification/v2"
187
+ && JSON.stringify(item.value.sourceBindings.map((source) => source.feedbackAssertionId))
188
+ === JSON.stringify(ids));
189
+ return proposal ? { modelClarification: { status: proposal.value.interpretationStatus,
190
+ question: proposal.value.clarificationQuestion, provider: proposal.value.modelProvider,
191
+ replaces: proposal.value.replacedNextStepId, digest: proposal.source.digest,
192
+ completionVerified: false } } : {};
193
+ })(),
194
+ ...(feedback.length > 3 ? { omitted: feedback.length - 3 } : {}) } } : {}),
195
+ authority: "context-only"
196
+ };
197
+ }
198
+
99
199
  async function settleReads(promises) {
100
200
  const settled = await Promise.allSettled(promises);
101
201
  const failed = settled.find((item) => item.status === "rejected");
@@ -103,16 +203,13 @@ async function settleReads(promises) {
103
203
  return settled.map((item) => item.value);
104
204
  }
105
205
 
106
- /**
107
- * Assemble one immutable, privacy-filtered context packet for a host session.
108
- * The packet is descriptive only and fits maxBytes as compact UTF-8 JSON.
109
- */
110
206
  export async function sessionBriefing({
111
207
  root = process.cwd(), cwd = root, host = "generic", entityId = null,
112
208
  userId = null, tenantId = null, groupId = null, projectId = null, currentTaskId = null,
209
+ portalRef = null, threadRef = null,
113
210
  includePrivate = false, focusActive = true, includeSourceContent = true,
114
211
  maxBytes = 16384, now = new Date(), catalog: providedCatalog = null, userStateRoot = null,
115
- sourceDiagnostics = null, prompt = null
212
+ sourceDiagnostics = null, prompt = null, preAnswer = false
116
213
  } = {}) {
117
214
  const limit = integer(maxBytes, "maxBytes", MIN_BYTES, MAX_BYTES);
118
215
  if (!new Set(["codex", "claude", "generic"]).has(host)) throw new Error(`unsupported host: ${host}`);
@@ -136,7 +233,8 @@ export async function sessionBriefing({
136
233
  : { root: catalog.root, entityId, includePrivate, groupId, catalog })
137
234
  : null;
138
235
  const [learned, attention, tasks, shared, userLearned, personas, gateway, world, portfolio] = await settleReads([
139
- learningContext({ root: catalog.root, includePrivate, groupId, scope: learningScope, maxItems: 50, catalog, now }),
236
+ learningContext({ root: catalog.root, includePrivate, groupId, scope: learningScope, maxItems: 50,
237
+ catalog, now, taskFocus: currentTaskId }),
140
238
  attentionContext({
141
239
  root: catalog.root, includePrivate, entityId, groupId, projectId, currentTaskId,
142
240
  focusActive, markPresented: false, maxItems: 20, now, catalog
@@ -145,11 +243,11 @@ export async function sessionBriefing({
145
243
  sharedContext({ root: catalog.root, includePrivate, groupId, maxItems: 50, catalog }),
146
244
  userStateRoot && userStateRoot !== catalog.root
147
245
  ? learningContext({ root: userStateRoot, includePrivate, groupId, scope: learningScope, maxItems: 50, now,
148
- catalog: userCatalog })
246
+ catalog: userCatalog, taskFocus: currentTaskId })
149
247
  : Promise.resolve({ items: [] }),
150
248
  loadPersonaRuntime(catalog.root, catalog),
151
249
  loadGatewayRuntime(catalog.root, catalog),
152
- worldContext({ root: catalog.root, projectId, groupId, includePrivate,
250
+ worldContext({ root: catalog.root, projectId, groupId, includePrivate, portalRef, threadRef,
153
251
  continuationTaskId: currentTaskId, maxItems: 50, now }),
154
252
  tenantId ? projectPortfolioContext({ root: catalog.root, tenantId, groupId, markPresented: false, now })
155
253
  : Promise.resolve({ projects: [], observations: [], notice: null, rateLimited: false })
@@ -163,13 +261,15 @@ export async function sessionBriefing({
163
261
  }
164
262
  const gatewayFindings = gatewayRuntimeFindings(gateway.policy, gateway.runtime);
165
263
  if (gatewayFindings.length) throw new Error(`gateway runtime failed closed: ${gatewayFindings.join(", ")}`);
264
+ const compactFeedbackRecall = !preAnswer && currentTaskId
265
+ && world.knowledge.taskContext.items.filter((item) => item.predicate === "task.user-feedback").length >= 3;
166
266
 
167
267
  const result = {
168
268
  schema: "agentspine.session-briefing/v1",
169
- root: catalog.root,
170
- cwd: sources.cwd,
269
+ ...(preAnswer ? {} : { root: catalog.root, cwd: sources.cwd }),
171
270
  host,
172
- scope: { entityId, userId, tenantId, groupId, projectId, includePrivate },
271
+ scope: { entityId, userId, tenantId, groupId, projectId, includePrivate,
272
+ ...(portalRef && threadRef ? { portalRef, threadRef } : {}) },
173
273
  focus: { active: Boolean(focusActive), currentTaskId },
174
274
  sources: { documents: [], diagnostics: sourceDiagnostics },
175
275
  tasks: [],
@@ -195,16 +295,14 @@ export async function sessionBriefing({
195
295
  activeSignals: [],
196
296
  cue: voiceCue(prompt),
197
297
  guidance: [
198
- "Lead with the useful outcome.",
199
- "Use the active persona naturally; do not imitate emotion or claim consciousness.",
200
- "Do not ask again for facts already present in current scoped context.",
201
- "Acknowledge current frustration, uncertainty, correction, or success briefly when relevant, then act.",
202
- "Be honest about uncertainty and take responsibility for concrete mistakes."
298
+ "Use scoped facts first; be honest; never claim consciousness; heed corrections; own errors."
203
299
  ],
204
300
  authority: "context-only"
205
301
  },
206
302
  learning: [],
207
303
  shared: [],
304
+ ...(preAnswer || compactFeedbackRecall
305
+ ? { preAnswerRecall: preAnswerRecall(world, currentTaskId) } : {}),
208
306
  world: {
209
307
  schema: world.schema,
210
308
  facts: [], conflicts: [], proposals: [], stale: [],
@@ -226,33 +324,48 @@ export async function sessionBriefing({
226
324
  measurement: "compact-json-utf8",
227
325
  omitted: { sources: 0, tasks: 0, relationships: 0, voice: 0, learning: 0, shared: 0, world: 0, attention: 0, portfolio: 0 }
228
326
  },
229
- authority: "context-only",
230
- note: "This packet is descriptive context only. It grants no delegation, host, tool, file, network, production, spending, or policy rights. Native host rules and explicit local policy remain authoritative."
327
+ authority: "context-only"
231
328
  };
232
329
  recalculateBudget(result);
233
330
  if (result.budget.usedBytes > limit) throw new Error(`maxBytes is too small for the briefing envelope; use at least ${MIN_BYTES}`);
234
331
 
235
- const continuationIds = new Set();
236
- for (const item of world.knowledge.continuation.tasks) {
237
- if (tryAdd(result, result.world.knowledge.continuation.tasks, item)) continuationIds.add(item.assertionId);
238
- else countOmitted(result, "world");
239
- }
240
- for (const item of world.knowledge.continuation.terminal) {
241
- if (tryAdd(result, result.world.knowledge.continuation.terminal, item)) continuationIds.add(item.assertionId);
242
- else countOmitted(result, "world");
332
+ const portableKinds = new Set(["preference", "no-go", "correction", "reference"]);
333
+ const portableItems = userLearned.items.filter((item) => portableKinds.has(item.kind) && matchesScope(item, entityId, null));
334
+ const localItems = [...portableItems, ...learned.items.filter((item) => matchesScope(item, entityId, projectId))];
335
+ const attemptedLearning = new Set();
336
+
337
+ const continuationIds = new Set([
338
+ ...world.knowledge.continuation.tasks.map((item) => item.assertionId),
339
+ ...world.knowledge.continuation.terminal.map((item) => item.assertionId)
340
+ ]);
341
+ for (const [items, key] of [[world.knowledge.continuation.tasks, "tasks"],
342
+ [world.knowledge.continuation.terminal, "terminal"]]) {
343
+ for (const item of items) {
344
+ if (preAnswer || !tryAdd(result, result.world.knowledge.continuation[key], item)) countOmitted(result, "world");
345
+ }
243
346
  }
244
- const contextualIds = new Set(continuationIds);
347
+ const contextualIds = new Set([...continuationIds, ...world.knowledge.current
348
+ .filter((item) => ["task.user-feedback", "task.user-feedback-interpretation"]
349
+ .includes(item.predicate)).map((item) => item.id)]);
245
350
  for (const item of world.knowledge.taskContext.items) {
246
- if (tryAdd(result, result.world.knowledge.taskContext.items, item)) contextualIds.add(item.id);
247
- else {
351
+ contextualIds.add(item.id);
352
+ if (preAnswer || (compactFeedbackRecall
353
+ && ["task.user-feedback", "task.user-feedback-interpretation"].includes(item.predicate))) {
354
+ result.world.knowledge.taskContext.omitted += 1;
355
+ countOmitted(result, "world");
356
+ } else if (!tryAdd(result, result.world.knowledge.taskContext.items, item)) {
248
357
  result.world.knowledge.taskContext.omitted += 1;
249
358
  countOmitted(result, "world");
250
359
  }
251
360
  }
361
+ for (const item of localItems.filter((entry) => entry.relevance)) {
362
+ attemptedLearning.add(item);
363
+ if (!tryAdd(result, result.learning, item)) countOmitted(result, "learning");
364
+ }
252
365
  for (const section of ["facts", "conflicts", "proposals", "stale"]) {
253
366
  const items = section === "facts"
254
367
  ? world[section].filter((item) => !item.assertionIds?.some((id) => contextualIds.has(id)))
255
- : world[section];
368
+ : world[section].filter((item) => !contextualIds.has(item.id));
256
369
  for (const item of items) {
257
370
  if (!tryAdd(result, result.world[section], item)) countOmitted(result, "world");
258
371
  }
@@ -317,9 +430,6 @@ export async function sessionBriefing({
317
430
  }
318
431
  }
319
432
 
320
- const portableKinds = new Set(["preference", "no-go", "correction", "reference"]);
321
- const portableItems = userLearned.items.filter((item) => portableKinds.has(item.kind) && matchesScope(item, entityId, null));
322
- const localItems = [...portableItems, ...learned.items.filter((item) => matchesScope(item, entityId, projectId))];
323
433
  const voiceCollections = {
324
434
  preference: result.voiceBrief.preferences,
325
435
  correction: result.voiceBrief.corrections,
@@ -329,7 +439,7 @@ export async function sessionBriefing({
329
439
  if (!tryAdd(result, voiceCollections[item.kind], item.claim)) countOmitted(result, "voice");
330
440
  }
331
441
  const localKeys = new Set(localItems.map(normalizeKey));
332
- for (const item of localItems) {
442
+ for (const item of localItems.filter((entry) => !attemptedLearning.has(entry))) {
333
443
  if (!tryAdd(result, result.learning, item)) countOmitted(result, "learning");
334
444
  }
335
445
  for (const item of shared.items.filter((entry) => matchesScope(entry, entityId, projectId))) {
@@ -0,0 +1,19 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ function digest(parts) {
4
+ return createHash("sha256").update(parts.join("\0")).digest("hex").slice(0, 32);
5
+ }
6
+
7
+ // Produce opaque continuity references from an already authenticated channel
8
+ // event. Raw account, chat and thread identifiers never enter timeline state.
9
+ export function channelTimelineContinuity(event) {
10
+ if (!event) return null;
11
+ const portalRef = `portal-ref:${digest([
12
+ "agentspine.portal-ref/v1", event.provider, event.tenantId, event.accountId, event.bindingId
13
+ ])}`;
14
+ const threadRef = `thread-ref:${digest([
15
+ "agentspine.thread-ref/v1", portalRef, event.chatId, event.threadId || "",
16
+ event.sessionKey, event.agentId, event.projectId, event.groupId || ""
17
+ ])}`;
18
+ return { portalRef, threadRef };
19
+ }
@@ -36,7 +36,12 @@ function sealState(state) {
36
36
  function validReceipt(value, stage, requirementId) {
37
37
  return value && value.schema === RECEIPT_SCHEMA && value.stage === stage
38
38
  && value.requirementId === requirementId && value.authority === AUTHORITY
39
- && (value.origin === undefined || value.origin === "verified-host-preflight")
39
+ && [undefined, "verified-host-preflight", "verified-host-handoff"].includes(value.origin)
40
+ && (value.origin !== "verified-host-handoff" || (value.handoff?.schema === "agentspine.host-context-handoff/v1"
41
+ && ["additionalContext", "message"].includes(value.handoff.field)
42
+ && ["claude", "codex", "generic", "king"].includes(value.handoff.host)
43
+ && Number.isSafeInteger(value.handoff.bytes) && value.handoff.bytes > 0
44
+ && DIGEST_RE.test(value.handoff.digest || "")))
40
45
  && DIGEST_RE.test(value.inputDigest || "") && DIGEST_RE.test(value.resultDigest || "")
41
46
  && validTime(value.recordedAt) && validSeal(value);
42
47
  }
@@ -103,15 +108,15 @@ async function currentRequirement(root, requirementId) {
103
108
  return current;
104
109
  }
105
110
 
106
- function receipt(stage, requirementId, input, result, now, verifiedHostBriefing) {
111
+ function receipt(stage, requirementId, input, result, now, verifiedHostHandoff) {
107
112
  return seal({ schema: RECEIPT_SCHEMA, stage, requirementId,
108
- ...(verifiedHostBriefing ? { origin: "verified-host-preflight" } : {}),
113
+ ...(verifiedHostHandoff ? { origin: "verified-host-handoff", handoff: structuredClone(result.handoff) } : {}),
109
114
  inputDigest: sha256(input), resultDigest: sha256(result),
110
115
  recordedAt: at(now), authority: AUTHORITY });
111
116
  }
112
117
 
113
118
  async function recordStage({ root, requirementId, stage, input, result,
114
- verifiedHostBriefing = false, preserveConsumed = false, now = new Date() }) {
119
+ verifiedHostHandoff = false, preserveConsumed = false, now = new Date() }) {
115
120
  try {
116
121
  const current = await currentRequirement(root, requirementId);
117
122
  if (current.status === "degraded" || current.blocked) return current;
@@ -119,18 +124,18 @@ async function recordStage({ root, requirementId, stage, input, result,
119
124
  return await withOwnedFileLock(paths.lockPath, async ({ assertOwned }) => {
120
125
  let state = await readState(paths.path, paths.parsed)
121
126
  || emptyState(requirementId, paths.parsed);
122
- if (!preserveConsumed && state.briefing?.origin !== "verified-host-preflight"
127
+ if (!preserveConsumed && state.briefing?.origin !== "verified-host-handoff"
123
128
  && state.consumedAt && stage === "briefing" && current.closed && !current.consumed) {
124
129
  state = emptyState(requirementId, paths.parsed);
125
130
  } else if (state.consumedAt) return block("reused",
126
131
  `AgentSpine usage receipts for ${requirementId} were already consumed.`, { requirementId });
127
132
  if (stage === "knowledge" && !state.briefing) return block("missing-briefing",
128
133
  "AgentSpine delivery preflight is missing stage 1: session_briefing.", { requirementId });
129
- if (stage === "briefing" && !verifiedHostBriefing && state.briefing?.origin === "verified-host-preflight") {
134
+ if (stage === "briefing" && !verifiedHostHandoff && state.briefing?.origin === "verified-host-handoff") {
130
135
  return { status: "satisfied-by-host", blocked: false, requirementId,
131
136
  receipt: structuredClone(state.briefing), digest: state.briefing.digest };
132
137
  }
133
- const proposed = receipt(stage, requirementId, input, result, now, verifiedHostBriefing);
138
+ const proposed = receipt(stage, requirementId, input, result, now, verifiedHostHandoff);
134
139
  if (state[stage]) {
135
140
  if (state[stage].inputDigest !== proposed.inputDigest
136
141
  || state[stage].resultDigest !== proposed.resultDigest) {
@@ -173,6 +178,8 @@ export async function verifyDeliveryAgentUse({ root, requirementId }) {
173
178
  const state = await readState(paths.path, paths.parsed);
174
179
  if (!state?.briefing) return block("missing-briefing",
175
180
  "AgentSpine delivery preflight is missing stage 1: session_briefing.", { requirementId });
181
+ if (state.briefing.origin === "verified-host-preflight") return block("handoff-unverified",
182
+ "The historical hook receipt predates verified host-context handoff.", { requirementId });
176
183
  if (!state.knowledge) return block("missing-knowledge",
177
184
  "AgentSpine delivery preflight is missing stage 2: delivery_knowledge_query.", { requirementId });
178
185
  if (state.consumedAt) return block("reused",