@vinaes/succ 1.4.0 → 1.5.37

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 (683) hide show
  1. package/README.md +64 -10
  2. package/dist/cli.js +71 -1
  3. package/dist/cli.js.map +1 -1
  4. package/dist/commands/agents-md.d.ts.map +1 -1
  5. package/dist/commands/agents-md.js +3 -2
  6. package/dist/commands/agents-md.js.map +1 -1
  7. package/dist/commands/analyze-profile.d.ts.map +1 -1
  8. package/dist/commands/analyze-profile.js +32 -8
  9. package/dist/commands/analyze-profile.js.map +1 -1
  10. package/dist/commands/analyze-recursive.d.ts.map +1 -1
  11. package/dist/commands/analyze-recursive.js +6 -2
  12. package/dist/commands/analyze-recursive.js.map +1 -1
  13. package/dist/commands/analyze-utils.d.ts.map +1 -1
  14. package/dist/commands/analyze-utils.js +17 -4
  15. package/dist/commands/analyze-utils.js.map +1 -1
  16. package/dist/commands/benchmark-quality.d.ts.map +1 -1
  17. package/dist/commands/benchmark-quality.js +11 -4
  18. package/dist/commands/benchmark-quality.js.map +1 -1
  19. package/dist/commands/benchmark-sqlite-vec.d.ts.map +1 -1
  20. package/dist/commands/benchmark-sqlite-vec.js +4 -0
  21. package/dist/commands/benchmark-sqlite-vec.js.map +1 -1
  22. package/dist/commands/benchmark.d.ts.map +1 -1
  23. package/dist/commands/benchmark.js +5 -1
  24. package/dist/commands/benchmark.js.map +1 -1
  25. package/dist/commands/codex-chat.d.ts +8 -0
  26. package/dist/commands/codex-chat.d.ts.map +1 -0
  27. package/dist/commands/codex-chat.js +161 -0
  28. package/dist/commands/codex-chat.js.map +1 -0
  29. package/dist/commands/config.d.ts.map +1 -1
  30. package/dist/commands/config.js +32 -4
  31. package/dist/commands/config.js.map +1 -1
  32. package/dist/commands/daemon.d.ts.map +1 -1
  33. package/dist/commands/daemon.js +13 -4
  34. package/dist/commands/daemon.js.map +1 -1
  35. package/dist/commands/index-code.d.ts +4 -0
  36. package/dist/commands/index-code.d.ts.map +1 -1
  37. package/dist/commands/index-code.js +1 -1
  38. package/dist/commands/index-code.js.map +1 -1
  39. package/dist/commands/init.d.ts.map +1 -1
  40. package/dist/commands/init.js +305 -203
  41. package/dist/commands/init.js.map +1 -1
  42. package/dist/commands/memories.d.ts.map +1 -1
  43. package/dist/commands/memories.js +25 -14
  44. package/dist/commands/memories.js.map +1 -1
  45. package/dist/commands/progress.d.ts.map +1 -1
  46. package/dist/commands/progress.js +3 -2
  47. package/dist/commands/progress.js.map +1 -1
  48. package/dist/commands/reindex.d.ts.map +1 -1
  49. package/dist/commands/reindex.js +54 -36
  50. package/dist/commands/reindex.js.map +1 -1
  51. package/dist/commands/retention.d.ts.map +1 -1
  52. package/dist/commands/retention.js +7 -5
  53. package/dist/commands/retention.js.map +1 -1
  54. package/dist/commands/scan-code.d.ts +76 -0
  55. package/dist/commands/scan-code.d.ts.map +1 -0
  56. package/dist/commands/scan-code.js +385 -0
  57. package/dist/commands/scan-code.js.map +1 -0
  58. package/dist/commands/score.d.ts.map +1 -1
  59. package/dist/commands/score.js +3 -2
  60. package/dist/commands/score.js.map +1 -1
  61. package/dist/commands/session.d.ts +33 -0
  62. package/dist/commands/session.d.ts.map +1 -0
  63. package/dist/commands/session.js +163 -0
  64. package/dist/commands/session.js.map +1 -0
  65. package/dist/commands/setup.d.ts.map +1 -1
  66. package/dist/commands/setup.js +254 -15
  67. package/dist/commands/setup.js.map +1 -1
  68. package/dist/commands/soul.js +3 -2
  69. package/dist/commands/soul.js.map +1 -1
  70. package/dist/commands/status.d.ts.map +1 -1
  71. package/dist/commands/status.js +14 -5
  72. package/dist/commands/status.js.map +1 -1
  73. package/dist/commands/watch.d.ts.map +1 -1
  74. package/dist/commands/watch.js +13 -4
  75. package/dist/commands/watch.js.map +1 -1
  76. package/dist/daemon/analyzer.d.ts.map +1 -1
  77. package/dist/daemon/analyzer.js +21 -5
  78. package/dist/daemon/analyzer.js.map +1 -1
  79. package/dist/daemon/client.d.ts.map +1 -1
  80. package/dist/daemon/client.js +32 -8
  81. package/dist/daemon/client.js.map +1 -1
  82. package/dist/daemon/routes/analyzer.d.ts +3 -0
  83. package/dist/daemon/routes/analyzer.d.ts.map +1 -0
  84. package/dist/daemon/routes/analyzer.js +27 -0
  85. package/dist/daemon/routes/analyzer.js.map +1 -0
  86. package/dist/daemon/routes/hooks.d.ts +14 -0
  87. package/dist/daemon/routes/hooks.d.ts.map +1 -0
  88. package/dist/daemon/routes/hooks.js +1212 -0
  89. package/dist/daemon/routes/hooks.js.map +1 -0
  90. package/dist/daemon/routes/memory.d.ts +4 -0
  91. package/dist/daemon/routes/memory.d.ts.map +1 -0
  92. package/dist/daemon/routes/memory.js +71 -0
  93. package/dist/daemon/routes/memory.js.map +1 -0
  94. package/dist/daemon/routes/reflection.d.ts +10 -0
  95. package/dist/daemon/routes/reflection.d.ts.map +1 -0
  96. package/dist/daemon/routes/reflection.js +397 -0
  97. package/dist/daemon/routes/reflection.js.map +1 -0
  98. package/dist/daemon/routes/search.d.ts +5 -0
  99. package/dist/daemon/routes/search.d.ts.map +1 -0
  100. package/dist/daemon/routes/search.js +93 -0
  101. package/dist/daemon/routes/search.js.map +1 -0
  102. package/dist/daemon/routes/sessions.d.ts +3 -0
  103. package/dist/daemon/routes/sessions.d.ts.map +1 -0
  104. package/dist/daemon/routes/sessions.js +160 -0
  105. package/dist/daemon/routes/sessions.js.map +1 -0
  106. package/dist/daemon/routes/skills.d.ts +3 -0
  107. package/dist/daemon/routes/skills.d.ts.map +1 -0
  108. package/dist/daemon/routes/skills.js +36 -0
  109. package/dist/daemon/routes/skills.js.map +1 -0
  110. package/dist/daemon/routes/status.d.ts +3 -0
  111. package/dist/daemon/routes/status.d.ts.map +1 -0
  112. package/dist/daemon/routes/status.js +47 -0
  113. package/dist/daemon/routes/status.js.map +1 -0
  114. package/dist/daemon/routes/types.d.ts +240 -0
  115. package/dist/daemon/routes/types.d.ts.map +1 -0
  116. package/dist/daemon/routes/types.js +97 -0
  117. package/dist/daemon/routes/types.js.map +1 -0
  118. package/dist/daemon/routes/versioning.d.ts +27 -0
  119. package/dist/daemon/routes/versioning.d.ts.map +1 -0
  120. package/dist/daemon/routes/versioning.js +44 -0
  121. package/dist/daemon/routes/versioning.js.map +1 -0
  122. package/dist/daemon/routes/watcher.d.ts +3 -0
  123. package/dist/daemon/routes/watcher.d.ts.map +1 -0
  124. package/dist/daemon/routes/watcher.js +28 -0
  125. package/dist/daemon/routes/watcher.js.map +1 -0
  126. package/dist/daemon/service.d.ts +5 -23
  127. package/dist/daemon/service.d.ts.map +1 -1
  128. package/dist/daemon/service.js +177 -935
  129. package/dist/daemon/service.js.map +1 -1
  130. package/dist/daemon/session-processor.d.ts +4 -8
  131. package/dist/daemon/session-processor.d.ts.map +1 -1
  132. package/dist/daemon/session-processor.js +39 -38
  133. package/dist/daemon/session-processor.js.map +1 -1
  134. package/dist/lib/ai-readiness.d.ts.map +1 -1
  135. package/dist/lib/ai-readiness.js +33 -8
  136. package/dist/lib/ai-readiness.js.map +1 -1
  137. package/dist/lib/analyze-state.d.ts.map +1 -1
  138. package/dist/lib/analyze-state.js +25 -3
  139. package/dist/lib/analyze-state.js.map +1 -1
  140. package/dist/lib/auto-memory/consolidation.d.ts +41 -0
  141. package/dist/lib/auto-memory/consolidation.d.ts.map +1 -0
  142. package/dist/lib/auto-memory/consolidation.js +151 -0
  143. package/dist/lib/auto-memory/consolidation.js.map +1 -0
  144. package/dist/lib/bpe.d.ts.map +1 -1
  145. package/dist/lib/bpe.js +9 -10
  146. package/dist/lib/bpe.js.map +1 -1
  147. package/dist/lib/brain-export.d.ts +65 -0
  148. package/dist/lib/brain-export.d.ts.map +1 -0
  149. package/dist/lib/brain-export.js +413 -0
  150. package/dist/lib/brain-export.js.map +1 -0
  151. package/dist/lib/checkpoint.d.ts.map +1 -1
  152. package/dist/lib/checkpoint.js +22 -6
  153. package/dist/lib/checkpoint.js.map +1 -1
  154. package/dist/lib/chunker.d.ts.map +1 -1
  155. package/dist/lib/chunker.js +6 -1
  156. package/dist/lib/chunker.js.map +1 -1
  157. package/dist/lib/claude-ws-transport.d.ts.map +1 -1
  158. package/dist/lib/claude-ws-transport.js +12 -4
  159. package/dist/lib/claude-ws-transport.js.map +1 -1
  160. package/dist/lib/command-safety.d.ts +64 -0
  161. package/dist/lib/command-safety.d.ts.map +1 -0
  162. package/dist/lib/command-safety.js +625 -0
  163. package/dist/lib/command-safety.js.map +1 -0
  164. package/dist/lib/compact-briefing.d.ts.map +1 -1
  165. package/dist/lib/compact-briefing.js +10 -13
  166. package/dist/lib/compact-briefing.js.map +1 -1
  167. package/dist/lib/config-defaults.d.ts.map +1 -1
  168. package/dist/lib/config-defaults.js +3 -0
  169. package/dist/lib/config-defaults.js.map +1 -1
  170. package/dist/lib/config-display.d.ts +4 -0
  171. package/dist/lib/config-display.d.ts.map +1 -1
  172. package/dist/lib/config-display.js +6 -1
  173. package/dist/lib/config-display.js.map +1 -1
  174. package/dist/lib/config-types.d.ts +149 -0
  175. package/dist/lib/config-types.d.ts.map +1 -1
  176. package/dist/lib/config-validation.d.ts.map +1 -1
  177. package/dist/lib/config-validation.js +5 -0
  178. package/dist/lib/config-validation.js.map +1 -1
  179. package/dist/lib/config.d.ts.map +1 -1
  180. package/dist/lib/config.js +92 -9
  181. package/dist/lib/config.js.map +1 -1
  182. package/dist/lib/consolidate.d.ts.map +1 -1
  183. package/dist/lib/consolidate.js +66 -47
  184. package/dist/lib/consolidate.js.map +1 -1
  185. package/dist/lib/content-sanitizer.d.ts +29 -0
  186. package/dist/lib/content-sanitizer.d.ts.map +1 -0
  187. package/dist/lib/content-sanitizer.js +72 -0
  188. package/dist/lib/content-sanitizer.js.map +1 -0
  189. package/dist/lib/cross-repo.d.ts +44 -0
  190. package/dist/lib/cross-repo.d.ts.map +1 -0
  191. package/dist/lib/cross-repo.js +108 -0
  192. package/dist/lib/cross-repo.js.map +1 -0
  193. package/dist/lib/daemon-port.d.ts +12 -0
  194. package/dist/lib/daemon-port.d.ts.map +1 -0
  195. package/dist/lib/daemon-port.js +20 -0
  196. package/dist/lib/daemon-port.js.map +1 -0
  197. package/dist/lib/db/auto-memory.d.ts +40 -0
  198. package/dist/lib/db/auto-memory.d.ts.map +1 -0
  199. package/dist/lib/db/auto-memory.js +74 -0
  200. package/dist/lib/db/auto-memory.js.map +1 -0
  201. package/dist/lib/db/bm25-indexes.d.ts.map +1 -1
  202. package/dist/lib/db/bm25-indexes.js +16 -4
  203. package/dist/lib/db/bm25-indexes.js.map +1 -1
  204. package/dist/lib/db/documents.d.ts.map +1 -1
  205. package/dist/lib/db/documents.js +4 -1
  206. package/dist/lib/db/documents.js.map +1 -1
  207. package/dist/lib/db/global-memories.d.ts +2 -10
  208. package/dist/lib/db/global-memories.d.ts.map +1 -1
  209. package/dist/lib/db/global-memories.js +13 -6
  210. package/dist/lib/db/global-memories.js.map +1 -1
  211. package/dist/lib/db/graph.d.ts +5 -1
  212. package/dist/lib/db/graph.d.ts.map +1 -1
  213. package/dist/lib/db/graph.js +38 -8
  214. package/dist/lib/db/graph.js.map +1 -1
  215. package/dist/lib/db/hybrid-search.d.ts +4 -2
  216. package/dist/lib/db/hybrid-search.d.ts.map +1 -1
  217. package/dist/lib/db/hybrid-search.js +29 -11
  218. package/dist/lib/db/hybrid-search.js.map +1 -1
  219. package/dist/lib/db/index.d.ts +6 -1
  220. package/dist/lib/db/index.d.ts.map +1 -1
  221. package/dist/lib/db/index.js +5 -1
  222. package/dist/lib/db/index.js.map +1 -1
  223. package/dist/lib/db/memories.d.ts +19 -14
  224. package/dist/lib/db/memories.d.ts.map +1 -1
  225. package/dist/lib/db/memories.js +100 -37
  226. package/dist/lib/db/memories.js.map +1 -1
  227. package/dist/lib/db/parse-helpers.d.ts +14 -0
  228. package/dist/lib/db/parse-helpers.d.ts.map +1 -0
  229. package/dist/lib/db/parse-helpers.js +59 -0
  230. package/dist/lib/db/parse-helpers.js.map +1 -0
  231. package/dist/lib/db/recall-events.d.ts +49 -0
  232. package/dist/lib/db/recall-events.d.ts.map +1 -0
  233. package/dist/lib/db/recall-events.js +196 -0
  234. package/dist/lib/db/recall-events.js.map +1 -0
  235. package/dist/lib/db/retention.d.ts +4 -3
  236. package/dist/lib/db/retention.d.ts.map +1 -1
  237. package/dist/lib/db/retention.js +12 -1
  238. package/dist/lib/db/retention.js.map +1 -1
  239. package/dist/lib/db/schema.d.ts +2 -0
  240. package/dist/lib/db/schema.d.ts.map +1 -1
  241. package/dist/lib/db/schema.js +140 -80
  242. package/dist/lib/db/schema.js.map +1 -1
  243. package/dist/lib/db/skills.d.ts.map +1 -1
  244. package/dist/lib/db/skills.js +10 -6
  245. package/dist/lib/db/skills.js.map +1 -1
  246. package/dist/lib/diff-brain.d.ts +24 -0
  247. package/dist/lib/diff-brain.d.ts.map +1 -0
  248. package/dist/lib/diff-brain.js +114 -0
  249. package/dist/lib/diff-brain.js.map +1 -0
  250. package/dist/lib/diff-parser.d.ts +74 -0
  251. package/dist/lib/diff-parser.d.ts.map +1 -0
  252. package/dist/lib/diff-parser.js +200 -0
  253. package/dist/lib/diff-parser.js.map +1 -0
  254. package/dist/lib/embedding-pool.d.ts.map +1 -1
  255. package/dist/lib/embedding-pool.js +5 -1
  256. package/dist/lib/embedding-pool.js.map +1 -1
  257. package/dist/lib/embeddings.d.ts +12 -0
  258. package/dist/lib/embeddings.d.ts.map +1 -1
  259. package/dist/lib/embeddings.js +77 -19
  260. package/dist/lib/embeddings.js.map +1 -1
  261. package/dist/lib/errors.d.ts +2 -0
  262. package/dist/lib/errors.d.ts.map +1 -1
  263. package/dist/lib/errors.js +4 -0
  264. package/dist/lib/errors.js.map +1 -1
  265. package/dist/lib/fault-logger.d.ts.map +1 -1
  266. package/dist/lib/fault-logger.js +22 -7
  267. package/dist/lib/fault-logger.js.map +1 -1
  268. package/dist/lib/git/co-change.d.ts +39 -0
  269. package/dist/lib/git/co-change.d.ts.map +1 -0
  270. package/dist/lib/git/co-change.js +139 -0
  271. package/dist/lib/git/co-change.js.map +1 -0
  272. package/dist/lib/graph/bridge-edges.d.ts +93 -0
  273. package/dist/lib/graph/bridge-edges.d.ts.map +1 -0
  274. package/dist/lib/graph/bridge-edges.js +276 -0
  275. package/dist/lib/graph/bridge-edges.js.map +1 -0
  276. package/dist/lib/graph/centrality.d.ts +11 -0
  277. package/dist/lib/graph/centrality.d.ts.map +1 -1
  278. package/dist/lib/graph/centrality.js +51 -3
  279. package/dist/lib/graph/centrality.js.map +1 -1
  280. package/dist/lib/graph/cleanup.d.ts.map +1 -1
  281. package/dist/lib/graph/cleanup.js +2 -1
  282. package/dist/lib/graph/cleanup.js.map +1 -1
  283. package/dist/lib/graph/community-detection.d.ts +17 -2
  284. package/dist/lib/graph/community-detection.d.ts.map +1 -1
  285. package/dist/lib/graph/community-detection.js +147 -48
  286. package/dist/lib/graph/community-detection.js.map +1 -1
  287. package/dist/lib/graph/community-summaries.d.ts +26 -0
  288. package/dist/lib/graph/community-summaries.d.ts.map +1 -0
  289. package/dist/lib/graph/community-summaries.js +130 -0
  290. package/dist/lib/graph/community-summaries.js.map +1 -0
  291. package/dist/lib/graph/contextual-proximity.d.ts.map +1 -1
  292. package/dist/lib/graph/contextual-proximity.js +11 -4
  293. package/dist/lib/graph/contextual-proximity.js.map +1 -1
  294. package/dist/lib/graph/graphology-bridge.d.ts +101 -0
  295. package/dist/lib/graph/graphology-bridge.d.ts.map +1 -0
  296. package/dist/lib/graph/graphology-bridge.js +488 -0
  297. package/dist/lib/graph/graphology-bridge.js.map +1 -0
  298. package/dist/lib/graph/llm-relations.d.ts.map +1 -1
  299. package/dist/lib/graph/llm-relations.js +27 -5
  300. package/dist/lib/graph/llm-relations.js.map +1 -1
  301. package/dist/lib/graph-export.d.ts.map +1 -1
  302. package/dist/lib/graph-export.js +2 -2
  303. package/dist/lib/graph-export.js.map +1 -1
  304. package/dist/lib/graph-scheduler.d.ts +0 -5
  305. package/dist/lib/graph-scheduler.d.ts.map +1 -1
  306. package/dist/lib/graph-scheduler.js +5 -1
  307. package/dist/lib/graph-scheduler.js.map +1 -1
  308. package/dist/lib/guardrails.d.ts +50 -0
  309. package/dist/lib/guardrails.d.ts.map +1 -0
  310. package/dist/lib/guardrails.js +502 -0
  311. package/dist/lib/guardrails.js.map +1 -0
  312. package/dist/lib/hook-rules.d.ts +1 -1
  313. package/dist/lib/hook-rules.d.ts.map +1 -1
  314. package/dist/lib/hook-rules.js +8 -2
  315. package/dist/lib/hook-rules.js.map +1 -1
  316. package/dist/lib/ifc/file-labels.d.ts +35 -0
  317. package/dist/lib/ifc/file-labels.d.ts.map +1 -0
  318. package/dist/lib/ifc/file-labels.js +208 -0
  319. package/dist/lib/ifc/file-labels.js.map +1 -0
  320. package/dist/lib/ifc/label.d.ts +38 -0
  321. package/dist/lib/ifc/label.d.ts.map +1 -0
  322. package/dist/lib/ifc/label.js +80 -0
  323. package/dist/lib/ifc/label.js.map +1 -0
  324. package/dist/lib/ifc/session-ifc.d.ts +92 -0
  325. package/dist/lib/ifc/session-ifc.d.ts.map +1 -0
  326. package/dist/lib/ifc/session-ifc.js +222 -0
  327. package/dist/lib/ifc/session-ifc.js.map +1 -0
  328. package/dist/lib/indexer.js +2 -2
  329. package/dist/lib/indexer.js.map +1 -1
  330. package/dist/lib/injection-detector.d.ts +83 -0
  331. package/dist/lib/injection-detector.d.ts.map +1 -0
  332. package/dist/lib/injection-detector.js +586 -0
  333. package/dist/lib/injection-detector.js.map +1 -0
  334. package/dist/lib/injection-semantic.d.ts +31 -0
  335. package/dist/lib/injection-semantic.d.ts.map +1 -0
  336. package/dist/lib/injection-semantic.js +230 -0
  337. package/dist/lib/injection-semantic.js.map +1 -0
  338. package/dist/lib/llm.d.ts.map +1 -1
  339. package/dist/lib/llm.js +19 -4
  340. package/dist/lib/llm.js.map +1 -1
  341. package/dist/lib/lock.d.ts.map +1 -1
  342. package/dist/lib/lock.js +24 -3
  343. package/dist/lib/lock.js.map +1 -1
  344. package/dist/lib/md-fetch.d.ts.map +1 -1
  345. package/dist/lib/md-fetch.js +9 -2
  346. package/dist/lib/md-fetch.js.map +1 -1
  347. package/dist/lib/observability.d.ts +75 -0
  348. package/dist/lib/observability.d.ts.map +1 -0
  349. package/dist/lib/observability.js +201 -0
  350. package/dist/lib/observability.js.map +1 -0
  351. package/dist/lib/ort-session.d.ts +26 -0
  352. package/dist/lib/ort-session.d.ts.map +1 -1
  353. package/dist/lib/ort-session.js +107 -3
  354. package/dist/lib/ort-session.js.map +1 -1
  355. package/dist/lib/prd/codebase-context.d.ts.map +1 -1
  356. package/dist/lib/prd/codebase-context.js +9 -2
  357. package/dist/lib/prd/codebase-context.js.map +1 -1
  358. package/dist/lib/prd/context.d.ts.map +1 -1
  359. package/dist/lib/prd/context.js +11 -3
  360. package/dist/lib/prd/context.js.map +1 -1
  361. package/dist/lib/prd/export.js +1 -1
  362. package/dist/lib/prd/export.js.map +1 -1
  363. package/dist/lib/prd/generate.d.ts.map +1 -1
  364. package/dist/lib/prd/generate.js +17 -4
  365. package/dist/lib/prd/generate.js.map +1 -1
  366. package/dist/lib/prd/parse.d.ts.map +1 -1
  367. package/dist/lib/prd/parse.js +6 -1
  368. package/dist/lib/prd/parse.js.map +1 -1
  369. package/dist/lib/prd/runner.d.ts +1 -2
  370. package/dist/lib/prd/runner.d.ts.map +1 -1
  371. package/dist/lib/prd/runner.js +43 -32
  372. package/dist/lib/prd/runner.js.map +1 -1
  373. package/dist/lib/prd/worktree.d.ts +1 -2
  374. package/dist/lib/prd/worktree.d.ts.map +1 -1
  375. package/dist/lib/prd/worktree.js +62 -70
  376. package/dist/lib/prd/worktree.js.map +1 -1
  377. package/dist/lib/precompute-context.d.ts.map +1 -1
  378. package/dist/lib/precompute-context.js +15 -34
  379. package/dist/lib/precompute-context.js.map +1 -1
  380. package/dist/lib/pricing.d.ts.map +1 -1
  381. package/dist/lib/pricing.js +5 -1
  382. package/dist/lib/pricing.js.map +1 -1
  383. package/dist/lib/process-registry.js +3 -3
  384. package/dist/lib/process-registry.js.map +1 -1
  385. package/dist/lib/public-api.d.ts +41 -1
  386. package/dist/lib/public-api.d.ts.map +1 -1
  387. package/dist/lib/public-api.js +38 -0
  388. package/dist/lib/public-api.js.map +1 -1
  389. package/dist/lib/quality.d.ts.map +1 -1
  390. package/dist/lib/quality.js +15 -6
  391. package/dist/lib/quality.js.map +1 -1
  392. package/dist/lib/query-expansion.d.ts +32 -0
  393. package/dist/lib/query-expansion.d.ts.map +1 -1
  394. package/dist/lib/query-expansion.js +62 -1
  395. package/dist/lib/query-expansion.js.map +1 -1
  396. package/dist/lib/reference-embeddings.d.ts.map +1 -1
  397. package/dist/lib/reference-embeddings.js +17 -4
  398. package/dist/lib/reference-embeddings.js.map +1 -1
  399. package/dist/lib/reflection-synthesizer.d.ts.map +1 -1
  400. package/dist/lib/reflection-synthesizer.js +7 -1
  401. package/dist/lib/reflection-synthesizer.js.map +1 -1
  402. package/dist/lib/reranker.d.ts +41 -0
  403. package/dist/lib/reranker.d.ts.map +1 -0
  404. package/dist/lib/reranker.js +294 -0
  405. package/dist/lib/reranker.js.map +1 -0
  406. package/dist/lib/retrieval-feedback.d.ts +100 -0
  407. package/dist/lib/retrieval-feedback.d.ts.map +1 -0
  408. package/dist/lib/retrieval-feedback.js +174 -0
  409. package/dist/lib/retrieval-feedback.js.map +1 -0
  410. package/dist/lib/review/context-pack.d.ts +58 -0
  411. package/dist/lib/review/context-pack.d.ts.map +1 -0
  412. package/dist/lib/review/context-pack.js +300 -0
  413. package/dist/lib/review/context-pack.js.map +1 -0
  414. package/dist/lib/search/hierarchical-summaries.d.ts +65 -0
  415. package/dist/lib/search/hierarchical-summaries.d.ts.map +1 -0
  416. package/dist/lib/search/hierarchical-summaries.js +423 -0
  417. package/dist/lib/search/hierarchical-summaries.js.map +1 -0
  418. package/dist/lib/search/hyde.d.ts +27 -0
  419. package/dist/lib/search/hyde.d.ts.map +1 -0
  420. package/dist/lib/search/hyde.js +141 -0
  421. package/dist/lib/search/hyde.js.map +1 -0
  422. package/dist/lib/search/late-chunking.d.ts +53 -0
  423. package/dist/lib/search/late-chunking.d.ts.map +1 -0
  424. package/dist/lib/search/late-chunking.js +230 -0
  425. package/dist/lib/search/late-chunking.js.map +1 -0
  426. package/dist/lib/search/ppr-retrieval.d.ts +49 -0
  427. package/dist/lib/search/ppr-retrieval.d.ts.map +1 -0
  428. package/dist/lib/search/ppr-retrieval.js +135 -0
  429. package/dist/lib/search/ppr-retrieval.js.map +1 -0
  430. package/dist/lib/search/repo-map.d.ts +43 -0
  431. package/dist/lib/search/repo-map.d.ts.map +1 -0
  432. package/dist/lib/search/repo-map.js +165 -0
  433. package/dist/lib/search/repo-map.js.map +1 -0
  434. package/dist/lib/session-analyzer.d.ts +90 -0
  435. package/dist/lib/session-analyzer.d.ts.map +1 -0
  436. package/dist/lib/session-analyzer.js +467 -0
  437. package/dist/lib/session-analyzer.js.map +1 -0
  438. package/dist/lib/session-observations.d.ts.map +1 -1
  439. package/dist/lib/session-observations.js +13 -3
  440. package/dist/lib/session-observations.js.map +1 -1
  441. package/dist/lib/session-summary.d.ts.map +1 -1
  442. package/dist/lib/session-summary.js +57 -50
  443. package/dist/lib/session-summary.js.map +1 -1
  444. package/dist/lib/session-surgeon.d.ts +53 -0
  445. package/dist/lib/session-surgeon.d.ts.map +1 -0
  446. package/dist/lib/session-surgeon.js +501 -0
  447. package/dist/lib/session-surgeon.js.map +1 -0
  448. package/dist/lib/similarity-utils.d.ts +26 -0
  449. package/dist/lib/similarity-utils.d.ts.map +1 -0
  450. package/dist/lib/similarity-utils.js +66 -0
  451. package/dist/lib/similarity-utils.js.map +1 -0
  452. package/dist/lib/skills.d.ts.map +1 -1
  453. package/dist/lib/skills.js +11 -11
  454. package/dist/lib/skills.js.map +1 -1
  455. package/dist/lib/storage/backends/interface.d.ts +13 -3
  456. package/dist/lib/storage/backends/interface.d.ts.map +1 -1
  457. package/dist/lib/storage/backends/postgresql.d.ts +52 -3
  458. package/dist/lib/storage/backends/postgresql.d.ts.map +1 -1
  459. package/dist/lib/storage/backends/postgresql.js +694 -49
  460. package/dist/lib/storage/backends/postgresql.js.map +1 -1
  461. package/dist/lib/storage/benchmark.js +2 -2
  462. package/dist/lib/storage/benchmark.js.map +1 -1
  463. package/dist/lib/storage/dispatcher/base.d.ts +114 -0
  464. package/dist/lib/storage/dispatcher/base.d.ts.map +1 -0
  465. package/dist/lib/storage/dispatcher/base.js +160 -0
  466. package/dist/lib/storage/dispatcher/base.js.map +1 -0
  467. package/dist/lib/storage/dispatcher/documents.d.ts +25 -0
  468. package/dist/lib/storage/dispatcher/documents.d.ts.map +1 -0
  469. package/dist/lib/storage/dispatcher/documents.js +194 -0
  470. package/dist/lib/storage/dispatcher/documents.js.map +1 -0
  471. package/dist/lib/storage/dispatcher/embeddings.d.ts +34 -0
  472. package/dist/lib/storage/dispatcher/embeddings.d.ts.map +1 -0
  473. package/dist/lib/storage/dispatcher/embeddings.js +144 -0
  474. package/dist/lib/storage/dispatcher/embeddings.js.map +1 -0
  475. package/dist/lib/storage/dispatcher/export-import.d.ts +139 -0
  476. package/dist/lib/storage/dispatcher/export-import.d.ts.map +1 -0
  477. package/dist/lib/storage/dispatcher/export-import.js +191 -0
  478. package/dist/lib/storage/dispatcher/export-import.js.map +1 -0
  479. package/dist/lib/storage/dispatcher/file-hashes.d.ts +13 -0
  480. package/dist/lib/storage/dispatcher/file-hashes.d.ts.map +1 -0
  481. package/dist/lib/storage/dispatcher/file-hashes.js +36 -0
  482. package/dist/lib/storage/dispatcher/file-hashes.js.map +1 -0
  483. package/dist/lib/storage/dispatcher/global-memories.d.ts +28 -0
  484. package/dist/lib/storage/dispatcher/global-memories.d.ts.map +1 -0
  485. package/dist/lib/storage/dispatcher/global-memories.js +151 -0
  486. package/dist/lib/storage/dispatcher/global-memories.js.map +1 -0
  487. package/dist/lib/storage/dispatcher/graph.d.ts +32 -0
  488. package/dist/lib/storage/dispatcher/graph.d.ts.map +1 -0
  489. package/dist/lib/storage/dispatcher/graph.js +146 -0
  490. package/dist/lib/storage/dispatcher/graph.js.map +1 -0
  491. package/dist/lib/storage/dispatcher/index.d.ts +34 -0
  492. package/dist/lib/storage/dispatcher/index.d.ts.map +1 -0
  493. package/dist/lib/storage/dispatcher/index.js +139 -0
  494. package/dist/lib/storage/dispatcher/index.js.map +1 -0
  495. package/dist/lib/storage/dispatcher/memories.d.ts +65 -0
  496. package/dist/lib/storage/dispatcher/memories.d.ts.map +1 -0
  497. package/dist/lib/storage/dispatcher/memories.js +466 -0
  498. package/dist/lib/storage/dispatcher/memories.js.map +1 -0
  499. package/dist/lib/storage/dispatcher/mixin-helper.d.ts +6 -0
  500. package/dist/lib/storage/dispatcher/mixin-helper.d.ts.map +1 -0
  501. package/dist/lib/storage/dispatcher/mixin-helper.js +10 -0
  502. package/dist/lib/storage/dispatcher/mixin-helper.js.map +1 -0
  503. package/dist/lib/storage/dispatcher/retention.d.ts +20 -0
  504. package/dist/lib/storage/dispatcher/retention.d.ts.map +1 -0
  505. package/dist/lib/storage/dispatcher/retention.js +123 -0
  506. package/dist/lib/storage/dispatcher/retention.js.map +1 -0
  507. package/dist/lib/storage/dispatcher/search.d.ts +34 -0
  508. package/dist/lib/storage/dispatcher/search.d.ts.map +1 -0
  509. package/dist/lib/storage/dispatcher/search.js +222 -0
  510. package/dist/lib/storage/dispatcher/search.js.map +1 -0
  511. package/dist/lib/storage/dispatcher/skills.d.ts +53 -0
  512. package/dist/lib/storage/dispatcher/skills.d.ts.map +1 -0
  513. package/dist/lib/storage/dispatcher/skills.js +98 -0
  514. package/dist/lib/storage/dispatcher/skills.js.map +1 -0
  515. package/dist/lib/storage/dispatcher/token-stats.d.ts +23 -0
  516. package/dist/lib/storage/dispatcher/token-stats.d.ts.map +1 -0
  517. package/dist/lib/storage/dispatcher/token-stats.js +92 -0
  518. package/dist/lib/storage/dispatcher/token-stats.js.map +1 -0
  519. package/dist/lib/storage/dispatcher/web-search.d.ts +10 -0
  520. package/dist/lib/storage/dispatcher/web-search.d.ts.map +1 -0
  521. package/dist/lib/storage/dispatcher/web-search.js +39 -0
  522. package/dist/lib/storage/dispatcher/web-search.js.map +1 -0
  523. package/dist/lib/storage/dispatcher-export.d.ts.map +1 -1
  524. package/dist/lib/storage/dispatcher-export.js +48 -39
  525. package/dist/lib/storage/dispatcher-export.js.map +1 -1
  526. package/dist/lib/storage/dispatcher.d.ts +1 -468
  527. package/dist/lib/storage/dispatcher.d.ts.map +1 -1
  528. package/dist/lib/storage/dispatcher.js +1 -1931
  529. package/dist/lib/storage/dispatcher.js.map +1 -1
  530. package/dist/lib/storage/index.d.ts +20 -5
  531. package/dist/lib/storage/index.d.ts.map +1 -1
  532. package/dist/lib/storage/index.js +36 -7
  533. package/dist/lib/storage/index.js.map +1 -1
  534. package/dist/lib/storage/migration/export-import.d.ts.map +1 -1
  535. package/dist/lib/storage/migration/export-import.js +9 -2
  536. package/dist/lib/storage/migration/export-import.js.map +1 -1
  537. package/dist/lib/storage/types.d.ts +152 -10
  538. package/dist/lib/storage/types.d.ts.map +1 -1
  539. package/dist/lib/storage/types.js +13 -0
  540. package/dist/lib/storage/types.js.map +1 -1
  541. package/dist/lib/storage/vector/interface.d.ts +4 -0
  542. package/dist/lib/storage/vector/interface.d.ts.map +1 -1
  543. package/dist/lib/storage/vector/qdrant.d.ts +13 -2
  544. package/dist/lib/storage/vector/qdrant.d.ts.map +1 -1
  545. package/dist/lib/storage/vector/qdrant.js +147 -61
  546. package/dist/lib/storage/vector/qdrant.js.map +1 -1
  547. package/dist/lib/token-budget.d.ts.map +1 -1
  548. package/dist/lib/token-budget.js +9 -2
  549. package/dist/lib/token-budget.js.map +1 -1
  550. package/dist/lib/transcript-utils.d.ts +60 -0
  551. package/dist/lib/transcript-utils.d.ts.map +1 -0
  552. package/dist/lib/transcript-utils.js +69 -0
  553. package/dist/lib/transcript-utils.js.map +1 -0
  554. package/dist/lib/tree-sitter/extractor.d.ts +1 -1
  555. package/dist/lib/tree-sitter/extractor.d.ts.map +1 -1
  556. package/dist/lib/tree-sitter/extractor.js +34 -9
  557. package/dist/lib/tree-sitter/extractor.js.map +1 -1
  558. package/dist/lib/tree-sitter/parser.d.ts.map +1 -1
  559. package/dist/lib/tree-sitter/parser.js +45 -11
  560. package/dist/lib/tree-sitter/parser.js.map +1 -1
  561. package/dist/lib/tree-sitter/public.d.ts +12 -0
  562. package/dist/lib/tree-sitter/public.d.ts.map +1 -1
  563. package/dist/lib/tree-sitter/public.js +33 -1
  564. package/dist/lib/tree-sitter/public.js.map +1 -1
  565. package/dist/lib/tree-sitter/queries.d.ts.map +1 -1
  566. package/dist/lib/tree-sitter/queries.js +8 -0
  567. package/dist/lib/tree-sitter/queries.js.map +1 -1
  568. package/dist/lib/working-memory-pipeline.d.ts.map +1 -1
  569. package/dist/lib/working-memory-pipeline.js +12 -3
  570. package/dist/lib/working-memory-pipeline.js.map +1 -1
  571. package/dist/lib/worktree-detect.d.ts +43 -0
  572. package/dist/lib/worktree-detect.d.ts.map +1 -0
  573. package/dist/lib/worktree-detect.js +154 -0
  574. package/dist/lib/worktree-detect.js.map +1 -0
  575. package/dist/lsp/client.d.ts +96 -0
  576. package/dist/lsp/client.d.ts.map +1 -0
  577. package/dist/lsp/client.js +435 -0
  578. package/dist/lsp/client.js.map +1 -0
  579. package/dist/lsp/installer.d.ts +39 -0
  580. package/dist/lsp/installer.d.ts.map +1 -0
  581. package/dist/lsp/installer.js +275 -0
  582. package/dist/lsp/installer.js.map +1 -0
  583. package/dist/lsp/manager.d.ts +62 -0
  584. package/dist/lsp/manager.d.ts.map +1 -0
  585. package/dist/lsp/manager.js +234 -0
  586. package/dist/lsp/manager.js.map +1 -0
  587. package/dist/lsp/servers.d.ts +52 -0
  588. package/dist/lsp/servers.d.ts.map +1 -0
  589. package/dist/lsp/servers.js +162 -0
  590. package/dist/lsp/servers.js.map +1 -0
  591. package/dist/mcp/helpers.d.ts.map +1 -1
  592. package/dist/mcp/helpers.js +8 -2
  593. package/dist/mcp/helpers.js.map +1 -1
  594. package/dist/mcp/profile.js +1 -1
  595. package/dist/mcp/server.d.ts +3 -2
  596. package/dist/mcp/server.d.ts.map +1 -1
  597. package/dist/mcp/server.js +19 -7
  598. package/dist/mcp/server.js.map +1 -1
  599. package/dist/mcp/tools/config.d.ts.map +1 -1
  600. package/dist/mcp/tools/config.js +28 -118
  601. package/dist/mcp/tools/config.js.map +1 -1
  602. package/dist/mcp/tools/dead-end.d.ts.map +1 -1
  603. package/dist/mcp/tools/dead-end.js +4 -3
  604. package/dist/mcp/tools/dead-end.js.map +1 -1
  605. package/dist/mcp/tools/debug.d.ts.map +1 -1
  606. package/dist/mcp/tools/debug.js +27 -112
  607. package/dist/mcp/tools/debug.js.map +1 -1
  608. package/dist/mcp/tools/graph.d.ts.map +1 -1
  609. package/dist/mcp/tools/graph.js +164 -176
  610. package/dist/mcp/tools/graph.js.map +1 -1
  611. package/dist/mcp/tools/indexing.d.ts +1 -1
  612. package/dist/mcp/tools/indexing.d.ts.map +1 -1
  613. package/dist/mcp/tools/indexing.js +63 -164
  614. package/dist/mcp/tools/indexing.js.map +1 -1
  615. package/dist/mcp/tools/memory/forget.d.ts +3 -0
  616. package/dist/mcp/tools/memory/forget.d.ts.map +1 -0
  617. package/dist/mcp/tools/memory/forget.js +175 -0
  618. package/dist/mcp/tools/memory/forget.js.map +1 -0
  619. package/dist/mcp/tools/memory/memory-helpers.d.ts +45 -0
  620. package/dist/mcp/tools/memory/memory-helpers.d.ts.map +1 -0
  621. package/dist/mcp/tools/memory/memory-helpers.js +291 -0
  622. package/dist/mcp/tools/memory/memory-helpers.js.map +1 -0
  623. package/dist/mcp/tools/memory/recall.d.ts +3 -0
  624. package/dist/mcp/tools/memory/recall.d.ts.map +1 -0
  625. package/dist/mcp/tools/memory/recall.js +495 -0
  626. package/dist/mcp/tools/memory/recall.js.map +1 -0
  627. package/dist/mcp/tools/memory/remember.d.ts +3 -0
  628. package/dist/mcp/tools/memory/remember.d.ts.map +1 -0
  629. package/dist/mcp/tools/memory/remember.js +256 -0
  630. package/dist/mcp/tools/memory/remember.js.map +1 -0
  631. package/dist/mcp/tools/memory/temporal-query.d.ts +8 -0
  632. package/dist/mcp/tools/memory/temporal-query.d.ts.map +1 -0
  633. package/dist/mcp/tools/memory/temporal-query.js +68 -0
  634. package/dist/mcp/tools/memory/temporal-query.js.map +1 -0
  635. package/dist/mcp/tools/memory.d.ts +0 -11
  636. package/dist/mcp/tools/memory.d.ts.map +1 -1
  637. package/dist/mcp/tools/memory.js +6 -1228
  638. package/dist/mcp/tools/memory.js.map +1 -1
  639. package/dist/mcp/tools/prd.d.ts.map +1 -1
  640. package/dist/mcp/tools/prd.js +19 -70
  641. package/dist/mcp/tools/prd.js.map +1 -1
  642. package/dist/mcp/tools/review.d.ts +8 -0
  643. package/dist/mcp/tools/review.d.ts.map +1 -0
  644. package/dist/mcp/tools/review.js +133 -0
  645. package/dist/mcp/tools/review.js.map +1 -0
  646. package/dist/mcp/tools/search.d.ts.map +1 -1
  647. package/dist/mcp/tools/search.js +79 -8
  648. package/dist/mcp/tools/search.js.map +1 -1
  649. package/dist/mcp/tools/status.d.ts.map +1 -1
  650. package/dist/mcp/tools/status.js +34 -75
  651. package/dist/mcp/tools/status.js.map +1 -1
  652. package/dist/mcp/tools/web-fetch.d.ts.map +1 -1
  653. package/dist/mcp/tools/web-fetch.js +5 -1
  654. package/dist/mcp/tools/web-fetch.js.map +1 -1
  655. package/dist/mcp/tools/web-search.d.ts.map +1 -1
  656. package/dist/mcp/tools/web-search.js +25 -103
  657. package/dist/mcp/tools/web-search.js.map +1 -1
  658. package/dist/prompts/guardrails.d.ts +14 -0
  659. package/dist/prompts/guardrails.d.ts.map +1 -0
  660. package/dist/prompts/guardrails.js +115 -0
  661. package/dist/prompts/guardrails.js.map +1 -0
  662. package/dist/prompts/index.d.ts +2 -1
  663. package/dist/prompts/index.d.ts.map +1 -1
  664. package/dist/prompts/index.js +3 -1
  665. package/dist/prompts/index.js.map +1 -1
  666. package/dist/prompts/prd.d.ts +0 -2
  667. package/dist/prompts/prd.d.ts.map +1 -1
  668. package/dist/prompts/prd.js +0 -2
  669. package/dist/prompts/prd.js.map +1 -1
  670. package/hooks/core/__tests__/adapter.test.cjs +340 -0
  671. package/hooks/core/adapter.cjs +463 -0
  672. package/hooks/core/config.cjs +83 -0
  673. package/hooks/core/daemon-boot.cjs +140 -0
  674. package/hooks/core/log.cjs +41 -0
  675. package/hooks/core/worktree.cjs +119 -0
  676. package/hooks/succ-post-tool.cjs +198 -134
  677. package/hooks/succ-pre-compact.cjs +262 -0
  678. package/hooks/succ-pre-tool.cjs +526 -182
  679. package/hooks/succ-session-end.cjs +40 -64
  680. package/hooks/succ-session-start.cjs +484 -430
  681. package/hooks/succ-stop-reflection.cjs +36 -62
  682. package/hooks/succ-user-prompt.cjs +137 -180
  683. package/package.json +17 -6
@@ -0,0 +1,208 @@
1
+ /**
2
+ * File Label Assignment — 4-layer label resolution for BLP IFC
3
+ *
4
+ * Assigns SecurityLabels to files using conservative (highest wins) layering:
5
+ * 1. Extension-based (deterministic, instant)
6
+ * 2. Path-based (deterministic, instant)
7
+ * 3. Content-based regex (deterministic, requires file content)
8
+ * 4. LLM classification (Phase 3, opt-in)
9
+ *
10
+ * Label assignment is monotonic — higher label always wins.
11
+ */
12
+ import { makeLabel, join, BOTTOM, } from './label.js';
13
+ const EXTENSION_RULES = [
14
+ // Highly confidential: private keys and certs
15
+ {
16
+ extensions: ['.pem', '.key', '.p12', '.pfx', '.jks', '.keystore'],
17
+ label: makeLabel(3, ['credentials']),
18
+ },
19
+ // Confidential: environment files with secrets
20
+ {
21
+ extensions: ['.env', '.env.local', '.env.production', '.env.staging', '.env.development'],
22
+ label: makeLabel(2, ['secrets', 'credentials']),
23
+ },
24
+ // Internal: config files that may contain infrastructure info
25
+ {
26
+ extensions: ['.htpasswd', '.htaccess'],
27
+ label: makeLabel(2, ['credentials']),
28
+ },
29
+ // Public: documentation
30
+ {
31
+ extensions: ['.md', '.txt', '.rst', '.adoc'],
32
+ label: BOTTOM,
33
+ },
34
+ ];
35
+ function labelByExtension(filePath) {
36
+ const lower = filePath.toLowerCase().replace(/\\/g, '/');
37
+ const basename = lower.split('/').pop() || '';
38
+ // Check full basename match first (for .env, .env.local, .env.production, etc.)
39
+ for (const rule of EXTENSION_RULES) {
40
+ for (const ext of rule.extensions) {
41
+ const name = ext.slice(1); // e.g. "env", "env.local", "pem"
42
+ // Exact match: ".env" → basename ".env"
43
+ if (basename === ext || basename === name) {
44
+ return rule.label;
45
+ }
46
+ // Prefix match: ".env" rule matches ".env.production", ".env.staging", etc.
47
+ // But NOT env.sh, env.py, etc. — only .env.* or bare env files
48
+ if (ext === '.env' && basename.startsWith('.env.')) {
49
+ return rule.label;
50
+ }
51
+ // Match bare "env" followed by dot-separated qualifiers (env.local, env.production)
52
+ // but NOT env.sh, env.py, env.ts, etc. (script files)
53
+ if (ext === '.env' && basename.startsWith('env.')) {
54
+ const afterEnvDot = basename.slice(4); // after "env."
55
+ // If it looks like a file extension (2-4 chars, common code ext), skip
56
+ if (/^(?:sh|py|ts|js|rb|go|rs|pl|bat|cmd|ps1|php|java|c|h|cpp)$/i.test(afterEnvDot)) {
57
+ // Not an env config file — skip
58
+ }
59
+ else {
60
+ return rule.label;
61
+ }
62
+ }
63
+ }
64
+ }
65
+ // Check all extensions in compound filenames (e.g., "backup.pem.bak" → check ".bak", ".pem")
66
+ // This ensures security-sensitive inner extensions aren't missed when outer extension differs
67
+ let compoundLabel = BOTTOM;
68
+ let remaining = basename;
69
+ while (true) {
70
+ const dotIdx = remaining.lastIndexOf('.');
71
+ if (dotIdx < 0)
72
+ break;
73
+ const ext = remaining.slice(dotIdx);
74
+ for (const rule of EXTENSION_RULES) {
75
+ if (rule.extensions.includes(ext)) {
76
+ compoundLabel = join(compoundLabel, rule.label);
77
+ }
78
+ }
79
+ remaining = remaining.slice(0, dotIdx);
80
+ }
81
+ return compoundLabel;
82
+ }
83
+ const PATH_RULES = [
84
+ // Secrets directories
85
+ { pattern: /[/\\]secrets?[/\\]/i, label: makeLabel(3, ['secrets']) },
86
+ { pattern: /[/\\]\.ssh[/\\]/i, label: makeLabel(3, ['credentials']) },
87
+ { pattern: /[/\\]\.gnupg[/\\]/i, label: makeLabel(3, ['credentials']) },
88
+ { pattern: /[/\\]private[/\\]/i, label: makeLabel(2, ['credentials']) },
89
+ // Infrastructure
90
+ { pattern: /[/\\]deploy[/\\]/i, label: makeLabel(2, ['internal_infra']) },
91
+ { pattern: /[/\\]infrastructure[/\\]/i, label: makeLabel(2, ['internal_infra']) },
92
+ { pattern: /[/\\]terraform[/\\]/i, label: makeLabel(2, ['internal_infra']) },
93
+ { pattern: /[/\\]k8s[/\\]/i, label: makeLabel(2, ['internal_infra']) },
94
+ { pattern: /[/\\]kubernetes[/\\]/i, label: makeLabel(2, ['internal_infra']) },
95
+ { pattern: /[/\\]ansible[/\\]/i, label: makeLabel(2, ['internal_infra']) },
96
+ // CI/CD configs (may contain deployment secrets)
97
+ { pattern: /[/\\]\.github[/\\]workflows[/\\]/i, label: makeLabel(1, ['internal_infra']) },
98
+ { pattern: /[/\\]\.gitlab-ci\.yml$/i, label: makeLabel(1, ['internal_infra']) },
99
+ { pattern: /[/\\]\.circleci[/\\]/i, label: makeLabel(1, ['internal_infra']) },
100
+ // Skip: node_modules, .git internals — not sensitive per se
101
+ { pattern: /[/\\]node_modules[/\\]/i, label: BOTTOM },
102
+ { pattern: /[/\\]\.git[/\\]/i, label: makeLabel(1) },
103
+ ];
104
+ function labelByPath(filePath) {
105
+ let normalized = filePath.replace(/\\/g, '/');
106
+ // Ensure repo-relative paths (e.g., "secrets/key.pem") match PATH_RULES that require /dir/ delimiters
107
+ if (!normalized.startsWith('/')) {
108
+ normalized = '/' + normalized;
109
+ }
110
+ let result = BOTTOM;
111
+ for (const rule of PATH_RULES) {
112
+ if (rule.pattern.test(normalized)) {
113
+ result = join(result, rule.label);
114
+ }
115
+ }
116
+ return result;
117
+ }
118
+ const CONTENT_PATTERNS = [
119
+ // API keys / tokens (→ secrets)
120
+ { pattern: /sk-(?:proj-)?[a-zA-Z0-9]{20,}/, compartments: ['secrets'], level: 3 },
121
+ { pattern: /sk-ant-[a-zA-Z0-9-]{20,}/, compartments: ['secrets'], level: 3 },
122
+ { pattern: /AKIA[0-9A-Z]{16}/, compartments: ['secrets'], level: 3 },
123
+ { pattern: /gh[pousr]_[a-zA-Z0-9]{36}/, compartments: ['secrets'], level: 3 },
124
+ { pattern: /github_pat_[a-zA-Z0-9]{22,}/, compartments: ['secrets'], level: 3 },
125
+ { pattern: /glpat-[a-zA-Z0-9-]{20,}/, compartments: ['secrets'], level: 3 },
126
+ {
127
+ pattern: /xox[baprs]-[0-9]{10,13}-[0-9]{10,13}-[a-zA-Z0-9]{24}/,
128
+ compartments: ['secrets'],
129
+ level: 3,
130
+ },
131
+ {
132
+ pattern: /eyJ[a-zA-Z0-9_-]*\.eyJ[a-zA-Z0-9_-]*\.[a-zA-Z0-9_-]*/,
133
+ compartments: ['secrets'],
134
+ level: 2,
135
+ },
136
+ // Private keys (→ credentials)
137
+ {
138
+ pattern: /-----BEGIN (?:RSA |EC |DSA |OPENSSH )?PRIVATE KEY-----/,
139
+ compartments: ['credentials'],
140
+ level: 3,
141
+ },
142
+ // Password assignments (→ secrets)
143
+ {
144
+ pattern: /(?:password|passwd|secret|api_key)\s*[:=]\s*['"][^'"]{8,}['"]/,
145
+ compartments: ['secrets'],
146
+ level: 2,
147
+ },
148
+ // Connection strings (→ credentials + internal_infra)
149
+ {
150
+ pattern: /(?:postgres|mysql|mongodb|redis):\/\/[^:]+:[^@]+@/,
151
+ compartments: ['credentials', 'internal_infra'],
152
+ level: 2,
153
+ },
154
+ // PII patterns
155
+ { pattern: /\b\d{3}-\d{2}-\d{4}\b/, compartments: ['pii'], level: 2 }, // SSN
156
+ { pattern: /\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z]{2,}\b/i, compartments: ['pii'], level: 1 }, // Email (low level — very common)
157
+ // Internal infrastructure markers
158
+ {
159
+ pattern: /(?:10\.\d{1,3}\.\d{1,3}\.\d{1,3}|172\.(?:1[6-9]|2\d|3[01])\.\d{1,3}\.\d{1,3}|192\.168\.\d{1,3}\.\d{1,3})/,
160
+ compartments: ['internal_infra'],
161
+ level: 1,
162
+ },
163
+ ];
164
+ /**
165
+ * Scan file content for sensitive patterns and return accumulated label.
166
+ * Short-circuits if content is empty.
167
+ */
168
+ export function labelByContent(content) {
169
+ if (!content || content.length === 0)
170
+ return BOTTOM;
171
+ let result = BOTTOM;
172
+ for (const { pattern, compartments, level } of CONTENT_PATTERNS) {
173
+ if (pattern.test(content)) {
174
+ result = join(result, makeLabel(level, compartments));
175
+ }
176
+ }
177
+ return result;
178
+ }
179
+ /**
180
+ * Resolve the security label for a file using 3 deterministic layers.
181
+ * Returns the join (LUB) of all applicable labels.
182
+ *
183
+ * Layer 4 (LLM classification) is handled externally in Phase 3.
184
+ */
185
+ export function resolveFileLabel(filePath, options = {}) {
186
+ // Normalize relative paths to have path separators for path-based rules
187
+ const normalizedPath = filePath.includes('/') || filePath.includes('\\') ? filePath : './' + filePath;
188
+ let result = BOTTOM;
189
+ // Layer 1: Extension
190
+ result = join(result, labelByExtension(normalizedPath));
191
+ // Layer 2: Path
192
+ result = join(result, labelByPath(normalizedPath));
193
+ // Layer 3: Content (if provided)
194
+ if (options.content) {
195
+ result = join(result, labelByContent(options.content));
196
+ }
197
+ return result;
198
+ }
199
+ /**
200
+ * Quick label check — extension + path only (no content scan).
201
+ * Use for pre-tool checks where content isn't available yet.
202
+ */
203
+ export function quickFileLabel(filePath) {
204
+ return join(labelByExtension(filePath), labelByPath(filePath));
205
+ }
206
+ // Re-export for convenience
207
+ export { BOTTOM, makeLabel, join, isBottom, } from './label.js';
208
+ //# sourceMappingURL=file-labels.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-labels.js","sourceRoot":"","sources":["../../../src/lib/ifc/file-labels.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Bell-LaPadula Security Label Lattice
3
+ *
4
+ * Full BLP model with compartments:
5
+ * - SecurityLevel: 0=public, 1=internal, 2=confidential, 3=highly_confidential
6
+ * - Compartments: secrets, credentials, pii, internal_infra
7
+ * - Lattice operations: join (LUB), dominates, isBottom, isComparable
8
+ *
9
+ * Label rules:
10
+ * - Labels only go UP (weak tranquility)
11
+ * - join(a, b) = max level + union compartments
12
+ * - dominates(a, b) = a.level >= b.level AND a.compartments ⊇ b.compartments
13
+ */
14
+ export type SecurityLevel = 0 | 1 | 2 | 3;
15
+ export declare const LEVEL_NAMES: Record<SecurityLevel, string>;
16
+ export type Compartment = 'secrets' | 'credentials' | 'pii' | 'internal_infra';
17
+ export declare const ALL_COMPARTMENTS: readonly Compartment[];
18
+ export interface SecurityLabel {
19
+ readonly level: SecurityLevel;
20
+ readonly compartments: ReadonlySet<Compartment>;
21
+ }
22
+ /** The bottom of the lattice — no classification, no compartments */
23
+ export declare const BOTTOM: SecurityLabel;
24
+ /** Create a label */
25
+ export declare function makeLabel(level: SecurityLevel, compartments?: Compartment[]): SecurityLabel;
26
+ /** Least Upper Bound — max level, union of compartments */
27
+ export declare function join(a: SecurityLabel, b: SecurityLabel): SecurityLabel;
28
+ /** Does `a` dominate `b`? (a.level >= b.level AND a.compartments ⊇ b.compartments) */
29
+ export declare function dominates(a: SecurityLabel, b: SecurityLabel): boolean;
30
+ /** Is label at the bottom of the lattice? */
31
+ export declare function isBottom(label: SecurityLabel): boolean;
32
+ /** Are two labels comparable? (one dominates the other) */
33
+ export declare function isComparable(a: SecurityLabel, b: SecurityLabel): boolean;
34
+ /** Are two labels equal? */
35
+ export declare function labelsEqual(a: SecurityLabel, b: SecurityLabel): boolean;
36
+ /** Format label for display */
37
+ export declare function formatLabel(label: SecurityLabel): string;
38
+ //# sourceMappingURL=label.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.d.ts","sourceRoot":"","sources":["../../../src/lib/ifc/label.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AAEH,MAAM,MAAM,aAAa,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;AAE1C,eAAO,MAAM,WAAW,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAKrD,CAAC;AAEF,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,aAAa,GAAG,KAAK,GAAG,gBAAgB,CAAC;AAE/E,eAAO,MAAM,gBAAgB,EAAE,SAAS,WAAW,EAKzC,CAAC;AAEX,MAAM,WAAW,aAAa;IAC5B,QAAQ,CAAC,KAAK,EAAE,aAAa,CAAC;IAC9B,QAAQ,CAAC,YAAY,EAAE,WAAW,CAAC,WAAW,CAAC,CAAC;CACjD;AAED,qEAAqE;AACrE,eAAO,MAAM,MAAM,EAAE,aAGF,CAAC;AAEpB,qBAAqB;AACrB,wBAAgB,SAAS,CAAC,KAAK,EAAE,aAAa,EAAE,YAAY,GAAE,WAAW,EAAO,GAAG,aAAa,CAK/F;AAED,2DAA2D;AAC3D,wBAAgB,IAAI,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,aAAa,CAItE;AAED,sFAAsF;AACtF,wBAAgB,SAAS,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAMrE;AAED,6CAA6C;AAC7C,wBAAgB,QAAQ,CAAC,KAAK,EAAE,aAAa,GAAG,OAAO,CAEtD;AAED,2DAA2D;AAC3D,wBAAgB,YAAY,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAExE;AAED,4BAA4B;AAC5B,wBAAgB,WAAW,CAAC,CAAC,EAAE,aAAa,EAAE,CAAC,EAAE,aAAa,GAAG,OAAO,CAOvE;AAED,+BAA+B;AAC/B,wBAAgB,WAAW,CAAC,KAAK,EAAE,aAAa,GAAG,MAAM,CAIxD"}
@@ -0,0 +1,80 @@
1
+ /**
2
+ * Bell-LaPadula Security Label Lattice
3
+ *
4
+ * Full BLP model with compartments:
5
+ * - SecurityLevel: 0=public, 1=internal, 2=confidential, 3=highly_confidential
6
+ * - Compartments: secrets, credentials, pii, internal_infra
7
+ * - Lattice operations: join (LUB), dominates, isBottom, isComparable
8
+ *
9
+ * Label rules:
10
+ * - Labels only go UP (weak tranquility)
11
+ * - join(a, b) = max level + union compartments
12
+ * - dominates(a, b) = a.level >= b.level AND a.compartments ⊇ b.compartments
13
+ */
14
+ export const LEVEL_NAMES = {
15
+ 0: 'public',
16
+ 1: 'internal',
17
+ 2: 'confidential',
18
+ 3: 'highly_confidential',
19
+ };
20
+ export const ALL_COMPARTMENTS = [
21
+ 'secrets',
22
+ 'credentials',
23
+ 'pii',
24
+ 'internal_infra',
25
+ ];
26
+ /** The bottom of the lattice — no classification, no compartments */
27
+ export const BOTTOM = Object.freeze({
28
+ level: 0,
29
+ compartments: Object.freeze(new Set()),
30
+ });
31
+ /** Create a label */
32
+ export function makeLabel(level, compartments = []) {
33
+ return {
34
+ level,
35
+ compartments: new Set(compartments),
36
+ };
37
+ }
38
+ /** Least Upper Bound — max level, union of compartments */
39
+ export function join(a, b) {
40
+ const level = Math.max(a.level, b.level);
41
+ const compartments = new Set([...a.compartments, ...b.compartments]);
42
+ return { level, compartments };
43
+ }
44
+ /** Does `a` dominate `b`? (a.level >= b.level AND a.compartments ⊇ b.compartments) */
45
+ export function dominates(a, b) {
46
+ if (a.level < b.level)
47
+ return false;
48
+ for (const c of b.compartments) {
49
+ if (!a.compartments.has(c))
50
+ return false;
51
+ }
52
+ return true;
53
+ }
54
+ /** Is label at the bottom of the lattice? */
55
+ export function isBottom(label) {
56
+ return label.level === 0 && label.compartments.size === 0;
57
+ }
58
+ /** Are two labels comparable? (one dominates the other) */
59
+ export function isComparable(a, b) {
60
+ return dominates(a, b) || dominates(b, a);
61
+ }
62
+ /** Are two labels equal? */
63
+ export function labelsEqual(a, b) {
64
+ if (a.level !== b.level)
65
+ return false;
66
+ if (a.compartments.size !== b.compartments.size)
67
+ return false;
68
+ for (const c of a.compartments) {
69
+ if (!b.compartments.has(c))
70
+ return false;
71
+ }
72
+ return true;
73
+ }
74
+ /** Format label for display */
75
+ export function formatLabel(label) {
76
+ const level = LEVEL_NAMES[label.level];
77
+ const comps = [...label.compartments].sort().join(', ');
78
+ return comps ? `${level} {${comps}}` : level;
79
+ }
80
+ //# sourceMappingURL=label.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"label.js","sourceRoot":"","sources":["../../../src/lib/ifc/label.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Session IFC State — Bell-LaPadula enforcement per session
3
+ *
4
+ * Tracks the security high-water mark for each session:
5
+ * - Labels only go UP (weak tranquility / monotonic)
6
+ * - Taints accumulate and never clear
7
+ * - Outbound operations are checked against *-property (no write down)
8
+ * - Users can grant one-shot trusted-subject escalations
9
+ *
10
+ * State is in-memory, discarded on session end. New session = clean slate.
11
+ */
12
+ import { type SecurityLabel, type SecurityLevel, type Compartment } from './label.js';
13
+ export type SecurityTaint = 'secrets_detected' | 'credentials_detected' | 'pii_detected' | 'prompt_injection' | 'high_entropy_output';
14
+ export interface LabelHistoryEntry {
15
+ timestamp: number;
16
+ previousLevel: SecurityLevel;
17
+ newLevel: SecurityLevel;
18
+ previousCompartments: Compartment[];
19
+ newCompartments: Compartment[];
20
+ trigger: string;
21
+ }
22
+ export interface SessionIFCState {
23
+ label: SecurityLabel;
24
+ taints: Set<SecurityTaint>;
25
+ outboundStepCount: number;
26
+ labelHistory: LabelHistoryEntry[];
27
+ trustedActions: Set<string>;
28
+ /** Permission mode registered at session start (trusted source of truth for bypass detection) */
29
+ permissionMode?: string;
30
+ }
31
+ export type OutboundChannel = 'file_write' | 'bash_network' | 'web_fetch' | 'git_commit' | 'memory_save';
32
+ export interface WriteDownCheckResult {
33
+ allowed: boolean;
34
+ action: 'allow' | 'deny' | 'ask' | 'warn';
35
+ reason?: string;
36
+ }
37
+ export interface IFCStepLimits {
38
+ highly_confidential: number;
39
+ confidential: number;
40
+ }
41
+ export declare function createSessionIFC(): SessionIFCState;
42
+ /**
43
+ * Raise the session label (monotonic — can only go up).
44
+ * Returns true if the label actually changed.
45
+ */
46
+ export declare function raiseLabel(state: SessionIFCState, fileLabel: SecurityLabel, trigger: string): boolean;
47
+ /**
48
+ * Add a taint to the session (accumulative, never removed).
49
+ */
50
+ export declare function addTaint(state: SessionIFCState, taint: SecurityTaint, source: string): void;
51
+ /**
52
+ * Grant a one-shot trusted-subject escalation.
53
+ * The action ID should be unique per operation (e.g., "bash:curl:step42").
54
+ */
55
+ export declare function grantTrustedAction(state: SessionIFCState, actionId: string): void;
56
+ /**
57
+ * Consume a trusted action (one-shot — removed after use).
58
+ * Returns true if the action was granted and is now consumed.
59
+ */
60
+ export declare function consumeTrustedAction(state: SessionIFCState, actionId: string): boolean;
61
+ /**
62
+ * Check if an outbound operation is allowed under BLP *-property.
63
+ *
64
+ * Graduated enforcement:
65
+ * - highly_confidential (3): deny all outbound unconditionally
66
+ * - confidential (2): deny if tainted, ask otherwise
67
+ * - internal (1): warn only
68
+ * - public (0): no restriction
69
+ *
70
+ * For file_write, caller must provide the destination file's label.
71
+ */
72
+ export declare function checkWriteDown(state: SessionIFCState, channel: OutboundChannel, options?: {
73
+ destinationLabel?: SecurityLabel;
74
+ actionId?: string;
75
+ stepLimits?: Partial<IFCStepLimits>;
76
+ }): WriteDownCheckResult;
77
+ /**
78
+ * Increment outbound step counter. Call after every outbound operation.
79
+ */
80
+ export declare function recordOutboundStep(state: SessionIFCState): void;
81
+ export interface SessionIFCSummary {
82
+ level: SecurityLevel;
83
+ levelName: string;
84
+ compartments: Compartment[];
85
+ taints: SecurityTaint[];
86
+ outboundStepCount: number;
87
+ historyLength: number;
88
+ trustedActionsCount: number;
89
+ formattedLabel: string;
90
+ }
91
+ export declare function summarizeIFC(state: SessionIFCState): SessionIFCSummary;
92
+ //# sourceMappingURL=session-ifc.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"session-ifc.d.ts","sourceRoot":"","sources":["../../../src/lib/ifc/session-ifc.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,EACL,KAAK,aAAa,EAClB,KAAK,aAAa,EAClB,KAAK,WAAW,EAOjB,MAAM,YAAY,CAAC;AAIpB,MAAM,MAAM,aAAa,GACrB,kBAAkB,GAClB,sBAAsB,GACtB,cAAc,GACd,kBAAkB,GAClB,qBAAqB,CAAC;AAE1B,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,aAAa,CAAC;IAC7B,QAAQ,EAAE,aAAa,CAAC;IACxB,oBAAoB,EAAE,WAAW,EAAE,CAAC;IACpC,eAAe,EAAE,WAAW,EAAE,CAAC;IAC/B,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,aAAa,CAAC;IACrB,MAAM,EAAE,GAAG,CAAC,aAAa,CAAC,CAAC;IAC3B,iBAAiB,EAAE,MAAM,CAAC;IAC1B,YAAY,EAAE,iBAAiB,EAAE,CAAC;IAClC,cAAc,EAAE,GAAG,CAAC,MAAM,CAAC,CAAC;IAC5B,iGAAiG;IACjG,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,MAAM,MAAM,eAAe,GACvB,YAAY,GACZ,cAAc,GACd,WAAW,GACX,YAAY,GACZ,aAAa,CAAC;AAElB,MAAM,WAAW,oBAAoB;IACnC,OAAO,EAAE,OAAO,CAAC;IACjB,MAAM,EAAE,OAAO,GAAG,MAAM,GAAG,KAAK,GAAG,MAAM,CAAC;IAC1C,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AAED,MAAM,WAAW,aAAa;IAC5B,mBAAmB,EAAE,MAAM,CAAC;IAC5B,YAAY,EAAE,MAAM,CAAC;CACtB;AAsBD,wBAAgB,gBAAgB,IAAI,eAAe,CAQlD;AAED;;;GAGG;AACH,wBAAgB,UAAU,CACxB,KAAK,EAAE,eAAe,EACtB,SAAS,EAAE,aAAa,EACxB,OAAO,EAAE,MAAM,GACd,OAAO,CA8BT;AAED;;GAEG;AACH,wBAAgB,QAAQ,CAAC,KAAK,EAAE,eAAe,EAAE,KAAK,EAAE,aAAa,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAsB3F;AAED;;;GAGG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,IAAI,CAEjF;AAED;;;GAGG;AACH,wBAAgB,oBAAoB,CAAC,KAAK,EAAE,eAAe,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtF;AAID;;;;;;;;;;GAUG;AACH,wBAAgB,cAAc,CAC5B,KAAK,EAAE,eAAe,EACtB,OAAO,EAAE,eAAe,EACxB,OAAO,GAAE;IACP,gBAAgB,CAAC,EAAE,aAAa,CAAC;IACjC,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,UAAU,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;CAChC,GACL,oBAAoB,CAkGtB;AAED;;GAEG;AACH,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE/D;AAID,MAAM,WAAW,iBAAiB;IAChC,KAAK,EAAE,aAAa,CAAC;IACrB,SAAS,EAAE,MAAM,CAAC;IAClB,YAAY,EAAE,WAAW,EAAE,CAAC;IAC5B,MAAM,EAAE,aAAa,EAAE,CAAC;IACxB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,mBAAmB,EAAE,MAAM,CAAC;IAC5B,cAAc,EAAE,MAAM,CAAC;CACxB;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,eAAe,GAAG,iBAAiB,CAWtE"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Session IFC State — Bell-LaPadula enforcement per session
3
+ *
4
+ * Tracks the security high-water mark for each session:
5
+ * - Labels only go UP (weak tranquility / monotonic)
6
+ * - Taints accumulate and never clear
7
+ * - Outbound operations are checked against *-property (no write down)
8
+ * - Users can grant one-shot trusted-subject escalations
9
+ *
10
+ * State is in-memory, discarded on session end. New session = clean slate.
11
+ */
12
+ import { makeLabel, join, dominates, isBottom, formatLabel, BOTTOM, } from './label.js';
13
+ const DEFAULT_STEP_LIMITS = {
14
+ highly_confidential: 25,
15
+ confidential: 100,
16
+ };
17
+ /** Max label history entries to keep (prevents unbounded growth in long sessions) */
18
+ const MAX_LABEL_HISTORY = 200;
19
+ // ─── Destination labels for outbound channels ───────────────────────
20
+ const CHANNEL_LABELS = {
21
+ file_write: BOTTOM, // Overridden by actual file label at check time
22
+ bash_network: BOTTOM, // Network = public
23
+ web_fetch: BOTTOM, // Network = public
24
+ git_commit: BOTTOM, // Commit message = public
25
+ memory_save: makeLabel(1), // Internal
26
+ };
27
+ // ─── State management ───────────────────────────────────────────────
28
+ export function createSessionIFC() {
29
+ return {
30
+ label: BOTTOM,
31
+ taints: new Set(),
32
+ outboundStepCount: 0,
33
+ labelHistory: [],
34
+ trustedActions: new Set(),
35
+ };
36
+ }
37
+ /**
38
+ * Raise the session label (monotonic — can only go up).
39
+ * Returns true if the label actually changed.
40
+ */
41
+ export function raiseLabel(state, fileLabel, trigger) {
42
+ const newLabel = join(state.label, fileLabel);
43
+ // Check if anything changed
44
+ if (newLabel.level === state.label.level) {
45
+ // Check compartments
46
+ let changed = false;
47
+ for (const c of newLabel.compartments) {
48
+ if (!state.label.compartments.has(c)) {
49
+ changed = true;
50
+ break;
51
+ }
52
+ }
53
+ if (!changed)
54
+ return false;
55
+ }
56
+ // Record history (capped to prevent unbounded growth)
57
+ if (state.labelHistory.length < MAX_LABEL_HISTORY) {
58
+ state.labelHistory.push({
59
+ timestamp: Date.now(),
60
+ previousLevel: state.label.level,
61
+ newLevel: newLabel.level,
62
+ previousCompartments: [...state.label.compartments],
63
+ newCompartments: [...newLabel.compartments],
64
+ trigger,
65
+ });
66
+ }
67
+ state.label = newLabel;
68
+ return true;
69
+ }
70
+ /**
71
+ * Add a taint to the session (accumulative, never removed).
72
+ */
73
+ export function addTaint(state, taint, source) {
74
+ if (state.taints.has(taint))
75
+ return;
76
+ state.taints.add(taint);
77
+ // Auto-raise label based on taint
78
+ switch (taint) {
79
+ case 'secrets_detected':
80
+ raiseLabel(state, makeLabel(3, ['secrets']), `taint:${taint} from ${source}`);
81
+ break;
82
+ case 'credentials_detected':
83
+ raiseLabel(state, makeLabel(3, ['credentials']), `taint:${taint} from ${source}`);
84
+ break;
85
+ case 'pii_detected':
86
+ raiseLabel(state, makeLabel(2, ['pii']), `taint:${taint} from ${source}`);
87
+ break;
88
+ case 'prompt_injection':
89
+ // Injection doesn't change label, but taints the session
90
+ break;
91
+ case 'high_entropy_output':
92
+ raiseLabel(state, makeLabel(2, ['secrets']), `taint:${taint} from ${source}`);
93
+ break;
94
+ }
95
+ }
96
+ /**
97
+ * Grant a one-shot trusted-subject escalation.
98
+ * The action ID should be unique per operation (e.g., "bash:curl:step42").
99
+ */
100
+ export function grantTrustedAction(state, actionId) {
101
+ state.trustedActions.add(actionId);
102
+ }
103
+ /**
104
+ * Consume a trusted action (one-shot — removed after use).
105
+ * Returns true if the action was granted and is now consumed.
106
+ */
107
+ export function consumeTrustedAction(state, actionId) {
108
+ return state.trustedActions.delete(actionId);
109
+ }
110
+ // ─── *-Property enforcement (no write down) ─────────────────────────
111
+ /**
112
+ * Check if an outbound operation is allowed under BLP *-property.
113
+ *
114
+ * Graduated enforcement:
115
+ * - highly_confidential (3): deny all outbound unconditionally
116
+ * - confidential (2): deny if tainted, ask otherwise
117
+ * - internal (1): warn only
118
+ * - public (0): no restriction
119
+ *
120
+ * For file_write, caller must provide the destination file's label.
121
+ */
122
+ export function checkWriteDown(state, channel, options = {}) {
123
+ // If session is at bottom (clean), always allow
124
+ if (isBottom(state.label)) {
125
+ return { allowed: true, action: 'allow' };
126
+ }
127
+ // Check one-shot trusted action (consumed on use — delete, not has)
128
+ if (options.actionId && state.trustedActions.delete(options.actionId)) {
129
+ return {
130
+ allowed: true,
131
+ action: 'allow',
132
+ reason: 'Trusted action granted by user (one-shot, now consumed)',
133
+ };
134
+ }
135
+ // Determine destination label
136
+ const destLabel = channel === 'file_write' && options.destinationLabel
137
+ ? options.destinationLabel
138
+ : CHANNEL_LABELS[channel];
139
+ // For file_write: check if destination dominates session (standard BLP)
140
+ if (channel === 'file_write' && options.destinationLabel) {
141
+ if (dominates(options.destinationLabel, state.label)) {
142
+ // Writing to equal or higher classification — always OK
143
+ return { allowed: true, action: 'allow' };
144
+ }
145
+ }
146
+ // Graduated enforcement by session level
147
+ const limits = { ...DEFAULT_STEP_LIMITS, ...options.stepLimits };
148
+ if (state.label.level === 3) {
149
+ // Highly confidential: deny all outbound (except file_write to same/higher level)
150
+ if (state.outboundStepCount >= limits.highly_confidential) {
151
+ return {
152
+ allowed: false,
153
+ action: 'deny',
154
+ reason: `Session has read highly confidential data (step limit ${limits.highly_confidential} reached). ` +
155
+ `All outbound operations blocked. Session label: ${formatLabel(state.label)}`,
156
+ };
157
+ }
158
+ return {
159
+ allowed: false,
160
+ action: 'deny',
161
+ reason: `Session has read highly confidential data. ` +
162
+ `${channel} to ${formatLabel(destLabel)} blocked (no write down). ` +
163
+ `Session label: ${formatLabel(state.label)}`,
164
+ };
165
+ }
166
+ if (state.label.level === 2) {
167
+ // Confidential: deny if tainted, ask otherwise
168
+ if (state.taints.size > 0) {
169
+ return {
170
+ allowed: false,
171
+ action: 'deny',
172
+ reason: `Session is confidential + tainted (${[...state.taints].join(', ')}). ` +
173
+ `${channel} blocked. Session label: ${formatLabel(state.label)}`,
174
+ };
175
+ }
176
+ if (state.outboundStepCount >= limits.confidential) {
177
+ return {
178
+ allowed: false,
179
+ action: 'ask',
180
+ reason: `Session has read confidential data (step limit ${limits.confidential} approaching). ` +
181
+ `${channel} requires approval. Session label: ${formatLabel(state.label)}`,
182
+ };
183
+ }
184
+ return {
185
+ allowed: false,
186
+ action: 'ask',
187
+ reason: `Session has read confidential data. ` +
188
+ `${channel} to ${formatLabel(destLabel)} requires approval (no write down). ` +
189
+ `Session label: ${formatLabel(state.label)}`,
190
+ };
191
+ }
192
+ if (state.label.level === 1) {
193
+ // Internal: warn only (don't block)
194
+ return {
195
+ allowed: true,
196
+ action: 'warn',
197
+ reason: `Session has read internal data. ` +
198
+ `${channel} allowed but noted. Session label: ${formatLabel(state.label)}`,
199
+ };
200
+ }
201
+ // Level 0 (public) — no restriction
202
+ return { allowed: true, action: 'allow' };
203
+ }
204
+ /**
205
+ * Increment outbound step counter. Call after every outbound operation.
206
+ */
207
+ export function recordOutboundStep(state) {
208
+ state.outboundStepCount++;
209
+ }
210
+ export function summarizeIFC(state) {
211
+ return {
212
+ level: state.label.level,
213
+ levelName: formatLabel(state.label).split(' ')[0],
214
+ compartments: [...state.label.compartments],
215
+ taints: [...state.taints],
216
+ outboundStepCount: state.outboundStepCount,
217
+ historyLength: state.labelHistory.length,
218
+ trustedActionsCount: state.trustedActions.size,
219
+ formattedLabel: formatLabel(state.label),
220
+ };
221
+ }
222
+ //# sourceMappingURL=session-ifc.js.map