zora-agent 0.9.0

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 (303) hide show
  1. package/CHANGELOG.md +145 -0
  2. package/LICENSE +21 -0
  3. package/README.md +159 -0
  4. package/dist/cli/audit-commands.d.ts +8 -0
  5. package/dist/cli/audit-commands.d.ts.map +1 -0
  6. package/dist/cli/audit-commands.js +67 -0
  7. package/dist/cli/audit-commands.js.map +1 -0
  8. package/dist/cli/daemon.d.ts +9 -0
  9. package/dist/cli/daemon.d.ts.map +1 -0
  10. package/dist/cli/daemon.js +107 -0
  11. package/dist/cli/daemon.js.map +1 -0
  12. package/dist/cli/doctor.d.ts +21 -0
  13. package/dist/cli/doctor.d.ts.map +1 -0
  14. package/dist/cli/doctor.js +31 -0
  15. package/dist/cli/doctor.js.map +1 -0
  16. package/dist/cli/edit-commands.d.ts +8 -0
  17. package/dist/cli/edit-commands.d.ts.map +1 -0
  18. package/dist/cli/edit-commands.js +46 -0
  19. package/dist/cli/edit-commands.js.map +1 -0
  20. package/dist/cli/index.d.ts +11 -0
  21. package/dist/cli/index.d.ts.map +1 -0
  22. package/dist/cli/index.js +319 -0
  23. package/dist/cli/index.js.map +1 -0
  24. package/dist/cli/init-command.d.ts +30 -0
  25. package/dist/cli/init-command.d.ts.map +1 -0
  26. package/dist/cli/init-command.js +425 -0
  27. package/dist/cli/init-command.js.map +1 -0
  28. package/dist/cli/memory-commands.d.ts +11 -0
  29. package/dist/cli/memory-commands.d.ts.map +1 -0
  30. package/dist/cli/memory-commands.js +57 -0
  31. package/dist/cli/memory-commands.js.map +1 -0
  32. package/dist/cli/presets.d.ts +12 -0
  33. package/dist/cli/presets.d.ts.map +1 -0
  34. package/dist/cli/presets.js +169 -0
  35. package/dist/cli/presets.js.map +1 -0
  36. package/dist/cli/skill-commands.d.ts +10 -0
  37. package/dist/cli/skill-commands.d.ts.map +1 -0
  38. package/dist/cli/skill-commands.js +73 -0
  39. package/dist/cli/skill-commands.js.map +1 -0
  40. package/dist/cli/steer-commands.d.ts +10 -0
  41. package/dist/cli/steer-commands.d.ts.map +1 -0
  42. package/dist/cli/steer-commands.js +92 -0
  43. package/dist/cli/steer-commands.js.map +1 -0
  44. package/dist/cli/team-commands.d.ts +8 -0
  45. package/dist/cli/team-commands.d.ts.map +1 -0
  46. package/dist/cli/team-commands.js +93 -0
  47. package/dist/cli/team-commands.js.map +1 -0
  48. package/dist/config/defaults.d.ts +26 -0
  49. package/dist/config/defaults.d.ts.map +1 -0
  50. package/dist/config/defaults.js +173 -0
  51. package/dist/config/defaults.js.map +1 -0
  52. package/dist/config/index.d.ts +3 -0
  53. package/dist/config/index.d.ts.map +1 -0
  54. package/dist/config/index.js +3 -0
  55. package/dist/config/index.js.map +1 -0
  56. package/dist/config/loader.d.ts +30 -0
  57. package/dist/config/loader.d.ts.map +1 -0
  58. package/dist/config/loader.js +130 -0
  59. package/dist/config/loader.js.map +1 -0
  60. package/dist/config/policy-loader.d.ts +18 -0
  61. package/dist/config/policy-loader.d.ts.map +1 -0
  62. package/dist/config/policy-loader.js +72 -0
  63. package/dist/config/policy-loader.js.map +1 -0
  64. package/dist/dashboard/auth-middleware.d.ts +15 -0
  65. package/dist/dashboard/auth-middleware.d.ts.map +1 -0
  66. package/dist/dashboard/auth-middleware.js +44 -0
  67. package/dist/dashboard/auth-middleware.js.map +1 -0
  68. package/dist/dashboard/frontend/vite.config.d.ts +3 -0
  69. package/dist/dashboard/frontend/vite.config.d.ts.map +1 -0
  70. package/dist/dashboard/frontend/vite.config.js +11 -0
  71. package/dist/dashboard/frontend/vite.config.js.map +1 -0
  72. package/dist/dashboard/server.d.ts +55 -0
  73. package/dist/dashboard/server.d.ts.map +1 -0
  74. package/dist/dashboard/server.js +254 -0
  75. package/dist/dashboard/server.js.map +1 -0
  76. package/dist/index.d.ts +20 -0
  77. package/dist/index.d.ts.map +1 -0
  78. package/dist/index.js +19 -0
  79. package/dist/index.js.map +1 -0
  80. package/dist/memory/category-organizer.d.ts +33 -0
  81. package/dist/memory/category-organizer.d.ts.map +1 -0
  82. package/dist/memory/category-organizer.js +137 -0
  83. package/dist/memory/category-organizer.js.map +1 -0
  84. package/dist/memory/extraction-pipeline.d.ts +22 -0
  85. package/dist/memory/extraction-pipeline.d.ts.map +1 -0
  86. package/dist/memory/extraction-pipeline.js +156 -0
  87. package/dist/memory/extraction-pipeline.js.map +1 -0
  88. package/dist/memory/index.d.ts +7 -0
  89. package/dist/memory/index.d.ts.map +1 -0
  90. package/dist/memory/index.js +7 -0
  91. package/dist/memory/index.js.map +1 -0
  92. package/dist/memory/memory-manager.d.ts +56 -0
  93. package/dist/memory/memory-manager.d.ts.map +1 -0
  94. package/dist/memory/memory-manager.js +198 -0
  95. package/dist/memory/memory-manager.js.map +1 -0
  96. package/dist/memory/memory-types.d.ts +44 -0
  97. package/dist/memory/memory-types.d.ts.map +1 -0
  98. package/dist/memory/memory-types.js +8 -0
  99. package/dist/memory/memory-types.js.map +1 -0
  100. package/dist/memory/salience-scorer.d.ts +19 -0
  101. package/dist/memory/salience-scorer.d.ts.map +1 -0
  102. package/dist/memory/salience-scorer.js +72 -0
  103. package/dist/memory/salience-scorer.js.map +1 -0
  104. package/dist/memory/structured-memory.d.ts +28 -0
  105. package/dist/memory/structured-memory.d.ts.map +1 -0
  106. package/dist/memory/structured-memory.js +140 -0
  107. package/dist/memory/structured-memory.js.map +1 -0
  108. package/dist/orchestrator/auth-monitor.d.ts +28 -0
  109. package/dist/orchestrator/auth-monitor.d.ts.map +1 -0
  110. package/dist/orchestrator/auth-monitor.js +49 -0
  111. package/dist/orchestrator/auth-monitor.js.map +1 -0
  112. package/dist/orchestrator/execution-loop.d.ts +59 -0
  113. package/dist/orchestrator/execution-loop.d.ts.map +1 -0
  114. package/dist/orchestrator/execution-loop.js +94 -0
  115. package/dist/orchestrator/execution-loop.js.map +1 -0
  116. package/dist/orchestrator/failover-controller.d.ts +32 -0
  117. package/dist/orchestrator/failover-controller.d.ts.map +1 -0
  118. package/dist/orchestrator/failover-controller.js +111 -0
  119. package/dist/orchestrator/failover-controller.js.map +1 -0
  120. package/dist/orchestrator/index.d.ts +11 -0
  121. package/dist/orchestrator/index.d.ts.map +1 -0
  122. package/dist/orchestrator/index.js +11 -0
  123. package/dist/orchestrator/index.js.map +1 -0
  124. package/dist/orchestrator/orchestrator.d.ts +99 -0
  125. package/dist/orchestrator/orchestrator.d.ts.map +1 -0
  126. package/dist/orchestrator/orchestrator.js +456 -0
  127. package/dist/orchestrator/orchestrator.js.map +1 -0
  128. package/dist/orchestrator/retry-queue.d.ts +39 -0
  129. package/dist/orchestrator/retry-queue.d.ts.map +1 -0
  130. package/dist/orchestrator/retry-queue.js +99 -0
  131. package/dist/orchestrator/retry-queue.js.map +1 -0
  132. package/dist/orchestrator/router.d.ts +49 -0
  133. package/dist/orchestrator/router.d.ts.map +1 -0
  134. package/dist/orchestrator/router.js +167 -0
  135. package/dist/orchestrator/router.js.map +1 -0
  136. package/dist/orchestrator/session-manager.d.ts +39 -0
  137. package/dist/orchestrator/session-manager.d.ts.map +1 -0
  138. package/dist/orchestrator/session-manager.js +117 -0
  139. package/dist/orchestrator/session-manager.js.map +1 -0
  140. package/dist/providers/claude-provider.d.ts +182 -0
  141. package/dist/providers/claude-provider.d.ts.map +1 -0
  142. package/dist/providers/claude-provider.js +443 -0
  143. package/dist/providers/claude-provider.js.map +1 -0
  144. package/dist/providers/gemini-provider.d.ts +46 -0
  145. package/dist/providers/gemini-provider.d.ts.map +1 -0
  146. package/dist/providers/gemini-provider.js +336 -0
  147. package/dist/providers/gemini-provider.js.map +1 -0
  148. package/dist/providers/index.d.ts +10 -0
  149. package/dist/providers/index.d.ts.map +1 -0
  150. package/dist/providers/index.js +10 -0
  151. package/dist/providers/index.js.map +1 -0
  152. package/dist/providers/ollama-provider.d.ts +61 -0
  153. package/dist/providers/ollama-provider.d.ts.map +1 -0
  154. package/dist/providers/ollama-provider.js +319 -0
  155. package/dist/providers/ollama-provider.js.map +1 -0
  156. package/dist/routines/event-triggers.d.ts +34 -0
  157. package/dist/routines/event-triggers.d.ts.map +1 -0
  158. package/dist/routines/event-triggers.js +104 -0
  159. package/dist/routines/event-triggers.js.map +1 -0
  160. package/dist/routines/heartbeat.d.ts +35 -0
  161. package/dist/routines/heartbeat.d.ts.map +1 -0
  162. package/dist/routines/heartbeat.js +93 -0
  163. package/dist/routines/heartbeat.js.map +1 -0
  164. package/dist/routines/index.d.ts +7 -0
  165. package/dist/routines/index.d.ts.map +1 -0
  166. package/dist/routines/index.js +7 -0
  167. package/dist/routines/index.js.map +1 -0
  168. package/dist/routines/routine-manager.d.ts +62 -0
  169. package/dist/routines/routine-manager.d.ts.map +1 -0
  170. package/dist/routines/routine-manager.js +148 -0
  171. package/dist/routines/routine-manager.js.map +1 -0
  172. package/dist/security/audit-logger.d.ts +55 -0
  173. package/dist/security/audit-logger.d.ts.map +1 -0
  174. package/dist/security/audit-logger.js +252 -0
  175. package/dist/security/audit-logger.js.map +1 -0
  176. package/dist/security/capability-tokens.d.ts +30 -0
  177. package/dist/security/capability-tokens.d.ts.map +1 -0
  178. package/dist/security/capability-tokens.js +110 -0
  179. package/dist/security/capability-tokens.js.map +1 -0
  180. package/dist/security/index.d.ts +18 -0
  181. package/dist/security/index.d.ts.map +1 -0
  182. package/dist/security/index.js +12 -0
  183. package/dist/security/index.js.map +1 -0
  184. package/dist/security/integrity-guardian.d.ts +43 -0
  185. package/dist/security/integrity-guardian.d.ts.map +1 -0
  186. package/dist/security/integrity-guardian.js +103 -0
  187. package/dist/security/integrity-guardian.js.map +1 -0
  188. package/dist/security/intent-capsule.d.ts +52 -0
  189. package/dist/security/intent-capsule.d.ts.map +1 -0
  190. package/dist/security/intent-capsule.js +157 -0
  191. package/dist/security/intent-capsule.js.map +1 -0
  192. package/dist/security/leak-detector.d.ts +26 -0
  193. package/dist/security/leak-detector.d.ts.map +1 -0
  194. package/dist/security/leak-detector.js +75 -0
  195. package/dist/security/leak-detector.js.map +1 -0
  196. package/dist/security/policy-engine.d.ts +188 -0
  197. package/dist/security/policy-engine.d.ts.map +1 -0
  198. package/dist/security/policy-engine.js +799 -0
  199. package/dist/security/policy-engine.js.map +1 -0
  200. package/dist/security/prompt-defense.d.ts +30 -0
  201. package/dist/security/prompt-defense.d.ts.map +1 -0
  202. package/dist/security/prompt-defense.js +164 -0
  203. package/dist/security/prompt-defense.js.map +1 -0
  204. package/dist/security/secrets-manager.d.ts +47 -0
  205. package/dist/security/secrets-manager.d.ts.map +1 -0
  206. package/dist/security/secrets-manager.js +132 -0
  207. package/dist/security/secrets-manager.js.map +1 -0
  208. package/dist/security/security-types.d.ts +84 -0
  209. package/dist/security/security-types.d.ts.map +1 -0
  210. package/dist/security/security-types.js +8 -0
  211. package/dist/security/security-types.js.map +1 -0
  212. package/dist/skills/index.d.ts +5 -0
  213. package/dist/skills/index.d.ts.map +1 -0
  214. package/dist/skills/index.js +5 -0
  215. package/dist/skills/index.js.map +1 -0
  216. package/dist/skills/skill-loader.d.ts +25 -0
  217. package/dist/skills/skill-loader.d.ts.map +1 -0
  218. package/dist/skills/skill-loader.js +64 -0
  219. package/dist/skills/skill-loader.js.map +1 -0
  220. package/dist/steering/flag-manager.d.ts +52 -0
  221. package/dist/steering/flag-manager.d.ts.map +1 -0
  222. package/dist/steering/flag-manager.js +160 -0
  223. package/dist/steering/flag-manager.js.map +1 -0
  224. package/dist/steering/index.d.ts +8 -0
  225. package/dist/steering/index.d.ts.map +1 -0
  226. package/dist/steering/index.js +8 -0
  227. package/dist/steering/index.js.map +1 -0
  228. package/dist/steering/steer-injector.d.ts +15 -0
  229. package/dist/steering/steer-injector.d.ts.map +1 -0
  230. package/dist/steering/steer-injector.js +41 -0
  231. package/dist/steering/steer-injector.js.map +1 -0
  232. package/dist/steering/steering-manager.d.ts +33 -0
  233. package/dist/steering/steering-manager.d.ts.map +1 -0
  234. package/dist/steering/steering-manager.js +79 -0
  235. package/dist/steering/steering-manager.js.map +1 -0
  236. package/dist/steering/telegram-gateway.d.ts +27 -0
  237. package/dist/steering/telegram-gateway.d.ts.map +1 -0
  238. package/dist/steering/telegram-gateway.js +89 -0
  239. package/dist/steering/telegram-gateway.js.map +1 -0
  240. package/dist/steering/types.d.ts +54 -0
  241. package/dist/steering/types.d.ts.map +1 -0
  242. package/dist/steering/types.js +11 -0
  243. package/dist/steering/types.js.map +1 -0
  244. package/dist/teams/agent-loader.d.ts +38 -0
  245. package/dist/teams/agent-loader.d.ts.map +1 -0
  246. package/dist/teams/agent-loader.js +85 -0
  247. package/dist/teams/agent-loader.js.map +1 -0
  248. package/dist/teams/bridge-watchdog.d.ts +44 -0
  249. package/dist/teams/bridge-watchdog.d.ts.map +1 -0
  250. package/dist/teams/bridge-watchdog.js +118 -0
  251. package/dist/teams/bridge-watchdog.js.map +1 -0
  252. package/dist/teams/gemini-bridge.d.ts +43 -0
  253. package/dist/teams/gemini-bridge.d.ts.map +1 -0
  254. package/dist/teams/gemini-bridge.js +132 -0
  255. package/dist/teams/gemini-bridge.js.map +1 -0
  256. package/dist/teams/index.d.ts +11 -0
  257. package/dist/teams/index.d.ts.map +1 -0
  258. package/dist/teams/index.js +11 -0
  259. package/dist/teams/index.js.map +1 -0
  260. package/dist/teams/mailbox.d.ts +33 -0
  261. package/dist/teams/mailbox.d.ts.map +1 -0
  262. package/dist/teams/mailbox.js +97 -0
  263. package/dist/teams/mailbox.js.map +1 -0
  264. package/dist/teams/pr-lifecycle.d.ts +47 -0
  265. package/dist/teams/pr-lifecycle.d.ts.map +1 -0
  266. package/dist/teams/pr-lifecycle.js +83 -0
  267. package/dist/teams/pr-lifecycle.js.map +1 -0
  268. package/dist/teams/team-manager.d.ts +57 -0
  269. package/dist/teams/team-manager.d.ts.map +1 -0
  270. package/dist/teams/team-manager.js +170 -0
  271. package/dist/teams/team-manager.js.map +1 -0
  272. package/dist/teams/team-types.d.ts +35 -0
  273. package/dist/teams/team-types.d.ts.map +1 -0
  274. package/dist/teams/team-types.js +9 -0
  275. package/dist/teams/team-types.js.map +1 -0
  276. package/dist/tools/index.d.ts +8 -0
  277. package/dist/tools/index.d.ts.map +1 -0
  278. package/dist/tools/index.js +8 -0
  279. package/dist/tools/index.js.map +1 -0
  280. package/dist/tools/notifications.d.ts +13 -0
  281. package/dist/tools/notifications.d.ts.map +1 -0
  282. package/dist/tools/notifications.js +30 -0
  283. package/dist/tools/notifications.js.map +1 -0
  284. package/dist/types.d.ts +311 -0
  285. package/dist/types.d.ts.map +1 -0
  286. package/dist/types.js +8 -0
  287. package/dist/types.js.map +1 -0
  288. package/dist/utils/fs.d.ts +9 -0
  289. package/dist/utils/fs.d.ts.map +1 -0
  290. package/dist/utils/fs.js +31 -0
  291. package/dist/utils/fs.js.map +1 -0
  292. package/dist/utils/logger.d.ts +43 -0
  293. package/dist/utils/logger.d.ts.map +1 -0
  294. package/dist/utils/logger.js +139 -0
  295. package/dist/utils/logger.js.map +1 -0
  296. package/dist/wasm/wasmtime-spike.d.ts +19 -0
  297. package/dist/wasm/wasmtime-spike.d.ts.map +1 -0
  298. package/dist/wasm/wasmtime-spike.js +39 -0
  299. package/dist/wasm/wasmtime-spike.js.map +1 -0
  300. package/examples/routines/content-pipeline.toml +20 -0
  301. package/examples/routines/job-search.toml +19 -0
  302. package/examples/routines/repo-cleanup.toml +14 -0
  303. package/package.json +66 -0
@@ -0,0 +1,110 @@
1
+ /**
2
+ * Capability Tokens — Worker capability enforcement.
3
+ *
4
+ * Spec §5.3 (WorkerCapabilityToken):
5
+ * - Create scoped tokens from policy
6
+ * - Enforce actions against token capabilities
7
+ * - Expiration checks
8
+ */
9
+ import path from 'node:path';
10
+ const DEFAULT_EXPIRATION_MS = 30 * 60 * 1000; // 30 minutes
11
+ /**
12
+ * Create a capability token scoped from policy for a specific job.
13
+ */
14
+ export function createCapabilityToken(jobId, policy, overrides) {
15
+ const now = new Date();
16
+ const maxExecTime = overrides?.maxExecutionTime ?? parseTimeToMs(policy.shell.max_execution_time);
17
+ return {
18
+ jobId,
19
+ allowedPaths: overrides?.allowedPaths ?? [...policy.filesystem.allowed_paths],
20
+ deniedPaths: overrides?.deniedPaths ?? [...policy.filesystem.denied_paths],
21
+ allowedCommands: overrides?.allowedCommands ?? [...policy.shell.allowed_commands],
22
+ allowedTools: overrides?.allowedTools ?? [],
23
+ maxExecutionTime: maxExecTime,
24
+ createdAt: now,
25
+ expiresAt: new Date(now.getTime() + DEFAULT_EXPIRATION_MS),
26
+ };
27
+ }
28
+ /**
29
+ * Check if an action is within the scope of a capability token.
30
+ */
31
+ export function enforceCapability(token, action) {
32
+ // Check expiration first
33
+ if (isTokenExpired(token)) {
34
+ return { allowed: false, reason: 'Token has expired' };
35
+ }
36
+ switch (action.type) {
37
+ case 'path':
38
+ return _enforcePath(token, action.target);
39
+ case 'command':
40
+ return _enforceCommand(token, action.target);
41
+ case 'tool':
42
+ return _enforceTool(token, action.target);
43
+ default:
44
+ return { allowed: false, reason: `Unknown action type: ${String(action.type)}` };
45
+ }
46
+ }
47
+ /**
48
+ * Check if a token has expired.
49
+ */
50
+ export function isTokenExpired(token) {
51
+ return new Date() > token.expiresAt;
52
+ }
53
+ // ─── Private Helpers ──────────────────────────────────────────────
54
+ function _enforcePath(token, targetPath) {
55
+ // Normalize the path to prevent traversal bypasses (e.g., /allowed/../denied)
56
+ const normalized = path.resolve(targetPath);
57
+ // Check denied paths first
58
+ for (const denied of token.deniedPaths) {
59
+ const normalizedDenied = path.resolve(denied);
60
+ if (normalized === normalizedDenied || normalized.startsWith(normalizedDenied + '/')) {
61
+ return { allowed: false, reason: `Path ${normalized} is denied by capability token` };
62
+ }
63
+ }
64
+ // Check allowed paths
65
+ for (const allowed of token.allowedPaths) {
66
+ const normalizedAllowed = path.resolve(allowed);
67
+ if (normalized === normalizedAllowed || normalized.startsWith(normalizedAllowed + '/')) {
68
+ return { allowed: true };
69
+ }
70
+ }
71
+ return { allowed: false, reason: `Path ${normalized} is not in token's allowed paths` };
72
+ }
73
+ function _enforceCommand(token, command) {
74
+ const baseCommand = command.trim().split(/\s+/)[0] ?? '';
75
+ if (token.allowedCommands.length === 0) {
76
+ return { allowed: false, reason: 'No commands are allowed by this capability token' };
77
+ }
78
+ if (!token.allowedCommands.includes(baseCommand)) {
79
+ return { allowed: false, reason: `Command '${baseCommand}' is not in token's allowed commands` };
80
+ }
81
+ return { allowed: true };
82
+ }
83
+ function _enforceTool(token, toolName) {
84
+ if (token.allowedTools.length === 0) {
85
+ // If no tools are specified, all tools are allowed (open policy)
86
+ return { allowed: true };
87
+ }
88
+ if (!token.allowedTools.includes(toolName)) {
89
+ return { allowed: false, reason: `Tool '${toolName}' is not in token's allowed tools` };
90
+ }
91
+ return { allowed: true };
92
+ }
93
+ /**
94
+ * Parse a time string like "1m", "30s", "2h" into milliseconds.
95
+ */
96
+ function parseTimeToMs(timeStr) {
97
+ const match = /^(\d+)\s*(ms|s|m|h)$/.exec(timeStr);
98
+ if (!match)
99
+ return 60_000; // default 1 minute
100
+ const value = parseInt(match[1], 10);
101
+ const unit = match[2];
102
+ switch (unit) {
103
+ case 'ms': return value;
104
+ case 's': return value * 1000;
105
+ case 'm': return value * 60_000;
106
+ case 'h': return value * 3_600_000;
107
+ default: return 60_000;
108
+ }
109
+ }
110
+ //# sourceMappingURL=capability-tokens.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"capability-tokens.js","sourceRoot":"","sources":["../../src/security/capability-tokens.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,18 @@
1
+ /**
2
+ * Security barrel exports.
3
+ */
4
+ export { PolicyEngine } from './policy-engine.js';
5
+ export type { ValidationResult } from './policy-engine.js';
6
+ export { SecretsManager } from './secrets-manager.js';
7
+ export { AuditLogger } from './audit-logger.js';
8
+ export type { AuditEntryInput, AuditFilter, ChainVerificationResult } from './audit-logger.js';
9
+ export { IntegrityGuardian } from './integrity-guardian.js';
10
+ export type { IntegrityCheckResult } from './integrity-guardian.js';
11
+ export { sanitizeInput, validateOutput, sanitizeToolOutput } from './prompt-defense.js';
12
+ export type { OutputValidationResult } from './prompt-defense.js';
13
+ export { IntentCapsuleManager } from './intent-capsule.js';
14
+ export { LeakDetector } from './leak-detector.js';
15
+ export { createCapabilityToken, enforceCapability, isTokenExpired, } from './capability-tokens.js';
16
+ export type { CapabilityAction, EnforcementResult } from './capability-tokens.js';
17
+ export type { AuditEntry, AuditEntryEventType, IntegrityBaseline, SecretReference, LeakPattern, LeakMatch, LeakSeverity, CapabilityGrant, BudgetStatus, DryRunResult, IntentCapsule, DriftCheckResult, } from './security-types.js';
18
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,YAAY,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAE3D,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAChD,YAAY,EAAE,eAAe,EAAE,WAAW,EAAE,uBAAuB,EAAE,MAAM,mBAAmB,CAAC;AAC/F,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAC5D,YAAY,EAAE,oBAAoB,EAAE,MAAM,yBAAyB,CAAC;AACpE,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AACxF,YAAY,EAAE,sBAAsB,EAAE,MAAM,qBAAqB,CAAC;AAClE,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,GACf,MAAM,wBAAwB,CAAC;AAChC,YAAY,EAAE,gBAAgB,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAC;AAGlF,YAAY,EACV,UAAU,EACV,mBAAmB,EACnB,iBAAiB,EACjB,eAAe,EACf,WAAW,EACX,SAAS,EACT,YAAY,EACZ,eAAe,EACf,YAAY,EACZ,YAAY,EACZ,aAAa,EACb,gBAAgB,GACjB,MAAM,qBAAqB,CAAC"}
@@ -0,0 +1,12 @@
1
+ /**
2
+ * Security barrel exports.
3
+ */
4
+ export { PolicyEngine } from './policy-engine.js';
5
+ export { SecretsManager } from './secrets-manager.js';
6
+ export { AuditLogger } from './audit-logger.js';
7
+ export { IntegrityGuardian } from './integrity-guardian.js';
8
+ export { sanitizeInput, validateOutput, sanitizeToolOutput } from './prompt-defense.js';
9
+ export { IntentCapsuleManager } from './intent-capsule.js';
10
+ export { LeakDetector } from './leak-detector.js';
11
+ export { createCapabilityToken, enforceCapability, isTokenExpired, } from './capability-tokens.js';
12
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/security/index.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD,OAAO,EAAE,cAAc,EAAE,MAAM,sBAAsB,CAAC;AACtD,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,OAAO,EAAE,iBAAiB,EAAE,MAAM,yBAAyB,CAAC;AAE5D,OAAO,EAAE,aAAa,EAAE,cAAc,EAAE,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAExF,OAAO,EAAE,oBAAoB,EAAE,MAAM,qBAAqB,CAAC;AAC3D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,EACL,qBAAqB,EACrB,iBAAiB,EACjB,cAAc,GACf,MAAM,wBAAwB,CAAC"}
@@ -0,0 +1,43 @@
1
+ /**
2
+ * IntegrityGuardian — SHA-256 baseline integrity checking.
3
+ *
4
+ * Spec §5.5 "Integrity Guardian":
5
+ * - Computes SHA-256 hashes of critical configuration files
6
+ * - Saves baselines and detects tampering
7
+ * - Quarantines suspicious files
8
+ */
9
+ import type { IntegrityBaseline } from './security-types.js';
10
+ export interface IntegrityCheckResult {
11
+ valid: boolean;
12
+ mismatches: Array<{
13
+ file: string;
14
+ expected: string;
15
+ actual: string;
16
+ }>;
17
+ }
18
+ export declare class IntegrityGuardian {
19
+ private readonly _baseDir;
20
+ private readonly _toolRegistry;
21
+ /**
22
+ * @param baseDir Root directory containing critical files (e.g. ~/.zora)
23
+ * @param toolRegistry Optional map of tool name → definition content to hash
24
+ */
25
+ constructor(baseDir: string, toolRegistry?: Record<string, string>);
26
+ /**
27
+ * Compute SHA-256 baselines for all critical files and the tool registry.
28
+ */
29
+ computeBaseline(): Promise<IntegrityBaseline[]>;
30
+ /**
31
+ * Save computed baselines to disk.
32
+ */
33
+ saveBaseline(): Promise<void>;
34
+ /**
35
+ * Compare current file hashes against saved baselines.
36
+ */
37
+ checkIntegrity(): Promise<IntegrityCheckResult>;
38
+ /**
39
+ * Quarantine a file by copying it to the quarantine directory with a timestamp.
40
+ */
41
+ quarantineFile(filePath: string): Promise<string>;
42
+ }
43
+ //# sourceMappingURL=integrity-guardian.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrity-guardian.d.ts","sourceRoot":"","sources":["../../src/security/integrity-guardian.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAKH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAM7D,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,OAAO,CAAC;IACf,UAAU,EAAE,KAAK,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACvE;AAED,qBAAa,iBAAiB;IAC5B,OAAO,CAAC,QAAQ,CAAC,QAAQ,CAAS;IAClC,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAyB;IAEvD;;;OAGG;gBACS,OAAO,EAAE,MAAM,EAAE,YAAY,GAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAM;IAKtE;;OAEG;IACG,eAAe,IAAI,OAAO,CAAC,iBAAiB,EAAE,CAAC;IA4BrD;;OAEG;IACG,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC;IAOnC;;OAEG;IACG,cAAc,IAAI,OAAO,CAAC,oBAAoB,CAAC;IA8BrD;;OAEG;IACG,cAAc,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;CAaxD"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * IntegrityGuardian — SHA-256 baseline integrity checking.
3
+ *
4
+ * Spec §5.5 "Integrity Guardian":
5
+ * - Computes SHA-256 hashes of critical configuration files
6
+ * - Saves baselines and detects tampering
7
+ * - Quarantines suspicious files
8
+ */
9
+ import crypto from 'node:crypto';
10
+ import fs from 'node:fs/promises';
11
+ import path from 'node:path';
12
+ const CRITICAL_FILES = ['SOUL.md', 'MEMORY.md', 'policy.toml', 'config.toml'];
13
+ const BASELINES_FILE = 'state/integrity-baselines.json';
14
+ const QUARANTINE_DIR = 'state/quarantine';
15
+ export class IntegrityGuardian {
16
+ _baseDir;
17
+ _toolRegistry;
18
+ /**
19
+ * @param baseDir Root directory containing critical files (e.g. ~/.zora)
20
+ * @param toolRegistry Optional map of tool name → definition content to hash
21
+ */
22
+ constructor(baseDir, toolRegistry = {}) {
23
+ this._baseDir = baseDir;
24
+ this._toolRegistry = toolRegistry;
25
+ }
26
+ /**
27
+ * Compute SHA-256 baselines for all critical files and the tool registry.
28
+ */
29
+ async computeBaseline() {
30
+ const baselines = [];
31
+ const now = new Date().toISOString();
32
+ for (const file of CRITICAL_FILES) {
33
+ const filePath = path.join(this._baseDir, file);
34
+ try {
35
+ const content = await fs.readFile(filePath, 'utf-8');
36
+ const hash = crypto.createHash('sha256').update(content).digest('hex');
37
+ baselines.push({ filePath: file, hash, updatedAt: now });
38
+ }
39
+ catch {
40
+ // File doesn't exist — record empty hash so we detect creation later
41
+ baselines.push({ filePath: file, hash: 'FILE_NOT_FOUND', updatedAt: now });
42
+ }
43
+ }
44
+ // Tool registry hash (combined hash of all tool definitions)
45
+ if (Object.keys(this._toolRegistry).length > 0) {
46
+ const registryContent = JSON.stringify(Object.fromEntries(Object.entries(this._toolRegistry).sort()));
47
+ const hash = crypto.createHash('sha256').update(registryContent).digest('hex');
48
+ baselines.push({ filePath: '__tool_registry__', hash, updatedAt: now });
49
+ }
50
+ return baselines;
51
+ }
52
+ /**
53
+ * Save computed baselines to disk.
54
+ */
55
+ async saveBaseline() {
56
+ const baselines = await this.computeBaseline();
57
+ const outputPath = path.join(this._baseDir, BASELINES_FILE);
58
+ await fs.mkdir(path.dirname(outputPath), { recursive: true });
59
+ await fs.writeFile(outputPath, JSON.stringify(baselines, null, 2), 'utf-8');
60
+ }
61
+ /**
62
+ * Compare current file hashes against saved baselines.
63
+ */
64
+ async checkIntegrity() {
65
+ const baselinesPath = path.join(this._baseDir, BASELINES_FILE);
66
+ let savedBaselines;
67
+ try {
68
+ const data = await fs.readFile(baselinesPath, 'utf-8');
69
+ savedBaselines = JSON.parse(data);
70
+ }
71
+ catch {
72
+ return { valid: false, mismatches: [{ file: BASELINES_FILE, expected: 'exists', actual: 'missing' }] };
73
+ }
74
+ const currentBaselines = await this.computeBaseline();
75
+ const mismatches = [];
76
+ for (const saved of savedBaselines) {
77
+ const current = currentBaselines.find(c => c.filePath === saved.filePath);
78
+ const actualHash = current?.hash ?? 'FILE_NOT_FOUND';
79
+ if (saved.hash !== actualHash) {
80
+ mismatches.push({
81
+ file: saved.filePath,
82
+ expected: saved.hash,
83
+ actual: actualHash,
84
+ });
85
+ }
86
+ }
87
+ return { valid: mismatches.length === 0, mismatches };
88
+ }
89
+ /**
90
+ * Quarantine a file by copying it to the quarantine directory with a timestamp.
91
+ */
92
+ async quarantineFile(filePath) {
93
+ const quarantineDir = path.join(this._baseDir, QUARANTINE_DIR);
94
+ await fs.mkdir(quarantineDir, { recursive: true });
95
+ const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
96
+ const basename = path.basename(filePath);
97
+ const quarantinePath = path.join(quarantineDir, `${basename}.${timestamp}`);
98
+ const sourcePath = path.isAbsolute(filePath) ? filePath : path.join(this._baseDir, filePath);
99
+ await fs.copyFile(sourcePath, quarantinePath);
100
+ return quarantinePath;
101
+ }
102
+ }
103
+ //# sourceMappingURL=integrity-guardian.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"integrity-guardian.js","sourceRoot":"","sources":["../../src/security/integrity-guardian.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,MAAM,MAAM,aAAa,CAAC;AACjC,OAAO,EAAE,MAAM,kBAAkB,CAAC;AAClC,OAAO,IAAI,MAAM,WAAW,CAAC;AAG7B,MAAM,cAAc,GAAG,CAAC,SAAS,EAAE,WAAW,EAAE,aAAa,EAAE,aAAa,CAAC,CAAC;AAC9E,MAAM,cAAc,GAAG,gCAAgC,CAAC;AACxD,MAAM,cAAc,GAAG,kBAAkB,CAAC;AAO1C,MAAM,OAAO,iBAAiB;IACX,QAAQ,CAAS;IACjB,aAAa,CAAyB;IAEvD;;;OAGG;IACH,YAAY,OAAe,EAAE,eAAuC,EAAE;QACpE,IAAI,CAAC,QAAQ,GAAG,OAAO,CAAC;QACxB,IAAI,CAAC,aAAa,GAAG,YAAY,CAAC;IACpC,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,eAAe;QACnB,MAAM,SAAS,GAAwB,EAAE,CAAC;QAC1C,MAAM,GAAG,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;QAErC,KAAK,MAAM,IAAI,IAAI,cAAc,EAAE,CAAC;YAClC,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,IAAI,CAAC,CAAC;YAChD,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,QAAQ,EAAE,OAAO,CAAC,CAAC;gBACrD,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;gBACvE,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YAC3D,CAAC;YAAC,MAAM,CAAC;gBACP,qEAAqE;gBACrE,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,IAAI,EAAE,IAAI,EAAE,gBAAgB,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;YAC7E,CAAC;QACH,CAAC;QAED,6DAA6D;QAC7D,IAAI,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC/C,MAAM,eAAe,GAAG,IAAI,CAAC,SAAS,CACpC,MAAM,CAAC,WAAW,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,IAAI,EAAE,CAAC,CAC9D,CAAC;YACF,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;YAC/E,SAAS,CAAC,IAAI,CAAC,EAAE,QAAQ,EAAE,mBAAmB,EAAE,IAAI,EAAE,SAAS,EAAE,GAAG,EAAE,CAAC,CAAC;QAC1E,CAAC;QAED,OAAO,SAAS,CAAC;IACnB,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,YAAY;QAChB,MAAM,SAAS,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC5D,MAAM,EAAE,CAAC,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAC9D,MAAM,EAAE,CAAC,SAAS,CAAC,UAAU,EAAE,IAAI,CAAC,SAAS,CAAC,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;IAC9E,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc;QAClB,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAE/D,IAAI,cAAmC,CAAC;QACxC,IAAI,CAAC;YACH,MAAM,IAAI,GAAG,MAAM,EAAE,CAAC,QAAQ,CAAC,aAAa,EAAE,OAAO,CAAC,CAAC;YACvD,cAAc,GAAG,IAAI,CAAC,KAAK,CAAC,IAAI,CAAwB,CAAC;QAC3D,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,UAAU,EAAE,CAAC,EAAE,IAAI,EAAE,cAAc,EAAE,QAAQ,EAAE,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,EAAE,CAAC;QACzG,CAAC;QAED,MAAM,gBAAgB,GAAG,MAAM,IAAI,CAAC,eAAe,EAAE,CAAC;QACtD,MAAM,UAAU,GAA8D,EAAE,CAAC;QAEjF,KAAK,MAAM,KAAK,IAAI,cAAc,EAAE,CAAC;YACnC,MAAM,OAAO,GAAG,gBAAgB,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,QAAQ,KAAK,KAAK,CAAC,QAAQ,CAAC,CAAC;YAC1E,MAAM,UAAU,GAAG,OAAO,EAAE,IAAI,IAAI,gBAAgB,CAAC;YAErD,IAAI,KAAK,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;gBAC9B,UAAU,CAAC,IAAI,CAAC;oBACd,IAAI,EAAE,KAAK,CAAC,QAAQ;oBACpB,QAAQ,EAAE,KAAK,CAAC,IAAI;oBACpB,MAAM,EAAE,UAAU;iBACnB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;QAED,OAAO,EAAE,KAAK,EAAE,UAAU,CAAC,MAAM,KAAK,CAAC,EAAE,UAAU,EAAE,CAAC;IACxD,CAAC;IAED;;OAEG;IACH,KAAK,CAAC,cAAc,CAAC,QAAgB;QACnC,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;QAC/D,MAAM,EAAE,CAAC,KAAK,CAAC,aAAa,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAEnD,MAAM,SAAS,GAAG,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC,OAAO,CAAC,OAAO,EAAE,GAAG,CAAC,CAAC;QACjE,MAAM,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;QACzC,MAAM,cAAc,GAAG,IAAI,CAAC,IAAI,CAAC,aAAa,EAAE,GAAG,QAAQ,IAAI,SAAS,EAAE,CAAC,CAAC;QAE5E,MAAM,UAAU,GAAG,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,EAAE,QAAQ,CAAC,CAAC;QAC7F,MAAM,EAAE,CAAC,QAAQ,CAAC,UAAU,EAAE,cAAc,CAAC,CAAC;QAE9C,OAAO,cAAc,CAAC;IACxB,CAAC;CACF"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * IntentCapsuleManager — Cryptographically signed mandate bundles for goal drift detection.
3
+ *
4
+ * Security Hardening (Feb 2026) — ASI01 Mitigation:
5
+ * - Creates HMAC-SHA256 signed "Intent Capsules" at task start
6
+ * - Verifies capsule integrity to detect tampering
7
+ * - Checks each action for consistency with the original mandate
8
+ * - Detects goal hijacking via keyword overlap and category matching
9
+ */
10
+ import type { IntentCapsule, DriftCheckResult } from './security-types.js';
11
+ export declare class IntentCapsuleManager {
12
+ private readonly _signingKey;
13
+ private _activeCapsule;
14
+ private _driftHistory;
15
+ constructor(signingSecret: string);
16
+ /**
17
+ * Create a signed intent capsule at task start.
18
+ * The capsule captures the original mandate and cannot be
19
+ * modified without invalidating the signature.
20
+ */
21
+ createCapsule(mandate: string, options?: {
22
+ allowedActionCategories?: string[];
23
+ ttlMs?: number;
24
+ }): IntentCapsule;
25
+ /**
26
+ * Verify the HMAC signature of an intent capsule.
27
+ * Returns false if the capsule has been tampered with.
28
+ */
29
+ verifyCapsule(capsule: IntentCapsule): boolean;
30
+ /**
31
+ * Check if an action is consistent with the active mandate.
32
+ * Uses category matching and keyword overlap heuristics.
33
+ */
34
+ checkDrift(actionType: string, actionDetail: string): DriftCheckResult;
35
+ /**
36
+ * Get the currently active capsule.
37
+ */
38
+ getActiveCapsule(): IntentCapsule | null;
39
+ /**
40
+ * Get drift check history.
41
+ */
42
+ getDriftHistory(): DriftCheckResult[];
43
+ /**
44
+ * Clear the active capsule (session end).
45
+ */
46
+ clearCapsule(): void;
47
+ /**
48
+ * Extract meaningful keywords from text, filtering stop words.
49
+ */
50
+ private _extractKeywords;
51
+ }
52
+ //# sourceMappingURL=intent-capsule.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-capsule.d.ts","sourceRoot":"","sources":["../../src/security/intent-capsule.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAW3E,qBAAa,oBAAoB;IAC/B,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,cAAc,CAA8B;IACpD,OAAO,CAAC,aAAa,CAA0B;gBAEnC,aAAa,EAAE,MAAM;IAIjC;;;;OAIG;IACH,aAAa,CAAC,OAAO,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QACvC,uBAAuB,CAAC,EAAE,MAAM,EAAE,CAAC;QACnC,KAAK,CAAC,EAAE,MAAM,CAAC;KAChB,GAAG,aAAa;IA8BjB;;;OAGG;IACH,aAAa,CAAC,OAAO,EAAE,aAAa,GAAG,OAAO;IAsB9C;;;OAGG;IACH,UAAU,CAAC,UAAU,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,GAAG,gBAAgB;IAuDtE;;OAEG;IACH,gBAAgB,IAAI,aAAa,GAAG,IAAI;IAIxC;;OAEG;IACH,eAAe,IAAI,gBAAgB,EAAE;IAIrC;;OAEG;IACH,YAAY,IAAI,IAAI;IAKpB;;OAEG;IACH,OAAO,CAAC,gBAAgB;CAOzB"}
@@ -0,0 +1,157 @@
1
+ /**
2
+ * IntentCapsuleManager — Cryptographically signed mandate bundles for goal drift detection.
3
+ *
4
+ * Security Hardening (Feb 2026) — ASI01 Mitigation:
5
+ * - Creates HMAC-SHA256 signed "Intent Capsules" at task start
6
+ * - Verifies capsule integrity to detect tampering
7
+ * - Checks each action for consistency with the original mandate
8
+ * - Detects goal hijacking via keyword overlap and category matching
9
+ */
10
+ import crypto from 'node:crypto';
11
+ const STOP_WORDS = new Set([
12
+ 'the', 'a', 'an', 'is', 'are', 'was', 'were', 'be', 'been',
13
+ 'have', 'has', 'had', 'do', 'does', 'did', 'will', 'would',
14
+ 'could', 'should', 'may', 'might', 'can', 'to', 'of', 'in',
15
+ 'for', 'on', 'with', 'at', 'by', 'from', 'this', 'that',
16
+ 'it', 'and', 'or', 'but', 'not', 'if', 'then', 'else',
17
+ 'please', 'help', 'me', 'i', 'you', 'we', 'they',
18
+ ]);
19
+ export class IntentCapsuleManager {
20
+ _signingKey;
21
+ _activeCapsule = null;
22
+ _driftHistory = [];
23
+ constructor(signingSecret) {
24
+ this._signingKey = crypto.createHash('sha256').update(signingSecret).digest();
25
+ }
26
+ /**
27
+ * Create a signed intent capsule at task start.
28
+ * The capsule captures the original mandate and cannot be
29
+ * modified without invalidating the signature.
30
+ */
31
+ createCapsule(mandate, options) {
32
+ const capsuleId = `capsule_${Date.now()}_${crypto.randomBytes(4).toString('hex')}`;
33
+ const mandateHash = crypto.createHash('sha256').update(mandate).digest('hex');
34
+ const mandateKeywords = this._extractKeywords(mandate);
35
+ const createdAt = new Date().toISOString();
36
+ const expiresAt = options?.ttlMs
37
+ ? new Date(Date.now() + options.ttlMs).toISOString()
38
+ : undefined;
39
+ const allowedActionCategories = options?.allowedActionCategories ?? [];
40
+ const payload = JSON.stringify({
41
+ capsuleId, mandate, mandateHash, mandateKeywords,
42
+ allowedActionCategories, createdAt, expiresAt,
43
+ });
44
+ const signature = crypto
45
+ .createHmac('sha256', this._signingKey)
46
+ .update(payload)
47
+ .digest('hex');
48
+ const capsule = {
49
+ capsuleId, mandate, mandateHash, mandateKeywords,
50
+ allowedActionCategories, signature, createdAt, expiresAt,
51
+ };
52
+ this._activeCapsule = capsule;
53
+ this._driftHistory = [];
54
+ return capsule;
55
+ }
56
+ /**
57
+ * Verify the HMAC signature of an intent capsule.
58
+ * Returns false if the capsule has been tampered with.
59
+ */
60
+ verifyCapsule(capsule) {
61
+ const payload = JSON.stringify({
62
+ capsuleId: capsule.capsuleId,
63
+ mandate: capsule.mandate,
64
+ mandateHash: capsule.mandateHash,
65
+ mandateKeywords: capsule.mandateKeywords,
66
+ allowedActionCategories: capsule.allowedActionCategories,
67
+ createdAt: capsule.createdAt,
68
+ expiresAt: capsule.expiresAt,
69
+ });
70
+ const expectedSignature = crypto
71
+ .createHmac('sha256', this._signingKey)
72
+ .update(payload)
73
+ .digest('hex');
74
+ return crypto.timingSafeEqual(Buffer.from(capsule.signature, 'hex'), Buffer.from(expectedSignature, 'hex'));
75
+ }
76
+ /**
77
+ * Check if an action is consistent with the active mandate.
78
+ * Uses category matching and keyword overlap heuristics.
79
+ */
80
+ checkDrift(actionType, actionDetail) {
81
+ if (!this._activeCapsule) {
82
+ return { consistent: true, confidence: 0, action: actionType, mandateHash: '' };
83
+ }
84
+ const capsule = this._activeCapsule;
85
+ // Check capsule expiry
86
+ if (capsule.expiresAt && new Date() > new Date(capsule.expiresAt)) {
87
+ const result = {
88
+ consistent: false, confidence: 1.0,
89
+ reason: 'Intent capsule has expired',
90
+ action: actionType, mandateHash: capsule.mandateHash,
91
+ };
92
+ this._driftHistory.push(result);
93
+ return result;
94
+ }
95
+ // Check action category against allowed categories
96
+ if (capsule.allowedActionCategories.length > 0) {
97
+ if (!capsule.allowedActionCategories.includes(actionType)) {
98
+ const result = {
99
+ consistent: false, confidence: 0.8,
100
+ reason: `Action '${actionType}' not in mandate's allowed categories: ${capsule.allowedActionCategories.join(', ')}`,
101
+ action: actionType, mandateHash: capsule.mandateHash,
102
+ };
103
+ this._driftHistory.push(result);
104
+ return result;
105
+ }
106
+ }
107
+ // Keyword overlap check: does the action detail relate to the mandate?
108
+ const actionKeywords = this._extractKeywords(actionDetail);
109
+ const overlap = actionKeywords.filter(k => capsule.mandateKeywords.includes(k));
110
+ const overlapRatio = actionKeywords.length > 0
111
+ ? overlap.length / actionKeywords.length
112
+ : 1.0; // empty action detail = no drift signal
113
+ const consistent = overlapRatio >= 0.1; // At least 10% keyword overlap
114
+ const confidence = consistent ? overlapRatio : 1.0 - overlapRatio;
115
+ const result = {
116
+ consistent,
117
+ confidence,
118
+ ...(!consistent ? {
119
+ reason: `Low mandate relevance (${(overlapRatio * 100).toFixed(0)}% keyword overlap)`,
120
+ } : {}),
121
+ action: actionType,
122
+ mandateHash: capsule.mandateHash,
123
+ };
124
+ this._driftHistory.push(result);
125
+ return result;
126
+ }
127
+ /**
128
+ * Get the currently active capsule.
129
+ */
130
+ getActiveCapsule() {
131
+ return this._activeCapsule;
132
+ }
133
+ /**
134
+ * Get drift check history.
135
+ */
136
+ getDriftHistory() {
137
+ return [...this._driftHistory];
138
+ }
139
+ /**
140
+ * Clear the active capsule (session end).
141
+ */
142
+ clearCapsule() {
143
+ this._activeCapsule = null;
144
+ this._driftHistory = [];
145
+ }
146
+ /**
147
+ * Extract meaningful keywords from text, filtering stop words.
148
+ */
149
+ _extractKeywords(text) {
150
+ return text
151
+ .toLowerCase()
152
+ .replace(/[^a-z0-9\s_-]/g, ' ')
153
+ .split(/\s+/)
154
+ .filter(w => w.length > 2 && !STOP_WORDS.has(w));
155
+ }
156
+ }
157
+ //# sourceMappingURL=intent-capsule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"intent-capsule.js","sourceRoot":"","sources":["../../src/security/intent-capsule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,26 @@
1
+ /**
2
+ * LeakDetector — Secret leak scanning and redaction.
3
+ *
4
+ * Spec §5.5 "Leak Detection":
5
+ * - Built-in patterns for common secret formats
6
+ * - Custom pattern registration
7
+ * - Text redaction
8
+ */
9
+ import type { LeakMatch, LeakSeverity } from './security-types.js';
10
+ export declare class LeakDetector {
11
+ private readonly _patterns;
12
+ constructor();
13
+ /**
14
+ * Scan text for potential secret leaks.
15
+ */
16
+ scan(text: string): LeakMatch[];
17
+ /**
18
+ * Add a custom leak detection pattern.
19
+ */
20
+ addPattern(name: string, pattern: RegExp, severity: LeakSeverity): void;
21
+ /**
22
+ * Redact detected secrets, replacing them with `[REDACTED:{patternName}]`.
23
+ */
24
+ redact(text: string): string;
25
+ }
26
+ //# sourceMappingURL=leak-detector.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leak-detector.d.ts","sourceRoot":"","sources":["../../src/security/leak-detector.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,OAAO,KAAK,EAAe,SAAS,EAAE,YAAY,EAAE,MAAM,qBAAqB,CAAC;AAuBhF,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAgB;;IAU1C;;OAEG;IACH,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,SAAS,EAAE;IAoB/B;;OAEG;IACH,UAAU,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,EAAE,QAAQ,EAAE,YAAY,GAAG,IAAI;IAIvE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM;CAU7B"}
@@ -0,0 +1,75 @@
1
+ /**
2
+ * LeakDetector — Secret leak scanning and redaction.
3
+ *
4
+ * Spec §5.5 "Leak Detection":
5
+ * - Built-in patterns for common secret formats
6
+ * - Custom pattern registration
7
+ * - Text redaction
8
+ */
9
+ const BUILT_IN_PATTERNS = [
10
+ // OpenAI / Anthropic API keys
11
+ { name: 'openai_api_key', pattern: /\bsk-[A-Za-z0-9]{20,}\b/g, severity: 'high' },
12
+ // Google AI API keys
13
+ { name: 'google_api_key', pattern: /\bAIza[A-Za-z0-9_-]{35,}\b/g, severity: 'high' },
14
+ // GitHub personal access tokens
15
+ { name: 'github_token', pattern: /\bghp_[A-Za-z0-9]{36,}\b/g, severity: 'high' },
16
+ // Slack bot tokens
17
+ { name: 'slack_token', pattern: /\bxoxb-[A-Za-z0-9-]+\b/g, severity: 'high' },
18
+ // JWT tokens
19
+ { name: 'jwt_token', pattern: /\beyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}\b/g, severity: 'medium' },
20
+ // Base64 encoded blocks > 50 chars (potential encoded secrets)
21
+ { name: 'base64_block', pattern: /\b[A-Za-z0-9+/]{50,}={0,2}\b/g, severity: 'low' },
22
+ // Private key headers
23
+ { name: 'private_key', pattern: /-----BEGIN\s+(RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/g, severity: 'high' },
24
+ // AWS access key IDs
25
+ { name: 'aws_access_key', pattern: /\b(AKIA|ASIA)[A-Z0-9]{16}\b/g, severity: 'high' },
26
+ // Generic secret assignment patterns
27
+ { name: 'password_assignment', pattern: /(?:password|passwd|pwd)\s*[:=]\s*["'][^"']{4,}["']/gi, severity: 'medium' },
28
+ ];
29
+ export class LeakDetector {
30
+ _patterns;
31
+ constructor() {
32
+ // Deep-copy built-in patterns to avoid shared state between instances
33
+ this._patterns = BUILT_IN_PATTERNS.map(p => ({
34
+ ...p,
35
+ pattern: new RegExp(p.pattern.source, p.pattern.flags),
36
+ }));
37
+ }
38
+ /**
39
+ * Scan text for potential secret leaks.
40
+ */
41
+ scan(text) {
42
+ const matches = [];
43
+ for (const { name, pattern, severity } of this._patterns) {
44
+ // Reset lastIndex for global regexes
45
+ const regex = new RegExp(pattern.source, pattern.flags);
46
+ let match;
47
+ while ((match = regex.exec(text)) !== null) {
48
+ matches.push({
49
+ pattern: name,
50
+ match: match[0],
51
+ severity,
52
+ });
53
+ }
54
+ }
55
+ return matches;
56
+ }
57
+ /**
58
+ * Add a custom leak detection pattern.
59
+ */
60
+ addPattern(name, pattern, severity) {
61
+ this._patterns.push({ name, pattern, severity });
62
+ }
63
+ /**
64
+ * Redact detected secrets, replacing them with `[REDACTED:{patternName}]`.
65
+ */
66
+ redact(text) {
67
+ let result = text;
68
+ for (const { name, pattern } of this._patterns) {
69
+ const regex = new RegExp(pattern.source, pattern.flags);
70
+ result = result.replace(regex, `[REDACTED:${name}]`);
71
+ }
72
+ return result;
73
+ }
74
+ }
75
+ //# sourceMappingURL=leak-detector.js.map