elanous 0.2.29 → 0.2.32

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 (775) 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/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{058a98ba.7eb28d5e6dc03565.js → 0bb0ff36.b8d418980951e5ba.js} +7 -7
  5. package/apps/pwa/out/_next/static/chunks/1034-8b639cee57b8e4a8.js +1 -0
  6. package/apps/pwa/out/_next/static/chunks/1085-6c2d35526f11f840.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1220.1ff7d5cdc34b1ae5.js +27 -0
  8. package/apps/pwa/out/_next/static/chunks/1247.5884ec81b39fe2e7.js +287 -0
  9. package/apps/pwa/out/_next/static/chunks/1302.87681521a7a4661e.js +62 -0
  10. package/apps/pwa/out/_next/static/chunks/1324-59dae3002413623b.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/{6013-2f769370d8b4c2c6.js → 1335-6731f392c35216eb.js} +3 -3
  12. package/apps/pwa/out/_next/static/chunks/1343-f40b5870ac1eda5a.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/146-b6cd56be11dda017.js +1 -0
  14. package/apps/pwa/out/_next/static/chunks/{8332.6f0f49df772e163b.js → 1654.32de4b324981a188.js} +1 -1
  15. package/apps/pwa/out/_next/static/chunks/1834-98b64172bc1efe77.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/1849.1ce38efa6c527d9a.js +149 -0
  17. package/apps/pwa/out/_next/static/chunks/{8795.32573a185af18c7b.js → 1913.7cc6fb6055b1ed3f.js} +2 -2
  18. package/apps/pwa/out/_next/static/chunks/{419.736c0d6f426249a7.js → 2001.6c7e0fd02190886c.js} +1 -1
  19. package/apps/pwa/out/_next/static/chunks/2030.41fae98c7e907304.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/2099-08b2f2dfba742c9b.js +1 -0
  21. package/apps/pwa/out/_next/static/chunks/2112-e4efc21a6505d5bc.js +1 -0
  22. package/apps/pwa/out/_next/static/chunks/2134.ecee03a550ee7250.js +1 -0
  23. package/apps/pwa/out/_next/static/chunks/{6767.1fcfc9b8be83975f.js → 2213.2ccbada92c33ea0f.js} +16 -16
  24. package/apps/pwa/out/_next/static/chunks/2236.66061832181cb745.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2422.b0bd272e7020d7e6.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/2534.e85ae21ad0dac829.js +1 -0
  27. package/apps/pwa/out/_next/static/chunks/{4759.1f76713aefb87db5.js → 2871.0bca6137343b3f76.js} +1 -1
  28. package/apps/pwa/out/_next/static/chunks/{6776.06ff1e3b464cc607.js → 2898.fd781bc7cf01a7b7.js} +1 -1
  29. package/apps/pwa/out/_next/static/chunks/{1782-59db1b5aa06df38a.js → 2940-619bfd8ef337c611.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/{8471.8d2a8c74f09c36ff.js → 2985.39ccdecd36848b12.js} +4 -4
  31. package/apps/pwa/out/_next/static/chunks/3040.92ff9ffc9f971cb9.js +115 -0
  32. package/apps/pwa/out/_next/static/chunks/3144.6861096c7b4edef7.js +64 -0
  33. package/apps/pwa/out/_next/static/chunks/{bc324b7c.02a09dd93f6a399b.js → 3267c0e6.d34854e7b3984a6e.js} +1 -1
  34. package/apps/pwa/out/_next/static/chunks/3278.2e5d15b53a4091c8.js +2 -0
  35. package/apps/pwa/out/_next/static/chunks/{7725-4f83d5541fbdb81b.js → 3541-ce3a5424ed5ad7f1.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3583.a05e88cc8d594628.js +1 -0
  37. package/apps/pwa/out/_next/static/chunks/3771.e928edf2867d28c0.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3902.e1e71aaac850a045.js +34 -0
  39. package/apps/pwa/out/_next/static/chunks/4063-03284b5de59965f3.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/{46bd8bea.2f4b4099172fcdb7.js → 409f1e57.d0649fc47691ebfe.js} +1 -1
  41. package/apps/pwa/out/_next/static/chunks/4111.2bfedbb233ad206b.js +1 -0
  42. package/apps/pwa/out/_next/static/chunks/{1142.65d002789ab3af7d.js → 4174.92ed04922709ac9e.js} +2 -2
  43. package/apps/pwa/out/_next/static/chunks/4300-c7ec4eeabbb5f3f7.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4483.646d5065199e1b55.js +36 -0
  45. package/apps/pwa/out/_next/static/chunks/4519.28199ff26b2fd80d.js +1 -0
  46. package/apps/pwa/out/_next/static/chunks/4581.ef2443578054544f.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4608-8d894e9cbe4f08bf.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4639.ae48a01d1bb50a93.js +286 -0
  49. package/apps/pwa/out/_next/static/chunks/4739.08742ac668aada67.js +77 -0
  50. package/apps/pwa/out/_next/static/chunks/4745.67d6f99c245af3f7.js +226 -0
  51. package/apps/pwa/out/_next/static/chunks/4882-16cef71d6a1a32be.js +1 -0
  52. package/apps/pwa/out/_next/static/chunks/4999.c064a4000c2a9e94.js +79 -0
  53. package/apps/pwa/out/_next/static/chunks/5173-233188df2f42c626.js +1 -0
  54. package/apps/pwa/out/_next/static/chunks/5260-69f35419bca263e7.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5272.b92d1b72a15c25fe.js +1 -0
  56. package/apps/pwa/out/_next/static/chunks/5304.04d24756f242a094.js +148 -0
  57. package/apps/pwa/out/_next/static/chunks/5307.60f2209e809bd627.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/5415-997980f828667736.js +1 -0
  59. package/apps/pwa/out/_next/static/chunks/{3396-97b97928c49190c9.js → 5458-16cd7a2b51b74c8c.js} +1 -1
  60. package/apps/pwa/out/_next/static/chunks/{3403.7199205e65124486.js → 5525.86debf231e181813.js} +1 -1
  61. package/apps/pwa/out/_next/static/chunks/{9143.ff14585db1d275ff.js → 5543.a438b8ab5a13ea47.js} +1 -1
  62. package/apps/pwa/out/_next/static/chunks/5572-42c9084f27ca761e.js +1 -0
  63. package/apps/pwa/out/_next/static/chunks/5661-80470aac963d9f36.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/5723.421338408b5c30c4.js +74 -0
  65. package/apps/pwa/out/_next/static/chunks/5809.64c3664267c50bce.js +1 -0
  66. package/apps/pwa/out/_next/static/chunks/6000.64bc21ac8627f2f5.js +94 -0
  67. package/apps/pwa/out/_next/static/chunks/6013.39459b9c68eabf5f.js +1 -0
  68. package/apps/pwa/out/_next/static/chunks/607-06466dff012b03ef.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/{8398.73a19b39715eda04.js → 6092.a7f99e68b188ca66.js} +1 -1
  70. package/apps/pwa/out/_next/static/chunks/60fb96c9.360b01d8d4927b7b.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/{5591.a35e7a217734a8b9.js → 6157.0c9af021de4fb31b.js} +2 -2
  72. package/apps/pwa/out/_next/static/chunks/6192.a190b989b81e9743.js +1 -0
  73. package/apps/pwa/out/_next/static/chunks/6323.8672b4817a306928.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/{7375.050ea0d72968e49f.js → 6433.fc573af22bbc9ab7.js} +17 -17
  75. package/apps/pwa/out/_next/static/chunks/6444.7d1fdcb9b09ae71c.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6517.4147878ac06d584d.js +90 -0
  77. package/apps/pwa/out/_next/static/chunks/6532.e34302010b2f0b68.js +32 -0
  78. package/apps/pwa/out/_next/static/chunks/6544cb48.a87fe20ddf137be2.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6546.74bc4ed82f19016d.js +104 -0
  80. package/apps/pwa/out/_next/static/chunks/6684-e7523ce7c2fad075.js +1 -0
  81. package/apps/pwa/out/_next/static/chunks/6726.ebdc82feb161431e.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/6739.00fb6f892e5e392b.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/6745.934c4921bf15513a.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/6767.ea607cf0c20a25af.js +24 -0
  85. package/apps/pwa/out/_next/static/chunks/6843.67bfd020da0926c5.js +93 -0
  86. package/apps/pwa/out/_next/static/chunks/69-0a2c8209c6d4a158.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/6948.1062d4594652b5bf.js +1 -0
  88. package/apps/pwa/out/_next/static/chunks/7138-eaf841fc1dc03463.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7174-cda29ee13d7790e7.js +1 -0
  90. package/apps/pwa/out/_next/static/chunks/7304-3c07583f4e405f4f.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7371.80c05c653b08e907.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7391.ebae168025c91b6a.js +1 -0
  93. package/apps/pwa/out/_next/static/chunks/{1852.7f7b53991fcb99ef.js → 7502.ccd5b8065545edd0.js} +2 -2
  94. package/apps/pwa/out/_next/static/chunks/7557.e325503a090a4310.js +8 -0
  95. package/apps/pwa/out/_next/static/chunks/7569-9ce9432c7f10989f.js +1 -0
  96. package/apps/pwa/out/_next/static/chunks/{6534.1ab00f370db7b105.js → 7862.30a8d6482bb238eb.js} +1 -1
  97. package/apps/pwa/out/_next/static/chunks/7886-55854585fadeded1.js +1 -0
  98. package/apps/pwa/out/_next/static/chunks/7947-d0759430f8042240.js +1 -0
  99. package/apps/pwa/out/_next/static/chunks/{285adb1a.5654e605dddf86d2.js → 7a1887c4.f36b88fba31da8fd.js} +1 -1
  100. package/apps/pwa/out/_next/static/chunks/8018.a32663f04a6fc5f9.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8097-9530c03bcc550f02.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8215-1661812b6e9ad71f.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8260-19c921a51ca8ec3e.js +1 -0
  104. package/apps/pwa/out/_next/static/chunks/8440.3a5cf5c85aa76db8.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/8519-4599be2249161e68.js +1 -0
  106. package/apps/pwa/out/_next/static/chunks/8547.b028b90c5c01ace6.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8587-cbe02a953a7f4990.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/877-2b977259c4b15655.js +1 -0
  109. package/apps/pwa/out/_next/static/chunks/9002.e5658224e3dc1b6f.js +24 -0
  110. package/apps/pwa/out/_next/static/chunks/9019-0a4b40c50c7314fb.js +1 -0
  111. package/apps/pwa/out/_next/static/chunks/{1516.dfaceff3fd2d0e0d.js → 9138.b6e80031afb1d973.js} +1 -1
  112. package/apps/pwa/out/_next/static/chunks/9188-d36e4fc869ddc166.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/{9907.49be0fcadaf214b5.js → 9221.7d22eaf353a2d4e7.js} +1 -1
  114. package/apps/pwa/out/_next/static/chunks/9230.44f5039e796e4ab4.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/{8767-2f6a634f5abeaa01.js → 9279-d28c5b7754d010ae.js} +1 -1
  116. package/apps/pwa/out/_next/static/chunks/939.336acce73e98482c.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/{3160-95c96f4d2a21dd26.js → 9398-6aed28f0a96d0d6f.js} +1 -1
  118. package/apps/pwa/out/_next/static/chunks/9407.e49124dedf0f5e72.js +1 -0
  119. package/apps/pwa/out/_next/static/chunks/9610.c07cce4bfcc14ed7.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9667-ce78c2ce91050ff9.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{328bb3ab-6628a1114fe3fb3b.js → 997ce8a5-2ad501927003b41b.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/{6853.cc5174a9dee59593.js → 9989.3694300e5f000b14.js} +1 -1
  123. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-339fabb3499da0e1.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/approvals/page-504204b58c82c253.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a9717a67c2eecbaf.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/board/page-5c9ec30aee62dfbf.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/botlab/page-584191533721fa16.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/bots/page-73c4b4bb3ac7ab5f.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/ceo/page-c0f1ca371f710b06.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/chat/page-46430d45a9e04eac.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/consult/page-3b2ebf1dc64ff0be.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/control/page-a27b1e5a0d1b308f.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/decisions/page-25654b82094f7d22.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/design-check/page-8ea49a4c6dd2c6e7.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/editor/page-ce5113aefea0a8d1.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/exec/page-0e5a41fac1c75396.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/field/page-31aaf1ed37c6df9a.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/healthz/route-339fabb3499da0e1.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/inside/page-3dcc1fa411e1f4e0.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/intake/page-c69247e7134d329d.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/layout-66dc5cd3a0999abe.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live/page-26ff7ff651a7217d.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/live-run/page-617b3976981efa96.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/loops/page-d256f5d5d9552823.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/market/page-ce8f1907b8a6101c.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-33e182a316263116.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/morning/page-32866485913d6a04.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/not-found-7607cca9b84950c6.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eeab86176b03dc3b.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5b93dbae3432b996.js +1 -0
  151. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-77a6cb90a9cf2b10.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-f47e768b5b242b5a.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/outputs/page-eb41aa3367fc2505.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/page-4d13ab0b8a267e3f.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/reflection/page-84dad32ff0fc0831.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-95306f892aa2d0ee.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/sessions/page-940fb6c217f6b470.js +1 -0
  158. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-8c66a3b24a745630.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/settings/page-7b675dfd35c36fc9.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8bd0d3cf7665bcfc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/layout-339fabb3499da0e1.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/setup/{page-29900ed0011b2c83.js → page-c219f2ed171131be.js} +1 -1
  163. package/apps/pwa/out/_next/static/chunks/app/share/page-40f8fa21bdae955b.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/showroom/page-468f8313e4f1fbd9.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/tasks/page-7bbb8fa353a246c4.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/term/page-04d00ae9b0890349.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/today/page-4214b855d9233ea8.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/trace/page-936752c7aa58762e.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/vault/page-ec052ad359df1797.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-8305570551091338.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workflows/page-fad650e4793adb65.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/workspace/page-d90e64743826e1d8.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a16bcfd49af86a32.js +1 -0
  174. package/apps/pwa/out/_next/static/chunks/{425cfc4d.fb91158e3971c39f.js → b313b242.cb1265eea908db61.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/e5012ffe.f727e23c231f4342.js +122 -0
  176. package/apps/pwa/out/_next/static/chunks/ea695e3c-1f1d70d740cf3031.js +1 -0
  177. package/apps/pwa/out/_next/static/chunks/ebc7d829.264a0bcb6c750b50.js +1 -0
  178. package/apps/pwa/out/_next/static/chunks/framework-906af9bd029e166c.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-a24847f9f684d469.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-7bdcd8aa7c8397d3.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-6ba46a5066fc226d.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-a8dc6d07591f2a25.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-f13df28c15c55eee.js +1 -0
  184. package/apps/pwa/out/_next/static/css/b5d88eba78a3d7bf.css +1 -0
  185. package/apps/pwa/out/approvals/index.html +1 -1
  186. package/apps/pwa/out/approvals/index.txt +23 -23
  187. package/apps/pwa/out/autopilot/index.html +1 -1
  188. package/apps/pwa/out/autopilot/index.txt +23 -23
  189. package/apps/pwa/out/board/index.html +1 -1
  190. package/apps/pwa/out/board/index.txt +23 -23
  191. package/apps/pwa/out/botlab/index.html +1 -1
  192. package/apps/pwa/out/botlab/index.txt +22 -22
  193. package/apps/pwa/out/bots/index.html +1 -1
  194. package/apps/pwa/out/bots/index.txt +22 -22
  195. package/apps/pwa/out/ceo/index.html +1 -1
  196. package/apps/pwa/out/ceo/index.txt +23 -23
  197. package/apps/pwa/out/chat/index.html +1 -1
  198. package/apps/pwa/out/chat/index.txt +22 -22
  199. package/apps/pwa/out/consult/index.html +1 -1
  200. package/apps/pwa/out/consult/index.txt +23 -23
  201. package/apps/pwa/out/control/index.html +1 -1
  202. package/apps/pwa/out/control/index.txt +23 -23
  203. package/apps/pwa/out/decisions/index.html +1 -1
  204. package/apps/pwa/out/decisions/index.txt +22 -22
  205. package/apps/pwa/out/design-check/index.html +1 -1
  206. package/apps/pwa/out/design-check/index.txt +23 -23
  207. package/apps/pwa/out/editor/index.html +1 -1
  208. package/apps/pwa/out/editor/index.txt +23 -23
  209. package/apps/pwa/out/exec/index.html +1 -1
  210. package/apps/pwa/out/exec/index.txt +23 -23
  211. package/apps/pwa/out/field/index.html +1 -1
  212. package/apps/pwa/out/field/index.txt +23 -23
  213. package/apps/pwa/out/healthz +1 -1
  214. package/apps/pwa/out/index.html +1 -1
  215. package/apps/pwa/out/index.txt +22 -22
  216. package/apps/pwa/out/inside/index.html +1 -1
  217. package/apps/pwa/out/inside/index.txt +22 -22
  218. package/apps/pwa/out/intake/index.html +1 -1
  219. package/apps/pwa/out/intake/index.txt +23 -23
  220. package/apps/pwa/out/live/index.html +1 -1
  221. package/apps/pwa/out/live/index.txt +26 -23
  222. package/apps/pwa/out/live-run/index.html +1 -1
  223. package/apps/pwa/out/live-run/index.txt +23 -23
  224. package/apps/pwa/out/loops/index.html +1 -1
  225. package/apps/pwa/out/loops/index.txt +22 -22
  226. package/apps/pwa/out/market/index.html +1 -1
  227. package/apps/pwa/out/market/index.txt +22 -22
  228. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  229. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  230. package/apps/pwa/out/morning/index.html +1 -1
  231. package/apps/pwa/out/morning/index.txt +23 -23
  232. package/apps/pwa/out/observatory/index.html +1 -1
  233. package/apps/pwa/out/observatory/index.txt +23 -23
  234. package/apps/pwa/out/ops/checklist/index.html +1 -1
  235. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  236. package/apps/pwa/out/ops/release/index.html +1 -1
  237. package/apps/pwa/out/ops/release/index.txt +22 -22
  238. package/apps/pwa/out/ops/seats/index.html +1 -1
  239. package/apps/pwa/out/ops/seats/index.txt +22 -22
  240. package/apps/pwa/out/outputs/index.html +1 -1
  241. package/apps/pwa/out/outputs/index.txt +22 -22
  242. package/apps/pwa/out/reflection/index.html +1 -1
  243. package/apps/pwa/out/reflection/index.txt +23 -23
  244. package/apps/pwa/out/scheduler/index.html +1 -1
  245. package/apps/pwa/out/scheduler/index.txt +23 -23
  246. package/apps/pwa/out/sessions/index.html +1 -1
  247. package/apps/pwa/out/sessions/index.txt +22 -22
  248. package/apps/pwa/out/settings/devices/index.html +1 -1
  249. package/apps/pwa/out/settings/devices/index.txt +23 -23
  250. package/apps/pwa/out/settings/index.html +1 -1
  251. package/apps/pwa/out/settings/index.txt +23 -23
  252. package/apps/pwa/out/setup/done/index.html +1 -1
  253. package/apps/pwa/out/setup/done/index.txt +23 -23
  254. package/apps/pwa/out/setup/index.html +1 -1
  255. package/apps/pwa/out/setup/index.txt +23 -23
  256. package/apps/pwa/out/share/index.html +1 -1
  257. package/apps/pwa/out/share/index.txt +23 -23
  258. package/apps/pwa/out/showroom/index.html +1 -1
  259. package/apps/pwa/out/showroom/index.txt +22 -22
  260. package/apps/pwa/out/tasks/index.html +1 -1
  261. package/apps/pwa/out/tasks/index.txt +23 -23
  262. package/apps/pwa/out/term/index.html +1 -1
  263. package/apps/pwa/out/term/index.txt +23 -23
  264. package/apps/pwa/out/today/index.html +1 -1
  265. package/apps/pwa/out/today/index.txt +23 -23
  266. package/apps/pwa/out/trace/index.html +1 -1
  267. package/apps/pwa/out/trace/index.txt +23 -23
  268. package/apps/pwa/out/vault/index.html +1 -1
  269. package/apps/pwa/out/vault/index.txt +23 -23
  270. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  271. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  272. package/apps/pwa/out/workflows/index.html +1 -1
  273. package/apps/pwa/out/workflows/index.txt +23 -23
  274. package/apps/pwa/out/workspace/index.html +1 -1
  275. package/apps/pwa/out/workspace/index.txt +23 -23
  276. package/apps/pwa/out/worktrees/index.html +1 -1
  277. package/apps/pwa/out/worktrees/index.txt +23 -23
  278. package/bin/elanous.mjs +7 -3
  279. package/graphs/context/nightly-condense.yaml +1 -0
  280. package/graphs/implement-loop.yaml +5 -0
  281. package/graphs/intake/intake-daily.yaml +8 -1
  282. package/graphs/intake/recipes.yaml +5 -0
  283. package/graphs/lecture/lecture-note.yaml +2 -2
  284. package/graphs/ops/harness-gc.yaml +1 -0
  285. package/graphs/release/recipes.yaml +3 -0
  286. package/graphs/release/release-loop.yaml +9 -5
  287. package/graphs/units/recipes.yaml +3 -0
  288. package/graphs/units/release-gate-recheck.yaml +15 -0
  289. package/package.json +2 -1
  290. package/scripts/check-native-tool-wiring.ts +3 -2
  291. package/scripts/ci-android-unit-tests.ts +16 -0
  292. package/scripts/ci-typecheck-changed.ts +63 -10
  293. package/scripts/coord-channel-watch.sh +22 -16
  294. package/scripts/coord-role-pack.ts +81 -2
  295. package/scripts/cron-run.ts +96 -3
  296. package/scripts/detect-test-interference.ts +38 -5
  297. package/scripts/gate-pr-cache.ts +65 -0
  298. package/scripts/gh-surface/capture.ts +126 -0
  299. package/scripts/gh-surface/gh +40 -0
  300. package/scripts/import-graph-scc.ts +38 -0
  301. package/scripts/install.ps1 +19 -0
  302. package/scripts/intake-social.ts +181 -0
  303. package/scripts/lecture-note/node.ts +71 -4
  304. package/scripts/lib/android-toolchain.ts +32 -0
  305. package/scripts/lib/deterministic-env.ts +62 -0
  306. package/scripts/lib/gate-test-env.ts +19 -0
  307. package/scripts/measure-goal-grounding-corpus.ts +2 -1
  308. package/scripts/measure-si-task-cpu.ts +143 -0
  309. package/scripts/ratchets/test-interference-patterns.allowlist.txt +255 -0
  310. package/scripts/ratchets/test-interference-patterns.ts +367 -0
  311. package/scripts/release-loop/cut-branch.ts +4 -3
  312. package/scripts/release-loop/export-check-node.ts +0 -1
  313. package/scripts/release-loop/fixtures/warm-failure-assertion/sample.junit.xml +8 -0
  314. package/scripts/release-loop/fixtures/warm-job-029/sample.json +1 -0
  315. package/scripts/release-loop/fixtures/warm-job-029/sample.junit.xml +10 -0
  316. package/scripts/release-loop/gate-closure.ts +12 -8
  317. package/scripts/release-loop/gate-diff.ts +1 -1
  318. package/scripts/release-loop/gate-host-mirror.ts +66 -0
  319. package/scripts/release-loop/gate-node.ts +523 -75
  320. package/scripts/release-loop/gate-partial.ts +106 -9
  321. package/scripts/release-loop/gate-pr-cache.ts +66 -0
  322. package/scripts/release-loop/gate-prewarm-plan.ts +66 -0
  323. package/scripts/release-loop/gate-r2-verdict.ts +189 -0
  324. package/scripts/release-loop/gate-recheck-plan-node.ts +52 -0
  325. package/scripts/release-loop/gate-warm-artifacts.ts +253 -0
  326. package/scripts/release-loop/import-graph-scc-run.ts +54 -0
  327. package/scripts/release-loop/import-graph-scc.ts +215 -0
  328. package/scripts/release-loop/node-verdict.ts +2 -0
  329. package/scripts/release-loop/prepare-node.ts +102 -4
  330. package/scripts/release-loop/probe-pod-host-dirs-live.ts +113 -0
  331. package/scripts/release-loop/resume-release.ts +33 -4
  332. package/scripts/release-loop/resume.ts +13 -5
  333. package/scripts/release-loop/spawn-lane.ts +2 -19
  334. package/scripts/release-loop/tui-sim-node.ts +3 -2
  335. package/scripts/release-loop/unattended-release.ts +16 -0
  336. package/scripts/test-deterministic.ts +5 -61
  337. package/scripts/train-reach-grouping.ts +48 -0
  338. package/scripts/tsc-incremental-cache.ts +86 -0
  339. package/scripts/tsc-incremental-diagnostics.ts +76 -0
  340. package/scripts/tsc-main-safety-net.ts +2 -2
  341. package/src/acp/client.ts +4 -1
  342. package/src/acp/core-turn-bridge.ts +65 -8
  343. package/src/acp/elanous-extensions.ts +3 -0
  344. package/src/acp/server.ts +3 -0
  345. package/src/acp/tool-trace.ts +186 -11
  346. package/src/ad-pipeline/run.ts +4 -2
  347. package/src/agent/runner.ts +169 -3
  348. package/src/agent/self-ambient-cache.ts +156 -0
  349. package/src/agent/self-ambient.ts +8 -1
  350. package/src/agent/subagent-callable.ts +3 -2
  351. package/src/agent/task-notification.ts +5 -0
  352. package/src/agent-mission/review-loop.ts +6 -3
  353. package/src/agent-substrate/acp-implementer.ts +14 -2
  354. package/src/agent-substrate/pr-reviewer.ts +14 -0
  355. package/src/agent-substrate/self-review-cli.ts +30 -4
  356. package/src/ask-user-question/tool.ts +22 -0
  357. package/src/autopilot/build/llm-conflict-merge.ts +56 -10
  358. package/src/autopilot/pr-manager.ts +80 -7
  359. package/src/briefing/brief-items.ts +24 -22
  360. package/src/capture/frame-state-detect.ts +39 -0
  361. package/src/capture/tui-self-report.ts +149 -6
  362. package/src/chat/chat-cli.ts +10 -2
  363. package/src/chat/index.ts +138 -26
  364. package/src/chat/input-control-key.ts +5 -3
  365. package/src/chat/pickers/modal-runtime.ts +6 -0
  366. package/src/chat/pickers/modals.ts +8 -2
  367. package/src/chat/tool-interrupt-behavior.ts +38 -0
  368. package/src/chat/tool-render/dispatch.ts +5 -1
  369. package/src/chat/turn-typeahead.ts +75 -20
  370. package/src/cli/__fixtures__/agent-help-before/agent.txt +4 -2
  371. package/src/cli/agent-cli.ts +41 -13
  372. package/src/cli/ask-bare.ts +1 -0
  373. package/src/cli/config-audit.ts +123 -0
  374. package/src/cli/decisions-cli.ts +80 -6
  375. package/src/cli/import-cli.ts +12 -0
  376. package/src/cli/log-event-names.ts +17 -0
  377. package/src/cli/mcp-login.ts +21 -5
  378. package/src/cli/msg-cli.ts +89 -0
  379. package/src/cli/pod-cli.ts +14 -3
  380. package/src/cli/pr-cli.ts +273 -81
  381. package/src/cli/pr-land-base-read.ts +34 -0
  382. package/src/cli/pr-land-heavy-remote.ts +82 -26
  383. package/src/cli/pr-land-overlap-evidence.ts +109 -11
  384. package/src/cli/pr-land-pod-shadow-job.ts +106 -0
  385. package/src/cli/pr-land-pod-shadow.ts +16 -3
  386. package/src/cli/pr-land-refusal.ts +20 -5
  387. package/src/cli/pr-land-virtual-rebase.ts +108 -0
  388. package/src/cli/pty-takeover-cli.ts +88 -14
  389. package/src/cli/release-cli.ts +80 -14
  390. package/src/cli/seat-cli.ts +138 -3
  391. package/src/cli/self-update.ts +5 -2
  392. package/src/cli/sim-cli.ts +18 -0
  393. package/src/cli/tasks-cli.ts +97 -19
  394. package/src/context-bus/context-first.ts +13 -0
  395. package/src/context-bus/context-now.ts +13 -2
  396. package/src/context-bus/ops-events.ts +79 -0
  397. package/src/control-plane/lease-holder.ts +12 -8
  398. package/src/control-plane/ledger.ts +163 -4
  399. package/src/control-plane/server.ts +91 -11
  400. package/src/core-turn/run-core-turn.ts +2 -0
  401. package/src/core-turn/run-goal-loop.ts +243 -3
  402. package/src/core-turn/seat-turn-cap.ts +79 -0
  403. package/src/core-turn/short-question.ts +38 -6
  404. package/src/core-turn/types.ts +6 -0
  405. package/src/dashboard/acp-active-model.ts +42 -1
  406. package/src/dashboard/acp-boot.ts +3 -0
  407. package/src/dashboard/background-jobs-status.ts +66 -0
  408. package/src/dashboard/index.ts +339 -657
  409. package/src/dashboard/input/agent-wake.ts +242 -0
  410. package/src/dashboard/input/chat-main-entry-runtime.ts +6 -1
  411. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +4 -1
  412. package/src/dashboard/input/chat-main-session.ts +8 -1
  413. package/src/dashboard/input/chat-main-turn.ts +12 -3
  414. package/src/dashboard/input/compact-prepass-recovery.ts +33 -0
  415. package/src/dashboard/input/external-input-host.ts +49 -9
  416. package/src/dashboard/input/internal-turn.ts +261 -0
  417. package/src/dashboard/input/mouse-wiring.ts +108 -11
  418. package/src/dashboard/input/seat-autowake.ts +318 -0
  419. package/src/dashboard/input/turn-steer-bridge.ts +70 -0
  420. package/src/dashboard/log-click-runtime.ts +118 -2
  421. package/src/dashboard/loop-scheduler.ts +72 -0
  422. package/src/dashboard/seat-boot-preamble.ts +18 -0
  423. package/src/dashboard/skill-runtime.ts +2 -0
  424. package/src/dashboard/slash-runtime/dashboard-handlers.ts +126 -1181
  425. package/src/dashboard/slash-runtime/help-from-registry.ts +2 -1
  426. package/src/dashboard/slash-runtime/index.ts +13 -0
  427. package/src/dashboard/turn-busy-teardown.ts +50 -0
  428. package/src/dashboard/turn-preamble.ts +116 -40
  429. package/src/dashboard/turn-session-layers.ts +4 -2
  430. package/src/dashboard/turn-start-segments.ts +222 -0
  431. package/src/decisions/decision-ledger.ts +45 -4
  432. package/src/discord-self-message.ts +4 -4
  433. package/src/display/prompt-row-owner.ts +146 -0
  434. package/src/display/resize-listener.ts +33 -2
  435. package/src/domains/release-tool.ts +18 -1
  436. package/src/field-note/transcribe.ts +17 -0
  437. package/src/fold-stack.ts +4 -2
  438. package/src/git-fs/index.ts +263 -36
  439. package/src/github/remote-call.ts +81 -0
  440. package/src/goals/registry.ts +46 -6
  441. package/src/goals/types.ts +7 -1
  442. package/src/graph-runner/runner.ts +1 -0
  443. package/src/grok/credential.ts +26 -0
  444. package/src/harness/gate-reserve.ts +87 -0
  445. package/src/harness/harness-clean.ts +2 -1
  446. package/src/harness/harness-cli-command.ts +52 -5
  447. package/src/harness/harness-gc.ts +2 -1
  448. package/src/harness/harness-incidents.ts +70 -20
  449. package/src/harness/harness-pod-dispatch.ts +87 -10
  450. package/src/harness/harness-queue.ts +68 -4
  451. package/src/harness/harness-stop.ts +4 -3
  452. package/src/harness/harness-substrate-default.ts +78 -7
  453. package/src/harness/harness-worktree-auto.ts +2 -1
  454. package/src/harness/harness-worktrees.ts +3 -2
  455. package/src/hooks/dispatch.ts +2 -1
  456. package/src/index.ts +156 -27
  457. package/src/input/external-input-queue.ts +64 -7
  458. package/src/intake-plane/slash.ts +14 -3
  459. package/src/keybindings.ts +4 -1
  460. package/src/llm/route-decision.ts +36 -0
  461. package/src/llm/tool-loop-steered-rejection.ts +41 -0
  462. package/src/llm-request-shape.ts +209 -0
  463. package/src/llm.ts +301 -283
  464. package/src/loops/consensus.ts +348 -0
  465. package/src/loops/msg-wake.ts +206 -4
  466. package/src/loops/observe.ts +19 -3
  467. package/src/loops/orchestrator/tick.ts +88 -12
  468. package/src/loops/orchestrator/traffic.ts +64 -1
  469. package/src/loops/registry.ts +30 -0
  470. package/src/market/signed-index.ts +14 -0
  471. package/src/maturity/feature-maturity.ts +1 -1
  472. package/src/mcp/mcp-oauth.ts +54 -5
  473. package/src/models/prompts.ts +28 -0
  474. package/src/msg/msg-sse-client.ts +223 -0
  475. package/src/msg/msg-store.ts +86 -2
  476. package/src/mss/logging/log-store.ts +225 -1
  477. package/src/mss/logging/render-categories.ts +5 -0
  478. package/src/nexus/DAEMON-THIN-inventory-2026-10-15.md +122 -0
  479. package/src/nexus/api/http-server.ts +54 -15
  480. package/src/nexus/api/loop-resources.ts +19 -3
  481. package/src/nexus/api/ops-api.ts +11 -0
  482. package/src/nexus/daemon-thin-inventory.md +37 -0
  483. package/src/nexus/index.ts +70 -0
  484. package/src/nexus/state/state.ts +1 -0
  485. package/src/oauth/store.ts +32 -7
  486. package/src/onboarding/first-run.ts +28 -3
  487. package/src/ops/overview-cache.ts +16 -4
  488. package/src/ops/overview.ts +59 -2
  489. package/src/ops/resources.ts +82 -0
  490. package/src/plugins/maker/connector-maker.ts +41 -0
  491. package/src/plugins/maker/skill-maker.ts +42 -0
  492. package/src/pr-tool/census.ts +303 -0
  493. package/src/pr-tool/inflight-registry.ts +143 -0
  494. package/src/prompt-library/chat-conciseness.ts +13 -0
  495. package/src/prompt-library/universal-preamble.ts +10 -5
  496. package/src/pty-shell/pty-manifest.ts +12 -3
  497. package/src/pty-shell/tui-run-state.ts +34 -3
  498. package/src/release-loop/gate-host-reservation.ts +97 -0
  499. package/src/release-loop/landing-freeze.ts +5 -0
  500. package/src/release-loop/light-rc.ts +5 -2
  501. package/src/release-loop/placement.ts +92 -1
  502. package/src/release-loop/rehearsal-shard-plan.ts +149 -0
  503. package/src/release-loop/rehearsal.ts +73 -17
  504. package/src/repl/index.ts +20 -2
  505. package/src/seat-loop/seat-knowhow.ts +282 -0
  506. package/src/seat-loop/seat-loop.ts +41 -2
  507. package/src/seat-loop/traffic-signal.ts +5 -1
  508. package/src/self-dev/ask-launch-flow.ts +37 -3
  509. package/src/self-dev/decompose-compose-graph.ts +28 -27
  510. package/src/self-dev/decompose-proposal.ts +53 -38
  511. package/src/self-dev/decompose.ts +17 -0
  512. package/src/self-dev/dev-pipeline.ts +31 -2
  513. package/src/self-dev/draft-residue.ts +267 -33
  514. package/src/self-dev/draft-sweep.ts +59 -4
  515. package/src/self-dev/external-call-zero.ts +77 -0
  516. package/src/self-dev/launch-preflight-text.ts +6 -0
  517. package/src/self-dev/launch-preflight.ts +25 -3
  518. package/src/self-dev/local-supervisor-judge.ts +185 -0
  519. package/src/self-dev/run-supervisor.ts +229 -19
  520. package/src/self-dev/run-types.ts +20 -0
  521. package/src/self-dev/shard-aggregate.ts +13 -2
  522. package/src/self-dev/shard-plan.ts +56 -1
  523. package/src/self-dev/shard-run.ts +207 -12
  524. package/src/self-dev/spawn-lane-files.ts +19 -0
  525. package/src/self-implement/app-api-budget.ts +51 -11
  526. package/src/self-implement/config-gate.ts +2 -1
  527. package/src/self-implement/elanous-tui-spawn.ts +14 -0
  528. package/src/self-implement/expose-gate.ts +2 -1
  529. package/src/self-implement/follow-up-placement.ts +79 -0
  530. package/src/self-implement/gate-artifacts.ts +416 -0
  531. package/src/self-implement/gate-baseline.ts +96 -5
  532. package/src/self-implement/gate-cli.ts +207 -17
  533. package/src/self-implement/gate-remote.ts +136 -26
  534. package/src/self-implement/gate-scenario.ts +85 -0
  535. package/src/self-implement/goal-author.ts +160 -8
  536. package/src/self-implement/graph-authority.ts +38 -6
  537. package/src/self-implement/graph-overlay-condition.ts +92 -1
  538. package/src/self-implement/heal-triage.ts +79 -0
  539. package/src/self-implement/host-regate.ts +97 -7
  540. package/src/self-implement/orchestrator.ts +115 -134
  541. package/src/self-implement/pr-title.ts +123 -0
  542. package/src/self-implement/run-checkpoint.ts +235 -0
  543. package/src/self-implement/run-ledger.ts +162 -15
  544. package/src/self-implement/run-stop.ts +4 -3
  545. package/src/self-implement/run-ttl.ts +28 -4
  546. package/src/self-implement/seams.ts +2 -0
  547. package/src/self-implement/shadow-stage.ts +7 -6
  548. package/src/self-implement/stop-autoheal.ts +2 -1
  549. package/src/self-implement/train-gate-remote.ts +37 -8
  550. package/src/self-implement/train-reach-grouping.ts +157 -0
  551. package/src/self-implement/train-scenario-layers.ts +133 -0
  552. package/src/self-implement/uncommitted-work.ts +2 -0
  553. package/src/session/pending-input.ts +19 -0
  554. package/src/session/session-start.ts +224 -0
  555. package/src/session-runtime/index.ts +22 -267
  556. package/src/session-runtime/parallel-dispatch.ts +22 -5
  557. package/src/shell-runner/background-surface.ts +15 -5
  558. package/src/skills/tools/agent.ts +39 -6
  559. package/src/skills/tools/dev-harness.ts +6 -4
  560. package/src/skills/tools/list-dir.ts +11 -0
  561. package/src/skills/tools/schedule-wakeup.ts +408 -0
  562. package/src/skills/tools/shell.ts +246 -4
  563. package/src/status/bar.ts +26 -0
  564. package/src/steward/digest-delivery.ts +118 -0
  565. package/src/steward/hold-hygiene.ts +120 -0
  566. package/src/steward/resync-tick.ts +114 -23
  567. package/src/steward/ta-repair-event-collect.ts +158 -0
  568. package/src/steward/triage.ts +10 -0
  569. package/src/surface/shell-runner-boot.ts +5 -2
  570. package/src/task-agent/card-evidence.ts +25 -1
  571. package/src/task-agent/green-sweep.ts +8 -3
  572. package/src/task-agent/judge.ts +76 -0
  573. package/src/task-agent/land-queue.ts +79 -0
  574. package/src/task-agent/live-moves.ts +30 -9
  575. package/src/task-agent/postland-card.ts +5 -0
  576. package/src/task-agent/prelaunch-already-done.ts +98 -0
  577. package/src/task-agent/real-launch-guard.ts +37 -0
  578. package/src/task-agent/rejudge-on-head.ts +89 -12
  579. package/src/task-agent/remote-rejudge-bind.ts +28 -8
  580. package/src/task-agent/repair-cycle.ts +45 -7
  581. package/src/task-agent/repair-worker.ts +7 -0
  582. package/src/task-agent/run-identity.ts +200 -0
  583. package/src/task-agent/shadow.ts +50 -3
  584. package/src/task-agent/task-hand.ts +182 -5
  585. package/src/task-agent/train-landing.ts +77 -0
  586. package/src/task-agent/work-order.ts +104 -0
  587. package/src/task-orchestrator/surfaces/pod-command-job.ts +151 -37
  588. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +88 -19
  589. package/src/task-orchestrator/surfaces/pod-host-acp-review.ts +2 -1
  590. package/src/task-orchestrator/surfaces/pod-image-source.ts +2 -1
  591. package/src/task-orchestrator/surfaces/pod-install-slots.ts +121 -9
  592. package/src/task-orchestrator/surfaces/pod-lease.ts +118 -6
  593. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +1 -1
  594. package/src/task-orchestrator/surfaces/pod-lifecycle-stages.ts +169 -0
  595. package/src/task-orchestrator/surfaces/pod-mirror-seed.ts +27 -0
  596. package/src/task-orchestrator/surfaces/pod-pool.ts +3 -1
  597. package/src/task-orchestrator/surfaces/pod-result-marker-wait.ts +33 -0
  598. package/src/task-orchestrator/surfaces/pod-reuse-cleanup.ts +67 -0
  599. package/src/task-orchestrator/surfaces/pod-source-receive.ts +19 -3
  600. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +141 -0
  601. package/src/task-orchestrator/surfaces/pod-warm-ta-shadow.ts +85 -0
  602. package/src/task-orchestrator/surfaces/pod-warm-worker-pod.ts +525 -0
  603. package/src/task-orchestrator/surfaces/pod-warm-worker-protocol.ts +153 -0
  604. package/src/task-orchestrator/surfaces/pod-warm-worker-runner.ts +90 -0
  605. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +362 -0
  606. package/src/task-orchestrator/surfaces/self-implement-pod.ts +138 -19
  607. package/src/telegram.ts +2 -4
  608. package/src/tui/chat/execution-badge.ts +5 -1
  609. package/src/tui/input/pickers.ts +732 -0
  610. package/src/tui/input-lag-probe.ts +230 -0
  611. package/src/tui/slash/mission.ts +492 -0
  612. package/src/tui/slash/term.ts +877 -0
  613. package/src/tui-client/dashboard-session.ts +9 -0
  614. package/src/tui.ts +52 -0
  615. package/src/user-config/gemini-server-tools.ts +9 -0
  616. package/src/user-config.ts +53 -16
  617. package/src/util/spawn-sync-output.ts +7 -0
  618. package/src/ux-sim/fake-bin.ts +154 -0
  619. package/src/ux-sim/fake-clock.ts +36 -0
  620. package/src/ux-sim/headless-tui.ts +72 -0
  621. package/src/ux-sim/in-process-cli.ts +2 -1
  622. package/src/ux-sim/scenario.ts +255 -0
  623. package/src/ux-sim/temp-git-remote.ts +82 -0
  624. package/src/version/packed-revision.json +1 -1
  625. package/src/video-pipeline/recipes/vlog.ts +25 -7
  626. package/apps/pwa/out/_next/static/chunks/1015-9cba22a5a4554797.js +0 -1
  627. package/apps/pwa/out/_next/static/chunks/1084-4e66af7376a18db7.js +0 -1
  628. package/apps/pwa/out/_next/static/chunks/1106.3a6410b7b0c70ad4.js +0 -1
  629. package/apps/pwa/out/_next/static/chunks/1127.32fc642f70423506.js +0 -8
  630. package/apps/pwa/out/_next/static/chunks/1189-d9b8e1995a831fae.js +0 -1
  631. package/apps/pwa/out/_next/static/chunks/1224.6da98c7ad0eb7dd8.js +0 -34
  632. package/apps/pwa/out/_next/static/chunks/1370.4e3e2558f111fd5d.js +0 -1
  633. package/apps/pwa/out/_next/static/chunks/1514-b7da377fdc4eb17a.js +0 -1
  634. package/apps/pwa/out/_next/static/chunks/1577.3c24c32584e10d70.js +0 -286
  635. package/apps/pwa/out/_next/static/chunks/161.130a569855c4d68c.js +0 -24
  636. package/apps/pwa/out/_next/static/chunks/1864.16da9556e78a9236.js +0 -1
  637. package/apps/pwa/out/_next/static/chunks/1b6f6b2a.aff090122be3726e.js +0 -1
  638. package/apps/pwa/out/_next/static/chunks/2341.e8a9135e5b910dd5.js +0 -36
  639. package/apps/pwa/out/_next/static/chunks/257.10afdbe3520f2fc2.js +0 -1
  640. package/apps/pwa/out/_next/static/chunks/2658.87550e692dc493f6.js +0 -64
  641. package/apps/pwa/out/_next/static/chunks/2673.85e2f02efae7a85f.js +0 -1
  642. package/apps/pwa/out/_next/static/chunks/2766-bee623b37472ed63.js +0 -1
  643. package/apps/pwa/out/_next/static/chunks/2794.6d836872b0bf43e2.js +0 -1
  644. package/apps/pwa/out/_next/static/chunks/2806.eb57ced1a528ed39.js +0 -1
  645. package/apps/pwa/out/_next/static/chunks/283.7a121c4910e6dad7.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/2870.1dc29aa5fc01f09f.js +0 -115
  647. package/apps/pwa/out/_next/static/chunks/293.fd38e77ce5d48103.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/2993-5952a1cd3fd5d441.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/32-a523427c5bd5ed00.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/3280.af38002a6424a905.js +0 -90
  651. package/apps/pwa/out/_next/static/chunks/3292-5ddffdb2f517b44f.js +0 -1
  652. package/apps/pwa/out/_next/static/chunks/3523.d3231daaf7aba993.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/3763.577de3181e1e6ea0.js +0 -1
  654. package/apps/pwa/out/_next/static/chunks/4138-cc56b0938ef72783.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/4255-8350c43d307a8875.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/4352.a4954693499c2714.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/4421-f2dcbc6fd80ec013.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/4513-51b94aeee37c9905.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/4928-c3b72f99aa588699.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/4986-f9fc0283fb325219.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/5014.671a7b9f69c2b7b1.js +0 -94
  662. package/apps/pwa/out/_next/static/chunks/5137.d398e24710b3feb6.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/5298.0bea74885cabe754.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/5315.74c53a39739b11c4.js +0 -1
  665. package/apps/pwa/out/_next/static/chunks/5317-8b1df8d02105cd07.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/5358-33051f41a2b239af.js +0 -1
  667. package/apps/pwa/out/_next/static/chunks/5388.a2ec02501f714ad5.js +0 -62
  668. package/apps/pwa/out/_next/static/chunks/5395.e6ac948a2d15058d.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/5409-f282bf533c151849.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/5466.d0f4aba9d52acfa8.js +0 -27
  671. package/apps/pwa/out/_next/static/chunks/5564.3d28b353470fe305.js +0 -104
  672. package/apps/pwa/out/_next/static/chunks/569.b0cbfb4dee4a167a.js +0 -93
  673. package/apps/pwa/out/_next/static/chunks/5835-72465b73a8bb8d74.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/5941.045d6093139e1f7a.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/6228.47cabb83564dfe54.js +0 -24
  676. package/apps/pwa/out/_next/static/chunks/6457-8d1993002a87d0fe.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/6513.ef54cfae52351982.js +0 -2
  678. package/apps/pwa/out/_next/static/chunks/6582.13d245bf87df69f1.js +0 -148
  679. package/apps/pwa/out/_next/static/chunks/6655.c33f6acc2c61bb89.js +0 -149
  680. package/apps/pwa/out/_next/static/chunks/6731-9d7195af289c8d4c.js +0 -1
  681. package/apps/pwa/out/_next/static/chunks/6733.0be05b1db9279fc5.js +0 -79
  682. package/apps/pwa/out/_next/static/chunks/6742-90937146253a8b9e.js +0 -1
  683. package/apps/pwa/out/_next/static/chunks/687-816858f77a396a4e.js +0 -1
  684. package/apps/pwa/out/_next/static/chunks/6888.72c7b8cfb02a7e61.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/6993.c17c828ac3ef3253.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/7076.9f27ef666b0cefdd.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/7113.1403c5d451804e8c.js +0 -287
  688. package/apps/pwa/out/_next/static/chunks/7169.9dd603c726c2cd7c.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/7247-e3ec21f761f86710.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/7261-a47b72f96f5199df.js +0 -1
  691. package/apps/pwa/out/_next/static/chunks/7335-5cda81ac90310077.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/7356-c2e4af090546e2d4.js +0 -1
  693. package/apps/pwa/out/_next/static/chunks/738-59518742078fda71.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/7385.a7375f10db73243a.js +0 -77
  695. package/apps/pwa/out/_next/static/chunks/7445.cf1cf2fe109bcd96.js +0 -1
  696. package/apps/pwa/out/_next/static/chunks/7505.a2057432ab6ef99a.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/7515.31f45fac1f9c70cb.js +0 -74
  698. package/apps/pwa/out/_next/static/chunks/7658-d4ce8c72a9548a91.js +0 -1
  699. package/apps/pwa/out/_next/static/chunks/8107-0b1ae46bc5bcb788.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/8132.bfea2f016ce8d992.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/8672.e299832bc7d18ee2.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/8735.f1ef798a5f260f6f.js +0 -226
  703. package/apps/pwa/out/_next/static/chunks/8774-88f67f7d8d53d299.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/8782.252e5a405d86e4ed.js +0 -32
  705. package/apps/pwa/out/_next/static/chunks/909-9ed7aa0dba804316.js +0 -1
  706. package/apps/pwa/out/_next/static/chunks/9100.22b0301256827007.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/9140-dde77575570bc71e.js +0 -1
  708. package/apps/pwa/out/_next/static/chunks/9292-a7ad9a01c7044b93.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/9517.00627dc51b02821c.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/9725.dcbb585652d8e9c5.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/9761.a3ebf5c389c24ddc.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/9972.834d2b2b7d48f1ed.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/9995-1a90486f5ae01546.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/a435ad95.577add051b4facb2.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-83372d8b5863ebf7.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/app/approvals/page-d69256d7613c140a.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-352c5e9ba3f9b858.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/app/board/page-69f1d725524201a8.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/app/botlab/page-a5635eba0d73b84e.js +0 -1
  720. package/apps/pwa/out/_next/static/chunks/app/bots/page-ad9181d84285e4ea.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/app/ceo/page-86feb08080261a2f.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/app/chat/page-ffa15987e4756d03.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/app/consult/page-11a3ab44ac327cc1.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/app/control/page-6309b11c4264d24d.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/app/decisions/page-8800472079612e87.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/app/design-check/page-d387bf3f2301882a.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/app/editor/page-048f88d8c8658da6.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/app/exec/page-6c14f9739b7f6880.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/app/field/page-2834f44f64e98d74.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/app/healthz/route-83372d8b5863ebf7.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/app/inside/page-a13df6f88e824887.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/app/intake/page-8a4397248754cf2b.js +0 -1
  733. package/apps/pwa/out/_next/static/chunks/app/layout-daf0bd329360a336.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/app/live/page-f7ef1c28764cb476.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/app/live-run/page-61e74f28b9353dac.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/app/loops/page-8aaa6dedc4c10dfb.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/app/market/page-294602ba649be829.js +0 -1
  738. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-5fa5f41ed3fce323.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/morning/page-33bf667a5fb297bf.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/not-found-5ae3cbd6e5dba515.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/observatory/page-eb867d16ad6fdede.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-1ab789fa68682f7e.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/ops/release/page-6fd41b5b6ff13a71.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-fb3d5f7642c99fba.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/outputs/page-70f705b2b5ed42ca.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/page-c9c93b358a7667b5.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/reflection/page-1563c556b81c96ed.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-ce89c20c45b3a673.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/sessions/page-423ae63d786f4ee9.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-591a5378a4c4447c.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/settings/page-a250496b19a5824b.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-c36a9277febc5911.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/setup/layout-83372d8b5863ebf7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/share/page-a5de57edc6d7f942.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/showroom/page-16bdd4c9f40498df.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/tasks/page-75e946e6e71cc6d8.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/term/page-9eb56166774eb256.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/today/page-1c5f9ef35dbb22c5.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/trace/page-657ff9985e508498.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/vault/page-22dc72499da68fb2.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-9f92737b8766009a.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/workflows/page-094ad334e40f8169.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/workspace/page-8bcd379852ff6287.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-6b04413f280cd344.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/de70ab42-d28d47437208d458.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/f800c5e3.46dbd7f2af8c3fce.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/f8bc19ad.47579f6d684b0760.js +0 -122
  768. package/apps/pwa/out/_next/static/chunks/framework-ca9ac4609fb9fed8.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/main-app-0dd08d32d15a030f.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/main-f0399d33955c4e01.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/pages/_app-d42caca6f8ac2211.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/pages/_error-42e713c13aa41ca8.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/webpack-8fbf8f61a377aa16.js +0 -1
  774. package/apps/pwa/out/_next/static/css/72becfd42807b50d.css +0 -1
  775. /package/apps/pwa/out/_next/static/{cIpv5nU9AycwYWZI9H589 → IVKr3AlRUVLKsw2fh7eXF}/_ssgManifest.js +0 -0
@@ -1,12 +1,19 @@
1
1
  import type { Command } from 'commander';
2
- import { existsSync, lstatSync, readFileSync, statSync } from 'node:fs';
2
+ import { existsSync, lstatSync, readFileSync, realpathSync, statSync } from 'node:fs';
3
3
  import { homedir } from 'node:os';
4
4
  import { dirname, join, relative, sep } from 'node:path';
5
+ import { fileURLToPath } from 'node:url';
5
6
  import { redactSecretText } from '../debug/log.js';
6
7
  import { defaultMsgStorePath, readUnreadCount } from '../msg/msg-store.js';
8
+ import { parseKnowhowItems, splitKnowhow } from '../seat-loop/seat-knowhow.js';
7
9
 
8
10
  export const SEAT_ROLES = ['OP', 'TC', 'MK', 'UX'] as const;
9
11
  export type SeatRole = typeof SEAT_ROLES[number];
12
+ export const SEAT_AGENTS = ['codex', 'elanous', 'claude'] as const;
13
+ export type SeatAgent = typeof SEAT_AGENTS[number];
14
+ export const SEAT_QUICKSTART_MANUAL = join('docs', 'manual', 'MANUAL-seat-agent-quickstart-2026-10-12.md');
15
+ export const SEAT_TRUST_LADDER = '신뢰 사다리: 지시 > 코드 > 문서 > 기억 — 어긋나면 앞이 이긴다';
16
+ export const SEAT_TACIT_TOP_N = 5;
10
17
 
11
18
  const MAX_FIELD = 160;
12
19
  const MAX_ROWS = 12;
@@ -107,11 +114,138 @@ export function collectSeatBootSections(seat: string, options: { home: string; m
107
114
  return { sections, unread };
108
115
  }
109
116
 
110
- export function registerSeatBootCommands(command: Command, options: { home?: () => string; contextNow?: () => unknown; msgPath?: () => string } = {}): void {
117
+ /** 표 줄을 칸으로 — 백틱 안의 `|`(예: `<pass|fail>`)는 칸 경계가 아니다. */
118
+ const cells = (line: string): string[] => (line.replace(/^\s*\|/, '').replace(/\|\s*$/, '').match(/(?:`[^`]*`|[^|`])+|(?<=\|)(?=\|)/g) ?? []).map(cell => cell.trim());
119
+ const backticked = (text: string): string[] => [...text.matchAll(/`([^`]+)`/g)].map(match => match[1]!);
120
+
121
+ /** L1 — 빠른 길 매뉴얼의 «무엇을 하려면 → 명령» 표를 고른 에이전트용 한 줄씩으로 접는다. ⚠️ 주석은 다른 에이전트만 이름 대면 뺀다. */
122
+ export function assembleSeatQuickPath(manual: string, agent: SeatAgent): string[] {
123
+ const lines = manual.split(/\r?\n/);
124
+ const start = lines.findIndex(line => /^##\s.*무엇.*명령/.test(line));
125
+ if (start < 0) return [];
126
+ const rows: string[] = [];
127
+ for (const line of lines.slice(start + 1)) {
128
+ if (/^#{1,2}\s/.test(line)) break;
129
+ if (!line.trim().startsWith('|') || /^\s*\|\s*-/.test(line)) continue;
130
+ const [what = '', command = '', dont = ''] = cells(line);
131
+ if (!what || what === '하려는 것') continue;
132
+ const segments = command.split(' · ').filter(segment => {
133
+ if (!segment.trim().startsWith('⚠️')) return true;
134
+ const named = SEAT_AGENTS.filter(name => new RegExp(`\\b${name}\\b`, 'i').test(segment));
135
+ return named.length === 0 || named.includes(agent);
136
+ });
137
+ const commands = segments.flatMap(segment => segment.trim().startsWith('⚠️') ? [segment.replace(/[`*]/g, '').trim()] : backticked(segment));
138
+ rows.push(`${what.replace(/\*\*/g, '')} → ${commands.join(' · ') || '미관측: 명령 없음'}${dont ? ` ⛔ ${dont.replace(/\*\*/g, '')}` : ''}`);
139
+ }
140
+ return rows;
141
+ }
142
+
143
+ export type SeatMemoryEntry = { title: string; hook: string; updated: string };
144
+ type TacitCandidate = { label: string; details?: string[]; updated: string; hits: number; index: number };
145
+
146
+ const tokens = (text: string): Set<string> => new Set(text.toLowerCase().split(/[^\p{L}\p{N}_]+/u).filter(Boolean));
147
+ const hitsOf = (text: string, query: Set<string>): number => [...tokens(text)].filter(token => query.has(token)).length;
148
+ /** 최근(날짜) 먼저, 같은 날이면 적중(질의 낱말 겹침) 많은 것, 그다음 원래 순서. */
149
+ const recentThenHits = (a: TacitCandidate, b: TacitCandidate): number => b.updated.slice(0, 10).localeCompare(a.updated.slice(0, 10)) || b.hits - a.hits || a.index - b.index;
150
+
151
+ /** 제목 이외의 운영 지침을 보존한다. 상태·검증은 분류에 이미 반영되어 중복 표시하지 않는다. */
152
+ function knowhowDetails(text: string, prefix: string): string[] {
153
+ return text.split(/\r?\n/).slice(1)
154
+ .filter(line => line.trim() && !/^\s*-\s*(?:상태|검증)\s*:/.test(line))
155
+ .flatMap(line => (line.trim().match(/.{1,140}/gu) ?? []).map(part => `${prefix} ↳ ${part}`));
156
+ }
157
+
158
+ /** L3 — 최근 문서 상위 5개는 본문까지, 기억은 상위 N을 보인다. 절별 출력 하드 캡은 없다. */
159
+ export function assembleSeatTacitKnowledge(input: { seat: string; agent: SeatAgent; knowhow: string; memories: readonly SeatMemoryEntry[]; now: Date; limit?: number }): string[] {
160
+ const limit = Math.max(0, input.limit ?? SEAT_TACIT_TOP_N);
161
+ const query = tokens(`${input.seat} ${input.agent}`);
162
+ const { facts, refs } = splitKnowhow(parseKnowhowItems(input.knowhow, input.seat), input.now);
163
+ const knowhow = [...facts, ...refs].map((item, index): TacitCandidate => {
164
+ const prefix = `[문서${facts.includes(item) ? '' : '·검증 안 됨'}]`;
165
+ const title = (item.text.split('\n', 1)[0] ?? '').replace(/^##\s*/, '');
166
+ return {
167
+ label: `${prefix} ${title}`,
168
+ details: knowhowDetails(item.text, prefix),
169
+ updated: item.verifiedAt?.toISOString() ?? '',
170
+ hits: hitsOf(item.text, query),
171
+ index,
172
+ };
173
+ }).sort(recentThenHits);
174
+ const memories = input.memories.map((entry, index): TacitCandidate => ({
175
+ label: `[기억] ${entry.title}${entry.hook ? ` — ${entry.hook}` : ''} (갱신 ${entry.updated.slice(0, 10) || '미상'})`,
176
+ updated: entry.updated,
177
+ hits: hitsOf(`${entry.title} ${entry.hook}`, query),
178
+ index,
179
+ })).sort(recentThenHits).slice(0, limit);
180
+ const visibleKnowhow = knowhow.slice(0, SEAT_TACIT_TOP_N);
181
+ const omittedKnowhow = knowhow.length - visibleKnowhow.length;
182
+ return [SEAT_TRUST_LADDER,
183
+ ...visibleKnowhow.flatMap(row => [row.label, ...(row.details ?? [])]),
184
+ ...(omittedKnowhow ? [`[문서] 나머지 ${omittedKnowhow}항목은 원문 KNOWHOW 참고`] : []),
185
+ ...memories.map(row => row.label)];
186
+ }
187
+
188
+ /** 저장소 안 일반 파일만 읽는다 — 링크가 저장소 밖을 가리키면 없는 것으로 친다. */
189
+ function readRepoDoc(repoRoot: string, path: string): { updated: string; text: string } | null {
190
+ try {
191
+ const suffix = relative(realpathSync(repoRoot), realpathSync(path));
192
+ if (!suffix || suffix === '..' || suffix.startsWith(`..${sep}`) || suffix.startsWith(sep)) return null;
193
+ const stat = statSync(path);
194
+ if (!stat.isFile()) return null;
195
+ return { updated: stat.mtime.toISOString(), text: readFileSync(path, 'utf8').slice(0, 256_000) };
196
+ } catch { return null; }
197
+ }
198
+
199
+ function memoryEntries(home: string, root: string): { entries: SeatMemoryEntry[]; reason?: string } {
200
+ const dir = join(root, 'memory');
201
+ const index = join(dir, 'MEMORY.md');
202
+ try {
203
+ if (!existsSync(index)) return { entries: [], reason: '미관측: 기억 색인 파일 없음' };
204
+ if (!isRegularSeatPath(home, root, index)) return { entries: [], reason: '미관측: 기억 색인이 일반 경로가 아님' };
205
+ const entries = readFileSync(index, 'utf8').slice(0, 256_000).split(/\r?\n/).flatMap(line => {
206
+ const match = line.match(/^-\s*\[([^\]]+)\]\(([^)]+)\)\s*(?:[—-]\s*(.*))?$/);
207
+ if (!match) return [];
208
+ const file = join(dir, match[2]!);
209
+ try {
210
+ if (!existsSync(file) || !isRegularSeatPath(home, root, file)) return [];
211
+ return [{ title: match[1]!, hook: match[3] ?? '', updated: statSync(file).mtime.toISOString() }];
212
+ } catch { return []; }
213
+ });
214
+ return entries.length ? { entries } : { entries, reason: '미관측: 기억 색인에 읽을 항목 없음' };
215
+ } catch { return { entries: [], reason: '미관측: 기억 색인 읽기 실패' }; }
216
+ }
217
+
218
+ /** L1·L3 절 — `--agent` 를 줬을 때만 L0 카드 뒤에 붙는다. */
219
+ export function collectSeatLadderSections(seat: string, agent: SeatAgent, options: { home: string; repoRoot: string; now: Date }): SeatBootSection[] {
220
+ const manualPath = join(options.repoRoot, SEAT_QUICKSTART_MANUAL);
221
+ const manual = readRepoDoc(options.repoRoot, manualPath);
222
+ const quick = manual ? assembleSeatQuickPath(manual.text, agent) : [];
223
+ const knowhowPath = join(options.repoRoot, 'docs', 'roles', seat, 'KNOWHOW.md');
224
+ const knowhow = readRepoDoc(options.repoRoot, knowhowPath);
225
+ const root = join(options.home, 'elanous-hq', 'seat-state');
226
+ const memories = memoryEntries(options.home, root);
227
+ const tacit = assembleSeatTacitKnowledge({ seat, agent, knowhow: knowhow?.text ?? '', memories: memories.entries, now: options.now });
228
+ const docs = tacit.filter(row => row.startsWith('[문서'));
229
+ const remembered = tacit.filter(row => row.startsWith('[기억]'));
230
+ const tacitRows = [
231
+ SEAT_TRUST_LADDER,
232
+ ...(docs.length ? docs : [knowhow ? '미관측: KNOWHOW 에 읽을 항목 없음' : '미관측: KNOWHOW 파일 없음']),
233
+ ...(remembered.length ? remembered : [memories.reason ?? '미관측: 기억 없음']),
234
+ ];
235
+ return [
236
+ { title: `L1 빠른 길 (${agent})`, source: manualPath, updated: manual?.updated ?? '미상', rows: quick, ...(quick.length ? {} : { reason: manual ? '미관측: «무엇→명령» 표 없음' : '미관측: 파일 없음' }) },
237
+ { title: `L3 암묵지 (${agent})`, source: `${knowhowPath} ⊕ ${join(root, 'memory', 'MEMORY.md')}`, updated: knowhow?.updated ?? '미상', rows: tacitRows },
238
+ ];
239
+ }
240
+
241
+ export function registerSeatBootCommands(command: Command, options: { home?: () => string; contextNow?: () => unknown; msgPath?: () => string; repoRoot?: () => string; now?: () => Date } = {}): void {
111
242
  command.command('boot <seat>').description('현재 자리 카드 — 허용된 메타데이터만 읽기 전용 표시')
112
- .action(async (rawSeat: string) => {
243
+ .option('--agent <agent>', '에이전트(codex|elanous|claude) — 주면 L1 빠른 길 ⊕ L3 암묵지를 붙인다')
244
+ .action(async (rawSeat: string, flags: { agent?: string }) => {
113
245
  const seat = rawSeat.toUpperCase();
114
246
  if (!(SEAT_ROLES as readonly string[]).includes(seat)) { console.error(`seat boot: unknown seat ${rawSeat} (OP|TC|MK|UX)`); process.exitCode = 2; return; }
247
+ const agent = flags.agent?.toLowerCase();
248
+ if (agent !== undefined && !(SEAT_AGENTS as readonly string[]).includes(agent)) { console.error(`seat boot: unknown agent ${flags.agent} (codex|elanous|claude)`); process.exitCode = 2; return; }
115
249
  const home = options.home?.() ?? homedir();
116
250
  let facts: string[] = [];
117
251
  let contextUpdated = '미상';
@@ -125,6 +259,7 @@ export function registerSeatBootCommands(command: Command, options: { home?: ()
125
259
  facts = contextFacts(snapshot);
126
260
  } catch { facts = []; contextUpdated = '미관측: contextNow 조회 실패'; }
127
261
  const sections = collectSeatBootSections(seat, { home, msgPath: options.msgPath?.() ?? defaultMsgStorePath() }).sections;
262
+ if (agent !== undefined) sections.push(...collectSeatLadderSections(seat, agent as SeatAgent, { home, repoRoot: options.repoRoot?.() ?? fileURLToPath(new URL('../../', import.meta.url)), now: options.now?.() ?? new Date() }));
128
263
  console.log(renderSeatBootCard(seat as SeatRole, sections, facts, contextUpdated));
129
264
  });
130
265
  }
@@ -590,8 +590,11 @@ function pruneUnusedVersions(dir: string, outcome: VersionPruneOutcome, listProc
590
590
  try { owner = statSync(join('/proc', pid)).uid; stat = readFileSync(join('/proc', pid, 'stat'), 'utf8'); }
591
591
  catch (failure) { if (exited(failure) && !existsSync(join('/proc', pid))) continue; throw failure; }
592
592
  if (procStatHoldsNothing(stat)) continue;
593
- // Our own links must be readable. Another UID's link failure (denied, or ENOENT from a live process) falls back to its argv.
594
- if ((code === 'EACCES' || code === 'EPERM' || code === 'ENOENT') && owner !== process.getuid?.()) {
593
+ // A denied link falls back to argv for any owner: Linux ptrace access also refuses same-UID
594
+ // processes holding extra capabilities or another user namespace (systemd --user, rootless
595
+ // containers), so requiring them would disable pruning on every systemd host. ENOENT from a
596
+ // live process stays fatal for our own UID and falls back to argv only for another UID.
597
+ if (code === 'EACCES' || code === 'EPERM' || (code === 'ENOENT' && owner !== process.getuid?.())) {
595
598
  if (!argvRead.has(pid)) {
596
599
  argvRead.add(pid);
597
600
  let argv: string | undefined;
@@ -0,0 +1,18 @@
1
+ import type { Command } from 'commander';
2
+ import { runScenarioFile } from '../ux-sim/scenario.js';
3
+
4
+ export function registerSimCommands(program: Command): void {
5
+ const sim = program.command('sim').description('격리 시나리오를 실행하고 화면·로그 기대값을 대조한다');
6
+ sim.command('run <scenario-file>')
7
+ .description('등록된 UX simulation 시나리오를 test 우주에서 실행한다')
8
+ .action(async (scenarioFile: string) => {
9
+ try {
10
+ const result = await runScenarioFile(scenarioFile);
11
+ console.log(JSON.stringify(result));
12
+ if (!result.pass) process.exitCode = 1;
13
+ } catch (error) {
14
+ console.error(`sim run: ${error instanceof Error ? error.message : String(error)}`);
15
+ process.exitCode = 2;
16
+ }
17
+ });
18
+ }
@@ -14,7 +14,8 @@ import { assignedVersions, releasedVersion, validateVersion } from '../release-l
14
14
  import { compareVersions } from '../directives/version-at.js';
15
15
  import { cardsBoard, countBoardTasks, INTERNAL_PACK_PROJECT, mergeBoards, releasePackBoard, type BoardNode } from '../task-agent/board.js';
16
16
  import type { Task } from '../task-orchestrator/types.js';
17
- import { cardPrNumber, CLOSED_BY_HAND_EVENT, closeTaskCard, COMPLETION_KINDS, handTask, updateTaskCard, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, nextMoveFor, resolveHandText, readTaskAgentState, readTaskCard, taskAgentStatePath as taskStatePathDefault, shellQuote, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
17
+ import { cardPrNumber, CLOSED_BY_HAND_EVENT, closeTaskCard, COMPLETION_KINDS, handTask, updateTaskCard, LIVE_MOVE_HISTORY_EVENT, LIVE_MOVE_RESULT_EVENT, nextMoveFor, resolveHandText, readTaskAgentState, readTaskCard, runTagChange, taskAgentStatePath as taskStatePathDefault, taskCardLabelContext, shellQuote, TASK_CARD_PREFIX, TASK_SEATS, type CompletionKind, type TaskCard, type TaskLaunchContext, type TaskLaunchReceipt, type TaskLauncher, type TaskSeat } from '../task-agent/task-hand.js';
18
+ import { RUN_TAG_KEYS, runIdentityFieldText, runPriorityClass } from '../task-agent/run-identity.js';
18
19
  import { readCardSalvageBranch, recordWiringLiveVerified, refreshCardRunBinding, type CardRunEvidenceDeps } from '../task-agent/card-evidence.js';
19
20
  import { captureReviewResults } from '../task-agent/review-result-capture.js';
20
21
  import { replayRemoteCardMoves } from '../task-agent/shadow.js';
@@ -33,6 +34,9 @@ export interface TasksCliDeps {
33
34
  bearerToken?: string;
34
35
  fetch?: typeof fetch;
35
36
  output?: (line: string) => void;
37
+ /** green-sweep entrypoint test seam: keep the actual CLI decision chain, replace only process reads. */
38
+ greenSweepChecklist?: typeof listChecklist;
39
+ greenSweepRun?: (command: string, args: string[]) => { status: number | null; stdout: string };
36
40
  /** `task hand --live` 의 발사기(시험 주입). 기본은 운영 config-dir 로 `harness say` 를 떼어 띄운다. */
37
41
  taskLauncher?: TaskLauncher;
38
42
  /** TA-REVIEW-RESULT-CAPTURE — `tasks show` 의 리뷰 결과 회수 시각(시험 주입 · 기본 지금). */
@@ -185,6 +189,12 @@ async function tryRemoteParent(args: string[], cwd: string | undefined, context:
185
189
  failed(targets[0]!, ['project-target-is-local']);
186
190
  return null;
187
191
  }
192
+ // ⛔ R7(2026-10-16): 시험 안에서 실 ssh 원격 발사는 명시 허용 없이 거부한다(가짜 ssh 주입은 통과).
193
+ // ⚠️ 이 가드는 hold(launchHoldActive) 판정보다 «앞»이어야 한다 — hold 는 preflightParentHost 의 입력일 뿐이고,
194
+ // preflightParentHost(parent-host.ts `preflightParentHost` 첫 줄)는 hold 와 무관하게 먼저 실 ssh 를 부른다(다중 대상이면
195
+ // 그 앞의 readParentHostCapacity 도 ssh). 가드를 아래로 내리면 hold 경로에서 시험이 실 ssh 를 쏜다(R7 사고 모양).
196
+ // hold 경로를 재는 시험은 deps.ssh 가짜 또는 parentHost:null 을 주입한다(real-launch-guard.test 가 이 순서를 문다).
197
+ if (!deps.ssh) (await import('../task-agent/real-launch-guard.js')).refuseRealLaunchUnderTest('remote-parent-ssh', targets.map((target) => target.host).join(','));
188
198
  let launchHoldActive = false;
189
199
  try {
190
200
  if (deps.launchHoldActive) launchHoldActive = deps.launchHoldActive();
@@ -236,6 +246,8 @@ export async function defaultTaskLauncher(args: string[], cwd?: string, context?
236
246
  const remote = await tryRemoteParent(args, cwd, context, deps);
237
247
  if (remote) return remote;
238
248
  }
249
+ // ⛔ R7(2026-10-16): 시험 안에서 실 `elanous harness say` 를 띄우는 것은 명시 허용 없이 거부한다(가짜 spawn 주입은 통과).
250
+ if (!deps.spawn) (await import('../task-agent/real-launch-guard.js')).refuseRealLaunchUnderTest('local-harness-spawn', args.slice(0, 2).join(' '));
239
251
  const spawn = deps.spawn ?? ((await import('node:child_process')).spawn as unknown as DetachedSpawn);
240
252
  const { getElanousConfigDirOverride } = await import('../elanous-config-dir.js');
241
253
  const { prodInstanceRoot } = await import('../instance/resolve.js');
@@ -366,9 +378,26 @@ function runLinkLine(card: TaskCard): string[] {
366
378
  return [`런: ${card.runId} · 골: ${card.goalId ?? '-'} · PR: ${pr}${card.runChildId ? ` · 자식 런: ${card.runChildId}` : ''}`];
367
379
  }
368
380
 
381
+ /** RUN-IDENTITY-TAGS — 신분 한 줄 + Pod 라벨 한 줄(원장 정본 2줄 렌더 · 신분 없는 카드는 «미기록»으로 적고 기본값 정책을 밝힌다). */
382
+ function cardIdentityLines(card: TaskCard): string[] {
383
+ const identity = card.identity;
384
+ const { labels } = taskCardLabelContext({ id: card.id });
385
+ // 경계: Pod 에 실제로 붙는 라벨은 카드 id 하나뿐이다 — 신분 값은 Pod 라벨에 아직 안 실린다(RUN-IDENTITY-ADMIT 몫). 화면도 그렇게 말한다.
386
+ const podLine = `Pod 라벨 ${Object.entries(labels).map(([key, value]) => `${key}=${value}`).join(' ')} (신분 값은 Pod 라벨 미탑재 — RUN-IDENTITY-ADMIT)`;
387
+ if (!identity) return [`신분 미기록 — 원장에 identity 없음 · 승인·선점은 기본 class=${runPriorityClass(identity)} 로 읽는다`, podLine];
388
+ // ⛔ 모르는 칸을 기본값으로 보이지 않는다 — 원장에 없는 칸은 «미기록»으로 적는다(확인된 칸만 값으로).
389
+ const identityText = RUN_TAG_KEYS.map((key) => `${key}=${runIdentityFieldText(identity, key)}`).join(' · ');
390
+ const originParts = [identity.origin?.checklistId, identity.origin?.version, identity.origin?.seat, identity.origin?.launcher].filter((part) => part !== undefined);
391
+ return [
392
+ `신분 ${identityText}${originParts.length > 0 ? ` — 출생 ${originParts.join(' · ')}` : ''}`,
393
+ podLine,
394
+ ];
395
+ }
396
+
369
397
  function taskCardLines(card: TaskCard): string[] {
370
398
  return [
371
399
  [card.id, card.status, card.seat ?? '-', card.checklistId ?? '-', card.createdAt, card.text].join('\t'),
400
+ ...cardIdentityLines(card),
372
401
  ...(card.mission ? [`미션: ${card.mission} · after: ${card.after?.length ? card.after.join(', ') : '-'}`] : []),
373
402
  ...runLinkLine(card),
374
403
  ...liveMoveLines(card),
@@ -786,7 +815,9 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
786
815
  .action((opts: { version: string; cell?: string; traffic?: string; json?: boolean }) => {
787
816
  try {
788
817
  validateVersion(opts.version);
789
- const snapshot = listChecklist(opts.version);
818
+ const snapshot = (deps.greenSweepChecklist ?? listChecklist)(opts.version);
819
+ const run = deps.greenSweepRun ?? ((command: string, args: string[]) => spawnSync(command, args,
820
+ { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000 }));
790
821
  const cards = Object.values(readTaskAgentState<{ tasks?: Record<string, TaskCard> }>(deps.taskStatePath ?? taskStatePathDefault()).tasks ?? {});
791
822
  let holds: Set<string> | null = null;
792
823
  if (opts.traffic) {
@@ -800,14 +831,11 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
800
831
  }
801
832
  const prCache = new Map<number, GreenSweepPr | null>();
802
833
  const ambiguousPrs = ambiguousGreenSweepPrs(snapshot.items, opts.version, cards);
803
- const origin = spawnSync('git', ['remote', 'get-url', 'origin'],
804
- { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000 });
834
+ const origin = run('git', ['remote', 'get-url', 'origin']);
805
835
  const originRepo = origin.status === 0
806
836
  ? /github\.com[:/]([^/\s]+\/[^/\s]+?)(?:\.git)?$/i.exec(origin.stdout.trim())?.[1]?.toLowerCase() : undefined;
807
- const localMain = spawnSync('git', ['rev-parse', 'origin/main'],
808
- { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000 });
809
- const remoteMain = spawnSync('git', ['ls-remote', 'origin', 'refs/heads/main'],
810
- { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000 });
837
+ const localMain = run('git', ['rev-parse', 'origin/main']);
838
+ const remoteMain = run('git', ['ls-remote', 'origin', 'refs/heads/main']);
811
839
  const localMainSha = localMain.status === 0 ? localMain.stdout.trim() : '';
812
840
  const remoteMainSha = remoteMain.status === 0 ? remoteMain.stdout.trim().split(/\s+/)[0] : '';
813
841
  const mainFresh = /^[a-f0-9]{40}$/i.test(localMainSha) && localMainSha === remoteMainSha;
@@ -817,8 +845,7 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
817
845
  return candidates.map((candidate) => {
818
846
  let pr = prCache.get(candidate.pr);
819
847
  if (pr === undefined) {
820
- const view = spawnSync('gh', ['pr', 'view', String(candidate.pr), '--json', 'number,state,mergeCommit,url'],
821
- { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000 });
848
+ const view = run('gh', ['pr', 'view', String(candidate.pr), '--json', 'number,state,mergeCommit,url']);
822
849
  try {
823
850
  if (view.status !== 0) throw new Error('gh failed');
824
851
  const parsed = JSON.parse(view.stdout) as { number?: number; state?: string; mergeCommit?: { oid?: string }; url?: string };
@@ -827,16 +854,31 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
827
854
  } catch { pr = null; }
828
855
  prCache.set(candidate.pr, pr);
829
856
  }
830
- const sha = pr?.mergeSha;
857
+ // A component PR stays CLOSED after a merged train. Reverify the integration PR
858
+ // recorded on the card before using its merge commit as landing evidence.
859
+ let landingPr = pr;
860
+ const train = candidate.card?.trainLanding;
861
+ if (pr?.state === 'CLOSED' && train?.componentPr === candidate.pr && /^[a-f0-9]{40}$/i.test(train.mergeSha)) {
862
+ const view = run('gh', ['pr', 'view', String(train.integrationPr), '--json', 'number,state,mergeCommit']);
863
+ try {
864
+ if (view.status === 0) {
865
+ const parsed = JSON.parse(view.stdout) as { number?: number; state?: string; mergeCommit?: { oid?: string } };
866
+ if (parsed.number === train.integrationPr && parsed.state === 'MERGED'
867
+ && parsed.mergeCommit?.oid?.toLowerCase() === train.mergeSha.toLowerCase()) {
868
+ landingPr = { ...pr, state: 'MERGED', mergeSha: train.mergeSha, viaTrain: { integrationPr: train.integrationPr } };
869
+ }
870
+ }
871
+ } catch { /* Unverified train is still a CLOSED component PR. */ }
872
+ }
873
+ const sha = landingPr?.mergeSha;
831
874
  const prRepo = /^https:\/\/github\.com\/([^/]+\/[^/]+)\/pull\/\d+(?:\/|$)/i.exec(pr?.url ?? '')?.[1]?.toLowerCase();
832
875
  const repositoryMatches = originRepo && prRepo ? originRepo === prRepo : null;
833
876
  const ancestor = !mainFresh || !sha || !/^[a-f0-9]{40}$/i.test(sha) ? null : (() => {
834
- const check = spawnSync('git', ['merge-base', '--is-ancestor', sha, 'origin/main'],
835
- { cwd: process.cwd(), encoding: 'utf8', timeout: 20_000 });
877
+ const check = run('git', ['merge-base', '--is-ancestor', sha, 'origin/main']);
836
878
  return check.status === 0 ? true : check.status === 1 ? false : null;
837
879
  })();
838
880
  const decision = decideGreenSweep({ item, candidate, candidateCount: candidates.length,
839
- pr: pr ?? null, ancestor, hold: holds === null ? null : holds.has(item.id), repositoryMatches,
881
+ pr: landingPr ?? null, ancestor, hold: holds === null ? null : holds.has(item.id), repositoryMatches,
840
882
  ambiguousAcrossCells: ambiguousPrs.has(candidate.pr) });
841
883
  observeGreenSweep(decision);
842
884
  return decision;
@@ -954,9 +996,13 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
954
996
  .option('--ta-land', 'TA-LIVE-LAND-2 — 호스트는 재게이트만 하고 병합은 TASK-AGENT 의 propose-land(`pr land --expected-head`)에 맡긴다 · 카드 taLand ⊕ 발사 env ELANOUS_TA_LAND=1 · taskAgent.liveMoves 에 propose-land 가 없으면 종전대로 호스트가 병합')
955
997
  .option('--child-llm <provider/model>', 'TASKS-HAND-CHILD-LLM — 구현 자식 LLM(예: grok/grok-4.7) → 발사 인자 --child-llm-provider <provider> --child-llm-model <model> · «첫» `/` 에서만 가른다(모델 id 의 `/` 는 보존) · openrouter 는 모델 id 가 openrouter/ 접두를 포함하므로 전체를 모델로(openrouter/z-ai/glm-5.3 → --child-llm-model openrouter/z-ai/glm-5.3) · 카드 childLlm · 안 주면 명령·카드 무변경')
956
998
  .option('--child-llm-effort <level>', '구현 자식 추론 노력 → 발사 인자 --child-llm-effort(검증은 하니스 · --child-llm 과 함께)')
999
+ .addOption(new Option('--tier <level>', '디스패처 난이도(하|중|상|특) — 카드에 보존해 수리 모델 정책에 사용').choices(['하', '중', '상', '특']))
1000
+ .option('--tag <k=v>', 'RUN-IDENTITY-TAGS — 출생 신분을 덮는다(class|care|rights|protect 의 k=v · 반복: --tag class=gate --tag protect=true) — 카드 원장 identity 에 남는다', (value: string, previous: string[] | undefined) => [...(previous ?? []), value])
957
1001
  .option('--json', 'JSON 출력')
958
- .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; version?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; json?: boolean }) => {
1002
+ .action(async (text: string | undefined, opts: { seat?: TaskSeat; checklist?: string; version?: string; completion?: CompletionKind; mission?: string; project?: string; target?: string; goal?: string; milestone?: string; live?: boolean; taLand?: boolean; childLlm?: string; childLlmEffort?: string; tier?: TaskCard['tier']; tag?: string[]; json?: boolean }) => {
959
1003
  const suppliedText = text !== undefined;
1004
+ /** RUN-IDENTITY-TAGS — 칸을 찾은 판(출생 신분이 그 판의 칸 우선순위를 읽는다 · 개발 판 밖 칸도). */
1005
+ let birthBoardVersion: string | undefined;
960
1006
  if (opts.version !== undefined && opts.checklist === undefined) {
961
1007
  out('--version 은 --checklist 와 함께 준다');
962
1008
  process.exitCode = 1;
@@ -1014,6 +1060,7 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1014
1060
  return;
1015
1061
  }
1016
1062
  if (matches.length > 1) console.error(`⚠ 체크리스트 칸 ${opts.checklist} 중복: ${matches.map((match) => match.version).join(', ')} — 가장 가까운 판 ${matches[0]!.version} 선택 (--version 으로 고정 가능)`);
1063
+ birthBoardVersion = matches[0]!.version;
1017
1064
  if (opts.mission === undefined && text === undefined) text = title;
1018
1065
  }
1019
1066
  if (opts.checklist !== undefined && opts.mission === undefined && suppliedText && !text!.split(/\r?\n/, 1)[0]!.startsWith('대상 경로:')) {
@@ -1032,8 +1079,8 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1032
1079
  process.exitCode = 1;
1033
1080
  return;
1034
1081
  }
1035
- if (opts.mission !== undefined && (opts.completion !== undefined || opts.project !== undefined || opts.goal !== undefined || opts.milestone !== undefined || opts.taLand === true || opts.childLlm !== undefined || opts.childLlmEffort !== undefined)) {
1036
- out('--completion/--project/--target/--goal/--milestone/--ta-land/--child-llm 은 과제 한 줄에만 준다 — --mission 조각은 종전처럼 code-pr 이다');
1082
+ if (opts.mission !== undefined && (opts.completion !== undefined || opts.project !== undefined || opts.goal !== undefined || opts.milestone !== undefined || opts.taLand === true || opts.childLlm !== undefined || opts.childLlmEffort !== undefined || opts.tier !== undefined || opts.tag !== undefined)) {
1083
+ out('--completion/--project/--target/--goal/--milestone/--ta-land/--child-llm/--tier/--tag 는 과제 한 줄에만 준다 — --mission 조각은 종전처럼 code-pr 이다');
1037
1084
  process.exitCode = 1;
1038
1085
  return;
1039
1086
  }
@@ -1089,6 +1136,9 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1089
1136
  ...(opts.taLand === true ? { taLand: true } : {}),
1090
1137
  ...(opts.childLlm !== undefined ? { childLlm: opts.childLlm } : {}),
1091
1138
  ...(opts.childLlmEffort !== undefined ? { childLlmEffort: opts.childLlmEffort } : {}),
1139
+ ...(opts.tier !== undefined ? { tier: opts.tier } : {}),
1140
+ ...(opts.tag !== undefined ? { tags: opts.tag } : {}),
1141
+ ...(birthBoardVersion !== undefined ? { checklistVersion: birthBoardVersion } : {}),
1092
1142
  ...(deps.taskStatePath ? { statePath: deps.taskStatePath } : {}),
1093
1143
  ...(deps.taskCompositionRoot ? { compositionRoot: deps.taskCompositionRoot } : {}),
1094
1144
  launcher: deps.taskLauncher ?? defaultTaskLauncher,
@@ -1096,10 +1146,12 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1096
1146
  if (opts.json) out(JSON.stringify(result));
1097
1147
  else {
1098
1148
  out(`${result.card.id}\t${result.mode}\t${result.launched ? 'launched' : 'not launched'}`);
1099
- out(`elanous ${result.move.command!.map(shellQuote).join(' ')}`);
1149
+ if (result.move.command) out(`elanous ${result.move.command.map(shellQuote).join(' ')}`);
1150
+ else out(result.move.reason);
1100
1151
  if (result.cwd) out(`(cwd: ${result.cwd})`);
1101
1152
  if (result.card.taLand) out('(ta-land — 발사 env ELANOUS_TA_LAND=1 · 원격 또는 로컬 부모 · taskAgent.liveMoves 에 propose-land 가 있으면 병합은 TASK-AGENT 몫, 없으면 종전대로 호스트 병합)');
1102
- if (!result.launched) out('(shadow — 띄우지 않았다 · 띄우려면 --live)');
1153
+ if (!result.launched && result.card.alreadyDoneCandidate) out('(main 증거 통과 — 발사 0 · green 후보만 기록, 주인 판정 대기)');
1154
+ else if (!result.launched) out('(shadow — 띄우지 않았다 · 띄우려면 --live)');
1103
1155
  }
1104
1156
  } catch (error) {
1105
1157
  out(error instanceof Error ? error.message : '과제 넘기기 실패');
@@ -1107,6 +1159,32 @@ export function registerTasksCommands(program: Command, deps: TasksCliDeps = {})
1107
1159
  }
1108
1160
  });
1109
1161
 
1162
+ tasks.command('tag <id> <k=v>')
1163
+ .description('RUN-IDENTITY-TAGS — 카드의 런 신분 태그를 바꾼다(class|care|rights|protect 의 k=v · 카드 history 에 감사 줄 run-tag-change {from, to, by, reason} 이 남는다 · 카드 상태 파일이 원장 정본 · 목록 밖 값은 거부)')
1164
+ .option('--by <seat>', '바꾼 자리(예: OP·MK·TC·UX) — 안 주면 호출 자리 ELANOUS_TRACK, 그것도 없으면 «unknown» 으로 감사 줄에 적는다(지어내지 않는다)')
1165
+ .option('--reason <text>', '왜 바꾸나 — 감사 줄에 남긴다')
1166
+ .option('--json', '바뀐 카드를 JSON 으로 출력')
1167
+ .action((id: string, kv: string, opts: { by?: string; reason?: string; json?: boolean }) => {
1168
+ try {
1169
+ const by = opts.by?.trim() || process.env.ELANOUS_TRACK?.trim() || 'unknown';
1170
+ const card = runTagChange(id, { tag: kv, by, ...(opts.reason !== undefined ? { reason: opts.reason } : {}) }, deps.taskStatePath ?? taskStatePathDefault());
1171
+ if (card === undefined) {
1172
+ out(`카드가 없습니다: ${id}`);
1173
+ process.exitCode = 1;
1174
+ return;
1175
+ }
1176
+ if (opts.json) {
1177
+ out(JSON.stringify(card));
1178
+ return;
1179
+ }
1180
+ out(`${card.id}\t${kv}`);
1181
+ for (const line of cardIdentityLines(card)) out(line);
1182
+ } catch (error) {
1183
+ out(error instanceof Error ? error.message : '태그 바꾸기 실패');
1184
+ process.exitCode = 1;
1185
+ }
1186
+ });
1187
+
1110
1188
  tasks.command('hand-move <id>')
1111
1189
  .description('HAND-MOVE-LEDGER — 자리가 손으로 마무리한 수(기존 실패 면제 · diff 재적용 · 범위 자르기 · 쪼개기 · 다른 모델 의견)를 그 카드 history 에 한 줄로 남긴다 — live-move 와 같은 원장 칸 · 기존 줄은 건드리지 않는다')
1112
1190
  .requiredOption('--kind <kind>', `손으로 쓴 수 (${HAND_MOVE_KINDS.join('|')})`)
@@ -69,6 +69,19 @@ export function isOperationalQuery(text: string | undefined): boolean {
69
69
  return !!text && OPERATIONAL_QUERY.test(text);
70
70
  }
71
71
 
72
+ /** 칸 3 a59c1c24c — «맥락 먼저 판단»의 공통 게이트 결정: 개시 대기 소진 → 표면 스위치 → 운영 질문 스킵.
73
+ * Telegram(maybeSendContextFirst)과 Discord(maybeSendContextFirst)가 같은 한 지점에서 판단한다. */
74
+ export function takeContextFirstOpening(opts: {
75
+ gate: ReturnType<typeof createContextFirstGate>;
76
+ key: string;
77
+ text?: string;
78
+ enabled?: boolean;
79
+ }): boolean {
80
+ if (!opts.gate.take(opts.key)) return false;
81
+ if (opts.enabled === false) return false;
82
+ return !isOperationalQuery(opts.text);
83
+ }
84
+
72
85
  export function renderContextFirst(
73
86
  read: (options: {}, deps?: ContextNowDeps) => ContextNowAnswer,
74
87
  deps: ContextNowDeps | undefined,
@@ -2,7 +2,7 @@ import { existsSync, lstatSync, readdirSync, readFileSync } from 'node:fs';
2
2
  import { join } from 'node:path';
3
3
  import { isMainThread, parentPort, workerData, Worker } from 'node:worker_threads';
4
4
  import { queryRunningRuns, type QueriedRunningRunsResult } from '../self-implement/running-runs.js';
5
- import { loadRunLedger } from '../self-implement/run-ledger.js';
5
+ import { loadRunLedger, resolveFederatedRunLedgerDirectories, runLedgerDir } from '../self-implement/run-ledger.js';
6
6
  import { localLoopRows } from '../dashboard/slash-runtime/loops-table.js';
7
7
  import { checkBrand } from '../../scripts/brand/check.js';
8
8
  import { debug, redactSecretText } from '../debug/log.js';
@@ -69,7 +69,15 @@ const releaseSource = 'elanous://graph-runs/release-loop';
69
69
  const scheduleSource = 'elanous://schedules';
70
70
  const oneLine = (text: string) => redactSecretText(text.split(/\r?\n/, 1)[0] ?? '').slice(0, 120);
71
71
 
72
- function runningRunFacts(now: Date, queryRuns: () => QueriedRunningRunsResult = () => queryRunningRuns({ includeTest: false, caller: 'context-now' })): Extract<ContextFact, { kind: 'run' }>[] {
72
+ // src/dashboard/slash-runtime/dashboard-handlers.ts:buildDashboardSlashRegistry /now calls contextNowInWorker;
73
+ // contextNow → queryRunningRuns → queryFederatedUnfinishedRunLedgers → queryUnfinishedRunLedgers (persisted scan index).
74
+ function runningRunFacts(now: Date, queryRuns: () => QueriedRunningRunsResult = () => queryRunningRuns({
75
+ includeTest: false,
76
+ caller: 'context-now',
77
+ noCache: false,
78
+ }, {
79
+ ledgerDirectories: () => [...new Set([runLedgerDir(), ...resolveFederatedRunLedgerDirectories({ includeTest: false })])],
80
+ })): Extract<ContextFact, { kind: 'run' }>[] {
73
81
  const observed = queryRuns();
74
82
  const unreadable = observed.completeness === 'partial' || observed.pty.unreadable.length || !!observed.phases?.unreadableTargetCount;
75
83
  const facts = observed.entries.filter(entry => observed.countedStatuses.includes(entry.status)).slice(0, 8).flatMap(entry => {
@@ -239,6 +247,7 @@ export function scanContextNowInWorker(options: Parameters<typeof contextNow>[0]
239
247
  createWorker: () => Worker = () => new Worker(new URL(import.meta.url), { workerData: { kind: 'context-now' } }),
240
248
  timeoutMs = WORKER_SCAN_TIMEOUT_MS): Promise<ContextNowAnswer> {
241
249
  const worker = createWorker();
250
+ const startedAt = Date.now();
242
251
  return new Promise((resolve, reject) => {
243
252
  let settled = false;
244
253
  const timeout = setTimeout(() => {
@@ -249,6 +258,8 @@ export function scanContextNowInWorker(options: Parameters<typeof contextNow>[0]
249
258
  if (settled) return;
250
259
  settled = true;
251
260
  clearTimeout(timeout);
261
+ // 첫 호출 지연은 색인과 무관하게 «따로» 재야 판정선과 비교할 수 있다 — 스캔 자체의 ms 를 남긴다.
262
+ debug.log('context.now', 'worker-answer', { topic: options?.topic ?? null, ok: !error, ms: Date.now() - startedAt });
252
263
  void worker.terminate();
253
264
  if (error) reject(error);
254
265
  else resolve(answer!);
@@ -0,0 +1,79 @@
1
+ import type { Database } from 'bun:sqlite';
2
+ import { debug, redactSecretText } from '../debug/log.js';
3
+ import { openSurfaceEventsDb, recordEvent, surfaceEventsDbPath } from '../domains/surface-events.js';
4
+ import { canonicalSeatId } from '../msg/msg-store.js';
5
+
6
+ export const OPS_EVENT_KINDS = [
7
+ 'land.start', 'land.refused', 'land.merged',
8
+ 'review.verdict',
9
+ 'gate.rc',
10
+ 'cell.opened', 'cell.hold',
11
+ 'config.set',
12
+ ] as const;
13
+ export type OpsEventKind = typeof OPS_EVENT_KINDS[number];
14
+
15
+ export interface OpsEventInput {
16
+ kind: OpsEventKind;
17
+ /** One nonempty line describing the ops fact; multi-line input keeps only the first line. */
18
+ text: string;
19
+ /** Optional locator — PR number, checklist cell id, config key, release version. */
20
+ ref?: string;
21
+ /** Optional seat identity, normalized by the shared message-address registry. */
22
+ seat?: string;
23
+ /** Optional ISO timestamp; unparseable values are dropped. */
24
+ at?: string;
25
+ }
26
+
27
+ export interface OpsEventDeps {
28
+ db?: Database;
29
+ /** Injection seam for tests; defaults to the surface-events recordEvent. */
30
+ record?: typeof recordEvent;
31
+ }
32
+
33
+ /** Persist a one-line harness ops fact (land flow · review verdict · release gate ·
34
+ * checklist cell · config set) into the existing surface_events.db journal via
35
+ * recordEvent (src/domains/surface-events.ts) so pr-cli / release-loop operations
36
+ * become recallable observations instead of vanishing side effects.
37
+ * Fail-soft contract: any write-path failure — db open error, recordEvent throw,
38
+ * schema mismatch — is caught, logged to debug, and swallowed. This writer never
39
+ * throws and never rejects; callers fire it as a side call without touching their
40
+ * own control flow. Malformed input (non-object, unknown kind, empty text) is a
41
+ * silent no-op. Returns the recorded event id, or null when nothing was recorded. */
42
+ export function emitOpsEvent(input: OpsEventInput, deps: OpsEventDeps = {}): string | null {
43
+ if (!input || typeof input !== 'object') return null;
44
+ let db: Database | undefined = deps.db;
45
+ let ownDb = false;
46
+ try {
47
+ if (!(OPS_EVENT_KINDS as readonly string[]).includes(input.kind)) return null;
48
+ const oneLine = (value: unknown): string =>
49
+ redactSecretText(String(value ?? '').split(/\r?\n/, 1)[0] ?? '').trim();
50
+ const text = oneLine(input.text);
51
+ if (!text) return null;
52
+ const ref = oneLine(input.ref) || null;
53
+ const seat = typeof input.seat === 'string' && input.seat.trim() ? canonicalSeatId(input.seat) : undefined;
54
+ const at = typeof input.at === 'string' && !Number.isNaN(Date.parse(input.at)) ? input.at : undefined;
55
+ if (!db) {
56
+ // Test runners must never fall through to the user's production memory DB
57
+ // (same guard as recordInboundTurn in domains/surface-events.ts).
58
+ const testRunner = process.env.NODE_ENV === 'test' || process.env.BUN_TEST !== undefined;
59
+ db = openSurfaceEventsDb(testRunner
60
+ ? (process.env.ELANOUS_STATE_DIR?.trim() ? surfaceEventsDbPath() : ':memory:')
61
+ : surfaceEventsDbPath());
62
+ ownDb = true;
63
+ }
64
+ const record = deps.record ?? recordEvent;
65
+ return record(db, {
66
+ surface: 'ops', direction: 'outbound', domain: 'elanous', category: 'ops',
67
+ kind: input.kind, text, summary: text.slice(0, 120),
68
+ refs: JSON.stringify({ kind: input.kind, ref, url: null, ...(seat ? { seat } : {}) }),
69
+ ...(at ? { ts: at } : {}),
70
+ });
71
+ } catch (error) {
72
+ try { debug.log('context.bus', 'write-failed', {
73
+ kind: input.kind, reason: error instanceof Error ? error.message : String(error),
74
+ }, { level: 'warn' }); } catch { /* A broken logger cannot change the caller's result. */ }
75
+ return null;
76
+ } finally {
77
+ if (ownDb && db) { try { db.close(); } catch { /* close failure is not the caller's problem */ } }
78
+ }
79
+ }
@@ -8,7 +8,7 @@ export interface LeaseHolderSnapshot {
8
8
  }
9
9
 
10
10
  export interface LeaseHolderView {
11
- get(): Promise<LeaseHolderSnapshot>;
11
+ get(options?: { fresh?: boolean }): Promise<LeaseHolderSnapshot>;
12
12
  }
13
13
 
14
14
  export function createLeaseHolderView({ machine, read, ttlMs = 10_000, now = Date.now }: {
@@ -20,17 +20,21 @@ export function createLeaseHolderView({ machine, read, ttlMs = 10_000, now = Dat
20
20
  let cached: LeaseHolderSnapshot | undefined;
21
21
  let measuredAt = 0;
22
22
  let pending: Promise<LeaseHolderSnapshot> | undefined;
23
+ const readSnapshot = async (): Promise<LeaseHolderSnapshot> => {
24
+ let result: RoleLeaseRead;
25
+ try { result = await read(); }
26
+ catch { result = { kind: 'unmeasured', why: 'read failed' }; }
27
+ return result.kind === 'present'
28
+ ? { holder: result.doc.holder, generation: result.doc.generation, iAmHolder: result.doc.holder === machine, known: true }
29
+ : { holder: null, generation: null, iAmHolder: false, known: false };
30
+ };
23
31
  return {
24
- get() {
32
+ get(options) {
33
+ if (options?.fresh) return readSnapshot();
25
34
  if (cached && now() - measuredAt < ttlMs) return Promise.resolve(cached);
26
35
  if (pending) return pending;
27
36
  pending = (async () => {
28
- let result: RoleLeaseRead;
29
- try { result = await read(); }
30
- catch { result = { kind: 'unmeasured', why: 'read failed' }; }
31
- const snapshot: LeaseHolderSnapshot = result.kind === 'present'
32
- ? { holder: result.doc.holder, generation: result.doc.generation, iAmHolder: result.doc.holder === machine, known: true }
33
- : { holder: null, generation: null, iAmHolder: false, known: false };
37
+ const snapshot = await readSnapshot();
34
38
  cached = snapshot;
35
39
  measuredAt = now();
36
40
  return snapshot;