elanous 0.2.41 → 0.2.43

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 (796) 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/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_buildManifest.js +1 -1
  4. package/apps/pwa/out/_next/static/chunks/{2fe2c302.41b517f88d6fe502.js → 0966f8a1.745fcd44f64a87ea.js} +1 -1
  5. package/apps/pwa/out/_next/static/chunks/{385e4574.e9886ab32759eda3.js → 0ad6802e.ae7afb63fdcb4491.js} +1 -1
  6. package/apps/pwa/out/_next/static/chunks/114.2b90424d1a3ce84c.js +1 -0
  7. package/apps/pwa/out/_next/static/chunks/1151-5c2bb8f002ca2dd6.js +1 -0
  8. package/apps/pwa/out/_next/static/chunks/1200.6a37c202f9f17e9a.js +226 -0
  9. package/apps/pwa/out/_next/static/chunks/1261-a616d5728e02e624.js +1 -0
  10. package/apps/pwa/out/_next/static/chunks/1313-19f737e0222c4444.js +1 -0
  11. package/apps/pwa/out/_next/static/chunks/1357.3bbef3976c37f94a.js +1 -0
  12. package/apps/pwa/out/_next/static/chunks/1362-20adddfaf662b0fa.js +1 -0
  13. package/apps/pwa/out/_next/static/chunks/{6874.d5cf7eb8edb2cabe.js → 1406.a1dc2ab6f8449374.js} +2 -2
  14. package/apps/pwa/out/_next/static/chunks/1737-9491fc6ab29b9ec6.js +1 -0
  15. package/apps/pwa/out/_next/static/chunks/1803-4f91a8e7dcaf042c.js +1 -0
  16. package/apps/pwa/out/_next/static/chunks/{5744.b9415e18ad623100.js → 1961.a81b12872c3e93a9.js} +1 -1
  17. package/apps/pwa/out/_next/static/chunks/1970cf59.2d4d8ce5d6c81853.js +1 -0
  18. package/apps/pwa/out/_next/static/chunks/1971-8890f3962ba7ee0a.js +1 -0
  19. package/apps/pwa/out/_next/static/chunks/2073-ba274e00e4f9efb4.js +1 -0
  20. package/apps/pwa/out/_next/static/chunks/{5471.1e611302ed3a7c53.js → 2144.25b292396712196d.js} +2 -2
  21. package/apps/pwa/out/_next/static/chunks/{3230-49298c3b73ef2268.js → 2268-53861f339e0b65a2.js} +1 -1
  22. package/apps/pwa/out/_next/static/chunks/{9834.63ab2bbc3153172e.js → 2312.0c8b61e22d3136d7.js} +1 -1
  23. package/apps/pwa/out/_next/static/chunks/{1800.f7ff51dc4978a958.js → 2573.387a707f6f9d720c.js} +2 -2
  24. package/apps/pwa/out/_next/static/chunks/273.f156eee28f11af77.js +1 -0
  25. package/apps/pwa/out/_next/static/chunks/2873.d2140e5a82546401.js +1 -0
  26. package/apps/pwa/out/_next/static/chunks/{9048.212083de42d25be3.js → 3072.01338851ca21a6f7.js} +2 -2
  27. package/apps/pwa/out/_next/static/chunks/3091.a5a4143dea33d197.js +90 -0
  28. package/apps/pwa/out/_next/static/chunks/3095.dc44586a5f83b86d.js +1 -0
  29. package/apps/pwa/out/_next/static/chunks/{2263.e09b6edea33bad2d.js → 3113.d7472bbc27d580c7.js} +1 -1
  30. package/apps/pwa/out/_next/static/chunks/3228-9650b6447b6fa288.js +1 -0
  31. package/apps/pwa/out/_next/static/chunks/3402.44b565b314f2263c.js +1 -0
  32. package/apps/pwa/out/_next/static/chunks/{addc2b32.8c4ff8f0aefe987d.js → 3557ac4a.c8931684475018ad.js} +1 -1
  33. package/apps/pwa/out/_next/static/chunks/360.ae9f9f4c33c395e8.js +79 -0
  34. package/apps/pwa/out/_next/static/chunks/3638.80412ea63aae8f3f.js +286 -0
  35. package/apps/pwa/out/_next/static/chunks/{a0a01613.6d1cca322238d7fe.js → 363bfab3.9623b9f89363541f.js} +1 -1
  36. package/apps/pwa/out/_next/static/chunks/3694.e0099884345f0198.js +64 -0
  37. package/apps/pwa/out/_next/static/chunks/3744.54f87db52acfd1ab.js +1 -0
  38. package/apps/pwa/out/_next/static/chunks/3903.3ef4656c67572764.js +1 -0
  39. package/apps/pwa/out/_next/static/chunks/3935.16701e33f8982dc9.js +1 -0
  40. package/apps/pwa/out/_next/static/chunks/3955.6922286237f2ac2b.js +24 -0
  41. package/apps/pwa/out/_next/static/chunks/3969.272ee7f9fd6c62e5.js +34 -0
  42. package/apps/pwa/out/_next/static/chunks/4199.ce86b281fd0a60b7.js +1 -0
  43. package/apps/pwa/out/_next/static/chunks/4311-6dd3144002cc0c2d.js +1 -0
  44. package/apps/pwa/out/_next/static/chunks/4426-2b230fad00c88930.js +1 -0
  45. package/apps/pwa/out/_next/static/chunks/{530.d26346e18089640a.js → 4445.7990c76b3751a918.js} +1 -1
  46. package/apps/pwa/out/_next/static/chunks/4447-14c5161fa59166c7.js +1 -0
  47. package/apps/pwa/out/_next/static/chunks/4856-b0b8075bba8c53f4.js +1 -0
  48. package/apps/pwa/out/_next/static/chunks/4870-de370d65e73c0bb5.js +1 -0
  49. package/apps/pwa/out/_next/static/chunks/4885-2c989165c4b29fad.js +1 -0
  50. package/apps/pwa/out/_next/static/chunks/4894.fec2ca9e99caefa2.js +1 -0
  51. package/apps/pwa/out/_next/static/chunks/5093.8f04b7f8cb899a95.js +94 -0
  52. package/apps/pwa/out/_next/static/chunks/5122-2bb177cebf89e19a.js +1 -0
  53. package/apps/pwa/out/_next/static/chunks/5154.5f56dc3902e3d275.js +36 -0
  54. package/apps/pwa/out/_next/static/chunks/529.64ff7257180b2ac9.js +1 -0
  55. package/apps/pwa/out/_next/static/chunks/5394.5dabeb0c62293a28.js +93 -0
  56. package/apps/pwa/out/_next/static/chunks/5461.08bf2404ff38ec85.js +1 -0
  57. package/apps/pwa/out/_next/static/chunks/5474-22e08a85583209b2.js +1 -0
  58. package/apps/pwa/out/_next/static/chunks/{1219.7e17964e0e7cd8e5.js → 5564.9e72532188f57586.js} +3 -3
  59. package/apps/pwa/out/_next/static/chunks/5567-265df39ed8fe9dcb.js +1 -0
  60. package/apps/pwa/out/_next/static/chunks/5570-a94ae19811cb2046.js +1 -0
  61. package/apps/pwa/out/_next/static/chunks/5574-b47c9ef2dceff1fd.js +1 -0
  62. package/apps/pwa/out/_next/static/chunks/5628.6ddb2d5ffba4ff4c.js +309 -0
  63. package/apps/pwa/out/_next/static/chunks/5730.43d7ccc09988e646.js +1 -0
  64. package/apps/pwa/out/_next/static/chunks/{1178.1aa9cad0e7695427.js → 5789.2da35c258292e1e5.js} +1 -1
  65. package/apps/pwa/out/_next/static/chunks/{4133.2056bb4d78f621af.js → 5824.da9527b15a3221e5.js} +1 -1
  66. package/apps/pwa/out/_next/static/chunks/5866.366966af47fdde5d.js +1 -0
  67. package/apps/pwa/out/_next/static/chunks/{4527.a69f2894d1bc9f4a.js → 5930.8b4df3b46c32b05a.js} +1 -1
  68. package/apps/pwa/out/_next/static/chunks/5963-c4d8469c52a0828b.js +1 -0
  69. package/apps/pwa/out/_next/static/chunks/6001.ec4049ceb3c43418.js +27 -0
  70. package/apps/pwa/out/_next/static/chunks/6120-471f03db1e299c0c.js +1 -0
  71. package/apps/pwa/out/_next/static/chunks/6175-41479e643aca1878.js +1 -0
  72. package/apps/pwa/out/_next/static/chunks/6291.a2de4f9787637075.js +104 -0
  73. package/apps/pwa/out/_next/static/chunks/6400-6699907c3537436a.js +1 -0
  74. package/apps/pwa/out/_next/static/chunks/6428.1f4327d6ae5fdf9a.js +287 -0
  75. package/apps/pwa/out/_next/static/chunks/644.02cb026fa44bcd0a.js +1 -0
  76. package/apps/pwa/out/_next/static/chunks/6466-6c87d60d3dd174fb.js +1 -0
  77. package/apps/pwa/out/_next/static/chunks/{9507.7026657a2f47eb64.js → 6540.c7bef57ad8f90a87.js} +16 -16
  78. package/apps/pwa/out/_next/static/chunks/6773.d4264665ab31bec0.js +1 -0
  79. package/apps/pwa/out/_next/static/chunks/6822.3c789f1a8443e774.js +1 -0
  80. package/apps/pwa/out/_next/static/chunks/{5574.f35accf4f132b29d.js → 6944.309f4e3ea54d1537.js} +1 -1
  81. package/apps/pwa/out/_next/static/chunks/7261-8ff69d3b2ee671fd.js +1 -0
  82. package/apps/pwa/out/_next/static/chunks/7266.084c6bbc70035140.js +1 -0
  83. package/apps/pwa/out/_next/static/chunks/7271.5c0100e7320aa856.js +1 -0
  84. package/apps/pwa/out/_next/static/chunks/7429-bf5731358c8f2f68.js +1 -0
  85. package/apps/pwa/out/_next/static/chunks/7464.01f7a0ae1215fbe7.js +1 -0
  86. package/apps/pwa/out/_next/static/chunks/7479.0fcad5f37eb64f0c.js +1 -0
  87. package/apps/pwa/out/_next/static/chunks/7483.427a2fe2049e388d.js +148 -0
  88. package/apps/pwa/out/_next/static/chunks/7502-be74718178e13e56.js +1 -0
  89. package/apps/pwa/out/_next/static/chunks/7530.0889722b19572065.js +24 -0
  90. package/apps/pwa/out/_next/static/chunks/7645.5b2ee3ad45c55ea3.js +1 -0
  91. package/apps/pwa/out/_next/static/chunks/7788.7d1c79f1a8e18946.js +1 -0
  92. package/apps/pwa/out/_next/static/chunks/7900.096f455c7c1efc53.js +77 -0
  93. package/apps/pwa/out/_next/static/chunks/7910-6f139bcafd238b9f.js +1 -0
  94. package/apps/pwa/out/_next/static/chunks/7966.f71c8958d1637548.js +1 -0
  95. package/apps/pwa/out/_next/static/chunks/{5947-135e26537d80a6b9.js → 8062-7cd0bcc7f01455ba.js} +3 -3
  96. package/apps/pwa/out/_next/static/chunks/8073.f6cf2f2c71aafbd0.js +1 -0
  97. package/apps/pwa/out/_next/static/chunks/8201.190b94088980f430.js +74 -0
  98. package/apps/pwa/out/_next/static/chunks/8205.282ca4bb62d54a0a.js +62 -0
  99. package/apps/pwa/out/_next/static/chunks/8313-dfa1021bb58a46d6.js +1 -0
  100. package/apps/pwa/out/_next/static/chunks/837-81336ebaca8198a8.js +1 -0
  101. package/apps/pwa/out/_next/static/chunks/8447.7963352ef5f71b76.js +1 -0
  102. package/apps/pwa/out/_next/static/chunks/8574-868e8129525ef6d9.js +1 -0
  103. package/apps/pwa/out/_next/static/chunks/8588.d1c6a2903727ce87.js +149 -0
  104. package/apps/pwa/out/_next/static/chunks/8637.90f92d5c8db4732c.js +1 -0
  105. package/apps/pwa/out/_next/static/chunks/{2743.5d3f76948be32b34.js → 868.6e953be05bcf6dca.js} +2 -2
  106. package/apps/pwa/out/_next/static/chunks/8706-e1fe0309343a2273.js +1 -0
  107. package/apps/pwa/out/_next/static/chunks/8749-06384cdfc4520add.js +1 -0
  108. package/apps/pwa/out/_next/static/chunks/{5964-7e21164a8f2cf0ce.js → 8861-cc1fa1c7b920fa8e.js} +1 -1
  109. package/apps/pwa/out/_next/static/chunks/8967-7dfebf710c9dec9d.js +1 -0
  110. package/apps/pwa/out/_next/static/chunks/{5159.115f1c2ca471386c.js → 8986.8e2e4efbfa655c59.js} +1 -1
  111. package/apps/pwa/out/_next/static/chunks/8997-3c564dbb3b58b055.js +1 -0
  112. package/apps/pwa/out/_next/static/chunks/923.2034d10ae91e9c20.js +1 -0
  113. package/apps/pwa/out/_next/static/chunks/9312.bc1b89c5d4368033.js +1 -0
  114. package/apps/pwa/out/_next/static/chunks/943.39ae5e82f4f1893f.js +1 -0
  115. package/apps/pwa/out/_next/static/chunks/9469.0500480de55fb205.js +32 -0
  116. package/apps/pwa/out/_next/static/chunks/9770.5f75bc6088b16109.js +1 -0
  117. package/apps/pwa/out/_next/static/chunks/9810-2543267050e58b82.js +1 -0
  118. package/apps/pwa/out/_next/static/chunks/9870.8419702475254745.js +8 -0
  119. package/apps/pwa/out/_next/static/chunks/9941-376d1b74d51b01a4.js +1 -0
  120. package/apps/pwa/out/_next/static/chunks/9958.385434ab04241758.js +1 -0
  121. package/apps/pwa/out/_next/static/chunks/{b2271e54.c1de3347976e90b0.js → aa57532f.510551854ff239b1.js} +1 -1
  122. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-deea1450b17cb8dc.js +1 -0
  123. package/apps/pwa/out/_next/static/chunks/app/approvals/page-70985b904f8650ef.js +1 -0
  124. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-a2e15e33e56a4353.js +1 -0
  125. package/apps/pwa/out/_next/static/chunks/app/board/page-fc72ce2db12d6ca9.js +1 -0
  126. package/apps/pwa/out/_next/static/chunks/app/botlab/page-be03e41f9436ebd9.js +1 -0
  127. package/apps/pwa/out/_next/static/chunks/app/bots/page-35a35999382da3f2.js +1 -0
  128. package/apps/pwa/out/_next/static/chunks/app/ceo/page-3ff5b1e6ca88b848.js +1 -0
  129. package/apps/pwa/out/_next/static/chunks/app/chat/page-a65101300a0ee5c1.js +1 -0
  130. package/apps/pwa/out/_next/static/chunks/app/consult/page-3aca5b6d67dba511.js +1 -0
  131. package/apps/pwa/out/_next/static/chunks/app/control/page-45b8ab0a71e61314.js +1 -0
  132. package/apps/pwa/out/_next/static/chunks/app/decisions/page-53046e282d4cda8e.js +1 -0
  133. package/apps/pwa/out/_next/static/chunks/app/design-check/page-17809e60e8354c17.js +1 -0
  134. package/apps/pwa/out/_next/static/chunks/app/editor/page-fd2442d347bf5898.js +1 -0
  135. package/apps/pwa/out/_next/static/chunks/app/exec/page-e9d720d6fc082e21.js +1 -0
  136. package/apps/pwa/out/_next/static/chunks/app/field/page-6b8b4267bab0a677.js +1 -0
  137. package/apps/pwa/out/_next/static/chunks/app/healthz/route-deea1450b17cb8dc.js +1 -0
  138. package/apps/pwa/out/_next/static/chunks/app/inside/page-8bcf6233ac7c17af.js +1 -0
  139. package/apps/pwa/out/_next/static/chunks/app/intake/page-7cc25591cfc2126f.js +1 -0
  140. package/apps/pwa/out/_next/static/chunks/app/layout-053e871f35c9beba.js +1 -0
  141. package/apps/pwa/out/_next/static/chunks/app/live/page-eff819f0c2d5e084.js +1 -0
  142. package/apps/pwa/out/_next/static/chunks/app/live-run/page-4d7e9d8db5274a87.js +1 -0
  143. package/apps/pwa/out/_next/static/chunks/app/loops/page-2b2d8f5aa5f69ad4.js +1 -0
  144. package/apps/pwa/out/_next/static/chunks/app/market/page-0b8f92c5062e68b1.js +1 -0
  145. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-1bd9d0fdac2ced3d.js +1 -0
  146. package/apps/pwa/out/_next/static/chunks/app/morning/page-9ee28f7df07428ea.js +1 -0
  147. package/apps/pwa/out/_next/static/chunks/app/not-found-44b7a1ff468c6648.js +1 -0
  148. package/apps/pwa/out/_next/static/chunks/app/observatory/page-cbc6523711dc1b65.js +1 -0
  149. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-fdad47899c2695be.js +1 -0
  150. package/apps/pwa/out/_next/static/chunks/app/ops/release/{page-40f9e19149024298.js → page-79a8b5fee4c20871.js} +1 -1
  151. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-03e8ac9606aeaffb.js +1 -0
  152. package/apps/pwa/out/_next/static/chunks/app/outputs/page-4cd55c55ec287e2f.js +1 -0
  153. package/apps/pwa/out/_next/static/chunks/app/page-db17b4305404161e.js +1 -0
  154. package/apps/pwa/out/_next/static/chunks/app/reflection/page-30041d848350fd02.js +1 -0
  155. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-c540da022dbf86b0.js +1 -0
  156. package/apps/pwa/out/_next/static/chunks/app/sessions/page-9399efc538da057f.js +1 -0
  157. package/apps/pwa/out/_next/static/chunks/app/settings/devices/{page-a142dfb0331a05f5.js → page-ca2d09128c585ca4.js} +1 -1
  158. package/apps/pwa/out/_next/static/chunks/app/settings/page-0e2635aecd343038.js +1 -0
  159. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ef7f4399b6b7726e.js +1 -0
  160. package/apps/pwa/out/_next/static/chunks/app/setup/layout-deea1450b17cb8dc.js +1 -0
  161. package/apps/pwa/out/_next/static/chunks/app/setup/page-caf530535b875468.js +1 -0
  162. package/apps/pwa/out/_next/static/chunks/app/share/page-eaa20c1543a5fd8e.js +1 -0
  163. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c541eb1b75120f61.js +1 -0
  164. package/apps/pwa/out/_next/static/chunks/app/tasks/page-ab5e213eda9479f4.js +1 -0
  165. package/apps/pwa/out/_next/static/chunks/app/term/page-0a815f34367b6db6.js +1 -0
  166. package/apps/pwa/out/_next/static/chunks/app/today/page-e858ba0ed9393b68.js +1 -0
  167. package/apps/pwa/out/_next/static/chunks/app/trace/page-1638ee9dd6e0582f.js +1 -0
  168. package/apps/pwa/out/_next/static/chunks/app/vault/page-4cf5a399109391f2.js +1 -0
  169. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-b4396321238798ec.js +1 -0
  170. package/apps/pwa/out/_next/static/chunks/app/workflows/page-cb72bfd21006781a.js +1 -0
  171. package/apps/pwa/out/_next/static/chunks/app/workspace/page-6135d0242afbc434.js +1 -0
  172. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-a1dccf907eddb856.js +1 -0
  173. package/apps/pwa/out/_next/static/chunks/{53aeb4ee-51c92f8d683f5220.js → c7945435-b44d4dbe90ba0dcb.js} +1 -1
  174. package/apps/pwa/out/_next/static/chunks/{2fdf2931.b431eee4fb468bc3.js → cb0f8df8.09a4a6be97e3fc5f.js} +1 -1
  175. package/apps/pwa/out/_next/static/chunks/{c0c1a699.0ba79f97005965d4.js → d96660fb.cbc21a2a88539dbb.js} +1 -1
  176. package/apps/pwa/out/_next/static/chunks/ea514caa.05a24f78d9dffe5f.js +122 -0
  177. package/apps/pwa/out/_next/static/chunks/{83184dcd-0ee6247ff41eb3f2.js → fb7d20d5-6892502b6ee39ca6.js} +1 -1
  178. package/apps/pwa/out/_next/static/chunks/framework-e8a911e19b1be41f.js +1 -0
  179. package/apps/pwa/out/_next/static/chunks/main-7022f418fabba021.js +1 -0
  180. package/apps/pwa/out/_next/static/chunks/main-app-e5f15df755756a1e.js +1 -0
  181. package/apps/pwa/out/_next/static/chunks/pages/_app-4525f91e36940c9b.js +1 -0
  182. package/apps/pwa/out/_next/static/chunks/pages/_error-140f0e519c085b0f.js +1 -0
  183. package/apps/pwa/out/_next/static/chunks/webpack-8f22ef63dcb865b1.js +1 -0
  184. package/apps/pwa/out/_next/static/css/{b9d8151e48998417.css → 62c858ad53854f47.css} +1 -1
  185. package/apps/pwa/out/_next/static/css/d1f8bb401740a549.css +1 -0
  186. package/apps/pwa/out/approvals/index.html +1 -1
  187. package/apps/pwa/out/approvals/index.txt +23 -23
  188. package/apps/pwa/out/autopilot/index.html +1 -1
  189. package/apps/pwa/out/autopilot/index.txt +23 -23
  190. package/apps/pwa/out/board/index.html +1 -1
  191. package/apps/pwa/out/board/index.txt +23 -23
  192. package/apps/pwa/out/botlab/index.html +1 -1
  193. package/apps/pwa/out/botlab/index.txt +22 -22
  194. package/apps/pwa/out/bots/index.html +1 -1
  195. package/apps/pwa/out/bots/index.txt +22 -22
  196. package/apps/pwa/out/ceo/index.html +1 -1
  197. package/apps/pwa/out/ceo/index.txt +23 -23
  198. package/apps/pwa/out/chat/index.html +1 -1
  199. package/apps/pwa/out/chat/index.txt +22 -22
  200. package/apps/pwa/out/consult/index.html +1 -1
  201. package/apps/pwa/out/consult/index.txt +23 -23
  202. package/apps/pwa/out/control/index.html +1 -1
  203. package/apps/pwa/out/control/index.txt +23 -23
  204. package/apps/pwa/out/decisions/index.html +1 -1
  205. package/apps/pwa/out/decisions/index.txt +22 -22
  206. package/apps/pwa/out/design-check/index.html +1 -1
  207. package/apps/pwa/out/design-check/index.txt +23 -23
  208. package/apps/pwa/out/editor/index.html +1 -1
  209. package/apps/pwa/out/editor/index.txt +24 -25
  210. package/apps/pwa/out/exec/index.html +1 -1
  211. package/apps/pwa/out/exec/index.txt +23 -23
  212. package/apps/pwa/out/field/index.html +1 -1
  213. package/apps/pwa/out/field/index.txt +23 -23
  214. package/apps/pwa/out/healthz +1 -1
  215. package/apps/pwa/out/index.html +1 -1
  216. package/apps/pwa/out/index.txt +22 -22
  217. package/apps/pwa/out/inside/index.html +1 -1
  218. package/apps/pwa/out/inside/index.txt +23 -23
  219. package/apps/pwa/out/intake/index.html +1 -1
  220. package/apps/pwa/out/intake/index.txt +23 -23
  221. package/apps/pwa/out/live/index.html +1 -1
  222. package/apps/pwa/out/live/index.txt +24 -25
  223. package/apps/pwa/out/live-run/index.html +1 -1
  224. package/apps/pwa/out/live-run/index.txt +24 -25
  225. package/apps/pwa/out/loops/index.html +1 -1
  226. package/apps/pwa/out/loops/index.txt +22 -22
  227. package/apps/pwa/out/market/index.html +1 -1
  228. package/apps/pwa/out/market/index.txt +22 -22
  229. package/apps/pwa/out/missions/placeholder/index.html +1 -1
  230. package/apps/pwa/out/missions/placeholder/index.txt +22 -22
  231. package/apps/pwa/out/morning/index.html +1 -1
  232. package/apps/pwa/out/morning/index.txt +23 -23
  233. package/apps/pwa/out/observatory/index.html +1 -1
  234. package/apps/pwa/out/observatory/index.txt +23 -23
  235. package/apps/pwa/out/ops/checklist/index.html +1 -1
  236. package/apps/pwa/out/ops/checklist/index.txt +22 -22
  237. package/apps/pwa/out/ops/release/index.html +1 -1
  238. package/apps/pwa/out/ops/release/index.txt +22 -22
  239. package/apps/pwa/out/ops/seats/index.html +1 -1
  240. package/apps/pwa/out/ops/seats/index.txt +22 -22
  241. package/apps/pwa/out/outputs/index.html +1 -1
  242. package/apps/pwa/out/outputs/index.txt +22 -22
  243. package/apps/pwa/out/reflection/index.html +1 -1
  244. package/apps/pwa/out/reflection/index.txt +23 -23
  245. package/apps/pwa/out/scheduler/index.html +1 -1
  246. package/apps/pwa/out/scheduler/index.txt +23 -23
  247. package/apps/pwa/out/sessions/index.html +1 -1
  248. package/apps/pwa/out/sessions/index.txt +22 -22
  249. package/apps/pwa/out/settings/devices/index.html +1 -1
  250. package/apps/pwa/out/settings/devices/index.txt +23 -23
  251. package/apps/pwa/out/settings/index.html +1 -1
  252. package/apps/pwa/out/settings/index.txt +23 -23
  253. package/apps/pwa/out/setup/done/index.html +1 -1
  254. package/apps/pwa/out/setup/done/index.txt +23 -23
  255. package/apps/pwa/out/setup/index.html +1 -1
  256. package/apps/pwa/out/setup/index.txt +23 -23
  257. package/apps/pwa/out/share/index.html +1 -1
  258. package/apps/pwa/out/share/index.txt +23 -23
  259. package/apps/pwa/out/showroom/index.html +1 -1
  260. package/apps/pwa/out/showroom/index.txt +22 -22
  261. package/apps/pwa/out/tasks/index.html +1 -1
  262. package/apps/pwa/out/tasks/index.txt +23 -23
  263. package/apps/pwa/out/term/index.html +1 -1
  264. package/apps/pwa/out/term/index.txt +23 -23
  265. package/apps/pwa/out/today/index.html +1 -1
  266. package/apps/pwa/out/today/index.txt +23 -23
  267. package/apps/pwa/out/trace/index.html +1 -1
  268. package/apps/pwa/out/trace/index.txt +23 -23
  269. package/apps/pwa/out/vault/index.html +1 -1
  270. package/apps/pwa/out/vault/index.txt +23 -23
  271. package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
  272. package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
  273. package/apps/pwa/out/workflows/index.html +1 -1
  274. package/apps/pwa/out/workflows/index.txt +23 -23
  275. package/apps/pwa/out/workspace/index.html +1 -1
  276. package/apps/pwa/out/workspace/index.txt +23 -23
  277. package/apps/pwa/out/worktrees/index.html +1 -1
  278. package/apps/pwa/out/worktrees/index.txt +23 -23
  279. package/catalog/external-commands.yaml +5 -3
  280. package/catalog/meta/catalogVersion.yaml +2 -1
  281. package/catalog/signing/catalog-signing-public.pem +3 -0
  282. package/docs/goal-context/04-mock-scenarios.md +13 -0
  283. package/graphs/catalog/catalog.yaml +1 -1
  284. package/graphs/heal/heal-loop.yaml +1 -0
  285. package/graphs/intake/intake-daily.yaml +16 -0
  286. package/graphs/intake/news-sources.yaml +1 -0
  287. package/graphs/intake/recipes.yaml +7 -0
  288. package/graphs/overlays/examples/research-runtime-empty-terminal.yaml +28 -0
  289. package/graphs/overlays/stop-heal-ladder.yaml +113 -0
  290. package/graphs/profiles/local.yaml +5 -0
  291. package/graphs/profiles/pod.yaml +4 -0
  292. package/graphs/units/verbs/recipes.yaml +11 -11
  293. package/graphs/work/research-report.yaml +10 -2
  294. package/package.json +6 -2
  295. package/plugins/demo-absorption-briefing/plugin.json +18 -0
  296. package/plugins/demo-absorption-briefing/skills/demo-absorption-briefing/SKILL.md +8 -0
  297. package/plugins/demo-browser-hand/plugin.json +13 -0
  298. package/plugins/demo-browser-hand/skills/demo-browser-hand/SKILL.md +8 -0
  299. package/plugins/demo-linear-secretary/plugin.json +15 -0
  300. package/plugins/demo-linear-secretary/skills/demo-linear-secretary/SKILL.md +8 -0
  301. package/plugins/demo-plugin-wizard/plugin.json +11 -0
  302. package/plugins/demo-plugin-wizard/skills/demo-plugin-wizard/SKILL.md +8 -0
  303. package/plugins/demo-research/plugin.json +16 -0
  304. package/plugins/demo-research/skills/demo-research/SKILL.md +8 -0
  305. package/plugins/demo-video-briefing/plugin.json +15 -0
  306. package/plugins/demo-video-briefing/skills/demo-video-briefing/SKILL.md +8 -0
  307. package/scripts/build-signed-catalog.ts +48 -0
  308. package/scripts/ci-typecheck-main-delta.sh +88 -0
  309. package/scripts/codex-fallback-live-probe.ts +1 -1
  310. package/scripts/demo/demo1104-parallel-scenes.ts +301 -0
  311. package/scripts/demo/demo1104-stage.config.ts +21 -0
  312. package/scripts/demo/demo1104-stage.ts +316 -0
  313. package/scripts/goal-method-audit.ts +17 -1
  314. package/scripts/graph-units/land-enqueue.ts +90 -0
  315. package/scripts/heal/run-role.ts +99 -5
  316. package/scripts/hooks/codex-notify.sh +32 -0
  317. package/scripts/install.sh +10 -38
  318. package/scripts/land-global-checks.ts +6 -1
  319. package/scripts/landing-heal/land-plan.ts +57 -0
  320. package/scripts/lib/decompose-ab.ts +1 -0
  321. package/scripts/lib/fixtures/tui-regress/help-insufficient-commands.txt +15 -0
  322. package/scripts/lib/fixtures/tui-regress/help-live.txt +42 -0
  323. package/scripts/lib/fixtures/tui-regress/help-missing-keys.txt +21 -0
  324. package/scripts/lib/fixtures/tui-regress/help-original.txt +51 -0
  325. package/scripts/lib/fixtures/tui-regress/help-shifted-input.txt +26 -0
  326. package/scripts/lib/tui-regress-checks.ts +33 -13
  327. package/scripts/release-loop/auto-approve-node.ts +1 -1
  328. package/scripts/release-loop/gate-autoheal-sim-evidence.ts +60 -0
  329. package/scripts/release-loop/gate-baseline-receipt.ts +47 -9
  330. package/scripts/release-loop/gate-image-pin.ts +81 -0
  331. package/scripts/release-loop/gate-method.ts +139 -0
  332. package/scripts/release-loop/gate-node-sim.ts +207 -0
  333. package/scripts/release-loop/gate-node.ts +463 -64
  334. package/scripts/release-loop/gate-pod-image-sticky-plan.ts +99 -0
  335. package/scripts/release-loop/gate-radius-live.ts +97 -13
  336. package/scripts/release-loop/gate-shard-dispatch.ts +43 -0
  337. package/scripts/release-loop/gate-traffic-mode.ts +151 -3
  338. package/scripts/release-loop/gate-train-receipts.ts +122 -0
  339. package/scripts/release-loop/node-verdict.ts +38 -25
  340. package/scripts/release-loop/preflight.ts +362 -8
  341. package/scripts/release-loop/resume-release.ts +83 -8
  342. package/scripts/release-loop/unattended-release.ts +20 -9
  343. package/scripts/rhythm/daily.ts +36 -4
  344. package/scripts/rhythm/linear-progress-sync.ts +298 -0
  345. package/scripts/ux-sim.ts +18 -1
  346. package/scripts/video-pipeline.ts +9 -1
  347. package/scripts/warm-pool-provider-config.ts +286 -0
  348. package/skills/omni-crawl/SKILL.md +5 -2
  349. package/skills/omni-crawl/scripts/main.ts +84 -23
  350. package/src/acp/agent-manager.ts +1 -0
  351. package/src/acp/codex-app-server-agent.ts +33 -0
  352. package/src/acp/codex-app-server-client.ts +153 -16
  353. package/src/acp/core-turn-bridge.ts +27 -9
  354. package/src/acp/event-router.ts +20 -1
  355. package/src/acp/server.ts +6 -0
  356. package/src/agent/registry.ts +2 -0
  357. package/src/agent/task-notification.ts +25 -5
  358. package/src/agent/types.ts +6 -0
  359. package/src/agent-mission/browser-roundtrip-coordinator.ts +85 -0
  360. package/src/agent-mission/claude-headless.ts +4 -1
  361. package/src/agent-mission/codex-exec.ts +105 -0
  362. package/src/agent-mission/driver.ts +192 -11
  363. package/src/agent-mission/grok-auth-status.ts +47 -0
  364. package/src/agent-mission/hand-hooks.ts +101 -0
  365. package/src/agent-mission/mission-cli.ts +63 -4
  366. package/src/agent-mission/mission-hand-reply.ts +118 -0
  367. package/src/agent-mission/mission-line.ts +180 -0
  368. package/src/agent-mission/mission-out.ts +833 -0
  369. package/src/agent-mission/tool-install.ts +200 -3
  370. package/src/agent-substrate/context-strategy.ts +4 -4
  371. package/src/agent-substrate/self-review-cli.ts +178 -13
  372. package/src/agents/general-purpose.md +1 -1
  373. package/src/auto-research/research-turn.ts +211 -53
  374. package/src/autopilot/pr-manager.ts +69 -10
  375. package/src/autopilot/pty-control-loop.ts +2 -0
  376. package/src/boot/daemon-tools/self-implement.ts +3 -1
  377. package/src/boot/daemon-tools/web-search.ts +1 -2
  378. package/src/briefing/brief-items.ts +55 -11
  379. package/src/capture/tui-self-report.ts +22 -6
  380. package/src/chat/index.ts +1 -1
  381. package/src/cli/agent-cli.ts +2 -1
  382. package/src/cli/catalog-cli.ts +31 -0
  383. package/src/cli/connector-cli.ts +16 -0
  384. package/src/cli/doctor-fix.ts +2 -2
  385. package/src/cli/fixtures/review-loop-breaker/opwaiver-32646-1694ccc7a170.json +1 -0
  386. package/src/cli/fixtures/review-loop-breaker/opwaiver-32853-bd8f73595c83.json +1 -0
  387. package/src/cli/fixtures/review-loop-breaker/opwaiver-33097-1cc85900413c.json +1 -0
  388. package/src/cli/fixtures/review-loop-breaker/opwaiver-33106-972f31e4a3ca.json +1 -0
  389. package/src/cli/fixtures/review-loop-breaker/opwaiver-33113-3ab51f05968f.json +1 -0
  390. package/src/cli/fixtures/review-loop-breaker/pr-33097-1cc85900413c.json +1 -0
  391. package/src/cli/intake-source-cli.ts +44 -8
  392. package/src/cli/msg-cli.ts +32 -3
  393. package/src/cli/pr-cli.ts +21 -1
  394. package/src/cli/pr-land-heavy-remote.ts +75 -5
  395. package/src/cli/pr-land-overlap-evidence.ts +113 -2
  396. package/src/cli/pr-land-pod-shadow-job.ts +202 -4
  397. package/src/cli/pr-land-pod-shadow.ts +9 -2
  398. package/src/cli/release-checklist-read-cli.ts +57 -19
  399. package/src/cli/release-cli.ts +23 -3
  400. package/src/cli/research-cli.ts +13 -5
  401. package/src/cli/setup-cli.ts +166 -6
  402. package/src/cli/setup-keys.ts +187 -0
  403. package/src/cli/task-plugin-wizard-host.ts +114 -0
  404. package/src/cli/tasks-cli.ts +61 -9
  405. package/src/cli/tui-test-cli.ts +186 -0
  406. package/src/compact/auto.ts +8 -1
  407. package/src/config.ts +4 -2
  408. package/src/connectors/linear-daily-progress.ts +228 -0
  409. package/src/connectors/linear-projector.ts +34 -12
  410. package/src/connectors/linear.ts +151 -7
  411. package/src/control-plane/ledger.ts +52 -2
  412. package/src/control-plane/server.ts +16 -2
  413. package/src/core-turn/deep-turn-bloom.ts +67 -0
  414. package/src/core-turn/research-policy.ts +37 -0
  415. package/src/core-turn/run-core-turn.ts +606 -95
  416. package/src/core-turn/run-goal-loop.ts +18 -0
  417. package/src/core-turn/types.ts +4 -0
  418. package/src/dashboard/chat/acp-chat.ts +10 -0
  419. package/src/dashboard/classic-sidetab-mission-job.ts +161 -0
  420. package/src/dashboard/classic-sidetab-mission-pair.ts +81 -0
  421. package/src/dashboard/classic-sidetab-mission-trio.ts +219 -0
  422. package/src/dashboard/classic-sidetab-mission.ts +347 -0
  423. package/src/dashboard/index.ts +517 -18
  424. package/src/dashboard/input/agent-wake.ts +23 -1
  425. package/src/dashboard/input/chat-main-acp-dispatch.ts +23 -0
  426. package/src/dashboard/input/chat-main-plain-turn-runtime.ts +17 -0
  427. package/src/dashboard/mission-cli-consumer.ts +165 -0
  428. package/src/dashboard/plugin-wizard-runtime.ts +50 -0
  429. package/src/dashboard/plugin-wizard-tool.ts +55 -0
  430. package/src/dashboard/seat-boot-preamble.ts +171 -1
  431. package/src/dashboard/side-basic-runtime.ts +54 -1
  432. package/src/dashboard/sidetab-runtime.ts +90 -1
  433. package/src/dashboard/skill-catalog-preamble.ts +101 -0
  434. package/src/dashboard/skill-detection-runtime.ts +55 -15
  435. package/src/dashboard/slash-runtime/dashboard-handlers.ts +15 -0
  436. package/src/dashboard/terminal-popup-runtime.ts +6 -3
  437. package/src/dashboard/turn-preamble.ts +53 -15
  438. package/src/dashboard/turn-prompt-runtime.ts +4 -2
  439. package/src/decisions/linear-progress-summary.ts +78 -0
  440. package/src/decisions/linear-progress-sync.ts +152 -0
  441. package/src/domains/outbound-alert.ts +49 -11
  442. package/src/domains/telegram-kind-route.ts +16 -9
  443. package/src/graph-runner/arg-allowance.ts +13 -0
  444. package/src/graph-runner/graph-cli.ts +23 -7
  445. package/src/graph-runner/graph-run-api.ts +3 -1
  446. package/src/graph-runner/graph-tick.ts +10 -2
  447. package/src/graph-runner/runner.ts +86 -18
  448. package/src/graph-wizard/mission-compose.ts +407 -12
  449. package/src/grok/agent-search.ts +14 -4
  450. package/src/grok/credential.ts +28 -11
  451. package/src/harness/dispatch-backpressure.ts +54 -1
  452. package/src/harness/dispatch-shadow-compare.ts +74 -0
  453. package/src/harness/harness-cli-command.ts +11 -1
  454. package/src/harness/harness-pod-dispatch.ts +81 -15
  455. package/src/harness/harness-stop.ts +155 -11
  456. package/src/harness/skill-exec.ts +21 -9
  457. package/src/harness/skill-select.ts +1 -1
  458. package/src/hooks/error-report-cloud.ts +101 -0
  459. package/src/hooks/receiver.ts +29 -2
  460. package/src/index.ts +159 -13
  461. package/src/instance/spawn-elanous.ts +6 -4
  462. package/src/intake-plane/actions.ts +354 -0
  463. package/src/intake-plane/adapters/telegram-ambient.ts +34 -18
  464. package/src/intake-plane/intake-sources.ts +78 -8
  465. package/src/intake-plane/items.ts +14 -4
  466. package/src/intake-plane/linear-mission-sync.ts +80 -0
  467. package/src/intake-plane/linear-secretary-runtime.ts +178 -0
  468. package/src/intake-plane/linear-wish.ts +227 -1
  469. package/src/life/life-cli.ts +168 -0
  470. package/src/life/life-kinds.ts +160 -0
  471. package/src/live-supply/budget-consumer.ts +78 -0
  472. package/src/live-supply/read.ts +3 -0
  473. package/src/live-supply/snapshot.ts +45 -0
  474. package/src/llm/provider-credentials.ts +8 -2
  475. package/src/llm.ts +168 -9
  476. package/src/loops/orchestrator/coordinator-shadow.ts +226 -0
  477. package/src/loops/orchestrator/tick.ts +13 -0
  478. package/src/maturity/feature-maturity.ts +4 -4
  479. package/src/msg/msg-sse-server.ts +3 -3
  480. package/src/msg/msg-store.ts +177 -19
  481. package/src/native-tool-catalog.ts +38 -4
  482. package/src/nexus/api/harness-traversal.ts +11 -0
  483. package/src/nexus/api/http-server.ts +37 -1
  484. package/src/nexus/api/mcp-public-allowlist.ts +2 -0
  485. package/src/nexus/index.ts +7 -2
  486. package/src/nexus/outbound/format.ts +9 -0
  487. package/src/nexus/outbound/router.ts +98 -13
  488. package/src/nexus/setup-status.ts +9 -0
  489. package/src/nexus/state/state.ts +3 -0
  490. package/src/oauth/codex-account-store.ts +20 -7
  491. package/src/oauth/codex-owner-mirror.ts +44 -0
  492. package/src/oauth/codex.ts +17 -2
  493. package/src/oauth/fallback-chain.ts +47 -17
  494. package/src/onboarding/first-run-doctor.ts +8 -1
  495. package/src/onboarding/first-run.ts +85 -26
  496. package/src/onboarding/key-setup.ts +103 -0
  497. package/src/onboarding/menu-answer.ts +13 -0
  498. package/src/onboarding/secret-prompt.ts +37 -0
  499. package/src/plugins/install/plugin-install.ts +59 -0
  500. package/src/pr-tool/census.ts +133 -2
  501. package/src/pty-shell/pty-control-ipc.ts +4 -1
  502. package/src/pty-shell/tui-run-state.ts +188 -2
  503. package/src/registry/catalog-server.ts +232 -0
  504. package/src/registry/loader.ts +45 -1
  505. package/src/registry/types.ts +1 -2
  506. package/src/release-loop/checklist-target-path-hint.ts +13 -0
  507. package/src/release-loop/checklist.ts +9 -1
  508. package/src/repl/index.ts +43 -2
  509. package/src/research/axis-fanout.ts +136 -16
  510. package/src/research/bloom-exemplars.ts +3 -1
  511. package/src/research/gap-followup.ts +13 -1
  512. package/src/research/plugin-discovery.ts +36 -14
  513. package/src/research-bridge/invoke.ts +22 -5
  514. package/src/research-bridge/types.ts +2 -0
  515. package/src/self-dev/ask-launch-flow.ts +72 -1
  516. package/src/self-dev/decompose.ts +119 -5
  517. package/src/self-dev/dev-cli.ts +4 -1
  518. package/src/self-dev/dev-pipeline.ts +5 -0
  519. package/src/self-dev/draft-residue.ts +64 -5
  520. package/src/self-dev/graph-front-nodes.ts +2 -1
  521. package/src/self-dev/graph-journey-route.ts +76 -21
  522. package/src/self-dev/launch-preflight-text.ts +5 -6
  523. package/src/self-dev/launch-preflight.ts +58 -0
  524. package/src/self-dev/orchestrate.ts +13 -3
  525. package/src/self-dev/review-provider-fallback.ts +9 -2
  526. package/src/self-dev/run-supervisor.ts +42 -4
  527. package/src/self-dev/run-types.ts +4 -0
  528. package/src/self-dev/shard-aggregate.ts +4 -0
  529. package/src/self-dev/shard-run.ts +36 -15
  530. package/src/self-implement/abandoned-classification.ts +12 -3
  531. package/src/self-implement/budget-gate.ts +7 -0
  532. package/src/self-implement/child-llm-preference.ts +10 -1
  533. package/src/self-implement/doctor-visit.ts +118 -8
  534. package/src/self-implement/elanous-tui-spawn.ts +3 -0
  535. package/src/self-implement/fixtures/tdd-green-missing-passing-child-transcript.txt +2 -0
  536. package/src/self-implement/gate-artifacts.ts +2 -1
  537. package/src/self-implement/goal-author-cli.ts +4 -2
  538. package/src/self-implement/goal-author.ts +684 -7
  539. package/src/self-implement/graph-overlay-yaml.ts +37 -4
  540. package/src/self-implement/graph-overlay.ts +3 -1
  541. package/src/self-implement/graph-profile-yaml.ts +107 -0
  542. package/src/self-implement/graph-yaml.ts +26 -3
  543. package/src/self-implement/headless-elanous-driver.ts +31 -2
  544. package/src/self-implement/heal-intake.ts +112 -4
  545. package/src/self-implement/heal-triage.ts +20 -0
  546. package/src/self-implement/host-regate.ts +27 -4
  547. package/src/self-implement/merge-train.ts +5 -0
  548. package/src/self-implement/off-diff-evidence.ts +249 -5
  549. package/src/self-implement/orchestrator.ts +365 -25
  550. package/src/self-implement/regate-detail.ts +38 -1
  551. package/src/self-implement/rework-child-provider.ts +25 -0
  552. package/src/self-implement/run-chart.ts +122 -0
  553. package/src/self-implement/run-ledger.ts +162 -11
  554. package/src/self-implement/run-stop.ts +188 -4
  555. package/src/self-implement/runtime-overlay-run-steps.ts +95 -0
  556. package/src/self-implement/stop-autoheal.ts +13 -0
  557. package/src/self-implement/tdd-evidence-tags.ts +9 -0
  558. package/src/self-implement/train-gate-receipt.ts +166 -0
  559. package/src/self-implement/train-gate-remote.ts +62 -18
  560. package/src/session/chat.ts +40 -4
  561. package/src/session/session-fanout.ts +2 -0
  562. package/src/session/streaming/acp-stream-sink.ts +2 -1
  563. package/src/session/streaming/chunk-producer.ts +6 -0
  564. package/src/session/streaming/stream-compositor.ts +3 -2
  565. package/src/session-runtime/index.ts +135 -5
  566. package/src/session-runtime/retry-policy.ts +1 -1
  567. package/src/session-runtime/tier-flip.ts +3 -3
  568. package/src/setup/llm-env-detect.ts +3 -0
  569. package/src/setup/service-key-catalog.ts +46 -0
  570. package/src/setup/service-keys.ts +241 -0
  571. package/src/sidetab-core/model.ts +19 -5
  572. package/src/sidetab-core/visible-agent-mission.ts +262 -0
  573. package/src/skills/name-match.ts +20 -0
  574. package/src/skills/tools/agent.ts +53 -6
  575. package/src/skills/tools/omni-search.ts +173 -13
  576. package/src/task-agent/parent-host.ts +10 -0
  577. package/src/task-agent/pod-distributor-entry.ts +3 -0
  578. package/src/task-agent/repair-outcomes.ts +65 -0
  579. package/src/task-agent/task-hand.ts +47 -7
  580. package/src/task-orchestrator/dispatcher.ts +14 -1
  581. package/src/task-orchestrator/linear-capture-events.ts +55 -0
  582. package/src/task-orchestrator/store.ts +16 -5
  583. package/src/task-orchestrator/surfaces/pod-artifact-return.ts +4 -0
  584. package/src/task-orchestrator/surfaces/pod-distributor.ts +48 -0
  585. package/src/task-orchestrator/surfaces/pod-failure-reason.ts +92 -1
  586. package/src/task-orchestrator/surfaces/pod-ledger-collect.ts +38 -1
  587. package/src/task-orchestrator/surfaces/pod-ledger-events.ts +113 -14
  588. package/src/task-orchestrator/surfaces/pod-si-warm-entry.ts +33 -6
  589. package/src/task-orchestrator/surfaces/pod-source-bundle.ts +45 -9
  590. package/src/task-orchestrator/surfaces/pod-source-receive.ts +178 -16
  591. package/src/task-orchestrator/surfaces/pod-source-spec.ts +3 -3
  592. package/src/task-orchestrator/surfaces/pod-warm-switch.ts +2 -0
  593. package/src/task-orchestrator/surfaces/pod-warm-worker-provider.ts +237 -41
  594. package/src/task-orchestrator/surfaces/pod-warm-worker-runtime.ts +80 -3
  595. package/src/task-orchestrator/surfaces/self-implement-pod.ts +337 -51
  596. package/src/task-orchestrator/surfaces/self-implement.ts +27 -3
  597. package/src/task-orchestrator/surfaces/warm-reuse-evidence.ts +169 -0
  598. package/src/task-orchestrator/types.ts +14 -0
  599. package/src/telegram.ts +14 -16
  600. package/src/terminal/coding-agent.ts +14 -5
  601. package/src/terminal/session-registry.ts +1 -1
  602. package/src/tokens.ts +35 -2
  603. package/src/tool-hints/gate.ts +1 -0
  604. package/src/tool-runtime/agent-runtime.ts +2 -0
  605. package/src/tool-runtime/browser-hand-runtime.ts +381 -0
  606. package/src/tool-runtime/browser-runtime.ts +2 -1
  607. package/src/tool-runtime/elanous-linear-issue-runtime.ts +76 -0
  608. package/src/tool-runtime/elanous-linear-secretary-runtime.ts +57 -0
  609. package/src/tool-runtime/elanous-skills-list-runtime.ts +5 -1
  610. package/src/tool-runtime/graph-mcp-runtimes.ts +240 -0
  611. package/src/tool-runtime/index.ts +6 -0
  612. package/src/tool-runtime/skill-exec-runtime.ts +33 -13
  613. package/src/tool-runtime/types.ts +4 -0
  614. package/src/tui/entry.ts +38 -5
  615. package/src/tui/sidetab/attach.ts +177 -1
  616. package/src/tui/sidetab/herdr-portal.ts +225 -0
  617. package/src/tui-client/local-chat-turn.ts +26 -13
  618. package/src/tui.ts +22 -0
  619. package/src/user-config.ts +34 -9
  620. package/src/user-intent/types.ts +4 -3
  621. package/src/ux-sim/browser-hand.ts +165 -0
  622. package/src/ux-sim/draft-inventory-builder.ts +198 -0
  623. package/src/ux-sim/fake-browser-page.ts +81 -0
  624. package/src/ux-sim/fake-kubectl.ts +37 -3
  625. package/src/ux-sim/fake-linear-device.ts +31 -0
  626. package/src/ux-sim/fault-pool-cap.ts +11 -6
  627. package/src/ux-sim/graph-engine-sim.ts +47 -0
  628. package/src/ux-sim/linear-secretary.ts +216 -0
  629. package/src/ux-sim/mock-scenario-catalog.json +93 -0
  630. package/src/ux-sim/mock-scenario-catalog.ts +274 -0
  631. package/src/ux-sim/onboarding-first-run-device.ts +31 -21
  632. package/src/ux-sim/scenario.ts +185 -48
  633. package/src/ux-sim/service-key-setup.ts +50 -0
  634. package/src/ux-sim/term-slash-device.ts +74 -0
  635. package/src/ux-sim/turn-throw-sim.ts +31 -0
  636. package/src/version/packed-revision.json +1 -1
  637. package/src/voice/voice-tts-singleton.ts +18 -3
  638. package/src/web-search/exa.ts +77 -0
  639. package/src/web-search/grok.ts +5 -9
  640. package/src/web-search/index.ts +30 -9
  641. package/src/web-search/provider.ts +4 -1
  642. package/src/web-search/x-intent.ts +5 -0
  643. package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +0 -149
  644. package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +0 -36
  645. package/apps/pwa/out/_next/static/chunks/1197-54da59d250a6e476.js +0 -1
  646. package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +0 -287
  647. package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +0 -1
  648. package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +0 -1
  649. package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +0 -1
  650. package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +0 -1
  651. package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +0 -90
  652. package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +0 -1
  653. package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +0 -77
  654. package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +0 -1
  655. package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +0 -1
  656. package/apps/pwa/out/_next/static/chunks/2073.689dcb2680113d76.js +0 -1
  657. package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +0 -1
  658. package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +0 -1
  659. package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +0 -1
  660. package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +0 -1
  661. package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +0 -1
  662. package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +0 -1
  663. package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +0 -1
  664. package/apps/pwa/out/_next/static/chunks/2773.0e80b9d325fb5635.js +0 -32
  665. package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +0 -1
  666. package/apps/pwa/out/_next/static/chunks/3097.864e92bdaa2f4d15.js +0 -79
  667. package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +0 -1
  668. package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +0 -1
  669. package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +0 -1
  670. package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +0 -74
  671. package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +0 -1
  672. package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +0 -1
  673. package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +0 -1
  674. package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +0 -1
  675. package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +0 -1
  676. package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +0 -1
  677. package/apps/pwa/out/_next/static/chunks/4156.ba4de4a3664f04b4.js +0 -1
  678. package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +0 -1
  679. package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +0 -1
  680. package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +0 -148
  681. package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +0 -226
  682. package/apps/pwa/out/_next/static/chunks/4667.97e31aa38c95c475.js +0 -309
  683. package/apps/pwa/out/_next/static/chunks/4702.4a4adc1f16d7c93b.js +0 -64
  684. package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +0 -1
  685. package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +0 -1
  686. package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +0 -1
  687. package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +0 -1
  688. package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +0 -1
  689. package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +0 -1
  690. package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +0 -94
  691. package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +0 -1
  692. package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +0 -8
  693. package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +0 -1
  694. package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +0 -1
  695. package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +0 -24
  696. package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +0 -1
  697. package/apps/pwa/out/_next/static/chunks/5937.c2df9e3447e1f667.js +0 -1
  698. package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +0 -286
  699. package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +0 -1
  700. package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +0 -1
  701. package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +0 -1
  702. package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +0 -27
  703. package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +0 -1
  704. package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +0 -62
  705. package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +0 -24
  706. package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +0 -1
  707. package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +0 -122
  708. package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +0 -1
  709. package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +0 -1
  710. package/apps/pwa/out/_next/static/chunks/7191.fdc955f7d96064a4.js +0 -1
  711. package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +0 -1
  712. package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +0 -1
  713. package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +0 -1
  714. package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +0 -1
  715. package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +0 -1
  716. package/apps/pwa/out/_next/static/chunks/8050-9b364bdef8f71927.js +0 -1
  717. package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +0 -1
  718. package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +0 -1
  719. package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +0 -104
  720. package/apps/pwa/out/_next/static/chunks/8464-e24f10451b658aac.js +0 -1
  721. package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +0 -1
  722. package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +0 -1
  723. package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +0 -1
  724. package/apps/pwa/out/_next/static/chunks/8880.64c445592f04acaf.js +0 -1
  725. package/apps/pwa/out/_next/static/chunks/8981.c706964c8ba27aff.js +0 -1
  726. package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +0 -1
  727. package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +0 -1
  728. package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +0 -1
  729. package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +0 -1
  730. package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +0 -1
  731. package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +0 -1
  732. package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +0 -93
  733. package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +0 -1
  734. package/apps/pwa/out/_next/static/chunks/9579.4a8169600fff2058.js +0 -1
  735. package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +0 -1
  736. package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +0 -1
  737. package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +0 -34
  738. package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +0 -1
  739. package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +0 -1
  740. package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +0 -1
  741. package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +0 -1
  742. package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +0 -1
  743. package/apps/pwa/out/_next/static/chunks/app/botlab/page-14949db884bfa672.js +0 -1
  744. package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +0 -1
  745. package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +0 -1
  746. package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +0 -1
  747. package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +0 -1
  748. package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +0 -1
  749. package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +0 -1
  750. package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +0 -1
  751. package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +0 -1
  752. package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +0 -1
  753. package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +0 -1
  754. package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +0 -1
  755. package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +0 -1
  756. package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +0 -1
  757. package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +0 -1
  758. package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +0 -1
  759. package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +0 -1
  760. package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +0 -1
  761. package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +0 -1
  762. package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +0 -1
  763. package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +0 -1
  764. package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +0 -1
  765. package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +0 -1
  766. package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +0 -1
  767. package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +0 -1
  768. package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +0 -1
  769. package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +0 -1
  770. package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +0 -1
  771. package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +0 -1
  772. package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +0 -1
  773. package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +0 -1
  774. package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +0 -1
  775. package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +0 -1
  776. package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +0 -1
  777. package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +0 -1
  778. package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +0 -1
  779. package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +0 -1
  780. package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +0 -1
  781. package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +0 -1
  782. package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +0 -1
  783. package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +0 -1
  784. package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +0 -1
  785. package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +0 -1
  786. package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +0 -1
  787. package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +0 -1
  788. package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +0 -1
  789. package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +0 -1
  790. package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +0 -1
  791. package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +0 -1
  792. package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +0 -1
  793. package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +0 -1
  794. package/apps/pwa/out/_next/static/css/be9019f696217521.css +0 -1
  795. package/apps/pwa/out/_next/static/css/d0a48dc099ed86cf.css +0 -1
  796. /package/apps/pwa/out/_next/static/{GiOLWmt4MqDZePubBjA4Q → Om5xS9jpjSXJCeTNGYEi4}/_ssgManifest.js +0 -0
@@ -32,6 +32,10 @@ export interface BriefItem {
32
32
  deadline: string | null;
33
33
  evidence: string | null;
34
34
  source: string;
35
+ /** Existing Linear issue identifier; this is the secretary contract key. */
36
+ issue_ref?: string | null;
37
+ /** Parent Linear issue UUID used by the Linear comment projector. */
38
+ linearIssueId?: string | null;
35
39
  created_at: string;
36
40
  sent_at: string | null;
37
41
  }
@@ -43,6 +47,9 @@ export interface AddBriefItem {
43
47
  deadline?: string | null;
44
48
  evidence?: string | null;
45
49
  source: string;
50
+ /** Reuses the Linear secretary issue identifier; no intake-specific key is created. */
51
+ issueRef?: string | null;
52
+ linearIssueId?: string;
46
53
  createdAt?: string;
47
54
  /** Optional normalized claim identity and time window for repeat observations. */
48
55
  dedupeKey?: string;
@@ -185,6 +192,7 @@ function itemLine(item: BriefItem): string {
185
192
  const extra = [
186
193
  item.deadline ? `마감: ${item.deadline}` : '',
187
194
  item.evidence ? `근거: ${item.evidence}` : '',
195
+ item.issue_ref ? `관련 이슈: ${item.issue_ref}` : '',
188
196
  `출처: ${item.source}`,
189
197
  ].filter(Boolean).join(' · ');
190
198
  return `- [${item.priority}] ${item.text} (${extra})`;
@@ -207,6 +215,7 @@ function migrateLegacyItems(db: Database, log: (category: string, event: string,
207
215
  deadline TEXT,
208
216
  evidence TEXT,
209
217
  source TEXT NOT NULL,
218
+ linear_issue_id TEXT,
210
219
  created_at TEXT NOT NULL,
211
220
  sent_at TEXT
212
221
  )`);
@@ -222,6 +231,12 @@ function migrateLegacyItems(db: Database, log: (category: string, event: string,
222
231
  log('briefing.items', 'migrated-legacy', { rows: (db.query('SELECT COUNT(*) AS n FROM items_v1').get() as { n: number }).n });
223
232
  }
224
233
 
234
+ function briefItem(row: BriefItem): BriefItem {
235
+ if (row.issue_ref != null) return row;
236
+ const { issue_ref: _issueRef, ...legacy } = row;
237
+ return legacy;
238
+ }
239
+
225
240
  /** Append-only briefing item ledger at `<state>/briefing/items.sqlite`. */
226
241
  export class BriefItemsLedger {
227
242
  readonly path: string;
@@ -251,6 +266,8 @@ export class BriefItemsLedger {
251
266
  deadline TEXT,
252
267
  evidence TEXT,
253
268
  source TEXT NOT NULL,
269
+ issue_ref TEXT,
270
+ linear_issue_id TEXT,
254
271
  created_at TEXT NOT NULL,
255
272
  sent_at TEXT
256
273
  );
@@ -284,8 +301,11 @@ export class BriefItemsLedger {
284
301
  update_id TEXT NOT NULL,
285
302
  PRIMARY KEY (bot_id, chat_id, update_id)
286
303
  );`);
287
- if (!(db.query("SELECT name FROM pragma_table_info('items')").all() as { name: string }[]).some(column => column.name === 'dedupe_key')) {
288
- db.exec('ALTER TABLE items ADD COLUMN dedupe_key TEXT');
304
+ const columns = db.query("SELECT name FROM pragma_table_info('items')").all() as { name: string }[];
305
+ if (!columns.some(column => column.name === 'dedupe_key')) db.exec('ALTER TABLE items ADD COLUMN dedupe_key TEXT');
306
+ if (!columns.some(column => column.name === 'issue_ref')) db.exec('ALTER TABLE items ADD COLUMN issue_ref TEXT');
307
+ if (!columns.some(column => column.name === 'linear_issue_id')) {
308
+ db.exec('ALTER TABLE items ADD COLUMN linear_issue_id TEXT');
289
309
  }
290
310
  db.exec('CREATE INDEX IF NOT EXISTS items_dedupe ON items(source, dedupe_key, created_at)');
291
311
  return work(db);
@@ -301,6 +321,9 @@ export class BriefItemsLedger {
301
321
  if (!(BRIEF_DOMAINS as readonly string[]).includes(input.domain)) throw new BriefItemsInputError('invalid domain');
302
322
  if (!(BRIEF_PRIORITIES as readonly string[]).includes(input.priority)) throw new BriefItemsInputError('invalid priority');
303
323
  const source = required(input.source, 'source');
324
+ if (input.linearIssueId !== undefined && !/^[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i.test(input.linearIssueId)) {
325
+ throw new BriefItemsInputError('invalid Linear issue UUID');
326
+ }
304
327
  const deadline = optional(input.deadline, 'deadline');
305
328
  // Every field that reaches the composed Markdown is one line, so no stored item can forge a heading or entry (ACP must-fix).
306
329
  for (const [field, value] of [['source', source], ['evidence', input.evidence ?? null], ['deadline', deadline]] as const) {
@@ -311,6 +334,8 @@ export class BriefItemsLedger {
311
334
  if (!format.test(deadline) || !Number.isFinite(Date.parse(deadline))) throw new BriefItemsInputError('invalid deadline');
312
335
  }
313
336
  const evidence = optional(input.evidence, 'evidence');
337
+ const issueRef = optional(input.issueRef, 'issueRef');
338
+ if (issueRef !== null && /[\r\n]/.test(issueRef)) throw new BriefItemsInputError('issueRef must be a single line');
314
339
  const createdAt = input.createdAt ?? this.now().toISOString();
315
340
  if (!Number.isFinite(Date.parse(createdAt))) throw new BriefItemsInputError('invalid createdAt');
316
341
  const dedupeKey = input.dedupeKey === undefined ? null : normalizeClaim(required(input.dedupeKey, 'dedupeKey'));
@@ -319,7 +344,7 @@ export class BriefItemsLedger {
319
344
  throw new BriefItemsInputError('invalid dedupe window');
320
345
  }
321
346
  const selected = this.using(db => {
322
- const select = 'SELECT id, text, domain, priority, deadline, evidence, source, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items WHERE id = ?';
347
+ const select = 'SELECT id, text, domain, priority, deadline, evidence, source, issue_ref, linear_issue_id AS linearIssueId, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items WHERE id = ?';
323
348
  db.exec('BEGIN IMMEDIATE');
324
349
  try {
325
350
  if (dedupeKey !== null && windowMs !== undefined) {
@@ -329,15 +354,15 @@ export class BriefItemsLedger {
329
354
  AND julianday(created_at) <= julianday(?) ORDER BY id DESC LIMIT 1`)
330
355
  .get(source, dedupeKey, createdAt, windowMs, createdAt) as { id: number } | null;
331
356
  if (existing) {
332
- const item = db.query(select).get(existing.id) as BriefItem;
357
+ const item = briefItem(db.query(select).get(existing.id) as BriefItem);
333
358
  db.exec('COMMIT');
334
359
  return { item, added: false };
335
360
  }
336
361
  }
337
362
  const result = db.query(
338
- 'INSERT INTO items (text, domain, priority, deadline, evidence, source, created_at, sent_at, dedupe_key) VALUES (?, ?, ?, ?, ?, ?, ?, NULL, ?)',
339
- ).run(text, input.domain, input.priority, deadline, evidence, source, createdAt, dedupeKey);
340
- const item = db.query(select).get(result.lastInsertRowid) as BriefItem;
363
+ 'INSERT INTO items (text, domain, priority, deadline, evidence, source, issue_ref, linear_issue_id, created_at, sent_at, dedupe_key) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, NULL, ?)',
364
+ ).run(text, input.domain, input.priority, deadline, evidence, source, issueRef, input.linearIssueId ?? null, createdAt, dedupeKey);
365
+ const item = briefItem(db.query(select).get(result.lastInsertRowid) as BriefItem);
341
366
  db.exec('COMMIT');
342
367
  return { item, added: true };
343
368
  } catch (cause) {
@@ -434,9 +459,13 @@ export class BriefItemsLedger {
434
459
 
435
460
  /** Insertion order. Optional domain filter. Item text is the stored original. */
436
461
  list(filters: { domain?: BriefDomain } = {}): BriefItem[] {
437
- return this.using(db => (filters.domain === undefined
438
- ? db.query('SELECT id, text, domain, priority, deadline, evidence, source, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items ORDER BY id').all()
439
- : db.query('SELECT id, text, domain, priority, deadline, evidence, source, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items WHERE domain = ? ORDER BY id').all(filters.domain)) as BriefItem[]);
462
+ const rows = this.using(db => {
463
+ const select = 'SELECT id, text, domain, priority, deadline, evidence, source, issue_ref, linear_issue_id AS linearIssueId, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items';
464
+ return filters.domain === undefined
465
+ ? db.query(`${select} ORDER BY id`).all()
466
+ : db.query(`${select} WHERE domain = ? ORDER BY id`).all(filters.domain);
467
+ }) as BriefItem[];
468
+ return rows.map(briefItem);
440
469
  }
441
470
 
442
471
  /**
@@ -450,7 +479,7 @@ export class BriefItemsLedger {
450
479
  }
451
480
 
452
481
  private itemsFromDb(db: Database): BriefItem[] {
453
- return db.query('SELECT id, text, domain, priority, deadline, evidence, source, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items ORDER BY id').all() as BriefItem[];
482
+ return (db.query('SELECT id, text, domain, priority, deadline, evidence, source, issue_ref, linear_issue_id AS linearIssueId, created_at, (SELECT MIN(sent_at) FROM sends WHERE sends.item_id = items.id) AS sent_at FROM items ORDER BY id').all() as BriefItem[]).map(briefItem);
454
483
  }
455
484
 
456
485
  private pageFromDb(db: Database, slot: BriefSendSlot): { markdown: string; ids: number[] } {
@@ -562,3 +591,18 @@ export class BriefItemsLedger {
562
591
  return this.using(db => db.transaction(() => this.markSentInDb(db, ids, slot))());
563
592
  }
564
593
  }
594
+
595
+ export interface IntakeDailyBrief {
596
+ orchestrationId: string;
597
+ markdown: string;
598
+ }
599
+
600
+ function orchestrationId(): string {
601
+ return globalThis.crypto?.randomUUID?.() ?? `intake-brief-${Date.now()}-${Math.random().toString(36).slice(2, 10)}`;
602
+ }
603
+
604
+ /** Graph entrypoint for the daily 08:30 briefing; requirement-funnel items stay ephemeral. */
605
+ export function composeIntakeDailyBrief(options: BriefItemsOptions = {}): IntakeDailyBrief {
606
+ const ledger = new BriefItemsLedger(options);
607
+ return { orchestrationId: orchestrationId(), markdown: ledger.compose('08:30') };
608
+ }
@@ -31,7 +31,7 @@
31
31
  import type { SelfReportFrame } from './self-report-frame.js';
32
32
  import { resolveInstanceName } from '../instance-identity.js';
33
33
  import { getHarnessRunId } from '../harness/harness-space.js';
34
- import { injectKey, setFrameObserver, splitKeys, termSize as tuiTermSize, type Key } from '../tui.js';
34
+ import { injectKey, routeExternalTuiKey, setFrameObserver, splitKeys, termSize as tuiTermSize, type Key } from '../tui.js';
35
35
  import { canTransitionAccessMode, type PtyAccessMode, type PtyTransitionPolicy } from '../pty-shell/pty-ref.js';
36
36
  import { resolveWriteDecision, type PtyWriteActor } from '../pty-shell/pty-write-arbiter.js';
37
37
  import { registerPtyControlTarget, startPtyControlPoller, type PtyControlTarget } from '../pty-shell/registry.js';
@@ -43,7 +43,7 @@ import {
43
43
  updatePtyManifestBuild,
44
44
  } from '../pty-shell/pty-manifest.js';
45
45
  import { writeHarnessScreen } from '../harness/harness-screen.js';
46
- import { runningBuild, startTuiRunStateRecorder } from '../pty-shell/tui-run-state.js';
46
+ import { runningBuild, seatCompareDepsFromEnv, startTuiRunStateRecorder } from '../pty-shell/tui-run-state.js';
47
47
  import type { TuiSelfRestartDeps } from '../pty-shell/tui-run-state.js';
48
48
  import { lastHumanKeyAt } from '../tui.js';
49
49
  import { debug } from '../debug/log.js';
@@ -176,9 +176,19 @@ export function createTuiControlTarget(surfaceId: string, deps: TuiControlTarget
176
176
  stopTurn: (force: true) => force && stopTurn(),
177
177
  canWrite: (actor: PtyWriteActor = 'human') => resolveWriteDecision(accessMode, actor).allow,
178
178
  write(chars: string): void {
179
+ const keys = parse(chars);
180
+ const remaining: Key[] = [];
181
+ let routedToModal = false;
182
+ for (const key of keys) {
183
+ if (routeExternalTuiKey(key)) routedToModal = true;
184
+ else remaining.push(key);
185
+ }
186
+ if (routedToModal) {
187
+ if (remaining.length > 0 && !remaining.every(inject)) throw new Error('tui-input-undelivered');
188
+ return;
189
+ }
179
190
  // ⭐ 이 write 는 «바깥»(제어 IPC)에서만 온다 — 키보드와 섞이기 전에 라우터가 먼저 가른다.
180
191
  if (routeExternal(chars) !== 'passthrough') return;
181
- const keys = parse(chars);
182
192
  if (!keys.length || !keys.every(inject)) throw new Error('tui-input-undelivered');
183
193
  },
184
194
  resize: () => { throw new Error('tui-resize-unsupported'); },
@@ -444,9 +454,15 @@ export function startTuiSelfReport(deps: TuiSelfReportDeps = {}): () => void {
444
454
  const startRunState = deps.startRunState
445
455
  ?? (deps.registerRow
446
456
  ? () => () => {}
447
- : (id: string) => startTuiRunStateRecorder(id, {
448
- selfRestart: deps.selfRestart === null ? undefined : (deps.selfRestart ?? productionTuiSelfRestart(readActiveSessionId)),
449
- }));
457
+ : (id: string) => {
458
+ // TUI-SEAT-PILOT-2H-COMPARE — 판정 신호 한 줄은 env(ELANOUS_SEAT_COMPARE_RUN_ID)가 있을 때만 켜진다.
459
+ // env 가 없으면 빈 spread → 종전 기록 경로 그대로(보존 계약).
460
+ const seatCompare = seatCompareDepsFromEnv();
461
+ return startTuiRunStateRecorder(id, {
462
+ selfRestart: deps.selfRestart === null ? undefined : (deps.selfRestart ?? productionTuiSelfRestart(readActiveSessionId)),
463
+ ...(seatCompare ? { seatCompare } : {}),
464
+ });
465
+ });
450
466
  try { stopRunState = startRunState(surfaceId); } catch { /* fail-soft — recorder logs its own write failures */ }
451
467
  // 미룬 우편 깨움(TUI-H4) — 이 TUI 가 턴 중·5분 창이라 못 받은 깨움을 idle 로 «기록»된 뒤 한 번 다시 두드린다.
452
468
  // 실 행 등록과 짝일 때만(시험이 행 등록을 갈아 끼우면 0) · 무거운 모듈은 늦게 불러온다.
package/src/chat/index.ts CHANGED
@@ -523,7 +523,7 @@ export const SLASH_COMMANDS: SlashCommand[] = ([
523
523
  { name: 'tablet', aliases: [], description: 'Tablet mode — collapse layout to log + input', subcommands: ['on', 'off', 'toggle', 'auto', 'status', 'browser-preview', 'bp'] },
524
524
  { name: 'surface', aliases: [], description: 'Surface control — open a pane/catalog launcher (/surface catalog · browser · preview · log · scratch · obsidian · skill) OR set a preferred LLM surface (/surface coding-agent · research-agent · control-agent · ops-agent · … · clear · status)', subcommands: ['catalog', 'browser', 'preview', 'browser-preview', 'log', 'scratch', 'obsidian', 'skill', 'skill-file', 'agents', 'coding-agent', 'coding-chat', 'research-agent', 'research-chat', 'control-agent', 'ops-ui-agent', 'ops-fleet-agent', 'ops-agent', 'clear', 'status'] },
525
525
  { name: 'term', aliases: ['terminal'], description: 'Interactive terminal modal — new / list / attach / detach / switch / kill / snapshot / resume', subcommands: ['new', 'list', 'attach', 'detach', 'switch', 'kill', 'snapshot', 'resume'] },
526
- { name: 'side', aliases: [], description: '사이드탭 기초 — 목록 · 셸 생성 · 번호로 PTY 보기/attach', subcommands: ['list', 'new', 'attach'] },
526
+ { name: 'side', aliases: [], description: '사이드탭 — 목록 · 셸/Codex/Claude 탭 · attach · 미션 결과 파일', subcommands: ['list', 'new', 'attach', 'open', 'mission'] },
527
527
  { name: 'claude', aliases: [], description: 'Spawn claude-code CLI in a terminal modal' },
528
528
  { name: 'codex', aliases: [], description: 'Spawn codex CLI in a terminal modal' },
529
529
  { name: 'gemini', aliases: [], description: 'Spawn gemini CLI in a terminal modal' },
@@ -540,7 +540,7 @@ export async function runChatTurnCli(opts: {
540
540
  tools = built;
541
541
  dispatchTool = (name, args) => built.dispatch(name, args, { signal: toolAbort.signal });
542
542
  enabledToolNames = built.specs.map(s => s.name);
543
- process.once('SIGINT', abortToolsOnSigint);
543
+ process.on('SIGINT', abortToolsOnSigint);
544
544
  }
545
545
  // Wire the universal preamble (project anchor + project tree +
546
546
  // family addendum + session-specific guidance) into every CLI system
@@ -600,6 +600,7 @@ export async function runChatTurnCli(opts: {
600
600
  userConfig: opts.cfg,
601
601
  sessionId: session.id,
602
602
  userText: opts.userText,
603
+ ...(opts.surface === 'ask' ? { utteranceSurface: 'ask' as const } : {}),
603
604
  systemPrompt: agentSystemPrompt,
604
605
  onDelta: (d) => {
605
606
  replyChunks.push(d);
@@ -0,0 +1,31 @@
1
+ import type { Command } from 'commander';
2
+ import { refreshServerCatalog } from '../registry/catalog-server.js';
3
+ import { reloadCatalog } from '../registry/loader.js';
4
+
5
+ export interface CatalogCliDeps {
6
+ refresh?: typeof refreshServerCatalog;
7
+ reload?: typeof reloadCatalog;
8
+ write?: (line: string) => void;
9
+ setExitCode?: (code: number) => void;
10
+ }
11
+
12
+ export function registerCatalogCommands(program: Command, deps: CatalogCliDeps = {}): void {
13
+ const catalog = program.command('catalog').description('서명된 LLM 모델 카탈로그 관리');
14
+ catalog.command('refresh')
15
+ .description('서버 카탈로그를 서명·판 검증 후 로컬 캐시에 갱신')
16
+ .option('--json', '구조화 결과')
17
+ .option('--url <url>', '카탈로그 서버 주소 재정의(검증된 서명만 수용)')
18
+ .action(async (opts: { json?: boolean; url?: string }) => {
19
+ const result = await (deps.refresh ?? refreshServerCatalog)(opts.url ? { url: opts.url } : {});
20
+ const write = deps.write ?? ((line: string) => console.log(line));
21
+ if (result.ok) {
22
+ (deps.reload ?? reloadCatalog)();
23
+ const output = { outcome: 'updated', catalogVersion: result.payload.catalogVersion };
24
+ write(opts.json ? JSON.stringify(output) : `카탈로그 갱신 완료 · v${output.catalogVersion}`);
25
+ return;
26
+ }
27
+ const output = { outcome: 'failed', reason: result.reason };
28
+ write(opts.json ? JSON.stringify(output) : `카탈로그 갱신 실패 · ${output.reason}`);
29
+ (deps.setExitCode ?? ((code: number) => { process.exitCode = code; }))(1);
30
+ });
31
+ }
@@ -28,6 +28,7 @@ export interface ConnectorCliDeps {
28
28
  log?: typeof debug.log;
29
29
  bearerToken?: string;
30
30
  readKey?: () => Promise<string>;
31
+ stateDir?: string;
31
32
  }
32
33
 
33
34
  async function setLinearSecret(id: string, deps: ConnectorCliDeps): Promise<number> {
@@ -202,3 +203,18 @@ export async function runLinearSync(opts: ConnectorSyncOptions, deps: ConnectorC
202
203
  const events = await fetchLinearIssues({ apiKey: key, teamKey: opts.team, labelOrPrefix: opts.prefix, fetch: deps.fetch ?? fetch, ledger: deps.ledger });
203
204
  return applyLinearEvents(events, opts, deps);
204
205
  }
206
+
207
+ export async function runLinearDailyProgress(opts: { send?: boolean; json?: boolean; version?: string }, deps: ConnectorCliDeps = {}): Promise<number> {
208
+ const { syncLinearDailyProgress } = await import('../connectors/linear-daily-progress.js');
209
+ const result = await syncLinearDailyProgress({
210
+ dryRun: !opts.send,
211
+ ...(opts.version ? { version: opts.version } : {}),
212
+ ...(deps.stateDir ? { stateDir: deps.stateDir } : {}),
213
+ ...(deps.getSecret ? { getSecret: deps.getSecret } : {}),
214
+ ...(deps.fetch ? { fetch: deps.fetch } : {}),
215
+ ...(deps.log ? { log: deps.log } : {}),
216
+ });
217
+ (deps.output ?? console.log)(opts.json ? JSON.stringify(result) :
218
+ `connector linear daily-summary: ${result.dryRun ? 'dry-run' : 'send'} · planned ${result.plan.length} · posted ${result.posted} · duplicate ${result.skipped} · failed ${result.failed}`);
219
+ return result.failed ? 1 : 0;
220
+ }
@@ -442,8 +442,8 @@ export function nodePtyRebuildPlan(deps: DoctorFixDeps): { versionDir: string; p
442
442
  try {
443
443
  const versionDir = (deps.realpath ?? realpathSync)(join(readiness.installPrefix, 'current'));
444
444
  const packageDir = join(versionDir, 'node_modules', 'elanous');
445
- const pkg = JSON.parse((deps.readFile ?? ((path: string) => readFileSync(path, 'utf8')))(join(packageDir, 'package.json'))) as { dependencies?: Record<string, string>; optionalDependencies?: Record<string, string> };
446
- const version = pkg.optionalDependencies?.['node-pty'] ?? pkg.dependencies?.['node-pty'];
445
+ const pkg = JSON.parse((deps.readFile ?? ((path: string) => readFileSync(path, 'utf8')))(join(packageDir, 'package.json'))) as { dependencies?: Record<string, string>; optionalDependencies?: Record<string, string>; peerDependencies?: Record<string, string>; elanousOptionalIntegrations?: Record<string, string> };
446
+ const version = pkg.elanousOptionalIntegrations?.['node-pty'] ?? pkg.optionalDependencies?.['node-pty'] ?? pkg.dependencies?.['node-pty'] ?? pkg.peerDependencies?.['node-pty'];
447
447
  if (!version) return undefined;
448
448
  // RFC #20265 A2 amzn2: node-pty 는 C++20(gcc10) · node-gyp 는 Python 3.8+ 를 요구한다.
449
449
  const env: Record<string, string> = readiness.distro === 'amzn2' ? { CC: 'gcc10-gcc', CXX: 'gcc10-g++', PYTHON: 'python3.8' } : {};
@@ -0,0 +1 @@
1
+ {"pr": 32646, "headCommit": "1694ccc7a1704d451508008068265aeee45cde24", "reviewed": true, "verdict": "pass", "mustFix": [], "shouldFix": [], "reviewer": "OP-waiver", "model": "none (OP adjudication)", "waiver": {"by": "OP", "approvedBy": "OP 2026-10-29 10:5x «무한 리뷰 중단·웨이버» · r9 초과", "adjudicates": "pr-32646-2dcdb05e4306.json (gpt-6.1-terra r9 fail · mustFix 1: evidencePathPattern 이 @·공백·한글 경로를 잘라 출력)", "headTestRun": {"host": "node-b", "sha": "1694ccc7a1704d451508008068265aeee45cde24", "command": "bun test src/dashboard/seat-boot-preamble.test.ts", "pass": 20, "fail": 0, "expects": 97, "exit": 0, "rawOutput": "~/elanous-hq/seat-state/OPC/evidence/32646-1694ccc7a170-node-b.txt"}, "diffChecked": "2dcdb05e→1694ccc7: seat-boot-preamble.ts +7/-5 · test +16/-8 — 경로 끝 경계 판정 · 공백 경로는 확장자 꼬리 확인 · 시험이 proof@2.md·검증@2.md 전체 보존 ⊕ 공백·# 경로는 잘린 포인터 미출력 확인 — OP 직접 대조", "dispositions": [{"finding": 1, "disposition": "fixed-in-this-head", "evidence": "seat-boot-preamble.test.ts 추가 단언(asciiSpecialPath·unicodeSpecialPath 포함 · spaced/delimiter 잘린 출력 없음) · node-b 20/0"}]}, "summary": "OP waiver — r9 지적 수리 확인."}
@@ -0,0 +1 @@
1
+ {"pr": 32853, "headCommit": "bd8f73595c83e3bee478faa3b765d4082c4c5aa6", "reviewed": true, "verdict": "pass", "mustFix": [], "shouldFix": [], "reviewer": "OP-waiver", "model": "none (OP adjudication)", "waiver": {"by": "OP", "approvedBy": "OP 2026-10-29 10:5x «b OP 판정 예외 승인 · 무한 리뷰 중단·웨이버»", "adjudicates": "pr-32853-1c0f33c905e0.json (gpt-6.1-terra r11 fail mustFix 5) — 이후 수정 1c0f33c9→f3d60e98→bd8f7359 은 driver.test.ts 만(import 1 · 동적 경로 · 구독 fake · fail-closed 회귀 추가) · OP 가 diff 직접 대조", "headTestRun": {"host": "node-b", "sha": "bd8f73595c83e3bee478faa3b765d4082c4c5aa6", "command": "bun test src/agent-mission/driver.test.ts", "pass": 140, "fail": 0, "expects": 586, "exit": 0, "reportedBy": "OPC #51223"}, "dispositions": [{"finding": 1, "disposition": "already-fixed", "evidence": "driver.test.ts «$name accepts only its observed final-input suggestion after marker, answer, and stable idle»"}, {"finding": 2, "disposition": "already-fixed", "evidence": "driver.test.ts «completion record preserves a final answer longer than 100 lines…» · «long final answer is preserved while output logging remains bounded» · driver.ts slice(-3500) 은 LLM 입력·reviewSummary 뿐"}, {"finding": 3, "disposition": "out-of-scope-followup", "evidence": "실 CLI 자동 시험 → AGENT-MISSION-BENCH-READY-FU · 실측 run-ab227633 양팔 통과"}, {"finding": 4, "disposition": "already-fixed", "evidence": "driver.test.ts «empty input prompt never completes even after a stable interval»"}, {"finding": 5, "disposition": "fixed-in-this-head", "evidence": "readdirSync import 추가(f3d60e98) · fail-closed 쓰기 실패 회귀 추가(bd8f7359)"}]}, "summary": "OP waiver(재작성) — 정확 head 실측 140/0 근거."}
@@ -0,0 +1 @@
1
+ {"pr": 33097, "headCommit": "1cc85900413cfcb2fdc427d4ca85c51fc0eb8358", "reviewed": true, "verdict": "pass", "mustFix": [], "shouldFix": [], "reviewer": "OP-waiver", "model": "none (OP adjudication)", "waiver": {"by": "OP", "approvedBy": "OP 2026-10-29 10:5x «무한 리뷰 중단·웨이버» 일반 승인 · r7 상한 도달", "adjudicates": "pr-33097-1cc85900413c.json (gpt-6.1-terra r7 fail mustFix 2 — 리뷰 입력이 PR 본문·실행 로그를 못 봐 재개)", "headTestRun": {"host": "node-b", "sha": "1cc85900413cfcb2fdc427d4ca85c51fc0eb8358", "command": "bun test src/cli/pr-land-heavy-remote.test.ts src/task-orchestrator/surfaces/pod-warm-switch.test.ts src/task-orchestrator/surfaces/warm-reuse-evidence.test.ts src/cli/pr-land-pod-shadow-job.test.ts src/task-orchestrator/surfaces/pod-warm-worker-provider.test.ts", "pass": 130, "fail": 0, "expects": 536, "exit": 0, "rawOutput": "~/elanous-hq/seat-state/TC/evidence/33097-1cc85900-node-b.txt"}, "dispositions": [{"finding": 1, "disposition": "evidence-provided", "evidence": "원문 파일에 명령·EXIT_CODE=0·130 pass · (pass) «heavy land gate decides warm reuse once per landing — no evidence=off · 3 matching=live · 1 mismatch=recent-mismatch» · «persisted writer rows flow through the shared reader…» — OP 가 원문·head 시험 존재 대조"}, {"finding": 2, "disposition": "already-fixed", "evidence": "warm-reuse-evidence.test.ts:56 «expired or corrupt rows cannot revive older warm matches» · :69 «corruption after recent passing rows invalidates the entire evidence window» · :83 «a corrupt recent mismatch row cannot restore the preceding three green samples» — 원문에서 corrupt (pass) 3"}]}, "summary": "OP waiver — r7 stale reopen · 정확 head node-b 원문 130/0 근거."}
@@ -0,0 +1 @@
1
+ {"pr":33106,"headCommit":"972f31e4a3cab0dc62873f915f0c71a2882b6044","reviewed":true,"verdict":"pass","mustFix":[],"shouldFix":[],"reviewer":"OP-waiver","model":"none (OP adjudication)","waiver":{"by":"OP","approvedBy":"OP 2026-10-29 12:2x «0.2.41 재개 최적 경로» · 10:5x 웨이버 승인","adjudicates":"gpt-6.1-terra r6 on cc59ca7b (fail · mustFix 2 · shouldFix 1)","headTestRun":{"host":"node-b","sha":"972f31e4a3cab0dc62873f915f0c71a2882b6044","scope":"resume-release.test.ts 전체(apps/pwa/node_modules 부재 전·후 모두 · afterAll rmdirSync 경로 실제 통과)","pass":40,"fail":0,"reportedBy":"MK #51574"},"parentTestRun":{"host":"node-b","sha":"cc59ca7b1e264f4f23504d5523a32efbecf300b9","scope":"resume-release·release-branch·gate-autoheal·gate-shard-receipts 4 suite","pass":287,"fail":0,"expects":1677,"reportedBy":"MK #51494"},"diffChecked":"cc59ca7b→32646bb4: resume-release.ts +13/-5 · resume-release.test.ts +45/-? — 저장된 cutoff baseline 과 receipt base40 대조 · 부재/불일치 시 full(fail-closed) · OP 직접 대조 · 32646bb4→30001d64→972f31e4: 시험 파일만 — Pod checkout 의 apps/pwa/node_modules 부재(기존 28·새 3 실패 공통 원인 · 급행 게이트 123723) 를 빈 디렉터리 fixture 로 · 정리는 rmdirSync","mergeGate":"급행 열차 gate 가 착지 전 전체 반경 재측정","dispositions":[{"finding":1,"disposition":"fixed-in-this-head","evidence":"expectedBase40 = cutoff 노드 baseline.sha · 불일치/부재 → fail(full gate)"},{"finding":2,"disposition":"out-of-scope-followup","evidence":"Goodhart(합성 gate 출력 대신 실 graph 상태) → 0.2.42 GATE-MOCK-EVENT-SCENARIOS"},{"finding":3,"disposition":"fixed-in-this-head","evidence":"SIGTERM 시험이 완료 receipt 확인 뒤 중단"}],"expressGateFinding":"batch-minim5-express-123723 introduced 3 = 환경 원인(verifyResumePreflight 기본 commandRoot 의 apps/pwa/node_modules 부재) — 같은 파일 preexisting 28 과 동일 원인"},"summary":"OP waiver — 0.2.41 필수 GATE-RESUME-STALLED-ONLY."}
@@ -0,0 +1 @@
1
+ {"pr": 33113, "headCommit": "3ab51f05968f926047a670d11c2afcca698df028", "reviewed": true, "verdict": "pass", "mustFix": [], "shouldFix": [], "reviewer": "OP-waiver", "model": "none (OP adjudication)", "waiver": {"by": "OP", "approvedBy": "OP 2026-10-29 10:5x «무한 리뷰 중단·웨이버» · identity 지적 r1·r2 반복", "adjudicates": "ux-coord-entrance-fold-terra-r2-33113-f5db480b56d5.json (fail · mustFix 2)", "headTestRun": {"host": "node-b", "sha": "3ab51f05968f926047a670d11c2afcca698df028", "tests": {"task-hand": "1/0", "coordinator-shadow": "9/0", "tick": "5/0"}, "exit": 0, "rawOutput": "~/elanous-hq/seat-state/UX/evidence/33113-3ab51f05968f-node-b.txt", "fileHashesMatchHead": 7}, "dispositions": [{"finding": 1, "disposition": "reviewer-misread-contract", "evidence": "칸 COORD-ENTRANCE-FOLD «조율자 그림자가 ④ builder 로 같은 칸·같은 지시서 3일 연속» — ④ builder 는 지시서를 «만드는» caller 단계(OP #51545·#51569 정의 · PR 본문 기록). recipient(--seat)는 받는 자리로 증거 행에만 남긴다. 리뷰어는 builder 4 를 «받는 쪽»으로 읽었다."}, {"finding": 2, "disposition": "fixed-in-this-head", "evidence": "coordinator-shadow.ts:120 그룹 키 = agent·cell·directive(recipient 제외) · :116-124 recipient 는 그룹 속성으로만 · recipient 없는 옛 행도 같은 그룹 — OP 가 head 코드 직접 대조"}]}, "summary": "OP waiver — 계약 오독 1 · 수리 확인 1."}
@@ -0,0 +1 @@
1
+ {"pr":"33097","model":"gpt-6.1-terra","verdict":"fail","mustFix":["통합 head의 필수 수용 증거가 미완료다: 골 문서가 요구한 `bun test src/cli/pr-land-heavy-remote.test.ts src/task-orchestrator/surfaces/pod-warm-switch.test.ts`와 생산 호출 경로를 지나는 mock 무대의 명령·종료 코드·출력 원문이 없다. 장애 환경을 피한 판단은 타당하지만, node-b에서 실행해 일치 3건의 live, mismatch의 recent-mismatch, 착지당 판정 1줄과 기존 시험 통과를 확인해야 한다.","`readWarmReuseEvidence()`는 손상되거나 유효하지 않은 행을 조용히 제거한다. 최근 mismatch 행이 손상되면 그 앞의 성공 행들이 연속 표본으로 복원될 수 있어 fail-closed가 아니다. 손상된 창은 미측정으로 처리하고 회귀 시험을 추가하라."],"shouldFix":[],"requirements":["DELTA-FINDING 1: OPEN — 이번 delta에 필수 실행 결과와 출력 증거가 없다.","DELTA-FINDING 2: OPEN — 회귀 시험은 추가됐지만 구현 변경이나 시험 통과 증거는 없다.","관찰: 추가된 시험은 임시 디렉터리의 파일만 쓰고 정리한다. 실제 fail-closed 동작은 시험 실행 결과로 확인해야 한다."],"reviewed":true,"diffBudget":{"truncated":false,"shownChars":1645,"totalChars":1645,"omittedFiles":0},"referencedFilesOpened":false,"referencedFilesRead":0,"reviewInputChars":2488,"reviewDurationMs":6440,"basedOn":"10cd6c80fe8d036f7530fd373fcfffc1aa9be044","basedOnReview":"warm-land-evidence-terra-0241-r5-33097-10cd6c80fe8d.json","deltaFindings":[{"finding":"통합 head의 필수 수용 증거가 미완료다: 골 문서가 요구한 `bun test src/cli/pr-land-heavy-remote.test.ts src/task-orchestrator/surfaces/pod-warm-switch.test.ts`와 생산 호출 경로를 지나는 mock 무대의 명령·종료 코드·출력 원문이 없다. 장애 환경을 피한 판단은 타당하지만, node-b에서 실행해 일치 3건의 live, mismatch의 recent-mismatch, 착지당 판정 1줄과 기존 시험 통과를 확인해야 한다.","status":"open"},{"finding":"`readWarmReuseEvidence()`는 손상되거나 유효하지 않은 행을 조용히 제거한다. 최근 mismatch 행이 손상되면 그 앞의 성공 행들이 연속 표본으로 복원될 수 있어 fail-closed가 아니다. 손상된 창은 미측정으로 처리하고 회귀 시험을 추가하라.","status":"open"}],"excludedNewFindings":2,"deltaInputChars":2488,"deltaDurationMs":6440,"deltaEfficiency":{"inputRatio":0.8632893823733518,"timeRatio":0.9649385675756668,"maxRatio":0.3333333333333333,"withinTarget":false},"deltaOutcome":"reviewed","reviewRoute":"api","fallbackAttempted":false,"requestedModel":"gpt-6.1-terra","fallbackNotAttemptedReason":"primary-review-succeeded","skippedAcpFallbackBackends":[{"backend":"gemini","reason":"Confirmed live 2026-08-19 (first observed 2026-08-12): gemini-cli is rejected with IneligibleTierError (free-tier UNSUPPORTED_CLIENT). Antigravity CLI (agy) replaces it but does NOT speak ACP, so this ACP entry has no successor yet — use the PTY backend (--backend gemini) instead."}],"respondedProvider":"openai-codex","respondedModel":"gpt-6.1-terra","reviewerSource":"cli","headCommit":"1cc85900413cfcb2fdc427d4ca85c51fc0eb8358","currentHeadCommit":"1cc85900413cfcb2fdc427d4ca85c51fc0eb8358","stale":false,"refetched":false,"diffSource":"sha-pinned","diffBaseCommit":"10cd6c80fe8d036f7530fd373fcfffc1aa9be044","localHeadComparison":"unavailable","localHead":"59018b9bd0d74574b50bdf4880373756335758a8","prHead":"1cc85900413cfcb2fdc427d4ca85c51fc0eb8358","localHeadComparisonReason":"detached-head","reviewerContextLoaded":0,"reviewerContextFailed":0,"reviewerContextFailures":[],"reviewerContextSource":"pr-diff-files","reviewerContextSourcePaths":[],"decompositionContextStatus":"absent","findingPathHeadChecks":[],"pathWarnings":[],"evidence":"saved-review-delta","prDiffFiles":1}
@@ -1,23 +1,44 @@
1
1
  import type { Command } from 'commander';
2
2
  import { randomUUID } from 'node:crypto';
3
+ import { resolve } from 'node:path';
3
4
  import { effectiveInstanceRoot } from '../instance/resolve.js';
4
- import { addSource, canonicalSeat, dueSources, expiredSource, listSources, removeSource, runDue, type SourceKind } from '../intake-plane/intake-sources.js';
5
+ import { addSource, canonicalSeat, dueSources, expiredSource, listSources, removeSource, runDue, type RunDueDeps, type SourceKind } from '../intake-plane/intake-sources.js';
6
+ import { projectTopicBriefing, subscribeTopicSearch, type SubscribeTopicSearchInput } from '../intake-plane/actions.js';
7
+ import { runIntakeIssueBriefing } from '../intake-plane/actions.js';
5
8
 
6
- export function registerIntakeSourceCommands(intake: Command, root: () => string = effectiveInstanceRoot): void {
9
+ export function registerIntakeSourceCommands(intake: Command, root: () => string = effectiveInstanceRoot,
10
+ deps: { subscribeTopicSearch?: (input: SubscribeTopicSearchInput, options?: { stateDir?: string; runDeps?: RunDueDeps }) => ReturnType<typeof subscribeTopicSearch> } = {}): void {
7
11
  const source = intake.command('source').description('자리별 흡수 원천과 주기 등록·조회·실행');
8
12
  const fail = (error: unknown) => { console.error(error instanceof Error ? error.message : String(error)); process.exitCode = 2; };
9
13
  source.command('add')
10
14
  .requiredOption('--seat <id>', '자리 id 또는 별칭')
11
- .requiredOption('--kind <kind>', 'github-query | rss | command')
15
+ .requiredOption('--kind <kind>', 'github-query | rss | command | topic-search')
12
16
  .requiredOption('--spec <spec>', 'GitHub 질의 · 피드 URL · 명령')
13
17
  .requiredOption('--every <cadence>', 'Nh | Nd | Nw')
14
18
  .option('--until <date>', '만료 시작 날짜 YYYY-MM-DD (UTC)')
15
19
  .option('--why <reason>', '등록 이유')
16
20
  .option('--id <id>', '원천 id')
17
- .action((opts: { seat: string; kind: string; spec: string; every: string; until?: string; why?: string; id?: string }) => {
21
+ .option('--linear-issue-id <uuid>', 'topic-search parent Linear issue UUID')
22
+ .option('--schedule-cron <expression>', 'topic-search schedule registry cron (e.g. 0 8 * * 1)')
23
+ .option('--telegram-dry-run-file <path>', 'Telegram 브리핑 본문을 이 파일에 기록하고 실제 발송은 하지 않음 (topic-search)')
24
+ .action(async (opts: { seat: string; kind: string; spec: string; every: string; until?: string; why?: string; id?: string; linearIssueId?: string; scheduleCron?: string; telegramDryRunFile?: string }) => {
18
25
  try {
26
+ if (opts.kind === 'topic-search') {
27
+ if (!opts.linearIssueId || !opts.scheduleCron) throw new Error('topic-search 는 --linear-issue-id 와 --schedule-cron 이 필요하다');
28
+ const telegramDryRunFile = opts.telegramDryRunFile ? resolve(opts.telegramDryRunFile) : undefined;
29
+ const result = await (deps.subscribeTopicSearch ?? subscribeTopicSearch)({ seat: opts.seat, topic: opts.spec,
30
+ linearIssueId: opts.linearIssueId, every: opts.every, scheduleCron: opts.scheduleCron,
31
+ ...(telegramDryRunFile ? { telegramDryRunFile } : {}) },
32
+ { stateDir: root(), runDeps: { projectTopicBriefing: telegramDryRunFile
33
+ ? (registered, items, stateDir) => projectTopicBriefing(registered, items, stateDir, { telegramDryRunFile })
34
+ : projectTopicBriefing } });
35
+ console.log(`${result.source.id} ${result.source.seat} topic-search ${result.source.every} schedule=${result.scheduleId} immediate=${result.immediate.ran.map(row => row.items).join(',')}`);
36
+ return;
37
+ }
19
38
  const added = addSource({ id: opts.id ?? `src-${randomUUID().slice(0, 8)}`, seat: opts.seat, kind: opts.kind as SourceKind,
20
- spec: opts.spec, every: opts.every, ...(opts.until ? { until: opts.until } : {}), ...(opts.why ? { why: opts.why } : {}) }, root());
39
+ spec: opts.spec, every: opts.every, ...(opts.until ? { until: opts.until } : {}), ...(opts.why ? { why: opts.why } : {}),
40
+ ...(opts.linearIssueId ? { linearIssueId: opts.linearIssueId } : {}),
41
+ ...(opts.scheduleCron ? { scheduleCron: opts.scheduleCron } : {}) }, root());
21
42
  console.log(`${added.id} ${added.seat} ${added.kind} ${added.every}`);
22
43
  } catch (error) { fail(error); }
23
44
  });
@@ -38,18 +59,33 @@ export function registerIntakeSourceCommands(intake: Command, root: () => string
38
59
  });
39
60
  source.command('run-due')
40
61
  .option('--seat <id>', '자리 id 또는 별칭')
62
+ .option('--source-id <id>', '단일 입력원만 실행 (스케줄 레지스트리 호출용)')
63
+ .option('--project-issue-briefing', 'topic-search 결과를 관련 Linear 이슈의 Telegram·코멘트에 투영')
64
+ .option('--telegram-dry-run-file <path>', 'Telegram 브리핑 본문을 이 파일에 기록하고 실제 발송은 하지 않음')
41
65
  .option('--dry-run', '기한 원천 목록만 · 수집·원장·마지막 실행 시각 무변')
42
66
  .option('--json', 'JSON 출력')
43
- .action(async (opts: { seat?: string; dryRun?: boolean; json?: boolean }) => {
67
+ .action(async (opts: { seat?: string; sourceId?: string; projectIssueBriefing?: boolean; telegramDryRunFile?: string; dryRun?: boolean; json?: boolean }) => {
44
68
  try {
45
69
  const seat = opts.seat === undefined ? undefined : canonicalSeat(opts.seat);
46
70
  if (opts.dryRun) {
47
- const sources = dueSources(new Date(), root()).filter((entry) => seat === undefined || entry.seat === seat);
71
+ const sources = dueSources(new Date(), root(), opts.sourceId).filter((entry) => seat === undefined || entry.seat === seat);
48
72
  if (opts.json) console.log(JSON.stringify(sources));
49
73
  else for (const entry of sources) console.log(`${entry.id} ${entry.seat} ${entry.kind} ${entry.every}`);
50
74
  return;
51
75
  }
52
- const result = await runDue({ seat, deps: { stateDir: root() } });
76
+ const telegramDryRunFile = opts.telegramDryRunFile ? resolve(opts.telegramDryRunFile) : undefined;
77
+ const result = await runDue({ seat, sourceId: opts.sourceId, deps: { stateDir: root(),
78
+ ...(opts.projectIssueBriefing || telegramDryRunFile ? { projectTopicBriefing: telegramDryRunFile
79
+ ? (registered, items, stateDir) => projectTopicBriefing(registered, items, stateDir, { telegramDryRunFile })
80
+ : projectTopicBriefing } : {}),
81
+ onCollected: async (source, raws) => {
82
+ if (!source.issueRef) return;
83
+ await runIntakeIssueBriefing({
84
+ issueRef: source.issueRef, topic: source.spec, state: 'open', collected: true,
85
+ evidence: raws.filter(raw => typeof raw.url === 'string' && raw.url.trim().length > 0)
86
+ .map(raw => ({ title: raw.title || source.spec, url: raw.url!, summary: raw.text || raw.title || source.spec })),
87
+ }, { stateDir: root() });
88
+ } } });
53
89
  if (opts.json) console.log(JSON.stringify(result));
54
90
  else for (const row of result.ran) console.log(`${row.id} ${row.items}${row.error ? ` 실패: ${row.error}` : ''}`);
55
91
  if (result.ran.some((row) => row.error)) process.exitCode = 1;
@@ -3,7 +3,7 @@ import { mkdirSync } from 'node:fs';
3
3
  import { dirname } from 'node:path';
4
4
  import { ensureAuthToken } from '../auth/acp-token.js';
5
5
  import { elanousStateRoot } from '../autopilot/state-paths.js';
6
- import { canonicalSeatId, openMsgStore, openMsgStoreReadOnly, type Message, type MsgStore } from '../msg/msg-store.js';
6
+ import { canonicalMessageAddress, canonicalSeatId, openMsgStore, openMsgStoreReadOnly, type Message, type MsgStore } from '../msg/msg-store.js';
7
7
  import { clearPostOffice, ensurePostOffice, writePostOffice } from '../msg/msg-post-office.js';
8
8
  import { acquireLockSync } from '../storage/file-lock.js';
9
9
  import { GitHubMsgMirrorTransport } from '../msg/msg-mirror-github.js';
@@ -325,7 +325,8 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
325
325
  const from = seat(opts.from, '--from');
326
326
  const unsupported = opts.to === undefined ? null : unsupportedLoopAddressNotice(opts.to);
327
327
  if (unsupported) out.error(unsupported);
328
- const to = seat(opts.to, '--to');
328
+ if (opts.to === undefined) throw new Error('--to is required');
329
+ const to = canonicalMessageAddress(opts.to);
329
330
  // Validate the auto-reply target before saving — a mismatched flag must not leave a stored message behind.
330
331
  const agentAddress = agentReplyAddress(opts.agentReply);
331
332
  if (agentAddress !== null) requireAgentTarget(agentAddress, to);
@@ -364,7 +365,7 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
364
365
  msg.command('route <address>').description('Show how a post to this address is read (replyBody) and woken (wake)')
365
366
  .option('--json')
366
367
  .action((address: string, opts: CommonOptions) => run(() => {
367
- const to = canonicalSeatId(address);
368
+ const to = canonicalMessageAddress(address);
368
369
  const wake = resolveWake(to, deps.wakeDeps);
369
370
  const row = { msgAddress: to, replyBody: messageRouteFor(to)?.replyBody ?? null, ...wake };
370
371
  emit(row, opts.json, () => out.log(`${to}\treplyBody=${row.replyBody ?? '모름'}\twake=${wake.wake}`
@@ -372,6 +373,34 @@ export function registerMsgCommands(program: Command, deps: MsgCliDeps = {}): vo
372
373
  + `\t(${wake.source}${wake.reason ? `: ${wake.reason}` : ''})`));
373
374
  })());
374
375
 
376
+ const group = msg.command('group').description('Manage local message group subscriptions');
377
+ group.command('create <name>').description('Create a group and subscribe its owner')
378
+ .requiredOption('--from <seat>', 'seat creating and owning the group').option('--json')
379
+ .action((name: string, opts: { from: string; json?: boolean }) => run(() => {
380
+ const address = withStore(store => store.createGroup(name, opts.from));
381
+ emit({ address, owner: canonicalSeatId(opts.from) }, opts.json, () => out.log(`${address} created; ${canonicalSeatId(opts.from)} subscribed`));
382
+ })());
383
+ group.command('join <name>').description('Subscribe a seat to a group')
384
+ .requiredOption('--seat <seat>').option('--json')
385
+ .action((name: string, opts: { seat: string; json?: boolean }) => run(() => {
386
+ const joined = withStore(store => store.joinGroup(name, opts.seat));
387
+ const row = { group: canonicalMessageAddress(name.startsWith('group:') ? name : `group:${name}`), seat: canonicalSeatId(opts.seat), joined };
388
+ emit(row, opts.json, () => out.log(`${row.seat} ${row.joined ? 'joined' : 'already subscribed'} ${row.group}`));
389
+ })());
390
+ group.command('leave <name>').description('Unsubscribe a seat from a group')
391
+ .requiredOption('--seat <seat>').option('--json')
392
+ .action((name: string, opts: { seat: string; json?: boolean }) => run(() => {
393
+ const left = withStore(store => store.leaveGroup(name, opts.seat));
394
+ const row = { group: canonicalMessageAddress(name.startsWith('group:') ? name : `group:${name}`), seat: canonicalSeatId(opts.seat), left };
395
+ emit(row, opts.json, () => out.log(`${row.seat} ${row.left ? 'left' : 'was not subscribed to'} ${row.group}`));
396
+ })());
397
+ group.command('list').description('List a seat’s active group subscriptions')
398
+ .requiredOption('--seat <seat>').option('--json')
399
+ .action((opts: { seat: string; json?: boolean }) => run(() => {
400
+ const groups = withStore(store => store.listGroups(opts.seat));
401
+ emit(groups, opts.json, () => { if (!groups.length) out.log('No groups.'); else for (const address of groups) out.log(address); });
402
+ })());
403
+
375
404
  msg.command('list').description('List messages for one recipient or one thread without acknowledging them')
376
405
  .option('--to <seat>').option('--thread <id>', 'request ID; list it and its replies, regardless of recipient')
377
406
  .option('--after <id>', 'exclusive message ID (default: acknowledged cursor for a recipient, 0 for a thread)')
package/src/cli/pr-cli.ts CHANGED
@@ -37,6 +37,7 @@ import {
37
37
  type CmdRunner,
38
38
  type PrManager,
39
39
  } from '../autopilot/pr-manager.js';
40
+ import { observePrLineage } from '../pr-tool/census.js';
40
41
  import {
41
42
  collectBaseLandingCommits,
42
43
  computeGranularityStats,
@@ -68,6 +69,7 @@ import { ensurePrLandHeavyRemote, type HeavyRemoteInput, type HeavyRemoteResult
68
69
  import { readPrBaseNameWithRetry } from './pr-land-base-read.js';
69
70
  import { runHeavyOnPodShadow } from './pr-land-pod-shadow.js';
70
71
  import type { LandingPodShadowInput, LandingPodShadowVerdict } from './pr-land-pod-shadow-job.js';
72
+ import { recordWarmReuseEvidence, warmReuseEvidencePath } from '../task-orchestrator/surfaces/warm-reuse-evidence.js';
71
73
  import { readTaskAgentState, taskAgentStatePath, type TaskCard } from '../task-agent/task-hand.js';
72
74
  import { INFLIGHT_REGISTRY_FILE, removeInflightForPr } from '../pr-tool/inflight-registry.js';
73
75
  import { PR_LABEL_NAMES } from '../github/pr-labels.js';
@@ -1899,10 +1901,19 @@ export async function runPrLand(opts: PrLandOpts = {}, deps: PrLandDeps = {}): P
1899
1901
  local: { measured: verdict.rootPlan != null, ok: verdict.ok, rootPlan: verdict.rootPlan ?? null },
1900
1902
  runPod: async () => {
1901
1903
  const runPod = deps.runLandingPodShadow ?? (await import('./pr-land-pod-shadow-job.js')).runLandingPodShadowJob;
1902
- return runPod({ head: opts.expectedHead!, main });
1904
+ return runPod({ pr: Number(opts.pr), repo: cwd, host: verdict.host ?? '', head: opts.expectedHead!, main });
1903
1905
  },
1904
1906
  log: (category, event, data) => debug.log(category, event, { ...data, main, phase: 'initial' }),
1905
1907
  warn: (message) => out.error(`⚠ heavy-on-pod-shadow: ${message}`),
1908
+ onShadow: ({ pod, agree }) => {
1909
+ const shadow = pod && typeof pod === 'object' ? pod as LandingPodShadowVerdict : undefined;
1910
+ const warm = shadow?.warmEvidence;
1911
+ recordWarmReuseEvidence(warmReuseEvidencePath(), {
1912
+ schema: 1, consumer: 'land', pr: Number(opts.pr), head: opts.expectedHead!, main, recordedAt: new Date().toISOString(),
1913
+ ...(warm ? { ...warm, agree: warm.agree && agree } : {}),
1914
+ ...(!warm ? { reason: shadow?.warmReason ?? 'warm-shadow-unmeasured' } : {}),
1915
+ });
1916
+ },
1906
1917
  });
1907
1918
  }
1908
1919
  }
@@ -2536,6 +2547,15 @@ export function registerPrCommands(program: Command, deps: PrLandDeps = {}, queu
2536
2547
  try { await supersedeMerged(number, opts.cwd ?? process.cwd()); }
2537
2548
  catch (error) { prToolOut.error(`✗ supersede-drafts: ${String(error)}`); prToolExit(1); }
2538
2549
  });
2550
+ pr.command('lineage <pr>')
2551
+ .description('PR 계보의 관측 사실만 JSON으로 읽기 (첫 조각 · 닫기 판정 없음)')
2552
+ .requiredOption('--json', 'JSON 관측 결과 출력')
2553
+ .option('--cwd <path>', '저장소 경로')
2554
+ .action((rawPr: string, opts: { cwd?: string }) => {
2555
+ const result = observePrLineage({ pr: Number(rawPr), run: prToolRun, cwd: opts.cwd });
2556
+ prToolOut.log(JSON.stringify(result));
2557
+ if (result.status === 'unknown') prToolExit(1);
2558
+ });
2539
2559
  pr.command('census')
2540
2560
  .description('열린 PR 전체·골 문서만·2일 무커밋 draft·미닫힌 superseded 집계')
2541
2561
  .option('--cwd <path>', '저장소 경로')