@askexenow/exe-os 0.9.374 → 0.9.376

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 (455) hide show
  1. package/deploy/compose/.env.customer.example +16 -1
  2. package/deploy/compose/.env.example +16 -1
  3. package/deploy/compose/docker-compose.yml +80 -18
  4. package/deploy/compose/gateway-watchdog.sh +17 -0
  5. package/deploy/compose/generate-env.ts +41 -1
  6. package/deploy/compose/sso-edge/default.conf.template +59 -63
  7. package/deploy/compose/sso-edge/error-pages/404.html +129 -0
  8. package/deploy/compose/sso-edge/error-pages/500.html +129 -0
  9. package/deploy/compose/sso-edge/error-pages/503.html +118 -0
  10. package/deploy/compose/sso-edge/sso-redirect.conf +115 -92
  11. package/dist/.dist-verified.json +3 -3
  12. package/dist/{active-agent-ONPPEWQV.js → active-agent-BOBBUJ74.js} +6 -6
  13. package/dist/{active-agent-UJKMG7LJ.js → active-agent-GFGEGK2U.js} +6 -6
  14. package/dist/{agent-defs-generator-ZWI6DXOE.js → agent-defs-generator-OX6UFPRX.js} +5 -5
  15. package/dist/{agent-loop-OYHJKNYH.js → agent-loop-7ZRH56EX.js} +1 -1
  16. package/dist/{agentic-ontology-WHFJ3QFS.js → agentic-ontology-DT3VOXBT.js} +1 -1
  17. package/dist/{backfill-metadata-3OUSQD5V.js → backfill-metadata-VRP6PTPP.js} +9 -9
  18. package/dist/{backup-verify-ZKTUYLTA.js → backup-verify-LWHKGOOV.js} +1 -1
  19. package/dist/behavior-injection-GMZKZ3BT.js +83 -0
  20. package/dist/behavior-promotion-QPC4AQ24.js +62 -0
  21. package/dist/{behaviors-ZJ45TFBJ.js → behaviors-GPI4BLTC.js} +16 -14
  22. package/dist/bin/agentic-ontology-backfill.js +10 -10
  23. package/dist/bin/agentic-reflection-backfill.js +11 -11
  24. package/dist/bin/agentic-semantic-label.js +10 -10
  25. package/dist/bin/backfill-conversations.js +14 -12
  26. package/dist/bin/backfill-responses.js +14 -12
  27. package/dist/bin/backfill-vectors.js +16 -14
  28. package/dist/bin/bulk-sync-postgres.js +21 -19
  29. package/dist/bin/cc-doctor.js +19 -11
  30. package/dist/bin/cleanup-stale-review-tasks.js +27 -26
  31. package/dist/bin/cli.js +83 -109
  32. package/dist/bin/daemon-restart-handoff.js +2 -1
  33. package/dist/bin/deferred-daemon-restart.js +118 -110
  34. package/dist/bin/exe-actions.js +176 -0
  35. package/dist/bin/exe-agent-config.js +5 -5
  36. package/dist/bin/exe-agent.js +23 -23
  37. package/dist/bin/exe-assign.js +16 -14
  38. package/dist/bin/exe-boot.js +91 -71
  39. package/dist/bin/exe-call.js +8 -8
  40. package/dist/bin/exe-cicd.js +1210 -0
  41. package/dist/bin/exe-cloud.js +70 -37
  42. package/dist/bin/exe-config-dump.js +5 -5
  43. package/dist/bin/exe-dispatch.js +28 -27
  44. package/dist/bin/exe-doctor.js +12 -11
  45. package/dist/bin/exe-export-behaviors.js +20 -18
  46. package/dist/bin/exe-forget.js +11 -11
  47. package/dist/bin/exe-gateway.js +10 -10
  48. package/dist/bin/exe-healthcheck.js +22 -10
  49. package/dist/bin/exe-heartbeat.js +33 -32
  50. package/dist/bin/exe-kill.js +32 -31
  51. package/dist/bin/exe-launch-agent.js +76 -54
  52. package/dist/bin/exe-mcp.js +10 -6
  53. package/dist/bin/exe-memory-reads.js +9 -9
  54. package/dist/bin/exe-model-supervisor.js +138 -0
  55. package/dist/bin/exe-new-employee.js +14 -14
  56. package/dist/bin/exe-os-mcp-proxy.js +10 -6
  57. package/dist/bin/exe-pending-messages.js +28 -27
  58. package/dist/bin/exe-pending-notifications.js +27 -26
  59. package/dist/bin/exe-pending-reviews.js +28 -27
  60. package/dist/bin/exe-rename.js +9 -9
  61. package/dist/bin/exe-repo-truth.js +1 -1
  62. package/dist/bin/exe-review.js +31 -30
  63. package/dist/bin/exe-search.js +10 -10
  64. package/dist/bin/exe-session-cleanup.js +32 -31
  65. package/dist/bin/exe-settings.js +21 -19
  66. package/dist/bin/exe-start-codex.js +31 -25
  67. package/dist/bin/exe-start-opencode.js +24 -22
  68. package/dist/bin/exe-start.sh +11 -2
  69. package/dist/bin/exe-status.js +29 -28
  70. package/dist/bin/exe-support.js +3 -3
  71. package/dist/bin/exe-team.js +7 -7
  72. package/dist/bin/exe-timers.js +2 -1
  73. package/dist/bin/exe-watchdog.js +170 -16
  74. package/dist/bin/generate-hook-manifest.js +8 -41
  75. package/dist/bin/git-sweep.js +28 -27
  76. package/dist/bin/graph-backfill.js +11 -11
  77. package/dist/bin/graph-export.js +10 -10
  78. package/dist/bin/hooks-cli.js +289 -0
  79. package/dist/bin/import-history.js +14 -14
  80. package/dist/bin/install.js +130 -116
  81. package/dist/bin/intercom-check.js +5 -5
  82. package/dist/bin/mcp-sessions.js +2 -2
  83. package/dist/bin/orchestration-metrics.js +7 -7
  84. package/dist/bin/postgres-agentic-reflection-backfill.js +4 -4
  85. package/dist/bin/postgres-agentic-semantic-backfill.js +4 -4
  86. package/dist/bin/pre-publish.js +1 -1
  87. package/dist/bin/reconcile-backlog.js +2 -2
  88. package/dist/bin/registry-proxy.js +2 -2
  89. package/dist/bin/scan-tasks.js +52 -38
  90. package/dist/bin/setup.js +1 -1
  91. package/dist/bin/shard-migrate.js +9 -9
  92. package/dist/bin/stack-update.js +10 -5
  93. package/dist/bin/verify-stack.js +3 -1
  94. package/dist/bin/vps-health-gate.js +1 -1
  95. package/dist/{boot-generation-JKVZ4ZAT.js → boot-generation-BN6GKASY.js} +6 -6
  96. package/dist/{boot-review-sections-2M6BTG73.js → boot-review-sections-OQ5JGSOD.js} +26 -25
  97. package/dist/{branch-hygiene-U5GFRSTP.js → branch-hygiene-QLD77IMJ.js} +1 -1
  98. package/dist/build-manifest.json +1186 -1106
  99. package/dist/{capability-cards-5IMJT6J7.js → capability-cards-EDZ62HKG.js} +5 -5
  100. package/dist/{capacity-monitor-SAXCQK7O.js → capacity-monitor-6GMTVILS.js} +28 -27
  101. package/dist/{catchup-brief-U2TXBLHD.js → catchup-brief-SGGBMDUP.js} +32 -31
  102. package/dist/{cc-binary-detect-6TNIY5JX.js → cc-binary-detect-ZR6WNOUU.js} +1 -3
  103. package/dist/{chunk-NKETJCB5.js → chunk-2ODXCCMR.js} +18 -3
  104. package/dist/{hook-integrity-KGAV6ZC2.js → chunk-3L72UBUH.js} +28 -15
  105. package/dist/chunk-3OX5S7KZ.js +273 -0
  106. package/dist/{chunk-W75GTHR3.js → chunk-3SRZNJKD.js} +1 -1
  107. package/dist/{chunk-I4DNJFDR.js → chunk-42IFYZUN.js} +4 -4
  108. package/dist/{chunk-JHI5WMK5.js → chunk-473JUDCT.js} +5 -5
  109. package/dist/{chunk-ANLFH23R.js → chunk-4F5CNI65.js} +1 -1
  110. package/dist/{chunk-AWWKRZMB.js → chunk-4KVSCQND.js} +87 -14
  111. package/dist/{chunk-ZCERWHY2.js → chunk-4M6RXJEY.js} +33 -23
  112. package/dist/{chunk-YTSXPJUQ.js → chunk-4YJEEOYT.js} +3 -3
  113. package/dist/{chunk-6RKKVPYF.js → chunk-4YUGB637.js} +1 -1
  114. package/dist/{chunk-XXOPG4BW.js → chunk-4ZSOKEDY.js} +3 -3
  115. package/dist/{chunk-55BEFF4V.js → chunk-5DF4Y6EC.js} +1 -1
  116. package/dist/{chunk-4QCFFW2H.js → chunk-5QCIWWFA.js} +46 -0
  117. package/dist/{chunk-3UUX5OY4.js → chunk-5QKLWJ4Z.js} +1 -1
  118. package/dist/{chunk-YSLGFPWX.js → chunk-5UBWBXLF.js} +3 -3
  119. package/dist/chunk-5WA4DG2A.js +117 -0
  120. package/dist/{chunk-4EN3IZ3Q.js → chunk-64ODONK2.js} +67 -1
  121. package/dist/{chunk-TAMDAOCU.js → chunk-66CGXQUA.js} +239 -39
  122. package/dist/{chunk-QHJR7IMX.js → chunk-6F3FQCAQ.js} +3 -3
  123. package/dist/{chunk-WMEYJT4R.js → chunk-6FG34V6D.js} +15 -14
  124. package/dist/{chunk-NMH5ZQPU.js → chunk-6KQ6WMTI.js} +1 -1
  125. package/dist/{chunk-IRVOXUSK.js → chunk-6WKBTZVL.js} +10 -4
  126. package/dist/{chunk-NOKJCF27.js → chunk-7INEFMVU.js} +9 -3
  127. package/dist/{chunk-GSJLB6JI.js → chunk-7THUQU44.js} +34 -8
  128. package/dist/{chunk-HDLAB7W3.js → chunk-7UH2JWBF.js} +1 -1
  129. package/dist/{chunk-KTCXJWJG.js → chunk-7UNMSF5O.js} +1 -1
  130. package/dist/{chunk-JTVIANUB.js → chunk-AEUGIJDO.js} +3 -1
  131. package/dist/{chunk-DSJI76XL.js → chunk-AHNVFBVB.js} +113 -16
  132. package/dist/{chunk-IBS2FAI4.js → chunk-AUKRBHHZ.js} +4 -1
  133. package/dist/{chunk-AKLJ4JH3.js → chunk-BBK2TSK3.js} +1 -1
  134. package/dist/{chunk-ZL4AGWAH.js → chunk-BNWWVYRN.js} +6 -5
  135. package/dist/{chunk-PY3FOMRN.js → chunk-BQEZPRUC.js} +4 -4
  136. package/dist/{chunk-DIXXEE3S.js → chunk-BQXYXJYC.js} +721 -309
  137. package/dist/{chunk-ORM7ZFKC.js → chunk-BZ546I4Q.js} +32 -0
  138. package/dist/{chunk-3KDCORDO.js → chunk-C2UN464N.js} +1 -1
  139. package/dist/{chunk-75H4R62K.js → chunk-CBPNZFSU.js} +0 -2
  140. package/dist/{chunk-YLXTKI6M.js → chunk-CHO5SNWR.js} +1 -1
  141. package/dist/{chunk-MXPNVSXI.js → chunk-CIEVY5TD.js} +11 -11
  142. package/dist/{chunk-UBK7HK3J.js → chunk-CKLJT2DH.js} +2 -2
  143. package/dist/{chunk-MOGA4Q7F.js → chunk-CKOJP7JI.js} +1 -1
  144. package/dist/{chunk-V3W3SATA.js → chunk-CL4J4757.js} +1 -1
  145. package/dist/{chunk-XNNECNDL.js → chunk-CQFWTWC6.js} +13 -13
  146. package/dist/{chunk-PDVXWXTL.js → chunk-CROVXJ4S.js} +3 -3
  147. package/dist/{chunk-WJG344NC.js → chunk-CWSLTSL6.js} +8 -8
  148. package/dist/{chunk-VMTZ4RUW.js → chunk-DDMGQ5Q3.js} +60 -26
  149. package/dist/{chunk-YKC7QDZH.js → chunk-DN24VTS5.js} +31 -6
  150. package/dist/{chunk-IN6CAM4F.js → chunk-EHAN752X.js} +7 -7
  151. package/dist/{chunk-EXTZSNWL.js → chunk-EPHSISMT.js} +2 -2
  152. package/dist/{chunk-6EZQUNE6.js → chunk-FCMQVEVL.js} +36 -3
  153. package/dist/{chunk-3L2QU5ZF.js → chunk-FS7XF7SE.js} +1 -1
  154. package/dist/{chunk-LGS2V2XD.js → chunk-FUKVP54K.js} +66 -19
  155. package/dist/{chunk-44TLJZJ5.js → chunk-FX2QRSRT.js} +1 -1
  156. package/dist/{chunk-PWRC5XZO.js → chunk-FXZ6VGFW.js} +16 -8
  157. package/dist/{chunk-NT7W4RXD.js → chunk-GKDAQL45.js} +1 -1
  158. package/dist/{chunk-EKE37MO4.js → chunk-GOT5ZHPX.js} +3 -3
  159. package/dist/{chunk-SLLLOOEI.js → chunk-GPJIBLP4.js} +1 -0
  160. package/dist/{chunk-EKYYMIVT.js → chunk-GPUOUUHA.js} +10 -1
  161. package/dist/{chunk-PB5S7YOF.js → chunk-GXNBPTPJ.js} +1 -1
  162. package/dist/{chunk-4SJ4LK4V.js → chunk-HE34XVD5.js} +5 -5
  163. package/dist/{chunk-6VHOQ3IM.js → chunk-HHAKXIKX.js} +12 -9
  164. package/dist/{chunk-TFKCERAK.js → chunk-HHT527PV.js} +38 -41
  165. package/dist/{chunk-ZSODLMFV.js → chunk-HIVOLPLD.js} +1 -40
  166. package/dist/{chunk-UCFC2AEI.js → chunk-I3LDTSWU.js} +1 -1
  167. package/dist/{chunk-Q3AXXKDF.js → chunk-IKXH4BFC.js} +5 -5
  168. package/dist/chunk-IMYGYIAI.js +23 -0
  169. package/dist/{chunk-GS7LIT34.js → chunk-IPHLUZ37.js} +1 -1
  170. package/dist/{chunk-M4IRPXSZ.js → chunk-IZA7XW2Q.js} +3 -3
  171. package/dist/{chunk-SEQIPGLU.js → chunk-IZLML47J.js} +1 -1
  172. package/dist/{chunk-4HKTO2SV.js → chunk-JRMHGO5B.js} +1 -1
  173. package/dist/{chunk-U73AC5AN.js → chunk-JSTTPYL3.js} +16 -16
  174. package/dist/{chunk-6SCGLHJ7.js → chunk-JVWLHBAV.js} +4 -4
  175. package/dist/{chunk-OVEQE6YS.js → chunk-K7UNIEB4.js} +254 -48
  176. package/dist/{chunk-HNWS7YHN.js → chunk-KBR5LIWD.js} +1 -1
  177. package/dist/{chunk-AKLQSC6W.js → chunk-KI7O64XV.js} +328 -98
  178. package/dist/{chunk-XXFKSJYA.js → chunk-KK3MIY5C.js} +5 -5
  179. package/dist/{chunk-U6SUKSZR.js → chunk-KO3OHI6V.js} +3 -3
  180. package/dist/{chunk-NJFJWQNN.js → chunk-L5CGXEZC.js} +27 -22
  181. package/dist/{chunk-NBXDXKLC.js → chunk-LK3XQDBP.js} +1 -1
  182. package/dist/{chunk-T3QUKNLI.js → chunk-LM443ORV.js} +1 -1
  183. package/dist/{chunk-BBSIEYF5.js → chunk-LNAFLXL7.js} +12 -4
  184. package/dist/{chunk-32YV32VA.js → chunk-LTUA5EYI.js} +122 -11
  185. package/dist/{chunk-23MVDXLY.js → chunk-MAXD5JQL.js} +11 -10
  186. package/dist/{chunk-GNUAL43X.js → chunk-MFASHRJ6.js} +5 -5
  187. package/dist/chunk-MFYMDGE7.js +37 -0
  188. package/dist/{chunk-VKJGHAZT.js → chunk-MGVILAYU.js} +57 -13
  189. package/dist/{chunk-DB55JZHU.js → chunk-MSLWRWTI.js} +1 -1
  190. package/dist/{chunk-C2L622QJ.js → chunk-NB5IRTC4.js} +52 -44
  191. package/dist/{chunk-2ZOEC4KC.js → chunk-ND75TGPR.js} +2 -2
  192. package/dist/{chunk-VRTCVZND.js → chunk-NE34MWVL.js} +142 -16
  193. package/dist/{chunk-S2WBS6BG.js → chunk-NMOFLWDY.js} +1 -1
  194. package/dist/{chunk-CRCB5S7I.js → chunk-NPXKGBVZ.js} +140 -23
  195. package/dist/{chunk-JSMDRKPJ.js → chunk-NRBGUIPE.js} +1 -1
  196. package/dist/{chunk-4LWBC7CM.js → chunk-NY6SBR4O.js} +1 -1
  197. package/dist/{chunk-UCUOGVDX.js → chunk-O3K2C22L.js} +13 -1
  198. package/dist/{chunk-R522MWAR.js → chunk-OATET4BV.js} +2 -2
  199. package/dist/chunk-OOZU5H3T.js +86 -0
  200. package/dist/{chunk-XFTEX77S.js → chunk-OQ4FNDRG.js} +28 -6
  201. package/dist/{chunk-VYQ7B7DI.js → chunk-OWVX52XF.js} +4 -4
  202. package/dist/{chunk-AETLDRZB.js → chunk-PEAAX6UA.js} +1 -1
  203. package/dist/{chunk-UM3N6VND.js → chunk-PFAVHC5N.js} +5 -5
  204. package/dist/chunk-PMVVUIHH.js +85 -0
  205. package/dist/chunk-PPMGQFLJ.js +2317 -0
  206. package/dist/{chunk-7TSBV3SD.js → chunk-PTY2N23C.js} +310 -2
  207. package/dist/{chunk-UKLN57Q5.js → chunk-PZ5SKYK6.js} +4 -4
  208. package/dist/{chunk-636LKCKE.js → chunk-Q6ZLQMP2.js} +1 -1
  209. package/dist/{chunk-N7VEP5B3.js → chunk-QFR5EKZG.js} +29 -7
  210. package/dist/{chunk-YMP2QSOP.js → chunk-QN56VQ6Z.js} +1 -1
  211. package/dist/{chunk-6YVUR3OU.js → chunk-QR3BUMOS.js} +2 -2
  212. package/dist/{chunk-XZ65ST2I.js → chunk-QV5CQLQH.js} +2 -2
  213. package/dist/{chunk-DJOIMFKV.js → chunk-REZIGNA6.js} +2 -2
  214. package/dist/{chunk-UQGSBM3U.js → chunk-RFPMXR6B.js} +11 -0
  215. package/dist/{chunk-DN4YVV4Z.js → chunk-RSABKW6B.js} +1 -1
  216. package/dist/{chunk-LP4GB656.js → chunk-RZNP35SI.js} +2 -2
  217. package/dist/{chunk-NUTZJZKW.js → chunk-SKTAZGFI.js} +10 -42
  218. package/dist/{chunk-TQAZTRQ3.js → chunk-SVXUT2DN.js} +4 -4
  219. package/dist/{chunk-DJ7YXOTU.js → chunk-T7EF5CQO.js} +3 -3
  220. package/dist/{chunk-QAEWWYHL.js → chunk-TDF2XKLK.js} +5 -1
  221. package/dist/{chunk-ZGYNKA3O.js → chunk-TT5BBVLX.js} +29 -31
  222. package/dist/{chunk-5H47VHB7.js → chunk-UWX6MMCX.js} +1 -1
  223. package/dist/{chunk-XL5MFGMR.js → chunk-V4YNN7PA.js} +10 -3
  224. package/dist/{chunk-SL6KQYDU.js → chunk-V5DDXXMP.js} +7 -7
  225. package/dist/{chunk-DZKPOSFD.js → chunk-VH6SPPNA.js} +1 -1
  226. package/dist/{chunk-LDNYSMPZ.js → chunk-VJUUI2VT.js} +1 -1
  227. package/dist/{chunk-CBCGDEJA.js → chunk-VN5WOOAQ.js} +42 -6
  228. package/dist/{chunk-EXDW3E2R.js → chunk-VPHJ2LUI.js} +165 -15
  229. package/dist/{chunk-GOMQ7PVQ.js → chunk-WJC6AAJN.js} +1 -1
  230. package/dist/{chunk-GJI77VDO.js → chunk-WVBVUVZB.js} +6 -5
  231. package/dist/{chunk-A6PDF4BO.js → chunk-XTQ7R2PA.js} +2 -2
  232. package/dist/{chunk-L6RXG36J.js → chunk-Y2HD2YB7.js} +1 -1
  233. package/dist/{chunk-KTU3EAWK.js → chunk-YAACLBZ7.js} +5 -5
  234. package/dist/{chunk-7GE2EQ23.js → chunk-YGVAKKGJ.js} +11 -6
  235. package/dist/chunk-YLHACCCB.js +166 -0
  236. package/dist/{chunk-PLZSZOZN.js → chunk-YP6UGVEY.js} +3 -3
  237. package/dist/{chunk-ULIBLJ6W.js → chunk-YYC553FO.js} +5 -5
  238. package/dist/{chunk-T35RCQFE.js → chunk-YZPEQW7H.js} +9 -8
  239. package/dist/{chunk-KI5PFRG6.js → chunk-ZKGWHT56.js} +60 -2
  240. package/dist/{chunk-NUK7EEN5.js → chunk-ZKJ5S23O.js} +33 -13
  241. package/dist/chunk-ZLPS3GR7.js +146 -0
  242. package/dist/{chunk-XH7YL7JM.js → chunk-ZMX22HSS.js} +50 -6
  243. package/dist/{chunk-JY5GAZYC.js → chunk-ZQEJ4IX2.js} +4 -0
  244. package/dist/{chunk-R4CBHKZ2.js → chunk-ZS5JO6QV.js} +7 -6
  245. package/dist/{cleanup-graph-garbage-DPJGO52H.js → cleanup-graph-garbage-LAPIZGFX.js} +12 -12
  246. package/dist/{cloud-sync-command-JPNTT4OQ.js → cloud-sync-command-QAZ2NWRA.js} +11 -2
  247. package/dist/{cloud-sync-db-init-V2LWIUQU.js → cloud-sync-db-init-HAGVF32Y.js} +1 -1
  248. package/dist/{cloud-sync-shutdown-BNALPWGX.js → cloud-sync-shutdown-DAEPCFVK.js} +5 -5
  249. package/dist/{co-activation-CMNSWS6B.js → co-activation-523TKQPZ.js} +5 -5
  250. package/dist/{co-occurrence-WRI2NAN6.js → co-occurrence-PQUCTENN.js} +36 -17
  251. package/dist/{code-context-index-NOJSHLPN.js → code-context-index-LIDOFKOR.js} +6 -4
  252. package/dist/{code-context-watcher-VZNZU3BO.js → code-context-watcher-4F7K2N3U.js} +6 -4
  253. package/dist/{content-extractor-NXYNEF5K.js → content-extractor-DJM5EUDA.js} +2 -2
  254. package/dist/{conversation-entity-extractor-74252CAO.js → conversation-entity-extractor-THGKQ5RD.js} +5 -5
  255. package/dist/{crdt-sync-B3JN6AIV.js → crdt-sync-32B55NOJ.js} +1 -1
  256. package/dist/{crm-webhook-GYWQRFET.js → crm-webhook-FHRISFYQ.js} +2 -2
  257. package/dist/{cto-delegation-gate-LQHVLEMW.js → cto-delegation-gate-O6XPGECP.js} +27 -26
  258. package/dist/{daemon-auth-QZHEO7IQ.js → daemon-auth-PNKHERLV.js} +6 -1
  259. package/dist/daemon-drift-N2GKUBAO.js +15 -0
  260. package/dist/{daemon-orchestration-5HIQALZH.js → daemon-orchestration-BWLSJG2X.js} +33 -30
  261. package/dist/{daemon-ready-P2BR2XP5.js → daemon-ready-BN6EZLTQ.js} +1 -1
  262. package/dist/{daemon-ready-signal-CKXPUMJ2.js → daemon-ready-signal-PNDMVKPJ.js} +3 -1
  263. package/dist/{daemon-restart-circuit-breaker-SMTWFX27.js → daemon-restart-circuit-breaker-CD4VMCU7.js} +1 -1
  264. package/dist/daemon-restart-report-FIO5HZTJ.js +15 -0
  265. package/dist/{daemon-timer-report-TNJH5SFY.js → daemon-timer-report-6UK5PSDP.js} +2 -1
  266. package/dist/{db-integrity-events-2DTFO37N.js → db-integrity-events-GYGANKZV.js} +1 -1
  267. package/dist/{destructive-data-guard-BVFWPPIS.js → destructive-data-guard-HHWUBIGS.js} +1 -1
  268. package/dist/{doc-graph-extractor-PQHDHQPQ.js → doc-graph-extractor-HOKOV7BE.js} +10 -10
  269. package/dist/{documents-C4SSPJMC.js → documents-HWEJMONR.js} +16 -14
  270. package/dist/{dreaming-XAO3FCBV.js → dreaming-FMNDODG2.js} +31 -30
  271. package/dist/{employee-boot-brief-W4OHUMRQ.js → employee-boot-brief-DBFROOQJ.js} +35 -34
  272. package/dist/{entity-boost-3UWGXG5O.js → entity-boost-5V4W6NFA.js} +1 -1
  273. package/dist/{exe-drift-AG2KMKD5.js → exe-drift-V55UAYRT.js} +6 -6
  274. package/dist/{exe-export-IC5BT335.js → exe-export-LHN42ZUS.js} +18 -16
  275. package/dist/{exe-import-A35ZLDPG.js → exe-import-M536BEZC.js} +18 -16
  276. package/dist/{exe-key-TCMJNYLA.js → exe-key-37XIR22X.js} +111 -107
  277. package/dist/{exe-org-JXCR3JYZ.js → exe-org-7TDIRNTE.js} +14 -14
  278. package/dist/{exe-snapshot-SV6SRIG6.js → exe-snapshot-EOUBCIQK.js} +34 -33
  279. package/dist/{fast-db-init-L2RGKJWH.js → fast-db-init-GWUZ746B.js} +1 -1
  280. package/dist/{founder-context-D4HFIESJ.js → founder-context-6LQKET4A.js} +2 -2
  281. package/dist/{fts-integrity-4YB34KWX.js → fts-integrity-PLAL6NMG.js} +1 -1
  282. package/dist/gateway/index.js +17 -17
  283. package/dist/{git-main-guard-VTW4N3CM.js → git-main-guard-BGICS25C.js} +1 -1
  284. package/dist/{git-staleness-TN7CYGFG.js → git-staleness-QNNXJK3W.js} +5 -5
  285. package/dist/{global-procedures-YFDEIOG7.js → global-procedures-NMQGF54V.js} +7 -7
  286. package/dist/{gotrue-session-ODZ2ERJX.js → gotrue-session-U4H3UGHL.js} +1 -3
  287. package/dist/{graph-auto-extract-3YR3TYRW.js → graph-auto-extract-7POGAKHM.js} +10 -10
  288. package/dist/{graph-query-AP5R6ZHO.js → graph-query-ZEDO4BDF.js} +1 -1
  289. package/dist/{graph-rag-Z2KCJTPK.js → graph-rag-JA7XN7NO.js} +5 -5
  290. package/dist/hook-integrity-6NLSNTXD.js +15 -0
  291. package/dist/{hook-prefetch-K5DN3TOQ.js → hook-prefetch-4KH3D4YU.js} +28 -26
  292. package/dist/hook-tamper-log-Z4PWC7N4.js +90 -0
  293. package/dist/hooks/bug-report-worker.js +31 -30
  294. package/dist/hooks/codex-stop-task-finalizer.js +33 -32
  295. package/dist/hooks/commit-complete.js +30 -29
  296. package/dist/hooks/error-recall.js +12 -12
  297. package/dist/hooks/exe-heartbeat-hook.js +7 -7
  298. package/dist/hooks/ingest-worker.js +17 -15
  299. package/dist/hooks/ingest.js +20 -20
  300. package/dist/hooks/instructions-loaded.js +9 -9
  301. package/dist/hooks/manifest.json +20 -20
  302. package/dist/hooks/notification.js +8 -8
  303. package/dist/hooks/post-compact.js +7 -7
  304. package/dist/hooks/post-tool-combined.js +14 -14
  305. package/dist/hooks/pre-compact.js +30 -29
  306. package/dist/hooks/pre-tool-use.js +303 -489
  307. package/dist/hooks/prompt-submit.js +61 -54
  308. package/dist/hooks/session-end.js +35 -34
  309. package/dist/hooks/session-start.js +18 -18
  310. package/dist/hooks/stop.js +36 -35
  311. package/dist/hooks/subagent-stop.js +32 -31
  312. package/dist/hooks/summary-worker.js +36 -35
  313. package/dist/index.js +39 -38
  314. package/dist/{installer-LK35OX6R.js → installer-M34Q7LAS.js} +25 -10
  315. package/dist/{installer-54HTN5RE.js → installer-POV6TDQ5.js} +12 -8
  316. package/dist/{installer-LLWKZI2S.js → installer-S624ZOMB.js} +12 -8
  317. package/dist/{intercom-queue-5NOT2RKI.js → intercom-queue-MKDWAEUV.js} +26 -25
  318. package/dist/lib/cloud-sync.js +27 -19
  319. package/dist/lib/consolidation.js +12 -12
  320. package/dist/lib/database.js +5 -5
  321. package/dist/lib/db-backup.js +7 -1
  322. package/dist/lib/db-daemon-client.js +8 -6
  323. package/dist/lib/db-write-worker.js +4 -4
  324. package/dist/lib/db.js +5 -5
  325. package/dist/lib/device-registry.js +1 -1
  326. package/dist/lib/embedder.js +6 -4
  327. package/dist/lib/employee-templates.js +8 -8
  328. package/dist/lib/employees.js +5 -5
  329. package/dist/lib/exe-daemon-client.js +5 -3
  330. package/dist/lib/exe-daemon.js +333 -262
  331. package/dist/lib/hybrid-search.js +10 -10
  332. package/dist/lib/identity-templates.js +1 -1
  333. package/dist/lib/identity.js +17 -7
  334. package/dist/lib/license.js +2 -2
  335. package/dist/lib/messaging.js +27 -26
  336. package/dist/lib/post-tool-memory.js +9 -9
  337. package/dist/lib/registry-proxy.js +3 -1
  338. package/dist/lib/reminders.js +6 -6
  339. package/dist/lib/schedules.js +11 -11
  340. package/dist/lib/session-registry.js +11 -7
  341. package/dist/lib/session-wrappers.js +1 -1
  342. package/dist/lib/skill-learning.js +17 -15
  343. package/dist/lib/status-brief.js +2 -1
  344. package/dist/lib/store.js +9 -9
  345. package/dist/lib/task-router.js +6 -6
  346. package/dist/lib/tasks.js +28 -27
  347. package/dist/lib/tmux-routing.js +26 -25
  348. package/dist/lib/tmux-status.js +5 -1
  349. package/dist/lib/token-spend.js +6 -6
  350. package/dist/{license-gate-JVMB6OFD.js → license-gate-2QNMBAZU.js} +3 -3
  351. package/dist/{license-sync-5VYS2F2W.js → license-sync-FEDKH5MD.js} +2 -2
  352. package/dist/{mailbox-inbox-4MEUOL3J.js → mailbox-inbox-XE72D3AX.js} +2 -2
  353. package/dist/{mailbox-outbox-J6WIF3UY.js → mailbox-outbox-DNDDP2HW.js} +1 -1
  354. package/dist/mcp/register-tools.js +110 -106
  355. package/dist/mcp/server.js +113 -109
  356. package/dist/mcp/tools/complete-reminder.js +7 -7
  357. package/dist/mcp/tools/create-reminder.js +7 -7
  358. package/dist/mcp/tools/create-task.js +30 -29
  359. package/dist/mcp/tools/deactivate-behavior.js +18 -16
  360. package/dist/mcp/tools/list-reminders.js +7 -7
  361. package/dist/mcp/tools/list-tasks.js +30 -29
  362. package/dist/mcp/tools/send-message.js +33 -30
  363. package/dist/mcp/tools/update-task.js +29 -28
  364. package/dist/{mcp-child-registry-OTG4MWO7.js → mcp-child-registry-DVHYAHPW.js} +2 -2
  365. package/dist/{mcp-health-HNVSWKFA.js → mcp-health-B5EKRCZG.js} +2 -2
  366. package/dist/{mcp-http-config-DQWL7U2Z.js → mcp-http-config-ZJ7XHWT7.js} +10 -6
  367. package/dist/{mcp-session-identity-277GASTQ.js → mcp-session-identity-PEVM7VIP.js} +26 -25
  368. package/dist/{memory-cards-3S2ZQPR7.js → memory-cards-VN5DEWPD.js} +9 -9
  369. package/dist/{memory-graph-extractor-A6DFEFIN.js → memory-graph-extractor-TMEB6WLA.js} +11 -11
  370. package/dist/{memory-poisoning-defense-ZVP4H6DY.js → memory-poisoning-defense-DYHARQ2G.js} +5 -5
  371. package/dist/{memory-pressure-watchdog-6W5F6R7H.js → memory-pressure-watchdog-J6Q3SIBL.js} +27 -26
  372. package/dist/{memory-queue-client-ADSDP6OX.js → memory-queue-client-QC2OTMJB.js} +6 -4
  373. package/dist/{memory-reflection-BKB2YOE6.js → memory-reflection-ZYJUOSFX.js} +9 -9
  374. package/dist/{message-queue-client-XQN7QABL.js → message-queue-client-OEQCGSWC.js} +1 -25
  375. package/dist/{notification-ledger-CLGM7ODF.js → notification-ledger-TG6EFYBP.js} +29 -28
  376. package/dist/{notifications-MACUZPYP.js → notifications-LGYY22W5.js} +26 -25
  377. package/dist/{orchestration-events-N7LYMUGA.js → orchestration-events-JPHB6NPY.js} +6 -6
  378. package/dist/{orchestrator-4X24EWHV.js → orchestrator-IC4WGP6L.js} +28 -27
  379. package/dist/{org-brief-session-FZOFMO5U.js → org-brief-session-DEPHWCQR.js} +9 -9
  380. package/dist/{org-consent-policy-O5E6HXBL.js → org-consent-policy-T27AO5OJ.js} +2 -2
  381. package/dist/{org-join-POWUG25F.js → org-join-A3YXC5RB.js} +2 -2
  382. package/dist/{org-key-admin-E7EMDOZZ.js → org-key-admin-SQFHCVP2.js} +3 -3
  383. package/dist/{org-partner-runtime-FODONVTM.js → org-partner-runtime-L7L2WWGN.js} +10 -10
  384. package/dist/{org-row-visibility-VX4AVV5Q.js → org-row-visibility-M54Z6ZH3.js} +1 -1
  385. package/dist/{pipeline-router-6GGT2ZW3.js → pipeline-router-NKYAUR3Y.js} +6 -6
  386. package/dist/{plan-limits-FUN76LYY.js → plan-limits-ISRRGF23.js} +8 -8
  387. package/dist/{platform-procedures-7YSCLF4Z.js → platform-procedures-Z7ZGBJWN.js} +1 -1
  388. package/dist/{project-boot-3Q65LCIP.js → project-boot-BLYGVUJH.js} +4 -1
  389. package/dist/{project-name-LJVFMYTQ.js → project-name-WKSNNKXK.js} +6 -6
  390. package/dist/{projection-worker-4OANGP5K.js → projection-worker-RNYPE46G.js} +2 -2
  391. package/dist/{prospective-memory-KR3P4T6N.js → prospective-memory-GEO6E3UL.js} +5 -5
  392. package/dist/{push-notifications-NCZLH6DI.js → push-notifications-EY6BXZUY.js} +27 -26
  393. package/dist/{reproject-worktree-memories-PWYKPB2U.js → reproject-worktree-memories-DAA5GWMH.js} +28 -27
  394. package/dist/{reranker-6V3C2AO4.js → reranker-7OADQPMG.js} +1 -1
  395. package/dist/{retrieval-health-5D7O6VH6.js → retrieval-health-FCEDWN2P.js} +2 -2
  396. package/dist/{review-polling-QW3LJ4KN.js → review-polling-G52BR4MC.js} +27 -26
  397. package/dist/runtime/index.js +39 -38
  398. package/dist/{session-events-T45SSTMF.js → session-events-P6E2373E.js} +27 -26
  399. package/dist/{session-kill-telemetry-QSPVJGBF.js → session-kill-telemetry-OHNJMIVT.js} +27 -26
  400. package/dist/{session-mcp-config-SC5BLWZG.js → session-mcp-config-WFZAH6R5.js} +2 -1
  401. package/dist/{session-scope-KRWE54C4.js → session-scope-DKOHPQPJ.js} +26 -25
  402. package/dist/{setup-wizard-GP3TBTPF.js → setup-wizard-RNU3RFBE.js} +1 -1
  403. package/dist/{skill-refinement-C7JTMLJG.js → skill-refinement-AKJTHFXC.js} +6 -6
  404. package/dist/{stack-generate-manifest-MFMDWRUP.js → stack-generate-manifest-7WJZWSPK.js} +163 -15
  405. package/dist/{stack-promote-EKSCYY63.js → stack-promote-OP2URGFF.js} +4 -4
  406. package/dist/{stack-release-2GZAAFO4.js → stack-release-MY6U2QIO.js} +31 -8
  407. package/dist/{stack-update-J6JXSTAZ.js → stack-update-QSHSLUTZ.js} +3 -3
  408. package/dist/{steward-gate-BFCCMCSW.js → steward-gate-KMLS5ECC.js} +6 -6
  409. package/dist/{subagent-brief-injection-ED36PLYY.js → subagent-brief-injection-HCKZQZBF.js} +37 -36
  410. package/dist/{support-inbox-YW47SYJF.js → support-inbox-UBXU5RKV.js} +11 -11
  411. package/dist/{support-outbox-HFJWG52M.js → support-outbox-G2NG2U5K.js} +2 -2
  412. package/dist/{sweep-budget-KMPJ7O5Z.js → sweep-budget-YGLCNXZZ.js} +9 -3
  413. package/dist/{task-enforcement-CECTQX4U.js → task-enforcement-2GR7HU6V.js} +27 -26
  414. package/dist/{task-request-inbox-Q5T4N5K7.js → task-request-inbox-ANCVK2VG.js} +2 -2
  415. package/dist/{task-scope-ERVEUEYU.js → task-scope-QANJJXXB.js} +30 -29
  416. package/dist/{tasks-crud-ZRQNJXQ2.js → tasks-crud-45WOIMIM.js} +44 -25
  417. package/dist/{tasks-notify-MIZH4C2O.js → tasks-notify-ZJS4MA3S.js} +29 -26
  418. package/dist/{tasks-review-Z7J2P6DG.js → tasks-review-ZVPKY47Z.js} +26 -25
  419. package/dist/{telemetry-upload-LVQUQYFP.js → telemetry-upload-VY3UWAEL.js} +10 -10
  420. package/dist/{token-budget-BU4NOVZF.js → token-budget-XHX6XFEC.js} +6 -6
  421. package/dist/{tool-capability-index-7F42MOJT.js → tool-capability-index-6HLZU437.js} +1 -1
  422. package/dist/{tool-telemetry-O27EVMBR.js → tool-telemetry-GBDI4AXR.js} +1 -1
  423. package/dist/tui/App.js +36 -35
  424. package/dist/{tui-data-TPWWBIUQ.js → tui-data-IQFE3UW3.js} +30 -29
  425. package/dist/{typed-messages-RCMPEKJN.js → typed-messages-P2HLLA62.js} +1 -1
  426. package/dist/{update-support-F2F5537B.js → update-support-BDN5AK4R.js} +25 -22
  427. package/dist/{work-claims-B73X5NE7.js → work-claims-PDQNLE5K.js} +7 -7
  428. package/dist/{work-state-heartbeat-P4YX6E2R.js → work-state-heartbeat-CH6BLQKV.js} +1 -1
  429. package/dist/{worker-gate-BEEIIVWA.js → worker-gate-NUUSQMBT.js} +1 -3
  430. package/dist/{workflow-engine-5X46PFCW.js → workflow-engine-RZ7QEI3Z.js} +2 -2
  431. package/dist/{worktree-W47CIMJ6.js → worktree-Q25PZST6.js} +11 -7
  432. package/dist/worktree-ownership-guard-4LKMW6PW.js +421 -0
  433. package/dist/{worktree-sweep-BNBD4RFX.js → worktree-sweep-EV5YQ2OB.js} +8 -8
  434. package/package.json +15 -3
  435. package/release-notes.json +5 -5
  436. package/src/commands/exe.md +16 -16
  437. package/stack.release.json +9 -8
  438. package/dist/behavior-injection-M6UYZCMW.js +0 -63
  439. package/dist/chunk-BJ7AVSY6.js +0 -50
  440. package/dist/daemon-restart-report-EIVD6WDJ.js +0 -10
  441. package/dist/worktree-ownership-guard-OUWJROW2.js +0 -88
  442. /package/dist/{chunk-GQOEWNVM.js → chunk-4EG4DT4F.js} +0 -0
  443. /package/dist/{chunk-AISULNGL.js → chunk-BRAIWGMF.js} +0 -0
  444. /package/dist/{chunk-NRG7KZIP.js → chunk-HQEAZDAC.js} +0 -0
  445. /package/dist/{chunk-VZAFWPAY.js → chunk-IK4344V5.js} +0 -0
  446. /package/dist/{chunk-GM7TLYOK.js → chunk-K3VDF6II.js} +0 -0
  447. /package/dist/{chunk-2AJGV5UL.js → chunk-KM7DAG5J.js} +0 -0
  448. /package/dist/{chunk-YO4BO2CL.js → chunk-QIEYJ4KZ.js} +0 -0
  449. /package/dist/{chunk-WSQASFLP.js → chunk-VCTK5HRA.js} +0 -0
  450. /package/dist/{chunk-KQ6RJWRW.js → chunk-VPT6VMBG.js} +0 -0
  451. /package/dist/{chunk-6WIFPD2P.js → chunk-YZ4AEMR7.js} +0 -0
  452. /package/dist/{core-memory-7I7RE2SJ.js → core-memory-UIZKCY4L.js} +0 -0
  453. /package/dist/{memory-isolation-2TUZ7Z4K.js → memory-isolation-3GJ6WLYX.js} +0 -0
  454. /package/dist/{oauth-server-AYM37SQ4.js → oauth-server-ZRHXIRXQ.js} +0 -0
  455. /package/dist/{wiki-acl-IBQLLBTS.js → wiki-acl-MFOYK5F4.js} +0 -0
@@ -13,13 +13,133 @@ import {
13
13
 
14
14
  // src/bin/verify-stack.ts
15
15
  import { execSync } from "child_process";
16
+ import { createHash } from "crypto";
16
17
  import { readFileSync, existsSync } from "fs";
17
18
  import http from "http";
18
19
  import path from "path";
20
+
21
+ // src/lib/sso-session-contract.ts
22
+ var APEX_SSO_COOKIES = ["exe_sess", "exe_sess_refresh", "exe_access_token"];
23
+ var SSO_PRESENCE_SENTINEL = "exe_access_token";
24
+ var SSO_PRESENCE_SENTINEL_VALUE = "1";
25
+ var SSO_SESSION_COOKIE = "exe_sess";
26
+ var MAX_SSO_HANDOFF_HOPS = 2;
27
+ var SSO_SESSION_CONTRACT_CHECK_NAME = "SSO session auth admission contract";
28
+ var FORGED_SESSION_VALUE = "eyJhbGciOiJIUzI1NiJ9.forged-payload-not-issued-by-gotrue.forged-signature";
29
+ function gatingLayerOf(probes) {
30
+ return probes.anonymous.finalHost === probes.authHost ? "edge-gated" : "client-gated";
31
+ }
32
+ function refusedAtEdge(probe, authHost) {
33
+ return probe.finalHost === authHost;
34
+ }
35
+ function evaluateProduct(probes) {
36
+ const layer = gatingLayerOf(probes);
37
+ const findings = [];
38
+ const at = (p) => `landed on ${p.finalHost} (status ${p.status}, ${p.hops} hop(s))`;
39
+ if (layer === "client-gated") {
40
+ findings.push({
41
+ scenario: "anonymous",
42
+ severity: "review",
43
+ detail: `${probes.host} is not gated at the edge \u2014 an anonymous visitor is served by the product itself (${at(probes.anonymous)}), so its admission decision runs in the browser and is invisible over plain HTTP. This check will NOT roll a deploy back on that: check 9 (served-HTML cookie contract) and the Playwright monitor both see what this cannot. If this product was supposed to be behind the edge gate, that is the finding.`
44
+ });
45
+ } else {
46
+ findings.push({
47
+ scenario: "anonymous",
48
+ severity: "ok",
49
+ detail: `anonymous visitor refused at the edge -> ${probes.authHost}`
50
+ });
51
+ const forgeries = [
52
+ {
53
+ scenario: "forged-session",
54
+ probe: probes.forgedSession,
55
+ detail: `a FORGED \`${SSO_SESSION_COOKIE}\` was ADMITTED to ${probes.host} while an anonymous visitor with no cookies at all was correctly refused \u2014 ${at(probes.forgedSession)}. The edge is trusting the cookie's mere presence instead of validating it against GoTrue. This is bug 462d3273's exact shape: anyone can mint this cookie.`
56
+ },
57
+ {
58
+ scenario: "sentinel-only",
59
+ probe: probes.sentinelOnly,
60
+ detail: `a forged \`${SSO_PRESENCE_SENTINEL}=${SSO_PRESENCE_SENTINEL_VALUE}\` sentinel with NO real \`${SSO_SESSION_COOKIE}\` was ADMITTED to ${probes.host} while an anonymous visitor was correctly refused \u2014 ${at(probes.sentinelOnly)}. The sentinel is deliberately JS-readable and therefore trivially forgeable; its presence is not proof of anything. This is bug 4a6650f5's exact shape, and it is the case most likely to regress unnoticed because a sentinel-only jar looks like a normal logged-in one at a glance.`
61
+ }
62
+ ];
63
+ for (const forgery of forgeries) {
64
+ findings.push(
65
+ refusedAtEdge(forgery.probe, probes.authHost) ? { scenario: forgery.scenario, severity: "ok", detail: `${forgery.scenario} refused at the edge` } : { scenario: forgery.scenario, severity: "violation", detail: forgery.detail }
66
+ );
67
+ }
68
+ }
69
+ const real = probes.realSession;
70
+ if (real) {
71
+ if (real.hops > MAX_SSO_HANDOFF_HOPS) {
72
+ findings.push({
73
+ scenario: "real-session",
74
+ severity: "violation",
75
+ detail: `a real apex session took ${real.hops} redirect(s) reaching ${probes.host}, over the contract's ${MAX_SSO_HANDOFF_HOPS} \u2014 ${at(real)}. An unbounded hop count here is the CRM livelock (bug 83ba9546 regression): the edge and the app are disagreeing about the handoff and bouncing the user between them.`
76
+ });
77
+ } else if (real.finalHost !== probes.host) {
78
+ findings.push({
79
+ scenario: "real-session",
80
+ severity: "violation",
81
+ detail: `a REAL apex session was sent away from ${probes.host} \u2014 ${at(real)}. The app never accepted the shared session at all.`
82
+ });
83
+ } else if (real.sawPasswordField) {
84
+ findings.push({
85
+ scenario: "real-session",
86
+ severity: "violation",
87
+ detail: `${probes.host} served a login form to a REAL apex session \u2014 ${at(real)}. The shared session was not accepted (the 2026-08-30 ERP/Wiki failure mode).`
88
+ });
89
+ } else if (real.bodyFingerprint === probes.anonymous.bodyFingerprint) {
90
+ findings.push({
91
+ scenario: "real-session",
92
+ severity: "violation",
93
+ detail: `${probes.host} served a REAL apex session the byte-identical response it serves an anonymous visitor \u2014 ${at(real)}. The session is being ignored, not honored; for a client-gated product this is the only shape of the 2026-08-30 failure visible without a browser.`
94
+ });
95
+ } else {
96
+ findings.push({
97
+ scenario: "real-session",
98
+ severity: "ok",
99
+ detail: `real apex session admitted in ${real.hops} hop(s)`
100
+ });
101
+ }
102
+ }
103
+ return findings;
104
+ }
105
+ function summarizeProducts(products) {
106
+ const violations = [];
107
+ const reviews = [];
108
+ let oks = 0;
109
+ for (const product of products) {
110
+ for (const finding of evaluateProduct(product)) {
111
+ const label = `${product.app}/${finding.scenario}`;
112
+ if (finding.severity === "violation") violations.push(`${label}: ${finding.detail}`);
113
+ else if (finding.severity === "review") reviews.push(`${label}: ${finding.detail}`);
114
+ else oks += 1;
115
+ }
116
+ }
117
+ return { violations, reviews, oks };
118
+ }
119
+ function htmlHasPasswordField(html) {
120
+ return /<input[^>]*type\s*=\s*["']?password["']?/i.test(html);
121
+ }
122
+ function cookieHeader(jar) {
123
+ return Object.entries(jar).map(([name, value]) => `${name}=${value}`).join("; ");
124
+ }
125
+ function parseApexCookies(setCookieLines) {
126
+ const jar = {};
127
+ for (const line of setCookieLines) {
128
+ const pair = line.split(";")[0] ?? "";
129
+ const eq = pair.indexOf("=");
130
+ if (eq <= 0) continue;
131
+ const name = pair.slice(0, eq).trim();
132
+ const value = pair.slice(eq + 1).trim();
133
+ if (APEX_SSO_COOKIES.includes(name)) jar[name] = value;
134
+ }
135
+ return jar;
136
+ }
137
+
138
+ // src/bin/verify-stack.ts
19
139
  var DEFAULT_COMPOSE = "/opt/exe-stack/docker-compose.yml";
20
140
  var DEFAULT_ENV = "/opt/exe-stack/.env";
21
141
  var CHECK_TIMEOUT_MS = 5e3;
22
- var TOTAL_TIMEOUT_MS = 6e4;
142
+ var TOTAL_TIMEOUT_MS = 12e4;
23
143
  var SERVICE_URLS = {
24
144
  "exe-os": "http://127.0.0.1:8765/health",
25
145
  "exe-gateway": "http://127.0.0.1:3100/health",
@@ -398,6 +518,189 @@ async function checkSsoCookieContract(deployed, urlOverrides) {
398
518
  message: `${Object.keys(urls).length} product(s) free of retired SSO cookie names`
399
519
  };
400
520
  }
521
+ var MAX_PROBE_HOPS = 6;
522
+ var SSO_ADMISSION_APPS = {
523
+ "exe-crm": "crm",
524
+ "exe-erp": "erp",
525
+ "exe-wiki": "wiki"
526
+ };
527
+ async function probeAdmission(url, jar, timeoutMs) {
528
+ let current = url;
529
+ let hops = 0;
530
+ const headers = {
531
+ // Some edges vary their gate on Accept; ask for a document like a browser does.
532
+ accept: "text/html,application/xhtml+xml",
533
+ "user-agent": "exe-os-verify-stack/sso-session-contract"
534
+ };
535
+ const cookie = cookieHeader(jar);
536
+ if (cookie) headers.cookie = cookie;
537
+ for (; ; ) {
538
+ const res = await fetch(current, {
539
+ headers,
540
+ redirect: "manual",
541
+ signal: AbortSignal.timeout(timeoutMs)
542
+ });
543
+ if (res.status >= 300 && res.status < 400) {
544
+ const location = res.headers.get("location");
545
+ if (location) {
546
+ hops += 1;
547
+ current = new URL(location, current).toString();
548
+ if (hops < MAX_PROBE_HOPS) continue;
549
+ }
550
+ return {
551
+ finalHost: new URL(current).host,
552
+ hops,
553
+ status: res.status,
554
+ sawPasswordField: false,
555
+ bodyFingerprint: `redirect:${res.status}:${location ?? ""}`
556
+ };
557
+ }
558
+ let body = "";
559
+ try {
560
+ body = await res.text();
561
+ } catch {
562
+ }
563
+ return {
564
+ finalHost: new URL(current).host,
565
+ hops,
566
+ status: res.status,
567
+ sawPasswordField: htmlHasPasswordField(body),
568
+ bodyFingerprint: createHash("sha256").update(body).digest("hex")
569
+ };
570
+ }
571
+ }
572
+ async function loginForApexCookies(authUrl, email, password, timeoutMs) {
573
+ let res;
574
+ try {
575
+ res = await fetch(`${authUrl}/auth/login`, {
576
+ method: "POST",
577
+ headers: { "content-type": "application/json" },
578
+ body: JSON.stringify({ email, password }),
579
+ redirect: "manual",
580
+ signal: AbortSignal.timeout(timeoutMs)
581
+ });
582
+ } catch (err) {
583
+ return { error: `login request failed: ${err instanceof Error ? err.message : String(err)}` };
584
+ }
585
+ if (res.status >= 400) {
586
+ return {
587
+ error: `POST ${authUrl}/auth/login returned ${res.status} (account locked, disabled, or password rotated?)`
588
+ };
589
+ }
590
+ const setCookies = typeof res.headers.getSetCookie === "function" ? res.headers.getSetCookie() : [];
591
+ const jar = parseApexCookies(setCookies);
592
+ const missing = APEX_SSO_COOKIES.filter((name) => !(name in jar));
593
+ if (missing.length > 0) {
594
+ return { error: `login succeeded but did not set: ${missing.join(", ")}` };
595
+ }
596
+ if (jar[SSO_PRESENCE_SENTINEL] !== SSO_PRESENCE_SENTINEL_VALUE) {
597
+ return {
598
+ error: `\`${SSO_PRESENCE_SENTINEL}\` came back as "${jar[SSO_PRESENCE_SENTINEL]}" rather than the literal presence sentinel "${SSO_PRESENCE_SENTINEL_VALUE}" \u2014 if it now carries a real value, every consumer that refuses to trust it and every consumer that wrongly trusts it both changed behaviour silently`
599
+ };
600
+ }
601
+ return { jar };
602
+ }
603
+ async function checkSsoSessionContract(env, deployed, overrides) {
604
+ const check = SSO_SESSION_CONTRACT_CHECK_NAME;
605
+ const domain = process.env.SSO_DOMAIN ?? env.SSO_DOMAIN ?? env.DOMAIN;
606
+ if (!overrides?.targets && !domain) {
607
+ return {
608
+ check,
609
+ status: "skip",
610
+ message: "No DOMAIN in the stack env \u2014 this check probes the PUBLIC hostnames the edge gate actually serves, and cannot infer them. Set DOMAIN (or SSO_DOMAIN) to enable it."
611
+ };
612
+ }
613
+ const targets = overrides?.targets ?? Object.entries(SSO_ADMISSION_APPS).filter(([service]) => deployed.size === 0 ? true : deployed.has(service)).map(([service, subdomain]) => ({
614
+ service,
615
+ host: `${subdomain}.${domain}`,
616
+ baseUrl: `https://${subdomain}.${domain}/`
617
+ }));
618
+ if (targets.length === 0) {
619
+ return { check, status: "skip", message: "No SSO-gated products deployed in this selection" };
620
+ }
621
+ const authHost = overrides?.authHost ?? `auth.${domain}`;
622
+ const authUrl = overrides?.authUrl ?? `https://auth.${domain}`;
623
+ const jars = [
624
+ { scenario: "anonymous", jar: {} },
625
+ { scenario: "forged-session", jar: { [SSO_SESSION_COOKIE]: FORGED_SESSION_VALUE } },
626
+ { scenario: "sentinel-only", jar: { [SSO_PRESENCE_SENTINEL]: SSO_PRESENCE_SENTINEL_VALUE } }
627
+ ];
628
+ const email = process.env.SSO_E2E_EMAIL ?? env.SSO_E2E_EMAIL ?? env.GOTRUE_TEST_EMAIL;
629
+ const password = process.env.SSO_E2E_PASSWORD ?? env.SSO_E2E_PASSWORD ?? env.GOTRUE_TEST_PASSWORD;
630
+ let happyPathSkip = null;
631
+ if (email && password) {
632
+ const login = await loginForApexCookies(authUrl, email, password, CHECK_TIMEOUT_MS * 2);
633
+ if ("error" in login) {
634
+ happyPathSkip = `real-session scenario NOT run \u2014 ${login.error}`;
635
+ } else {
636
+ jars.push({ scenario: "real-session", jar: login.jar });
637
+ }
638
+ } else {
639
+ happyPathSkip = "real-session scenario NOT run \u2014 no SSO_E2E_EMAIL/SSO_E2E_PASSWORD (or GOTRUE_TEST_*) configured. The three deny-side scenarios need no credential, still ran, and still gate this deploy.";
640
+ }
641
+ const pairs = targets.flatMap((target) => jars.map(({ scenario, jar }) => ({ target, scenario, jar })));
642
+ const settled = await Promise.all(
643
+ pairs.map(async (pair) => {
644
+ try {
645
+ return { pair, probe: await probeAdmission(pair.target.baseUrl, pair.jar, CHECK_TIMEOUT_MS * 2) };
646
+ } catch (err) {
647
+ return { pair, error: err instanceof Error ? err.message : String(err) };
648
+ }
649
+ })
650
+ );
651
+ const byProduct = /* @__PURE__ */ new Map();
652
+ const unreachable = [];
653
+ for (const entry of settled) {
654
+ if ("probe" in entry && entry.probe) {
655
+ const bucket = byProduct.get(entry.pair.target.service) ?? {};
656
+ bucket[entry.pair.scenario] = entry.probe;
657
+ byProduct.set(entry.pair.target.service, bucket);
658
+ } else {
659
+ unreachable.push(
660
+ `${entry.pair.target.service} (${entry.pair.target.host}/${entry.pair.scenario}): ${"error" in entry ? entry.error : "no result"}`
661
+ );
662
+ }
663
+ }
664
+ const products = [];
665
+ for (const target of targets) {
666
+ const bucket = byProduct.get(target.service);
667
+ if (!bucket?.anonymous || !bucket["forged-session"] || !bucket["sentinel-only"]) {
668
+ unreachable.push(
669
+ `${target.service} (${target.host}): incomplete probe set \u2014 no baseline to judge against`
670
+ );
671
+ continue;
672
+ }
673
+ products.push({
674
+ app: target.service,
675
+ host: target.host,
676
+ authHost,
677
+ anonymous: bucket.anonymous,
678
+ forgedSession: bucket["forged-session"],
679
+ sentinelOnly: bucket["sentinel-only"],
680
+ realSession: bucket["real-session"]
681
+ });
682
+ }
683
+ const { violations, reviews, oks } = summarizeProducts(products);
684
+ if (violations.length > 0) {
685
+ return {
686
+ check,
687
+ status: "fail",
688
+ message: `${violations.length} SSO admission contract violation(s) on the DEPLOYED stack \u2014 ${violations.join(" | ")}`
689
+ };
690
+ }
691
+ const notes = [];
692
+ if (reviews.length > 0) notes.push(`needs review: ${reviews.join(" | ")}`);
693
+ if (unreachable.length > 0) notes.push(`unreachable: ${unreachable.join("; ")}`);
694
+ if (happyPathSkip) notes.push(happyPathSkip);
695
+ if (notes.length > 0) {
696
+ return { check, status: "warn", message: `${oks} admission decision(s) correct. ${notes.join(" | ")}` };
697
+ }
698
+ return {
699
+ check,
700
+ status: "pass",
701
+ message: `${oks} admission decision(s) correct across ${products.length} product(s): both forgery shapes refused wherever the edge refuses an anonymous visitor, and a real apex session honored within ${MAX_SSO_HANDOFF_HOPS} hop(s)`
702
+ };
703
+ }
401
704
  async function checkLiveArtifactMatchesManifest(composeFile, manifestPath) {
402
705
  const check = LIVE_ARTIFACT_CHECK_NAME;
403
706
  const candidates = manifestPath ? [manifestPath] : ["/opt/exe-stack/stack-manifest.json", "deploy/stack-manifests/v0.9.json"];
@@ -535,6 +838,8 @@ async function runVerifyStack(options) {
535
838
  addResult(await checkSsoCookieContract(deployed));
536
839
  if (Date.now() > deadline) return summarize(results);
537
840
  addResult(await checkLiveArtifactMatchesManifest(composeFile));
841
+ if (Date.now() > deadline) return summarize(results);
842
+ addResult(await checkSsoSessionContract(env, deployed));
538
843
  return summarize(results);
539
844
  }
540
845
  function summarize(results) {
@@ -562,7 +867,7 @@ function printUsage() {
562
867
  console.log(`
563
868
  Usage: exe-os verify-stack [options]
564
869
 
565
- Post-deploy verification \u2014 10 runtime checks after stack-update.
870
+ Post-deploy verification \u2014 11 runtime checks after stack-update.
566
871
 
567
872
  Options:
568
873
  --compose <path> Path to docker-compose.yml (default: ${DEFAULT_COMPOSE})
@@ -580,6 +885,8 @@ Checks:
580
885
  8. Cross-service auth (JWT \u2192 wiki + CRM)
581
886
  9. SSO auth cookie contract (no retired cookie name in served HTML)
582
887
  10. Live artifact matches the digest pinned by the signed manifest
888
+ 11. SSO session auth admission contract \u2014 presents real and forged cookie jars
889
+ to the live edge and asserts who gets admitted (fatal: rolls back)
583
890
  `);
584
891
  }
585
892
  if (isMainModule(import.meta.url) && process.argv[1]?.includes("verify-stack")) {
@@ -607,6 +914,7 @@ export {
607
914
  LIVE_ARTIFACT_CHECK_NAME,
608
915
  parseComposeServiceNames,
609
916
  checkSsoCookieContract,
917
+ checkSsoSessionContract,
610
918
  checkLiveArtifactMatchesManifest,
611
919
  runVerifyStack
612
920
  };
@@ -1,11 +1,11 @@
1
+ import {
2
+ ingest
3
+ } from "./chunk-5UBWBXLF.js";
1
4
  import {
2
5
  listWorkflowDefinitions,
3
6
  runWorkflow,
4
7
  startWorkflow
5
- } from "./chunk-YMP2QSOP.js";
6
- import {
7
- ingest
8
- } from "./chunk-YSLGFPWX.js";
8
+ } from "./chunk-QN56VQ6Z.js";
9
9
  import {
10
10
  initCRMBridge
11
11
  } from "./chunk-ML4S5SHZ.js";
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  getClient
3
- } from "./chunk-TAMDAOCU.js";
3
+ } from "./chunk-66CGXQUA.js";
4
4
  import {
5
5
  loadConfig
6
6
  } from "./chunk-ZIG7VPJV.js";
@@ -1,17 +1,18 @@
1
1
  import {
2
2
  updateTask
3
- } from "./chunk-ZCERWHY2.js";
3
+ } from "./chunk-4M6RXJEY.js";
4
4
  import {
5
5
  TASK_ALREADY_CLAIMED_PREFIX,
6
6
  TASK_CLAIM_NOT_HELD_PREFIX,
7
+ TASK_PR_TRACEABILITY_REQUIRED_PREFIX,
7
8
  TASK_SIDECHAIN_WRITE_BLOCKED_PREFIX
8
- } from "./chunk-AKLQSC6W.js";
9
+ } from "./chunk-KI7O64XV.js";
9
10
  import {
10
11
  getAgentContext
11
12
  } from "./chunk-GJV3WDWM.js";
12
13
  import {
13
14
  isCoordinatorName
14
- } from "./chunk-TAMDAOCU.js";
15
+ } from "./chunk-66CGXQUA.js";
15
16
 
16
17
  // src/mcp/tools/update-task.ts
17
18
  import { z } from "zod";
@@ -48,7 +49,9 @@ function registerUpdateTask(server) {
48
49
  commits: z.array(z.string()).optional().describe("Commit hashes produced"),
49
50
  tests_status: z.enum(["pass", "fail", "skip", "none"]).optional().describe("Test execution status"),
50
51
  build_status: z.enum(["pass", "fail", "skip"]).optional().describe("Build status"),
51
- pr_number: z.number().optional().describe("PR number if created"),
52
+ pr_number: z.number().int().positive().optional().describe("PR number if created. Required (along with pr_url, or use pr_no_reason instead) when completing a task that reports commits/files_changed \u2014 all agents share one GitHub account, so this task record is the only reliable way to trace a merged PR back to the agent/task/session that produced it."),
53
+ pr_url: z.string().optional().describe("Full PR URL, e.g. https://github.com/org/repo/pull/123. More traceable than pr_number alone \u2014 derives pr_number automatically. Prefer this over pr_number."),
54
+ pr_no_reason: z.string().optional().describe('Explicit reason this completion has no PR (e.g. "direct to main", "non-code task"). Required instead of pr_number/pr_url when completing a task with commits/files_changed but no PR was opened.'),
52
55
  open_questions: z.array(z.string()).optional().describe("Open questions for reviewer"),
53
56
  assertions: z.string().optional().describe(
54
57
  'JSON array of assertions with confidence scores. Use when starting work (in_progress). Format: [{"type":"diagnosis|scope|estimate|approach|build|judgment","claim":"...","confidence":0.8,"basis":"..."}]'
@@ -66,13 +69,13 @@ function registerUpdateTask(server) {
66
69
  estimate_confidence: z.number().min(0).max(1).optional().describe("Confidence in time estimate (0.0-1.0). Provide alongside estimated_minutes.")
67
70
  }
68
71
  },
69
- async ({ task_id, status: rawStatus, result, files_changed, decisions, commits, tests_status, build_status, pr_number, open_questions, assertions, assertions_resolved, receipts, estimated_minutes, estimate_confidence }) => {
72
+ async ({ task_id, status: rawStatus, result, files_changed, decisions, commits, tests_status, build_status, pr_number, pr_url, pr_no_reason, open_questions, assertions, assertions_resolved, receipts, estimated_minutes, estimate_confidence }) => {
70
73
  const status = rawStatus;
71
74
  let callerAgentId;
72
75
  let callerSession;
73
76
  let callerIsSidechain = false;
74
77
  try {
75
- const { getActiveAgent: getAgent } = await import("./active-agent-ONPPEWQV.js");
78
+ const { getActiveAgent: getAgent } = await import("./active-agent-BOBBUJ74.js");
76
79
  const active = getAgent();
77
80
  callerAgentId = active.agentId;
78
81
  callerSession = resolveCallerSessionForUpdate();
@@ -103,6 +106,8 @@ function registerUpdateTask(server) {
103
106
  testsStatus: tests_status,
104
107
  buildStatus: build_status,
105
108
  prNumber: pr_number,
109
+ prUrl: pr_url,
110
+ prNoReason: pr_no_reason,
106
111
  openQuestions: open_questions,
107
112
  assertions,
108
113
  assertionsResolved: assertions_resolved,
@@ -141,12 +146,29 @@ function registerUpdateTask(server) {
141
146
  isError: true
142
147
  };
143
148
  }
149
+ if (msg.startsWith(TASK_PR_TRACEABILITY_REQUIRED_PREFIX)) {
150
+ return {
151
+ content: [{
152
+ type: "text",
153
+ text: `BLOCKED: this completion reports commits/files_changed but no PR traceability. All agents share one GitHub account, so git blame cannot tell which agent/task produced a merged PR \u2014 this task record has to. Retry update_task with pr_url (preferred) or pr_number if you opened a PR, or pr_no_reason (e.g. "direct to main", "non-code task") if there genuinely isn't one.
154
+
155
+ Detail: ${msg}`
156
+ }],
157
+ isError: true
158
+ };
159
+ }
144
160
  throw err;
145
161
  }
146
162
  let text = `Task "${task.title}" marked ${task.status}.
147
163
  File: ${task.taskFile}`;
164
+ if (task.prUrl) text += `
165
+ PR: ${task.prUrl}`;
166
+ else if (task.prNumber) text += `
167
+ PR: #${task.prNumber}`;
168
+ else if (task.prNoReason) text += `
169
+ PR: none (${task.prNoReason})`;
148
170
  const isTerminal = status === "done" || status === "needs_review" || status === "closed";
149
- if (isTerminal && task.reviewer) {
171
+ if (isTerminal && task.executionMode === "durable_tmux" && task.reviewer) {
150
172
  try {
151
173
  const { notifyCoordinatorTaskCompletion } = await import("./lib/tmux-routing.js");
152
174
  const { isCoordinatorName: isCoordinatorName2 } = await import("./lib/employees.js");
@@ -1,7 +1,7 @@
1
1
  import {
2
2
  executeAction,
3
3
  substituteTemplate
4
- } from "./chunk-GM7TLYOK.js";
4
+ } from "./chunk-K3VDF6II.js";
5
5
 
6
6
  // src/automation/workflow-engine.ts
7
7
  import { randomUUID } from "crypto";
@@ -3,12 +3,12 @@ import {
3
3
  getClient,
4
4
  isInitialized,
5
5
  loadEmployees
6
- } from "./chunk-TAMDAOCU.js";
6
+ } from "./chunk-66CGXQUA.js";
7
7
  import {
8
8
  checkLicense,
9
9
  isFeatureAllowed,
10
10
  isPersonalFreeGrandfathered
11
- } from "./chunk-L6RXG36J.js";
11
+ } from "./chunk-Y2HD2YB7.js";
12
12
  import {
13
13
  PLAN_LIMITS
14
14
  } from "./chunk-A7XLR3K7.js";
@@ -6,10 +6,10 @@ import {
6
6
  connectEmbedDaemon,
7
7
  isClientConnected,
8
8
  sendDaemonRequest
9
- } from "./chunk-NUK7EEN5.js";
9
+ } from "./chunk-ZKJ5S23O.js";
10
10
  import {
11
11
  directWriterAllowed
12
- } from "./chunk-V3W3SATA.js";
12
+ } from "./chunk-CL4J4757.js";
13
13
 
14
14
  // src/lib/db-daemon-client.ts
15
15
  function normalizeStatement(stmt) {
@@ -1,10 +1,10 @@
1
1
  import {
2
2
  registerScopedQueryChokepoint,
3
3
  scopedQueryChokepointStatus
4
- } from "./chunk-IN6CAM4F.js";
4
+ } from "./chunk-EHAN752X.js";
5
5
  import {
6
6
  getClient
7
- } from "./chunk-TAMDAOCU.js";
7
+ } from "./chunk-66CGXQUA.js";
8
8
 
9
9
  // src/lib/org-scoped-rows.ts
10
10
  var SCOPED_QUERY_MAX_LIMIT = 200;
@@ -34,6 +34,8 @@ var NO_DB_INTEGRITY_EVENTS = Object.freeze({
34
34
  unresolvedUnverifiedBackups: 0,
35
35
  lastUnresolvedUnverified: null,
36
36
  failedBackups: 0,
37
+ lowDiskSkips: 0,
38
+ lastLowDiskSkip: null,
37
39
  lastVerifiedBackup: null,
38
40
  lastProvenBackupOnDisk: null,
39
41
  provenBackupsAllDeleted: false
@@ -99,6 +101,13 @@ function getDbIntegrityHealth() {
99
101
  break;
100
102
  }
101
103
  }
104
+ let lastLowDiskSkip = null;
105
+ for (let i = events.length - 1; i >= 0; i--) {
106
+ if (events[i].kind === "backup-skipped-low-disk") {
107
+ lastLowDiskSkip = events[i];
108
+ break;
109
+ }
110
+ }
102
111
  const unresolved = selectUnresolvedUnverified(events);
103
112
  const lastProvenBackupOnDisk = selectLastProvenOnDisk(events);
104
113
  return {
@@ -112,6 +121,8 @@ function getDbIntegrityHealth() {
112
121
  unresolvedUnverifiedBackups: unresolved.length,
113
122
  lastUnresolvedUnverified: unresolved.length > 0 ? unresolved[unresolved.length - 1] : null,
114
123
  failedBackups: countOf("backup-failed"),
124
+ lowDiskSkips: countOf("backup-skipped-low-disk"),
125
+ lastLowDiskSkip,
115
126
  lastVerifiedBackup,
116
127
  lastProvenBackupOnDisk,
117
128
  provenBackupsAllDeleted: lastVerifiedBackup !== null && lastProvenBackupOnDisk === null
@@ -3,7 +3,7 @@ import {
3
3
  } from "./chunk-5MOYSU5A.js";
4
4
  import {
5
5
  redactSecrets
6
- } from "./chunk-4QCFFW2H.js";
6
+ } from "./chunk-5QCIWWFA.js";
7
7
 
8
8
  // src/lib/memory-write-governor.ts
9
9
  import { createHash } from "crypto";
@@ -1,12 +1,12 @@
1
1
  import {
2
2
  sessionScopeFilter
3
- } from "./chunk-AKLQSC6W.js";
3
+ } from "./chunk-KI7O64XV.js";
4
4
  import {
5
5
  leaseExpiryIso
6
6
  } from "./chunk-E23LNUWJ.js";
7
7
  import {
8
8
  getProjectName
9
- } from "./chunk-JTVIANUB.js";
9
+ } from "./chunk-AEUGIJDO.js";
10
10
 
11
11
  // src/lib/subagent-observability.ts
12
12
  var MAX_RESULT_DIGEST_CHARS = 200;