@jlongo78/agent-spaces 0.9.6 → 0.9.8

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 (917) hide show
  1. package/.next/standalone/.claude/settings.local.json +68 -0
  2. package/.next/standalone/.claude/spaces-env.json +1 -0
  3. package/.next/standalone/.next/BUILD_ID +1 -1
  4. package/.next/standalone/.next/app-path-routes-manifest.json +1 -0
  5. package/.next/standalone/.next/build-manifest.json +2 -2
  6. package/.next/standalone/.next/prerender-manifest.json +3 -3
  7. package/.next/standalone/.next/required-server-files.json +19 -19
  8. package/.next/standalone/.next/routes-manifest.json +6 -0
  9. package/.next/standalone/.next/server/app/(desktop)/admin/analytics/page_client-reference-manifest.js +1 -1
  10. package/.next/standalone/.next/server/app/(desktop)/admin/users/page_client-reference-manifest.js +1 -1
  11. package/.next/standalone/.next/server/app/(desktop)/analytics/page_client-reference-manifest.js +1 -1
  12. package/.next/standalone/.next/server/app/(desktop)/cortex/page_client-reference-manifest.js +1 -1
  13. package/.next/standalone/.next/server/app/(desktop)/network/page_client-reference-manifest.js +1 -1
  14. package/.next/standalone/.next/server/app/(desktop)/page_client-reference-manifest.js +1 -1
  15. package/.next/standalone/.next/server/app/(desktop)/projects/page_client-reference-manifest.js +1 -1
  16. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page.js.nft.json +1 -1
  17. package/.next/standalone/.next/server/app/(desktop)/sessions/[id]/page_client-reference-manifest.js +1 -1
  18. package/.next/standalone/.next/server/app/(desktop)/sessions/page_client-reference-manifest.js +1 -1
  19. package/.next/standalone/.next/server/app/(desktop)/settings/page_client-reference-manifest.js +1 -1
  20. package/.next/standalone/.next/server/app/(desktop)/terminal/page.js.nft.json +1 -1
  21. package/.next/standalone/.next/server/app/(desktop)/terminal/page_client-reference-manifest.js +1 -1
  22. package/.next/standalone/.next/server/app/(desktop)/terminal/pane/[id]/page_client-reference-manifest.js +1 -1
  23. package/.next/standalone/.next/server/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page_client-reference-manifest.js +1 -1
  24. package/.next/standalone/.next/server/app/(desktop)/workspaces/page_client-reference-manifest.js +1 -1
  25. package/.next/standalone/.next/server/app/_global-error.html +2 -2
  26. package/.next/standalone/.next/server/app/_global-error.rsc +1 -1
  27. package/.next/standalone/.next/server/app/_global-error.segments/__PAGE__.segment.rsc +1 -1
  28. package/.next/standalone/.next/server/app/_global-error.segments/_full.segment.rsc +1 -1
  29. package/.next/standalone/.next/server/app/_global-error.segments/_head.segment.rsc +1 -1
  30. package/.next/standalone/.next/server/app/_global-error.segments/_index.segment.rsc +1 -1
  31. package/.next/standalone/.next/server/app/_global-error.segments/_tree.segment.rsc +1 -1
  32. package/.next/standalone/.next/server/app/_not-found/page_client-reference-manifest.js +1 -1
  33. package/.next/standalone/.next/server/app/_not-found.html +1 -1
  34. package/.next/standalone/.next/server/app/_not-found.rsc +2 -2
  35. package/.next/standalone/.next/server/app/_not-found.segments/_full.segment.rsc +2 -2
  36. package/.next/standalone/.next/server/app/_not-found.segments/_head.segment.rsc +1 -1
  37. package/.next/standalone/.next/server/app/_not-found.segments/_index.segment.rsc +2 -2
  38. package/.next/standalone/.next/server/app/_not-found.segments/_not-found/__PAGE__.segment.rsc +1 -1
  39. package/.next/standalone/.next/server/app/_not-found.segments/_not-found.segment.rsc +1 -1
  40. package/.next/standalone/.next/server/app/_not-found.segments/_tree.segment.rsc +2 -2
  41. package/.next/standalone/.next/server/app/admin/analytics.html +1 -1
  42. package/.next/standalone/.next/server/app/admin/analytics.rsc +2 -2
  43. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics/__PAGE__.segment.rsc +1 -1
  44. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin/analytics.segment.rsc +1 -1
  45. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  46. package/.next/standalone/.next/server/app/admin/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  47. package/.next/standalone/.next/server/app/admin/analytics.segments/_full.segment.rsc +2 -2
  48. package/.next/standalone/.next/server/app/admin/analytics.segments/_head.segment.rsc +1 -1
  49. package/.next/standalone/.next/server/app/admin/analytics.segments/_index.segment.rsc +2 -2
  50. package/.next/standalone/.next/server/app/admin/analytics.segments/_tree.segment.rsc +2 -2
  51. package/.next/standalone/.next/server/app/admin/users.html +1 -1
  52. package/.next/standalone/.next/server/app/admin/users.rsc +2 -2
  53. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users/__PAGE__.segment.rsc +1 -1
  54. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin/users.segment.rsc +1 -1
  55. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap/admin.segment.rsc +1 -1
  56. package/.next/standalone/.next/server/app/admin/users.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  57. package/.next/standalone/.next/server/app/admin/users.segments/_full.segment.rsc +2 -2
  58. package/.next/standalone/.next/server/app/admin/users.segments/_head.segment.rsc +1 -1
  59. package/.next/standalone/.next/server/app/admin/users.segments/_index.segment.rsc +2 -2
  60. package/.next/standalone/.next/server/app/admin/users.segments/_tree.segment.rsc +2 -2
  61. package/.next/standalone/.next/server/app/analytics.html +1 -1
  62. package/.next/standalone/.next/server/app/analytics.rsc +2 -2
  63. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics/__PAGE__.segment.rsc +1 -1
  64. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap/analytics.segment.rsc +1 -1
  65. package/.next/standalone/.next/server/app/analytics.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  66. package/.next/standalone/.next/server/app/analytics.segments/_full.segment.rsc +2 -2
  67. package/.next/standalone/.next/server/app/analytics.segments/_head.segment.rsc +1 -1
  68. package/.next/standalone/.next/server/app/analytics.segments/_index.segment.rsc +2 -2
  69. package/.next/standalone/.next/server/app/analytics.segments/_tree.segment.rsc +2 -2
  70. package/.next/standalone/.next/server/app/api/analytics/overview/route.js +1 -1
  71. package/.next/standalone/.next/server/app/api/analytics/overview/route.js.nft.json +1 -1
  72. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js +1 -1
  73. package/.next/standalone/.next/server/app/api/benchmark/lobes/route.js.nft.json +1 -1
  74. package/.next/standalone/.next/server/app/api/benchmark/run/route.js +1 -1
  75. package/.next/standalone/.next/server/app/api/benchmark/run/route.js.nft.json +1 -1
  76. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js +1 -1
  77. package/.next/standalone/.next/server/app/api/benchmark/runs/[id]/route.js.nft.json +1 -1
  78. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js +1 -1
  79. package/.next/standalone/.next/server/app/api/benchmark/runs/route.js.nft.json +1 -1
  80. package/.next/standalone/.next/server/app/api/benchmark/status/route.js +1 -1
  81. package/.next/standalone/.next/server/app/api/benchmark/status/route.js.nft.json +1 -1
  82. package/.next/standalone/.next/server/app/api/bulk/route.js +1 -1
  83. package/.next/standalone/.next/server/app/api/bulk/route.js.nft.json +1 -1
  84. package/.next/standalone/.next/server/app/api/config/route.js +1 -1
  85. package/.next/standalone/.next/server/app/api/config/route.js.nft.json +1 -1
  86. package/.next/standalone/.next/server/app/api/cortex/context/route.js +1 -1
  87. package/.next/standalone/.next/server/app/api/cortex/context/route.js.nft.json +1 -1
  88. package/.next/standalone/.next/server/app/api/cortex/curation/assess/route.js +1 -1
  89. package/.next/standalone/.next/server/app/api/cortex/curation/assess/route.js.nft.json +1 -1
  90. package/.next/standalone/.next/server/app/api/cortex/curation/publish/route.js +1 -1
  91. package/.next/standalone/.next/server/app/api/cortex/curation/publish/route.js.nft.json +1 -1
  92. package/.next/standalone/.next/server/app/api/cortex/curation/refine/route.js +1 -1
  93. package/.next/standalone/.next/server/app/api/cortex/curation/refine/route.js.nft.json +1 -1
  94. package/.next/standalone/.next/server/app/api/cortex/curation/review/route.js +1 -1
  95. package/.next/standalone/.next/server/app/api/cortex/curation/review/route.js.nft.json +1 -1
  96. package/.next/standalone/.next/server/app/api/cortex/curation/seed/route.js +1 -1
  97. package/.next/standalone/.next/server/app/api/cortex/curation/seed/route.js.nft.json +1 -1
  98. package/.next/standalone/.next/server/app/api/cortex/export/route.js +1 -1
  99. package/.next/standalone/.next/server/app/api/cortex/export/route.js.nft.json +1 -1
  100. package/.next/standalone/.next/server/app/api/cortex/federation/pending/route.js +1 -1
  101. package/.next/standalone/.next/server/app/api/cortex/federation/pending/route.js.nft.json +1 -1
  102. package/.next/standalone/.next/server/app/api/cortex/federation/resolve/route.js +1 -1
  103. package/.next/standalone/.next/server/app/api/cortex/federation/resolve/route.js.nft.json +1 -1
  104. package/.next/standalone/.next/server/app/api/cortex/federation/search/route.js +1 -1
  105. package/.next/standalone/.next/server/app/api/cortex/federation/search/route.js.nft.json +1 -1
  106. package/.next/standalone/.next/server/app/api/cortex/federation/teach/route.js +1 -1
  107. package/.next/standalone/.next/server/app/api/cortex/federation/teach/route.js.nft.json +1 -1
  108. package/.next/standalone/.next/server/app/api/cortex/graph/edges/route.js +1 -1
  109. package/.next/standalone/.next/server/app/api/cortex/graph/edges/route.js.nft.json +1 -1
  110. package/.next/standalone/.next/server/app/api/cortex/graph/entities/[id]/route.js +1 -1
  111. package/.next/standalone/.next/server/app/api/cortex/graph/entities/[id]/route.js.nft.json +1 -1
  112. package/.next/standalone/.next/server/app/api/cortex/graph/entities/route.js +1 -1
  113. package/.next/standalone/.next/server/app/api/cortex/graph/entities/route.js.nft.json +1 -1
  114. package/.next/standalone/.next/server/app/api/cortex/graph/populate/route.js +1 -1
  115. package/.next/standalone/.next/server/app/api/cortex/graph/populate/route.js.nft.json +1 -1
  116. package/.next/standalone/.next/server/app/api/cortex/import/route.js +1 -1
  117. package/.next/standalone/.next/server/app/api/cortex/import/route.js.nft.json +1 -1
  118. package/.next/standalone/.next/server/app/api/cortex/import/status/route.js +1 -1
  119. package/.next/standalone/.next/server/app/api/cortex/import/status/route.js.nft.json +1 -1
  120. package/.next/standalone/.next/server/app/api/cortex/ingest/bootstrap/route.js +1 -1
  121. package/.next/standalone/.next/server/app/api/cortex/ingest/bootstrap/route.js.nft.json +1 -1
  122. package/.next/standalone/.next/server/app/api/cortex/ingest/status/route.js +1 -1
  123. package/.next/standalone/.next/server/app/api/cortex/ingest/status/route.js.nft.json +1 -1
  124. package/.next/standalone/.next/server/app/api/cortex/knowledge/[id]/route.js +1 -1
  125. package/.next/standalone/.next/server/app/api/cortex/knowledge/[id]/route.js.nft.json +1 -1
  126. package/.next/standalone/.next/server/app/api/cortex/knowledge/route.js +1 -1
  127. package/.next/standalone/.next/server/app/api/cortex/knowledge/route.js.nft.json +1 -1
  128. package/.next/standalone/.next/server/app/api/cortex/lobes/[id]/route.js +1 -1
  129. package/.next/standalone/.next/server/app/api/cortex/lobes/[id]/route.js.nft.json +1 -1
  130. package/.next/standalone/.next/server/app/api/cortex/lobes/route.js +1 -1
  131. package/.next/standalone/.next/server/app/api/cortex/lobes/route.js.nft.json +1 -1
  132. package/.next/standalone/.next/server/app/api/cortex/lobes/share/route.js +1 -1
  133. package/.next/standalone/.next/server/app/api/cortex/lobes/share/route.js.nft.json +1 -1
  134. package/.next/standalone/.next/server/app/api/cortex/marketplace/browse/route.js +1 -1
  135. package/.next/standalone/.next/server/app/api/cortex/marketplace/browse/route.js.nft.json +1 -1
  136. package/.next/standalone/.next/server/app/api/cortex/marketplace/preview/route.js +1 -1
  137. package/.next/standalone/.next/server/app/api/cortex/marketplace/preview/route.js.nft.json +1 -1
  138. package/.next/standalone/.next/server/app/api/cortex/mcp/call/route.js +1 -1
  139. package/.next/standalone/.next/server/app/api/cortex/mcp/call/route.js.nft.json +1 -1
  140. package/.next/standalone/.next/server/app/api/cortex/mcp/tools/route.js +1 -1
  141. package/.next/standalone/.next/server/app/api/cortex/mcp/tools/route.js.nft.json +1 -1
  142. package/.next/standalone/.next/server/app/api/cortex/search/route.js +1 -1
  143. package/.next/standalone/.next/server/app/api/cortex/search/route.js.nft.json +1 -1
  144. package/.next/standalone/.next/server/app/api/cortex/settings/route.js +1 -1
  145. package/.next/standalone/.next/server/app/api/cortex/settings/route.js.nft.json +1 -1
  146. package/.next/standalone/.next/server/app/api/cortex/status/route.js +1 -1
  147. package/.next/standalone/.next/server/app/api/cortex/status/route.js.nft.json +1 -1
  148. package/.next/standalone/.next/server/app/api/cortex/timeline/route.js +1 -1
  149. package/.next/standalone/.next/server/app/api/cortex/timeline/route.js.nft.json +1 -1
  150. package/.next/standalone/.next/server/app/api/cortex/usage/route.js +1 -1
  151. package/.next/standalone/.next/server/app/api/cortex/usage/route.js.nft.json +1 -1
  152. package/.next/standalone/.next/server/app/api/cortex/workspace/[id]/context/route.js +1 -1
  153. package/.next/standalone/.next/server/app/api/cortex/workspace/[id]/context/route.js.nft.json +1 -1
  154. package/.next/standalone/.next/server/app/api/events/route.js +1 -1
  155. package/.next/standalone/.next/server/app/api/events/route.js.nft.json +1 -1
  156. package/.next/standalone/.next/server/app/api/files/route.js +1 -1
  157. package/.next/standalone/.next/server/app/api/files/route.js.nft.json +1 -1
  158. package/.next/standalone/.next/server/app/api/folders/route.js +1 -1
  159. package/.next/standalone/.next/server/app/api/folders/route.js.nft.json +1 -1
  160. package/.next/standalone/.next/server/app/api/network/handshake/route.js +1 -1
  161. package/.next/standalone/.next/server/app/api/network/handshake/route.js.nft.json +1 -1
  162. package/.next/standalone/.next/server/app/api/network/panes/[id]/route.js +1 -1
  163. package/.next/standalone/.next/server/app/api/network/panes/[id]/route.js.nft.json +1 -1
  164. package/.next/standalone/.next/server/app/api/network/panes/route.js +1 -1
  165. package/.next/standalone/.next/server/app/api/network/panes/route.js.nft.json +1 -1
  166. package/.next/standalone/.next/server/app/api/network/projects/route.js +1 -1
  167. package/.next/standalone/.next/server/app/api/network/projects/route.js.nft.json +1 -1
  168. package/.next/standalone/.next/server/app/api/network/search/route.js +1 -1
  169. package/.next/standalone/.next/server/app/api/network/search/route.js.nft.json +1 -1
  170. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js +1 -1
  171. package/.next/standalone/.next/server/app/api/network/sessions/[id]/messages/route.js.nft.json +1 -1
  172. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js +1 -1
  173. package/.next/standalone/.next/server/app/api/network/sessions/[id]/route.js.nft.json +1 -1
  174. package/.next/standalone/.next/server/app/api/network/sessions/route.js +1 -1
  175. package/.next/standalone/.next/server/app/api/network/sessions/route.js.nft.json +1 -1
  176. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js +1 -1
  177. package/.next/standalone/.next/server/app/api/network/workspaces/[id]/route.js.nft.json +1 -1
  178. package/.next/standalone/.next/server/app/api/network/workspaces/route.js +1 -1
  179. package/.next/standalone/.next/server/app/api/network/workspaces/route.js.nft.json +1 -1
  180. package/.next/standalone/.next/server/app/api/panes/[id]/diff/route.js +1 -1
  181. package/.next/standalone/.next/server/app/api/panes/[id]/diff/route.js.nft.json +1 -1
  182. package/.next/standalone/.next/server/app/api/panes/[id]/route.js +1 -1
  183. package/.next/standalone/.next/server/app/api/panes/[id]/route.js.nft.json +1 -1
  184. package/.next/standalone/.next/server/app/api/panes/route.js +1 -1
  185. package/.next/standalone/.next/server/app/api/panes/route.js.nft.json +1 -1
  186. package/.next/standalone/.next/server/app/api/projects/route.js +1 -1
  187. package/.next/standalone/.next/server/app/api/projects/route.js.nft.json +1 -1
  188. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/[...path]/route.js +1 -1
  189. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/[...path]/route.js.nft.json +1 -1
  190. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/status/route.js +1 -1
  191. package/.next/standalone/.next/server/app/api/proxy/models/[modelId]/status/route.js.nft.json +1 -1
  192. package/.next/standalone/.next/server/app/api/search/route.js +2 -2
  193. package/.next/standalone/.next/server/app/api/search/route.js.nft.json +1 -1
  194. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js +1 -1
  195. package/.next/standalone/.next/server/app/api/sessions/[id]/chat/route.js.nft.json +1 -1
  196. package/.next/standalone/.next/server/app/api/sessions/[id]/messages/route.js +1 -1
  197. package/.next/standalone/.next/server/app/api/sessions/[id]/messages/route.js.nft.json +1 -1
  198. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js +1 -1
  199. package/.next/standalone/.next/server/app/api/sessions/[id]/route.js.nft.json +1 -1
  200. package/.next/standalone/.next/server/app/api/sessions/route.js +2 -2
  201. package/.next/standalone/.next/server/app/api/sessions/route.js.nft.json +1 -1
  202. package/.next/standalone/.next/server/app/api/sync/route.js +1 -1
  203. package/.next/standalone/.next/server/app/api/sync/route.js.nft.json +1 -1
  204. package/.next/standalone/.next/server/app/api/tags/route.js +1 -1
  205. package/.next/standalone/.next/server/app/api/tags/route.js.nft.json +1 -1
  206. package/.next/standalone/.next/server/app/api/tier/route.js +1 -1
  207. package/.next/standalone/.next/server/app/api/tier/route.js.nft.json +1 -1
  208. package/.next/standalone/.next/server/app/api/whisper/config/route.js +1 -1
  209. package/.next/standalone/.next/server/app/api/whisper/config/route.js.nft.json +1 -1
  210. package/.next/standalone/.next/server/app/api/whisper/route.js.nft.json +1 -1
  211. package/.next/standalone/.next/server/app/api/wizard/chart/route/app-paths-manifest.json +3 -0
  212. package/.next/standalone/.next/server/app/api/wizard/chart/route/build-manifest.json +11 -0
  213. package/.next/standalone/.next/server/app/api/wizard/chart/route/server-reference-manifest.json +4 -0
  214. package/.next/standalone/.next/server/app/api/wizard/chart/route.js +7 -0
  215. package/.next/standalone/.next/server/app/api/wizard/chart/route.js.map +5 -0
  216. package/.next/standalone/.next/server/app/api/wizard/chart/route.js.nft.json +1 -0
  217. package/.next/standalone/.next/server/app/api/wizard/chart/route_client-reference-manifest.js +2 -0
  218. package/.next/standalone/.next/server/app/api/wizard/chat/route.js +1 -1
  219. package/.next/standalone/.next/server/app/api/wizard/chat/route.js.nft.json +1 -1
  220. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/[key]/route.js +1 -1
  221. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/[key]/route.js.nft.json +1 -1
  222. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/route.js +1 -1
  223. package/.next/standalone/.next/server/app/api/workspaces/[id]/context/route.js.nft.json +1 -1
  224. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/[msgId]/route.js +1 -1
  225. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/[msgId]/route.js.nft.json +1 -1
  226. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/route.js +1 -1
  227. package/.next/standalone/.next/server/app/api/workspaces/[id]/messages/route.js.nft.json +1 -1
  228. package/.next/standalone/.next/server/app/api/workspaces/[id]/route.js +1 -1
  229. package/.next/standalone/.next/server/app/api/workspaces/[id]/route.js.nft.json +1 -1
  230. package/.next/standalone/.next/server/app/api/workspaces/[id]/sessions/route.js +1 -1
  231. package/.next/standalone/.next/server/app/api/workspaces/[id]/sessions/route.js.nft.json +1 -1
  232. package/.next/standalone/.next/server/app/api/workspaces/route.js +2 -2
  233. package/.next/standalone/.next/server/app/api/workspaces/route.js.nft.json +1 -1
  234. package/.next/standalone/.next/server/app/cortex.html +1 -1
  235. package/.next/standalone/.next/server/app/cortex.rsc +3 -3
  236. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex/__PAGE__.segment.rsc +2 -2
  237. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap/cortex.segment.rsc +1 -1
  238. package/.next/standalone/.next/server/app/cortex.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  239. package/.next/standalone/.next/server/app/cortex.segments/_full.segment.rsc +3 -3
  240. package/.next/standalone/.next/server/app/cortex.segments/_head.segment.rsc +1 -1
  241. package/.next/standalone/.next/server/app/cortex.segments/_index.segment.rsc +2 -2
  242. package/.next/standalone/.next/server/app/cortex.segments/_tree.segment.rsc +2 -2
  243. package/.next/standalone/.next/server/app/login/page_client-reference-manifest.js +1 -1
  244. package/.next/standalone/.next/server/app/login.html +1 -1
  245. package/.next/standalone/.next/server/app/login.rsc +2 -2
  246. package/.next/standalone/.next/server/app/login.segments/_full.segment.rsc +2 -2
  247. package/.next/standalone/.next/server/app/login.segments/_head.segment.rsc +1 -1
  248. package/.next/standalone/.next/server/app/login.segments/_index.segment.rsc +2 -2
  249. package/.next/standalone/.next/server/app/login.segments/_tree.segment.rsc +2 -2
  250. package/.next/standalone/.next/server/app/login.segments/login/__PAGE__.segment.rsc +1 -1
  251. package/.next/standalone/.next/server/app/login.segments/login.segment.rsc +1 -1
  252. package/.next/standalone/.next/server/app/m/page_client-reference-manifest.js +1 -1
  253. package/.next/standalone/.next/server/app/m/projects/page_client-reference-manifest.js +1 -1
  254. package/.next/standalone/.next/server/app/m/projects.html +1 -1
  255. package/.next/standalone/.next/server/app/m/projects.rsc +2 -2
  256. package/.next/standalone/.next/server/app/m/projects.segments/_full.segment.rsc +2 -2
  257. package/.next/standalone/.next/server/app/m/projects.segments/_head.segment.rsc +1 -1
  258. package/.next/standalone/.next/server/app/m/projects.segments/_index.segment.rsc +2 -2
  259. package/.next/standalone/.next/server/app/m/projects.segments/_tree.segment.rsc +2 -2
  260. package/.next/standalone/.next/server/app/m/projects.segments/m/projects/__PAGE__.segment.rsc +1 -1
  261. package/.next/standalone/.next/server/app/m/projects.segments/m/projects.segment.rsc +1 -1
  262. package/.next/standalone/.next/server/app/m/projects.segments/m.segment.rsc +1 -1
  263. package/.next/standalone/.next/server/app/m/sessions/[id]/page.js.nft.json +1 -1
  264. package/.next/standalone/.next/server/app/m/sessions/[id]/page_client-reference-manifest.js +1 -1
  265. package/.next/standalone/.next/server/app/m/sessions/page_client-reference-manifest.js +1 -1
  266. package/.next/standalone/.next/server/app/m/sessions.html +1 -1
  267. package/.next/standalone/.next/server/app/m/sessions.rsc +2 -2
  268. package/.next/standalone/.next/server/app/m/sessions.segments/_full.segment.rsc +2 -2
  269. package/.next/standalone/.next/server/app/m/sessions.segments/_head.segment.rsc +1 -1
  270. package/.next/standalone/.next/server/app/m/sessions.segments/_index.segment.rsc +2 -2
  271. package/.next/standalone/.next/server/app/m/sessions.segments/_tree.segment.rsc +2 -2
  272. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions/__PAGE__.segment.rsc +1 -1
  273. package/.next/standalone/.next/server/app/m/sessions.segments/m/sessions.segment.rsc +1 -1
  274. package/.next/standalone/.next/server/app/m/sessions.segments/m.segment.rsc +1 -1
  275. package/.next/standalone/.next/server/app/m/settings/page_client-reference-manifest.js +1 -1
  276. package/.next/standalone/.next/server/app/m/settings.html +1 -1
  277. package/.next/standalone/.next/server/app/m/settings.rsc +2 -2
  278. package/.next/standalone/.next/server/app/m/settings.segments/_full.segment.rsc +2 -2
  279. package/.next/standalone/.next/server/app/m/settings.segments/_head.segment.rsc +1 -1
  280. package/.next/standalone/.next/server/app/m/settings.segments/_index.segment.rsc +2 -2
  281. package/.next/standalone/.next/server/app/m/settings.segments/_tree.segment.rsc +2 -2
  282. package/.next/standalone/.next/server/app/m/settings.segments/m/settings/__PAGE__.segment.rsc +1 -1
  283. package/.next/standalone/.next/server/app/m/settings.segments/m/settings.segment.rsc +1 -1
  284. package/.next/standalone/.next/server/app/m/settings.segments/m.segment.rsc +1 -1
  285. package/.next/standalone/.next/server/app/m/terminal/page_client-reference-manifest.js +1 -1
  286. package/.next/standalone/.next/server/app/m/terminal.html +1 -1
  287. package/.next/standalone/.next/server/app/m/terminal.rsc +3 -3
  288. package/.next/standalone/.next/server/app/m/terminal.segments/_full.segment.rsc +3 -3
  289. package/.next/standalone/.next/server/app/m/terminal.segments/_head.segment.rsc +1 -1
  290. package/.next/standalone/.next/server/app/m/terminal.segments/_index.segment.rsc +2 -2
  291. package/.next/standalone/.next/server/app/m/terminal.segments/_tree.segment.rsc +2 -2
  292. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal/__PAGE__.segment.rsc +2 -2
  293. package/.next/standalone/.next/server/app/m/terminal.segments/m/terminal.segment.rsc +1 -1
  294. package/.next/standalone/.next/server/app/m/terminal.segments/m.segment.rsc +1 -1
  295. package/.next/standalone/.next/server/app/m.html +1 -1
  296. package/.next/standalone/.next/server/app/m.rsc +2 -2
  297. package/.next/standalone/.next/server/app/m.segments/_full.segment.rsc +2 -2
  298. package/.next/standalone/.next/server/app/m.segments/_head.segment.rsc +1 -1
  299. package/.next/standalone/.next/server/app/m.segments/_index.segment.rsc +2 -2
  300. package/.next/standalone/.next/server/app/m.segments/_tree.segment.rsc +2 -2
  301. package/.next/standalone/.next/server/app/m.segments/m/__PAGE__.segment.rsc +1 -1
  302. package/.next/standalone/.next/server/app/m.segments/m.segment.rsc +1 -1
  303. package/.next/standalone/.next/server/app/network.html +1 -1
  304. package/.next/standalone/.next/server/app/network.rsc +2 -2
  305. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network/__PAGE__.segment.rsc +1 -1
  306. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap/network.segment.rsc +1 -1
  307. package/.next/standalone/.next/server/app/network.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  308. package/.next/standalone/.next/server/app/network.segments/_full.segment.rsc +2 -2
  309. package/.next/standalone/.next/server/app/network.segments/_head.segment.rsc +1 -1
  310. package/.next/standalone/.next/server/app/network.segments/_index.segment.rsc +2 -2
  311. package/.next/standalone/.next/server/app/network.segments/_tree.segment.rsc +2 -2
  312. package/.next/standalone/.next/server/app/projects.html +1 -1
  313. package/.next/standalone/.next/server/app/projects.rsc +2 -2
  314. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects/__PAGE__.segment.rsc +1 -1
  315. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap/projects.segment.rsc +1 -1
  316. package/.next/standalone/.next/server/app/projects.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  317. package/.next/standalone/.next/server/app/projects.segments/_full.segment.rsc +2 -2
  318. package/.next/standalone/.next/server/app/projects.segments/_head.segment.rsc +1 -1
  319. package/.next/standalone/.next/server/app/projects.segments/_index.segment.rsc +2 -2
  320. package/.next/standalone/.next/server/app/projects.segments/_tree.segment.rsc +2 -2
  321. package/.next/standalone/.next/server/app/sessions.html +1 -1
  322. package/.next/standalone/.next/server/app/sessions.rsc +2 -2
  323. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions/__PAGE__.segment.rsc +1 -1
  324. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap/sessions.segment.rsc +1 -1
  325. package/.next/standalone/.next/server/app/sessions.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  326. package/.next/standalone/.next/server/app/sessions.segments/_full.segment.rsc +2 -2
  327. package/.next/standalone/.next/server/app/sessions.segments/_head.segment.rsc +1 -1
  328. package/.next/standalone/.next/server/app/sessions.segments/_index.segment.rsc +2 -2
  329. package/.next/standalone/.next/server/app/sessions.segments/_tree.segment.rsc +2 -2
  330. package/.next/standalone/.next/server/app/settings.html +1 -1
  331. package/.next/standalone/.next/server/app/settings.rsc +2 -2
  332. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings/__PAGE__.segment.rsc +1 -1
  333. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap/settings.segment.rsc +1 -1
  334. package/.next/standalone/.next/server/app/settings.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  335. package/.next/standalone/.next/server/app/settings.segments/_full.segment.rsc +2 -2
  336. package/.next/standalone/.next/server/app/settings.segments/_head.segment.rsc +1 -1
  337. package/.next/standalone/.next/server/app/settings.segments/_index.segment.rsc +2 -2
  338. package/.next/standalone/.next/server/app/settings.segments/_tree.segment.rsc +2 -2
  339. package/.next/standalone/.next/server/app/terminal.html +1 -1
  340. package/.next/standalone/.next/server/app/terminal.rsc +3 -3
  341. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal/__PAGE__.segment.rsc +2 -2
  342. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap/terminal.segment.rsc +1 -1
  343. package/.next/standalone/.next/server/app/terminal.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  344. package/.next/standalone/.next/server/app/terminal.segments/_full.segment.rsc +3 -3
  345. package/.next/standalone/.next/server/app/terminal.segments/_head.segment.rsc +1 -1
  346. package/.next/standalone/.next/server/app/terminal.segments/_index.segment.rsc +2 -2
  347. package/.next/standalone/.next/server/app/terminal.segments/_tree.segment.rsc +2 -2
  348. package/.next/standalone/.next/server/app/vr/page/react-loadable-manifest.json +1 -1
  349. package/.next/standalone/.next/server/app/vr/page_client-reference-manifest.js +1 -1
  350. package/.next/standalone/.next/server/app/vr.html +1 -1
  351. package/.next/standalone/.next/server/app/vr.rsc +3 -3
  352. package/.next/standalone/.next/server/app/vr.segments/_full.segment.rsc +3 -3
  353. package/.next/standalone/.next/server/app/vr.segments/_head.segment.rsc +1 -1
  354. package/.next/standalone/.next/server/app/vr.segments/_index.segment.rsc +2 -2
  355. package/.next/standalone/.next/server/app/vr.segments/_tree.segment.rsc +2 -2
  356. package/.next/standalone/.next/server/app/vr.segments/vr/__PAGE__.segment.rsc +2 -2
  357. package/.next/standalone/.next/server/app/vr.segments/vr.segment.rsc +1 -1
  358. package/.next/standalone/.next/server/app/workspaces.html +1 -1
  359. package/.next/standalone/.next/server/app/workspaces.rsc +2 -2
  360. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces/__PAGE__.segment.rsc +1 -1
  361. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap/workspaces.segment.rsc +1 -1
  362. package/.next/standalone/.next/server/app/workspaces.segments/!KGRlc2t0b3Ap.segment.rsc +1 -1
  363. package/.next/standalone/.next/server/app/workspaces.segments/_full.segment.rsc +2 -2
  364. package/.next/standalone/.next/server/app/workspaces.segments/_head.segment.rsc +1 -1
  365. package/.next/standalone/.next/server/app/workspaces.segments/_index.segment.rsc +2 -2
  366. package/.next/standalone/.next/server/app/workspaces.segments/_tree.segment.rsc +2 -2
  367. package/.next/standalone/.next/server/app-paths-manifest.json +1 -0
  368. package/.next/standalone/.next/server/chunks/[root-of-the-server]__00e90fc6._.js +98 -0
  369. package/.next/standalone/.next/server/chunks/[root-of-the-server]__01ab8675._.js +98 -0
  370. package/.next/standalone/.next/server/chunks/[root-of-the-server]__03974f05._.js +98 -0
  371. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__bb331da9._.js → [root-of-the-server]__046c9b91._.js} +3 -3
  372. package/.next/standalone/.next/server/chunks/[root-of-the-server]__04ae6bf0._.js +98 -0
  373. package/.next/standalone/.next/server/chunks/[root-of-the-server]__056fa416._.js +1 -1
  374. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0ac4ea3f._.js +3 -0
  375. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0b8e64cb._.js +98 -0
  376. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__d95165f0._.js → [root-of-the-server]__0facd39e._.js} +3 -3
  377. package/.next/standalone/.next/server/chunks/[root-of-the-server]__10bc76a3._.js +3 -0
  378. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__9d68157b._.js → [root-of-the-server]__115f3934._.js} +3 -3
  379. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11f155f1._.js +3 -0
  380. package/.next/standalone/.next/server/chunks/[root-of-the-server]__160e7c73._.js +22 -33
  381. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__91e23c96._.js → [root-of-the-server]__17a3b966._.js} +3 -3
  382. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__277d9445._.js → [root-of-the-server]__17d3a2b2._.js} +3 -3
  383. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1a86c055._.js +98 -0
  384. package/.next/standalone/.next/server/chunks/[root-of-the-server]__20b5e9c4._.js +3 -0
  385. package/.next/standalone/.next/server/chunks/[root-of-the-server]__28d6fbd8._.js +98 -0
  386. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__04f04898._.js → [root-of-the-server]__2a3f866b._.js} +2 -2
  387. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__a95bb38b._.js → [root-of-the-server]__316617e7._.js} +2 -2
  388. package/.next/standalone/.next/server/chunks/[root-of-the-server]__32ad8f71._.js +98 -0
  389. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__6fe5e6c8._.js → [root-of-the-server]__35457394._.js} +2 -2
  390. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__1f054c65._.js → [root-of-the-server]__35de78e6._.js} +3 -3
  391. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3685ffcb._.js +98 -0
  392. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__614458b7._.js → [root-of-the-server]__38954988._.js} +3 -3
  393. package/.next/standalone/.next/server/chunks/[root-of-the-server]__426ad936._.js +106 -0
  394. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4985c034._.js +98 -0
  395. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5c6ce9ed._.js +98 -0
  396. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5cebe58a._.js +98 -0
  397. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5d5e4789._.js +98 -0
  398. package/.next/standalone/.next/server/chunks/[root-of-the-server]__65676930._.js +3 -0
  399. package/.next/standalone/.next/server/chunks/[root-of-the-server]__67cab326._.js +58 -0
  400. package/.next/standalone/.next/server/chunks/[root-of-the-server]__698c6f01._.js +98 -0
  401. package/.next/standalone/.next/server/chunks/[root-of-the-server]__6c64af29._.js +131 -0
  402. package/.next/standalone/.next/server/chunks/[root-of-the-server]__73aed9f5._.js +98 -0
  403. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__ac84b704._.js → [root-of-the-server]__79b6a9bb._.js} +3 -3
  404. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__e56abacf._.js → [root-of-the-server]__7db704c6._.js} +4 -4
  405. package/.next/standalone/.next/server/chunks/[root-of-the-server]__812ca02b._.js +98 -0
  406. package/.next/standalone/.next/server/chunks/[root-of-the-server]__821f50fa._.js +98 -0
  407. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8716b86e._.js +98 -0
  408. package/.next/standalone/.next/server/chunks/[root-of-the-server]__884ef754._.js +98 -0
  409. package/.next/standalone/.next/server/chunks/[root-of-the-server]__88cdbd68._.js +98 -0
  410. package/.next/standalone/.next/server/chunks/[root-of-the-server]__89d9aba9._.js +98 -0
  411. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8d536cb5._.js +98 -0
  412. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8df8c5d1._.js +98 -0
  413. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__2d7a454e._.js → [root-of-the-server]__8f2ccc41._.js} +3 -3
  414. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__2a2c5fc5._.js → [root-of-the-server]__95c9d682._.js} +4 -4
  415. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9e5d7774._.js +98 -0
  416. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__cc6e2885._.js → [root-of-the-server]__9edcff87._.js} +2 -2
  417. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a049dfc2._.js +98 -0
  418. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a5b4bb9a._.js +98 -0
  419. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__929ea03a._.js → [root-of-the-server]__a83262a1._.js} +2 -2
  420. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9cd1240._.js +98 -0
  421. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a9d7f822._.js +98 -0
  422. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad08c221._.js +98 -0
  423. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad585f2f._.js +98 -0
  424. package/.next/standalone/.next/server/chunks/[root-of-the-server]__afcb8f7d._.js +98 -0
  425. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bc250d43._.js +98 -0
  426. package/.next/standalone/.next/server/chunks/[root-of-the-server]__bce2a6e7._.js +98 -0
  427. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c011bf91._.js +98 -0
  428. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c0ac2895._.js +3 -0
  429. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c130a00c._.js +1 -1
  430. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c37d6380._.js +3 -0
  431. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cae392eb._.js +98 -0
  432. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cc2616bb._.js +3 -3
  433. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d501fa9b._.js +98 -0
  434. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d59c6c15._.js +98 -0
  435. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d5c1db32._.js +98 -0
  436. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d5d92527._.js +1 -1
  437. package/.next/standalone/.next/server/chunks/[root-of-the-server]__dba60c86._.js +98 -0
  438. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__2384f98e._.js → [root-of-the-server]__de14b9ae._.js} +3 -3
  439. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e10643d1._.js +98 -0
  440. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__00fdfbda._.js → [root-of-the-server]__e2a996e5._.js} +2 -2
  441. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__4d903941._.js → [root-of-the-server]__e3477417._.js} +3 -3
  442. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__32dc5513._.js → [root-of-the-server]__e4db362e._.js} +2 -2
  443. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__49e42a3a._.js → [root-of-the-server]__e4e70b86._.js} +3 -3
  444. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__ac39ecc7._.js → [root-of-the-server]__e54925af._.js} +3 -3
  445. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e8edc5b0._.js +98 -0
  446. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__eafd040b._.js → [root-of-the-server]__eab4d83b._.js} +2 -2
  447. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ead29015._.js +1 -1
  448. package/.next/standalone/.next/server/chunks/{[root-of-the-server]__194955d4._.js → [root-of-the-server]__f056fd83._.js} +3 -3
  449. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f0e99572._.js +98 -0
  450. package/.next/standalone/.next/server/chunks/[root-of-the-server]__fe1e16d0._.js +98 -0
  451. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ff9cd277._.js +98 -0
  452. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ffaea2ce._.js +98 -0
  453. package/.next/standalone/.next/server/chunks/_next-internal_server_app_api_wizard_chart_route_actions_888e2ec1.js +3 -0
  454. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__2cffc362._.js +3 -0
  455. package/.next/standalone/.next/server/chunks/ssr/{[root-of-the-server]__f1050870._.js → [root-of-the-server]__47c97637._.js} +2 -2
  456. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__66aca5d4._.js +1 -1
  457. package/.next/standalone/.next/server/chunks/ssr/_17b946fd._.js +3 -0
  458. package/.next/standalone/.next/server/chunks/ssr/_2a1d79e7._.js +1 -1
  459. package/.next/standalone/.next/server/chunks/ssr/_5c3c4cfa._.js +7 -5
  460. package/.next/standalone/.next/server/chunks/ssr/_ba432382._.js +7 -5
  461. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_cortex_page_tsx_0f33d8b3._.js +1 -1
  462. package/.next/standalone/.next/server/chunks/ssr/src_app_(desktop)_terminal_page_tsx_de5e8d85._.js +4 -4
  463. package/.next/standalone/.next/server/edge/chunks/[root-of-the-server]__90eeddae._.js +1 -1
  464. package/.next/standalone/.next/server/middleware-manifest.json +5 -5
  465. package/.next/standalone/.next/server/pages/404.html +1 -1
  466. package/.next/standalone/.next/server/pages/500.html +2 -2
  467. package/.next/standalone/.next/server/server-reference-manifest.js +1 -1
  468. package/.next/standalone/.next/server/server-reference-manifest.json +1 -1
  469. package/.next/standalone/.next/static/chunks/0852575eb90c1e8d.js +85 -0
  470. package/.next/standalone/.next/static/chunks/{74d0ac0b1d0a1b79.js → 10b00b4f66102dcf.js} +1 -1
  471. package/.next/standalone/.next/static/chunks/{16eb77953dee9ea3.js → 19c71a8376c23c58.js} +1 -1
  472. package/.next/standalone/.next/static/chunks/2b769d1597e4fc1c.css +3 -0
  473. package/.next/standalone/.next/static/chunks/{3e91fc608659c524.js → 350271fe79509caf.js} +1 -1
  474. package/.next/standalone/.next/static/chunks/{70423c7afd8abf5f.js → 597847c22200c212.js} +1 -1
  475. package/.next/standalone/.next/static/chunks/{fb0abd1933b2b2e1.js → 7f6a14f1849fa94d.js} +1 -1
  476. package/.next/standalone/.next/static/chunks/{7ecd9bbb0ce4d68a.js → b7c8fe9b7275a84f.js} +1 -1
  477. package/.next/standalone/.next/static/chunks/{6245135a7afb8c7b.js → c9b10fc55516d142.js} +8 -6
  478. package/.next/standalone/.next/static/chunks/d0065f48eab94944.js +1 -0
  479. package/.next/standalone/.next/static/chunks/{180c1b9ff31b979f.js → f7b34c807badf95d.js} +8 -6
  480. package/.next/standalone/.spaces/cortex-context.md +50 -144
  481. package/.next/standalone/LICENSE +661 -661
  482. package/.next/standalone/NOTICE +5 -5
  483. package/.next/standalone/README.md +131 -131
  484. package/.next/standalone/bin/cortex-hook.js +79 -79
  485. package/.next/standalone/bin/cortex-hook.sh +62 -62
  486. package/.next/standalone/bin/cortex-learn-hook.js +138 -138
  487. package/.next/standalone/bin/cortex-mcp.js +60 -60
  488. package/.next/standalone/bin/cortex-pi-extension.ts +170 -170
  489. package/.next/standalone/bin/fix-standalone-externals.js +79 -79
  490. package/.next/standalone/bin/lib/auto-setup.js +110 -110
  491. package/.next/standalone/bin/mdns-service.js +171 -171
  492. package/.next/standalone/bin/postinstall.js +35 -35
  493. package/.next/standalone/bin/setup-admin.js +195 -195
  494. package/.next/standalone/bin/spaces-dev.js +247 -247
  495. package/.next/standalone/bin/spaces-install.js +660 -660
  496. package/.next/standalone/bin/spaces-postinstall.js +50 -50
  497. package/.next/standalone/bin/spaces-reset-totp.js +50 -50
  498. package/.next/standalone/bin/spaces-service.js +1046 -1046
  499. package/.next/standalone/bin/spaces-setup.js +253 -253
  500. package/.next/standalone/bin/spaces.js +808 -805
  501. package/.next/standalone/bin/ssh-auth-keys.sh +68 -68
  502. package/.next/standalone/bin/terminal-server.js +2819 -2781
  503. package/.next/standalone/cortex-hook-debug.log +57 -23
  504. package/.next/standalone/docker-compose.yml +28 -28
  505. package/.next/standalone/docs/architecture.md +387 -387
  506. package/.next/standalone/docs/cortex-integration-reference.md +268 -268
  507. package/.next/standalone/docs/cortex.md +293 -293
  508. package/.next/standalone/docs/getting-started.md +96 -96
  509. package/.next/standalone/docs/plans/2026-02-24-multi-agent-sessions-design.md +133 -133
  510. package/.next/standalone/docs/plans/2026-02-24-multi-agent-sessions-plan.md +959 -959
  511. package/.next/standalone/docs/plans/2026-03-02-security-audit.md +229 -229
  512. package/.next/standalone/docs/plans/2026-03-07-service-command-design.md +146 -146
  513. package/.next/standalone/docs/plans/2026-03-07-service-command-plan.md +254 -254
  514. package/.next/standalone/docs/server-install.md +564 -564
  515. package/.next/standalone/docs/social-card.html +150 -150
  516. package/.next/standalone/docs/superpowers/plans/2026-03-12-spaces-cortex.md +5270 -5270
  517. package/.next/standalone/docs/superpowers/plans/2026-03-13-cortex-wiring.md +1387 -1387
  518. package/.next/standalone/docs/superpowers/plans/2026-03-14-cortex-v2-entity-graph.md +1923 -1923
  519. package/.next/standalone/docs/superpowers/plans/2026-03-14-cortex-v2-knowledge-evolution.md +1113 -1113
  520. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-boundary-engine.md +853 -853
  521. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-context-engine.md +1274 -1274
  522. package/.next/standalone/docs/superpowers/plans/2026-03-15-cortex-v2-signal-ingestion.md +933 -933
  523. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-lobes.md +1080 -1080
  524. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-v2-gravity-system.md +768 -768
  525. package/.next/standalone/docs/superpowers/plans/2026-03-16-cortex-v2-ui.md +1108 -1108
  526. package/.next/standalone/docs/superpowers/plans/2026-03-18-cortex-ui-integration.md +1846 -1846
  527. package/.next/standalone/docs/superpowers/plans/2026-03-19-vr-phase1-shell.md +1639 -1639
  528. package/.next/standalone/docs/superpowers/plans/2026-03-27-dockview-pane-layout.md +98 -98
  529. package/.next/standalone/docs/superpowers/specs/2026-03-11-universe-view-design.md +320 -320
  530. package/.next/standalone/docs/superpowers/specs/2026-03-12-spaces-brain-design.md +720 -720
  531. package/.next/standalone/docs/superpowers/specs/2026-03-13-cortex-wiring-design.md +268 -268
  532. package/.next/standalone/docs/superpowers/specs/2026-03-14-cortex-v2-design.md +623 -623
  533. package/.next/standalone/docs/superpowers/specs/2026-03-16-cortex-lobes-design.md +263 -263
  534. package/.next/standalone/docs/superpowers/specs/2026-03-16-cortex-v2-ui-design.md +240 -240
  535. package/.next/standalone/docs/superpowers/specs/2026-03-16-pane-ux-design.md +77 -77
  536. package/.next/standalone/docs/superpowers/specs/2026-03-18-cortex-ui-integration-design.md +341 -341
  537. package/.next/standalone/docs/superpowers/specs/2026-03-19-vr-phase1-shell-design.md +288 -288
  538. package/.next/standalone/docs/superpowers/specs/2026-03-27-pane-diff-review-and-project-wizard-design.md +322 -322
  539. package/.next/standalone/docs/tiers.md +104 -104
  540. package/.next/standalone/eslint.config.mjs +18 -18
  541. package/.next/standalone/next.config.ts +20 -20
  542. package/.next/standalone/nginx.conf +53 -53
  543. package/.next/standalone/node_modules/@img/sharp-win32-x64/lib/sharp-win32-x64.node +0 -0
  544. package/.next/standalone/node_modules/@img/{sharp-linux-x64 → sharp-win32-x64}/package.json +39 -46
  545. package/.next/standalone/package-lock.json +14985 -14986
  546. package/.next/standalone/package.json +111 -111
  547. package/.next/standalone/postcss.config.mjs +7 -7
  548. package/.next/standalone/scripts/rebuild.cmd +65 -65
  549. package/.next/standalone/scripts/rebuild.sh +59 -59
  550. package/.next/standalone/server.js +1 -1
  551. package/.next/standalone/src/app/(desktop)/admin/analytics/page.tsx +266 -266
  552. package/.next/standalone/src/app/(desktop)/admin/users/page.tsx +399 -399
  553. package/.next/standalone/src/app/(desktop)/analytics/page.tsx +166 -166
  554. package/.next/standalone/src/app/(desktop)/cortex/page.tsx +81 -81
  555. package/.next/standalone/src/app/(desktop)/dashboard-client.tsx +56 -56
  556. package/.next/standalone/src/app/(desktop)/layout.tsx +18 -18
  557. package/.next/standalone/src/app/(desktop)/network/page.tsx +137 -137
  558. package/.next/standalone/src/app/(desktop)/page.tsx +17 -17
  559. package/.next/standalone/src/app/(desktop)/projects/page.tsx +68 -68
  560. package/.next/standalone/src/app/(desktop)/sessions/[id]/page.tsx +519 -519
  561. package/.next/standalone/src/app/(desktop)/sessions/page.tsx +145 -145
  562. package/.next/standalone/src/app/(desktop)/settings/page.tsx +446 -446
  563. package/.next/standalone/src/app/(desktop)/terminal/layout.tsx +7 -7
  564. package/.next/standalone/src/app/(desktop)/terminal/page.tsx +1330 -1291
  565. package/.next/standalone/src/app/(desktop)/terminal/pane/[id]/page.tsx +211 -211
  566. package/.next/standalone/src/app/(desktop)/terminal/remote/[nodeId]/[workspaceId]/page.tsx +252 -252
  567. package/.next/standalone/src/app/(desktop)/workspaces/page.tsx +12 -12
  568. package/.next/standalone/src/app/api/admin/analytics/route.ts +10 -10
  569. package/.next/standalone/src/app/api/admin/users/[id]/route.ts +20 -20
  570. package/.next/standalone/src/app/api/admin/users/route.ts +15 -15
  571. package/.next/standalone/src/app/api/analytics/overview/route.ts +80 -80
  572. package/.next/standalone/src/app/api/auth/login/route.ts +10 -10
  573. package/.next/standalone/src/app/api/auth/logout/route.ts +9 -9
  574. package/.next/standalone/src/app/api/auth/me/route.ts +22 -22
  575. package/.next/standalone/src/app/api/auth/totp/setup/route.ts +10 -10
  576. package/.next/standalone/src/app/api/auth/totp/status/route.ts +10 -10
  577. package/.next/standalone/src/app/api/auth/totp/verify/route.ts +10 -10
  578. package/.next/standalone/src/app/api/benchmark/lobes/route.ts +16 -16
  579. package/.next/standalone/src/app/api/benchmark/run/route.ts +113 -92
  580. package/.next/standalone/src/app/api/benchmark/runs/[id]/route.ts +26 -26
  581. package/.next/standalone/src/app/api/benchmark/runs/route.ts +16 -16
  582. package/.next/standalone/src/app/api/benchmark/status/route.ts +35 -35
  583. package/.next/standalone/src/app/api/bulk/route.ts +34 -34
  584. package/.next/standalone/src/app/api/chat/route.ts +85 -85
  585. package/.next/standalone/src/app/api/config/route.ts +30 -30
  586. package/.next/standalone/src/app/api/cortex/context/route.ts +78 -78
  587. package/.next/standalone/src/app/api/cortex/curation/assess/route.ts +27 -27
  588. package/.next/standalone/src/app/api/cortex/curation/publish/route.ts +23 -23
  589. package/.next/standalone/src/app/api/cortex/curation/refine/route.ts +23 -23
  590. package/.next/standalone/src/app/api/cortex/curation/review/route.ts +29 -29
  591. package/.next/standalone/src/app/api/cortex/curation/seed/route.ts +23 -23
  592. package/.next/standalone/src/app/api/cortex/export/route.ts +40 -40
  593. package/.next/standalone/src/app/api/cortex/federation/pending/route.ts +20 -20
  594. package/.next/standalone/src/app/api/cortex/federation/resolve/route.ts +43 -43
  595. package/.next/standalone/src/app/api/cortex/federation/search/route.ts +35 -35
  596. package/.next/standalone/src/app/api/cortex/federation/teach/route.ts +76 -76
  597. package/.next/standalone/src/app/api/cortex/graph/edges/route.ts +112 -112
  598. package/.next/standalone/src/app/api/cortex/graph/entities/[id]/route.ts +73 -73
  599. package/.next/standalone/src/app/api/cortex/graph/entities/route.ts +75 -75
  600. package/.next/standalone/src/app/api/cortex/graph/populate/route.ts +203 -203
  601. package/.next/standalone/src/app/api/cortex/import/route.ts +75 -75
  602. package/.next/standalone/src/app/api/cortex/import/status/route.ts +15 -15
  603. package/.next/standalone/src/app/api/cortex/ingest/bootstrap/route.ts +39 -39
  604. package/.next/standalone/src/app/api/cortex/ingest/status/route.ts +15 -15
  605. package/.next/standalone/src/app/api/cortex/knowledge/[id]/route.ts +91 -91
  606. package/.next/standalone/src/app/api/cortex/knowledge/route.ts +97 -97
  607. package/.next/standalone/src/app/api/cortex/lobes/[id]/route.ts +67 -67
  608. package/.next/standalone/src/app/api/cortex/lobes/route.ts +22 -22
  609. package/.next/standalone/src/app/api/cortex/lobes/share/route.ts +80 -80
  610. package/.next/standalone/src/app/api/cortex/marketplace/browse/route.ts +43 -43
  611. package/.next/standalone/src/app/api/cortex/marketplace/preview/route.ts +46 -46
  612. package/.next/standalone/src/app/api/cortex/mcp/call/route.ts +11 -11
  613. package/.next/standalone/src/app/api/cortex/mcp/tools/route.ts +8 -8
  614. package/.next/standalone/src/app/api/cortex/search/route.ts +57 -45
  615. package/.next/standalone/src/app/api/cortex/settings/route.ts +35 -35
  616. package/.next/standalone/src/app/api/cortex/status/route.ts +169 -169
  617. package/.next/standalone/src/app/api/cortex/timeline/route.ts +42 -42
  618. package/.next/standalone/src/app/api/cortex/usage/route.ts +31 -31
  619. package/.next/standalone/src/app/api/cortex/workspace/[id]/context/route.ts +41 -41
  620. package/.next/standalone/src/app/api/events/route.ts +40 -40
  621. package/.next/standalone/src/app/api/files/route.ts +187 -187
  622. package/.next/standalone/src/app/api/folders/route.ts +107 -97
  623. package/.next/standalone/src/app/api/network/connect-callback/route.ts +11 -11
  624. package/.next/standalone/src/app/api/network/connect-request/[id]/route.ts +11 -11
  625. package/.next/standalone/src/app/api/network/connect-request/route.ts +17 -17
  626. package/.next/standalone/src/app/api/network/discovered/route.ts +9 -9
  627. package/.next/standalone/src/app/api/network/handshake/route.ts +25 -25
  628. package/.next/standalone/src/app/api/network/health/route.ts +10 -10
  629. package/.next/standalone/src/app/api/network/identity/route.ts +15 -15
  630. package/.next/standalone/src/app/api/network/keys/[id]/route.ts +10 -10
  631. package/.next/standalone/src/app/api/network/keys/route.ts +15 -15
  632. package/.next/standalone/src/app/api/network/nodes/[id]/route.ts +15 -15
  633. package/.next/standalone/src/app/api/network/nodes/check/route.ts +9 -9
  634. package/.next/standalone/src/app/api/network/nodes/route.ts +15 -15
  635. package/.next/standalone/src/app/api/network/panes/[id]/route.ts +78 -62
  636. package/.next/standalone/src/app/api/network/panes/route.ts +61 -50
  637. package/.next/standalone/src/app/api/network/projects/route.ts +32 -25
  638. package/.next/standalone/src/app/api/network/proxy/[nodeId]/[...path]/route.ts +25 -25
  639. package/.next/standalone/src/app/api/network/search/route.ts +45 -38
  640. package/.next/standalone/src/app/api/network/sessions/[id]/messages/route.ts +43 -36
  641. package/.next/standalone/src/app/api/network/sessions/[id]/route.ts +41 -34
  642. package/.next/standalone/src/app/api/network/sessions/route.ts +50 -43
  643. package/.next/standalone/src/app/api/network/terminal/token/route.ts +10 -10
  644. package/.next/standalone/src/app/api/network/workspaces/[id]/route.ts +80 -71
  645. package/.next/standalone/src/app/api/network/workspaces/route.ts +87 -85
  646. package/.next/standalone/src/app/api/panes/[id]/diff/route.ts +121 -121
  647. package/.next/standalone/src/app/api/panes/[id]/route.ts +60 -60
  648. package/.next/standalone/src/app/api/panes/route.ts +39 -39
  649. package/.next/standalone/src/app/api/projects/route.ts +13 -13
  650. package/.next/standalone/src/app/api/proxy/models/[modelId]/[...path]/route.ts +80 -80
  651. package/.next/standalone/src/app/api/proxy/models/[modelId]/status/route.ts +33 -33
  652. package/.next/standalone/src/app/api/search/route.ts +47 -47
  653. package/.next/standalone/src/app/api/sessions/[id]/chat/route.ts +120 -120
  654. package/.next/standalone/src/app/api/sessions/[id]/messages/route.ts +34 -34
  655. package/.next/standalone/src/app/api/sessions/[id]/route.ts +73 -73
  656. package/.next/standalone/src/app/api/sessions/route.ts +64 -64
  657. package/.next/standalone/src/app/api/sync/route.ts +24 -24
  658. package/.next/standalone/src/app/api/tags/route.ts +35 -35
  659. package/.next/standalone/src/app/api/tier/route.ts +16 -16
  660. package/.next/standalone/src/app/api/updates/route.ts +65 -65
  661. package/.next/standalone/src/app/api/whisper/config/route.ts +50 -42
  662. package/.next/standalone/src/app/api/whisper/route.ts +91 -91
  663. package/.next/standalone/src/app/api/wizard/chart/route.ts +129 -0
  664. package/.next/standalone/src/app/api/wizard/chat/route.ts +113 -113
  665. package/.next/standalone/src/app/api/workspaces/[id]/context/[key]/route.ts +39 -39
  666. package/.next/standalone/src/app/api/workspaces/[id]/context/route.ts +28 -28
  667. package/.next/standalone/src/app/api/workspaces/[id]/messages/[msgId]/route.ts +17 -17
  668. package/.next/standalone/src/app/api/workspaces/[id]/messages/route.ts +39 -39
  669. package/.next/standalone/src/app/api/workspaces/[id]/route.ts +47 -47
  670. package/.next/standalone/src/app/api/workspaces/[id]/sessions/route.ts +62 -62
  671. package/.next/standalone/src/app/api/workspaces/route.ts +79 -79
  672. package/.next/standalone/src/app/globals.css +88 -88
  673. package/.next/standalone/src/app/layout.tsx +33 -33
  674. package/.next/standalone/src/app/login/layout.tsx +7 -7
  675. package/.next/standalone/src/app/login/page.tsx +315 -315
  676. package/.next/standalone/src/app/m/layout.tsx +16 -16
  677. package/.next/standalone/src/app/m/page.tsx +118 -118
  678. package/.next/standalone/src/app/m/projects/page.tsx +64 -64
  679. package/.next/standalone/src/app/m/sessions/[id]/page.tsx +168 -168
  680. package/.next/standalone/src/app/m/sessions/page.tsx +177 -177
  681. package/.next/standalone/src/app/m/settings/page.tsx +230 -230
  682. package/.next/standalone/src/app/m/terminal/page.tsx +413 -413
  683. package/.next/standalone/src/app/vr/page.tsx +21 -21
  684. package/.next/standalone/src/app/vr/vr-app.tsx +163 -163
  685. package/.next/standalone/src/app/vr/vr-controls.tsx +139 -139
  686. package/.next/standalone/src/app/vr/vr-door.tsx +82 -82
  687. package/.next/standalone/src/app/vr/vr-environment.tsx +71 -71
  688. package/.next/standalone/src/app/vr/vr-gaze.tsx +89 -89
  689. package/.next/standalone/src/app/vr/vr-layout.ts +49 -49
  690. package/.next/standalone/src/app/vr/vr-lobby.tsx +97 -97
  691. package/.next/standalone/src/app/vr/vr-pane.tsx +195 -195
  692. package/.next/standalone/src/app/vr/vr-room.tsx +79 -79
  693. package/.next/standalone/src/app/vr/vr-terminal.tsx +303 -303
  694. package/.next/standalone/src/components/auth/totp-gate.tsx +183 -183
  695. package/.next/standalone/src/components/bus/activity-panel.tsx +261 -261
  696. package/.next/standalone/src/components/common/color-picker.tsx +35 -35
  697. package/.next/standalone/src/components/common/dev-directory-picker.tsx +339 -339
  698. package/.next/standalone/src/components/common/folder-picker.tsx +200 -200
  699. package/.next/standalone/src/components/common/tag-picker.tsx +190 -190
  700. package/.next/standalone/src/components/common/workspace-picker.tsx +113 -113
  701. package/.next/standalone/src/components/cortex/benchmark-tab.tsx +894 -880
  702. package/.next/standalone/src/components/cortex/constants.ts +29 -29
  703. package/.next/standalone/src/components/cortex/cortex-dashboard.tsx +304 -304
  704. package/.next/standalone/src/components/cortex/cortex-indicator.tsx +44 -44
  705. package/.next/standalone/src/components/cortex/cortex-panel.tsx +140 -140
  706. package/.next/standalone/src/components/cortex/cortex-settings.tsx +280 -280
  707. package/.next/standalone/src/components/cortex/curation-tab.tsx +810 -810
  708. package/.next/standalone/src/components/cortex/entity-detail.tsx +101 -101
  709. package/.next/standalone/src/components/cortex/entity-graph.tsx +382 -382
  710. package/.next/standalone/src/components/cortex/import-dialog.tsx +212 -212
  711. package/.next/standalone/src/components/cortex/injection-badge.tsx +72 -72
  712. package/.next/standalone/src/components/cortex/knowledge-card.tsx +109 -109
  713. package/.next/standalone/src/components/cortex/knowledge-tab.tsx +158 -158
  714. package/.next/standalone/src/components/cortex/lobe-settings.tsx +215 -215
  715. package/.next/standalone/src/components/cortex/marketplace-card.tsx +126 -126
  716. package/.next/standalone/src/components/cortex/marketplace-tab.tsx +113 -113
  717. package/.next/standalone/src/components/dashboard/activity-chart.tsx +41 -41
  718. package/.next/standalone/src/components/dashboard/model-usage-chart.tsx +61 -61
  719. package/.next/standalone/src/components/dashboard/recent-sessions.tsx +68 -68
  720. package/.next/standalone/src/components/dashboard/stats-cards.tsx +36 -36
  721. package/.next/standalone/src/components/files/file-explorer.tsx +703 -703
  722. package/.next/standalone/src/components/layout/providers.tsx +38 -38
  723. package/.next/standalone/src/components/layout/sidebar.tsx +170 -170
  724. package/.next/standalone/src/components/layout/tier-provider.tsx +53 -53
  725. package/.next/standalone/src/components/layout/update-banner.tsx +92 -92
  726. package/.next/standalone/src/components/mobile/bottom-nav.tsx +46 -46
  727. package/.next/standalone/src/components/mobile/immersive-voice-button.tsx +123 -123
  728. package/.next/standalone/src/components/mobile/mobile-chat-input.tsx +244 -244
  729. package/.next/standalone/src/components/mobile/mobile-header.tsx +44 -44
  730. package/.next/standalone/src/components/mobile/mobile-session-card.tsx +56 -56
  731. package/.next/standalone/src/components/mobile/mobile-terminal-input.tsx +74 -74
  732. package/.next/standalone/src/components/mobile/mobile-terminal-pane.tsx +302 -302
  733. package/.next/standalone/src/components/mobile/mobile-terminal-toolbar.tsx +76 -76
  734. package/.next/standalone/src/components/mobile/pull-to-refresh.tsx +82 -82
  735. package/.next/standalone/src/components/mobile/voice-input.tsx +53 -53
  736. package/.next/standalone/src/components/network/api-key-list.tsx +190 -190
  737. package/.next/standalone/src/components/network/connection-requests.tsx +94 -94
  738. package/.next/standalone/src/components/network/node-add-dialog.tsx +131 -131
  739. package/.next/standalone/src/components/network/node-badge.tsx +26 -26
  740. package/.next/standalone/src/components/network/node-list.tsx +207 -207
  741. package/.next/standalone/src/components/network/node-selector.tsx +49 -49
  742. package/.next/standalone/src/components/sessions/session-filters.tsx +116 -116
  743. package/.next/standalone/src/components/sessions/session-list.tsx +485 -485
  744. package/.next/standalone/src/components/terminal/pane-diff-panel.tsx +179 -179
  745. package/.next/standalone/src/components/terminal/terminal-pane.tsx +1530 -1464
  746. package/.next/standalone/src/components/viewer/chat-input.tsx +275 -275
  747. package/.next/standalone/src/components/viewer/message-renderer.tsx +551 -551
  748. package/.next/standalone/src/components/wizard/chart-wizard.tsx +405 -0
  749. package/.next/standalone/src/components/wizard/project-wizard.tsx +153 -153
  750. package/.next/standalone/src/components/wizard/wizard-chat.tsx +99 -99
  751. package/.next/standalone/src/components/wizard/wizard-plan-summary.tsx +103 -103
  752. package/.next/standalone/src/components/wizard/wizard-review.tsx +225 -225
  753. package/.next/standalone/src/components/workspace/universe-cluster.tsx +131 -131
  754. package/.next/standalone/src/components/workspace/universe-orb.tsx +128 -128
  755. package/.next/standalone/src/components/workspace/universe-types.ts +22 -22
  756. package/.next/standalone/src/components/workspace/universe-utils.ts +11 -11
  757. package/.next/standalone/src/components/workspace/universe-view.tsx +397 -397
  758. package/.next/standalone/src/components/workspace/workspace-chooser.tsx +634 -634
  759. package/.next/standalone/src/hooks/use-benchmark.ts +72 -71
  760. package/.next/standalone/src/hooks/use-bus.ts +147 -147
  761. package/.next/standalone/src/hooks/use-idle-detection.ts +79 -79
  762. package/.next/standalone/src/hooks/use-network.ts +229 -229
  763. package/.next/standalone/src/hooks/use-sessions.ts +437 -437
  764. package/.next/standalone/src/hooks/use-speech-recognition.ts +114 -113
  765. package/.next/standalone/src/hooks/use-sse.ts +35 -35
  766. package/.next/standalone/src/hooks/use-tier.ts +39 -39
  767. package/.next/standalone/src/lib/agents.ts +97 -97
  768. package/.next/standalone/src/lib/aider/parser.ts +111 -111
  769. package/.next/standalone/src/lib/api.ts +19 -19
  770. package/.next/standalone/src/lib/auth.ts +47 -47
  771. package/.next/standalone/src/lib/claude/parser.ts +212 -212
  772. package/.next/standalone/src/lib/claude/stats.ts +204 -204
  773. package/.next/standalone/src/lib/codex/parser.test.ts +111 -111
  774. package/.next/standalone/src/lib/codex/parser.ts +287 -287
  775. package/.next/standalone/src/lib/config.ts +132 -132
  776. package/.next/standalone/src/lib/cortex/benchmark.ts +83 -67
  777. package/.next/standalone/src/lib/cortex/config.ts +42 -42
  778. package/.next/standalone/src/lib/cortex/debug.ts +10 -10
  779. package/.next/standalone/src/lib/cortex/distillation/usage-store.ts +18 -18
  780. package/.next/standalone/src/lib/cortex/graph/resolver.ts +10 -10
  781. package/.next/standalone/src/lib/cortex/graph/types.ts +22 -22
  782. package/.next/standalone/src/lib/cortex/index.ts +109 -56
  783. package/.next/standalone/src/lib/cortex/ingestion/bootstrap.ts +14 -14
  784. package/.next/standalone/src/lib/cortex/knowledge/compat.ts +14 -14
  785. package/.next/standalone/src/lib/cortex/knowledge/contradiction.ts +10 -10
  786. package/.next/standalone/src/lib/cortex/knowledge/types.ts +67 -67
  787. package/.next/standalone/src/lib/cortex/lobes/config.ts +16 -16
  788. package/.next/standalone/src/lib/cortex/lobes/resolver.ts +8 -8
  789. package/.next/standalone/src/lib/cortex/lobes/shares.ts +14 -14
  790. package/.next/standalone/src/lib/cortex/mcp/server.ts +12 -12
  791. package/.next/standalone/src/lib/cortex/portability/exporter.ts +6 -6
  792. package/.next/standalone/src/lib/cortex/portability/importer.ts +10 -10
  793. package/.next/standalone/src/lib/cortex/retrieval/context-engine.ts +10 -10
  794. package/.next/standalone/src/lib/cortex/types.ts +39 -39
  795. package/.next/standalone/src/lib/cost-calculator.ts +48 -48
  796. package/.next/standalone/src/lib/db/init.ts +71 -71
  797. package/.next/standalone/src/lib/db/queries.ts +740 -827
  798. package/.next/standalone/src/lib/db/schema.ts +206 -206
  799. package/.next/standalone/src/lib/events/sse.ts +36 -36
  800. package/.next/standalone/src/lib/forge/parser.ts +52 -52
  801. package/.next/standalone/src/lib/gemini/parser.ts +258 -258
  802. package/.next/standalone/src/lib/license.ts +56 -56
  803. package/.next/standalone/src/lib/pro.ts +31 -31
  804. package/.next/standalone/src/lib/shell-user.ts +101 -0
  805. package/.next/standalone/src/lib/sync/indexer.ts +504 -504
  806. package/.next/standalone/src/lib/sync/watcher.ts +64 -64
  807. package/.next/standalone/src/lib/teams.ts +31 -31
  808. package/.next/standalone/src/lib/telemetry.ts +75 -75
  809. package/.next/standalone/src/lib/terminal/server.ts +188 -188
  810. package/.next/standalone/src/lib/tier.ts +38 -38
  811. package/.next/standalone/src/lib/utils.ts +72 -72
  812. package/.next/standalone/src/lib/vms/manager.ts +121 -121
  813. package/.next/standalone/src/middleware.ts +133 -133
  814. package/.next/standalone/src/types/claude.ts +208 -208
  815. package/.next/standalone/src/types/network.ts +61 -61
  816. package/.next/standalone/tests/setup.ts +8 -8
  817. package/.next/standalone/tsconfig.json +34 -34
  818. package/.next/standalone/vitest.config.ts +24 -24
  819. package/LICENSE +661 -661
  820. package/README.md +131 -131
  821. package/bin/cortex-hook.js +79 -79
  822. package/bin/cortex-hook.sh +62 -62
  823. package/bin/cortex-learn-hook.js +138 -138
  824. package/bin/cortex-mcp.js +60 -60
  825. package/bin/cortex-pi-extension.ts +170 -170
  826. package/bin/fix-standalone-externals.js +79 -79
  827. package/bin/lib/auto-setup.js +110 -110
  828. package/bin/mdns-service.js +171 -171
  829. package/bin/postinstall.js +35 -35
  830. package/bin/setup-admin.js +195 -195
  831. package/bin/spaces-dev.js +247 -247
  832. package/bin/spaces-install.js +660 -660
  833. package/bin/spaces-postinstall.js +50 -50
  834. package/bin/spaces-reset-totp.js +50 -50
  835. package/bin/spaces-service.js +1046 -1046
  836. package/bin/spaces-setup.js +253 -253
  837. package/bin/spaces.js +808 -805
  838. package/bin/ssh-auth-keys.sh +68 -68
  839. package/bin/terminal-server.js +2819 -2781
  840. package/package.json +111 -111
  841. package/.next/standalone/.next/server/chunks/[root-of-the-server]__0903a426._.js +0 -98
  842. package/.next/standalone/.next/server/chunks/[root-of-the-server]__09e8ccc9._.js +0 -98
  843. package/.next/standalone/.next/server/chunks/[root-of-the-server]__11c684b1._.js +0 -98
  844. package/.next/standalone/.next/server/chunks/[root-of-the-server]__1572d4ef._.js +0 -98
  845. package/.next/standalone/.next/server/chunks/[root-of-the-server]__186cd0bb._.js +0 -3
  846. package/.next/standalone/.next/server/chunks/[root-of-the-server]__212760e6._.js +0 -98
  847. package/.next/standalone/.next/server/chunks/[root-of-the-server]__228595ec._.js +0 -98
  848. package/.next/standalone/.next/server/chunks/[root-of-the-server]__283c890f._.js +0 -3
  849. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2f300a68._.js +0 -98
  850. package/.next/standalone/.next/server/chunks/[root-of-the-server]__2f452778._.js +0 -98
  851. package/.next/standalone/.next/server/chunks/[root-of-the-server]__35f8e77e._.js +0 -98
  852. package/.next/standalone/.next/server/chunks/[root-of-the-server]__379fc2e9._.js +0 -98
  853. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3b40d79f._.js +0 -98
  854. package/.next/standalone/.next/server/chunks/[root-of-the-server]__3d3dca2b._.js +0 -98
  855. package/.next/standalone/.next/server/chunks/[root-of-the-server]__4d5b78d2._.js +0 -98
  856. package/.next/standalone/.next/server/chunks/[root-of-the-server]__54163e52._.js +0 -98
  857. package/.next/standalone/.next/server/chunks/[root-of-the-server]__563c0817._.js +0 -3
  858. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5812f90a._.js +0 -98
  859. package/.next/standalone/.next/server/chunks/[root-of-the-server]__5c5e87f5._.js +0 -98
  860. package/.next/standalone/.next/server/chunks/[root-of-the-server]__60d15b16._.js +0 -98
  861. package/.next/standalone/.next/server/chunks/[root-of-the-server]__69d315e5._.js +0 -3
  862. package/.next/standalone/.next/server/chunks/[root-of-the-server]__71f29038._.js +0 -98
  863. package/.next/standalone/.next/server/chunks/[root-of-the-server]__74084e07._.js +0 -3
  864. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7921aa80._.js +0 -98
  865. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7e077dd8._.js +0 -98
  866. package/.next/standalone/.next/server/chunks/[root-of-the-server]__7ebc4280._.js +0 -131
  867. package/.next/standalone/.next/server/chunks/[root-of-the-server]__857c60bb._.js +0 -98
  868. package/.next/standalone/.next/server/chunks/[root-of-the-server]__874fe565._.js +0 -98
  869. package/.next/standalone/.next/server/chunks/[root-of-the-server]__8e2171f7._.js +0 -98
  870. package/.next/standalone/.next/server/chunks/[root-of-the-server]__95659b2d._.js +0 -98
  871. package/.next/standalone/.next/server/chunks/[root-of-the-server]__9679b91e._.js +0 -98
  872. package/.next/standalone/.next/server/chunks/[root-of-the-server]__a90729a1._.js +0 -98
  873. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ad4346fa._.js +0 -98
  874. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b0862d69._.js +0 -98
  875. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b43306ee._.js +0 -98
  876. package/.next/standalone/.next/server/chunks/[root-of-the-server]__b689ff5e._.js +0 -106
  877. package/.next/standalone/.next/server/chunks/[root-of-the-server]__ba87daaa._.js +0 -98
  878. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c0461005._.js +0 -98
  879. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c1deb5f3._.js +0 -98
  880. package/.next/standalone/.next/server/chunks/[root-of-the-server]__c8a62f42._.js +0 -98
  881. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cabaac2b._.js +0 -98
  882. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cb027619._.js +0 -98
  883. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cf608218._.js +0 -98
  884. package/.next/standalone/.next/server/chunks/[root-of-the-server]__cfc1290d._.js +0 -98
  885. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d0109b9b._.js +0 -98
  886. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d0125483._.js +0 -3
  887. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d048ee6b._.js +0 -98
  888. package/.next/standalone/.next/server/chunks/[root-of-the-server]__d12644e7._.js +0 -98
  889. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e3cc946c._.js +0 -98
  890. package/.next/standalone/.next/server/chunks/[root-of-the-server]__e6fd27f8._.js +0 -98
  891. package/.next/standalone/.next/server/chunks/[root-of-the-server]__efb8251e._.js +0 -98
  892. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f44c6882._.js +0 -98
  893. package/.next/standalone/.next/server/chunks/[root-of-the-server]__f85283de._.js +0 -98
  894. package/.next/standalone/.next/server/chunks/[root-of-the-server]__feceb3e4._.js +0 -98
  895. package/.next/standalone/.next/server/chunks/ssr/[root-of-the-server]__843070a6._.js +0 -3
  896. package/.next/standalone/.next/server/chunks/ssr/_e84a0c06._.js +0 -3
  897. package/.next/standalone/.next/static/chunks/470cade58d4eceeb.css +0 -3
  898. package/.next/standalone/.next/static/chunks/9d4164833c2c1fd6.js +0 -85
  899. package/.next/standalone/.next/static/chunks/f091f4bf8d80fd07.js +0 -1
  900. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/README.md +0 -46
  901. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  902. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/index.js +0 -1
  903. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  904. package/.next/standalone/node_modules/@img/sharp-libvips-linux-x64/package.json +0 -42
  905. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/README.md +0 -46
  906. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/glib-2.0/include/glibconfig.h +0 -221
  907. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/index.js +0 -1
  908. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/lib/libvips-cpp.so.8.17.3 +0 -0
  909. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/package.json +0 -42
  910. package/.next/standalone/node_modules/@img/sharp-libvips-linuxmusl-x64/versions.json +0 -30
  911. package/.next/standalone/node_modules/@img/sharp-linux-x64/lib/sharp-linux-x64.node +0 -0
  912. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/lib/sharp-linuxmusl-x64.node +0 -0
  913. package/.next/standalone/node_modules/@img/sharp-linuxmusl-x64/package.json +0 -46
  914. /package/.next/standalone/.next/static/{5S4TviTCiNiTjf6KjXjBo → u1pHON3drz1mBi7owkbBP}/_buildManifest.js +0 -0
  915. /package/.next/standalone/.next/static/{5S4TviTCiNiTjf6KjXjBo → u1pHON3drz1mBi7owkbBP}/_clientMiddlewareManifest.json +0 -0
  916. /package/.next/standalone/.next/static/{5S4TviTCiNiTjf6KjXjBo → u1pHON3drz1mBi7owkbBP}/_ssgManifest.js +0 -0
  917. /package/.next/standalone/node_modules/@img/{sharp-libvips-linux-x64 → sharp-win32-x64}/versions.json +0 -0
@@ -1,853 +1,853 @@
1
- # Cortex v2 — Pillar 4: Boundary Engine
2
-
3
- > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
4
-
5
- **Goal:** Add three-layer access control to Cortex: auto-classification of sensitivity, organizational policies, and creator overrides — ensuring confidential knowledge never leaks across scope boundaries.
6
-
7
- **Architecture:** A new `src/lib/cortex/boundary/` module with three components: a `Classifier` (regex-based sensitivity detection), a `PolicyEngine` (rule evaluation), and an `AccessFilter` (query-time enforcement). The AccessFilter integrates with the ContextEngine to pre-filter scopes before search. An audit log records all access decisions in the entity graph's SQLite database.
8
-
9
- **Tech Stack:** TypeScript, better-sqlite3 (existing graph DB), vitest
10
-
11
- **Spec:** `docs/superpowers/specs/2026-03-14-cortex-v2-design.md` — Pillar 4
12
-
13
- **Depends on:** Pillar 1 (Entity Graph) + Pillar 2 (Knowledge Unit Evolution) — both completed
14
-
15
- ---
16
-
17
- ## File Structure
18
-
19
- ```
20
- New files:
21
- ├── src/lib/cortex/boundary/classifier.ts — Auto-classification (Layer 1)
22
- ├── src/lib/cortex/boundary/policy.ts — Policy engine (Layer 2)
23
- ├── src/lib/cortex/boundary/access.ts — Query-time access filter (Layer 3 + enforcement)
24
- ├── src/lib/cortex/boundary/audit.ts — Audit trail logging
25
- ├── src/lib/cortex/boundary/index.ts — Barrel export
26
-
27
- Modified files:
28
- ├── src/lib/cortex/ingestion/pipeline.ts — Auto-classify on ingestion
29
- ├── src/lib/cortex/retrieval/context-engine.ts — Pre-filter with AccessFilter
30
- ├── src/lib/cortex/config.ts — Add policies to config
31
-
32
- Test files:
33
- ├── tests/lib/cortex/boundary/classifier.test.ts
34
- ├── tests/lib/cortex/boundary/policy.test.ts
35
- ├── tests/lib/cortex/boundary/access.test.ts
36
- ├── tests/lib/cortex/boundary/audit.test.ts
37
- ```
38
-
39
- ---
40
-
41
- ## Chunk 1: Auto-Classification and Policy Engine
42
-
43
- ### Task 1: Sensitivity auto-classifier
44
-
45
- **Files:**
46
- - Create: `src/lib/cortex/boundary/classifier.ts`
47
- - Create: `tests/lib/cortex/boundary/classifier.test.ts`
48
-
49
- - [ ] **Step 1: Write failing tests**
50
-
51
- ```typescript
52
- // tests/lib/cortex/boundary/classifier.test.ts
53
- import { describe, it, expect } from 'vitest';
54
- import { classifySensitivity } from '@/lib/cortex/boundary/classifier';
55
-
56
- describe('classifySensitivity', () => {
57
- it('classifies secrets as confidential', () => {
58
- expect(classifySensitivity('Set API_KEY=sk-ant-abc123 in .env')).toBe('confidential');
59
- expect(classifySensitivity('password: hunter2')).toBe('confidential');
60
- expect(classifySensitivity('DATABASE_URL=postgres://user:pass@host')).toBe('confidential');
61
- });
62
-
63
- it('classifies personnel content as confidential', () => {
64
- expect(classifySensitivity('Alice performance review: exceeds expectations')).toBe('confidential');
65
- expect(classifySensitivity('salary adjustment from 120k to 140k')).toBe('confidential');
66
- });
67
-
68
- it('classifies security content as restricted', () => {
69
- expect(classifySensitivity('Found SQL injection vulnerability in login endpoint')).toBe('restricted');
70
- expect(classifySensitivity('CVE-2024-1234 affects our auth library')).toBe('restricted');
71
- });
72
-
73
- it('classifies business content as restricted', () => {
74
- expect(classifySensitivity('Q3 revenue was $2.5M, below target')).toBe('restricted');
75
- expect(classifySensitivity('Unreleased product launch planned for April')).toBe('restricted');
76
- });
77
-
78
- it('classifies technical content as internal', () => {
79
- expect(classifySensitivity('We decided to use PostgreSQL for the new service')).toBe('internal');
80
- expect(classifySensitivity('The auth middleware handles JWT validation')).toBe('internal');
81
- });
82
-
83
- it('classifies general content as public', () => {
84
- expect(classifySensitivity('How to use git rebase')).toBe('public');
85
- expect(classifySensitivity('JavaScript array methods')).toBe('public');
86
- });
87
-
88
- it('returns most restrictive when multiple detectors match', () => {
89
- // Has both secret (confidential) and security (restricted) signals
90
- expect(classifySensitivity('API_KEY leaked in CVE-2024-1234')).toBe('confidential');
91
- });
92
- });
93
- ```
94
-
95
- - [ ] **Step 2: Implement classifier**
96
-
97
- ```typescript
98
- // src/lib/cortex/boundary/classifier.ts
99
- import type { SensitivityClass } from '../knowledge/types';
100
-
101
- interface Detector {
102
- sensitivity: SensitivityClass;
103
- patterns: RegExp[];
104
- priority: number; // higher = more restrictive
105
- }
106
-
107
- const DETECTORS: Detector[] = [
108
- {
109
- sensitivity: 'confidential',
110
- priority: 4,
111
- patterns: [
112
- // Secrets
113
- /\b(api[_-]?key|secret[_-]?key|access[_-]?token|auth[_-]?token)\s*[=:]/i,
114
- /\b(password|passwd|pwd)\s*[=:]/i,
115
- /\bsk-[a-z]{2,4}-[a-zA-Z0-9]{10,}/, // Anthropic/OpenAI key format
116
- /\b(DATABASE_URL|REDIS_URL|MONGO_URI)\s*=/i,
117
- /\bpostgres:\/\/\w+:\w+@/i,
118
- /\b(private[_-]?key|ssh[_-]?key)\b/i,
119
- // Personnel
120
- /\b(performance\s+review|annual\s+review)\b/i,
121
- /\b(salary|compensation|pay\s+raise|pay\s+cut)\b/i,
122
- /\b(hiring|termination|fired|let\s+go)\b/i,
123
- /\b(1:1\s+notes?|one[\s-]on[\s-]one)\b/i,
124
- ],
125
- },
126
- {
127
- sensitivity: 'restricted',
128
- priority: 3,
129
- patterns: [
130
- // Security
131
- /\b(vulnerab|exploit|attack\s+vector|injection|xss|csrf|ssrf)\b/i,
132
- /\bCVE-\d{4}-\d+/i,
133
- /\b(incident\s+report|security\s+breach|data\s+leak)\b/i,
134
- // Business
135
- /\b(revenue|profit|loss|earnings|ARR|MRR)\b/i,
136
- /\b(unreleased|pre-launch|confidential\s+plan|roadmap)\b/i,
137
- /\bcustomer\s+(data|records|PII)\b/i,
138
- ],
139
- },
140
- {
141
- sensitivity: 'internal',
142
- priority: 2,
143
- patterns: [
144
- /\b(we\s+decided|architecture|design\s+pattern|refactor)\b/i,
145
- /\b(middleware|service|endpoint|database|schema)\b/i,
146
- /\b(deployment|CI\/CD|pipeline|infrastructure)\b/i,
147
- /\b(bug\s+fix|pull\s+request|code\s+review)\b/i,
148
- ],
149
- },
150
- ];
151
-
152
- export function classifySensitivity(text: string): SensitivityClass {
153
- let highestPriority = 0;
154
- let result: SensitivityClass = 'public';
155
-
156
- for (const detector of DETECTORS) {
157
- if (detector.priority <= highestPriority) continue;
158
- for (const pattern of detector.patterns) {
159
- if (pattern.test(text)) {
160
- highestPriority = detector.priority;
161
- result = detector.sensitivity;
162
- break;
163
- }
164
- }
165
- }
166
-
167
- return result;
168
- }
169
- ```
170
-
171
- - [ ] **Step 3: Run tests, commit**
172
-
173
- ```bash
174
- git commit -m "feat(cortex): add sensitivity auto-classifier for boundary engine"
175
- ```
176
-
177
- ---
178
-
179
- ### Task 2: Policy engine
180
-
181
- **Files:**
182
- - Create: `src/lib/cortex/boundary/policy.ts`
183
- - Create: `tests/lib/cortex/boundary/policy.test.ts`
184
-
185
- - [ ] **Step 1: Write failing tests**
186
-
187
- ```typescript
188
- // tests/lib/cortex/boundary/policy.test.ts
189
- import { describe, it, expect } from 'vitest';
190
- import { PolicyEngine } from '@/lib/cortex/boundary/policy';
191
- import type { Policy } from '@/lib/cortex/boundary/policy';
192
-
193
- describe('PolicyEngine', () => {
194
- it('returns empty actions when no policies match', () => {
195
- const engine = new PolicyEngine([]);
196
- const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal' });
197
- expect(actions).toEqual([]);
198
- });
199
-
200
- it('matches by knowledge type', () => {
201
- const policies: Policy[] = [{
202
- name: 'arch-decisions-propagate',
203
- match: { type: 'decision' },
204
- action: { propagate_to: [{ level: 'department' }] },
205
- }];
206
- const engine = new PolicyEngine(policies);
207
- const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal' });
208
- expect(actions).toHaveLength(1);
209
- expect(actions[0].propagate_to).toEqual([{ level: 'department' }]);
210
- });
211
-
212
- it('matches by sensitivity', () => {
213
- const policies: Policy[] = [{
214
- name: 'lock-confidential',
215
- match: { sensitivity: 'confidential' },
216
- action: { cannot_propagate: true },
217
- }];
218
- const engine = new PolicyEngine(policies);
219
- const actions = engine.evaluate({ type: 'pattern', sensitivity: 'confidential' });
220
- expect(actions).toHaveLength(1);
221
- expect(actions[0].cannot_propagate).toBe(true);
222
- });
223
-
224
- it('matches by topics', () => {
225
- const policies: Policy[] = [{
226
- name: 'security-routing',
227
- match: { topics: ['security', 'vulnerability'] },
228
- action: { max_scope: 'department', propagate_to: [{ level: 'team', entity_id: 'team-security' }] },
229
- }];
230
- const engine = new PolicyEngine(policies);
231
- const actions = engine.evaluate({ type: 'error_fix', sensitivity: 'restricted', topics: ['security'] });
232
- expect(actions).toHaveLength(1);
233
- expect(actions[0].max_scope).toBe('department');
234
- });
235
-
236
- it('returns multiple matching policies', () => {
237
- const policies: Policy[] = [
238
- { name: 'p1', match: { type: 'decision' }, action: { trickle_down: true } },
239
- { name: 'p2', match: { sensitivity: 'internal' }, action: { max_scope: 'organization' } },
240
- ];
241
- const engine = new PolicyEngine(policies);
242
- const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal' });
243
- expect(actions).toHaveLength(2);
244
- });
245
-
246
- it('does not match when criteria do not overlap', () => {
247
- const policies: Policy[] = [{
248
- name: 'security-only',
249
- match: { topics: ['security'] },
250
- action: { cannot_propagate: true },
251
- }];
252
- const engine = new PolicyEngine(policies);
253
- const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal', topics: ['architecture'] });
254
- expect(actions).toHaveLength(0);
255
- });
256
- });
257
- ```
258
-
259
- - [ ] **Step 2: Implement policy engine**
260
-
261
- ```typescript
262
- // src/lib/cortex/boundary/policy.ts
263
- import type { KnowledgeType, SensitivityClass, ScopeLevel } from '../knowledge/types';
264
-
265
- export interface PropagationTarget {
266
- level: ScopeLevel;
267
- entity_id?: string;
268
- }
269
-
270
- export interface PolicyAction {
271
- max_scope?: ScopeLevel;
272
- propagate_to?: PropagationTarget[];
273
- trickle_down?: boolean;
274
- cannot_propagate?: boolean;
275
- }
276
-
277
- export interface Policy {
278
- name: string;
279
- match: {
280
- type?: KnowledgeType;
281
- topics?: string[];
282
- sensitivity?: SensitivityClass;
283
- scope_level?: ScopeLevel;
284
- };
285
- action: PolicyAction;
286
- }
287
-
288
- export interface PolicyMatchInput {
289
- type: KnowledgeType | string;
290
- sensitivity: SensitivityClass | string;
291
- topics?: string[];
292
- scope_level?: ScopeLevel | string;
293
- }
294
-
295
- export class PolicyEngine {
296
- constructor(private policies: Policy[]) {}
297
-
298
- evaluate(input: PolicyMatchInput): PolicyAction[] {
299
- const matched: PolicyAction[] = [];
300
-
301
- for (const policy of this.policies) {
302
- if (this.matches(policy, input)) {
303
- matched.push(policy.action);
304
- }
305
- }
306
-
307
- return matched;
308
- }
309
-
310
- private matches(policy: Policy, input: PolicyMatchInput): boolean {
311
- const { match } = policy;
312
-
313
- if (match.type && match.type !== input.type) return false;
314
- if (match.sensitivity && match.sensitivity !== input.sensitivity) return false;
315
- if (match.scope_level && match.scope_level !== input.scope_level) return false;
316
-
317
- if (match.topics && match.topics.length > 0) {
318
- const inputTopics = input.topics ?? [];
319
- const hasOverlap = match.topics.some(t => inputTopics.includes(t));
320
- if (!hasOverlap) return false;
321
- }
322
-
323
- return true;
324
- }
325
- }
326
- ```
327
-
328
- - [ ] **Step 3: Run tests, commit**
329
-
330
- ```bash
331
- git commit -m "feat(cortex): add policy engine for boundary enforcement"
332
- ```
333
-
334
- ---
335
-
336
- ## Chunk 2: Access Filter and Audit Trail
337
-
338
- ### Task 3: Query-time access filter
339
-
340
- **Files:**
341
- - Create: `src/lib/cortex/boundary/access.ts`
342
- - Create: `tests/lib/cortex/boundary/access.test.ts`
343
-
344
- - [ ] **Step 1: Write failing tests**
345
-
346
- ```typescript
347
- // tests/lib/cortex/boundary/access.test.ts
348
- import { describe, it, expect } from 'vitest';
349
- import { AccessFilter } from '@/lib/cortex/boundary/access';
350
- import type { ScoredKnowledge } from '@/lib/cortex/knowledge/types';
351
-
352
- function makeUnit(overrides: Partial<ScoredKnowledge> = {}): ScoredKnowledge {
353
- return {
354
- id: 'k1', vector: [], text: 'test', type: 'decision', layer: 'personal',
355
- workspace_id: null, session_id: null, agent_type: 'claude',
356
- project_path: null, file_refs: [], confidence: 0.8,
357
- created: new Date().toISOString(), source_timestamp: new Date().toISOString(),
358
- stale_score: 0, access_count: 0, last_accessed: null, metadata: {},
359
- relevance_score: 0.9, similarity: 0.9,
360
- sensitivity: 'internal',
361
- scope: { level: 'personal', entity_id: 'person-alice' },
362
- origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-alice' },
363
- ...overrides,
364
- };
365
- }
366
-
367
- describe('AccessFilter', () => {
368
- const filter = new AccessFilter({
369
- requesterId: 'person-alice',
370
- requesterScope: { level: 'team', entity_id: 'team-platform' },
371
- requesterOrg: 'organization-acme',
372
- });
373
-
374
- it('allows public knowledge from anywhere in org', () => {
375
- const unit = makeUnit({ sensitivity: 'public', scope: { level: 'organization', entity_id: 'org-acme' } });
376
- expect(filter.canAccess(unit)).toBe(true);
377
- });
378
-
379
- it('allows internal knowledge within org', () => {
380
- const unit = makeUnit({ sensitivity: 'internal', scope: { level: 'team', entity_id: 'team-other' } });
381
- expect(filter.canAccess(unit)).toBe(true);
382
- });
383
-
384
- it('allows restricted knowledge within same scope', () => {
385
- const unit = makeUnit({
386
- sensitivity: 'restricted',
387
- scope: { level: 'team', entity_id: 'team-platform' },
388
- });
389
- expect(filter.canAccess(unit)).toBe(true);
390
- });
391
-
392
- it('denies restricted knowledge from different department', () => {
393
- const unit = makeUnit({
394
- sensitivity: 'restricted',
395
- scope: { level: 'department', entity_id: 'department-sales' },
396
- });
397
- // Alice is in team-platform, not department-sales
398
- expect(filter.canAccess(unit)).toBe(false);
399
- });
400
-
401
- it('allows confidential knowledge from self', () => {
402
- const unit = makeUnit({
403
- sensitivity: 'confidential',
404
- scope: { level: 'personal', entity_id: 'person-alice' },
405
- origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-alice' },
406
- });
407
- expect(filter.canAccess(unit)).toBe(true);
408
- });
409
-
410
- it('denies confidential knowledge from others', () => {
411
- const unit = makeUnit({
412
- sensitivity: 'confidential',
413
- scope: { level: 'personal', entity_id: 'person-bob' },
414
- origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-bob' },
415
- });
416
- expect(filter.canAccess(unit)).toBe(false);
417
- });
418
-
419
- it('respects creator_scope override (further restriction)', () => {
420
- const unit = makeUnit({
421
- sensitivity: 'internal', // normally accessible org-wide
422
- creator_scope: { max_level: 'personal' }, // but creator restricted to personal only
423
- scope: { level: 'personal', entity_id: 'person-bob' },
424
- });
425
- // Alice can't access Bob's personal-restricted knowledge even though it's internal
426
- expect(filter.canAccess(unit)).toBe(false);
427
- });
428
-
429
- it('filters a list of results', () => {
430
- const results = [
431
- makeUnit({ id: 'a', sensitivity: 'public' }),
432
- makeUnit({ id: 'b', sensitivity: 'confidential', origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-bob' } }),
433
- makeUnit({ id: 'c', sensitivity: 'internal' }),
434
- ];
435
- const filtered = filter.filterResults(results);
436
- expect(filtered).toHaveLength(2); // a and c pass, b denied
437
- expect(filtered.map(r => r.id)).toEqual(['a', 'c']);
438
- });
439
- });
440
- ```
441
-
442
- - [ ] **Step 2: Implement access filter**
443
-
444
- ```typescript
445
- // src/lib/cortex/boundary/access.ts
446
- import type { ScoredKnowledge, Scope, ScopeLevel, SensitivityClass } from '../knowledge/types';
447
-
448
- const SCOPE_HIERARCHY: Record<ScopeLevel, number> = {
449
- personal: 0,
450
- team: 1,
451
- department: 2,
452
- organization: 3,
453
- };
454
-
455
- export interface AccessFilterConfig {
456
- requesterId: string;
457
- requesterScope: Scope; // requester's team scope
458
- requesterOrg: string; // requester's org entity_id
459
- grants?: Set<string>; // knowledge IDs the requester has been granted access to
460
- }
461
-
462
- export class AccessFilter {
463
- private config: AccessFilterConfig;
464
-
465
- constructor(config: AccessFilterConfig) {
466
- this.config = config;
467
- }
468
-
469
- canAccess(unit: ScoredKnowledge): boolean {
470
- const sensitivity = (unit.sensitivity ?? 'internal') as SensitivityClass;
471
- const unitScope = unit.scope ?? { level: 'personal' as ScopeLevel, entity_id: '' };
472
- const creatorId = unit.origin?.creator_entity_id ?? '';
473
-
474
- // Check creator_scope override first — most restrictive wins
475
- if (unit.creator_scope) {
476
- const maxLevel = SCOPE_HIERARCHY[unit.creator_scope.max_level] ?? 0;
477
- const requesterLevel = this.getRequesterProximityLevel(unitScope);
478
- if (requesterLevel > maxLevel) return false;
479
- }
480
-
481
- switch (sensitivity) {
482
- case 'public':
483
- return true;
484
-
485
- case 'internal':
486
- // Accessible to anyone in the same org
487
- return true;
488
-
489
- case 'restricted':
490
- // Accessible within same scope or if policy grants cross-scope access
491
- return this.isWithinScope(unitScope);
492
-
493
- case 'confidential':
494
- // Only creator or explicit grant
495
- if (this.config.requesterId === creatorId) return true;
496
- if (this.config.grants?.has(unit.id)) return true;
497
- return false;
498
-
499
- default:
500
- return false;
501
- }
502
- }
503
-
504
- filterResults(results: ScoredKnowledge[]): ScoredKnowledge[] {
505
- return results.filter(r => this.canAccess(r));
506
- }
507
-
508
- private isWithinScope(unitScope: Scope): boolean {
509
- // Same entity_id = same scope
510
- if (unitScope.entity_id === this.config.requesterScope.entity_id) return true;
511
- if (unitScope.entity_id === this.config.requesterId) return true;
512
- // Same org for org-level scopes
513
- if (unitScope.level === 'organization' && unitScope.entity_id === this.config.requesterOrg) return true;
514
- return false;
515
- }
516
-
517
- private getRequesterProximityLevel(unitScope: Scope): number {
518
- // How "far" is the requester from the unit's scope?
519
- // 0 = same entity, 1 = same scope level, 2+ = further
520
- if (unitScope.entity_id === this.config.requesterId) return 0;
521
- if (unitScope.entity_id === this.config.requesterScope.entity_id) return 0;
522
- return SCOPE_HIERARCHY[unitScope.level] ?? 3;
523
- }
524
- }
525
- ```
526
-
527
- - [ ] **Step 3: Run tests, commit**
528
-
529
- ```bash
530
- git commit -m "feat(cortex): add query-time access filter for boundary enforcement"
531
- ```
532
-
533
- ---
534
-
535
- ### Task 4: Audit trail
536
-
537
- **Files:**
538
- - Create: `src/lib/cortex/boundary/audit.ts`
539
- - Create: `tests/lib/cortex/boundary/audit.test.ts`
540
-
541
- - [ ] **Step 1: Write failing tests**
542
-
543
- ```typescript
544
- // tests/lib/cortex/boundary/audit.test.ts
545
- import { describe, it, expect, beforeEach, afterEach } from 'vitest';
546
- import fs from 'fs';
547
- import path from 'path';
548
- import os from 'os';
549
- import Database from 'better-sqlite3';
550
- import { AuditLog } from '@/lib/cortex/boundary/audit';
551
-
552
- describe('AuditLog', () => {
553
- let tmpDir: string;
554
- let audit: AuditLog;
555
-
556
- beforeEach(() => {
557
- tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cortex-audit-'));
558
- const db = new Database(path.join(tmpDir, 'graph.db'));
559
- audit = new AuditLog(db);
560
- });
561
-
562
- afterEach(() => {
563
- fs.rmSync(tmpDir, { recursive: true, force: true });
564
- });
565
-
566
- it('logs an access decision', () => {
567
- audit.log({
568
- requesterId: 'person-alice',
569
- knowledgeId: 'k1',
570
- action: 'allowed',
571
- reason: 'public sensitivity',
572
- });
573
- const entries = audit.query({ requesterId: 'person-alice' });
574
- expect(entries).toHaveLength(1);
575
- expect(entries[0].action).toBe('allowed');
576
- });
577
-
578
- it('logs denied access', () => {
579
- audit.log({
580
- requesterId: 'person-alice',
581
- knowledgeId: 'k2',
582
- action: 'denied',
583
- reason: 'confidential, not creator',
584
- });
585
- const entries = audit.query({ requesterId: 'person-alice' });
586
- expect(entries).toHaveLength(1);
587
- expect(entries[0].action).toBe('denied');
588
- });
589
-
590
- it('queries by time range', () => {
591
- audit.log({ requesterId: 'person-alice', knowledgeId: 'k1', action: 'allowed', reason: 'public' });
592
- const recent = audit.query({ since: new Date(Date.now() - 60000).toISOString() });
593
- expect(recent).toHaveLength(1);
594
-
595
- const future = audit.query({ since: new Date(Date.now() + 60000).toISOString() });
596
- expect(future).toHaveLength(0);
597
- });
598
-
599
- it('supports retention cleanup', () => {
600
- audit.log({ requesterId: 'person-alice', knowledgeId: 'k1', action: 'allowed', reason: 'test' });
601
- // Cleanup entries older than 0 days (everything)
602
- audit.cleanup(0);
603
- const entries = audit.query({});
604
- expect(entries).toHaveLength(0);
605
- });
606
- });
607
- ```
608
-
609
- - [ ] **Step 2: Implement audit log**
610
-
611
- ```typescript
612
- // src/lib/cortex/boundary/audit.ts
613
- import type Database from 'better-sqlite3';
614
-
615
- export interface AuditEntry {
616
- requesterId: string;
617
- knowledgeId: string;
618
- action: 'allowed' | 'denied';
619
- reason: string;
620
- }
621
-
622
- export interface AuditQueryFilter {
623
- requesterId?: string;
624
- since?: string; // ISO timestamp
625
- limit?: number;
626
- }
627
-
628
- export interface AuditRecord extends AuditEntry {
629
- timestamp: string;
630
- }
631
-
632
- export class AuditLog {
633
- private db: InstanceType<typeof Database>;
634
-
635
- constructor(db: InstanceType<typeof Database>) {
636
- this.db = db;
637
- this.db.exec(`
638
- CREATE TABLE IF NOT EXISTS audit_log (
639
- id INTEGER PRIMARY KEY AUTOINCREMENT,
640
- requester_id TEXT NOT NULL,
641
- knowledge_id TEXT NOT NULL,
642
- action TEXT NOT NULL,
643
- reason TEXT NOT NULL,
644
- timestamp TEXT NOT NULL
645
- );
646
- CREATE INDEX IF NOT EXISTS idx_audit_requester ON audit_log(requester_id);
647
- CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON audit_log(timestamp);
648
- `);
649
- }
650
-
651
- log(entry: AuditEntry): void {
652
- this.db.prepare(`
653
- INSERT INTO audit_log (requester_id, knowledge_id, action, reason, timestamp)
654
- VALUES (?, ?, ?, ?, ?)
655
- `).run(entry.requesterId, entry.knowledgeId, entry.action, entry.reason, new Date().toISOString());
656
- }
657
-
658
- query(filter: AuditQueryFilter): AuditRecord[] {
659
- let sql = 'SELECT * FROM audit_log WHERE 1=1';
660
- const params: any[] = [];
661
-
662
- if (filter.requesterId) {
663
- sql += ' AND requester_id = ?';
664
- params.push(filter.requesterId);
665
- }
666
- if (filter.since) {
667
- sql += ' AND timestamp >= ?';
668
- params.push(filter.since);
669
- }
670
-
671
- sql += ' ORDER BY timestamp DESC';
672
-
673
- if (filter.limit) {
674
- sql += ' LIMIT ?';
675
- params.push(filter.limit);
676
- }
677
-
678
- return (this.db.prepare(sql).all(...params) as any[]).map(row => ({
679
- requesterId: row.requester_id,
680
- knowledgeId: row.knowledge_id,
681
- action: row.action,
682
- reason: row.reason,
683
- timestamp: row.timestamp,
684
- }));
685
- }
686
-
687
- cleanup(retentionDays: number): void {
688
- const cutoff = new Date(Date.now() - retentionDays * 86400000).toISOString();
689
- this.db.prepare('DELETE FROM audit_log WHERE timestamp < ?').run(cutoff);
690
- }
691
- }
692
- ```
693
-
694
- - [ ] **Step 3: Run tests, commit**
695
-
696
- ```bash
697
- git commit -m "feat(cortex): add audit trail for access decisions"
698
- ```
699
-
700
- ---
701
-
702
- ## Chunk 3: Integration
703
-
704
- ### Task 5: Integrate with ingestion pipeline
705
-
706
- **Files:**
707
- - Modify: `src/lib/cortex/ingestion/pipeline.ts`
708
-
709
- - [ ] **Step 1: Read pipeline.ts**
710
-
711
- - [ ] **Step 2: Add auto-classification during ingestion**
712
-
713
- Import the classifier:
714
- ```typescript
715
- import { classifySensitivity } from '../boundary/classifier';
716
- ```
717
-
718
- In the KnowledgeUnit construction (where v2 fields are set), replace the hardcoded `sensitivity: 'internal'` with:
719
- ```typescript
720
- sensitivity: classifySensitivity(chunk.text),
721
- ```
722
-
723
- This ensures every ingested knowledge unit gets an auto-classified sensitivity level.
724
-
725
- - [ ] **Step 3: Run pipeline tests to verify no regressions**
726
-
727
- ```bash
728
- npx vitest run tests/lib/cortex/ingestion/
729
- ```
730
-
731
- - [ ] **Step 4: Commit**
732
-
733
- ```bash
734
- git commit -m "feat(cortex): auto-classify sensitivity during ingestion"
735
- ```
736
-
737
- ---
738
-
739
- ### Task 6: Integrate AccessFilter with ContextEngine
740
-
741
- **Files:**
742
- - Modify: `src/lib/cortex/retrieval/context-engine.ts`
743
-
744
- - [ ] **Step 1: Read context-engine.ts**
745
-
746
- - [ ] **Step 2: Add AccessFilter to the pipeline**
747
-
748
- Import AccessFilter:
749
- ```typescript
750
- import { AccessFilter } from '../boundary/access';
751
- ```
752
-
753
- Add to `ContextEngineDeps`:
754
- ```typescript
755
- accessFilter?: AccessFilter;
756
- ```
757
-
758
- In the `assemble()` method, after fusion/ranking (Stage 5) but before conflict detection (Stage 6), apply the access filter:
759
-
760
- ```typescript
761
- // Stage 5.5: Access control filtering
762
- let accessible = fused;
763
- if (this.deps.accessFilter) {
764
- accessible = this.deps.accessFilter.filterResults(fused);
765
- }
766
- ```
767
-
768
- Then pass `accessible` (not `fused`) to conflict detection and formatting.
769
-
770
- - [ ] **Step 3: Run context-engine tests to verify no regressions**
771
-
772
- ```bash
773
- npx vitest run tests/lib/cortex/retrieval/context-engine.test.ts
774
- ```
775
-
776
- - [ ] **Step 4: Commit**
777
-
778
- ```bash
779
- git commit -m "feat(cortex): integrate access filter into context assembly pipeline"
780
- ```
781
-
782
- ---
783
-
784
- ### Task 7: Barrel export and config integration
785
-
786
- **Files:**
787
- - Create: `src/lib/cortex/boundary/index.ts`
788
- - Modify: `src/lib/cortex/config.ts` (add policies array to config)
789
-
790
- - [ ] **Step 1: Create barrel export**
791
-
792
- ```typescript
793
- // src/lib/cortex/boundary/index.ts
794
- export { classifySensitivity } from './classifier';
795
- export { PolicyEngine } from './policy';
796
- export type { Policy, PolicyAction, PropagationTarget } from './policy';
797
- export { AccessFilter } from './access';
798
- export type { AccessFilterConfig } from './access';
799
- export { AuditLog } from './audit';
800
- export type { AuditEntry, AuditRecord, AuditQueryFilter } from './audit';
801
- ```
802
-
803
- - [ ] **Step 2: Add policies to CortexConfig**
804
-
805
- In `src/lib/cortex/config.ts`, add to the `CortexConfig` interface:
806
- ```typescript
807
- policies?: Policy[]; // Organizational boundary policies
808
- ```
809
-
810
- And in `DEFAULT_CORTEX_CONFIG`:
811
- ```typescript
812
- policies: [],
813
- ```
814
-
815
- Import the Policy type:
816
- ```typescript
817
- import type { Policy } from './boundary/policy';
818
- ```
819
-
820
- - [ ] **Step 3: Run full test suite**
821
-
822
- ```bash
823
- npx vitest run tests/lib/cortex/
824
- ```
825
-
826
- - [ ] **Step 4: Commit**
827
-
828
- ```bash
829
- git commit -m "feat(cortex): add boundary module barrel export and config integration"
830
- ```
831
-
832
- ---
833
-
834
- ## Summary
835
-
836
- | Task | Component | Tests | Status |
837
- |------|-----------|-------|--------|
838
- | 1 | Sensitivity classifier | 7 | |
839
- | 2 | Policy engine | 6 | |
840
- | 3 | Access filter | 8 | |
841
- | 4 | Audit trail | 4 | |
842
- | 5 | Pipeline integration | regression | |
843
- | 6 | ContextEngine integration | regression | |
844
- | 7 | Barrel export + config | regression | |
845
-
846
- **Total: 7 tasks, ~25 new tests, 3 chunks**
847
-
848
- **Key design decisions:**
849
- - Auto-classification is regex-based (no LLM call) — fast, deterministic, auditable
850
- - Policies are stored in CortexConfig (admin-editable JSON) — not code
851
- - AccessFilter is a separate class that can be composed with ContextEngine or used standalone
852
- - Audit log uses the entity graph's SQLite DB (same file, new table) — no new database
853
- - Most restrictive classification always wins (confidential > restricted > internal > public)
1
+ # Cortex v2 — Pillar 4: Boundary Engine
2
+
3
+ > **For agentic workers:** REQUIRED: Use superpowers:subagent-driven-development (if subagents available) or superpowers:executing-plans to implement this plan. Steps use checkbox (`- [ ]`) syntax for tracking.
4
+
5
+ **Goal:** Add three-layer access control to Cortex: auto-classification of sensitivity, organizational policies, and creator overrides — ensuring confidential knowledge never leaks across scope boundaries.
6
+
7
+ **Architecture:** A new `src/lib/cortex/boundary/` module with three components: a `Classifier` (regex-based sensitivity detection), a `PolicyEngine` (rule evaluation), and an `AccessFilter` (query-time enforcement). The AccessFilter integrates with the ContextEngine to pre-filter scopes before search. An audit log records all access decisions in the entity graph's SQLite database.
8
+
9
+ **Tech Stack:** TypeScript, better-sqlite3 (existing graph DB), vitest
10
+
11
+ **Spec:** `docs/superpowers/specs/2026-03-14-cortex-v2-design.md` — Pillar 4
12
+
13
+ **Depends on:** Pillar 1 (Entity Graph) + Pillar 2 (Knowledge Unit Evolution) — both completed
14
+
15
+ ---
16
+
17
+ ## File Structure
18
+
19
+ ```
20
+ New files:
21
+ ├── src/lib/cortex/boundary/classifier.ts — Auto-classification (Layer 1)
22
+ ├── src/lib/cortex/boundary/policy.ts — Policy engine (Layer 2)
23
+ ├── src/lib/cortex/boundary/access.ts — Query-time access filter (Layer 3 + enforcement)
24
+ ├── src/lib/cortex/boundary/audit.ts — Audit trail logging
25
+ ├── src/lib/cortex/boundary/index.ts — Barrel export
26
+
27
+ Modified files:
28
+ ├── src/lib/cortex/ingestion/pipeline.ts — Auto-classify on ingestion
29
+ ├── src/lib/cortex/retrieval/context-engine.ts — Pre-filter with AccessFilter
30
+ ├── src/lib/cortex/config.ts — Add policies to config
31
+
32
+ Test files:
33
+ ├── tests/lib/cortex/boundary/classifier.test.ts
34
+ ├── tests/lib/cortex/boundary/policy.test.ts
35
+ ├── tests/lib/cortex/boundary/access.test.ts
36
+ ├── tests/lib/cortex/boundary/audit.test.ts
37
+ ```
38
+
39
+ ---
40
+
41
+ ## Chunk 1: Auto-Classification and Policy Engine
42
+
43
+ ### Task 1: Sensitivity auto-classifier
44
+
45
+ **Files:**
46
+ - Create: `src/lib/cortex/boundary/classifier.ts`
47
+ - Create: `tests/lib/cortex/boundary/classifier.test.ts`
48
+
49
+ - [ ] **Step 1: Write failing tests**
50
+
51
+ ```typescript
52
+ // tests/lib/cortex/boundary/classifier.test.ts
53
+ import { describe, it, expect } from 'vitest';
54
+ import { classifySensitivity } from '@/lib/cortex/boundary/classifier';
55
+
56
+ describe('classifySensitivity', () => {
57
+ it('classifies secrets as confidential', () => {
58
+ expect(classifySensitivity('Set API_KEY=sk-ant-abc123 in .env')).toBe('confidential');
59
+ expect(classifySensitivity('password: hunter2')).toBe('confidential');
60
+ expect(classifySensitivity('DATABASE_URL=postgres://user:pass@host')).toBe('confidential');
61
+ });
62
+
63
+ it('classifies personnel content as confidential', () => {
64
+ expect(classifySensitivity('Alice performance review: exceeds expectations')).toBe('confidential');
65
+ expect(classifySensitivity('salary adjustment from 120k to 140k')).toBe('confidential');
66
+ });
67
+
68
+ it('classifies security content as restricted', () => {
69
+ expect(classifySensitivity('Found SQL injection vulnerability in login endpoint')).toBe('restricted');
70
+ expect(classifySensitivity('CVE-2024-1234 affects our auth library')).toBe('restricted');
71
+ });
72
+
73
+ it('classifies business content as restricted', () => {
74
+ expect(classifySensitivity('Q3 revenue was $2.5M, below target')).toBe('restricted');
75
+ expect(classifySensitivity('Unreleased product launch planned for April')).toBe('restricted');
76
+ });
77
+
78
+ it('classifies technical content as internal', () => {
79
+ expect(classifySensitivity('We decided to use PostgreSQL for the new service')).toBe('internal');
80
+ expect(classifySensitivity('The auth middleware handles JWT validation')).toBe('internal');
81
+ });
82
+
83
+ it('classifies general content as public', () => {
84
+ expect(classifySensitivity('How to use git rebase')).toBe('public');
85
+ expect(classifySensitivity('JavaScript array methods')).toBe('public');
86
+ });
87
+
88
+ it('returns most restrictive when multiple detectors match', () => {
89
+ // Has both secret (confidential) and security (restricted) signals
90
+ expect(classifySensitivity('API_KEY leaked in CVE-2024-1234')).toBe('confidential');
91
+ });
92
+ });
93
+ ```
94
+
95
+ - [ ] **Step 2: Implement classifier**
96
+
97
+ ```typescript
98
+ // src/lib/cortex/boundary/classifier.ts
99
+ import type { SensitivityClass } from '../knowledge/types';
100
+
101
+ interface Detector {
102
+ sensitivity: SensitivityClass;
103
+ patterns: RegExp[];
104
+ priority: number; // higher = more restrictive
105
+ }
106
+
107
+ const DETECTORS: Detector[] = [
108
+ {
109
+ sensitivity: 'confidential',
110
+ priority: 4,
111
+ patterns: [
112
+ // Secrets
113
+ /\b(api[_-]?key|secret[_-]?key|access[_-]?token|auth[_-]?token)\s*[=:]/i,
114
+ /\b(password|passwd|pwd)\s*[=:]/i,
115
+ /\bsk-[a-z]{2,4}-[a-zA-Z0-9]{10,}/, // Anthropic/OpenAI key format
116
+ /\b(DATABASE_URL|REDIS_URL|MONGO_URI)\s*=/i,
117
+ /\bpostgres:\/\/\w+:\w+@/i,
118
+ /\b(private[_-]?key|ssh[_-]?key)\b/i,
119
+ // Personnel
120
+ /\b(performance\s+review|annual\s+review)\b/i,
121
+ /\b(salary|compensation|pay\s+raise|pay\s+cut)\b/i,
122
+ /\b(hiring|termination|fired|let\s+go)\b/i,
123
+ /\b(1:1\s+notes?|one[\s-]on[\s-]one)\b/i,
124
+ ],
125
+ },
126
+ {
127
+ sensitivity: 'restricted',
128
+ priority: 3,
129
+ patterns: [
130
+ // Security
131
+ /\b(vulnerab|exploit|attack\s+vector|injection|xss|csrf|ssrf)\b/i,
132
+ /\bCVE-\d{4}-\d+/i,
133
+ /\b(incident\s+report|security\s+breach|data\s+leak)\b/i,
134
+ // Business
135
+ /\b(revenue|profit|loss|earnings|ARR|MRR)\b/i,
136
+ /\b(unreleased|pre-launch|confidential\s+plan|roadmap)\b/i,
137
+ /\bcustomer\s+(data|records|PII)\b/i,
138
+ ],
139
+ },
140
+ {
141
+ sensitivity: 'internal',
142
+ priority: 2,
143
+ patterns: [
144
+ /\b(we\s+decided|architecture|design\s+pattern|refactor)\b/i,
145
+ /\b(middleware|service|endpoint|database|schema)\b/i,
146
+ /\b(deployment|CI\/CD|pipeline|infrastructure)\b/i,
147
+ /\b(bug\s+fix|pull\s+request|code\s+review)\b/i,
148
+ ],
149
+ },
150
+ ];
151
+
152
+ export function classifySensitivity(text: string): SensitivityClass {
153
+ let highestPriority = 0;
154
+ let result: SensitivityClass = 'public';
155
+
156
+ for (const detector of DETECTORS) {
157
+ if (detector.priority <= highestPriority) continue;
158
+ for (const pattern of detector.patterns) {
159
+ if (pattern.test(text)) {
160
+ highestPriority = detector.priority;
161
+ result = detector.sensitivity;
162
+ break;
163
+ }
164
+ }
165
+ }
166
+
167
+ return result;
168
+ }
169
+ ```
170
+
171
+ - [ ] **Step 3: Run tests, commit**
172
+
173
+ ```bash
174
+ git commit -m "feat(cortex): add sensitivity auto-classifier for boundary engine"
175
+ ```
176
+
177
+ ---
178
+
179
+ ### Task 2: Policy engine
180
+
181
+ **Files:**
182
+ - Create: `src/lib/cortex/boundary/policy.ts`
183
+ - Create: `tests/lib/cortex/boundary/policy.test.ts`
184
+
185
+ - [ ] **Step 1: Write failing tests**
186
+
187
+ ```typescript
188
+ // tests/lib/cortex/boundary/policy.test.ts
189
+ import { describe, it, expect } from 'vitest';
190
+ import { PolicyEngine } from '@/lib/cortex/boundary/policy';
191
+ import type { Policy } from '@/lib/cortex/boundary/policy';
192
+
193
+ describe('PolicyEngine', () => {
194
+ it('returns empty actions when no policies match', () => {
195
+ const engine = new PolicyEngine([]);
196
+ const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal' });
197
+ expect(actions).toEqual([]);
198
+ });
199
+
200
+ it('matches by knowledge type', () => {
201
+ const policies: Policy[] = [{
202
+ name: 'arch-decisions-propagate',
203
+ match: { type: 'decision' },
204
+ action: { propagate_to: [{ level: 'department' }] },
205
+ }];
206
+ const engine = new PolicyEngine(policies);
207
+ const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal' });
208
+ expect(actions).toHaveLength(1);
209
+ expect(actions[0].propagate_to).toEqual([{ level: 'department' }]);
210
+ });
211
+
212
+ it('matches by sensitivity', () => {
213
+ const policies: Policy[] = [{
214
+ name: 'lock-confidential',
215
+ match: { sensitivity: 'confidential' },
216
+ action: { cannot_propagate: true },
217
+ }];
218
+ const engine = new PolicyEngine(policies);
219
+ const actions = engine.evaluate({ type: 'pattern', sensitivity: 'confidential' });
220
+ expect(actions).toHaveLength(1);
221
+ expect(actions[0].cannot_propagate).toBe(true);
222
+ });
223
+
224
+ it('matches by topics', () => {
225
+ const policies: Policy[] = [{
226
+ name: 'security-routing',
227
+ match: { topics: ['security', 'vulnerability'] },
228
+ action: { max_scope: 'department', propagate_to: [{ level: 'team', entity_id: 'team-security' }] },
229
+ }];
230
+ const engine = new PolicyEngine(policies);
231
+ const actions = engine.evaluate({ type: 'error_fix', sensitivity: 'restricted', topics: ['security'] });
232
+ expect(actions).toHaveLength(1);
233
+ expect(actions[0].max_scope).toBe('department');
234
+ });
235
+
236
+ it('returns multiple matching policies', () => {
237
+ const policies: Policy[] = [
238
+ { name: 'p1', match: { type: 'decision' }, action: { trickle_down: true } },
239
+ { name: 'p2', match: { sensitivity: 'internal' }, action: { max_scope: 'organization' } },
240
+ ];
241
+ const engine = new PolicyEngine(policies);
242
+ const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal' });
243
+ expect(actions).toHaveLength(2);
244
+ });
245
+
246
+ it('does not match when criteria do not overlap', () => {
247
+ const policies: Policy[] = [{
248
+ name: 'security-only',
249
+ match: { topics: ['security'] },
250
+ action: { cannot_propagate: true },
251
+ }];
252
+ const engine = new PolicyEngine(policies);
253
+ const actions = engine.evaluate({ type: 'decision', sensitivity: 'internal', topics: ['architecture'] });
254
+ expect(actions).toHaveLength(0);
255
+ });
256
+ });
257
+ ```
258
+
259
+ - [ ] **Step 2: Implement policy engine**
260
+
261
+ ```typescript
262
+ // src/lib/cortex/boundary/policy.ts
263
+ import type { KnowledgeType, SensitivityClass, ScopeLevel } from '../knowledge/types';
264
+
265
+ export interface PropagationTarget {
266
+ level: ScopeLevel;
267
+ entity_id?: string;
268
+ }
269
+
270
+ export interface PolicyAction {
271
+ max_scope?: ScopeLevel;
272
+ propagate_to?: PropagationTarget[];
273
+ trickle_down?: boolean;
274
+ cannot_propagate?: boolean;
275
+ }
276
+
277
+ export interface Policy {
278
+ name: string;
279
+ match: {
280
+ type?: KnowledgeType;
281
+ topics?: string[];
282
+ sensitivity?: SensitivityClass;
283
+ scope_level?: ScopeLevel;
284
+ };
285
+ action: PolicyAction;
286
+ }
287
+
288
+ export interface PolicyMatchInput {
289
+ type: KnowledgeType | string;
290
+ sensitivity: SensitivityClass | string;
291
+ topics?: string[];
292
+ scope_level?: ScopeLevel | string;
293
+ }
294
+
295
+ export class PolicyEngine {
296
+ constructor(private policies: Policy[]) {}
297
+
298
+ evaluate(input: PolicyMatchInput): PolicyAction[] {
299
+ const matched: PolicyAction[] = [];
300
+
301
+ for (const policy of this.policies) {
302
+ if (this.matches(policy, input)) {
303
+ matched.push(policy.action);
304
+ }
305
+ }
306
+
307
+ return matched;
308
+ }
309
+
310
+ private matches(policy: Policy, input: PolicyMatchInput): boolean {
311
+ const { match } = policy;
312
+
313
+ if (match.type && match.type !== input.type) return false;
314
+ if (match.sensitivity && match.sensitivity !== input.sensitivity) return false;
315
+ if (match.scope_level && match.scope_level !== input.scope_level) return false;
316
+
317
+ if (match.topics && match.topics.length > 0) {
318
+ const inputTopics = input.topics ?? [];
319
+ const hasOverlap = match.topics.some(t => inputTopics.includes(t));
320
+ if (!hasOverlap) return false;
321
+ }
322
+
323
+ return true;
324
+ }
325
+ }
326
+ ```
327
+
328
+ - [ ] **Step 3: Run tests, commit**
329
+
330
+ ```bash
331
+ git commit -m "feat(cortex): add policy engine for boundary enforcement"
332
+ ```
333
+
334
+ ---
335
+
336
+ ## Chunk 2: Access Filter and Audit Trail
337
+
338
+ ### Task 3: Query-time access filter
339
+
340
+ **Files:**
341
+ - Create: `src/lib/cortex/boundary/access.ts`
342
+ - Create: `tests/lib/cortex/boundary/access.test.ts`
343
+
344
+ - [ ] **Step 1: Write failing tests**
345
+
346
+ ```typescript
347
+ // tests/lib/cortex/boundary/access.test.ts
348
+ import { describe, it, expect } from 'vitest';
349
+ import { AccessFilter } from '@/lib/cortex/boundary/access';
350
+ import type { ScoredKnowledge } from '@/lib/cortex/knowledge/types';
351
+
352
+ function makeUnit(overrides: Partial<ScoredKnowledge> = {}): ScoredKnowledge {
353
+ return {
354
+ id: 'k1', vector: [], text: 'test', type: 'decision', layer: 'personal',
355
+ workspace_id: null, session_id: null, agent_type: 'claude',
356
+ project_path: null, file_refs: [], confidence: 0.8,
357
+ created: new Date().toISOString(), source_timestamp: new Date().toISOString(),
358
+ stale_score: 0, access_count: 0, last_accessed: null, metadata: {},
359
+ relevance_score: 0.9, similarity: 0.9,
360
+ sensitivity: 'internal',
361
+ scope: { level: 'personal', entity_id: 'person-alice' },
362
+ origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-alice' },
363
+ ...overrides,
364
+ };
365
+ }
366
+
367
+ describe('AccessFilter', () => {
368
+ const filter = new AccessFilter({
369
+ requesterId: 'person-alice',
370
+ requesterScope: { level: 'team', entity_id: 'team-platform' },
371
+ requesterOrg: 'organization-acme',
372
+ });
373
+
374
+ it('allows public knowledge from anywhere in org', () => {
375
+ const unit = makeUnit({ sensitivity: 'public', scope: { level: 'organization', entity_id: 'org-acme' } });
376
+ expect(filter.canAccess(unit)).toBe(true);
377
+ });
378
+
379
+ it('allows internal knowledge within org', () => {
380
+ const unit = makeUnit({ sensitivity: 'internal', scope: { level: 'team', entity_id: 'team-other' } });
381
+ expect(filter.canAccess(unit)).toBe(true);
382
+ });
383
+
384
+ it('allows restricted knowledge within same scope', () => {
385
+ const unit = makeUnit({
386
+ sensitivity: 'restricted',
387
+ scope: { level: 'team', entity_id: 'team-platform' },
388
+ });
389
+ expect(filter.canAccess(unit)).toBe(true);
390
+ });
391
+
392
+ it('denies restricted knowledge from different department', () => {
393
+ const unit = makeUnit({
394
+ sensitivity: 'restricted',
395
+ scope: { level: 'department', entity_id: 'department-sales' },
396
+ });
397
+ // Alice is in team-platform, not department-sales
398
+ expect(filter.canAccess(unit)).toBe(false);
399
+ });
400
+
401
+ it('allows confidential knowledge from self', () => {
402
+ const unit = makeUnit({
403
+ sensitivity: 'confidential',
404
+ scope: { level: 'personal', entity_id: 'person-alice' },
405
+ origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-alice' },
406
+ });
407
+ expect(filter.canAccess(unit)).toBe(true);
408
+ });
409
+
410
+ it('denies confidential knowledge from others', () => {
411
+ const unit = makeUnit({
412
+ sensitivity: 'confidential',
413
+ scope: { level: 'personal', entity_id: 'person-bob' },
414
+ origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-bob' },
415
+ });
416
+ expect(filter.canAccess(unit)).toBe(false);
417
+ });
418
+
419
+ it('respects creator_scope override (further restriction)', () => {
420
+ const unit = makeUnit({
421
+ sensitivity: 'internal', // normally accessible org-wide
422
+ creator_scope: { max_level: 'personal' }, // but creator restricted to personal only
423
+ scope: { level: 'personal', entity_id: 'person-bob' },
424
+ });
425
+ // Alice can't access Bob's personal-restricted knowledge even though it's internal
426
+ expect(filter.canAccess(unit)).toBe(false);
427
+ });
428
+
429
+ it('filters a list of results', () => {
430
+ const results = [
431
+ makeUnit({ id: 'a', sensitivity: 'public' }),
432
+ makeUnit({ id: 'b', sensitivity: 'confidential', origin: { source_type: 'conversation', source_ref: '', creator_entity_id: 'person-bob' } }),
433
+ makeUnit({ id: 'c', sensitivity: 'internal' }),
434
+ ];
435
+ const filtered = filter.filterResults(results);
436
+ expect(filtered).toHaveLength(2); // a and c pass, b denied
437
+ expect(filtered.map(r => r.id)).toEqual(['a', 'c']);
438
+ });
439
+ });
440
+ ```
441
+
442
+ - [ ] **Step 2: Implement access filter**
443
+
444
+ ```typescript
445
+ // src/lib/cortex/boundary/access.ts
446
+ import type { ScoredKnowledge, Scope, ScopeLevel, SensitivityClass } from '../knowledge/types';
447
+
448
+ const SCOPE_HIERARCHY: Record<ScopeLevel, number> = {
449
+ personal: 0,
450
+ team: 1,
451
+ department: 2,
452
+ organization: 3,
453
+ };
454
+
455
+ export interface AccessFilterConfig {
456
+ requesterId: string;
457
+ requesterScope: Scope; // requester's team scope
458
+ requesterOrg: string; // requester's org entity_id
459
+ grants?: Set<string>; // knowledge IDs the requester has been granted access to
460
+ }
461
+
462
+ export class AccessFilter {
463
+ private config: AccessFilterConfig;
464
+
465
+ constructor(config: AccessFilterConfig) {
466
+ this.config = config;
467
+ }
468
+
469
+ canAccess(unit: ScoredKnowledge): boolean {
470
+ const sensitivity = (unit.sensitivity ?? 'internal') as SensitivityClass;
471
+ const unitScope = unit.scope ?? { level: 'personal' as ScopeLevel, entity_id: '' };
472
+ const creatorId = unit.origin?.creator_entity_id ?? '';
473
+
474
+ // Check creator_scope override first — most restrictive wins
475
+ if (unit.creator_scope) {
476
+ const maxLevel = SCOPE_HIERARCHY[unit.creator_scope.max_level] ?? 0;
477
+ const requesterLevel = this.getRequesterProximityLevel(unitScope);
478
+ if (requesterLevel > maxLevel) return false;
479
+ }
480
+
481
+ switch (sensitivity) {
482
+ case 'public':
483
+ return true;
484
+
485
+ case 'internal':
486
+ // Accessible to anyone in the same org
487
+ return true;
488
+
489
+ case 'restricted':
490
+ // Accessible within same scope or if policy grants cross-scope access
491
+ return this.isWithinScope(unitScope);
492
+
493
+ case 'confidential':
494
+ // Only creator or explicit grant
495
+ if (this.config.requesterId === creatorId) return true;
496
+ if (this.config.grants?.has(unit.id)) return true;
497
+ return false;
498
+
499
+ default:
500
+ return false;
501
+ }
502
+ }
503
+
504
+ filterResults(results: ScoredKnowledge[]): ScoredKnowledge[] {
505
+ return results.filter(r => this.canAccess(r));
506
+ }
507
+
508
+ private isWithinScope(unitScope: Scope): boolean {
509
+ // Same entity_id = same scope
510
+ if (unitScope.entity_id === this.config.requesterScope.entity_id) return true;
511
+ if (unitScope.entity_id === this.config.requesterId) return true;
512
+ // Same org for org-level scopes
513
+ if (unitScope.level === 'organization' && unitScope.entity_id === this.config.requesterOrg) return true;
514
+ return false;
515
+ }
516
+
517
+ private getRequesterProximityLevel(unitScope: Scope): number {
518
+ // How "far" is the requester from the unit's scope?
519
+ // 0 = same entity, 1 = same scope level, 2+ = further
520
+ if (unitScope.entity_id === this.config.requesterId) return 0;
521
+ if (unitScope.entity_id === this.config.requesterScope.entity_id) return 0;
522
+ return SCOPE_HIERARCHY[unitScope.level] ?? 3;
523
+ }
524
+ }
525
+ ```
526
+
527
+ - [ ] **Step 3: Run tests, commit**
528
+
529
+ ```bash
530
+ git commit -m "feat(cortex): add query-time access filter for boundary enforcement"
531
+ ```
532
+
533
+ ---
534
+
535
+ ### Task 4: Audit trail
536
+
537
+ **Files:**
538
+ - Create: `src/lib/cortex/boundary/audit.ts`
539
+ - Create: `tests/lib/cortex/boundary/audit.test.ts`
540
+
541
+ - [ ] **Step 1: Write failing tests**
542
+
543
+ ```typescript
544
+ // tests/lib/cortex/boundary/audit.test.ts
545
+ import { describe, it, expect, beforeEach, afterEach } from 'vitest';
546
+ import fs from 'fs';
547
+ import path from 'path';
548
+ import os from 'os';
549
+ import Database from 'better-sqlite3';
550
+ import { AuditLog } from '@/lib/cortex/boundary/audit';
551
+
552
+ describe('AuditLog', () => {
553
+ let tmpDir: string;
554
+ let audit: AuditLog;
555
+
556
+ beforeEach(() => {
557
+ tmpDir = fs.mkdtempSync(path.join(os.tmpdir(), 'cortex-audit-'));
558
+ const db = new Database(path.join(tmpDir, 'graph.db'));
559
+ audit = new AuditLog(db);
560
+ });
561
+
562
+ afterEach(() => {
563
+ fs.rmSync(tmpDir, { recursive: true, force: true });
564
+ });
565
+
566
+ it('logs an access decision', () => {
567
+ audit.log({
568
+ requesterId: 'person-alice',
569
+ knowledgeId: 'k1',
570
+ action: 'allowed',
571
+ reason: 'public sensitivity',
572
+ });
573
+ const entries = audit.query({ requesterId: 'person-alice' });
574
+ expect(entries).toHaveLength(1);
575
+ expect(entries[0].action).toBe('allowed');
576
+ });
577
+
578
+ it('logs denied access', () => {
579
+ audit.log({
580
+ requesterId: 'person-alice',
581
+ knowledgeId: 'k2',
582
+ action: 'denied',
583
+ reason: 'confidential, not creator',
584
+ });
585
+ const entries = audit.query({ requesterId: 'person-alice' });
586
+ expect(entries).toHaveLength(1);
587
+ expect(entries[0].action).toBe('denied');
588
+ });
589
+
590
+ it('queries by time range', () => {
591
+ audit.log({ requesterId: 'person-alice', knowledgeId: 'k1', action: 'allowed', reason: 'public' });
592
+ const recent = audit.query({ since: new Date(Date.now() - 60000).toISOString() });
593
+ expect(recent).toHaveLength(1);
594
+
595
+ const future = audit.query({ since: new Date(Date.now() + 60000).toISOString() });
596
+ expect(future).toHaveLength(0);
597
+ });
598
+
599
+ it('supports retention cleanup', () => {
600
+ audit.log({ requesterId: 'person-alice', knowledgeId: 'k1', action: 'allowed', reason: 'test' });
601
+ // Cleanup entries older than 0 days (everything)
602
+ audit.cleanup(0);
603
+ const entries = audit.query({});
604
+ expect(entries).toHaveLength(0);
605
+ });
606
+ });
607
+ ```
608
+
609
+ - [ ] **Step 2: Implement audit log**
610
+
611
+ ```typescript
612
+ // src/lib/cortex/boundary/audit.ts
613
+ import type Database from 'better-sqlite3';
614
+
615
+ export interface AuditEntry {
616
+ requesterId: string;
617
+ knowledgeId: string;
618
+ action: 'allowed' | 'denied';
619
+ reason: string;
620
+ }
621
+
622
+ export interface AuditQueryFilter {
623
+ requesterId?: string;
624
+ since?: string; // ISO timestamp
625
+ limit?: number;
626
+ }
627
+
628
+ export interface AuditRecord extends AuditEntry {
629
+ timestamp: string;
630
+ }
631
+
632
+ export class AuditLog {
633
+ private db: InstanceType<typeof Database>;
634
+
635
+ constructor(db: InstanceType<typeof Database>) {
636
+ this.db = db;
637
+ this.db.exec(`
638
+ CREATE TABLE IF NOT EXISTS audit_log (
639
+ id INTEGER PRIMARY KEY AUTOINCREMENT,
640
+ requester_id TEXT NOT NULL,
641
+ knowledge_id TEXT NOT NULL,
642
+ action TEXT NOT NULL,
643
+ reason TEXT NOT NULL,
644
+ timestamp TEXT NOT NULL
645
+ );
646
+ CREATE INDEX IF NOT EXISTS idx_audit_requester ON audit_log(requester_id);
647
+ CREATE INDEX IF NOT EXISTS idx_audit_timestamp ON audit_log(timestamp);
648
+ `);
649
+ }
650
+
651
+ log(entry: AuditEntry): void {
652
+ this.db.prepare(`
653
+ INSERT INTO audit_log (requester_id, knowledge_id, action, reason, timestamp)
654
+ VALUES (?, ?, ?, ?, ?)
655
+ `).run(entry.requesterId, entry.knowledgeId, entry.action, entry.reason, new Date().toISOString());
656
+ }
657
+
658
+ query(filter: AuditQueryFilter): AuditRecord[] {
659
+ let sql = 'SELECT * FROM audit_log WHERE 1=1';
660
+ const params: any[] = [];
661
+
662
+ if (filter.requesterId) {
663
+ sql += ' AND requester_id = ?';
664
+ params.push(filter.requesterId);
665
+ }
666
+ if (filter.since) {
667
+ sql += ' AND timestamp >= ?';
668
+ params.push(filter.since);
669
+ }
670
+
671
+ sql += ' ORDER BY timestamp DESC';
672
+
673
+ if (filter.limit) {
674
+ sql += ' LIMIT ?';
675
+ params.push(filter.limit);
676
+ }
677
+
678
+ return (this.db.prepare(sql).all(...params) as any[]).map(row => ({
679
+ requesterId: row.requester_id,
680
+ knowledgeId: row.knowledge_id,
681
+ action: row.action,
682
+ reason: row.reason,
683
+ timestamp: row.timestamp,
684
+ }));
685
+ }
686
+
687
+ cleanup(retentionDays: number): void {
688
+ const cutoff = new Date(Date.now() - retentionDays * 86400000).toISOString();
689
+ this.db.prepare('DELETE FROM audit_log WHERE timestamp < ?').run(cutoff);
690
+ }
691
+ }
692
+ ```
693
+
694
+ - [ ] **Step 3: Run tests, commit**
695
+
696
+ ```bash
697
+ git commit -m "feat(cortex): add audit trail for access decisions"
698
+ ```
699
+
700
+ ---
701
+
702
+ ## Chunk 3: Integration
703
+
704
+ ### Task 5: Integrate with ingestion pipeline
705
+
706
+ **Files:**
707
+ - Modify: `src/lib/cortex/ingestion/pipeline.ts`
708
+
709
+ - [ ] **Step 1: Read pipeline.ts**
710
+
711
+ - [ ] **Step 2: Add auto-classification during ingestion**
712
+
713
+ Import the classifier:
714
+ ```typescript
715
+ import { classifySensitivity } from '../boundary/classifier';
716
+ ```
717
+
718
+ In the KnowledgeUnit construction (where v2 fields are set), replace the hardcoded `sensitivity: 'internal'` with:
719
+ ```typescript
720
+ sensitivity: classifySensitivity(chunk.text),
721
+ ```
722
+
723
+ This ensures every ingested knowledge unit gets an auto-classified sensitivity level.
724
+
725
+ - [ ] **Step 3: Run pipeline tests to verify no regressions**
726
+
727
+ ```bash
728
+ npx vitest run tests/lib/cortex/ingestion/
729
+ ```
730
+
731
+ - [ ] **Step 4: Commit**
732
+
733
+ ```bash
734
+ git commit -m "feat(cortex): auto-classify sensitivity during ingestion"
735
+ ```
736
+
737
+ ---
738
+
739
+ ### Task 6: Integrate AccessFilter with ContextEngine
740
+
741
+ **Files:**
742
+ - Modify: `src/lib/cortex/retrieval/context-engine.ts`
743
+
744
+ - [ ] **Step 1: Read context-engine.ts**
745
+
746
+ - [ ] **Step 2: Add AccessFilter to the pipeline**
747
+
748
+ Import AccessFilter:
749
+ ```typescript
750
+ import { AccessFilter } from '../boundary/access';
751
+ ```
752
+
753
+ Add to `ContextEngineDeps`:
754
+ ```typescript
755
+ accessFilter?: AccessFilter;
756
+ ```
757
+
758
+ In the `assemble()` method, after fusion/ranking (Stage 5) but before conflict detection (Stage 6), apply the access filter:
759
+
760
+ ```typescript
761
+ // Stage 5.5: Access control filtering
762
+ let accessible = fused;
763
+ if (this.deps.accessFilter) {
764
+ accessible = this.deps.accessFilter.filterResults(fused);
765
+ }
766
+ ```
767
+
768
+ Then pass `accessible` (not `fused`) to conflict detection and formatting.
769
+
770
+ - [ ] **Step 3: Run context-engine tests to verify no regressions**
771
+
772
+ ```bash
773
+ npx vitest run tests/lib/cortex/retrieval/context-engine.test.ts
774
+ ```
775
+
776
+ - [ ] **Step 4: Commit**
777
+
778
+ ```bash
779
+ git commit -m "feat(cortex): integrate access filter into context assembly pipeline"
780
+ ```
781
+
782
+ ---
783
+
784
+ ### Task 7: Barrel export and config integration
785
+
786
+ **Files:**
787
+ - Create: `src/lib/cortex/boundary/index.ts`
788
+ - Modify: `src/lib/cortex/config.ts` (add policies array to config)
789
+
790
+ - [ ] **Step 1: Create barrel export**
791
+
792
+ ```typescript
793
+ // src/lib/cortex/boundary/index.ts
794
+ export { classifySensitivity } from './classifier';
795
+ export { PolicyEngine } from './policy';
796
+ export type { Policy, PolicyAction, PropagationTarget } from './policy';
797
+ export { AccessFilter } from './access';
798
+ export type { AccessFilterConfig } from './access';
799
+ export { AuditLog } from './audit';
800
+ export type { AuditEntry, AuditRecord, AuditQueryFilter } from './audit';
801
+ ```
802
+
803
+ - [ ] **Step 2: Add policies to CortexConfig**
804
+
805
+ In `src/lib/cortex/config.ts`, add to the `CortexConfig` interface:
806
+ ```typescript
807
+ policies?: Policy[]; // Organizational boundary policies
808
+ ```
809
+
810
+ And in `DEFAULT_CORTEX_CONFIG`:
811
+ ```typescript
812
+ policies: [],
813
+ ```
814
+
815
+ Import the Policy type:
816
+ ```typescript
817
+ import type { Policy } from './boundary/policy';
818
+ ```
819
+
820
+ - [ ] **Step 3: Run full test suite**
821
+
822
+ ```bash
823
+ npx vitest run tests/lib/cortex/
824
+ ```
825
+
826
+ - [ ] **Step 4: Commit**
827
+
828
+ ```bash
829
+ git commit -m "feat(cortex): add boundary module barrel export and config integration"
830
+ ```
831
+
832
+ ---
833
+
834
+ ## Summary
835
+
836
+ | Task | Component | Tests | Status |
837
+ |------|-----------|-------|--------|
838
+ | 1 | Sensitivity classifier | 7 | |
839
+ | 2 | Policy engine | 6 | |
840
+ | 3 | Access filter | 8 | |
841
+ | 4 | Audit trail | 4 | |
842
+ | 5 | Pipeline integration | regression | |
843
+ | 6 | ContextEngine integration | regression | |
844
+ | 7 | Barrel export + config | regression | |
845
+
846
+ **Total: 7 tasks, ~25 new tests, 3 chunks**
847
+
848
+ **Key design decisions:**
849
+ - Auto-classification is regex-based (no LLM call) — fast, deterministic, auditable
850
+ - Policies are stored in CortexConfig (admin-editable JSON) — not code
851
+ - AccessFilter is a separate class that can be composed with ContextEngine or used standalone
852
+ - Audit log uses the entity graph's SQLite DB (same file, new table) — no new database
853
+ - Most restrictive classification always wins (confidential > restricted > internal > public)