@aitne/daemon 0.1.9 → 0.1.11

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 (333) hide show
  1. package/dist/adapters/adapter-watchdog.d.ts +70 -0
  2. package/dist/adapters/adapter-watchdog.js +115 -0
  3. package/dist/adapters/discord.d.ts +17 -1
  4. package/dist/adapters/discord.js +33 -0
  5. package/dist/adapters/notification-manager.d.ts +27 -1
  6. package/dist/adapters/notification-manager.js +54 -39
  7. package/dist/adapters/slack-adapter.d.ts +26 -1
  8. package/dist/adapters/slack-adapter.js +41 -0
  9. package/dist/adapters/telegram-adapter.d.ts +18 -1
  10. package/dist/adapters/telegram-adapter.js +41 -2
  11. package/dist/adapters/types.d.ts +20 -0
  12. package/dist/adapters/whatsapp-adapter.d.ts +26 -7
  13. package/dist/adapters/whatsapp-adapter.js +74 -21
  14. package/dist/api/env-writer.d.ts +1 -0
  15. package/dist/api/env-writer.js +17 -7
  16. package/dist/api/helpers/agent-errors-registry.d.ts +5 -5
  17. package/dist/api/helpers/agent-errors-registry.js +5 -5
  18. package/dist/api/routes/agent-schedule.js +5 -1
  19. package/dist/api/routes/agent.js +33 -12
  20. package/dist/api/routes/agents/index.js +75 -16
  21. package/dist/api/routes/agents/views.d.ts +37 -2
  22. package/dist/api/routes/agents/views.js +64 -2
  23. package/dist/api/routes/apple-calendar.js +4 -1
  24. package/dist/api/routes/background-task.d.ts +22 -0
  25. package/dist/api/routes/background-task.js +338 -0
  26. package/dist/api/routes/browser-history.js +9 -1
  27. package/dist/api/routes/calendar.js +12 -2
  28. package/dist/api/routes/context/path-resolve.js +6 -1
  29. package/dist/api/routes/context/permissions.js +12 -2
  30. package/dist/api/routes/context/snapshots.js +0 -3
  31. package/dist/api/routes/context/write.js +3 -17
  32. package/dist/api/routes/dashboard/config.js +58 -12
  33. package/dist/api/routes/dashboard/cost-approvals.js +66 -0
  34. package/dist/api/routes/dashboard/notifications.js +9 -9
  35. package/dist/api/routes/dashboard/oauth-google.js +5 -3
  36. package/dist/api/routes/feedback.d.ts +3 -0
  37. package/dist/api/routes/feedback.js +349 -0
  38. package/dist/api/routes/git.js +10 -3
  39. package/dist/api/routes/github.js +5 -1
  40. package/dist/api/routes/integrations/crud-patch.js +5 -1
  41. package/dist/api/routes/integrations-reconcile.js +2 -2
  42. package/dist/api/routes/mcp.js +65 -13
  43. package/dist/api/routes/notion.d.ts +1 -1
  44. package/dist/api/routes/observations.js +7 -7
  45. package/dist/api/routes/obsidian.d.ts +1 -1
  46. package/dist/api/routes/receipts.js +5 -1
  47. package/dist/api/routes/setup-migrate.js +1 -1
  48. package/dist/api/routes/setup.js +1 -1
  49. package/dist/api/routes/task-flows.d.ts +1 -1
  50. package/dist/api/routes/task-flows.js +1 -1
  51. package/dist/api/routes/tuning.d.ts +29 -0
  52. package/dist/api/routes/tuning.js +304 -0
  53. package/dist/api/server.d.ts +44 -16
  54. package/dist/api/server.js +12 -0
  55. package/dist/bootstrap/adapters.d.ts +19 -0
  56. package/dist/bootstrap/adapters.js +61 -0
  57. package/dist/bootstrap/api.d.ts +5 -3
  58. package/dist/bootstrap/api.js +45 -13
  59. package/dist/bootstrap/catchup.d.ts +1 -1
  60. package/dist/bootstrap/catchup.js +11 -11
  61. package/dist/bootstrap/event-pipeline.d.ts +11 -0
  62. package/dist/bootstrap/event-pipeline.js +246 -8
  63. package/dist/bootstrap/observers.js +9 -6
  64. package/dist/bootstrap/schedule-helpers.d.ts +104 -6
  65. package/dist/bootstrap/schedule-helpers.js +172 -19
  66. package/dist/config.js +32 -12
  67. package/dist/core/agent-core.d.ts +33 -1
  68. package/dist/core/agent-core.js +36 -1
  69. package/dist/core/agents/activity-scan-cadence.d.ts +103 -0
  70. package/dist/core/agents/activity-scan-cadence.js +127 -0
  71. package/dist/core/agents/agent-route-override.d.ts +53 -0
  72. package/dist/core/agents/agent-route-override.js +69 -0
  73. package/dist/core/agents/builtin-registry.d.ts +51 -14
  74. package/dist/core/agents/builtin-registry.js +92 -15
  75. package/dist/core/agents/config-gate-reconcile.d.ts +38 -0
  76. package/dist/core/agents/config-gate-reconcile.js +51 -0
  77. package/dist/core/agents/cron-substitute.d.ts +1 -1
  78. package/dist/core/agents/cron-substitute.js +1 -1
  79. package/dist/core/agents/custom-routine-migration.d.ts +60 -0
  80. package/dist/core/agents/custom-routine-migration.js +149 -0
  81. package/dist/core/agents/firing-blocked.d.ts +1 -1
  82. package/dist/core/agents/hourly-cadence.d.ts +102 -0
  83. package/dist/core/agents/hourly-cadence.js +126 -0
  84. package/dist/core/agents/loader-boot.js +23 -0
  85. package/dist/core/agents/loader.d.ts +19 -0
  86. package/dist/core/agents/loader.js +34 -2
  87. package/dist/core/agents/override-merge.d.ts +1 -1
  88. package/dist/core/agents/override-merge.js +9 -1
  89. package/dist/core/agents/recurrence-convert.d.ts +1 -1
  90. package/dist/core/agents/recurrence-convert.js +1 -1
  91. package/dist/core/agents/recurring-schedule-adapter.js +8 -0
  92. package/dist/core/alerts.js +6 -6
  93. package/dist/core/backends/auth-health-monitor.d.ts +2 -2
  94. package/dist/core/backends/auth-health-monitor.js +1 -1
  95. package/dist/core/backends/backend-router.d.ts +27 -1
  96. package/dist/core/backends/backend-router.js +165 -1
  97. package/dist/core/backends/claude-code-core.d.ts +71 -31
  98. package/dist/core/backends/claude-code-core.js +282 -54
  99. package/dist/core/backends/cli-quota-guards.d.ts +29 -1
  100. package/dist/core/backends/cli-quota-guards.js +40 -5
  101. package/dist/core/backends/codex-core.d.ts +6 -0
  102. package/dist/core/backends/codex-core.js +22 -6
  103. package/dist/core/backends/failure-spend.d.ts +58 -0
  104. package/dist/core/backends/failure-spend.js +137 -0
  105. package/dist/core/backends/gemini-cli-core.d.ts +6 -0
  106. package/dist/core/backends/gemini-cli-core.js +38 -6
  107. package/dist/core/backends/model-registry.d.ts +1 -1
  108. package/dist/core/backends/model-registry.js +4 -4
  109. package/dist/core/backends/opencode-core.d.ts +1 -1
  110. package/dist/core/backends/opencode-core.js +5 -5
  111. package/dist/core/backends/plan-presets.js +47 -18
  112. package/dist/core/bang-commands/commands-cost.js +3 -1
  113. package/dist/core/bang-commands/commands-report.js +4 -3
  114. package/dist/core/bang-commands/commands-research.js +4 -1
  115. package/dist/core/bang-commands/commands-revert-tuning.d.ts +18 -0
  116. package/dist/core/bang-commands/commands-revert-tuning.js +63 -0
  117. package/dist/core/bang-commands/commands-stop-start.js +3 -3
  118. package/dist/core/bang-commands/commands-task-control.d.ts +19 -0
  119. package/dist/core/bang-commands/commands-task-control.js +147 -0
  120. package/dist/core/bang-commands/commands-wiki.js +5 -5
  121. package/dist/core/bang-commands/index.d.ts +2 -0
  122. package/dist/core/bang-commands/index.js +12 -0
  123. package/dist/core/bang-commands/registry.d.ts +12 -0
  124. package/dist/core/browser-history/research-cluster-fanout.d.ts +28 -14
  125. package/dist/core/browser-history/research-cluster-fanout.js +39 -16
  126. package/dist/core/channel-timeline.d.ts +5 -1
  127. package/dist/core/channel-timeline.js +13 -0
  128. package/dist/core/context/index-reconciler.js +5 -2
  129. package/dist/core/context/policy-index-reconciler.d.ts +6 -4
  130. package/dist/core/context/policy-index-runner.js +25 -6
  131. package/dist/core/context-builder-calendar.js +10 -2
  132. package/dist/core/context-builder-conversation.d.ts +8 -1
  133. package/dist/core/context-builder-conversation.js +41 -7
  134. package/dist/core/context-builder-yesterday.js +4 -3
  135. package/dist/core/context-builder.d.ts +7 -2
  136. package/dist/core/context-builder.js +193 -5
  137. package/dist/core/context-file-serializer.d.ts +1 -1
  138. package/dist/core/context-file-serializer.js +1 -1
  139. package/dist/core/context-health.js +2 -2
  140. package/dist/core/context-paths.d.ts +11 -1
  141. package/dist/core/context-paths.js +17 -1
  142. package/dist/core/context-validation/prepare-write.js +1 -1
  143. package/dist/core/context-validation/routine-rulebook.d.ts +1 -1
  144. package/dist/core/context-vault-aliases.d.ts +0 -13
  145. package/dist/core/context-vault-aliases.js +37 -0
  146. package/dist/core/custom-routines.d.ts +99 -0
  147. package/dist/core/custom-routines.js +187 -0
  148. package/dist/core/daemon-api-cli.js +50 -1
  149. package/dist/core/day-boundary.d.ts +46 -0
  150. package/dist/core/day-boundary.js +40 -0
  151. package/dist/core/dispatcher-activity-scan.d.ts +221 -0
  152. package/dist/core/dispatcher-activity-scan.js +775 -0
  153. package/dist/core/dispatcher-error-handling.d.ts +6 -11
  154. package/dist/core/dispatcher-error-handling.js +38 -62
  155. package/dist/core/dispatcher-hourly-check.js +6 -1
  156. package/dist/core/dispatcher-message-handler.d.ts +10 -0
  157. package/dist/core/dispatcher-message-handler.js +24 -0
  158. package/dist/core/dispatcher-morning-routine.d.ts +6 -6
  159. package/dist/core/dispatcher-morning-routine.js +13 -13
  160. package/dist/core/dispatcher-result-processor.d.ts +33 -0
  161. package/dist/core/dispatcher-result-processor.js +167 -11
  162. package/dist/core/dispatcher-scheduled-background-task.d.ts +42 -0
  163. package/dist/core/dispatcher-scheduled-background-task.js +89 -0
  164. package/dist/core/dispatcher-scheduled-tasks.d.ts +104 -1
  165. package/dist/core/dispatcher-scheduled-tasks.js +480 -8
  166. package/dist/core/dispatcher-task-delivery.d.ts +105 -0
  167. package/dist/core/dispatcher-task-delivery.js +555 -0
  168. package/dist/core/dispatcher-types.d.ts +48 -9
  169. package/dist/core/dispatcher-types.js +3 -3
  170. package/dist/core/dispatcher.d.ts +112 -31
  171. package/dist/core/dispatcher.js +297 -60
  172. package/dist/core/dm-freshness-metrics.d.ts +1 -1
  173. package/dist/core/drift-effects.js +2 -2
  174. package/dist/core/feedback/consolidation-prep.d.ts +94 -0
  175. package/dist/core/feedback/consolidation-prep.js +254 -0
  176. package/dist/core/feedback/eviction-scorer.d.ts +81 -0
  177. package/dist/core/feedback/eviction-scorer.js +136 -0
  178. package/dist/core/feedback/lesson-format.d.ts +79 -0
  179. package/dist/core/feedback/lesson-format.js +199 -0
  180. package/dist/core/feedback/lesson-injection.d.ts +98 -0
  181. package/dist/core/feedback/lesson-injection.js +174 -0
  182. package/dist/core/feedback/lesson-merge.d.ts +51 -0
  183. package/dist/core/feedback/lesson-merge.js +88 -0
  184. package/dist/core/feedback/lesson-store-overview.d.ts +46 -0
  185. package/dist/core/feedback/lesson-store-overview.js +42 -0
  186. package/dist/core/feedback/promotion-gate.d.ts +69 -0
  187. package/dist/core/feedback/promotion-gate.js +117 -0
  188. package/dist/core/feedback/regeneralization-prep.d.ts +87 -0
  189. package/dist/core/feedback/regeneralization-prep.js +152 -0
  190. package/dist/core/feedback/scope-parser.d.ts +86 -0
  191. package/dist/core/feedback/scope-parser.js +141 -0
  192. package/dist/core/feedback/self-performance-prep.d.ts +186 -0
  193. package/dist/core/feedback/self-performance-prep.js +541 -0
  194. package/dist/core/feedback/tuning-actuator.d.ts +198 -0
  195. package/dist/core/feedback/tuning-actuator.js +432 -0
  196. package/dist/core/feedback/tuning-recommender.d.ts +247 -0
  197. package/dist/core/feedback/tuning-recommender.js +580 -0
  198. package/dist/core/feedback/tuning-revert-monitor.d.ts +90 -0
  199. package/dist/core/feedback/tuning-revert-monitor.js +213 -0
  200. package/dist/core/health-monitor.d.ts +6 -0
  201. package/dist/core/health-monitor.js +1 -1
  202. package/dist/core/injection-policy.d.ts +83 -1
  203. package/dist/core/injection-policy.js +61 -3
  204. package/dist/core/integration-main-backend.js +4 -0
  205. package/dist/core/management-md.d.ts +2 -2
  206. package/dist/core/management-md.js +51 -13
  207. package/dist/core/morning/orchestrator.d.ts +2 -2
  208. package/dist/core/morning/orchestrator.js +2 -2
  209. package/dist/core/notification-gate.d.ts +64 -0
  210. package/dist/core/notification-gate.js +51 -0
  211. package/dist/core/notification-rate-limit.d.ts +40 -0
  212. package/dist/core/notification-rate-limit.js +50 -0
  213. package/dist/core/policy-files.d.ts +1 -1
  214. package/dist/core/policy-files.js +2 -2
  215. package/dist/core/pre-pass-freshness.d.ts +4 -4
  216. package/dist/core/retention.d.ts +5 -0
  217. package/dist/core/retention.js +20 -4
  218. package/dist/core/review-context.d.ts +1 -1
  219. package/dist/core/review-context.js +10 -5
  220. package/dist/core/roadmap-write-lock.d.ts +2 -1
  221. package/dist/core/roadmap-write-lock.js +15 -10
  222. package/dist/core/routine-acquisition-plan.d.ts +47 -1
  223. package/dist/core/routine-acquisition-plan.js +78 -20
  224. package/dist/core/routine-fetch-window-retry.js +7 -4
  225. package/dist/core/routine-fetch-window-runner.d.ts +39 -3
  226. package/dist/core/routine-fetch-window-runner.js +264 -13
  227. package/dist/core/routine-windows.d.ts +2 -2
  228. package/dist/core/routine-windows.js +8 -5
  229. package/dist/core/scheduler.d.ts +175 -16
  230. package/dist/core/scheduler.js +559 -102
  231. package/dist/core/signal-detector.d.ts +51 -1
  232. package/dist/core/signal-detector.js +321 -24
  233. package/dist/core/skills-compiler-denied-tools.js +2 -2
  234. package/dist/core/skills-compiler-skill-index.d.ts +2 -2
  235. package/dist/core/skills-compiler-skill-index.js +2 -2
  236. package/dist/core/skills-compiler-variants.d.ts +1 -1
  237. package/dist/core/skills-compiler-variants.js +8 -0
  238. package/dist/core/skills-compiler.d.ts +29 -26
  239. package/dist/core/skills-compiler.js +117 -81
  240. package/dist/core/skills-manifest.d.ts +37 -0
  241. package/dist/core/skills-manifest.js +73 -2
  242. package/dist/core/sleep-inhibitor.d.ts +79 -0
  243. package/dist/core/sleep-inhibitor.js +132 -0
  244. package/dist/core/slim-system-prompt-loader.d.ts +77 -0
  245. package/dist/core/slim-system-prompt-loader.js +141 -0
  246. package/dist/core/spawn-gates.d.ts +126 -0
  247. package/dist/core/spawn-gates.js +180 -0
  248. package/dist/core/today-direct-writer.d.ts +60 -14
  249. package/dist/core/today-direct-writer.js +90 -13
  250. package/dist/core/today-write-lock.d.ts +4 -2
  251. package/dist/core/today-write-lock.js +30 -20
  252. package/dist/core/wake-detector.d.ts +55 -0
  253. package/dist/core/wake-detector.js +80 -0
  254. package/dist/core/wiki/compile-lock.d.ts +1 -1
  255. package/dist/core/wiki/compile-lock.js +1 -1
  256. package/dist/core/wiki/wiki-fts.js +13 -6
  257. package/dist/core/workdir.js +15 -6
  258. package/dist/db/activity-scan-signals.d.ts +77 -0
  259. package/dist/db/activity-scan-signals.js +378 -0
  260. package/dist/db/agents-store.d.ts +28 -0
  261. package/dist/db/agents-store.js +62 -0
  262. package/dist/db/background-task-clarifications-store.d.ts +81 -0
  263. package/dist/db/background-task-clarifications-store.js +152 -0
  264. package/dist/db/background-task-store.d.ts +207 -0
  265. package/dist/db/background-task-store.js +380 -0
  266. package/dist/db/browser-history-store.d.ts +39 -6
  267. package/dist/db/browser-history-store.js +51 -7
  268. package/dist/db/browser-task-clarifications-store.d.ts +12 -0
  269. package/dist/db/browser-task-clarifications-store.js +35 -5
  270. package/dist/db/browser-task-store.d.ts +3 -0
  271. package/dist/db/browser-task-store.js +29 -4
  272. package/dist/db/deferred-dm.d.ts +86 -0
  273. package/dist/db/deferred-dm.js +199 -0
  274. package/dist/db/feedback-signals-store.d.ts +77 -0
  275. package/dist/db/feedback-signals-store.js +144 -0
  276. package/dist/db/migrations.js +380 -0
  277. package/dist/db/observations.d.ts +2 -2
  278. package/dist/db/observations.js +3 -3
  279. package/dist/db/schema.js +260 -22
  280. package/dist/db/voice-transcripts-store.d.ts +1 -1
  281. package/dist/index.js +86 -29
  282. package/dist/messaging/browser-task-mcp-notifier.d.ts +12 -70
  283. package/dist/messaging/browser-task-mcp-notifier.js +30 -151
  284. package/dist/messaging/browser-task-screenshot-attachment.d.ts +15 -0
  285. package/dist/messaging/browser-task-screenshot-attachment.js +63 -0
  286. package/dist/observers/delegated-sync-worker.d.ts +6 -6
  287. package/dist/observers/delegated-sync-worker.js +10 -10
  288. package/dist/observers/git-delegated-cron.d.ts +1 -1
  289. package/dist/observers/git-delegated-cron.js +2 -2
  290. package/dist/observers/github-poller-classifier.d.ts +3 -3
  291. package/dist/observers/github-poller-classifier.js +3 -3
  292. package/dist/observers/imminent-event-scheduler.d.ts +1 -1
  293. package/dist/observers/imminent-event-scheduler.js +1 -1
  294. package/dist/observers/mail-poller.d.ts +1 -0
  295. package/dist/observers/mail-poller.js +42 -3
  296. package/dist/observers/observation-summarizer/summarizer-client.d.ts +2 -2
  297. package/dist/observers/observation-summarizer/summarizer-client.js +2 -2
  298. package/dist/observers/observation-summarizer/worker.d.ts +2 -2
  299. package/dist/observers/observation-summarizer/worker.js +4 -4
  300. package/dist/observers/obsidian-watcher.d.ts +1 -1
  301. package/dist/observers/obsidian-watcher.js +1 -1
  302. package/dist/safety/agent-write-tracker.d.ts +4 -4
  303. package/dist/safety/agent-write-tracker.js +4 -4
  304. package/dist/safety/always-disallowed.d.ts +1 -1
  305. package/dist/safety/always-disallowed.js +39 -0
  306. package/dist/safety/audit.d.ts +43 -5
  307. package/dist/safety/audit.js +86 -18
  308. package/dist/safety/risk-classifier.d.ts +6 -0
  309. package/dist/safety/risk-classifier.js +97 -18
  310. package/dist/scheduler/activity-scan-gate.d.ts +86 -0
  311. package/dist/scheduler/activity-scan-gate.js +132 -0
  312. package/dist/services/background-task/background-task-budget.d.ts +80 -0
  313. package/dist/services/background-task/background-task-budget.js +91 -0
  314. package/dist/services/background-task/background-task-driver.d.ts +105 -0
  315. package/dist/services/background-task/background-task-driver.js +416 -0
  316. package/dist/services/background-task/background-task-runner.d.ts +96 -0
  317. package/dist/services/background-task/background-task-runner.js +673 -0
  318. package/dist/services/background-task/background-task-tools.d.ts +84 -0
  319. package/dist/services/background-task/background-task-tools.js +247 -0
  320. package/dist/services/background-task/background-task-transition-events.d.ts +43 -0
  321. package/dist/services/background-task/background-task-transition-events.js +54 -0
  322. package/dist/services/browser-history/automation/egress-denylist.d.ts +1 -1
  323. package/dist/services/browser-history/automation/egress-denylist.js +34 -8
  324. package/dist/services/browser-history/lifecycle/platform.js +44 -2
  325. package/dist/services/browser-history/managed-chromium/sandbox-launcher.js +0 -1
  326. package/dist/services/browser-task/browser-task-runner.js +53 -8
  327. package/dist/services/mcp/probe.js +30 -8
  328. package/dist/services/observations-batch.d.ts +1 -1
  329. package/dist/services/observations-batch.js +2 -2
  330. package/dist/settings/runtime-settings.d.ts +45 -12
  331. package/dist/settings/runtime-settings.js +215 -40
  332. package/dist/settings/settings-store.js +11 -3
  333. package/package.json +4 -4
@@ -0,0 +1,86 @@
1
+ /**
2
+ * Feedback Learning Loop — scope grammar (FEEDBACK_LEARNING_LOOP_DESIGN.md §3.3).
3
+ *
4
+ * A feedback signal / lesson carries a **scope** that decides *who sees it*.
5
+ * This module is the single source of truth that maps the DB row's
6
+ * `(scope_type, scope_ref)` pair onto:
7
+ * - a canonical, human-readable scope string (`user`, `agent`,
8
+ * `agent:report-writer`, `channel:slack`, …) used in worksheet XML and
9
+ * lesson-file headers, and
10
+ * - the writable vault file that stores that scope's lessons.
11
+ *
12
+ * Pure logic, no I/O — the §4 division-of-labour "scope parser" covered module.
13
+ * Phase 2 only *stores* `user` + `agent`; the parser still recognises the full
14
+ * v2 grammar (`agent_slug`, `channel`, `task`, `integration`) so forward-compat
15
+ * rows round-trip rather than throwing, but `scopeStoreFile` returns `null` for
16
+ * the not-yet-stored classes — the caller treats that as "surface but do not
17
+ * persist a lesson file yet".
18
+ */
19
+ import type { FeedbackScopeType } from "../../db/feedback-signals-store.js";
20
+ /** Parsed, normalised scope. `agent_slug` collapses to `kind: "agent_slug"`. */
21
+ export type CanonicalScope = {
22
+ kind: "user";
23
+ } | {
24
+ kind: "agent";
25
+ } | {
26
+ kind: "agent_slug";
27
+ ref: string;
28
+ } | {
29
+ kind: "channel";
30
+ ref: string;
31
+ } | {
32
+ kind: "task";
33
+ ref: string;
34
+ } | {
35
+ kind: "integration";
36
+ ref: string;
37
+ };
38
+ /**
39
+ * Parse a `(scope_type, scope_ref)` pair into a {@link CanonicalScope}.
40
+ * Returns `null` when the type is unknown or a ref-required class is missing
41
+ * its ref — the caller drops such rows from the worksheet rather than guessing.
42
+ */
43
+ export declare function parseScope(scopeType: string, scopeRef: string | null | undefined): CanonicalScope | null;
44
+ /**
45
+ * Canonical human-readable scope label used in worksheet XML attributes and
46
+ * the `<!-- scope: … -->` lesson-file header. `agent:<slug>` is the literal
47
+ * answer to requirement #3 ("feedback on a generated agent's output").
48
+ */
49
+ export declare function formatScope(scope: CanonicalScope): string;
50
+ /**
51
+ * Stable grouping key for a scope — used by the consolidation pre-step to
52
+ * bucket unconsumed signals by `(scope_type, scope_ref)` (§4 step 1). Equal
53
+ * for two signals that target the same lesson destination.
54
+ */
55
+ export declare function scopeKey(scope: CanonicalScope): string;
56
+ /**
57
+ * Resolve the writable-vault relative path that stores a scope's lessons.
58
+ * - `user` → `identity/profile.md` (`## Learned Context` section)
59
+ * - `agent` → `policies/agent-lessons.md`
60
+ * - `agent:slug` → `policies/agents/<slug>/lessons.md`
61
+ * - everything else (v2 channel/task/integration) → `null` (not yet stored)
62
+ *
63
+ * The `agent:<slug>` ref is path-validated with {@link isSafeAgentSlug} before
64
+ * it is composed into a vault path — the same guard the inject side applies to
65
+ * `event.data.agentId` (`context-builder.ts`), so both consumers of a slug
66
+ * reject the same unsafe shapes (`agentLessonsPath` itself trusts a
67
+ * pre-validated slug). A path-unsafe ref yields `null` ("surface but do not
68
+ * persist"), so the consolidation worksheet never emits an unsafe `store=` for
69
+ * the LLM to PATCH. In practice the `/api/feedback` route + the behavioral
70
+ * sink only ever write a real `agents.id` ref, so this is pure defence-in-depth
71
+ * against a malformed / forged row.
72
+ */
73
+ export declare function scopeStoreFile(scope: CanonicalScope): string | null;
74
+ export declare function isSafeAgentSlug(value: string): boolean;
75
+ /**
76
+ * The markdown section a scope's lessons live under, for PATCH `section=`
77
+ * targeting. `user` folds into the existing `## Learned Context`; lesson
78
+ * stores use `## Lessons`.
79
+ */
80
+ export declare function scopeSectionSlug(scope: CanonicalScope): string;
81
+ /**
82
+ * True when a scope type needs a ref to be valid. Exposed for the route /
83
+ * worksheet validators that mirror the §3.5.2 "scope_ref present iff
84
+ * scope_type=agent_slug" rule across the extended grammar.
85
+ */
86
+ export declare function scopeNeedsRef(scopeType: FeedbackScopeType): boolean;
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Feedback Learning Loop — scope grammar (FEEDBACK_LEARNING_LOOP_DESIGN.md §3.3).
3
+ *
4
+ * A feedback signal / lesson carries a **scope** that decides *who sees it*.
5
+ * This module is the single source of truth that maps the DB row's
6
+ * `(scope_type, scope_ref)` pair onto:
7
+ * - a canonical, human-readable scope string (`user`, `agent`,
8
+ * `agent:report-writer`, `channel:slack`, …) used in worksheet XML and
9
+ * lesson-file headers, and
10
+ * - the writable vault file that stores that scope's lessons.
11
+ *
12
+ * Pure logic, no I/O — the §4 division-of-labour "scope parser" covered module.
13
+ * Phase 2 only *stores* `user` + `agent`; the parser still recognises the full
14
+ * v2 grammar (`agent_slug`, `channel`, `task`, `integration`) so forward-compat
15
+ * rows round-trip rather than throwing, but `scopeStoreFile` returns `null` for
16
+ * the not-yet-stored classes — the caller treats that as "surface but do not
17
+ * persist a lesson file yet".
18
+ */
19
+ import { agentLessonsPath, CONTEXT_RELATIVE_PATHS } from "../context-paths.js";
20
+ /** Scope classes that require a `scope_ref` to be meaningful. */
21
+ const REF_REQUIRED = new Set([
22
+ "agent_slug",
23
+ "channel",
24
+ "task",
25
+ "integration",
26
+ ]);
27
+ /**
28
+ * Parse a `(scope_type, scope_ref)` pair into a {@link CanonicalScope}.
29
+ * Returns `null` when the type is unknown or a ref-required class is missing
30
+ * its ref — the caller drops such rows from the worksheet rather than guessing.
31
+ */
32
+ export function parseScope(scopeType, scopeRef) {
33
+ const ref = typeof scopeRef === "string" ? scopeRef.trim() : "";
34
+ switch (scopeType) {
35
+ case "user":
36
+ return { kind: "user" };
37
+ case "agent":
38
+ return { kind: "agent" };
39
+ case "agent_slug":
40
+ return ref.length > 0 ? { kind: "agent_slug", ref } : null;
41
+ case "channel":
42
+ return ref.length > 0 ? { kind: "channel", ref } : null;
43
+ case "task":
44
+ return ref.length > 0 ? { kind: "task", ref } : null;
45
+ case "integration":
46
+ return ref.length > 0 ? { kind: "integration", ref } : null;
47
+ default:
48
+ return null;
49
+ }
50
+ }
51
+ /**
52
+ * Canonical human-readable scope label used in worksheet XML attributes and
53
+ * the `<!-- scope: … -->` lesson-file header. `agent:<slug>` is the literal
54
+ * answer to requirement #3 ("feedback on a generated agent's output").
55
+ */
56
+ export function formatScope(scope) {
57
+ switch (scope.kind) {
58
+ case "user":
59
+ return "user";
60
+ case "agent":
61
+ return "agent";
62
+ case "agent_slug":
63
+ return `agent:${scope.ref}`;
64
+ case "channel":
65
+ return `channel:${scope.ref}`;
66
+ case "task":
67
+ return `task:${scope.ref}`;
68
+ case "integration":
69
+ return `integration:${scope.ref}`;
70
+ }
71
+ }
72
+ /**
73
+ * Stable grouping key for a scope — used by the consolidation pre-step to
74
+ * bucket unconsumed signals by `(scope_type, scope_ref)` (§4 step 1). Equal
75
+ * for two signals that target the same lesson destination.
76
+ */
77
+ export function scopeKey(scope) {
78
+ return formatScope(scope);
79
+ }
80
+ /**
81
+ * Resolve the writable-vault relative path that stores a scope's lessons.
82
+ * - `user` → `identity/profile.md` (`## Learned Context` section)
83
+ * - `agent` → `policies/agent-lessons.md`
84
+ * - `agent:slug` → `policies/agents/<slug>/lessons.md`
85
+ * - everything else (v2 channel/task/integration) → `null` (not yet stored)
86
+ *
87
+ * The `agent:<slug>` ref is path-validated with {@link isSafeAgentSlug} before
88
+ * it is composed into a vault path — the same guard the inject side applies to
89
+ * `event.data.agentId` (`context-builder.ts`), so both consumers of a slug
90
+ * reject the same unsafe shapes (`agentLessonsPath` itself trusts a
91
+ * pre-validated slug). A path-unsafe ref yields `null` ("surface but do not
92
+ * persist"), so the consolidation worksheet never emits an unsafe `store=` for
93
+ * the LLM to PATCH. In practice the `/api/feedback` route + the behavioral
94
+ * sink only ever write a real `agents.id` ref, so this is pure defence-in-depth
95
+ * against a malformed / forged row.
96
+ */
97
+ export function scopeStoreFile(scope) {
98
+ switch (scope.kind) {
99
+ case "user":
100
+ return CONTEXT_RELATIVE_PATHS.user.profile;
101
+ case "agent":
102
+ return CONTEXT_RELATIVE_PATHS.agentLessons;
103
+ case "agent_slug":
104
+ return isSafeAgentSlug(scope.ref) ? agentLessonsPath(scope.ref) : null;
105
+ default:
106
+ return null;
107
+ }
108
+ }
109
+ /**
110
+ * Path-safety guard for an `agent:<slug>` ref before it is interpolated into a
111
+ * vault file path (`agentLessonsPath`). The Phase-4 inject path reads
112
+ * `event.data.agentId` — a `Record<string, unknown>` value set by the dispatch
113
+ * site from `resolveAgentId()` — and joins it under `policies/agents/`. Although
114
+ * `resolveAgentId` only ever returns DB-verified / built-in-registry slugs,
115
+ * defence-in-depth requires the consuming side validate the shape rather than
116
+ * trust the carrier: the slug must be a single safe segment (kebab-case-ish,
117
+ * the same `[a-z0-9._-]` alphabet `deriveSlug` and the context-write whitelist
118
+ * use), start alphanumeric (so `.`/`..` are rejected outright), and contain no
119
+ * `..` traversal or `/` separator. A failing value yields no self block rather
120
+ * than a path escape.
121
+ */
122
+ const SAFE_AGENT_SLUG_RE = /^[a-z0-9][a-z0-9._-]*$/;
123
+ export function isSafeAgentSlug(value) {
124
+ return SAFE_AGENT_SLUG_RE.test(value) && !value.includes("..");
125
+ }
126
+ /**
127
+ * The markdown section a scope's lessons live under, for PATCH `section=`
128
+ * targeting. `user` folds into the existing `## Learned Context`; lesson
129
+ * stores use `## Lessons`.
130
+ */
131
+ export function scopeSectionSlug(scope) {
132
+ return scope.kind === "user" ? "learned_context" : "lessons";
133
+ }
134
+ /**
135
+ * True when a scope type needs a ref to be valid. Exposed for the route /
136
+ * worksheet validators that mirror the §3.5.2 "scope_ref present iff
137
+ * scope_type=agent_slug" rule across the extended grammar.
138
+ */
139
+ export function scopeNeedsRef(scopeType) {
140
+ return REF_REQUIRED.has(scopeType);
141
+ }
@@ -0,0 +1,186 @@
1
+ /**
2
+ * Self-Tuning Review Cycle — Measure stage (SELF_TUNING_REVIEW_CYCLE_DESIGN.md
3
+ * §3.1, Phase 1).
4
+ *
5
+ * The daemon-side, deterministic Measure step ($0 — LLM tokens buy judgment
6
+ * only, P1). On the weekly-review dispatch it computes SQL aggregates over
7
+ * `agent_actions`, `notification_log`, and the `runtime_state` self-tuning
8
+ * ledger for a 7-day window plus a 7-day-prior baseline (trend column), and
9
+ * renders one compact `<self_performance>` block — hard-capped at
10
+ * {@link SELF_PERFORMANCE_MAX_BYTES} — so the weekly review's "Metrics (agent
11
+ * side)" section copies daemon-computed facts instead of paying Sonnet prices
12
+ * to re-count them.
13
+ *
14
+ * Two layers, mirroring `consolidation-prep.ts`:
15
+ * - {@link gatherSelfPerformanceData} — the single DB read (side-effect
16
+ * free): per-`action_type` run/cost/duration aggregates (`agent_actions`
17
+ * has no process_key column; `action_type` carries the routine identity),
18
+ * the `routine.fetch_window` empty-run rate per integration (from the
19
+ * fan-out audit rows' `detail.prePass` payload the runner persists), the
20
+ * `activity_scan.gate` stage distribution (from `buildGateAuditDetail`'s
21
+ * historical per-tick rows), per-notification-type `user_reaction`
22
+ * breakdowns (the first reader of the column `signal-detector.ts`
23
+ * populates), and the `runtime_state.self_tuning:*` ledger.
24
+ * - {@link buildSelfPerformanceBlock} — pure renderer. Deterministic
25
+ * byte-capped output: per-section row budgets shrink one row at a time
26
+ * (largest section first) until the block fits the cap, and clipped rows
27
+ * surface as `omitted="N"` so truncation is never silent.
28
+ *
29
+ * Phase 1 carries no actuator: nothing here writes config, schedules, or
30
+ * lessons. Later phases (Recommend / Judge / Actuate) consume the same data
31
+ * shape; {@link SELF_TUNING_LEDGER_PREFIX} is exported so the Phase 3
32
+ * actuator writes the ledger keys this module already reads.
33
+ */
34
+ import type Database from "better-sqlite3";
35
+ /** Measurement window length; the baseline is the same span immediately prior. */
36
+ export declare const SELF_PERFORMANCE_WINDOW_DAYS = 7;
37
+ /** §3.1 — hard cap on the rendered `<self_performance>` block, in UTF-8 bytes. */
38
+ export declare const SELF_PERFORMANCE_MAX_BYTES = 1500;
39
+ /**
40
+ * §3.4 ledger key prefix. Phase 3's actuator writes
41
+ * `runtime_state.self_tuning:<key> = {prev, applied_at, baselineMetric, rule}`;
42
+ * Phase 1 already reads (and renders) whatever sits under the prefix so the
43
+ * weekly review sees applied changes the cycle they land.
44
+ */
45
+ export declare const SELF_TUNING_LEDGER_PREFIX = "self_tuning:";
46
+ /** Fan-out audit rows carry the fetcher event's type as `action_type`. */
47
+ export declare const FETCH_WINDOW_ACTION_TYPE = "routine.fetch_window";
48
+ /** Per-tick gate audit rows (`buildGateAuditDetail` payload in `detail`). */
49
+ export declare const ACTIVITY_SCAN_GATE_ACTION_TYPE = "activity_scan.gate";
50
+ export interface ActionTypeStats {
51
+ actionType: string;
52
+ runs: number;
53
+ success: number;
54
+ partial: number;
55
+ failed: number;
56
+ skipped: number;
57
+ costUsd: number;
58
+ /** Median over rows with a non-null `duration_ms`; null when none have one. */
59
+ p50DurationMs: number | null;
60
+ }
61
+ export interface FetchWindowIntegrationStats {
62
+ integrationKey: string;
63
+ /** Completed fan-out attempts (prePass status success|partial). */
64
+ runs: number;
65
+ /** Completed attempts with `fetched=0 ∧ posted=0` (§3.1 empty-run def). */
66
+ empty: number;
67
+ }
68
+ export interface HourlyGateStats {
69
+ /** Every audited cron tick, including rows whose detail failed to parse. */
70
+ ticks: number;
71
+ stage0: number;
72
+ /**
73
+ * Lite-triage ticks that stayed silent. The writer persists the alias
74
+ * `stage2_log_only` verbatim (`dispatcher-activity-scan.ts:logGateAuditRow`
75
+ * overrides `stage_reached` with the applied decision, and a Stage-2 tick
76
+ * only ever settles to log_only-silent or stage3); a bare `stage2` is
77
+ * accepted defensively but never occurs in production rows.
78
+ */
79
+ stage2: number;
80
+ /**
81
+ * Full-session escalations that actually ran. Rows the legacy
82
+ * min-observations floor short-circuited (`result='skipped'` with
83
+ * `stage_reached='stage3'`) are excluded — no session ran, no spend.
84
+ */
85
+ stage3: number;
86
+ /**
87
+ * …of those, ticks whose `gate_reason` was the low-signal fallback (R3).
88
+ * Forced ticks (`!run` / run-now, `detail.forced=true`) are excluded:
89
+ * they escalate at any signal level and say nothing about the gate.
90
+ */
91
+ stage3LowSignal: number;
92
+ /** …of those, ticks whose snapshot max novelty was ≤ 1 (null counts as ≤1). */
93
+ stage3LowSignalLowNovelty: number;
94
+ }
95
+ export interface NotificationTypeStats {
96
+ notificationType: string;
97
+ /** Rows with status delivered|batched (suppressed/failed are not "sent"). */
98
+ sent: number;
99
+ replied: number;
100
+ acted: number;
101
+ corrected: number;
102
+ ignored: number;
103
+ /** No-reaction-yet (incl. unrecognised reaction values, clamped ≥ 0). */
104
+ pending: number;
105
+ }
106
+ export interface SelfPerformanceWindow {
107
+ actions: ActionTypeStats[];
108
+ fetchWindow: FetchWindowIntegrationStats[];
109
+ gate: HourlyGateStats;
110
+ notifications: NotificationTypeStats[];
111
+ }
112
+ export interface SelfTuningLedgerEntry {
113
+ /** Knob name — the runtime_state key with the prefix stripped. */
114
+ key: string;
115
+ prev: unknown;
116
+ appliedAt: string | null;
117
+ rule: string | null;
118
+ /**
119
+ * §3.4 — the rule's target metric captured at apply time, so the weekly
120
+ * review can compare it against the current `<self_performance>` numbers
121
+ * (the "measured effect" §3.1 asks the ledger section to carry). Absent
122
+ * until Phase 3's actuator writes it.
123
+ */
124
+ baselineMetric?: unknown;
125
+ /**
126
+ * §3.4 — stamped by the Phase 3 auto-revert monitor. Present means the
127
+ * change regressed and was rolled back; the Phase 2 recommender reads it
128
+ * to apply the extended 28-day cool-down (vs the normal 14-day
129
+ * hysteresis) so the apply→revert→re-apply cycle can't flap.
130
+ */
131
+ revertedAt?: string;
132
+ /**
133
+ * §3.4 — stamped by the auto-revert monitor after a clean 7-day verify
134
+ * window (`pass`, `no_baseline`, …). Rendered so the weekly judge can
135
+ * tell a verified-clean change from one still inside its window.
136
+ */
137
+ verifyResult?: string;
138
+ }
139
+ export interface SelfPerformanceData {
140
+ windowDays: number;
141
+ current: SelfPerformanceWindow;
142
+ baseline: SelfPerformanceWindow;
143
+ ledger: SelfTuningLedgerEntry[];
144
+ }
145
+ /** §3.5 — lesson-store byte pressure, the standing cost multiplier to watch. */
146
+ export interface LessonStoreUtilization {
147
+ /** Canonical scope label — `agent` or `agent:<slug>`. */
148
+ scope: string;
149
+ /** UTF-8 byte size of the `## Lessons` section body (the §6 cap unit). */
150
+ bytes: number;
151
+ capBytes: number;
152
+ entries: number;
153
+ /** Median `ev=` across all entries (R5's evidence signal); null when empty. */
154
+ medianEv: number | null;
155
+ }
156
+ /**
157
+ * The single DB read. Computes the current window `[now − windowDays, now)`
158
+ * and the baseline window `[now − 2·windowDays, now − windowDays)` over
159
+ * `agent_actions` / `notification_log` (both store SQLite UTC
160
+ * `YYYY-MM-DD HH:MM:SS` timestamps, so lexicographic comparison against
161
+ * `formatSqliteDatetime` cutoffs is exact), plus the self-tuning ledger.
162
+ */
163
+ export declare function gatherSelfPerformanceData(db: Database.Database, opts: {
164
+ now: Date;
165
+ windowDays?: number;
166
+ }): SelfPerformanceData;
167
+ /**
168
+ * §3.5 — summarise one lesson store's byte pressure from its raw file
169
+ * contents. Pure (the caller does the FS read); a file with no `## Lessons`
170
+ * section degrades to an empty store, never a throw. `medianEv` carries the
171
+ * evidence signal R5's Phase 2 rule keys on (utilization > 90% with median
172
+ * evidence ≤ 1), so the measurement lands one phase ahead of the rule.
173
+ */
174
+ export declare function summarizeLessonStoreUtilization(scope: string, fileMd: string, capBytes: number): LessonStoreUtilization;
175
+ /**
176
+ * Compose the `<self_performance>` block. Returns `null` when there is no
177
+ * telemetry at all (fresh install) so the caller stamps nothing — no empty
178
+ * block in the prompt. The byte cap is a hard guarantee: row budgets shrink
179
+ * until the block fits; in the (synthetic) case where even the skeleton
180
+ * exceeds the cap, a minimal self-closing element is emitted instead.
181
+ */
182
+ export declare function buildSelfPerformanceBlock(data: SelfPerformanceData, opts: {
183
+ generatedAt: string;
184
+ lessonStores?: ReadonlyArray<LessonStoreUtilization>;
185
+ maxBytes?: number;
186
+ }): string | null;