elanous 0.2.19 → 0.2.21
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.
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/MObU8ujkMciAKr6ljAV05/_buildManifest.js +1 -0
- package/apps/pwa/out/_next/static/chunks/088d8e8a.8069543d082bec12.js +160 -0
- package/apps/pwa/out/_next/static/chunks/1109.78a7a3288c0259d9.js +148 -0
- package/apps/pwa/out/_next/static/chunks/115.1c6690b8604f81c4.js +32 -0
- package/apps/pwa/out/_next/static/chunks/119fc678.6f591cdb84ca5791.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1262.76a3f08e67c5f816.js +309 -0
- package/apps/pwa/out/_next/static/chunks/{4323.c5dfb6f503304775.js → 1268.0840ff91e083fcbd.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/1307-c97eba9fb72a9a5e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1358d292.5c87f12cad6eaa91.js +122 -0
- package/apps/pwa/out/_next/static/chunks/1438.27a1a7b8f2308004.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1442.02d85cd88f4c1eac.js +79 -0
- package/apps/pwa/out/_next/static/chunks/1501-1aad662d82ba43f7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1584.9e2dd53da6e6d4b1.js +24 -0
- package/apps/pwa/out/_next/static/chunks/1586.b989b0614afb77e6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1609.2ad355062870151f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1612-f6df0fc0eed7157b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1826-5d279da64bbbc2de.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1923.37f1d5fe7ebe3860.js +27 -0
- package/apps/pwa/out/_next/static/chunks/1948.5f35b39eef222a94.js +5 -0
- package/apps/pwa/out/_next/static/chunks/195-fb1d7690bf30bab4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1986-33e13d648a9df765.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1993.3fd074a2a246234e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2977-e38442e86289f1d3.js → 211-9c9090c59e2c5907.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2140.d2daf9ee96e295d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2196-4700653d12a44b40.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2212.0359851457473efc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/224.583e562365a52f74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2328.0f37465646bafa7d.js +36 -0
- package/apps/pwa/out/_next/static/chunks/2372.bf71372184991937.js +286 -0
- package/apps/pwa/out/_next/static/chunks/2489-ff55a35b202c0f94.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2537-6c289376caa88ca1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2549-a8515c86f9e8cb96.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2655.72cc6a97276c5acc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2699-325cc923ba7b8631.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2743-ef6e8c3ced74cce5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2840-5458ad50c49cac6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2856.f75d5baef7f49b74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/311.e685738f92e6e2ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3194-807b212fb8eae065.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3324-d1d2979821dfa845.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3344.0de4b0ec5a454b7a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/335.a13f339e97893437.js +94 -0
- package/apps/pwa/out/_next/static/chunks/3394.646348f34b2500be.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3443.6276909b53d72d53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3495.abd4254d808bf2dc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3522-1de1319d028ac89c.js +25 -0
- package/apps/pwa/out/_next/static/chunks/3558-bbb5ab553a0471d3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3721.ba5b82db0d9a5572.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3857-995ea9f5ef33d71e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3916-3d02dd1fc257dd3c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3919.9ff7dc25afefee33.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3998.bd9a69d9b50e9bd2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4003.ab6db1dc266576c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4144-fad095b48a1862ee.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4216.e8ac94b9fe6b96ab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4327.c44dc2b55cb43ee5.js +34 -0
- package/apps/pwa/out/_next/static/chunks/4401.94257d497b6d26bc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4559.17ca2cdbaa8d414f.js +115 -0
- package/apps/pwa/out/_next/static/chunks/4565-3d7e3fdeb43686a8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4588.ad3364cb7fb97ada.js +86 -0
- package/apps/pwa/out/_next/static/chunks/4706.97e734bd4c9816ca.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4795-f372490b178583fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4982.6e44352f751b9a1b.js +77 -0
- package/apps/pwa/out/_next/static/chunks/5342.49c5c5a530e62b50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5360-08a80abdf3a4da99.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5431.66c58ab1327ee0b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5717.bcfcb96e701b82e0.js +90 -0
- package/apps/pwa/out/_next/static/chunks/5755-30d102586789bf7f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5957.3f1a4012388dd962.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5977-59fedea50d13c762.js +1 -0
- package/apps/pwa/out/_next/static/chunks/602.9bf02ac8e9502598.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6020.3a1b347e2d2dfacc.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{4847.56f5bc454fbcc827.js → 6110.1297d4093fdfbb0d.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6158.566c890adc06a459.js +2 -0
- package/apps/pwa/out/_next/static/chunks/6375.fce1d174ba6d0324.js +64 -0
- package/apps/pwa/out/_next/static/chunks/6546.92a828aef441271f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/658.957fdb0a8c6c6c8e.js +287 -0
- package/apps/pwa/out/_next/static/chunks/6706.323590aabb8b1293.js +226 -0
- package/apps/pwa/out/_next/static/chunks/6747.b67947f293a4c02d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6767.8e6c5f6e744fcd9f.js +38 -0
- package/apps/pwa/out/_next/static/chunks/6868.000b24a3045c5574.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6877-74399f69c7da1433.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6946.bba74e9c96050f30.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7033.a558f1b2f6912a53.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7065.46029c26c53eac50.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7087.6fae577d09249bc1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7175-350f4ce2873bc038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/722.de8d9801e0f6d414.js +41 -0
- package/apps/pwa/out/_next/static/chunks/{1470.98a6ab61ccb4131c.js → 726.83532d69452ee24b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7290-f09c928a06c52e2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{6062-73e68343a9814f6a.js → 7327-2d69fb321ba73389.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/7497.57981e9d7a75a52a.js +24 -0
- package/apps/pwa/out/_next/static/chunks/7630.2b9a68659053ff4e.js +193 -0
- package/apps/pwa/out/_next/static/chunks/7672.4af122ad892117c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/771.6ab889a233e7dae7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7797-df5aa0381fdc078f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7899.597af4a9996c907f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/79b78388.663188133449d707.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8060-cc008cc6fedfa818.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8085-d065d0393c1760f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8096.f7da0776cfde6300.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8194.484f51e273d9abd2.js +217 -0
- package/apps/pwa/out/_next/static/chunks/8401-35e94e9091f5eb8d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8682-7061dd4fa7bd62ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8695-846034ce44852c70.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8769.815ca69879f608b4.js +104 -0
- package/apps/pwa/out/_next/static/chunks/8857-f1762140ef9a96b1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/88729267.9c6c000157c83f2f.js +62 -0
- package/apps/pwa/out/_next/static/chunks/8f835b4f.048eeb02299e3e12.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9068.5f2764fccf86c1b2.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9070.067c106528ec1ae6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9103-60fbef33e66f0a46.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9247-7581825d511a64c0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7647.2fcd30d894d5ee30.js → 935.4ddaa99fc1d1126c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9451.ebfb0dcc9c02250f.js +23 -0
- package/apps/pwa/out/_next/static/chunks/9497-b0e758d1cd4ae8d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9559.e648369b1d57cf9a.js +62 -0
- package/apps/pwa/out/_next/static/chunks/9832.2ab2e818013574c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/a9f2b54d-40c16bd0efdb04b8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-937c92292a4ab4f0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-d781be3e3a9cfd74.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-b0a80997903852d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-2b1263165630d9c8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea998f7f5d156bea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-33c328b64ca508f8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-e2d6bed48ac20120.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-111cabe4d1fd69ae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-544dd4bd4847eeb7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-3ee191319bf97d87.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-e4bcb2c503dab04b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-300897dcbbd5ed76.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-a449f1ed472b81c2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-9045094d6d3b5cd0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-c06673596849ef45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-103fa3191c1b2e08.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-9f81233f29dcd409.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/{page-b70cd005d9169e25.js → page-be8b4615c919e36c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-c685b104e0dfa609.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-8d693331cfbb6add.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-cef4f30a4c22fae1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-66ea1b54fc83fa15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-7a12f61be4a579d1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-c85b0589591a99c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-725a4da02dd129eb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-8cc707bd09a497d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-90b55be1f15ce0e8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-cb16606e08be65db.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-16dc64b74ed6a40a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-21bec4afeb2f0917.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-dc39ee7a36d26385.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-84ae759f76053672.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-3db58ddb61fe2be9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-c5315e30f3528dc4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-2fe368efb6de3b6a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-8d04132dd0ac5e10.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-c1a96669158471ec.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-f23484de467c9ea3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-c69762987b751174.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-5456692bda39aafb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-d75f7cd65845ce98.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-5603f5e568b25ce3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-d2cc0f4e89f42028.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-a6eb73b8a4840f1c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-c0a3f4d10edb83fa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-6c0b88068c143f15.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-7f8d7fcdf058a845.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-22163556cd38bc88.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-141436fd26dd56fc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/d70879db.c66c56a95a91efc6.js +66 -0
- package/apps/pwa/out/_next/static/chunks/{8046cadf-211ca3c0e00f2b72.js → f6231284-45726550aba08fca.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2ea96958.e8c7e112de50b067.js → f6b7c9ba.64a895b8b2fedbdc.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/f8626309.a4e5d362b1d55e59.js +1 -0
- package/apps/pwa/out/_next/static/chunks/framework-5c169757551134ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-59fe95fed40c7a01.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-4ca74dbbee7057c6.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-13a0a886df4d97a1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-6af8591cd3a3f038.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-f2b4016b9b981bc8.js +1 -0
- package/apps/pwa/out/_next/static/css/{d3427996da11e480.css → b9d8151e48998417.css} +1 -1
- package/apps/pwa/out/_next/static/css/e81df11490b4413b.css +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +23 -23
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +23 -23
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +23 -23
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +22 -22
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +22 -22
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +23 -23
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +22 -22
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +23 -23
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +23 -23
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +22 -22
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +23 -23
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +24 -24
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +23 -23
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +23 -23
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +22 -22
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +23 -23
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +23 -23
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +23 -23
- package/apps/pwa/out/live-run/index.html +1 -0
- package/apps/pwa/out/live-run/index.txt +35 -0
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +22 -22
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +22 -22
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +22 -22
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +23 -23
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +23 -23
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +22 -22
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +22 -22
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +22 -22
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +22 -22
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +23 -23
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +23 -23
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +22 -22
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +23 -23
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +23 -23
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +23 -23
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +23 -23
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +23 -23
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +22 -22
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +23 -23
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +23 -23
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +23 -23
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +23 -23
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +23 -23
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +23 -23
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +23 -23
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +23 -23
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +23 -23
- package/graphs/demo/editor-recipes.yaml +22 -0
- package/graphs/drafts/recipes.yaml +4 -4
- package/graphs/implement-loop.yaml +277 -5
- package/graphs/retro/daily.yaml +25 -0
- package/graphs/retro/recipes.yaml +24 -0
- package/package.json +1 -1
- package/scripts/ask-marker-check.ts +3 -1
- package/scripts/coord-channel-watch.sh +31 -4
- package/scripts/docs-lint.ts +4 -1
- package/scripts/land-global-checks.ts +89 -0
- package/scripts/lib/pch-regress-map.ts +2 -1
- package/scripts/marketing/generate-ax-brief.ts +18 -1
- package/scripts/measure-nl-routing-corpus.ts +11 -3
- package/scripts/release-loop/gate-node.ts +296 -25
- package/scripts/release-loop/gate-timing.ts +116 -7
- package/scripts/release-loop/preflight.ts +6 -4
- package/scripts/release-loop/publish-window.ts +141 -0
- package/scripts/release-loop/release-docs.ts +1 -4
- package/scripts/release-loop/release-universe.ts +38 -0
- package/scripts/release-loop/resume-release.ts +4 -1
- package/scripts/release-loop/shard-plan.ts +50 -5
- package/scripts/release-loop/unattended-release.ts +10 -2
- package/scripts/release-story/draft.ts +5 -1
- package/scripts/retro/shadow-compare.ts +71 -0
- package/scripts/rhythm/daily.ts +8 -2
- package/src/agent-mission/driver.ts +34 -6
- package/src/autopilot/build/llm-conflict-merge.ts +132 -7
- package/src/autopilot/build/merge-intent.ts +135 -7
- package/src/away/release-watch.ts +20 -3
- package/src/browser-cdp/client.ts +10 -5
- package/src/cli/config-drift.ts +513 -0
- package/src/cli/log-event-names.ts +4 -0
- package/src/cli/ops-cli.ts +11 -0
- package/src/cli/ops-overview-cli.ts +50 -0
- package/src/cli/pod-cli.ts +1 -0
- package/src/cli/pr-cli.ts +20 -0
- package/src/cli/release-cli.ts +20 -5
- package/src/cli/retro-cli.ts +78 -0
- package/src/cli/tasks-cli.ts +200 -8
- package/src/dashboard/index.ts +40 -4
- package/src/dashboard/slash-runtime/dashboard-handlers.ts +5 -4
- package/src/dashboard/slash-runtime/help-from-registry.ts +57 -31
- package/src/domains/outbound-log-probe.ts +6 -1
- package/src/esc-abort-gate.ts +3 -1
- package/src/graph-runner/graph-cli.ts +57 -0
- package/src/graph-runner/graph-run-api.ts +218 -0
- package/src/graph-runner/runner.ts +11 -1
- package/src/graph-wizard/archetypes.ts +88 -0
- package/src/graph-wizard/generate.ts +545 -0
- package/src/graph-wizard/saved-steps.ts +120 -0
- package/src/graph-wizard/steps.ts +193 -0
- package/src/harness/harness-cli-command.ts +482 -59
- package/src/harness/harness-queue.ts +315 -25
- package/src/harness/harness-salvage-cli.ts +62 -0
- package/src/hq/fence-outcomes.ts +63 -0
- package/src/hq/fence-wrapper.ts +33 -0
- package/src/hq/hq.ts +11 -1
- package/src/index.ts +76 -10
- package/src/intake-plane/digest.ts +18 -11
- package/src/maturity/feature-maturity.ts +4 -3
- package/src/nexus/api/draft-metrics.ts +114 -0
- package/src/nexus/api/graph-kinds.ts +10 -4
- package/src/nexus/api/graph-wizard-api.ts +53 -0
- package/src/nexus/api/graphs-api.ts +220 -10
- package/src/nexus/api/harness-traversal.ts +205 -0
- package/src/nexus/api/http-server.ts +69 -3
- package/src/nexus/api/loop-edges.ts +4 -2
- package/src/nexus/api/ops-api.ts +22 -7
- package/src/nexus/api/ops-board-route.ts +48 -0
- package/src/nexus/outbound/router.ts +28 -8
- package/src/onboarding/entry-hints.ts +5 -0
- package/src/onboarding/first-run.ts +3 -0
- package/src/onboarding.ts +24 -6
- package/src/ops/overview-collect.ts +345 -0
- package/src/ops/overview-seat-era.ts +90 -0
- package/src/ops/overview.ts +223 -0
- package/src/release-loop/feature-store.ts +14 -11
- package/src/release-loop/gate-shards.ts +163 -0
- package/src/release-loop/release-schedule.ts +6 -2
- package/src/retro/daily.ts +372 -0
- package/src/seat-loop/op-decide.ts +173 -0
- package/src/seat-loop/seat-loop.ts +60 -3
- package/src/seat-loop/seat-report.ts +58 -3
- package/src/self-dev/ask-launch-flow.ts +9 -6
- package/src/self-dev/ask-launch-io.ts +52 -2
- package/src/self-dev/ask-path-candidates.ts +40 -2
- package/src/self-dev/draft-sweep.ts +371 -16
- package/src/self-dev/draft-triage-rules.ts +19 -4
- package/src/self-dev/graph-journey-nodes.ts +157 -0
- package/src/self-dev/graph-journey-route.ts +105 -0
- package/src/self-dev/launch-preflight.ts +43 -3
- package/src/self-dev/pr-preview.ts +84 -16
- package/src/self-dev/release-path-guard.ts +7 -4
- package/src/self-implement/blocked-draft-policy.ts +101 -0
- package/src/self-implement/execution-clarification.ts +11 -0
- package/src/self-implement/frozen-merges.ts +23 -0
- package/src/self-implement/gate-env-retry.ts +83 -0
- package/src/self-implement/goal-author.ts +14 -0
- package/src/self-implement/heal-intake.ts +3 -0
- package/src/self-implement/orchestrator.ts +234 -6
- package/src/self-implement/run-stop.ts +123 -0
- package/src/self-implement/run-ttl.ts +258 -0
- package/src/self-implement/salvage-retention.ts +123 -0
- package/src/self-implement/seams.ts +7 -0
- package/src/self-implement/self-implement-cli.ts +2 -0
- package/src/self-implement/self-implement-runtime.ts +12 -0
- package/src/self-implement/sibling-resync.ts +223 -0
- package/src/self-implement/stop-autoheal.ts +204 -0
- package/src/session-runtime/index.ts +5 -3
- package/src/shell-env-bootstrap.ts +17 -3
- package/src/task-agent/board.ts +1 -1
- package/src/task-agent/card-evidence.ts +105 -10
- package/src/task-agent/judge.ts +7 -0
- package/src/task-agent/live-moves.ts +120 -20
- package/src/task-agent/mission.ts +1 -1
- package/src/task-agent/parent-host.ts +315 -0
- package/src/task-agent/shadow.ts +10 -1
- package/src/task-agent/task-hand.ts +16 -4
- package/src/task-orchestrator/surfaces/pod-command-job.ts +60 -11
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +4 -0
- package/src/task-orchestrator/surfaces/pod-gate-deps.ts +123 -0
- package/src/task-orchestrator/surfaces/pod-install-slots.ts +89 -0
- package/src/task-orchestrator/surfaces/pod-lease.ts +93 -10
- package/src/task-orchestrator/surfaces/pod-pool.ts +147 -34
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +58 -9
- package/src/telegram-commands.ts +41 -0
- package/src/testing/real-cli-spawn.ts +106 -0
- package/src/tool-runtime/browser-runtime.ts +87 -3
- package/src/tool-runtime/index.ts +1 -0
- package/src/user-config.ts +76 -7
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/J5H7BvqgSI8DUjtRRcA_S/_buildManifest.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1105-c473ed46272fba79.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1157-cba0e8553d35a980.js +0 -1
- package/apps/pwa/out/_next/static/chunks/171-23a877ed11720de9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/216-5acd01cbde4acda7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2330-c2f07246c8788af1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2336-e830c777eb6bce04.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2375-e061bb24cd2b5cde.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2415.ed6428ff334c7ce2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3094.67339318c7f72a3a.js +0 -2
- package/apps/pwa/out/_next/static/chunks/338-ceb956612dcfaa86.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3395-835e4ceaa6335ba4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3403.4bc97b4066945a94.js +0 -5
- package/apps/pwa/out/_next/static/chunks/3441-be82e3595aef3a20.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3689-89905039bf3e7257.js +0 -1
- package/apps/pwa/out/_next/static/chunks/371-4ad6af55dad02ced.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3822-6f268bc26c6a84ac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4114-3e63117452378807.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4457-d7df81c90f9d0268.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4551-77dadae76f6cbace.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4978.6fd93b974441e87f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5012-f746f6549b869f91.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5609-012bb3557211f07e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5791-bb82743fa6299562.js +0 -1
- package/apps/pwa/out/_next/static/chunks/62-5bfed1e23790b745.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6320-9bc8561fde416e07.js +0 -1
- package/apps/pwa/out/_next/static/chunks/649-ca96d1c5d09e02b8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6725-68ab7cc0b1faf00d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6726-85a7db59b288c53f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6735-33267c4630d0d963.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6998-a654fe5c58271600.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7633-141682015873beb6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7673-2eda1507d38dadb8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7990-e12efba616f46e03.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8067-143791231c99bd02.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8142-744998d65d7bb17e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8430-a10cfba8ef282d4e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8870-9614a213b990b10b.js +0 -25
- package/apps/pwa/out/_next/static/chunks/920-f7dceb78f1c585ef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9454-12c2f30dea62291c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/976-4a9b4ebdca7c739a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9989-15cdf568bafa9fc8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/ae787e4c-e5b1ef00b2dbceca.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-deef5ee191830f14.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-b193da485f9a14b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-b6e1a79df0e214f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/botlab/page-e84df4d907f703c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-a5fb9a5db89ae4ea.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-1499f481d7fc52d6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-c7cf753aeb648790.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-4118469e514e10fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-e968f7630654332a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-505915052f947022.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-c2f962fb4a3b06c6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-7b5ed0bd8a589ec4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-cf8193250dd42dd4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-cf3f5dfa35dea8e9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-5b29d9b06ceadade.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-a15e7fcc283e9ca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-d2915e7b70ff3d0e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-2595f0eba29f57e1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-c776322454156e36.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-77bbd17f4435aa10.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-049689e611ecc936.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-85954a4fb09c44eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-e773e552e1068ee6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-5633c4bfa7684b4a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-d829b92bd01b4994.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-061c317fc771becf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3a45ece8865ed4b6.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-0be990618c0d56bd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-bfea4865dc244b73.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-0d6ba8e337741484.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-76a88b55d816482e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-bba1542df59f61ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-4185c95689bb372e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-b699e1a8d5d34b8b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-859cea1570b6227a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-c225e338c31bf274.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-449353f70507ca1f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-90b889714102476d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f1ee7fbeb7f96ddc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-d59a95e1434dfaa0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-71491a23414d1a47.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-de7112bdb65fa4fe.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-feb4d0d88079660d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-f17d887b40dd6b1d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-8da77be2192bcd5d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-72c3b9a5e9582b29.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-c3afe4c8d0c48c39.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-ea806bb57f2b8923.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-8d2302399c2c8f87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-b9308f2d8a931531.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-b10928c60f0b8488.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-689039227d443fab.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-6f35f9d892fa630b.js +0 -1
- package/apps/pwa/out/_next/static/css/85f53c6f35d11382.css +0 -1
- /package/apps/pwa/out/_next/static/{J5H7BvqgSI8DUjtRRcA_S → MObU8ujkMciAKr6ljAV05}/_ssgManifest.js +0 -0
- /package/skills/project-onboarding/{skill.md → SKILL.md} +0 -0
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
import { randomUUID } from 'node:crypto';
|
|
2
|
+
import { debug } from '../debug/log.js';
|
|
3
|
+
import { GRAPH_SPECS, GRAPH_TEMPLATES, GRAPH_TEMPLATES_SOURCE, pipelineNodeEntryPayload, templateForGoalType, type GraphTemplate } from '../self-implement/graph-templates.js';
|
|
4
|
+
import type { GoalType } from '../self-implement/goal-author.js';
|
|
5
|
+
|
|
6
|
+
/** ⭐ HARNESS-FULL-GRAPH (0.2.21 · 대표 10-08) — 하니스 «여정» 전 단계를 그래프 노드로 선언·관측한다.
|
|
7
|
+
*
|
|
8
|
+
* 🩸 계기: `내부 문서 `TECH-harness-map-2026-10-06`` 차트의 단계 중 «입구·대기열·발사 관문·배치·Pod 입장·
|
|
9
|
+
* 이미지 동기화·자격 선갱신·동결 검사·보류·회수·실패 쪽(결과 해석·수확·heal·다음 한 수)»이
|
|
10
|
+
* 그래프 밖의 «맨 코드»였다. 공개 문서는 「그래프 선언이 모든 걸음을 대조한다」고 말한다 — 거짓이 되지 않게.
|
|
11
|
+
*
|
|
12
|
+
* ⛔ 이 모듈은 «관측»이다(1단계) — 흐름을 바꾸지 않는다. 진입은 기존 노드와 «같은 사건»
|
|
13
|
+
* (`self-implement` / `pipeline-node-entry` · 같은 `pipelineNodeEntryPayload`)으로 남겨
|
|
14
|
+
* 그래프 권위의 declared/undeclared 판정과 원장 질의가 이 노드들을 «같은 자»로 본다.
|
|
15
|
+
* 출구는 `pipeline-node-exit`(결과 `outcome` 포함)로 남긴다.
|
|
16
|
+
* ⛔ fail-soft — 관측이 발사·착지를 죽이지 않는다.
|
|
17
|
+
*
|
|
18
|
+
* 🔗 조인(런 id 가 없는 앞단): 입구에서 `ELANOUS_JOURNEY_KEY` 를 한 번 만들어 환경에 싣는다.
|
|
19
|
+
* 자식 프로세스는 그 값을 물려받고, 오케스트레이터의 모든 파이프라인 관측에도 `journeyKey` 가 실린다.
|
|
20
|
+
* ⇒ `journeyKey` 로 「runId 없이 남은 앞단 걸음」과 「runId 가 있는 후반 걸음」을 한 질의로 묶는다.
|
|
21
|
+
* 대기열을 거친 발사는 부모·자식 프로세스가 다르다 — 그 자리는 `queueLaunchId`(=`ELANOUS_HARNESS_QUEUE_LAUNCH`)가 잇는다.
|
|
22
|
+
* 설계 = 내부 문서 `RFC-harness-full-journey-as-graph-2026-10-08` §4. */
|
|
23
|
+
|
|
24
|
+
/** 여정 노드 — ⛔ id 는 원장의 조인 키이자 라이브 그래프 화면(HARNESS-RUN-LIVE-GRAPH)의 키다. 바꾸지 마라. */
|
|
25
|
+
export const JOURNEY_NODE_IDS = [
|
|
26
|
+
'intake',
|
|
27
|
+
'queue',
|
|
28
|
+
'launch-gate',
|
|
29
|
+
'dispatch',
|
|
30
|
+
'pool-admit',
|
|
31
|
+
'image-sync',
|
|
32
|
+
'credential-refresh',
|
|
33
|
+
'freeze-check',
|
|
34
|
+
'hold',
|
|
35
|
+
'cleanup',
|
|
36
|
+
'result-parse',
|
|
37
|
+
'salvage',
|
|
38
|
+
'heal',
|
|
39
|
+
'next-move',
|
|
40
|
+
'stopped',
|
|
41
|
+
] as const;
|
|
42
|
+
export type JourneyNodeId = typeof JOURNEY_NODE_IDS[number];
|
|
43
|
+
|
|
44
|
+
export const JOURNEY_KEY_ENV = 'ELANOUS_JOURNEY_KEY';
|
|
45
|
+
const QUEUE_LAUNCH_ENV = 'ELANOUS_HARNESS_QUEUE_LAUNCH';
|
|
46
|
+
const RUN_ID_ENV = 'ELANOUS_RUN_ID';
|
|
47
|
+
|
|
48
|
+
/** 이 여정의 조인 키 — 없으면 만들어 환경에 싣는다(자식이 물려받는다). */
|
|
49
|
+
export function ensureJourneyKey(env: NodeJS.ProcessEnv = process.env): string {
|
|
50
|
+
const existing = env[JOURNEY_KEY_ENV]?.trim();
|
|
51
|
+
if (existing) return existing;
|
|
52
|
+
const key = `jrn-${randomUUID()}`;
|
|
53
|
+
env[JOURNEY_KEY_ENV] = key;
|
|
54
|
+
return key;
|
|
55
|
+
}
|
|
56
|
+
|
|
57
|
+
/** 관측 자리마다 펼치는 조인 칸(있는 것만). */
|
|
58
|
+
export function journeyJoinFields(env: NodeJS.ProcessEnv = process.env): { journeyKey?: string; queueLaunchId?: string } {
|
|
59
|
+
const journeyKey = env[JOURNEY_KEY_ENV]?.trim();
|
|
60
|
+
const queueLaunchId = env[QUEUE_LAUNCH_ENV]?.trim();
|
|
61
|
+
return {
|
|
62
|
+
...(journeyKey ? { journeyKey } : {}),
|
|
63
|
+
...(queueLaunchId ? { queueLaunchId } : {}),
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
/** 여정 노드를 선언한 템플릿 — 골 종류의 템플릿이 그 노드를 선언하면 그것, 아니면 구현 루프. */
|
|
68
|
+
export function journeyTemplate(node: string, goalType?: GoalType | null): GraphTemplate {
|
|
69
|
+
const own = goalType ? templateForGoalType(goalType) : null;
|
|
70
|
+
if (own && own.nodes.some((n) => n.nodeId === node)) return own;
|
|
71
|
+
return GRAPH_TEMPLATES['self-implement'] as GraphTemplate;
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export interface JourneyObservation {
|
|
75
|
+
readonly provenance: string;
|
|
76
|
+
readonly outcome?: string;
|
|
77
|
+
readonly runId?: string;
|
|
78
|
+
readonly goalType?: GoalType | null;
|
|
79
|
+
readonly data?: Readonly<Record<string, unknown>>;
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
function emit(entry: boolean, node: JourneyNodeId, o: JourneyObservation): void {
|
|
83
|
+
try {
|
|
84
|
+
const template = journeyTemplate(node, o.goalType);
|
|
85
|
+
const runId = o.runId ?? process.env[RUN_ID_ENV]?.trim();
|
|
86
|
+
const fields = {
|
|
87
|
+
node,
|
|
88
|
+
round: 0,
|
|
89
|
+
phase: 'journey',
|
|
90
|
+
provenance: o.provenance,
|
|
91
|
+
...(o.outcome === undefined ? {} : { outcome: o.outcome }),
|
|
92
|
+
...(runId ? { runId } : {}),
|
|
93
|
+
...(o.goalType ? { goalType: o.goalType } : {}),
|
|
94
|
+
...journeyJoinFields(),
|
|
95
|
+
...o.data,
|
|
96
|
+
graphTemplatesSource: GRAPH_TEMPLATES_SOURCE,
|
|
97
|
+
};
|
|
98
|
+
// ⛔ 진입은 «공용 payload» 를 그 호출 안에서 펼친다 — 우회 가드(graph-templates.ts)가 행 단위로 문다.
|
|
99
|
+
if (entry) debug.log('self-implement', 'pipeline-node-entry', { ...pipelineNodeEntryPayload(template, node), ...fields });
|
|
100
|
+
else debug.log('self-implement', 'pipeline-node-exit', { ...pipelineNodeEntryPayload(template, node), ...fields });
|
|
101
|
+
} catch { /* 관측은 fail-soft */ }
|
|
102
|
+
}
|
|
103
|
+
|
|
104
|
+
/** 노드 진입. */
|
|
105
|
+
export function enterJourneyNode(node: JourneyNodeId, o: JourneyObservation): void {
|
|
106
|
+
emit(true, node, o);
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
/** 노드 출구 — `outcome` 이 그 노드에서 나간 간선의 라벨(YAML `map` 키)이다.
|
|
110
|
+
* ⭐ 그 라벨이 선언에서 종결 노드 `stopped` 로 가면 `stopped` 진입도 남긴다 — 거절·포기 런이 «선언된 종결점»에서 끝난다.
|
|
111
|
+
* `outcome: 'error'` = 노드 안 작업이 예외를 던졌다(예외는 호출자에게 그대로 간다). */
|
|
112
|
+
export function exitJourneyNode(node: JourneyNodeId, o: JourneyObservation & { readonly outcome: string }): void {
|
|
113
|
+
emit(false, node, o);
|
|
114
|
+
if (node !== 'stopped' && journeyEdgeTarget(node, o.outcome) === 'stopped') {
|
|
115
|
+
const { outcome: _outcome, ...rest } = o;
|
|
116
|
+
emit(true, 'stopped', { ...rest, provenance: `${node}:${o.outcome}` });
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
/** 선언(기준 YAML)에서 `from` 의 `label` 간선이 가는 노드. 없으면 undefined. */
|
|
121
|
+
export function journeyEdgeTarget(from: string, label: string): string | undefined {
|
|
122
|
+
try {
|
|
123
|
+
for (const edge of GRAPH_SPECS['self-implement']?.edges ?? []) {
|
|
124
|
+
if (edge.from === from && edge.map !== undefined && Object.hasOwn(edge.map, label)) return edge.map[label];
|
|
125
|
+
}
|
|
126
|
+
} catch { /* 관측 보조 — 실패해도 출구는 이미 남았다 */ }
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
|
|
130
|
+
/** 노드 안 작업을 감싼다 — 예외면 출구 `error` 를 남기고 다시 던진다(진입 뒤 출구가 빠지지 않게). */
|
|
131
|
+
export function withJourneyNode<T>(node: JourneyNodeId, o: JourneyObservation, work: () => Promise<T>): Promise<T> {
|
|
132
|
+
const onError = (error: unknown): void => {
|
|
133
|
+
exitJourneyNode(node, { ...o, outcome: 'error', data: { ...o.data, error: error instanceof Error ? error.message : String(error) } });
|
|
134
|
+
};
|
|
135
|
+
let pending: Promise<T>;
|
|
136
|
+
try { pending = work(); }
|
|
137
|
+
catch (error) { onError(error); throw error; }
|
|
138
|
+
// ⛔ 같은 약속을 «그대로» 돌려준다 — async/await 로 감싸면 마이크로태스크가 늘어 호출자의 순서가 밀린다
|
|
139
|
+
// (2판에서 self-implement-pod 시험이 그 차이를 잡았다). 관측은 곁가지(.then)로만 붙인다.
|
|
140
|
+
pending.then(undefined, onError);
|
|
141
|
+
return pending;
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/** 동기 판. */
|
|
145
|
+
export function withJourneyNodeSync<T>(node: JourneyNodeId, o: JourneyObservation, work: () => T): T {
|
|
146
|
+
try { return work(); }
|
|
147
|
+
catch (error) {
|
|
148
|
+
exitJourneyNode(node, { ...o, outcome: 'error', data: { ...o.data, error: error instanceof Error ? error.message : String(error) } });
|
|
149
|
+
throw error;
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
/** 진입·출구를 한 번에 — 판정만 하는 노드(대기 없는 관문)용. */
|
|
154
|
+
export function passJourneyNode(node: JourneyNodeId, o: JourneyObservation & { readonly outcome: string }): void {
|
|
155
|
+
enterJourneyNode(node, o);
|
|
156
|
+
exitJourneyNode(node, o);
|
|
157
|
+
}
|
|
@@ -0,0 +1,105 @@
|
|
|
1
|
+
import { debug } from '../debug/log.js';
|
|
2
|
+
import { GRAPH_SPECS } from '../self-implement/graph-templates.js';
|
|
3
|
+
import { applyGraphOverlays, defaultOverlaysDir, loadGraphOverlays, selectOverlays, type GraphOverlaySpec } from '../self-implement/graph-overlay-yaml.js';
|
|
4
|
+
import type { GraphTemplateSpec } from '../self-implement/graph-yaml.js';
|
|
5
|
+
import { journeyJoinFields } from './graph-journey-nodes.js';
|
|
6
|
+
|
|
7
|
+
/** ⭐ HARNESS-FULL-GRAPH 2판 — 「다음 노드」를 코드가 아니라 «그래프»가 정한다.
|
|
8
|
+
*
|
|
9
|
+
* 대표 10-08: *«그래프에 따라 실제 경로가 바뀌어야 한다. 기본은 풀세트, 환경 셋업·운영 방법에 따라 일부만 걷거나 생략.»*
|
|
10
|
+
* ⇒ 코드는 «상태 값»(queue=queued|direct · substrate=local|pod · freeze=open|frozen …)만 낸다.
|
|
11
|
+
* 그 값으로 «어느 간선을 타나»는 YAML 의 `on:`/`map:`(⊕ `stage: launch` 오버레이)이 정한다.
|
|
12
|
+
* ⛔ 기본 YAML 은 오늘 코드와 «같은 길»을 낸다 — 시험이 그 동치를 문다(graph-journey-route.test.ts).
|
|
13
|
+
* ⛔ 그래프가 답을 못 내면(간선 없음·로드 실패) 코드 기본으로 간다 — 그 사실을 `source: 'code-default'` 로 남긴다.
|
|
14
|
+
* 🔎 관측: `self-implement` / `graph-edge-taken` { from, on, label, to, source, overlays } */
|
|
15
|
+
|
|
16
|
+
export interface JourneyRoute {
|
|
17
|
+
readonly from: string;
|
|
18
|
+
readonly on: string | null;
|
|
19
|
+
readonly label: string;
|
|
20
|
+
/** 그래프가 고른 다음 노드. 못 고르면 null. */
|
|
21
|
+
readonly to: string | null;
|
|
22
|
+
readonly source: 'graph' | 'code-default';
|
|
23
|
+
readonly overlays: readonly string[];
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/** ⛔ 캐시하지 않는다 — 여러 런을 처리하는 프로세스(데몬·대기열 tick)가 다음 발사에서 오버레이 변경을 봐야 한다.
|
|
27
|
+
* 여정 판정은 발사당 몇 번뿐이라 디렉터리 한 번 읽기가 싸다. */
|
|
28
|
+
let overlaysForTesting: readonly GraphOverlaySpec[] | undefined;
|
|
29
|
+
function launchOverlays(): readonly GraphOverlaySpec[] {
|
|
30
|
+
if (overlaysForTesting !== undefined) return overlaysForTesting;
|
|
31
|
+
try { return loadGraphOverlays(defaultOverlaysDir()).overlays; }
|
|
32
|
+
catch { return []; }
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** 시험 전용 — 오버레이 묶음을 고정한다(undefined 면 디스크에서 읽는다). */
|
|
36
|
+
export function setJourneyOverlaysForTesting(overlays: readonly GraphOverlaySpec[] | undefined): void {
|
|
37
|
+
overlaysForTesting = overlays;
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
/** 상태 값으로 고른 «이 런의 여정 선언» — 기준 YAML ⊕ 조건이 맞는 launch 오버레이. */
|
|
41
|
+
export function journeySpec(
|
|
42
|
+
state: Readonly<Record<string, unknown>>,
|
|
43
|
+
base: GraphTemplateSpec | undefined = GRAPH_SPECS['self-implement'],
|
|
44
|
+
overlays: readonly GraphOverlaySpec[] = launchOverlays(),
|
|
45
|
+
): { readonly spec: GraphTemplateSpec | undefined; readonly applied: readonly string[] } {
|
|
46
|
+
if (base === undefined) return { spec: undefined, applied: [] };
|
|
47
|
+
try {
|
|
48
|
+
const { applied } = selectOverlays(overlays, { graphId: base.graphId, stage: 'launch', state });
|
|
49
|
+
if (applied.length === 0) return { spec: base, applied: [] };
|
|
50
|
+
const result = applyGraphOverlays(base, applied);
|
|
51
|
+
// ⛔ 거절된 오버레이는 길을 바꾸지 않는다 — 기준 선언으로 간다.
|
|
52
|
+
return result.ok ? { spec: result.template, applied: result.overlayIds } : { spec: base, applied: [] };
|
|
53
|
+
} catch {
|
|
54
|
+
return { spec: base, applied: [] };
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
|
|
58
|
+
/** `from` 노드에서 `label` 로 나가는 다음 노드를 그래프에서 «읽는다»(기록하지 않는다).
|
|
59
|
+
* ⛔ 판독과 기록을 가른다 — 실제로 탄 간선은 전제 검사·실제 단계 경계 «뒤»에 `recordJourneyEdge` 로 남긴다. */
|
|
60
|
+
export function readJourneyEdge(
|
|
61
|
+
from: string,
|
|
62
|
+
label: string,
|
|
63
|
+
state: Readonly<Record<string, unknown>> = {},
|
|
64
|
+
deps: { readonly base?: GraphTemplateSpec; readonly overlays?: readonly GraphOverlaySpec[] } = {},
|
|
65
|
+
): JourneyRoute {
|
|
66
|
+
const { spec, applied } = journeySpec(state, deps.base ?? GRAPH_SPECS['self-implement'], deps.overlays ?? launchOverlays());
|
|
67
|
+
let route: JourneyRoute = { from, on: null, label, to: null, source: 'code-default', overlays: applied };
|
|
68
|
+
for (const edge of spec?.edges ?? []) {
|
|
69
|
+
if (edge.from !== from) continue;
|
|
70
|
+
if (edge.map !== undefined && Object.hasOwn(edge.map, label)) {
|
|
71
|
+
route = { from, on: edge.on ?? null, label, to: edge.map[label]!, source: 'graph', overlays: applied };
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
return route;
|
|
76
|
+
}
|
|
77
|
+
|
|
78
|
+
/** 실제로 탄 간선을 남긴다 — `taken` 은 실제 다음 노드(그래프 답과 다르면 `honored: false` · 그 이유를 `reason` 에). */
|
|
79
|
+
export function recordJourneyEdge(route: JourneyRoute, taken: string, reason?: string): void {
|
|
80
|
+
try {
|
|
81
|
+
debug.log('self-implement', 'graph-edge-taken', {
|
|
82
|
+
graphId: 'self-implement', ...route, taken, honored: route.to === null || route.to === taken,
|
|
83
|
+
...(reason === undefined ? {} : { reason }), ...journeyJoinFields(),
|
|
84
|
+
});
|
|
85
|
+
} catch { /* 관측은 fail-soft */ }
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/** 판독 ⊕ 그 자리에서 기록 — 판독 자리가 곧 실제 단계 경계일 때만 쓴다. */
|
|
89
|
+
export function routeJourneyEdge(
|
|
90
|
+
from: string,
|
|
91
|
+
label: string,
|
|
92
|
+
state: Readonly<Record<string, unknown>> = {},
|
|
93
|
+
deps: { readonly base?: GraphTemplateSpec; readonly overlays?: readonly GraphOverlaySpec[] } = {},
|
|
94
|
+
): JourneyRoute {
|
|
95
|
+
const route = readJourneyEdge(from, label, state, deps);
|
|
96
|
+
recordJourneyEdge(route, route.to ?? label);
|
|
97
|
+
return route;
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
/** 입구의 대기열 갈래 — 그래프가 고른 다음 노드로 정한다. 그래프가 답을 못 내면 코드 라벨을 따른다.
|
|
101
|
+
* ⛔ `eligible`(자리 있음 · 대기열 자식 아님 · --no-queue 아님)은 그래프가 못 넘는 전제다. */
|
|
102
|
+
export function intakeTakesQueue(label: 'queued' | 'direct', route: Pick<JourneyRoute, 'source' | 'to'>, eligible: boolean): boolean {
|
|
103
|
+
const graphQueues = route.source === 'graph' ? route.to === 'queue' : label === 'queued';
|
|
104
|
+
return graphQueues && eligible;
|
|
105
|
+
}
|
|
@@ -538,6 +538,9 @@ export interface LaunchPreflightInput {
|
|
|
538
538
|
readonly askTargetPaths?: readonly string[];
|
|
539
539
|
/** 대상 경로 라벨이 «있는데» 거부된 조각. 0건 막음 문면이 그 이유를 말하게 한다(판정은 안 바꾼다). */
|
|
540
540
|
readonly askTargetPathRejections?: readonly AskTargetPathHintRejection[];
|
|
541
|
+
/** AUTO-TARGET: machine-suggested target paths dropped because the goal is NOT-GROUNDED (no persistent evidence).
|
|
542
|
+
* Non-empty = the goal is a scope card and must not launch an implementation. */
|
|
543
|
+
readonly notGroundedDroppedTargetPaths?: readonly string[];
|
|
541
544
|
/** ask 원문 경로. 있으면 ask-outside-path 경고만 이 목록과 최종 대상을 비교한다. */
|
|
542
545
|
readonly askOutsidePathHints?: readonly string[];
|
|
543
546
|
/** 이번에 쏠 골의 브랜치 이름. 없으면 형제 PR 축의 경고를 내지 않는다. */
|
|
@@ -559,19 +562,31 @@ function emitAskMarkerObservation(result: LaunchPreflightResult): void {
|
|
|
559
562
|
emittedAskMarkerObservations.add(result);
|
|
560
563
|
}
|
|
561
564
|
|
|
565
|
+
/** AUTO-TARGET: blocker name for a NOT-GROUNDED goal whose only target paths were machine-suggested (a scope card). */
|
|
566
|
+
export const NOT_GROUNDED_SCOPE_CARD_BLOCKER = '(NOT-GROUNDED 범위 카드)';
|
|
567
|
+
|
|
562
568
|
export function evaluateLaunchPreflight(input: LaunchPreflightInput): LaunchPreflightResult {
|
|
563
569
|
const paths = [...new Set(input.paths.filter((path) => path.trim().length > 0))];
|
|
564
570
|
const blockers: LaunchPreflightBlocker[] = [];
|
|
565
571
|
const warnings: LaunchPreflightBlocker[] = [];
|
|
566
572
|
|
|
573
|
+
// AUTO-TARGET (10-08 canary · TSC-HEAP): a NOT-GROUNDED goal whose only target paths came from the
|
|
574
|
+
// harness candidate search is a scope card — refuse it with that reason, not the generic «no label» text.
|
|
575
|
+
const notGroundedDropped = input.notGroundedDroppedTargetPaths ?? [];
|
|
576
|
+
const notGroundedDetail = notGroundedDropped.length > 0
|
|
577
|
+
? `골이 NOT-GROUNDED(영속 근거 0)라 하니스 후보 검색이 넣은 대상 경로 ${notGroundedDropped.length}개(${notGroundedDropped.slice(0, 3).join(' · ')}${notGroundedDropped.length > 3 ? ' …' : ''})를 대상으로 쓰지 않는다 — 범위 카드: 구현 발사 대상이 아니다 · ask 첫 줄에 사람이 「대상 경로: <파일>」을 적거나 접지 근거를 복구한 뒤 다시 저작`
|
|
578
|
+
: undefined;
|
|
579
|
+
if (notGroundedDetail !== undefined && paths.length > 0) {
|
|
580
|
+
blockers.push({ kind: 'no-target-paths', name: NOT_GROUNDED_SCOPE_CARD_BLOCKER, detail: notGroundedDetail });
|
|
581
|
+
}
|
|
567
582
|
// ① 모집단이 0이면 «통과»가 아니라 «막는 사유»다(METHOD v32 를 이 코드에도 적용).
|
|
568
583
|
if (paths.length === 0) {
|
|
569
584
|
blockers.push({
|
|
570
585
|
kind: 'no-target-paths',
|
|
571
|
-
name: '(대상 경로 0)',
|
|
586
|
+
name: notGroundedDetail !== undefined ? NOT_GROUNDED_SCOPE_CARD_BLOCKER : '(대상 경로 0)',
|
|
572
587
|
// ⛔ 2026-09-23 — 라벨이 «있는데» 조각이 거부된 경우를 「라벨을 넣어라」로 뭉개면 「거부됐다」를 「없다」로 읽게 된다
|
|
573
588
|
// (실측: `대상 경로: README.md — 설명…` 한 줄 → has-whitespace 로 통째 거부 · 문면은 「넣어라」뿐이었다).
|
|
574
|
-
detail: (input.askTargetPathRejections?.length
|
|
589
|
+
detail: notGroundedDetail !== undefined ? notGroundedDetail : (input.askTargetPathRejections?.length
|
|
575
590
|
? `대상 경로 라벨은 있는데 조각 ${input.askTargetPathRejections.length}개가 거부됐다: ${input.askTargetPathRejections.slice(0, 3).map((r) => `「${r.fragment.length > 40 ? `${r.fragment.slice(0, 40)}…` : r.fragment}」(${r.reason})`).join(' · ')} — 그 줄에는 «경로만» 둔다(설명은 다음 줄)`
|
|
576
591
|
: '골에서 대상 경로를 하나도 못 뽑았다 — ask 첫 줄에 「대상 경로: <파일> · <파일>」을 넣어라')
|
|
577
592
|
+ ' — 이 상태의 「위반 0」은 「검사했다」가 아니다 — elanous self author --inspect-target-paths "<문면>"',
|
|
@@ -1192,6 +1207,9 @@ export interface AskPreflightDeps {
|
|
|
1192
1207
|
readonly askTargetPaths?: (document: string) => readonly string[];
|
|
1193
1208
|
/** 대상 경로 라벨 «안»에서 거부된 조각(이유 포함). 0건 막음 문면이 「라벨이 없다」와 「있는데 거부됐다」를 가르게 한다. */
|
|
1194
1209
|
readonly askTargetPathRejections?: (document: string) => readonly AskTargetPathHintRejection[];
|
|
1210
|
+
/** AUTO-TARGET: true when the authored goal is NOT-GROUNDED with no persistent evidence (a scope card).
|
|
1211
|
+
* Omitted = this distinction is not made (existing behavior). Production wires `isNotGroundedWithoutPersistentEvidence`. */
|
|
1212
|
+
readonly notGroundedWithoutPersistentEvidence?: (document: string) => boolean;
|
|
1195
1213
|
}
|
|
1196
1214
|
|
|
1197
1215
|
export interface AskPreflightOptions {
|
|
@@ -1212,6 +1230,10 @@ export interface AskPreflightOptions {
|
|
|
1212
1230
|
readonly plannedBranch?: string;
|
|
1213
1231
|
/** 저작 전 ask 원문. 주면 기존 ask-marker-check로 형식을 관측하되 발사를 막지 않는다. */
|
|
1214
1232
|
readonly askText?: string;
|
|
1233
|
+
/** AUTO-TARGET: target paths the harness put into the ask (candidate search), not the human.
|
|
1234
|
+
* If the authored goal is NOT-GROUNDED without persistent evidence, these paths are dropped and the
|
|
1235
|
+
* goal stops before launch (`no-target-paths` blocker naming the reason). */
|
|
1236
|
+
readonly machineSuggestedTargetPaths?: readonly string[];
|
|
1215
1237
|
}
|
|
1216
1238
|
|
|
1217
1239
|
export type PlannedBranchResolution =
|
|
@@ -1539,7 +1561,24 @@ export function decideAskPreflight(
|
|
|
1539
1561
|
}
|
|
1540
1562
|
}
|
|
1541
1563
|
// ⛔ 저작 전에는 pathsOverride 자체가 ask 대상 힌트다. 저작 뒤에는 골에서 뽑은 대상만 역할로 쓴다.
|
|
1542
|
-
const
|
|
1564
|
+
const declaredAskTargetPaths = opts.pathsOverride ?? (goalDocument && deps.askTargetPaths ? deps.askTargetPaths(goalDocument) : []);
|
|
1565
|
+
// AUTO-TARGET: a NOT-GROUNDED goal (no persistent evidence) carries no machine-suggested target path.
|
|
1566
|
+
const machineSuggested = new Set((opts.machineSuggestedTargetPaths ?? []).map((path) => path.trim()).filter(Boolean));
|
|
1567
|
+
let notGroundedGoal = false;
|
|
1568
|
+
if (!opts.pathsOverride && goalDocument !== null && machineSuggested.size > 0 && deps.notGroundedWithoutPersistentEvidence) {
|
|
1569
|
+
try { notGroundedGoal = deps.notGroundedWithoutPersistentEvidence(goalDocument); } catch { notGroundedGoal = false; }
|
|
1570
|
+
}
|
|
1571
|
+
const notGroundedDroppedTargetPaths = notGroundedGoal ? declaredAskTargetPaths.filter((path) => machineSuggested.has(path)) : [];
|
|
1572
|
+
const askTargetPaths = notGroundedDroppedTargetPaths.length > 0
|
|
1573
|
+
? declaredAskTargetPaths.filter((path) => !machineSuggested.has(path))
|
|
1574
|
+
: declaredAskTargetPaths;
|
|
1575
|
+
if (notGroundedDroppedTargetPaths.length > 0) {
|
|
1576
|
+
try {
|
|
1577
|
+
debug.log('harness.preflight', 'not-grounded-target-paths-dropped', { goalFile: opts.goalFile, dropped: notGroundedDroppedTargetPaths });
|
|
1578
|
+
} catch {
|
|
1579
|
+
// Observation never changes the launch decision.
|
|
1580
|
+
}
|
|
1581
|
+
}
|
|
1543
1582
|
// 저작 뒤에는 접지가 읽은 경로와 선언 대상 경로를 함께 검사한다. 저작 전 pathsOverride는 그대로 쓴다.
|
|
1544
1583
|
const paths = opts.pathsOverride ?? [...new Set([...tracedPaths, ...askTargetPaths])];
|
|
1545
1584
|
const askMarkerInspection = opts.askText === undefined
|
|
@@ -1677,6 +1716,7 @@ export function decideAskPreflight(
|
|
|
1677
1716
|
...(goalRulersUnknownReason ? { goalRulersUnknownReason } : {}),
|
|
1678
1717
|
preexistingFailures,
|
|
1679
1718
|
...(askTargetPaths.length > 0 ? { askTargetPaths } : {}),
|
|
1719
|
+
...(notGroundedDroppedTargetPaths.length > 0 ? { notGroundedDroppedTargetPaths } : {}),
|
|
1680
1720
|
...(askTargetPaths.length === 0 && goalDocument && deps.askTargetPathRejections
|
|
1681
1721
|
? { askTargetPathRejections: deps.askTargetPathRejections(goalDocument) }
|
|
1682
1722
|
: {}),
|
|
@@ -8,6 +8,8 @@ export interface PreviewOptions {
|
|
|
8
8
|
scenario?: string;
|
|
9
9
|
/** Main-based combined preview: only existing config paths may be enabled. */
|
|
10
10
|
flags?: readonly string[];
|
|
11
|
+
/** PR heads to preview together on main when no feature flags exist. */
|
|
12
|
+
bundlePrs?: readonly number[];
|
|
11
13
|
commentPr?: number;
|
|
12
14
|
}
|
|
13
15
|
export interface PreviewResult {
|
|
@@ -35,14 +37,50 @@ export interface PreviewDeps {
|
|
|
35
37
|
probePwa?: (url: string) => Promise<boolean>;
|
|
36
38
|
}
|
|
37
39
|
|
|
38
|
-
const SCENARIOS: Record<string, string> = {
|
|
39
|
-
|
|
40
|
+
const SCENARIOS: Record<string, { input: string; expected: string; matches: (snapshot: string) => boolean }> = {
|
|
41
|
+
// GOODHART (#24844 review): a group head (`▸ 시작`) or the echoed `/help` is not the list. The /help modal
|
|
42
|
+
// (help-from-registry.ts) prints one `/name description` row per command; the «시작» group alone has six.
|
|
43
|
+
// Pass only when at least three other start-group commands are listed as rows.
|
|
44
|
+
S2: { input: '/help', expected: 'help command list (/status, /model, /clear ... rows)', matches: (s) =>
|
|
45
|
+
['status', 'model', 'clear', 'new', 'resume'].filter((name) => new RegExp(`(?:^|\\s)/${name}(?: \\([^)]*\\))?\\s{2,}\\S`, 'mu').test(s)).length >= 3 },
|
|
46
|
+
S3: { input: '/status', expected: 'model and connection', matches: (s) => /모델|model/iu.test(s) && /연결|connection/iu.test(s) },
|
|
47
|
+
S6: { input: '/now', expected: 'current runs or schedules', matches: (s) => /지금|도는 런|스케줄|running|schedule/iu.test(s) },
|
|
48
|
+
S7: { input: '/term list', expected: 'terminal/PTY list', matches: (s) => /terminal|pty|터미널/iu.test(s) },
|
|
49
|
+
S8: { input: '/model', expected: 'model choices', matches: (s) => /빠름|보통|깊음|terra|sol|luna|선택/iu.test(s) },
|
|
50
|
+
S9: { input: '/harness', expected: 'harness usage or stages', matches: (s) => /usage:.*harness|저작|구현|리뷰|착지/iu.test(s) },
|
|
40
51
|
};
|
|
41
52
|
|
|
53
|
+
/**
|
|
54
|
+
* Lines of `after` that were not already on `before`'s screen (multiset by line, trailing spaces ignored).
|
|
55
|
+
* A prefix check is not enough: the PTY re-renders and scrolls, so the previous scenario's answer can
|
|
56
|
+
* reappear anywhere on the next screen (#24844 review). A repeated line is conservatively treated as old.
|
|
57
|
+
*/
|
|
58
|
+
export function previewFreshLines(before: string, after: string): string {
|
|
59
|
+
const seen = new Map<string, number>();
|
|
60
|
+
for (const line of before.split('\n')) {
|
|
61
|
+
const key = line.trimEnd();
|
|
62
|
+
if (key) seen.set(key, (seen.get(key) ?? 0) + 1);
|
|
63
|
+
}
|
|
64
|
+
return after.split('\n').filter((line) => {
|
|
65
|
+
const key = line.trimEnd();
|
|
66
|
+
if (!key) return false;
|
|
67
|
+
const left = seen.get(key) ?? 0;
|
|
68
|
+
if (left > 0) { seen.set(key, left - 1); return false; }
|
|
69
|
+
return true;
|
|
70
|
+
}).join('\n');
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
/** Whether a fresh screen region shows the scenario's expected answer (exported for the preview tests). */
|
|
74
|
+
export function previewScenarioMatches(scenario: string, fresh: string): boolean {
|
|
75
|
+
const entry = Object.hasOwn(SCENARIOS, scenario) ? SCENARIOS[scenario] : undefined;
|
|
76
|
+
if (!entry) throw new Error(`TUI-COMFORT §4: unsupported scenario ${scenario}`);
|
|
77
|
+
return entry.matches(fresh);
|
|
78
|
+
}
|
|
79
|
+
|
|
42
80
|
export function previewScenarioInput(scenario: string): string {
|
|
43
81
|
const text = Object.hasOwn(SCENARIOS, scenario) ? SCENARIOS[scenario] : undefined;
|
|
44
82
|
if (!text) throw new Error(`TUI-COMFORT §4: unsupported scenario ${scenario}; available: ${Object.keys(SCENARIOS).join(', ')}`);
|
|
45
|
-
return text;
|
|
83
|
+
return text.input;
|
|
46
84
|
}
|
|
47
85
|
|
|
48
86
|
const defaultRun: NonNullable<PreviewDeps['run']> = (command, args, cwd, timeoutMs = 120_000) => {
|
|
@@ -60,13 +98,18 @@ export async function runPrPreview(options: PreviewOptions, deps: PreviewDeps =
|
|
|
60
98
|
if (isPr && !Number.isSafeInteger(Number(target))) throw new Error('preview: invalid PR number');
|
|
61
99
|
if (/^\d+$/u.test(target) && !isPr) throw new Error('preview: invalid PR number');
|
|
62
100
|
if (options.commentPr !== undefined && (!Number.isSafeInteger(options.commentPr) || options.commentPr <= 0)) throw new Error('preview: invalid --comment-pr');
|
|
101
|
+
const bundlePrs = options.bundlePrs ?? [];
|
|
102
|
+
if (bundlePrs.length && (target !== 'main' || (options.flags?.length ?? 0) > 0)) throw new Error('preview: --bundle-pr requires main without feature flags');
|
|
103
|
+
if (bundlePrs.length && (new Set(bundlePrs).size !== bundlePrs.length || bundlePrs.some((pr) => !Number.isSafeInteger(pr) || pr <= 0))) throw new Error('preview: invalid or duplicate --bundle-pr');
|
|
63
104
|
if (target === 'main' && options.commentPr === undefined) throw new Error('preview: main ⊕ flags requires --comment-pr <PR number> to publish the result');
|
|
64
105
|
if (isPr && options.commentPr !== undefined && options.commentPr !== Number(target)) throw new Error('preview: --comment-pr must match the target PR');
|
|
65
106
|
const flags = options.flags ?? [];
|
|
66
107
|
if (flags.length && target !== 'main') throw new Error('preview: --flag requires main (main ⊕ feature flags)');
|
|
67
108
|
if (flags.some((flag) => !/^[a-zA-Z][\w-]*(?:\.[a-zA-Z][\w-]*)+$/u.test(flag))) throw new Error('preview: --flag expects an existing dotted config path');
|
|
68
|
-
const
|
|
69
|
-
|
|
109
|
+
const scenarios = (options.scenario ?? 'S2').split(',').map((id) => id.trim());
|
|
110
|
+
if (scenarios.length === 0 || new Set(scenarios).size !== scenarios.length) throw new Error('preview: duplicate or empty scenario');
|
|
111
|
+
for (const id of scenarios) previewScenarioInput(id);
|
|
112
|
+
const scenario = scenarios.join(',');
|
|
70
113
|
const check = (command: string, args: readonly string[], cwd: string, timeout?: number): string => {
|
|
71
114
|
const r = run(command, args, cwd, timeout);
|
|
72
115
|
if (r.status !== 0) throw new Error(`preview: ${command} ${args.join(' ')} failed: ${(r.stdout + '\n' + r.stderr).slice(-600)}`);
|
|
@@ -99,6 +142,16 @@ export async function runPrPreview(options: PreviewOptions, deps: PreviewDeps =
|
|
|
99
142
|
const pr = JSON.parse(check('gh', ['pr', 'view', String(prNumber), '--json', 'headRefOid,headRefName'], root)) as { headRefOid?: string; headRefName?: string };
|
|
100
143
|
if (pr.headRefName !== target || pr.headRefOid !== head || (branchPrHead !== undefined && branchPrHead !== head)) throw new Error('preview: branch does not match the target PR head; use the PR number');
|
|
101
144
|
}
|
|
145
|
+
const bundleHeads = bundlePrs.map((number) => {
|
|
146
|
+
const pr = JSON.parse(check('gh', ['pr', 'view', String(number), '--json', 'number,headRefOid'], root)) as { number?: number; headRefOid?: string };
|
|
147
|
+
if (pr.number !== number || !/^[0-9a-f]{40}$/iu.test(pr.headRefOid ?? '')) throw new Error(`preview: PR #${number} head is unavailable`);
|
|
148
|
+
const oid = pr.headRefOid!;
|
|
149
|
+
if (run('git', ['cat-file', '-e', `${oid}^{commit}`], root).status !== 0) {
|
|
150
|
+
check('git', ['fetch', '--no-tags', 'origin', `pull/${number}/head`], root, 120_000);
|
|
151
|
+
if (check('git', ['rev-parse', '--verify', 'FETCH_HEAD^{commit}'], root) !== oid) throw new Error(`preview: PR #${number} head changed while fetching; retry`);
|
|
152
|
+
}
|
|
153
|
+
return { number, oid };
|
|
154
|
+
});
|
|
102
155
|
const directory = (deps.makeDir ?? (() => {
|
|
103
156
|
const previews = join(root, '.elanous-test', 'previews');
|
|
104
157
|
mkdirSync(previews, { recursive: true });
|
|
@@ -112,6 +165,11 @@ export async function runPrPreview(options: PreviewOptions, deps: PreviewDeps =
|
|
|
112
165
|
try {
|
|
113
166
|
check('git', ['worktree', 'add', '--detach', worktree, head], root);
|
|
114
167
|
added = true;
|
|
168
|
+
for (const { number, oid } of bundleHeads) {
|
|
169
|
+
const current = JSON.parse(check('gh', ['pr', 'view', String(number), '--json', 'number,headRefOid'], root)) as { number?: number; headRefOid?: string };
|
|
170
|
+
if (current.number !== number || current.headRefOid !== oid) throw new Error(`preview: PR #${number} head changed while preparing bundle; retry`);
|
|
171
|
+
check('git', ['-c', 'user.name=elanous-preview', '-c', 'user.email=preview@localhost', 'merge', '--no-ff', '--no-edit', oid], worktree, 120_000);
|
|
172
|
+
}
|
|
115
173
|
check('bun', ['install', '--frozen-lockfile'], worktree, 300_000);
|
|
116
174
|
check('bun', ['install', '--frozen-lockfile'], join(worktree, 'apps/pwa'), 300_000);
|
|
117
175
|
for (const flag of flags) {
|
|
@@ -145,17 +203,27 @@ export async function runPrPreview(options: PreviewOptions, deps: PreviewDeps =
|
|
|
145
203
|
if (pty.held !== true || !/^pty_[\w-]+$/u.test(pty.ptyId ?? '')) throw new Error('preview: B-1 held TUI did not return a PTY reference');
|
|
146
204
|
heldPty = pty.ptyId;
|
|
147
205
|
const snapshotArgs = ['bin/elanous.mjs', '--test', 'pty', 'snapshot', pty.ptyId!] as const;
|
|
148
|
-
const
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
206
|
+
const rows: string[] = [];
|
|
207
|
+
const snapshots: string[] = [];
|
|
208
|
+
for (const id of scenarios) {
|
|
209
|
+
const { input, expected, matches } = SCENARIOS[id]!;
|
|
210
|
+
const before = check('bun', snapshotArgs, worktree);
|
|
211
|
+
check('bun', ['bin/elanous.mjs', '--test', 'pty', 'text', pty.ptyId!, input, '--enter'], worktree);
|
|
212
|
+
// A constant sleep misses slow frames under load — poll until this scenario's expected response (≤ 20s).
|
|
213
|
+
let snapshot = '';
|
|
214
|
+
let matched = false;
|
|
215
|
+
for (let attempt = 0; attempt < 20; attempt++) {
|
|
216
|
+
await wait(1000);
|
|
217
|
+
snapshot = check('bun', snapshotArgs, worktree);
|
|
218
|
+
const fresh = previewFreshLines(before, snapshot);
|
|
219
|
+
matched = snapshot !== 'ok' && snapshot !== before && matches(fresh);
|
|
220
|
+
if (matched) break;
|
|
221
|
+
}
|
|
222
|
+
const observed = snapshot && snapshot !== 'ok' && snapshot !== before;
|
|
223
|
+
rows.push(`| TUI-COMFORT §4 ${id} | \`${input}\` → ${matched ? `expected ${expected} matched` : `friction: expected ${expected} not found${observed ? '' : ' (no response within 20s)'}`} |`);
|
|
224
|
+
snapshots.push(`<details><summary>Inner PTY snapshot ${id}</summary>\n\n\`\`\`text\n${snapshot.slice(-3000).replaceAll('```', "'''")}\n\`\`\`\n</details>`);
|
|
156
225
|
}
|
|
157
|
-
|
|
158
|
-
report = `| Check | Observation |\n|---|---|\n| head | \`${head}\` |\n| B-1 version | ${version.slice(0, 120)} |\n| P-1 PWA | \`${endpoint}/app/\` served the built PWA |\n| TUI-COMFORT §4 ${scenario} | \`${input}\` → snapshot captured |\n\n<details><summary>Inner PTY snapshot</summary>\n\n\`\`\`text\n${snapshot.slice(-3000).replaceAll('```', "'''")}\n\`\`\`\n</details>`;
|
|
226
|
+
report = `| Check | Observation |\n|---|---|\n| head | \`${head}\` |${bundleHeads.length ? `\n| bundled PR heads | ${bundleHeads.map(({ number, oid }) => `#${number} \`${oid}\``).join(' ⊕ ')} |` : ''}\n| B-1 version | ${version.slice(0, 120)} |\n| P-1 PWA | \`${endpoint}/app/\` served the built PWA |\n${rows.join('\n')}\n\n${snapshots.join('\n\n')}`;
|
|
159
227
|
} catch (error) {
|
|
160
228
|
report = `| Check | Friction |\n|---|---|\n| head | \`${head}\` |\n| TUI-COMFORT §4 ${scenario} | ${String(error).replaceAll('|', '\\|').slice(0, 700)} |`;
|
|
161
229
|
} finally {
|
|
@@ -167,7 +235,7 @@ export async function runPrPreview(options: PreviewOptions, deps: PreviewDeps =
|
|
|
167
235
|
}
|
|
168
236
|
(deps.dispose ?? ((dir) => rmSync(dir, { recursive: true, force: true })))(directory);
|
|
169
237
|
}
|
|
170
|
-
const status = report.includes('| Friction |') ? 'friction' : 'passed';
|
|
238
|
+
const status = report.includes('| Friction |') || report.includes('→ friction:') ? 'friction' : 'passed';
|
|
171
239
|
const body = `## PR preview — ${target} (${status})\n\n${report}`;
|
|
172
240
|
if (prNumber === undefined) throw new Error('preview: cannot comment without a PR number');
|
|
173
241
|
check('gh', ['pr', 'comment', String(prNumber), '--body', body], root);
|
|
@@ -1,6 +1,9 @@
|
|
|
1
|
-
// Release path =
|
|
2
|
-
//
|
|
3
|
-
|
|
1
|
+
// Release path = release scripts and graph, manifest, notes and cut schedule, plus gate execution modules
|
|
2
|
+
// imported by scripts/release-loop/gate-node.ts (pod-command-job → pod-pool → pod-lease; pod-bun-cache; pod-install-slots; gate-shards).
|
|
3
|
+
// The checklist store (`checklist.ts`, `feature-store.ts`) remains shared ops ledger code (OP 10-03).
|
|
4
|
+
export const RELEASE_PATH_PREFIXES = ['scripts/release-loop/', 'graphs/release/', 'src/release-loop/manifest', 'src/release-loop/release-note', 'src/release-loop/release-schedule',
|
|
5
|
+
'src/task-orchestrator/surfaces/pod-command-job.ts', 'src/task-orchestrator/surfaces/pod-pool.ts', 'src/task-orchestrator/surfaces/pod-lease.ts',
|
|
6
|
+
'src/task-orchestrator/surfaces/pod-bun-cache.ts', 'src/task-orchestrator/surfaces/pod-install-slots.ts', 'src/release-loop/gate-shards.ts'] as const;
|
|
4
7
|
export const RELEASE_PATH_LABEL = 'elanous:release-path';
|
|
5
8
|
|
|
6
9
|
/** Flatten every GitHub PR file page, including the source of a rename. */
|
|
@@ -35,7 +38,7 @@ export function releaseGitDiffPaths(output: string): string[] {
|
|
|
35
38
|
|
|
36
39
|
/** Evaluate the paths from the opened PR, not the requested goal or local working tree. */
|
|
37
40
|
export function releasePathHold(paths: readonly string[]): string | undefined {
|
|
38
|
-
return paths.find((path) => RELEASE_PATH_PREFIXES.some((prefix) => path.startsWith(prefix)));
|
|
41
|
+
return paths.find((path) => RELEASE_PATH_PREFIXES.some((prefix) => prefix.endsWith('.ts') ? path === prefix : path.startsWith(prefix)));
|
|
39
42
|
}
|
|
40
43
|
|
|
41
44
|
/** Fixed opening of the hold comment — also how a PR held by several merge surfaces (or polls) is recognised, so it is posted once. */
|