elanous 0.2.24 → 0.2.27

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 (601) hide show
  1. package/apps/pwa/out/404/index.html +1 -1
  2. package/apps/pwa/out/404.html +1 -1
  3. package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/1027.a0f04663d24c2779.js +1 -0
  5. package/apps/pwa/out/_next/static/chunks/1038.676007ae505822e7.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1113.a37eadf7f740d955.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/112-fa7c526c20ce1405.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1144.5fa1fa1d48dbcd12.js +36 -0
  9. package/apps/pwa/out/_next/static/chunks/1146.80d15ea7c6e6ee95.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1157.f08bf2b70915e176.js +148 -0
  11. package/apps/pwa/out/_next/static/chunks/119b405e.8fdd0e44d1ff37aa.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1296.04560d98e73fbf51.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/1314-f604ba013ec535b0.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/1454-a9c338f5bb556f42.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1464.f3209af0d8ae4ff2.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{8532.a86e99acf9b761cb.js → 1516.83dd2c1b86b4e507.js} +2 -2
  17. package/apps/pwa/out/_next/static/chunks/{89849432.9eaa2f4c9c010965.js → 16e57f67.3ea19e893461e611.js} +3 -3
  18. package/apps/pwa/out/_next/static/chunks/1729-d73dd25e564679d4.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/{1505.5826671109111e75.js → 1743.563d3168e95825ef.js} +2 -2
  20. package/apps/pwa/out/_next/static/chunks/1843.5924c24295243261.js +27 -0
  21. package/apps/pwa/out/_next/static/chunks/1987.e28149724b92918b.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2066-5ca18ffa5a4be68b.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/2240.d10a66695155fd93.js +1 -0
  24. package/apps/pwa/out/_next/static/chunks/2391.e2cbc98d4abbb41a.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2528.3868070ef1be69f9.js +24 -0
  26. package/apps/pwa/out/_next/static/chunks/2566-734cb83bbd405886.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/2697.76ca2ac3efef6f3b.js +1 -0
  28. package/apps/pwa/out/_next/static/chunks/275.0e6bad414729bfa0.js +32 -0
  29. package/apps/pwa/out/_next/static/chunks/2803-33bdae771855a8d1.js +1 -0
  30. package/apps/pwa/out/_next/static/chunks/2846.d6a433b8663819a5.js +309 -0
  31. package/apps/pwa/out/_next/static/chunks/3143.257997a5f1ed79df.js +34 -0
  32. package/apps/pwa/out/_next/static/chunks/{5967-c0a80f8ffe5d4050.js → 3259-86f3be56e43eaf6a.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/3280-e177c33bfbdcfb0a.js +1 -0
  34. package/apps/pwa/out/_next/static/chunks/3294-2b6a6d45a46a6c1c.js +1 -0
  35. package/apps/pwa/out/_next/static/chunks/3309.364573ceedbdfd5f.js +1 -0
  36. package/apps/pwa/out/_next/static/chunks/3522.758840fc5e7fe630.js +287 -0
  37. package/apps/pwa/out/_next/static/chunks/3525-a7c989c1a661e880.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3694.b1a66387756458c0.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/370.124f9e678a76fc01.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3797-9643105335e660fe.js +1 -0
  41. package/apps/pwa/out/_next/static/chunks/{5578.ac963634373b28c6.js → 4084.15ecaf4240bd9e77.js} +2 -2
  42. package/apps/pwa/out/_next/static/chunks/4089-b3382b8843114eee.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/{8438.ee7f0df3b3f6fcb4.js → 4204.a409ab6250c0f6a8.js} +1 -1
  44. package/apps/pwa/out/_next/static/chunks/4293.928a8d573c16aab7.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/4402.f9238a3b18a7bd43.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4490-9b090b0f9427f902.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4548.13502d0ca3b4f862.js +8 -0
  48. package/apps/pwa/out/_next/static/chunks/4565-67e4c620597965c8.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/{7905.b230b9d06cb4ad5d.js → 4593.10f5b9bd702d4a6c.js} +1 -1
  50. package/apps/pwa/out/_next/static/chunks/4599-548bc96cda44a5a7.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/4625.206574e33a9e7ae8.js +104 -0
  52. package/apps/pwa/out/_next/static/chunks/4862-392c9a71f0d8dfb4.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5054.2906d1b02542edc5.js +149 -0
  54. package/apps/pwa/out/_next/static/chunks/{8569.b853a8daa8f31d12.js → 5081.a240b63fad28663a.js} +1 -1
  55. package/apps/pwa/out/_next/static/chunks/5102-c822bbbee5a022a4.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5194-8c93f2e7e4b6f717.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5305-bacd7eca0b9a5848.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5311.9071ee3f44fd7ff5.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/5369.9f34353442daa421.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/{2528.0af5c0e1fad88df6.js → 5408.377c8c543635b81f.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9502-32c5dc22e8f120f5.js → 5492-e05e26a033ba80d2.js} +3 -3
  62. package/apps/pwa/out/_next/static/chunks/5785-ea8d2c633b6688e3.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/589-49d730cb8138b397.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5904-264a6412ae3c9028.js +1 -0
  65. package/apps/pwa/out/_next/static/chunks/5980.728531d5c566535c.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/599-a914cc0468f56143.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/6011.f525002e21bef0ac.js +23 -0
  68. package/apps/pwa/out/_next/static/chunks/6132.4381ab93683f1acf.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6149.2e698635e454d8f6.js +1 -0
  70. package/apps/pwa/out/_next/static/chunks/{5974.360f8441eb0ac1ec.js → 6196.34d6b229079e9e28.js} +1 -1
  71. package/apps/pwa/out/_next/static/chunks/6356-0afafc4230cf9767.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6406.64756073f7df35b8.js +77 -0
  73. package/apps/pwa/out/_next/static/chunks/6479-16e62aedafa0e310.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6599.b5246b46a2453329.js +64 -0
  75. package/apps/pwa/out/_next/static/chunks/{ce383d63.d2ede338788ed18e.js → 65ebff95.081daeff622d238e.js} +1 -1
  76. package/apps/pwa/out/_next/static/chunks/6610.5c26eec011565acb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/666.37d18474edc1c552.js +2 -0
  78. package/apps/pwa/out/_next/static/chunks/6904.a0b5b1ed4f2d2c20.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/{83cfc5c8.349535543c1548b6.js → 6def8a8e.c81f9ca41028eccf.js} +1 -1
  80. package/apps/pwa/out/_next/static/chunks/7247-1f4aba94aba50d9f.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/7274-e71a7c5b7760cd02.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7290.1fcaeef3adb5d0d4.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7477-2c64e42760f82f33.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/{2721.bc9a8f36bd85c07a.js → 7483.ba01c6c209b81bba.js} +1 -1
  85. package/apps/pwa/out/_next/static/chunks/7505-47002b76ff1aef6c.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7600-11884ca4da68e5d9.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7607.40d8bb3689697ccb.js +62 -0
  88. package/apps/pwa/out/_next/static/chunks/{6702.ebbd165d5e4a4a14.js → 7752.5cbdd0b433c54af9.js} +1 -1
  89. package/apps/pwa/out/_next/static/chunks/7763.f51fcc19ca1414ec.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7785.846140c859b1adf6.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7807-a0fdac6393e0bf36.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7837-20a63b4b7e9342b1.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/800.7815414cf280545d.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/{8925-2abfb48af477fb7f.js → 8085-1e5fce59500a2cc2.js} +1 -1
  95. package/apps/pwa/out/_next/static/chunks/8100.415f2105faa63e97.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/8290.701aa42ed13aa767.js +226 -0
  97. package/apps/pwa/out/_next/static/chunks/{b4e12462-5fab4a813a63dadd.js → 83a80514-b897b64df43ce108.js} +1 -1
  98. package/apps/pwa/out/_next/static/chunks/8444.d9c74214a3145a43.js +93 -0
  99. package/apps/pwa/out/_next/static/chunks/8569.98c915534928c7f9.js +24 -0
  100. package/apps/pwa/out/_next/static/chunks/{8264.00e434fbd02e9311.js → 8578.dff22d988cc2b106.js} +3 -3
  101. package/apps/pwa/out/_next/static/chunks/8591.b1c7f876e5ec7cfb.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8715-f63756021d3ab989.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8879.776c2ec7732aa114.js +115 -0
  104. package/apps/pwa/out/_next/static/chunks/8881.ddca15b3c82c490c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8946.5da5c87f32a2e1a8.js +41 -0
  106. package/apps/pwa/out/_next/static/chunks/9117.080b9b75be90e14d.js +74 -0
  107. package/apps/pwa/out/_next/static/chunks/9167.f3ecb28f367d6e69.js +94 -0
  108. package/apps/pwa/out/_next/static/chunks/9224.66095370ee28c93b.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9238-0682b013c83d6449.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{7518.49161e8f5814abdb.js → 9311.24c8f5ea793253dd.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/{9976.8f28864317639fe6.js → 94.4cfed21c0b781a06.js} +3 -3
  112. package/apps/pwa/out/_next/static/chunks/9449.d3ed795da4befb1c.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/949.1e7d45ccb71580aa.js +90 -0
  114. package/apps/pwa/out/_next/static/chunks/9638-d268329f2c6f4f8d.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{0e3acd34.d42b2ef87fdf4234.js → 973cbf1b.3bbcf2b41548eca7.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/9842-d6644eb53d3dc6bf.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9863.94ca3263e760696e.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/{6571-926ddf024a6ad5df.js → 9917-9e26abc5f7772735.js} +1 -1
  119. package/apps/pwa/out/_next/static/chunks/9938.b23e4d4dfa0114cd.js +79 -0
  120. package/apps/pwa/out/_next/static/chunks/{740.90b31555290236a9.js → 9974.e77b4ff4884557b3.js} +2 -2
  121. package/apps/pwa/out/_next/static/chunks/{4c5e95ce.83e9b16add6fcd8c.js → ab4d57c2.e90bc2cb31949045.js} +7 -7
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-d9babd8795f396a5.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-a1ce306364f08da9.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-07110da72c45e68f.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-d2d76d4a7eae91bd.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-30007380f2e2a3c1.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-e5a9302c105725a3.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-b93c04b5311c97ec.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-718a49e86bf25f9c.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-20662900d6b4b455.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-f707a509515ac50c.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-6a16a48d1aa6e91f.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/{page-26345242e4049f55.js → page-fcb06e305f515527.js} +1 -1
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-6acf5ec4e6c6d1af.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-39f82acf619cca23.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-7c2c8f81b185f9c0.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-d9babd8795f396a5.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-ae7aff07e32676bb.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-482c60c1bc540d0a.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-7cb996c1aa08b6f5.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-623e08fe4477d606.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-db460cd8aecb8490.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-ff27902d0b11ef4f.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-8397a5c6ca569bf4.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1917ea87ea71ab6b.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-25a302273b054fd7.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-670510eda8b9443f.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-d73c3f1e00d93986.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-65caacf54389081e.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-4bb7556e2e97a750.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-77e04b4f8762c666.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/{page-b92caddb5c715f30.js → page-15c0a4095baddfba.js} +1 -1
  153. package/apps/pwa/out/_next/static/chunks/app/page-4eb96fc7241c2456.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-63e272a4cd3b6634.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d64ff212dc55d03.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-7f096248993fc2d4.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-e47fc72049149a38.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-f7d808e31e005895.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-5c2b24b5496dad73.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-d9babd8795f396a5.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-76cdb531668b5191.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-e2b63345bba1a11f.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-d376e0c83edc041a.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-d6db55fe2c04d128.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-87b88f551f421d8b.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-dab163b338e3b966.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-08019efef111ed2e.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-0260ffc7eda50db1.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-980ce6fe36ad95eb.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-99c4e6c7345a9156.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-0ab42e0f05823013.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-ad9220422d20ba33.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/dcf24383-2f82e35f2d827393.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{53746282.1be36038d1abd949.js → e117f801.e92bf10242653497.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/e87d89b9.2e71c0ae475d28a1.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/{0673cc54.8e2ef1c23e49e190.js → f4dfbfc0.a69fb12f854882aa.js} +1 -1
  177. package/apps/pwa/out/_next/static/chunks/framework-bf135b997155e90e.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/main-5571537543bea91c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-app-25c51c7df7f3a442.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/pages/_app-e3b2c1f5d82abd65.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_error-083f2e23e9bc3641.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/webpack-e94d22b7a028217b.js +1 -0
  183. package/apps/pwa/out/approvals/index.html +1 -1
  184. package/apps/pwa/out/approvals/index.txt +22 -22
  185. package/apps/pwa/out/autopilot/index.html +1 -1
  186. package/apps/pwa/out/autopilot/index.txt +22 -22
  187. package/apps/pwa/out/board/index.html +1 -1
  188. package/apps/pwa/out/board/index.txt +22 -22
  189. package/apps/pwa/out/botlab/index.html +1 -1
  190. package/apps/pwa/out/botlab/index.txt +21 -21
  191. package/apps/pwa/out/bots/index.html +1 -1
  192. package/apps/pwa/out/bots/index.txt +21 -21
  193. package/apps/pwa/out/ceo/index.html +1 -1
  194. package/apps/pwa/out/ceo/index.txt +22 -22
  195. package/apps/pwa/out/chat/index.html +1 -1
  196. package/apps/pwa/out/chat/index.txt +21 -21
  197. package/apps/pwa/out/consult/index.html +1 -1
  198. package/apps/pwa/out/consult/index.txt +22 -22
  199. package/apps/pwa/out/control/index.html +1 -1
  200. package/apps/pwa/out/control/index.txt +22 -22
  201. package/apps/pwa/out/decisions/index.html +1 -1
  202. package/apps/pwa/out/decisions/index.txt +21 -21
  203. package/apps/pwa/out/design-check/index.html +1 -1
  204. package/apps/pwa/out/design-check/index.txt +22 -22
  205. package/apps/pwa/out/editor/index.html +1 -1
  206. package/apps/pwa/out/editor/index.txt +22 -22
  207. package/apps/pwa/out/exec/index.html +1 -1
  208. package/apps/pwa/out/exec/index.txt +22 -22
  209. package/apps/pwa/out/field/index.html +1 -1
  210. package/apps/pwa/out/field/index.txt +22 -22
  211. package/apps/pwa/out/healthz +1 -1
  212. package/apps/pwa/out/index.html +1 -1
  213. package/apps/pwa/out/index.txt +21 -21
  214. package/apps/pwa/out/inside/index.html +1 -1
  215. package/apps/pwa/out/inside/index.txt +21 -21
  216. package/apps/pwa/out/intake/index.html +1 -1
  217. package/apps/pwa/out/intake/index.txt +22 -22
  218. package/apps/pwa/out/live/index.html +1 -1
  219. package/apps/pwa/out/live/index.txt +22 -22
  220. package/apps/pwa/out/live-run/index.html +1 -1
  221. package/apps/pwa/out/live-run/index.txt +22 -22
  222. package/apps/pwa/out/loops/index.html +1 -1
  223. package/apps/pwa/out/loops/index.txt +21 -21
  224. package/apps/pwa/out/market/index.html +1 -1
  225. package/apps/pwa/out/market/index.txt +21 -21
  226. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  227. package/apps/pwa/out/missions/placeholder/index.txt +21 -21
  228. package/apps/pwa/out/morning/index.html +1 -1
  229. package/apps/pwa/out/morning/index.txt +22 -22
  230. package/apps/pwa/out/observatory/index.html +1 -1
  231. package/apps/pwa/out/observatory/index.txt +22 -22
  232. package/apps/pwa/out/ops/checklist/index.html +1 -1
  233. package/apps/pwa/out/ops/checklist/index.txt +21 -21
  234. package/apps/pwa/out/ops/release/index.html +1 -1
  235. package/apps/pwa/out/ops/release/index.txt +21 -21
  236. package/apps/pwa/out/ops/seats/index.html +1 -1
  237. package/apps/pwa/out/ops/seats/index.txt +21 -21
  238. package/apps/pwa/out/outputs/index.html +1 -1
  239. package/apps/pwa/out/outputs/index.txt +21 -21
  240. package/apps/pwa/out/reflection/index.html +1 -1
  241. package/apps/pwa/out/reflection/index.txt +22 -22
  242. package/apps/pwa/out/scheduler/index.html +1 -1
  243. package/apps/pwa/out/scheduler/index.txt +22 -22
  244. package/apps/pwa/out/sessions/index.html +1 -1
  245. package/apps/pwa/out/sessions/index.txt +21 -21
  246. package/apps/pwa/out/settings/devices/index.html +1 -1
  247. package/apps/pwa/out/settings/devices/index.txt +22 -22
  248. package/apps/pwa/out/settings/index.html +1 -1
  249. package/apps/pwa/out/settings/index.txt +22 -22
  250. package/apps/pwa/out/setup/done/index.html +1 -1
  251. package/apps/pwa/out/setup/done/index.txt +22 -22
  252. package/apps/pwa/out/setup/index.html +1 -1
  253. package/apps/pwa/out/setup/index.txt +22 -22
  254. package/apps/pwa/out/share/index.html +1 -1
  255. package/apps/pwa/out/share/index.txt +22 -22
  256. package/apps/pwa/out/showroom/index.html +1 -1
  257. package/apps/pwa/out/showroom/index.txt +21 -21
  258. package/apps/pwa/out/tasks/index.html +1 -1
  259. package/apps/pwa/out/tasks/index.txt +22 -22
  260. package/apps/pwa/out/term/index.html +1 -1
  261. package/apps/pwa/out/term/index.txt +22 -22
  262. package/apps/pwa/out/today/index.html +1 -1
  263. package/apps/pwa/out/today/index.txt +22 -22
  264. package/apps/pwa/out/trace/index.html +1 -1
  265. package/apps/pwa/out/trace/index.txt +22 -22
  266. package/apps/pwa/out/vault/index.html +1 -1
  267. package/apps/pwa/out/vault/index.txt +22 -22
  268. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  269. package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
  270. package/apps/pwa/out/workflows/index.html +1 -1
  271. package/apps/pwa/out/workflows/index.txt +22 -22
  272. package/apps/pwa/out/workspace/index.html +1 -1
  273. package/apps/pwa/out/workspace/index.txt +22 -22
  274. package/apps/pwa/out/worktrees/index.html +1 -1
  275. package/apps/pwa/out/worktrees/index.txt +22 -22
  276. package/graphs/release/release-loop.yaml +5 -5
  277. package/graphs/steward/recipes.yaml +4 -0
  278. package/graphs/steward/steward.yaml +10 -1
  279. package/package.json +1 -1
  280. package/scripts/bench-report.ts +46 -1
  281. package/scripts/ci-typecheck-changed.ts +88 -7
  282. package/scripts/coord-msg-bridge.ts +209 -0
  283. package/scripts/coord-post.sh +40 -7
  284. package/scripts/coord-requests-bridge.ts +10 -5
  285. package/scripts/expose-rubric-suggest.ts +1 -1
  286. package/scripts/measure-tsc-affected-roots.ts +10 -1
  287. package/scripts/release-loop/auto-approve-node.ts +6 -0
  288. package/scripts/release-loop/export-check-node.ts +8 -5
  289. package/scripts/release-loop/gate-closure.ts +286 -0
  290. package/scripts/release-loop/gate-node.ts +73 -13
  291. package/scripts/release-loop/gate-partial.ts +34 -6
  292. package/scripts/release-loop/node-verdict.ts +7 -2
  293. package/scripts/release-loop/ops-upgrade-node.ts +63 -42
  294. package/scripts/release-loop/publish-node.ts +6 -0
  295. package/scripts/release-loop/resume-release.ts +37 -10
  296. package/scripts/release-loop/resume.ts +69 -4
  297. package/scripts/tsc-baseline-cache.ts +28 -3
  298. package/scripts/usage-rollup.ts +27 -13
  299. package/scripts/ux-sim.ts +30 -1
  300. package/skills/youtube-master/scripts/main.ts +4 -1
  301. package/skills/youtube-master/src/obsidian.ts +9 -0
  302. package/src/agent/task-notification.ts +30 -1
  303. package/src/agent-substrate/acp-implementer.ts +14 -7
  304. package/src/agent-substrate/pr-reviewer.ts +30 -10
  305. package/src/agent-substrate/review-observation.ts +9 -2
  306. package/src/agent-substrate/self-review-cli.ts +154 -16
  307. package/src/boot/daemon-tools/self-implement.ts +72 -4
  308. package/src/budget/cost-tier-advisor.ts +91 -0
  309. package/src/budget/llm-cost.ts +5 -1
  310. package/src/budget/shadow-arms.ts +77 -0
  311. package/src/budget/types.ts +5 -3
  312. package/src/budget/unified-usage.ts +172 -8
  313. package/src/cli/control-cli.ts +29 -0
  314. package/src/cli/doctor-cli.ts +106 -3
  315. package/src/cli/friendly-errors.ts +113 -0
  316. package/src/cli/intake-cli.ts +3 -1
  317. package/src/cli/memory-cli.ts +182 -0
  318. package/src/cli/model-watch-cli.ts +4 -1
  319. package/src/cli/msg-cli.ts +15 -5
  320. package/src/cli/pr-cli.ts +53 -0
  321. package/src/cli/pr-land-overlap-evidence.ts +18 -10
  322. package/src/cli/pr-land-pod-shadow.ts +54 -0
  323. package/src/cli/release-cli.ts +41 -12
  324. package/src/cli/release-run-if-ready.ts +11 -0
  325. package/src/cli/resource-cli.ts +48 -0
  326. package/src/cli/retro-cli.ts +12 -3
  327. package/src/cli/seat-cli.ts +121 -0
  328. package/src/cli/seat-requests-cli.ts +25 -0
  329. package/src/cli/self-utterances-cli.ts +140 -0
  330. package/src/cli/tasks-cli.ts +168 -14
  331. package/src/cli/usage-cli.ts +3 -1
  332. package/src/compact/verify-probe.ts +23 -3
  333. package/src/context-card/cell.ts +40 -0
  334. package/src/context-card/index.ts +50 -0
  335. package/src/control/control-status.ts +30 -1
  336. package/src/dashboard/boot-timing.ts +35 -0
  337. package/src/dashboard/index.ts +86 -24
  338. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +26 -0
  339. package/src/dashboard/slash-runtime/dashboard-handlers.ts +10 -138
  340. package/src/dashboard/slash-runtime/shell-slash.ts +145 -0
  341. package/src/debug/log-diet.ts +16 -4
  342. package/src/debug/log.ts +1 -1
  343. package/src/domains/morning-essential.ts +18 -3
  344. package/src/domains/release-tool.ts +29 -8
  345. package/src/domains/surface-events.ts +16 -0
  346. package/src/elanous-config-dir.ts +2 -2
  347. package/src/execution-loop/launch-gate.ts +158 -2
  348. package/src/fleet/host-doctor.ts +446 -0
  349. package/src/goals/judge.ts +20 -6
  350. package/src/graph-runner/runner.ts +12 -6
  351. package/src/graph-wizard/archetypes.ts +14 -8
  352. package/src/graph-wizard/generate.ts +77 -1
  353. package/src/grok.ts +13 -7
  354. package/src/harness/harness-cli-command.ts +102 -51
  355. package/src/harness/harness-stop.ts +93 -19
  356. package/src/index.ts +52 -179
  357. package/src/instance/current.ts +2 -6
  358. package/src/instance/resolve.ts +5 -6
  359. package/src/intake-plane/collect-github.ts +7 -2
  360. package/src/intake-plane/lens.ts +46 -4
  361. package/src/intake-plane/requirement-funnel.ts +53 -1
  362. package/src/intelligence-map/catalog-feed.ts +119 -0
  363. package/src/intelligence-map/model-watch-intake.ts +40 -0
  364. package/src/intelligence-map/model-watch-mission.ts +14 -1
  365. package/src/llm/open-weight-discipline.ts +21 -0
  366. package/src/llm/openai-sampling-fields.ts +89 -0
  367. package/src/llm/runtime-model-family.ts +61 -0
  368. package/src/llm/zai-coding-plan.ts +27 -1
  369. package/src/llm.ts +17 -97
  370. package/src/machines/machine-ledger.ts +31 -3
  371. package/src/maturity/cli-maturity.ts +13 -3
  372. package/src/maturity/feature-maturity.ts +1 -1
  373. package/src/msg/msg-store.ts +69 -7
  374. package/src/nexus/api/http-server.ts +22 -0
  375. package/src/oauth/codex-account-rotation.ts +4 -1
  376. package/src/oauth/codex-account-store.ts +20 -7
  377. package/src/oauth/codex-quota-policy.ts +33 -4
  378. package/src/ops/overview-collect.ts +3 -2
  379. package/src/ops/overview-owner.ts +29 -0
  380. package/src/plugin-hooks/shell-hook.ts +17 -2
  381. package/src/plugin-missions/evaluator-runner.ts +18 -2
  382. package/src/plugins/install/plugin-install.ts +11 -1
  383. package/src/preview/terminal.ts +15 -5
  384. package/src/project/project-store.ts +20 -0
  385. package/src/prompt-enhance/enhance.ts +11 -0
  386. package/src/release-loop/auto-start.ts +7 -5
  387. package/src/release-loop/checklist.ts +52 -5
  388. package/src/release-loop/feature-store.ts +10 -9
  389. package/src/release-loop/gate-shards.ts +4 -0
  390. package/src/release-loop/light-rc.ts +84 -13
  391. package/src/release-loop/merged-pr-checklist.ts +35 -5
  392. package/src/release-loop/rehearsal.ts +1 -1
  393. package/src/seat-loop/duty-ledger.ts +64 -0
  394. package/src/seat-loop/seat-loop.ts +5 -1
  395. package/src/self-dev/decompose.ts +37 -3
  396. package/src/self-dev/dev-pipeline.ts +32 -7
  397. package/src/self-dev/draft-residue.ts +16 -6
  398. package/src/self-dev/draft-sweep.ts +75 -18
  399. package/src/self-dev/fabric-decompose-adapter.ts +9 -2
  400. package/src/self-dev/orchestrate.ts +6 -2
  401. package/src/self-dev/run-supervisor.ts +72 -8
  402. package/src/self-implement/gate-cli.ts +29 -10
  403. package/src/self-implement/gate-remote.ts +4 -1
  404. package/src/self-implement/goal-author.ts +15 -29
  405. package/src/self-implement/goal-command-execution.ts +26 -0
  406. package/src/self-implement/goal-new-paths.ts +42 -0
  407. package/src/self-implement/host-regate.ts +124 -30
  408. package/src/self-implement/importer-test-index.ts +3 -1
  409. package/src/self-implement/l8-merge-queue.ts +80 -2
  410. package/src/self-implement/merge-train.ts +19 -0
  411. package/src/self-implement/off-diff-evidence.ts +40 -1
  412. package/src/self-implement/orchestrator.ts +90 -20
  413. package/src/self-implement/premise-review.ts +159 -0
  414. package/src/self-implement/pwa-import-graph.ts +194 -7
  415. package/src/self-implement/regate-detail.ts +79 -0
  416. package/src/self-implement/review-deferred-to-host.ts +21 -0
  417. package/src/self-implement/rework-budget-judgment.ts +23 -3
  418. package/src/self-implement/running-runs.ts +2 -2
  419. package/src/self-implement/scope-adjacency.ts +23 -0
  420. package/src/self-implement/seams.ts +42 -7
  421. package/src/self-implement/self-implement-runtime.ts +126 -21
  422. package/src/session/index.ts +14 -4
  423. package/src/session-runtime/index.ts +55 -11
  424. package/src/skills/tools/agent.ts +16 -1
  425. package/src/skills/tools/persistent-grounding.ts +11 -1
  426. package/src/skills/tools/shell.ts +33 -1
  427. package/src/steward/rejudge-tick.ts +142 -0
  428. package/src/task-agent/board.ts +92 -3
  429. package/src/task-agent/card-evidence.ts +88 -1
  430. package/src/task-agent/cover.ts +85 -1
  431. package/src/task-agent/live-moves.ts +14 -6
  432. package/src/task-agent/parent-host.ts +27 -3
  433. package/src/task-agent/rejudge-on-head.ts +370 -29
  434. package/src/task-agent/review-result-capture.ts +67 -2
  435. package/src/task-agent/shadow.ts +148 -21
  436. package/src/task-agent/task-hand.ts +22 -3
  437. package/src/task-orchestrator/surfaces/pod-command-job.ts +14 -0
  438. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +122 -0
  439. package/src/task-orchestrator/surfaces/pod-manifest-test-normalize.ts +23 -0
  440. package/src/task-orchestrator/surfaces/pod-pool.ts +53 -0
  441. package/src/task-orchestrator/surfaces/self-implement-pod.ts +236 -28
  442. package/src/tool-runtime/tool-search-runtime.ts +25 -0
  443. package/src/tui.ts +20 -1
  444. package/src/user-config.ts +21 -63
  445. package/src/ux-sim/fault-cred-expiry.ts +100 -0
  446. package/src/ux-sim/fault-pod-death.ts +74 -0
  447. package/src/ux-sim/fault-pool-cap.ts +81 -0
  448. package/src/version/packed-revision.json +1 -1
  449. package/src/webclone/qa-table.ts +22 -0
  450. package/apps/pwa/out/_next/static/chunks/0a09e062-34f747a17d8d8c2e.js +0 -1
  451. package/apps/pwa/out/_next/static/chunks/1168.a0fb3d9db76c00bd.js +0 -77
  452. package/apps/pwa/out/_next/static/chunks/1325-dc3f3c21eb181cb4.js +0 -1
  453. package/apps/pwa/out/_next/static/chunks/1357.a843c41d2cd7ec31.js +0 -34
  454. package/apps/pwa/out/_next/static/chunks/1430.53f49882b17607c2.js +0 -24
  455. package/apps/pwa/out/_next/static/chunks/1459-be6509b3419d8a9f.js +0 -1
  456. package/apps/pwa/out/_next/static/chunks/153.0a4e3cd516930491.js +0 -1
  457. package/apps/pwa/out/_next/static/chunks/1572.7bc291352e241a45.js +0 -1
  458. package/apps/pwa/out/_next/static/chunks/1593-d07ad068c120dfb0.js +0 -1
  459. package/apps/pwa/out/_next/static/chunks/1608.b7c900baa56cab32.js +0 -1
  460. package/apps/pwa/out/_next/static/chunks/1615-4d8156febaac4b35.js +0 -1
  461. package/apps/pwa/out/_next/static/chunks/1646.e03f0fbc26bc72f6.js +0 -1
  462. package/apps/pwa/out/_next/static/chunks/1669-da843ed73aa301f5.js +0 -1
  463. package/apps/pwa/out/_next/static/chunks/176.13ba0659e3e96fd4.js +0 -1
  464. package/apps/pwa/out/_next/static/chunks/1990.9c60f495ef33c070.js +0 -36
  465. package/apps/pwa/out/_next/static/chunks/2042e469.f86158dd5c1e51a1.js +0 -122
  466. package/apps/pwa/out/_next/static/chunks/2543-28ec6aeb80a5e1e1.js +0 -1
  467. package/apps/pwa/out/_next/static/chunks/2561.43c99d6ee914ee6a.js +0 -62
  468. package/apps/pwa/out/_next/static/chunks/2638.b39ab2f674caa1a5.js +0 -1
  469. package/apps/pwa/out/_next/static/chunks/272-0eed0fb0aab716b6.js +0 -1
  470. package/apps/pwa/out/_next/static/chunks/2778.67e0c1d484189ccf.js +0 -1
  471. package/apps/pwa/out/_next/static/chunks/2841.10ff309f6a3168af.js +0 -1
  472. package/apps/pwa/out/_next/static/chunks/2886-9639f97d523d752a.js +0 -1
  473. package/apps/pwa/out/_next/static/chunks/2978.57fb87ce21cc5a85.js +0 -1
  474. package/apps/pwa/out/_next/static/chunks/3664.15f968c39d15bd28.js +0 -149
  475. package/apps/pwa/out/_next/static/chunks/3786-935eb3fcde90e496.js +0 -1
  476. package/apps/pwa/out/_next/static/chunks/3813.df4a01ae89c6f63f.js +0 -1
  477. package/apps/pwa/out/_next/static/chunks/3961-aaae04ed1d32622f.js +0 -1
  478. package/apps/pwa/out/_next/static/chunks/3992.f79c70480e8c4077.js +0 -309
  479. package/apps/pwa/out/_next/static/chunks/40-413e8641de9ed1e5.js +0 -1
  480. package/apps/pwa/out/_next/static/chunks/4054-521f11a503daed64.js +0 -1
  481. package/apps/pwa/out/_next/static/chunks/4315.e7356f34c7d8ec79.js +0 -1
  482. package/apps/pwa/out/_next/static/chunks/4489-bf629de6f04f7681.js +0 -1
  483. package/apps/pwa/out/_next/static/chunks/4540.557733cc88c6a82b.js +0 -1
  484. package/apps/pwa/out/_next/static/chunks/462.0275b4338c5b6337.js +0 -1
  485. package/apps/pwa/out/_next/static/chunks/4658-7ed9266098a787e4.js +0 -1
  486. package/apps/pwa/out/_next/static/chunks/4945-0f4046cfc3228ea3.js +0 -1
  487. package/apps/pwa/out/_next/static/chunks/5105-18b4165c5d3a86b0.js +0 -1
  488. package/apps/pwa/out/_next/static/chunks/5205-6992210fe31f45f4.js +0 -1
  489. package/apps/pwa/out/_next/static/chunks/5287-72898b126d722457.js +0 -1
  490. package/apps/pwa/out/_next/static/chunks/5313.1697309c532b9856.js +0 -2
  491. package/apps/pwa/out/_next/static/chunks/5474.991b90688c3cb321.js +0 -1
  492. package/apps/pwa/out/_next/static/chunks/5544-871146192d095594.js +0 -1
  493. package/apps/pwa/out/_next/static/chunks/5935.d5e8ca3e096772e8.js +0 -1
  494. package/apps/pwa/out/_next/static/chunks/6006.84e8b418a7a0db97.js +0 -1
  495. package/apps/pwa/out/_next/static/chunks/6013-1267ba7454d6764b.js +0 -1
  496. package/apps/pwa/out/_next/static/chunks/6038-1e0f7ee1086da4cf.js +0 -1
  497. package/apps/pwa/out/_next/static/chunks/617.709dd0019fe99796.js +0 -1
  498. package/apps/pwa/out/_next/static/chunks/6261.fb9bf94947094636.js +0 -74
  499. package/apps/pwa/out/_next/static/chunks/6411.1966866fae31ffa9.js +0 -1
  500. package/apps/pwa/out/_next/static/chunks/6481-b829d99aa8d158f5.js +0 -1
  501. package/apps/pwa/out/_next/static/chunks/6541.2b7daa043100d0fa.js +0 -1
  502. package/apps/pwa/out/_next/static/chunks/6597.2d7a6d77ab485b27.js +0 -64
  503. package/apps/pwa/out/_next/static/chunks/67.5dd2dc543c2fa3de.js +0 -1
  504. package/apps/pwa/out/_next/static/chunks/6777-312496b0d774719b.js +0 -1
  505. package/apps/pwa/out/_next/static/chunks/681.0116f7036cfb4e8d.js +0 -32
  506. package/apps/pwa/out/_next/static/chunks/6871.30b2bf23b3126e36.js +0 -24
  507. package/apps/pwa/out/_next/static/chunks/6882.737d366d54e29d83.js +0 -1
  508. package/apps/pwa/out/_next/static/chunks/7035.54c2c535164b1c9b.js +0 -1
  509. package/apps/pwa/out/_next/static/chunks/7086-8bfa7e8f796a03d9.js +0 -1
  510. package/apps/pwa/out/_next/static/chunks/7126.5e5599f251726b67.js +0 -93
  511. package/apps/pwa/out/_next/static/chunks/7203-47ff0740a293e284.js +0 -1
  512. package/apps/pwa/out/_next/static/chunks/7268.017f49dafb5f0ff3.js +0 -1
  513. package/apps/pwa/out/_next/static/chunks/7355.5d65a87e9567ae08.js +0 -1
  514. package/apps/pwa/out/_next/static/chunks/7392.4018c2a62177f296.js +0 -1
  515. package/apps/pwa/out/_next/static/chunks/7471.3a3d1be50559cfb8.js +0 -148
  516. package/apps/pwa/out/_next/static/chunks/7500.73489a345cef2201.js +0 -226
  517. package/apps/pwa/out/_next/static/chunks/7565.c2f72a15c1ed0396.js +0 -27
  518. package/apps/pwa/out/_next/static/chunks/7651.6d1c984d3d8587a4.js +0 -1
  519. package/apps/pwa/out/_next/static/chunks/7713.7ab863ed59b2d661.js +0 -1
  520. package/apps/pwa/out/_next/static/chunks/7793.d7cd2026767ddd54.js +0 -115
  521. package/apps/pwa/out/_next/static/chunks/7837.c7c267e5dceadb11.js +0 -1
  522. package/apps/pwa/out/_next/static/chunks/7891.09266382daf70d1c.js +0 -1
  523. package/apps/pwa/out/_next/static/chunks/7990-cbf6a01bcbdcb7e6.js +0 -1
  524. package/apps/pwa/out/_next/static/chunks/8119-819c549e0c197786.js +0 -1
  525. package/apps/pwa/out/_next/static/chunks/8186-74ea19a3700d04a8.js +0 -1
  526. package/apps/pwa/out/_next/static/chunks/8267-e7b3262b735ae106.js +0 -1
  527. package/apps/pwa/out/_next/static/chunks/8386.86518e55b75f7cf5.js +0 -8
  528. package/apps/pwa/out/_next/static/chunks/8437.ba6eeeb29590042f.js +0 -23
  529. package/apps/pwa/out/_next/static/chunks/8469-1500be57e582296f.js +0 -1
  530. package/apps/pwa/out/_next/static/chunks/8483-7164cecdaf178ca6.js +0 -1
  531. package/apps/pwa/out/_next/static/chunks/8722-4c940f02c496ad36.js +0 -1
  532. package/apps/pwa/out/_next/static/chunks/887-41d0dcf5af48c628.js +0 -1
  533. package/apps/pwa/out/_next/static/chunks/9039.da86361496797522.js +0 -90
  534. package/apps/pwa/out/_next/static/chunks/905.d5745a25884754d4.js +0 -94
  535. package/apps/pwa/out/_next/static/chunks/9089-d909f3d4478b0628.js +0 -1
  536. package/apps/pwa/out/_next/static/chunks/9096.dc5c7a267f83790c.js +0 -41
  537. package/apps/pwa/out/_next/static/chunks/93.a567257b6bdb7fe4.js +0 -1
  538. package/apps/pwa/out/_next/static/chunks/9320.419acb9665b46597.js +0 -287
  539. package/apps/pwa/out/_next/static/chunks/9356.b8ceda6634612ff8.js +0 -79
  540. package/apps/pwa/out/_next/static/chunks/94.e9e1043b35cd3eed.js +0 -1
  541. package/apps/pwa/out/_next/static/chunks/9400-7498ea90b2e6ee8f.js +0 -1
  542. package/apps/pwa/out/_next/static/chunks/9930-58644af9c813d6e1.js +0 -1
  543. package/apps/pwa/out/_next/static/chunks/9932.367cf4725fedd6e2.js +0 -1
  544. package/apps/pwa/out/_next/static/chunks/9935.1628b904cdc8ce0e.js +0 -104
  545. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-a2aa8709d193ee0d.js +0 -1
  546. package/apps/pwa/out/_next/static/chunks/app/approvals/page-3b9fc39362473ae7.js +0 -1
  547. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-f2b62c19ca68fef8.js +0 -1
  548. package/apps/pwa/out/_next/static/chunks/app/board/page-d7602d489edf5f37.js +0 -1
  549. package/apps/pwa/out/_next/static/chunks/app/botlab/page-24282bf9f90031a5.js +0 -1
  550. package/apps/pwa/out/_next/static/chunks/app/bots/page-8b7c5ab6b5bc8d64.js +0 -1
  551. package/apps/pwa/out/_next/static/chunks/app/ceo/page-4eb84d454f8c3415.js +0 -1
  552. package/apps/pwa/out/_next/static/chunks/app/chat/page-b2e494bdad57fcb5.js +0 -1
  553. package/apps/pwa/out/_next/static/chunks/app/consult/page-c0ab229673a8b0eb.js +0 -1
  554. package/apps/pwa/out/_next/static/chunks/app/control/page-3e2b45f3c36dbac4.js +0 -1
  555. package/apps/pwa/out/_next/static/chunks/app/decisions/page-c22aa511b28743ad.js +0 -1
  556. package/apps/pwa/out/_next/static/chunks/app/editor/page-bf88c0f558d8ef54.js +0 -1
  557. package/apps/pwa/out/_next/static/chunks/app/exec/page-52fec523e5b5d3ad.js +0 -1
  558. package/apps/pwa/out/_next/static/chunks/app/field/page-67723dfdcde92b31.js +0 -1
  559. package/apps/pwa/out/_next/static/chunks/app/healthz/route-a2aa8709d193ee0d.js +0 -1
  560. package/apps/pwa/out/_next/static/chunks/app/inside/page-22725e2570f1126b.js +0 -1
  561. package/apps/pwa/out/_next/static/chunks/app/intake/page-1891335950d68b70.js +0 -1
  562. package/apps/pwa/out/_next/static/chunks/app/layout-3267af1ebdc73cf5.js +0 -1
  563. package/apps/pwa/out/_next/static/chunks/app/live/page-c314b75c11234998.js +0 -1
  564. package/apps/pwa/out/_next/static/chunks/app/live-run/page-9f9c85415f61782b.js +0 -1
  565. package/apps/pwa/out/_next/static/chunks/app/loops/page-c1d4276059085587.js +0 -1
  566. package/apps/pwa/out/_next/static/chunks/app/market/page-833aab587f26ad4c.js +0 -1
  567. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-8526c17ae38e6a50.js +0 -1
  568. package/apps/pwa/out/_next/static/chunks/app/morning/page-f998637a8402115c.js +0 -1
  569. package/apps/pwa/out/_next/static/chunks/app/not-found-b7bb53828b17b335.js +0 -1
  570. package/apps/pwa/out/_next/static/chunks/app/observatory/page-1b1850de0257e46d.js +0 -1
  571. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-6f23159fedb41f67.js +0 -1
  572. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-1d809a87139dd024.js +0 -1
  573. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-da9e570234d481fd.js +0 -1
  574. package/apps/pwa/out/_next/static/chunks/app/page-8ce3a38e210b810a.js +0 -1
  575. package/apps/pwa/out/_next/static/chunks/app/reflection/page-57ffeeb6019440fd.js +0 -1
  576. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-abbb417bf514630b.js +0 -1
  577. package/apps/pwa/out/_next/static/chunks/app/sessions/page-2c2b3f29cec1efa4.js +0 -1
  578. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-9369279f72fc7b51.js +0 -1
  579. package/apps/pwa/out/_next/static/chunks/app/settings/page-64861f14039499c3.js +0 -1
  580. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ddc4c93efd8ab94b.js +0 -1
  581. package/apps/pwa/out/_next/static/chunks/app/setup/layout-a2aa8709d193ee0d.js +0 -1
  582. package/apps/pwa/out/_next/static/chunks/app/setup/page-901a1391b81053bc.js +0 -1
  583. package/apps/pwa/out/_next/static/chunks/app/share/page-68d9bbaac9841a58.js +0 -1
  584. package/apps/pwa/out/_next/static/chunks/app/showroom/page-b5c0c996f329371e.js +0 -1
  585. package/apps/pwa/out/_next/static/chunks/app/tasks/page-89881ccbcf728978.js +0 -1
  586. package/apps/pwa/out/_next/static/chunks/app/term/page-0e87a803b3d7165e.js +0 -1
  587. package/apps/pwa/out/_next/static/chunks/app/today/page-58d4e5cb30ef4871.js +0 -1
  588. package/apps/pwa/out/_next/static/chunks/app/trace/page-02ce4c3b5f39e4d2.js +0 -1
  589. package/apps/pwa/out/_next/static/chunks/app/vault/page-e620d1bb8eadcec2.js +0 -1
  590. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-acf868c64d77f950.js +0 -1
  591. package/apps/pwa/out/_next/static/chunks/app/workflows/page-54fa605fa6dba457.js +0 -1
  592. package/apps/pwa/out/_next/static/chunks/app/workspace/page-bc79f0833533fa84.js +0 -1
  593. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-d5c4398eea03d8f3.js +0 -1
  594. package/apps/pwa/out/_next/static/chunks/cd39fa05.fac4545f42a3ef70.js +0 -1
  595. package/apps/pwa/out/_next/static/chunks/framework-b2763b10dc6b3836.js +0 -1
  596. package/apps/pwa/out/_next/static/chunks/main-app-27893e93b0ec193d.js +0 -1
  597. package/apps/pwa/out/_next/static/chunks/main-f280047194e1daf8.js +0 -1
  598. package/apps/pwa/out/_next/static/chunks/pages/_app-e90eff2d0b70564c.js +0 -1
  599. package/apps/pwa/out/_next/static/chunks/pages/_error-70f2d654b3435d34.js +0 -1
  600. package/apps/pwa/out/_next/static/chunks/webpack-4794f053bd5e4230.js +0 -1
  601. /package/apps/pwa/out/_next/static/{Q-7iofoxOEv1WX18S35of → Ev2jivDMTSoEc-5rIXdcy}/_ssgManifest.js +0 -0
@@ -28,7 +28,7 @@ import { effectiveInstanceRoot, releaseLedgerRoot } from '../instance/resolve.js
28
28
  import { getElanousConfigDirOverride } from '../elanous-config-dir.js';
29
29
  import { envLiteral } from '../platform/env-literal.js';
30
30
  import { getUserConfig, userConfigPath } from '../user-config.js';
31
- import { addItem, cellsReferencingDoc, claimItem, decodeClaimHistoryEntry, devVersion, lintDocRefs, listChecklist, normalizeRefs, ownerMatches, parseOwner, parityGap, refRoots, removeItem, renderRefsStatus, seedFromRoadmap, setItem, summarizeChecklist, type ChecklistStatus, type ChecklistDisposition, type ChecklistKind } from '../release-loop/checklist.js';
31
+ import { addItem, cellsReferencingDoc, claimItem, decodeClaimHistoryEntry, devVersion, inspectChecklistTargetPaths, lintDocRefs, listChecklist, normalizeRefs, ownerMatches, parseOwner, parityGap, refRoots, removeItem, renderRefsStatus, seedFromRoadmap, setItem, summarizeChecklist, type ChecklistStatus, type ChecklistDisposition, type ChecklistKind, type ChecklistDispatchKind } from '../release-loop/checklist.js';
32
32
  import * as features from '../release-loop/feature-store.js';
33
33
  import { evidencePlan, landedButYellow, type MergedChecklistPr } from '../release-loop/landed-but-yellow.js';
34
34
  import { formatSchedule, getSchedule, listSchedules, setSchedule } from '../release-loop/release-schedule.js';
@@ -488,6 +488,28 @@ async function jsonAction<T>(json: boolean | undefined, body: (log: (l: string)
488
488
  }
489
489
  }
490
490
 
491
+ function warnChecklistTargetPaths(input: { title: string; evidence?: string; refs?: readonly string[]; dispatchKind?: ChecklistDispatchKind }): void {
492
+ const cwd = process.cwd();
493
+ const existsAtMain = (path: string): boolean => {
494
+ if (path.startsWith('/') || path.split('/').includes('..')) return false;
495
+ const result = spawnSync('git', ['cat-file', '-e', `origin/main:${path}`], { cwd, timeout: 5_000, stdio: 'ignore' });
496
+ return result.status === 0;
497
+ };
498
+ const mergedPrFiles = (number: number): string[] => {
499
+ const result = spawnSync('gh', ['pr', 'view', String(number), '--json', 'state,files'], { cwd, encoding: 'utf8', timeout: 10_000 });
500
+ if (result.status !== 0) return [];
501
+ try {
502
+ const pr = JSON.parse(result.stdout) as { state?: string; files?: Array<{ path?: string }> };
503
+ return pr.state === 'MERGED' ? (pr.files ?? []).map((file) => file.path).filter((path): path is string => typeof path === 'string') : [];
504
+ } catch { return []; }
505
+ };
506
+ const report = inspectChecklistTargetPaths(input, { existsAtMain, mergedPrFiles });
507
+ for (const warning of report.warnings) {
508
+ console.error(`⚠ 대상 경로: ${warning}${report.candidates.length ? ` · 후보: ${report.candidates.join(' · ')}` : ''}`);
509
+ debug.log('release.checklist', 'target-path-warning', { warning, candidates: report.candidates });
510
+ }
511
+ }
512
+
491
513
  function checklistCodenames(): Record<string, string> {
492
514
  const path = getElanousConfigDirOverride() ? join(effectiveInstanceRoot(), 'config.json') : userConfigPath();
493
515
  if (!existsSync(path)) return {};
@@ -815,7 +837,7 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
815
837
  process.exitCode = 1;
816
838
  }
817
839
  });
818
- withContext(checklist.command('add <id> <title>').description('칸 추가')).option('--owner <owner>', '담당').option('--kind <kind>', 'screen = 다섯 화면 짝 칸 · 근거에 짝: PWA … · 데스크톱 … · 폴드 … · 아이폰 … · 아이패드 … 한 줄 · postpub = 발행 뒤 실측 칸 — 판 관문이 발행 전 판정에서 빼고 따로 센다')
840
+ withContext(checklist.command('add <id> <title>').description('칸 추가')).option('--owner <owner>', '담당').option('--kind <kind>', 'screen = 다섯 화면 짝 칸 · 근거에 짝: PWA … · 데스크톱 … · 폴드 … · 아이폰 … · 아이패드 … 한 줄 · postpub = 발행 뒤 실측 칸 — 판 관문이 발행 전 판정에서 빼고 따로 센다 · code|ops|measure|decision|umbrella = 발사 분류')
819
841
  .option('--priority <priority>', 'P0|P1|P2').option('--deadline-version <v>', '마감 판').option('--predecessor <id...>', '선행 칸 id')
820
842
  .option('--ceo-minutes <minutes>', '대표 손 분량(분)').option('--ceo-date <date>', '대표 손 날짜 YYYY-MM-DD (없으면 판 착지일 KST)')
821
843
  .option('--accelerator', '가속 등급 — 다른 칸의 처리량을 올리는 칸(자율성·효율성·동시성). 생략하면 등급 없음')
@@ -824,12 +846,14 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
824
846
  .action((id: string, title: string, opts: { ref?: string[]; owner?: string; kind?: string; priority?: string; deadlineVersion?: string; predecessor?: string[]; ceoMinutes?: string; ceoDate?: string; accelerator?: boolean; allowDuplicateId?: boolean }, cmd: Command) => {
825
847
  const { version, json } = context(cmd);
826
848
  if (!mayWrite(cmd)) return;
827
- const data = addItem(version, { id, title, ...(opts.ref !== undefined ? { refs: opts.ref } : {}), ...(opts.owner !== undefined ? { owner: opts.owner } : {}), ...(opts.kind !== undefined ? { kind: opts.kind as ChecklistKind } : {}), ...(opts.priority !== undefined ? { priority: opts.priority as PlacementPriority } : {}), ...(opts.deadlineVersion !== undefined ? { deadlineVersion: opts.deadlineVersion } : {}), ...(opts.predecessor !== undefined ? { predecessors: opts.predecessor } : {}), ...(opts.ceoMinutes !== undefined ? { ceoMinutes: ceoMinutes(opts.ceoMinutes) } : {}), ...(opts.ceoDate !== undefined ? { ceoDate: opts.ceoDate } : {}), ...(opts.accelerator ? { accelerator: true } : {}) }, { allowDuplicateId: opts.allowDuplicateId });
849
+ const dispatchKind = opts.kind && !['screen', 'postpub'].includes(opts.kind) ? opts.kind as ChecklistDispatchKind : undefined;
850
+ const data = addItem(version, { id, title, ...(opts.ref !== undefined ? { refs: opts.ref } : {}), ...(opts.owner !== undefined ? { owner: opts.owner } : {}), ...(opts.kind !== undefined && !dispatchKind ? { kind: opts.kind as ChecklistKind } : {}), ...(dispatchKind ? { dispatchKind } : {}), ...(opts.priority !== undefined ? { priority: opts.priority as PlacementPriority } : {}), ...(opts.deadlineVersion !== undefined ? { deadlineVersion: opts.deadlineVersion } : {}), ...(opts.predecessor !== undefined ? { predecessors: opts.predecessor } : {}), ...(opts.ceoMinutes !== undefined ? { ceoMinutes: ceoMinutes(opts.ceoMinutes) } : {}), ...(opts.ceoDate !== undefined ? { ceoDate: opts.ceoDate } : {}), ...(opts.accelerator ? { accelerator: true } : {}) }, { allowDuplicateId: opts.allowDuplicateId });
851
+ warnChecklistTargetPaths({ title, refs: opts.ref, dispatchKind });
828
852
  if (json) console.log(JSON.stringify(data)); else console.log(`✅ ${id} 추가`);
829
853
  });
830
854
  withContext(checklist.command('set <id>').description('칸 상태·근거·담당·처분 갱신'))
831
855
  .option('--status <status>', 'green|yellow|red|done').option('--evidence <evidence>', '근거').option('--owner <owner>', '담당')
832
- .option('--disposition <disposition>', 'move|known-issue|block').option('--kind <kind>', 'screen = 다섯 화면 짝 칸 · 근거에 짝: PWA … · 데스크톱 … · 폴드 … · 아이폰 … · 아이패드 … 한 줄 · postpub = 발행 뒤 실측 칸 — 판 관문이 발행 전 판정에서 빼고 따로 센다')
856
+ .option('--disposition <disposition>', 'move|known-issue|block').option('--kind <kind>', 'screen = 다섯 화면 짝 칸 · 근거에 짝: PWA … · 데스크톱 … · 폴드 … · 아이폰 … · 아이패드 … 한 줄 · postpub = 발행 뒤 실측 칸 — 판 관문이 발행 전 판정에서 빼고 따로 센다 · code|ops|measure|decision|umbrella = 발사 분류')
833
857
  .option('--priority <priority>', 'P0|P1|P2').option('--deadline-version <v>', '마감 판').option('--predecessor <id...>', '선행 칸 id').option('--no-predecessor', '선행 칸 비우기(진짜 의존이 아니면 · CHECKLIST-PRED-CLEAR)')
834
858
  .option('--ceo-minutes <minutes>', '대표 손 분량(분)').option('--ceo-date <date>', '대표 손 날짜 YYYY-MM-DD')
835
859
  .option('--accelerator', '가속 등급 부여').option('--no-accelerator', '가속 등급 해제(기본은 없음)')
@@ -840,7 +864,8 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
840
864
  if (opts.disposition !== undefined && !['move', 'known-issue', 'block'].includes(opts.disposition)) throw new CliUserError(`잘못된 처분: ${opts.disposition}`, 'move|known-issue|block');
841
865
  if (opts.status === undefined && opts.evidence === undefined && opts.owner === undefined && opts.disposition === undefined && opts.kind === undefined && opts.priority === undefined && opts.deadlineVersion === undefined && opts.predecessor === undefined && opts.ceoMinutes === undefined && opts.ceoDate === undefined && opts.accelerator === undefined && opts.ref === undefined) throw new CliUserError('갱신할 칸을 지정하라', '--ref · --status · --evidence · --owner · --disposition · --kind · --priority · --deadline-version · --predecessor · --ceo-minutes · --ceo-date · --accelerator · --no-accelerator 중 하나');
842
866
  if (!mayWrite(cmd)) return;
843
- const data = setItem(version, id, { ...(opts.ref !== undefined ? { refs: opts.ref } : {}), ...(opts.status !== undefined ? { status: opts.status as ChecklistStatus } : {}), ...(opts.evidence !== undefined ? { evidence: opts.evidence } : {}), ...(opts.owner !== undefined ? { owner: opts.owner } : {}), ...(opts.disposition !== undefined ? { disposition: opts.disposition as ChecklistDisposition } : {}), ...(opts.kind !== undefined ? { kind: opts.kind as ChecklistKind } : {}), ...(opts.priority !== undefined ? { priority: opts.priority as PlacementPriority } : {}), ...(opts.deadlineVersion !== undefined ? { deadlineVersion: opts.deadlineVersion } : {}), ...(opts.predecessor !== undefined ? { predecessors: opts.predecessor === false ? [] : opts.predecessor } : {}), ...(opts.ceoMinutes !== undefined ? { ceoMinutes: ceoMinutes(opts.ceoMinutes) } : {}), ...(opts.ceoDate !== undefined ? { ceoDate: opts.ceoDate } : {}), ...(opts.accelerator !== undefined ? { accelerator: opts.accelerator ? true : null } : {}) }, process.env.ELANOUS_TRACK || 'cli');
867
+ const dispatchKind = opts.kind && !['screen', 'postpub'].includes(opts.kind) ? opts.kind as ChecklistDispatchKind : undefined;
868
+ const data = setItem(version, id, { ...(opts.ref !== undefined ? { refs: opts.ref } : {}), ...(opts.status !== undefined ? { status: opts.status as ChecklistStatus } : {}), ...(opts.evidence !== undefined ? { evidence: opts.evidence } : {}), ...(opts.owner !== undefined ? { owner: opts.owner } : {}), ...(opts.disposition !== undefined ? { disposition: opts.disposition as ChecklistDisposition } : {}), ...(opts.kind !== undefined && !dispatchKind ? { kind: opts.kind as ChecklistKind } : {}), ...(dispatchKind ? { dispatchKind } : {}), ...(opts.priority !== undefined ? { priority: opts.priority as PlacementPriority } : {}), ...(opts.deadlineVersion !== undefined ? { deadlineVersion: opts.deadlineVersion } : {}), ...(opts.predecessor !== undefined ? { predecessors: opts.predecessor === false ? [] : opts.predecessor } : {}), ...(opts.ceoMinutes !== undefined ? { ceoMinutes: ceoMinutes(opts.ceoMinutes) } : {}), ...(opts.ceoDate !== undefined ? { ceoDate: opts.ceoDate } : {}), ...(opts.accelerator !== undefined ? { accelerator: opts.accelerator ? true : null } : {}) }, process.env.ELANOUS_TRACK || 'cli');
844
869
  const item = data.items.find((entry) => entry.id === id);
845
870
  const why = item?.kind === 'screen' && item.status === 'green' ? parityGap(item.evidence) : null;
846
871
  if (why) {
@@ -891,6 +916,8 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
891
916
  if (!mayWrite(cmd)) return;
892
917
  const snapshot = listChecklist(version);
893
918
  features.retitle(id, title, actor(), snapshot.released, snapshot.dev);
919
+ const item = snapshot.items.find((entry) => entry.id === id);
920
+ warnChecklistTargetPaths({ title, evidence: item?.evidence, refs: item?.refs, dispatchKind: item?.dispatchKind });
894
921
  if (json) console.log(JSON.stringify(listChecklist(version))); else console.log(`✅ ${id} 제목 수정`);
895
922
  });
896
923
  const evidence = checklist.command('evidence').description('칸의 PR·커밋 근거');
@@ -1107,17 +1134,18 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1107
1134
  .description('가벼운 RC 점검 — 직전 판 컷(또는 --base) 이후 변경 범위 self gate ⊕ 상시 목록(release/light-rc-always.txt)을 원격 게이트 호스트에서 · 새 회귀(introduced>0)면 exit 1')
1108
1135
  .requiredOption('--version <v>', '점검할 판(x.y.z)')
1109
1136
  .option('--base <ref>', '비교 기준(기본: git merge-base origin/main origin/release/<원장 직전 판>)')
1137
+ .option('--head <ref>', '잴 커밋(기본: git fetch origin main 뒤 origin/main — 작업 트리 HEAD 가 아니다 · 다르면 분리 체크아웃에서 잰다)')
1110
1138
  .option('--remote <host>', '게이트 호스트(기본 config gateRemote.host)')
1111
1139
  .option('--local', '원격 대신 이 기계에서 돌린다(원격 자식이 이것으로 다시 불린다)')
1112
1140
  .option('--shards <n>', '시험 분할 수', '4')
1113
1141
  .option('--json', '결과 한 줄 JSON(stdout) · 사람 줄은 stderr')
1114
- .action(async (o: { version: string; base?: string; remote?: string; local?: boolean; shards: string; json?: boolean }) => {
1142
+ .action(async (o: { version: string; base?: string; head?: string; remote?: string; local?: boolean; shards: string; json?: boolean }) => {
1115
1143
  // The root strips `--local` from argv (remote-bookmark attach) before Commander sees it — same read as `self gate`.
1116
1144
  const local = !!o.local || process.argv.slice(2).includes('--local');
1117
1145
  await jsonAction(o.json, async (log) => {
1118
1146
  if (o.remote !== undefined && local) throw new Error('release light-rc: --remote and --local cannot be combined');
1119
1147
  const shards = Number(o.shards);
1120
- const result = await runLightRc(o.version, { base: o.base, remote: o.remote, local, shards, ledgerRoot: releaseRunDeps.ledgerRoot, log: (l) => console.error(l) }, lightRcDeps);
1148
+ const result = await runLightRc(o.version, { base: o.base, head: o.head, remote: o.remote, local, shards, ledgerRoot: releaseRunDeps.ledgerRoot, log: (l) => console.error(l) }, lightRcDeps);
1121
1149
  for (const line of formatLightRc(result)) log(line);
1122
1150
  return result;
1123
1151
  }, (r) => r.ok);
@@ -1126,7 +1154,8 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1126
1154
  .description('실패한 릴리스 런을 이어 달린다 — cut-branch --append 로 고친 release/<v> 새 끝을 version-release 기록에 반영(빨리감기만·상태 백업) 뒤 --from 노드부터')
1127
1155
  .requiredOption('--run <runId>', '실패한 release-loop 런 ID')
1128
1156
  .requiredOption('--from <node>', '다시 시작할 노드(예: gate)')
1129
- .option('--partial', 'GATE-PARTIAL — --from gate 에서 앞 게이트 뒤 바뀐 시험 파일 ⊕ 앞 실패 파일만 다시 돈다(시험·문서만 바뀐 경우 · 아니면 전체 게이트로)')
1157
+ .option('--partial', 'GATE-PARTIAL — --from gate 에서 바뀐 시험 ⊕ 앞 실패 ⊕ 바뀐 코드에 import 로 닿는 시험만 다시 돈다(끝이 움직인 --from gate 는 기본 · 의심이면 전체 게이트)')
1158
+ .option('--no-partial', 'GATE-REUSE-BY-DIFF 기본 부분 재검을 끄고 전체 게이트')
1130
1159
  .option('--waive <node>', '저장된 실패 노드 한 개를 면제(--from 은 그 노드 그대로)')
1131
1160
  .option('--reason <text>', '면제 사유 — 공개 알려진 문제에 들어갈 사용자 영향 설명')
1132
1161
  .option('--accepted-regressions <json>', '알려진 문제 추가 입력 JSON 배열 [{"id":"…","note":"…"}]')
@@ -1153,7 +1182,7 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1153
1182
  const override = result.state.inputOverrides?.at(-1);
1154
1183
  if (o.gateExecutor !== undefined && override) log(`⇄ gate 실행기 ${override.set.gateExecutor}${override.set.gateRemote ? ` @ ${override.set.gateRemote}` : ''} (런 입력에 기록 · 면제 아님)`);
1155
1184
  if (result.partial.requested) log(result.partial.applied
1156
- ? `◐ 부분 재검: ${result.partial.files}파일 · 나머지는 앞 게이트(${result.partial.priorCommit.slice(0, 12)}) 결과를 잇는다`
1185
+ ? `◐ 부분 재검${result.partial.auto ? '(기본)' : ''}: ${result.partial.files}파일${result.partial.closure ? ` (코드 닿음 ${result.partial.closure.reached} · 닫힘 불투명 ${result.partial.closure.opaque})` : ''} · 나머지는 앞 게이트(${result.partial.priorCommit.slice(0, 12)}) 결과를 잇는다`
1157
1186
  : `● 전체 게이트로: ${result.partial.reason}`);
1158
1187
  log(`${result.tip.changed ? `↻ ${result.tip.branch} ${result.tip.from.slice(0, 12)} → ${result.tip.to.slice(0, 12)} (백업 ${result.tip.backup})` : `· ${result.tip.branch} 끝 그대로 ${result.tip.to.slice(0, 12)}`} · ${o.from} 부터 → ${result.state.status}`);
1159
1188
  return { tip: result.tip, partial: result.partial, status: result.state.status, runId: result.state.runId,
@@ -1184,14 +1213,14 @@ export function registerReleaseCommands(program: Command, releaseRunDeps: Unatte
1184
1213
  const result = await autoStartScheduledRelease({
1185
1214
  windowMinutes: Number(o.windowMinutes), apply: o.apply, ledgerRoot: scheduleLedgerRoot(),
1186
1215
  readiness: (version, ledgerRoot, now) => releaseReadiness(version, { ledgerRoot, now: () => now, checklist: releaseRunDeps.checklist }),
1187
- launch: async (version) => {
1188
- const ran = await runAction({ version, ifReady: true, json: false }, log);
1216
+ launch: async (version, launchOptions) => {
1217
+ const ran = await runAction({ version, ifReady: true, publishAt: launchOptions?.publishAt, json: false }, log);
1189
1218
  if (ran && typeof ran === 'object' && ran.deferred) return ran;
1190
1219
  if (ran !== true) throw new Error(`release run 미시작 또는 실패: ${version}`);
1191
1220
  },
1192
1221
  });
1193
1222
  if (result.status === 'planned') log(`· 미리 보기 ${result.version} · 컷 ${result.cutAt} · 실행하려면 --apply`);
1194
- else if (result.status === 'started') log(`▶ 릴리스 시작 ${result.version} · 컷 ${result.cutAt}`);
1223
+ else if (result.status === 'started') log(`▶ 릴리스 시작 ${result.version} · 컷 ${result.cutAt}${result.publishAt ? ` · 발행 ${result.publishAt}` : ''}`);
1195
1224
  else if (result.status === 'skipped') log(`· 릴리스 연기 ${result.version} · ${result.reason}`);
1196
1225
  else log('· 선택할 컷 없음');
1197
1226
  return result;
@@ -2,6 +2,8 @@ import { closeSync, mkdirSync, openSync, rmSync, writeFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { debug } from '../debug/log.js';
4
4
  import { releaseLedgerRoot } from '../instance/resolve.js';
5
+ import { adviseLaunch, compareLaunchAdvice } from '../harness/launch-advice.js';
6
+ import type { QueuePool } from '../harness/harness-queue.js';
5
7
  import type { ReleaseReadiness } from '../../scripts/release-loop/release-readiness.js';
6
8
 
7
9
  export type ReleaseIfReadySkip = { skipped: true; reason: Exclude<ReleaseReadiness, { ready: true }>['reason']; detail: string };
@@ -12,6 +14,8 @@ export async function runReleaseIfReady<T>(version: string, deps: {
12
14
  ledgerRoot?: string;
13
15
  pid?: number;
14
16
  now?: () => Date;
17
+ advice?: typeof adviseLaunch;
18
+ pool?: () => QueuePool | undefined;
15
19
  }): Promise<ReleaseIfReadySkip | { skipped: false; result: T }> {
16
20
  const skip = (readiness: Exclude<ReleaseReadiness, { ready: true }>): ReleaseIfReadySkip => {
17
21
  const detail = readiness.reason === 'checklist-blocked'
@@ -40,6 +44,13 @@ export async function runReleaseIfReady<T>(version: string, deps: {
40
44
  const insideLock = await deps.readiness(version, { isPidAlive: () => false });
41
45
  if (!insideLock.ready) return skip(insideLock);
42
46
  debug.log('release-loop.readiness', 'ready', { version });
47
+ try {
48
+ const advice = (deps.advice ?? adviseLaunch)({ pool: deps.pool?.(), caller: 'release-run' });
49
+ const { kind } = compareLaunchAdvice(advice, 'launched');
50
+ debug.log('resource.advice', 'launch-advice', { caller: 'release-run', verdict: advice.verdict, why: advice.why, actual: 'launched', kind, version });
51
+ } catch {
52
+ // Shadow only: a throwing advice seam must never affect the launch decision or result.
53
+ }
43
54
  return { skipped: false, result: await deps.run() };
44
55
  } finally {
45
56
  closeSync(fd);
@@ -0,0 +1,48 @@
1
+ import type { Command } from 'commander';
2
+ import { debug } from '../debug/log.js';
3
+ import { TRAFFIC_SEATS, type TrafficResult } from '../loops/orchestrator/traffic.js';
4
+ import { observeLoopResources } from '../nexus/api/loop-resources.js';
5
+ import { writeStdoutJson } from './stdout-json.js';
6
+
7
+ /** 칸 제목은 여러 줄(«대상 경로:»·«신설:» …)이다 — 표의 한 칸에는 첫 줄만, 상한을 넘으면 «…» 로 자른 것을 표시한다. */
8
+ export const RESOURCE_TITLE_MAX_CHARS = 60;
9
+ export function oneLineTitle(title: string): string {
10
+ const first = (title.split(/\r?\n/).find((line) => line.trim()) ?? '').replace(/\s+/g, ' ').trim();
11
+ return first.length > RESOURCE_TITLE_MAX_CHARS ? `${first.slice(0, RESOURCE_TITLE_MAX_CHARS - 1)}…` : first;
12
+ }
13
+
14
+ /** Read-only CLI view of the same traffic snapshot returned by the Nexus resource GET. */
15
+ export function registerResourceCommands(program: Command, observe: () => TrafficResult = observeLoopResources): void {
16
+ program.command('resource').description('자리별 루프 자원 관측 (읽기 전용)')
17
+ .command('status').description('자리별 공급·다음 칸·임대 상태')
18
+ .option('--json', '관측 스냅샷 JSON 출력')
19
+ .action(async (opts: { json?: boolean }) => {
20
+ let resource: TrafficResult;
21
+ try { resource = observe(); }
22
+ catch (error) {
23
+ const reason = error instanceof Error ? error.message : String(error);
24
+ debug.log('resource.loop', 'status-read', { readStatus: 'unreadable', seats: null, cells: null });
25
+ process.exitCode = 1;
26
+ if (opts.json) await writeStdoutJson(JSON.stringify({ readStatus: 'unreadable', reason }) + '\n');
27
+ else console.error(`resource status: 못 읽음 — ${reason}`);
28
+ return;
29
+ }
30
+ debug.log('resource.loop', 'status-read', {
31
+ readStatus: 'ok', seats: resource.seats.length,
32
+ cells: resource.seats.filter(row => row.nextCell !== null).length,
33
+ });
34
+ if (opts.json) {
35
+ await writeStdoutJson(JSON.stringify({ resource, readStatus: 'ok' }) + '\n');
36
+ return;
37
+ }
38
+ console.log('자리\t쓰는 자리/공급\t다음 칸\t임대(빌림/빌려줌)\t대기 이유');
39
+ for (const seat of TRAFFIC_SEATS) {
40
+ const row = resource.seats.find(item => item.seat === seat);
41
+ if (!row) { console.log(`${seat}\t못 읽음\t못 읽음\t못 읽음\t자리 관측 없음`); continue; }
42
+ const cell = row.nextCell;
43
+ const reason = !cell ? '다음 칸 없음' : row.launchCap <= row.running ? '발사 자리 없음' : '다음 칸 대기';
44
+ console.log(`${seat}\t${row.running}/${row.cap}\t${cell ? `1 · ${cell.id} ${oneLineTitle(cell.title)}` : '0'}\t${row.borrowed}/${row.lent}\t${reason}`);
45
+ }
46
+ if (resource.unassigned > 0) console.log(`미배정\t${resource.unassigned}`);
47
+ });
48
+ }
@@ -1,8 +1,10 @@
1
1
  import { existsSync } from 'node:fs';
2
2
  import type { Command } from 'commander';
3
+ import { readRunExits } from '../harness/harness-incidents.js';
4
+ import { effectiveInstanceRoot } from '../instance/resolve.js';
3
5
  import { LogStore, logsDbPath } from '../mss/logging/log-store.js';
4
6
 
5
- type RetroFact = { store: string; at: string; category: string; event: string; kind: 'draft-birth' | 'draft-death' | 'stop-reason' | 'ta-outcome'; data: unknown };
7
+ type RetroFact = { store: string; at: string; category: string; event: string; kind: 'draft-birth' | 'draft-death' | 'stop-reason' | 'ta-outcome' | 'incident'; data: unknown };
6
8
 
7
9
  const FACT_EVENTS = new Map<string, RetroFact['kind']>([
8
10
  ['rework-blocked-draft-pr', 'draft-birth'],
@@ -21,7 +23,7 @@ export function parseRetroSince(value: string, now = Date.now()): number {
21
23
  return now - duration;
22
24
  }
23
25
 
24
- export function collectRetroFacts(sinceMs: number, targets: readonly { name: string; dbPath: string }[] = [{ name: 'current', dbPath: logsDbPath() }]): { facts: RetroFact[]; unavailable: string[] } {
26
+ export function collectRetroFacts(sinceMs: number, targets: readonly { name: string; dbPath: string }[] = [{ name: 'current', dbPath: logsDbPath() }], incidentRoot?: string): { facts: RetroFact[]; unavailable: string[] } {
25
27
  const facts: RetroFact[] = [];
26
28
  const unavailable: string[] = [];
27
29
  const untilMs = Date.now();
@@ -53,13 +55,20 @@ export function collectRetroFacts(sinceMs: number, targets: readonly { name: str
53
55
  } finally { store.close(); }
54
56
  } catch { unavailable.push(target.name); }
55
57
  }
58
+ try {
59
+ for (const row of readRunExits(incidentRoot ?? effectiveInstanceRoot())) {
60
+ if (Date.parse(row.at) < sinceMs) continue;
61
+ facts.push({ store: 'incidents', at: row.at, category: 'harness.incident', event: row.reason, kind: 'incident',
62
+ data: { runId: row.runId, seat: row.seat, entrance: row.entrance } });
63
+ }
64
+ } catch { unavailable.push('incidents'); }
56
65
  facts.sort((a, b) => b.at.localeCompare(a.at));
57
66
  return { facts, unavailable };
58
67
  }
59
68
 
60
69
  export function registerRetroCommands(program: Command): void {
61
70
  program.command('retro').description('Read-only retrospective facts from existing logs')
62
- .command('facts').description('Draft births/deaths, stop reasons and task-agent outcomes')
71
+ .command('facts').description('Draft births/deaths, stop reasons, task-agent outcomes and run incidents')
63
72
  .option('--since <duration>', 'Lookback duration', '24h')
64
73
  .option('--json', 'JSON output')
65
74
  .action((opts: { since: string; json?: boolean }) => {
@@ -0,0 +1,121 @@
1
+ import type { Command } from 'commander';
2
+ import { existsSync, lstatSync, readFileSync, statSync } from 'node:fs';
3
+ import { homedir } from 'node:os';
4
+ import { dirname, join, relative, sep } from 'node:path';
5
+ import { redactSecretText } from '../debug/log.js';
6
+ import { defaultMsgStorePath, readUnreadCount } from '../msg/msg-store.js';
7
+
8
+ export const SEAT_ROLES = ['OP', 'TC', 'MK', 'UX'] as const;
9
+ export type SeatRole = typeof SEAT_ROLES[number];
10
+
11
+ const MAX_FIELD = 160;
12
+ const MAX_ROWS = 12;
13
+ const clean = (value: unknown): string => redactSecretText(String(value ?? '').replace(/[\r\n\t]+/g, ' ').trim()).slice(0, MAX_FIELD);
14
+ const safeObject = (value: unknown, keys: readonly string[]): Record<string, string> => {
15
+ const source = value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
16
+ return Object.fromEntries(keys.filter(key => source[key] !== undefined && source[key] !== null).map(key => [key, clean(source[key])]));
17
+ };
18
+
19
+ function isRegularSeatPath(home: string, root: string, path: string): boolean {
20
+ const suffix = relative(root, path);
21
+ if (!suffix || suffix === '..' || suffix.startsWith(`..${sep}`) || suffix.startsWith(sep)) return false;
22
+ if (!lstatSync(home).isDirectory()) return false;
23
+ let parent = home;
24
+ for (const part of relative(home, dirname(path)).split(sep).filter(Boolean)) {
25
+ parent = join(parent, part);
26
+ if (!lstatSync(parent).isDirectory()) return false;
27
+ }
28
+ return lstatSync(path).isFile();
29
+ }
30
+
31
+ function metadata(home: string, root: string, path: string, kind: 'markdown' | 'tsv' | 'memory'): { source: string; updated: string; rows: string[]; reason?: string } {
32
+ if (!existsSync(path)) return { source: path, updated: '미상', rows: [], reason: '미관측: 파일 없음' };
33
+ try {
34
+ if (!isRegularSeatPath(home, root, path)) return { source: path, updated: '미상', rows: [], reason: '미관측: 일반 경로가 아님' };
35
+ const updated = statSync(path).mtime.toISOString();
36
+ const text = readFileSync(path, 'utf8').slice(0, 256_000);
37
+ let rows: string[] = [];
38
+ if (kind === 'tsv') {
39
+ const headers = (text.split(/\r?\n/, 1)[0] ?? '').split('\t');
40
+ const allowed = kind === 'tsv' && path.endsWith('harvest-claims.tsv') ? ['pr', 'claimer', 'at', 'status'] : ['at', 'what', 'then'];
41
+ const indexes = allowed.map(key => headers.indexOf(key));
42
+ rows = text.split(/\r?\n/).slice(1).filter(Boolean).slice(0, MAX_ROWS).map(line => {
43
+ const cells = line.split('\t');
44
+ return allowed.map((key, i) => indexes[i] < 0 ? '' : `${key}=${clean(cells[indexes[i]])}`).filter(Boolean).join(' · ');
45
+ }).filter(Boolean);
46
+ } else if (kind === 'memory') {
47
+ rows = text.split(/\r?\n/).filter(line => /^#{1,6}\s/.test(line)).slice(0, MAX_ROWS).map(line => clean(line.replace(/^#+\s*/, '')));
48
+ } else {
49
+ rows = text.split(/\r?\n/).filter(line => (/^#{1,6}\s/.test(line) || /^(?:[-*]\s*)?(?:from|발신|시각|at)\s*[::]/i.test(line)) && !/[`$;|<>]/.test(line)).slice(0, MAX_ROWS).map(line => {
50
+ const from = line.match(/^(?:[-*]\s*)?(?:from|발신)\s*[::]\s*(OP|TC|MK|UX)\b/i);
51
+ if (/^(?:[-*]\s*)?(?:from|발신)\s*[::]/i.test(line)) return from ? `From: ${from[1]!.toUpperCase()}` : '';
52
+ return clean(line.replace(/^#{1,6}\s*/, ''));
53
+ }).filter(Boolean);
54
+ }
55
+ return { source: path, updated, rows, ...(rows.length ? {} : { reason: '미관측: 허용된 메타데이터 없음' }) };
56
+ } catch {
57
+ return { source: path, updated: '미상', rows: [], reason: '미관측: 읽기 실패' };
58
+ }
59
+ }
60
+
61
+ function contextFacts(snapshot: unknown): string[] {
62
+ const root = snapshot !== null && typeof snapshot === 'object' && !Array.isArray(snapshot) ? snapshot as Record<string, unknown> : {};
63
+ const facts: string[] = [];
64
+ const sourceFacts = Array.isArray(root.facts) ? root.facts as unknown[] : [];
65
+ for (const item of sourceFacts.slice(0, MAX_ROWS)) {
66
+ const value = item !== null && typeof item === 'object' && !Array.isArray(item) ? item as Record<string, unknown> : {};
67
+ const keys = value.kind === 'cell' ? ['id', 'status', 'owner', 'version', 'source']
68
+ : value.kind === 'seat' ? ['seat', 'at', 'status', 'id', 'source']
69
+ : value.kind === 'run' ? ['phase', 'elapsed', 'source'] : [];
70
+ const values = safeObject(value, keys);
71
+ if (Object.keys(values).length) facts.push(`${clean(value.kind)}: ${Object.entries(values).map(([k, v]) => `${k}=${v}`).join(' · ')}`);
72
+ }
73
+ const sourceEvents = Array.isArray(root.events) ? root.events as unknown[] : [];
74
+ for (const item of sourceEvents.slice(0, MAX_ROWS)) {
75
+ const values = safeObject(item, ['at', 'kind', 'source', 'summary']);
76
+ if (Object.keys(values).length) facts.push(`event: ${Object.entries(values).map(([k, v]) => `${k}=${v}`).join(' · ')}`);
77
+ }
78
+ return facts.slice(0, MAX_ROWS);
79
+ }
80
+
81
+ export function renderSeatBootCard(seat: SeatRole, sections: ReadonlyArray<{ title: string; source: string; updated: string; rows: readonly string[]; reason?: string }>, facts: readonly string[], contextUpdated = '미상'): string {
82
+ const out = [`# ${seat} 자리 부팅 카드`, '', '## 현재 구조화 관측', '출처: elanous://context-now', `갱신: ${clean(contextUpdated)}`, ...(facts.length ? facts.map(row => `- ${clean(row)}`) : ['- 미관측: contextNow 구조화 facts/events 없음'])];
83
+ for (const section of sections) out.push('', `## ${section.title}`, `출처: ${clean(section.source)}`, `갱신: ${clean(section.updated)}`, ...(section.rows.length ? section.rows.map(row => `- ${clean(row)}`) : [`- ${clean(section.reason ?? '미관측')}`]));
84
+ return out.join('\n');
85
+ }
86
+
87
+ export function registerSeatBootCommands(command: Command, options: { home?: () => string; contextNow?: () => unknown; msgPath?: () => string } = {}): void {
88
+ command.command('boot <seat>').description('현재 자리 카드 — 허용된 메타데이터만 읽기 전용 표시')
89
+ .action(async (rawSeat: string) => {
90
+ const seat = rawSeat.toUpperCase();
91
+ if (!(SEAT_ROLES as readonly string[]).includes(seat)) { console.error(`seat boot: unknown seat ${rawSeat} (OP|TC|MK|UX)`); process.exitCode = 2; return; }
92
+ const home = options.home?.() ?? homedir();
93
+ const root = join(home, 'elanous-hq', 'seat-state');
94
+ let facts: string[] = [];
95
+ let contextUpdated = '미상';
96
+ try {
97
+ const snapshot = options.contextNow ? options.contextNow() : await (async () => {
98
+ const mod = await import('../context-bus/context-now.js');
99
+ return (mod.contextNow as unknown as (options: { audience: string }) => unknown)({ audience: 'operator' });
100
+ })();
101
+ const context = snapshot !== null && typeof snapshot === 'object' ? snapshot as Record<string, unknown> : {};
102
+ contextUpdated = typeof context.at === 'string' ? clean(context.at) : '시각 미관측';
103
+ facts = contextFacts(snapshot);
104
+ } catch { facts = []; contextUpdated = '미관측: contextNow 조회 실패'; }
105
+ const seatDir = join(root, seat);
106
+ const msgPath = options.msgPath?.() ?? defaultMsgStorePath();
107
+ let unread: number | null = null;
108
+ try { unread = readUnreadCount(seat, msgPath); }
109
+ catch { /* unavailable is not a measured zero */ }
110
+ const sections = [
111
+ { title: 'msg 원장', source: msgPath, updated: unread === null ? '미상' : new Date().toISOString(), rows: [`안 읽은 msg ${unread ?? '미관측'} (${seat})`] },
112
+ { title: 'HANDOFF', ...metadata(home, root, join(seatDir, 'HANDOFF.md'), 'markdown') },
113
+ { title: 'inbox', ...metadata(home, root, join(seatDir, 'inbox.md'), 'markdown') },
114
+ { title: '수확 주장', ...metadata(home, root, join(seatDir, 'harvest-claims.tsv'), 'tsv') },
115
+ { title: '예약', ...metadata(home, root, join(seatDir, 'scheduled.tsv'), 'tsv') },
116
+ { title: '공통 메모리 색인', ...metadata(home, root, join(root, 'memory', 'MEMORY.md'), 'memory') },
117
+ ];
118
+ console.log(renderSeatBootCard(seat as SeatRole, sections, facts, contextUpdated));
119
+ });
120
+ }
121
+
@@ -2,6 +2,7 @@ import type { Command } from 'commander';
2
2
  import { effectiveInstanceRoot } from '../instance/resolve.js';
3
3
  import { hqCliWriteAllowed, type HqDeps } from '../hq/hq.js';
4
4
  import { isIsolatedLedgerWriteRoot } from '../hq/ledger-write-target.js';
5
+ import { appendDuty, listDuties, type DutyStatus } from '../seat-loop/duty-ledger.js';
5
6
  import { closeSeatRequests, listSeatRequests, type SeatRequestStatus } from '../seat-dispatch/seat-request-ledger.js';
6
7
 
7
8
  function duration(value: string): number {
@@ -49,4 +50,28 @@ export function registerSeatRequestsCommands(seat: Command, deps: { root?: () =>
49
50
  for (const row of rows) console.log(`${opts.dryRun ? 'would close' : 'closed'} ${row.key} ${row.status}: ${row.reason}`);
50
51
  } catch (error) { console.error(`seat requests close: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
51
52
  });
53
+ const duty = seat.command('duty').description('자리 임무 원장 기록·조회');
54
+ duty.command('add <seat> <duty>').description('임무 한 줄을 원장에 덧붙임')
55
+ .requiredOption('--source <source>', '임무의 출처')
56
+ .option('--ref <ref>', '근거 참조')
57
+ .option('--status <status>', 'standing|done|missed', 'standing')
58
+ .action((seatId: string, dutyText: string, opts: { source: string; ref?: string; status: string }) => {
59
+ try {
60
+ const row = appendDuty((deps.root ?? effectiveInstanceRoot)(), {
61
+ seat: seatId, duty: dutyText, source: opts.source, status: opts.status as DutyStatus,
62
+ ...(opts.ref === undefined ? {} : { ref: opts.ref }),
63
+ }, deps.now);
64
+ console.log(`added ${row.seat} ${row.status}: ${row.duty}`);
65
+ } catch (error) { console.error(`seat duty add: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
66
+ });
67
+ duty.command('ls').description('임무 원장 조회 (at 순서)')
68
+ .option('--seat <seat>', '자리 ID')
69
+ .option('--json', 'JSON 출력')
70
+ .action((opts: { seat?: string; json?: boolean }) => {
71
+ try {
72
+ const rows = listDuties((deps.root ?? effectiveInstanceRoot)(), { seat: opts.seat });
73
+ if (opts.json) console.log(JSON.stringify(rows));
74
+ else for (const row of rows) console.log(`${row.at} ${row.seat} ${row.status} ${row.duty} (${row.source}${row.ref ? ` ${row.ref}` : ''})`);
75
+ } catch (error) { console.error(`seat duty ls: ${error instanceof Error ? error.message : String(error)}`); process.exitCode = 1; }
76
+ });
52
77
  }
@@ -0,0 +1,140 @@
1
+ import type { Command } from 'commander';
2
+ import { Database } from 'bun:sqlite';
3
+ import { redactSecretText } from '../debug/log.js';
4
+ import { openSurfaceEventsDb, querySurfaceUtterances, surfaceEventsDbPath, type SurfaceEventRow } from '../domains/surface-events.js';
5
+ import { injectUtterance, type UtteranceInput } from '../domains/self-awareness.js';
6
+ import { writeStdoutJson } from './stdout-json.js';
7
+
8
+ const PAGE_SIZE = 50;
9
+ type UtteranceOrigin = 'human' | 'agent' | 'unknown';
10
+
11
+ function refsOf(raw: string | null): Record<string, unknown> {
12
+ if (!raw) return {};
13
+ try {
14
+ const value: unknown = JSON.parse(raw);
15
+ return value !== null && typeof value === 'object' && !Array.isArray(value) ? value as Record<string, unknown> : {};
16
+ } catch { return {}; }
17
+ }
18
+
19
+ function redact(value: string): string {
20
+ return redactSecretText(value)
21
+ .replace(/[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}/gi, '[REDACTED_EMAIL]')
22
+ .replace(/(https?:\/\/[^\s?#]+)\?[^\s#]*/gi, '$1?[REDACTED_QUERY]');
23
+ }
24
+
25
+ function isAutomatic(row: SurfaceEventRow): boolean {
26
+ const refs = refsOf(row.refs);
27
+ if (row.surface === 'coord:channel' || row.surface === 'coord:seat' || refs.origin === 'coord:channel') return true;
28
+ const seatSource = typeof refs.origin === 'string' && /^(?:seat|seat-notice|notification|wake|coord:seat)$/i.test(refs.origin);
29
+ if (seatSource) return true;
30
+ if (refs.origin === 'observer' || refs.origin === 'observer-generated' || /observer-generated/i.test(row.tags ?? '')) return true;
31
+ if (row.kind === 'qna' && /^(?:telegram|discord)$/i.test(row.surface)) return false;
32
+ if (refs.origin === 'human' || refs.origin === 'user') return false;
33
+ return false;
34
+ }
35
+
36
+ function originOf(row: SurfaceEventRow): UtteranceOrigin {
37
+ if (row.direction !== 'inbound') return 'unknown';
38
+ const refs = refsOf(row.refs);
39
+ if (refs.utteranceOrigin === 'human' || refs.utteranceOrigin === 'agent') return refs.utteranceOrigin;
40
+ const explicit = refs.origin;
41
+ if (typeof explicit === 'string') {
42
+ if (/^(?:human|user|tui|pwa|telegram|discord|cli)$/i.test(explicit)) return 'human';
43
+ if (/^(?:claude-code|codex|gemini|agent|external:)/i.test(explicit)) return 'agent';
44
+ }
45
+ // recordInboundTurn marks its recorder as elanous-self; on chat Q&A the speaker is the human.
46
+ if (row.kind === 'qna' && /^(?:telegram|discord)$/i.test(row.surface)) return 'human';
47
+ if (explicit === 'elanous-self') return 'agent';
48
+ if (/^ext:/i.test(row.surface)) return 'agent';
49
+ if (/^(?:cli|tui|pwa|telegram|discord|ipad|watch)$/i.test(row.surface)) return 'human';
50
+ return 'unknown';
51
+ }
52
+
53
+ function utteranceText(row: SurfaceEventRow): { text: string; extract: 'direct' | 'qna' | 'ambiguous' | 'summary'; truncated: boolean; truncationEvidence: 'cap-reached' | 'over-cap' | null; possibleLoss: boolean } {
54
+ if (row.kind !== 'qna') return { text: row.text, extract: 'direct', truncated: false, truncationEvidence: null, possibleLoss: false };
55
+ const firstAnswer = row.text.startsWith('Q: ') ? row.text.indexOf('\nA: ', 3) : -1;
56
+ if (firstAnswer >= 0) {
57
+ const ambiguous = row.text.indexOf('\nQ: ', 3) >= 0 || row.text.indexOf('\nA: ', firstAnswer + 4) >= 0;
58
+ return { text: row.text.slice(3, firstAnswer), extract: ambiguous ? 'ambiguous' : 'qna', truncated: false, truncationEvidence: null, possibleLoss: ambiguous };
59
+ }
60
+ const summary = row.summary ?? '';
61
+ return { text: summary.slice(0, 150), extract: 'summary', truncated: summary.length > 150, truncationEvidence: summary.length > 150 ? 'over-cap' : summary.length === 150 ? 'cap-reached' : null, possibleLoss: false };
62
+ }
63
+
64
+ function validDate(value: string, name: string): string {
65
+ const date = new Date(value);
66
+ if (!value || !Number.isFinite(date.getTime()) || !/^\d{4}-\d\d-\d\d(?:T.*)?$/.test(value)) throw new Error(`--${name} must be a valid ISO date/time`);
67
+ return date.toISOString();
68
+ }
69
+
70
+ interface SelfUtterancesOptions {
71
+ from: string; to: string; surface?: string; origin?: UtteranceOrigin; page?: string; json?: boolean;
72
+ }
73
+
74
+ export function collectSelfUtterances(opts: SelfUtterancesOptions, db: ReturnType<typeof openSurfaceEventsDb>) {
75
+ const from = validDate(opts.from, 'from');
76
+ const to = validDate(opts.to, 'to');
77
+ if (from >= to) throw new Error('--from must be earlier than --to');
78
+ const page = opts.page === undefined ? 1 : Number(opts.page);
79
+ if (!Number.isSafeInteger(page) || page < 1) throw new Error('--page must be a positive integer');
80
+ const rows = querySurfaceUtterances(db, { from, to, ...(opts.surface ? { surface: opts.surface } : {}) });
81
+ let excludedAutomatic = 0;
82
+ let excludedByOrigin = 0;
83
+ let ambiguous = 0;
84
+ let truncated = 0;
85
+ let capReached = 0;
86
+ let possibleLoss = 0;
87
+ let excludedUnextractable = 0;
88
+ const utterances = rows.flatMap((row) => {
89
+ if (isAutomatic(row)) { excludedAutomatic += 1; return []; }
90
+ const origin = originOf(row);
91
+ if (opts.origin && origin !== opts.origin) { excludedByOrigin += 1; return []; }
92
+ const refs = refsOf(row.refs);
93
+ const cwd = typeof refs.cwd === 'string' && refs.cwd.length > 0 && !/[\u0000-\u001f\u007f]/.test(refs.cwd) ? redact(refs.cwd) : null;
94
+ const extracted = utteranceText(row);
95
+ if (row.kind === 'qna' && extracted.text.trim() === '') { excludedUnextractable += 1; return []; }
96
+ if (extracted.extract === 'ambiguous') ambiguous += 1;
97
+ if (extracted.truncated) truncated += 1;
98
+ if (extracted.truncationEvidence === 'cap-reached') capReached += 1;
99
+ if (extracted.possibleLoss) possibleLoss += 1;
100
+ return [{ id: redact(row.id), ts: redact(row.ts), surface: redact(row.surface), session: row.session_id ? redact(row.session_id) : null, cwd, origin, source: typeof refs.origin === 'string' ? redact(refs.origin) : 'unrecorded', text: redact(extracted.text), extract: extracted.extract, truncated: extracted.truncated, truncationEvidence: extracted.truncationEvidence, possibleLoss: extracted.possibleLoss }];
101
+ });
102
+ const total = utterances.length;
103
+ const start = (page - 1) * PAGE_SIZE;
104
+ return { source: 'surface_events.events (read-only)', filters: { from, to, surface: opts.surface ?? null, origin: opts.origin ?? null, automatic: 'excluded' }, counts: { matched: total, excludedAutomatic, excludedByOrigin, excludedUnextractable, ambiguous, truncated, capReached, possibleLoss }, page: { number: page, size: PAGE_SIZE, total, hasNext: start + PAGE_SIZE < total }, utterances: utterances.slice(start, start + PAGE_SIZE) };
105
+ }
106
+
107
+ export function recordSelfUtterance(input: UtteranceInput & { utteranceOrigin?: 'human' | 'agent' }, db?: Database): { eventId: string } {
108
+ const store = db ?? openSurfaceEventsDb();
109
+ try {
110
+ const result = injectUtterance(input, store);
111
+ if (input.utteranceOrigin === 'human') {
112
+ store.prepare("UPDATE events SET refs = json_set(refs, '$.utteranceOrigin', 'human') WHERE id = ?").run(result.eventId);
113
+ }
114
+ return result;
115
+ } finally { if (!db) store.close(); }
116
+ }
117
+
118
+ export function registerSelfUtterancesCommand(selfCmd: Command): void {
119
+ selfCmd.command('utterances').description('Read paginated original utterances from surface_events (read-only)')
120
+ .requiredOption('--from <ISO>', 'Inclusive ISO date/time')
121
+ .requiredOption('--to <ISO>', 'Exclusive ISO date/time')
122
+ .option('--surface <surface>', 'Filter by surface')
123
+ .option('--origin <origin>', 'Filter by known origin: human|agent')
124
+ .option('--page <page>', 'One-based page number', '1')
125
+ .option('--json', 'Emit JSON')
126
+ .action(async (opts: SelfUtterancesOptions) => {
127
+ if (opts.origin && opts.origin !== 'human' && opts.origin !== 'agent') throw new Error('--origin must be human or agent');
128
+ const db = new Database(surfaceEventsDbPath(), { readonly: true });
129
+ try {
130
+ const result = collectSelfUtterances(opts, db);
131
+ if (opts.json) { await writeStdoutJson(JSON.stringify(result, null, 2) + '\n'); return; }
132
+ console.log(`source=${result.source} matched=${result.counts.matched} excludedAutomatic=${result.counts.excludedAutomatic} excludedByOrigin=${result.counts.excludedByOrigin} excludedUnextractable=${result.counts.excludedUnextractable} page=${result.page.number} size=${result.page.size} hasNext=${result.page.hasNext}`);
133
+ console.log(`filters=${JSON.stringify(result.filters)}`);
134
+ for (const item of result.utterances) console.log(JSON.stringify(item));
135
+ console.log(`ambiguous=${result.counts.ambiguous} truncated=${result.counts.truncated} cap-reached=${result.counts.capReached} possibleLoss=${result.counts.possibleLoss}`);
136
+ } finally { db.close(); }
137
+ });
138
+ }
139
+
140
+ export { PAGE_SIZE };