elanous 0.2.40 → 0.2.41
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/README.md +7 -7
- package/apps/pwa/out/404/index.html +1 -1
- package/apps/pwa/out/404.html +1 -1
- package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → GiOLWmt4MqDZePubBjA4Q}/_buildManifest.js +1 -1
- package/apps/pwa/out/_next/static/chunks/1115.434ae2ecb0ad986d.js +149 -0
- package/apps/pwa/out/_next/static/chunks/1121.667cec0bcdbb3fdb.js +36 -0
- package/apps/pwa/out/_next/static/chunks/{9184.45afbf44fec87574.js → 1178.1aa9cad0e7695427.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{2829-734fe8bf2eee7347.js → 1197-54da59d250a6e476.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6749.0744ce6eb08d40e9.js → 1219.7e17964e0e7cd8e5.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/1245.1cfd13b26dbd71d6.js +287 -0
- package/apps/pwa/out/_next/static/chunks/1494-f93046ff5c5a124d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1609.2b312797599b8e45.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1661.0dd330f3d89f73f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/167-0c121e4b47e0f9da.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1700.cdc2bf8cc685e221.js +90 -0
- package/apps/pwa/out/_next/static/chunks/1703-78e46acad29f3cfc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1765.679b29625c8e88d4.js +77 -0
- package/apps/pwa/out/_next/static/chunks/{2226.2cf61ec781827219.js → 1800.f7ff51dc4978a958.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/1971-7efb628c471dc5a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/1999-8de7b7bb36801913.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9175.2de5209a5ce6f68a.js → 2073.689dcb2680113d76.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2198-557d49184104d165.js +1 -0
- package/apps/pwa/out/_next/static/chunks/221-440ce67fa9f5c839.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5383.bdfa5d886e39a826.js → 2263.e09b6edea33bad2d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/2427-8ed8e98624cbd664.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2457-725c5827bc003795.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2491-2718b15a5ccb75a5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2527-5c636a43c7cc5dde.js +1 -0
- package/apps/pwa/out/_next/static/chunks/2692-1027cb16fe4ccf49.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{9069.657590a84afb8fac.js → 2743.5d3f76948be32b34.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/{6624.981ef7caeb680560.js → 2773.0e80b9d325fb5635.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/2873-0f3cb56c8e3528ea.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4864a2ca.1c1c280a7772c5e5.js → 2fdf2931.b431eee4fb468bc3.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9189505a.980427ac048c8c60.js → 2fe2c302.41b517f88d6fe502.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{9992.07ce73c10bd5e6a1.js → 3097.864e92bdaa2f4d15.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/3136-d6870ba63300a93e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3173-0289113d434e83b7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3230-49298c3b73ef2268.js +1 -0
- package/apps/pwa/out/_next/static/chunks/325-dd9208a1a0ab7ce4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3283.528f430dd043fb4e.js +74 -0
- package/apps/pwa/out/_next/static/chunks/3295.cc8cb13b8f0dae1a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3688-86e3b88abf18cb3b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3804-7220467a5473a8df.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3808.3e1e247ce7bdf889.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{b84cad00.594027ebe0531fe2.js → 385e4574.e9886ab32759eda3.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/3927.b5473ad109da44c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/3934-98ea94832e194796.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4133.2056bb4d78f621af.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8086.1ab9103c41be884f.js → 4156.ba4de4a3664f04b4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4297-239ca82f293faab0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4320-dcc5a7734126f4c9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4434.94b4c552a2d91e69.js +148 -0
- package/apps/pwa/out/_next/static/chunks/{1281.d81877e35b9068f4.js → 4527.a69f2894d1bc9f4a.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4579.03e4092f73950965.js +226 -0
- package/apps/pwa/out/_next/static/chunks/{8357.1aaa713b052a78b1.js → 4667.97e31aa38c95c475.js} +4 -4
- package/apps/pwa/out/_next/static/chunks/{5436.fdf6fa8ae3e9588d.js → 4702.4a4adc1f16d7c93b.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/4815.481501c57b3568d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/487-d16e698ef14662d9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/4888-7a38bf522c9cc6fe.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5034-30e429d6bb086881.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5040-35c494e60dadd97d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/50c6ab1e.81a96e419350909d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5154.4b6a836179356f30.js +94 -0
- package/apps/pwa/out/_next/static/chunks/{4769.9fd582071301f382.js → 5159.115f1c2ca471386c.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5228-a8200df486278f2d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/530.d26346e18089640a.js +115 -0
- package/apps/pwa/out/_next/static/chunks/5379.97af106d09566f69.js +8 -0
- package/apps/pwa/out/_next/static/chunks/{d8de0de2-dd0f4ac8e5ab1832.js → 53aeb4ee-51c92f8d683f5220.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6257.c0037b8949239f5e.js → 5471.1e611302ed3a7c53.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/5479-b6372e762719f92f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/5534-699c5cbcbc96c5d7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2566.beaffc3a5e1fcd2e.js → 5574.f35accf4f132b29d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5701.9c4e8f250312eeee.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{2066.a77257c8c350770a.js → 5744.b9415e18ad623100.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5892.2526d962339662d8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{4351.0f37a6db2b34d50b.js → 5937.c2df9e3447e1f667.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5941.8210cc93c9202c0a.js +286 -0
- package/apps/pwa/out/_next/static/chunks/{6051-0ae955eedb10adb9.js → 5947-135e26537d80a6b9.js} +3 -3
- package/apps/pwa/out/_next/static/chunks/{3746-f80a78f220bf37b5.js → 5964-7e21164a8f2cf0ce.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/5975.4004f820ae3cecd5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6142-7ccd48795d7abd55.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6160.bf9177b8c1bfb243.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6398.71ba0690c8027555.js +27 -0
- package/apps/pwa/out/_next/static/chunks/6492.2bd5c10edc1a064e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/6552.a3840aa7da35ad68.js +62 -0
- package/apps/pwa/out/_next/static/chunks/6736.1e36d3ac5fa5e41d.js +24 -0
- package/apps/pwa/out/_next/static/chunks/{2047.8f23e210995d4548.js → 6874.d5cf7eb8edb2cabe.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/6900.3ccbe069bdd4556a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/71327eb4.add50b365f94bf3a.js +122 -0
- package/apps/pwa/out/_next/static/chunks/7136.deca3e3a2ddaa374.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7139-ee9f8ed2677a40b3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7191.fdc955f7d96064a4.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7423-e0aa5d9e2962120e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7453.afc1ea7e05d56a8c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7503-5e6a3d7fe67e4a0c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7761-476fd7bf768abd34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/7975.eafb12097a0a9e62.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{8272-025653884f9645d2.js → 8050-9b364bdef8f71927.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8152.64e253c35cccfaae.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8190.620f0231b3924bcb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/83184dcd-0ee6247ff41eb3f2.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8448.45b6b1f1a99eeb35.js +104 -0
- package/apps/pwa/out/_next/static/chunks/{2281-b8cede695c6c650e.js → 8464-e24f10451b658aac.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/8477.e4c944bb3aa5d2f3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8710.ca385257d5ca422e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/8830.627ccf294ec2465c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{5622.94893f5aea7185d0.js → 8880.64c445592f04acaf.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{1452.162bb2d9d699e82a.js → 8981.c706964c8ba27aff.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{470.51a72a2348306455.js → 9048.212083de42d25be3.js} +2 -2
- package/apps/pwa/out/_next/static/chunks/9053.bd0fffaff8d3f836.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9161-c66e723d7ec9d682.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9185.1ecdf9b65c0bb684.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9356.fccd5f58086b4ff5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9446.dc0406109371d329.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9506.dcf25d467a42627e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{2177.df8547f9d7215c4e.js → 9507.7026657a2f47eb64.js} +16 -16
- package/apps/pwa/out/_next/static/chunks/9541.eb8e2f8480c7feca.js +93 -0
- package/apps/pwa/out/_next/static/chunks/9577.ed7582186efa5482.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{7515.1ad6efe157fa4448.js → 9579.4a8169600fff2058.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9642-ff2e039eb62e3b92.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9659-8f2323348113ad80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/9724.4c5623af2db43153.js +34 -0
- package/apps/pwa/out/_next/static/chunks/{2499.02fbfd18126c10c0.js → 9834.63ab2bbc3153172e.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/9869.81a1e24ca682d5a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{409c787b.e48c5bec8ec10456.js → a0a01613.6d1cca322238d7fe.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{6cc1d1d6.9a98dd4622f1afc6.js → addc2b32.8c4ff8f0aefe987d.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-8d9d76ea322d855c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-ed2c4e59f9f1fe21.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-2dc99e03c5d76ca0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/board/page-b5a3a788330e920f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/botlab/{page-ba957ff875a026a0.js → page-14949db884bfa672.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-ea76c85b36388a97.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-01716d20af62d325.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/chat/page-62baf6881a64b1e9.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/consult/page-f89ba590c2af8afa.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/control/page-22f8b0f78d9637e5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-817f9d7e6820be80.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-ffb9bc0d2650249a.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/editor/page-f6d0e64873c0f629.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/exec/page-8bfa0d4ba23a209d.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/field/page-f5060462249e32c7.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-8d9d76ea322d855c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/inside/page-b2049f8b1ef79117.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/intake/page-1446c5fa93907f11.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/layout-b48a7a07c5204156.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live/page-e974b8c4ca47614c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-8a919b869bd28594.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/loops/page-d31b8de6bfcd72ed.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/market/page-64765f817909db29.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-d128c8569a36ee9b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/morning/page-b2679d357e9b9270.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/not-found-6fabec98a9e7b269.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-048f30149dcf1349.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-9113181d6b5a2725.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-40f9e19149024298.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-1e7a755a13227611.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-3c8f8b67a203cf07.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/page-18032f5437215062.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-da3b739192fd0ee3.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-d332545571bd6fd1.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-5237aa5b3f3b8ec5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-a142dfb0331a05f5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/settings/page-d16e56c3989c147e.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-6b6593600869e2cd.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-8d9d76ea322d855c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/setup/page-29e8b8a8396b55cb.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/share/page-b3414d856a1a7e2f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-c3affa52b7ce961b.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-f21dddf9f95b6fab.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/term/page-f5a30a24745bf088.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/today/page-8c8569a09b4d4e34.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/trace/page-2ce32722c0243483.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/vault/page-4767b0d9c0a98c6c.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-116ee1339c387a75.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-35e8c50ca4ef7ffc.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-52e17113356bb891.js +1 -0
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-7458ae05ed2ac1a0.js +1 -0
- package/apps/pwa/out/_next/static/chunks/{c696986b.5dc8bb1143af16d1.js → b2271e54.c1de3347976e90b0.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/{ca3702f8.2913182e73889fa2.js → c0c1a699.0ba79f97005965d4.js} +1 -1
- package/apps/pwa/out/_next/static/chunks/framework-ad6c9dd524ad6ef8.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-app-2ddd1f2b44d6aa59.js +1 -0
- package/apps/pwa/out/_next/static/chunks/main-e3d82bdc358d20c5.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_app-71d5aa3896e1655f.js +1 -0
- package/apps/pwa/out/_next/static/chunks/pages/_error-03ffc54e00438546.js +1 -0
- package/apps/pwa/out/_next/static/chunks/webpack-56bb89af5a611d0b.js +1 -0
- package/apps/pwa/out/approvals/index.html +1 -1
- package/apps/pwa/out/approvals/index.txt +22 -22
- package/apps/pwa/out/autopilot/index.html +1 -1
- package/apps/pwa/out/autopilot/index.txt +22 -22
- package/apps/pwa/out/board/index.html +1 -1
- package/apps/pwa/out/board/index.txt +22 -22
- package/apps/pwa/out/botlab/index.html +1 -1
- package/apps/pwa/out/botlab/index.txt +21 -21
- package/apps/pwa/out/bots/index.html +1 -1
- package/apps/pwa/out/bots/index.txt +21 -21
- package/apps/pwa/out/ceo/index.html +1 -1
- package/apps/pwa/out/ceo/index.txt +22 -22
- package/apps/pwa/out/chat/index.html +1 -1
- package/apps/pwa/out/chat/index.txt +21 -21
- package/apps/pwa/out/consult/index.html +1 -1
- package/apps/pwa/out/consult/index.txt +22 -22
- package/apps/pwa/out/control/index.html +1 -1
- package/apps/pwa/out/control/index.txt +22 -22
- package/apps/pwa/out/decisions/index.html +1 -1
- package/apps/pwa/out/decisions/index.txt +21 -21
- package/apps/pwa/out/design-check/index.html +1 -1
- package/apps/pwa/out/design-check/index.txt +22 -22
- package/apps/pwa/out/editor/index.html +1 -1
- package/apps/pwa/out/editor/index.txt +22 -22
- package/apps/pwa/out/exec/index.html +1 -1
- package/apps/pwa/out/exec/index.txt +22 -22
- package/apps/pwa/out/field/index.html +1 -1
- package/apps/pwa/out/field/index.txt +22 -22
- package/apps/pwa/out/healthz +1 -1
- package/apps/pwa/out/index.html +1 -1
- package/apps/pwa/out/index.txt +21 -21
- package/apps/pwa/out/inside/index.html +1 -1
- package/apps/pwa/out/inside/index.txt +21 -21
- package/apps/pwa/out/intake/index.html +1 -1
- package/apps/pwa/out/intake/index.txt +22 -22
- package/apps/pwa/out/live/index.html +1 -1
- package/apps/pwa/out/live/index.txt +22 -22
- package/apps/pwa/out/live-run/index.html +1 -1
- package/apps/pwa/out/live-run/index.txt +22 -22
- package/apps/pwa/out/loops/index.html +1 -1
- package/apps/pwa/out/loops/index.txt +21 -21
- package/apps/pwa/out/market/index.html +1 -1
- package/apps/pwa/out/market/index.txt +21 -21
- package/apps/pwa/out/missions/placeholder/index.html +1 -1
- package/apps/pwa/out/missions/placeholder/index.txt +21 -21
- package/apps/pwa/out/morning/index.html +1 -1
- package/apps/pwa/out/morning/index.txt +22 -22
- package/apps/pwa/out/observatory/index.html +1 -1
- package/apps/pwa/out/observatory/index.txt +22 -22
- package/apps/pwa/out/ops/checklist/index.html +1 -1
- package/apps/pwa/out/ops/checklist/index.txt +21 -21
- package/apps/pwa/out/ops/release/index.html +1 -1
- package/apps/pwa/out/ops/release/index.txt +21 -21
- package/apps/pwa/out/ops/seats/index.html +1 -1
- package/apps/pwa/out/ops/seats/index.txt +21 -21
- package/apps/pwa/out/outputs/index.html +1 -1
- package/apps/pwa/out/outputs/index.txt +21 -21
- package/apps/pwa/out/reflection/index.html +1 -1
- package/apps/pwa/out/reflection/index.txt +22 -22
- package/apps/pwa/out/scheduler/index.html +1 -1
- package/apps/pwa/out/scheduler/index.txt +22 -22
- package/apps/pwa/out/sessions/index.html +1 -1
- package/apps/pwa/out/sessions/index.txt +21 -21
- package/apps/pwa/out/settings/devices/index.html +1 -1
- package/apps/pwa/out/settings/devices/index.txt +22 -22
- package/apps/pwa/out/settings/index.html +1 -1
- package/apps/pwa/out/settings/index.txt +22 -22
- package/apps/pwa/out/setup/done/index.html +1 -1
- package/apps/pwa/out/setup/done/index.txt +22 -22
- package/apps/pwa/out/setup/index.html +1 -1
- package/apps/pwa/out/setup/index.txt +22 -22
- package/apps/pwa/out/share/index.html +1 -1
- package/apps/pwa/out/share/index.txt +22 -22
- package/apps/pwa/out/showroom/index.html +1 -1
- package/apps/pwa/out/showroom/index.txt +21 -21
- package/apps/pwa/out/tasks/index.html +1 -1
- package/apps/pwa/out/tasks/index.txt +22 -22
- package/apps/pwa/out/term/index.html +1 -1
- package/apps/pwa/out/term/index.txt +22 -22
- package/apps/pwa/out/today/index.html +1 -1
- package/apps/pwa/out/today/index.txt +22 -22
- package/apps/pwa/out/trace/index.html +1 -1
- package/apps/pwa/out/trace/index.txt +22 -22
- package/apps/pwa/out/vault/index.html +1 -1
- package/apps/pwa/out/vault/index.txt +22 -22
- package/apps/pwa/out/workflows/chat-ui/index.html +1 -1
- package/apps/pwa/out/workflows/chat-ui/index.txt +22 -22
- package/apps/pwa/out/workflows/index.html +1 -1
- package/apps/pwa/out/workflows/index.txt +22 -22
- package/apps/pwa/out/workspace/index.html +1 -1
- package/apps/pwa/out/workspace/index.txt +22 -22
- package/apps/pwa/out/worktrees/index.html +1 -1
- package/apps/pwa/out/worktrees/index.txt +22 -22
- package/bin/elanous.mjs +6 -1
- package/catalog/models/openai/gpt-6.1-sol.yaml +16 -0
- package/catalog/models/openai/gpt-6.1-terra.yaml +16 -0
- package/graphs/demo/persona-teacher/lesson-pack.yaml +16 -0
- package/graphs/demo/persona-teacher/recipes.yaml +17 -0
- package/graphs/demo/persona-teacher/weekly-lesson.yaml +36 -0
- package/graphs/overlays/stop-heal-ladder.yaml +23 -2
- package/graphs/release/release-loop.yaml +3 -1
- package/graphs/units/gate/gate.yaml +20 -0
- package/graphs/units/git/git.yaml +26 -0
- package/graphs/units/implement/implement.yaml +19 -0
- package/graphs/units/landing/landing.yaml +18 -0
- package/graphs/units/review/review.yaml +20 -0
- package/graphs/units/verbs/recipes.yaml +3 -0
- package/graphs/units/verbs/research.yaml +20 -0
- package/graphs/work/research-report.yaml +11 -1
- package/package.json +1 -1
- package/scripts/disk-steward.ts +46 -0
- package/scripts/fleet/node-setup.sh +50 -0
- package/scripts/graph-units/verbs/research.ts +55 -0
- package/scripts/llm-cost-ledger.ts +179 -8
- package/scripts/measure-nl-routing-corpus.ts +10 -2
- package/scripts/persona-teacher/weekly-lesson-node.ts +172 -0
- package/scripts/public-copy-lint.ts +163 -19
- package/scripts/ratchets/train-side-invariants.sh +0 -1
- package/scripts/release-loop/gate-autoheal.ts +117 -0
- package/scripts/release-loop/gate-baseline-receipt.ts +8 -1
- package/scripts/release-loop/gate-diff.ts +22 -3
- package/scripts/release-loop/gate-node.ts +205 -17
- package/scripts/release-loop/gate-shard-load-flaky.ts +256 -0
- package/scripts/release-loop/gate-triage-node.ts +70 -10
- package/scripts/release-loop/resume-release.ts +247 -15
- package/scripts/release-loop/traffic-node.ts +6 -3
- package/scripts/release-loop/unattended-release.ts +4 -2
- package/scripts/shadow-authoring-probe.ts +20 -0
- package/scripts/ux-sim.ts +19 -2
- package/src/acp/core-turn-bridge.ts +86 -4
- package/src/agent-substrate/self-review-cli.ts +91 -29
- package/src/auto-research/research-turn.ts +10 -1
- package/src/autopilot/discovery/wiki-claim-proposer.ts +22 -1
- package/src/boot/daemon-tools/self-implement.ts +46 -9
- package/src/budget/shadow-arms.ts +52 -0
- package/src/chat/pickers/state.ts +7 -1
- package/src/cli/log-event-names.ts +5 -0
- package/src/cli/mcp-login.ts +8 -18
- package/src/cli/msg-cli.ts +57 -1
- package/src/cli/pr-land-heavy-remote.ts +15 -9
- package/src/cli/release-cli.ts +27 -1
- package/src/cli/sim-cli.ts +7 -1
- package/src/cli/tasks-cli.ts +5 -4
- package/src/codex/models.ts +30 -15
- package/src/core-turn/run-core-turn.ts +3 -0
- package/src/core-turn/run-goal-loop.ts +88 -2
- package/src/dashboard/acp-boot.ts +72 -3
- package/src/dashboard/index.ts +6 -0
- package/src/dashboard/turn-preamble.ts +12 -1
- package/src/disk-steward/judge.ts +73 -0
- package/src/disk-steward/ledger.ts +122 -0
- package/src/disk-steward/steward.ts +373 -0
- package/src/domains/guardian-tick.ts +191 -2
- package/src/graph-runner/graph-cli.ts +21 -0
- package/src/graph-runner/in-process-registry.ts +37 -0
- package/src/graph-runner/runner.ts +33 -3
- package/src/grounding/ref-index.ts +19 -0
- package/src/grounding/sources-cli.ts +9 -1
- package/src/harness/harness-cli-command.ts +267 -14
- package/src/harness/harness-incidents.ts +312 -7
- package/src/harness/harness-space.ts +15 -1
- package/src/harness/progress-worker-entry.ts +59 -0
- package/src/harness/progress-worker-runtime.ts +11 -0
- package/src/index.ts +18 -2
- package/src/instance/dev-project.ts +25 -0
- package/src/intelligence-map/model-alias.ts +6 -5
- package/src/intelligence-map/model-catalog.ts +59 -2
- package/src/llm/model-defaults.ts +4 -4
- package/src/llm.ts +42 -11
- package/src/loops/orchestrator/tick.ts +48 -0
- package/src/mcp/mcp-oauth.ts +3 -1
- package/src/model-tier/llm-tier-map.ts +9 -9
- package/src/model-tier/turn-tier.ts +1 -1
- package/src/msg/msg-mirror-github.ts +80 -0
- package/src/msg/msg-mirror-policy.ts +61 -0
- package/src/msg/msg-mirror-runner.ts +219 -0
- package/src/msg/msg-mirror-state.ts +33 -0
- package/src/msg/msg-store.ts +11 -0
- package/src/output-truncation.ts +41 -12
- package/src/project/project-store.ts +48 -1
- package/src/release-loop/gate-host-reservation.ts +144 -0
- package/src/release-loop/release-schedule.ts +90 -1
- package/src/research/bloom-exemplars.ts +135 -0
- package/src/self-dev/ask-launch-flow.ts +39 -25
- package/src/self-dev/dev-cli.ts +17 -17
- package/src/self-dev/graph-front-nodes.ts +23 -0
- package/src/self-dev/launch-preflight.ts +9 -4
- package/src/self-dev/orchestrate.ts +15 -0
- package/src/self-dev/run-supervisor.ts +185 -3
- package/src/self-dev/run-types.ts +3 -0
- package/src/self-implement/gate-artifacts.ts +13 -0
- package/src/self-implement/gate-cli.ts +54 -24
- package/src/self-implement/gate-remote.ts +23 -5
- package/src/self-implement/goal-author-clarification.ts +31 -12
- package/src/self-implement/goal-author.ts +77 -5
- package/src/self-implement/graph-stage-units.ts +172 -0
- package/src/self-implement/graph-templates.ts +162 -1
- package/src/self-implement/graph-variant.ts +37 -4
- package/src/self-implement/host-regate.ts +4 -4
- package/src/self-implement/knowhow-pack.ts +38 -0
- package/src/self-implement/orchestrator.ts +235 -21
- package/src/self-implement/run-ledger.ts +64 -6
- package/src/self-implement/run-stop.ts +21 -2
- package/src/self-implement/running-runs.ts +35 -12
- package/src/self-implement/self-implement-cli.ts +36 -4
- package/src/self-implement/stop-autoheal-operational.ts +43 -0
- package/src/self-implement/stop-autoheal.ts +15 -6
- package/src/session/chat.ts +31 -54
- package/src/session/request-size-guard.ts +123 -0
- package/src/sidetab-core/model.ts +136 -0
- package/src/task-agent/parent-host.ts +14 -1
- package/src/task-agent/task-hand.ts +4 -1
- package/src/task-orchestrator/surfaces/pod-failure-reason.ts +43 -0
- package/src/task-orchestrator/surfaces/pod-ledger-events.ts +29 -4
- package/src/task-orchestrator/surfaces/self-implement-pod.ts +116 -16
- package/src/task-orchestrator/surfaces/self-implement.ts +18 -0
- package/src/tui/entry.ts +10 -3
- package/src/tui/sidetab/list.ts +45 -0
- package/src/tui/sidetab/nl-tool.ts +2 -136
- package/src/tui/sidetab/peek.ts +52 -0
- package/src/tui-client/dashboard-session.ts +3 -0
- package/src/user-config.ts +11 -5
- package/src/ux-sim/fault-needs-human-reason-repair.ts +107 -0
- package/src/ux-sim/fault-pod-child-result.ts +42 -0
- package/src/ux-sim/release-sim-rig.ts +262 -0
- package/src/ux-sim/seminar-rehearsal.ts +109 -0
- package/src/ux-sim/subagent-tools-device.ts +2 -2
- package/src/version/packed-revision.json +1 -1
- package/apps/pwa/out/_next/static/chunks/1060.014f1f01a17aec26.js +0 -115
- package/apps/pwa/out/_next/static/chunks/1350.59f40e39e02d91b1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1415.79821ec7ae99acdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/147.f92f63bbc5e85fa5.js +0 -286
- package/apps/pwa/out/_next/static/chunks/1537-6bb97b5214928ea9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1661.fb425a1d8a065b72.js +0 -149
- package/apps/pwa/out/_next/static/chunks/1671-1c22b40b50b208f2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/1758.0204d3f48783c49d.js +0 -90
- package/apps/pwa/out/_next/static/chunks/1806.027bf78b6a94d340.js +0 -104
- package/apps/pwa/out/_next/static/chunks/2061-7f2bbc53ae96c88b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2096-a938496bc996dcbd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2200-9a453b8f99687d49.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2522.f2766b76d22c8bdf.js +0 -34
- package/apps/pwa/out/_next/static/chunks/261.0d471e8aded799f3.js +0 -226
- package/apps/pwa/out/_next/static/chunks/2615.3c9738153de3ef3f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2727.e703d99ac414916d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2752.7904b8df0254d0ae.js +0 -27
- package/apps/pwa/out/_next/static/chunks/2762-5051a862dfa40e99.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2767-31784bfedf8e245d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2774-719820e3f5b2a3eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/2812-f016aa0dda149287.js +0 -1
- package/apps/pwa/out/_next/static/chunks/311-32dcac79970985e8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3175-f93f7495cd28253c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3184.8da993f5502d2140.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3231-d7c981db0ff8bdcc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3250.151309c5176d6b4b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3330.7443183b7e6fdbdf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3517.a5aa1797a9dbf2ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3567-45f676877ed9e8a5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/3819.8a1de79b2e8c7298.js +0 -24
- package/apps/pwa/out/_next/static/chunks/39.9b37b0be4c128a83.js +0 -77
- package/apps/pwa/out/_next/static/chunks/3b355b3d.6f73c98bf6f9c749.js +0 -122
- package/apps/pwa/out/_next/static/chunks/4023.a19045970a9ce16a.js +0 -36
- package/apps/pwa/out/_next/static/chunks/413-24c8284bda08241d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4135.e45d6ebc29e20647.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4283.65502f5d0e6ff6c0.js +0 -287
- package/apps/pwa/out/_next/static/chunks/4305-4e28fa92a7b34a5b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4335-50efa61fd7613142.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4720.ecbd1693fa151068.js +0 -1
- package/apps/pwa/out/_next/static/chunks/483.725e4a61be922788.js +0 -1
- package/apps/pwa/out/_next/static/chunks/4969-4b209d7307410c00.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5068-c7f53862f83c0917.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5315.bc96711c24dfefe2.js +0 -74
- package/apps/pwa/out/_next/static/chunks/5542.efbf14f16baed4dd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5644.8f401a25601d05fc.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5658.35f70eb9871a54bf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5721.7bdc0e904c76ab51.js +0 -8
- package/apps/pwa/out/_next/static/chunks/5790-eef0ca20884a6bdf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5802.ef0d8598ca68fe84.js +0 -62
- package/apps/pwa/out/_next/static/chunks/5890.fb974729788dcb71.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5924.5ef25cddd36d5dbf.js +0 -1
- package/apps/pwa/out/_next/static/chunks/5979-e59c099ebf8d1f35.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6020.714cfeada2315e2e.js +0 -94
- package/apps/pwa/out/_next/static/chunks/6027-dfe0349d8c50f698.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6178.bc4730c86cf74536.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6273.d808b0dcb3c2b155.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6292.6ef1df64fa6a4c8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/647-af8dd920ba46533c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6541-170dc5c59e135c0c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6742-a1ad4a94ba7bc37a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6836-493dc55c39187949.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6856-53ac421c06039a18.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6908.06008c67f6380ea9.js +0 -148
- package/apps/pwa/out/_next/static/chunks/6915.096931864206f522.js +0 -1
- package/apps/pwa/out/_next/static/chunks/6925.5e181fb7dcf90193.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7203-800e11037adc41eb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7219-15bdd9a80661af8e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7279.6170f591105936bb.js +0 -93
- package/apps/pwa/out/_next/static/chunks/7349-373165c7fbdcc3df.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7514-a533ba0ca1cae4f4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7521.d919cc1fab80c1d9.js +0 -24
- package/apps/pwa/out/_next/static/chunks/7538.90e97bbdf9178cff.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7611.85f045bf232053ac.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7825-39203196a12579b2.js +0 -1
- package/apps/pwa/out/_next/static/chunks/7869.5e1a9a12fd70d6c7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8099.1cccf31c1baa7e1c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8179-e61fffbdb70f1152.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8265.bdeb991b34db6a06.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8638-e42615f2166165b5.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8639-92c11d069792429e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8691.54e22831d5e8ccf8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/8d173e38.18a2f7b4e1848bdb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9125-ae588d88a0293b93.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9311.f9f641a46a508611.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9371-a6fee8378ebfa3ee.js +0 -1
- package/apps/pwa/out/_next/static/chunks/9421-3aa9ff4fa7f63d8a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/_not-found/page-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/approvals/page-1b948637c37b3abd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/autopilot/page-c63400f1bcf3e47c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/board/page-95d0957267819586.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/bots/page-bb6fd0714879cb87.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ceo/page-8f9038520d2acbef.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/chat/page-d4b48397e05fce2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/consult/page-72d5744245dc0c27.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/control/page-37625dc8300fa43a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/decisions/page-fbef9d160272dbc1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/design-check/page-58424168df84928e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/editor/page-72c12ba430ac57c0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/exec/page-d53f3e9ed806d7e0.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/field/page-4d2fbd45feee0829.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/healthz/route-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/inside/page-8783dc0ed7590a2c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/intake/page-3706cb390606e930.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/layout-9b0a86598e0111fd.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live/page-4edb8df90f4537ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/live-run/page-83d27757e2b8060a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/loops/page-47398b9ba1cc5e1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/market/page-fb86f55cfe2e681d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/missions/[id]/page-e22345fc8fd47b1b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/morning/page-fca2e59a81744d9e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/not-found-6e96bda63100b31e.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/observatory/page-4d17ad8e0db8cea4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/checklist/page-121f92766c33beaa.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/release/page-43f14212c545f92d.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/ops/seats/page-ccec2023e7a974ec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/outputs/page-b04f33f548b89a94.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/page-c8792823c0917021.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/reflection/page-8c0e32782ceef4cb.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/scheduler/page-94bd3922eb230ce8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/sessions/page-bca565887bafa03c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/devices/page-ac1dffafe649fc6c.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/settings/page-52374edb5e23e455.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/done/page-ad4ebca120d43ca7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/layout-76394dc618d322c8.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/setup/page-718b89ce4b4ae4e4.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/share/page-204eca33eeeaddec.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/showroom/page-e58ba9bcdb9ac0f9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/tasks/page-98f6dd50bafd7734.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/term/page-139d722de1dcd6c1.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/today/page-5a4bdd72bff27057.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/trace/page-6f6ab17d44f984ce.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/vault/page-aabb7bd15fb72da9.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/chat-ui/page-e4322319164a4436.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workflows/page-e9efc0c8f32e2371.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/workspace/page-ccde99f07aaf71f7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/app/worktrees/page-80464aced9614390.js +0 -1
- package/apps/pwa/out/_next/static/chunks/d5d3cefc-373c4eb722ed848b.js +0 -1
- package/apps/pwa/out/_next/static/chunks/framework-002b472a66935d31.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-49b88d47292c0476.js +0 -1
- package/apps/pwa/out/_next/static/chunks/main-app-fff2549cb10a133f.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_app-32abbbba3f3b76b7.js +0 -1
- package/apps/pwa/out/_next/static/chunks/pages/_error-9d9cfef60c60dd7a.js +0 -1
- package/apps/pwa/out/_next/static/chunks/webpack-cc7f483fa294034a.js +0 -1
- package/scripts/ratchets/next-tui-entry-budget.ts +0 -124
- /package/apps/pwa/out/_next/static/{HjeK7zONHfR7op1hKXp4k → GiOLWmt4MqDZePubBjA4Q}/_ssgManifest.js +0 -0
|
@@ -84,7 +84,7 @@ export interface GoalAuthorSelfResolutionContext {
|
|
|
84
84
|
|
|
85
85
|
export type GoalAuthorSelfResolution =
|
|
86
86
|
| { answer: string; evidence: readonly string[]; assumption?: string; declined?: undefined }
|
|
87
|
-
| { answer?: undefined; evidence?: undefined; declined?: boolean };
|
|
87
|
+
| { answer?: undefined; evidence?: undefined; declined?: boolean; failed?: boolean };
|
|
88
88
|
|
|
89
89
|
export interface GoalAuthorClarificationResolutionDeps {
|
|
90
90
|
/** Elanousic authoring seam; it must return no answer when the available evidence is insufficient. */
|
|
@@ -227,7 +227,7 @@ export async function defaultGoalAuthorSelfResolve(
|
|
|
227
227
|
parsed = JSON.parse(result);
|
|
228
228
|
} catch {
|
|
229
229
|
observeSelfResolve('self-resolve-parse-failed', context, startedAt, { usage: deriveUsage(usages) });
|
|
230
|
-
return {};
|
|
230
|
+
return { failed: true };
|
|
231
231
|
}
|
|
232
232
|
const answer = parsed !== null && typeof parsed === 'object'
|
|
233
233
|
? (parsed as { answer?: unknown }).answer
|
|
@@ -256,7 +256,7 @@ export async function defaultGoalAuthorSelfResolve(
|
|
|
256
256
|
startedAt,
|
|
257
257
|
{ usage: deriveUsage(usages) },
|
|
258
258
|
);
|
|
259
|
-
return {};
|
|
259
|
+
return { failed: true };
|
|
260
260
|
} finally {
|
|
261
261
|
clearTimeout(timeout);
|
|
262
262
|
}
|
|
@@ -530,7 +530,7 @@ export function goalClarificationDecisionCategory(
|
|
|
530
530
|
const text = [clarification.header, clarification.question, ...clarification.options.flatMap((option) => [option.label, option.description])]
|
|
531
531
|
.join(' ')
|
|
532
532
|
.toLocaleLowerCase();
|
|
533
|
-
if (/\b(payment|purchase|spend|budget|credit|charge|price|cost|paid)\b
|
|
533
|
+
if (/\b(payment|purchase|spend|budget|credit|charge|price|cost|paid|refund|reimburse(?:ment)?|chargeback|transfer|wire(?:\s+transfer)?|withdraw(?:al)?|deposit|invoice|subscribe|subscription|renewal)\b|결제|구매|지출|예산|크레딧|과금|가격|비용|환불|환급|송금|이체|구독|정기결제/.test(text)) return 'money';
|
|
534
534
|
if (/\b(security|credential|token|secret|password|authorization|authentication|permission|access control)\b|보안|자격 증명|토큰|비밀키|비밀번호|인가|인증|권한/.test(text)) return 'security';
|
|
535
535
|
if (/\b(publish|publication|deploy|send|delete|release|irreversible|external side effect|production)\b|발행|게시|배포|전송|삭제|릴리스|되돌릴 수 없|외부 효과|운영 환경/.test(text)) return 'irreversible';
|
|
536
536
|
return undefined;
|
|
@@ -827,7 +827,7 @@ export async function selfAnswerGoalDocumentClarifications(
|
|
|
827
827
|
runId?: string;
|
|
828
828
|
skipQuestionIds?: ReadonlySet<string>;
|
|
829
829
|
},
|
|
830
|
-
): Promise<{ document: string; asked: number; answered: number; unanswered: number; newlyAnswered: number }> {
|
|
830
|
+
): Promise<{ document: string; asked: number; answered: number; unanswered: number; newlyAnswered: number; resolverFailedQuestionIds: string[] }> {
|
|
831
831
|
const clarifications = parseGoalDocumentClarifications(document);
|
|
832
832
|
const pending = clarifications.filter((item) => !item.answered);
|
|
833
833
|
// The first say pass may already have self-answered some questions while authoring: count those,
|
|
@@ -837,6 +837,7 @@ export async function selfAnswerGoalDocumentClarifications(
|
|
|
837
837
|
: 0;
|
|
838
838
|
let updated = document;
|
|
839
839
|
let answered = 0;
|
|
840
|
+
const resolverFailedQuestionIds: string[] = [];
|
|
840
841
|
const evidence = options.evidence ?? document.split(/\r?\n/)
|
|
841
842
|
.filter((line) => /^(?:\s*- (?:\[code:|\[document:|TRACED PATHS|evidence:|Evidence:)|\s*-?\s*`?(?:src|test|scripts)\/[^\s`]+:\d+)/i.test(line))
|
|
842
843
|
.slice(0, 40);
|
|
@@ -844,6 +845,8 @@ export async function selfAnswerGoalDocumentClarifications(
|
|
|
844
845
|
if (parseGoalDocumentClarifications(updated).filter((entry) => entry.questionId === item.questionId).length !== 1) continue;
|
|
845
846
|
let response: Awaited<ReturnType<typeof resolveGoalAuthorClarification>>;
|
|
846
847
|
let declined = false;
|
|
848
|
+
let resolverFailed = false;
|
|
849
|
+
const baseResolver = options.resolver ?? defaultGoalAuthorSelfResolve;
|
|
847
850
|
try { response = await resolveGoalAuthorClarification({
|
|
848
851
|
questionId: item.questionId,
|
|
849
852
|
kind: 'scope',
|
|
@@ -853,17 +856,25 @@ export async function selfAnswerGoalDocumentClarifications(
|
|
|
853
856
|
blocking: false,
|
|
854
857
|
}, {
|
|
855
858
|
selfResolve: async (context) => {
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
+
try {
|
|
860
|
+
const resolution = await baseResolver(context);
|
|
861
|
+
declined = resolution.declined === true;
|
|
862
|
+
resolverFailed = 'failed' in resolution && resolution.failed === true;
|
|
863
|
+
return resolution;
|
|
864
|
+
} catch (error) {
|
|
865
|
+
resolverFailed = true;
|
|
866
|
+
throw error;
|
|
867
|
+
}
|
|
859
868
|
},
|
|
860
869
|
evidence,
|
|
861
870
|
ask: options.ask,
|
|
862
871
|
selfResolutionSelected: true,
|
|
863
872
|
}); } catch {
|
|
864
873
|
// A resolver failure leaves this question unanswered; the remaining questions are still attempted.
|
|
874
|
+
resolverFailedQuestionIds.push(item.questionId);
|
|
865
875
|
continue;
|
|
866
876
|
}
|
|
877
|
+
if (resolverFailed) resolverFailedQuestionIds.push(item.questionId);
|
|
867
878
|
let defaultExportCount: number | undefined;
|
|
868
879
|
if (response.answer === null && item.questionId === 'preservation_contract'
|
|
869
880
|
&& declined) {
|
|
@@ -916,7 +927,7 @@ export async function selfAnswerGoalDocumentClarifications(
|
|
|
916
927
|
path: options.path, asked, answered, unanswered,
|
|
917
928
|
reason: unanswered === 0 ? 'answered' : 'insufficient-evidence',
|
|
918
929
|
});
|
|
919
|
-
return { document: updated, asked, answered, unanswered, newlyAnswered };
|
|
930
|
+
return { document: updated, asked, answered, unanswered, newlyAnswered, resolverFailedQuestionIds };
|
|
920
931
|
}
|
|
921
932
|
|
|
922
933
|
/** SelfImplement boundary: resolve pending questions itself and record a bounded policy assumption if that fails.
|
|
@@ -940,15 +951,23 @@ export async function selfAnswerOrAssumeGoalDocumentClarifications(
|
|
|
940
951
|
const decisionRequired: Array<{ questionId: string; header: string; question: string; category: GoalClarificationDecisionCategory }> =
|
|
941
952
|
safetyQuestions.map(({ entry, category }) => ({ questionId: entry.questionId, header: entry.header, question: entry.question, category }));
|
|
942
953
|
for (const item of parseGoalDocumentClarifications(updated).filter((entry) => !entry.answered)) {
|
|
954
|
+
if (attempted.resolverFailedQuestionIds.includes(item.questionId)) continue;
|
|
943
955
|
const category = goalClarificationDecisionCategory(item);
|
|
944
956
|
if (category) continue;
|
|
945
957
|
const offered = item.options.filter((option) => option.label.trim() && !/[\r\n]/.test(option.label));
|
|
946
|
-
const
|
|
958
|
+
const requestText = (options.ask ?? '').toLocaleLowerCase().replace(/\s+/g, ' ').trim();
|
|
959
|
+
const inScopeOptions = item.includeOther ? [] : offered.filter((option) =>
|
|
960
|
+
[option.label, option.description ?? ''].some((candidate) => {
|
|
961
|
+
const normalized = candidate.toLocaleLowerCase().replace(/\s+/g, ' ').trim();
|
|
962
|
+
return normalized.length >= 4 && requestText.includes(normalized);
|
|
963
|
+
}));
|
|
964
|
+
if (!item.includeOther && inScopeOptions.length !== 1) continue;
|
|
965
|
+
const useOfferedOption = !item.includeOther;
|
|
947
966
|
const answer = useOfferedOption
|
|
948
|
-
?
|
|
967
|
+
? inScopeOptions[0]!.label.trim()
|
|
949
968
|
: '근거가 부족하므로 요청에 명시된 범위만 진행한다고 가정한다';
|
|
950
969
|
const assumption = useOfferedOption
|
|
951
|
-
? '
|
|
970
|
+
? '요청 원문에 명시된 후보만 허용되어 그 후보를 정책 가정으로 선택했다'
|
|
952
971
|
: '자가 해소가 답을 내지 못해 추가 범위를 만들지 않고 요청에 명시된 범위만 진행한다고 가정했다';
|
|
953
972
|
try {
|
|
954
973
|
const current = findUnansweredGoalDocumentClarification(updated, item.questionId);
|
|
@@ -57,6 +57,7 @@ import { targetScopedGoalText } from './goal-text-path-scope.js';
|
|
|
57
57
|
import { parseReleaseNoteSection } from '../release-loop/release-note.js';
|
|
58
58
|
import { declaredNewFilePaths } from './goal-new-paths.js';
|
|
59
59
|
import { classifyGoalCommandExecution, type GoalCommandExecutionResult } from './goal-command-execution.js';
|
|
60
|
+
import { formatShadowArmProbeRecord, probeShadowArm, type ShadowArmProbeRecord, type ShadowDifficulty } from '../budget/shadow-arms.js';
|
|
60
61
|
import { identityLines, repositoryIdentifiers } from './goal-author-identity.js';
|
|
61
62
|
import { selectRelevantAuthoringLessons } from './knowhow-pack.js';
|
|
62
63
|
import { elanousStateRoot } from '../autopilot/state-paths.js';
|
|
@@ -385,6 +386,7 @@ type GoalAuthorTimedPhase = GoalAuthorPhase | GoalAuthorAssembleSubphase;
|
|
|
385
386
|
function startGoalAuthorPhase(phase: GoalAuthorTimedPhase, authorRunId: string, onProgress?: GoalAuthorDeps['onProgress']): number {
|
|
386
387
|
observeGoalAuthor('goal-author', 'phase-start', { phase, authorRunId });
|
|
387
388
|
if (GOAL_AUTHOR_PHASES.includes(phase as GoalAuthorPhase)) {
|
|
389
|
+
if (phase === 'assemble') probeAuthoringShadowArm(authorRunId);
|
|
388
390
|
if (onProgress) onProgress(phase as GoalAuthorPhase, 'start');
|
|
389
391
|
else process.stderr.write(`[goal-author] ${phase} started\n`);
|
|
390
392
|
}
|
|
@@ -403,6 +405,56 @@ function endGoalAuthorPhase(phase: GoalAuthorTimedPhase, startedAt: number, auth
|
|
|
403
405
|
}
|
|
404
406
|
}
|
|
405
407
|
|
|
408
|
+
// ── SHADOW-MODEL-ARMS · 저작 단계 그림자 «1팔» probe(명시 실행 · 관측만) ────────────────
|
|
409
|
+
/**
|
|
410
|
+
* ⭐ 저작 단계 그림자 1팔 — `planShadowArms`(src/budget/shadow-arms.ts) 를 일일 상한
|
|
411
|
+
* 안에서 «실제 호출»해 난이도·모델·예상/실제 비용·결과를 한 줄 원장 형식으로 기록한다.
|
|
412
|
+
* ⛔ 관측만 한다 — 라이브 LLM(Claude 구독) 호출 0 · 골/PR/착지 파일 쓰기 0.
|
|
413
|
+
* 팔은 «계획»이고, 실행·자동 런 훅·다른 단계(implement·review·judge) 팔은 후속 조각이다.
|
|
414
|
+
* ⛔ 오늘 이미 쓴 그림자 예산의 실 지출 원장 배선도 후속 — 지금은 0지출 고정값으로 판정한다.
|
|
415
|
+
*/
|
|
416
|
+
export const SHADOW_AUTHORING_ARM_MODEL = 'gpt-5.6-terra';
|
|
417
|
+
export const SHADOW_AUTHORING_ARM_DIFFICULTY: ShadowDifficulty = 'medium';
|
|
418
|
+
export const SHADOW_AUTHORING_ARM_INPUT_TOKENS = 24_000;
|
|
419
|
+
export const SHADOW_AUTHORING_ARM_OUTPUT_TOKENS = 8_000;
|
|
420
|
+
export const SHADOW_AUTHORING_SPENT_TODAY_USD = 0;
|
|
421
|
+
export const SHADOW_AUTHORING_DAILY_CAP_USD = 5;
|
|
422
|
+
|
|
423
|
+
export interface AuthoringShadowArmProbe {
|
|
424
|
+
record: ShadowArmProbeRecord;
|
|
425
|
+
line: string;
|
|
426
|
+
}
|
|
427
|
+
|
|
428
|
+
let shadowArmProbeObserver: ((probe: AuthoringShadowArmProbe, authorRunId: string) => void) | undefined;
|
|
429
|
+
|
|
430
|
+
function defaultShadowArmProbeObserver(probe: AuthoringShadowArmProbe, authorRunId: string): void {
|
|
431
|
+
observeGoalAuthor('goal-author', 'shadow-arm-authoring', { authorRunId, ...probe.record, line: probe.line });
|
|
432
|
+
}
|
|
433
|
+
|
|
434
|
+
/** 저작 단계 그림자 1팔을 실제 호출해 기록을 낸다 — 부작용은 관측 원장뿐이다(관측만). */
|
|
435
|
+
export function probeAuthoringShadowArm(authorRunId: string): AuthoringShadowArmProbe {
|
|
436
|
+
const record = probeShadowArm({
|
|
437
|
+
stage: 'authoring',
|
|
438
|
+
difficulty: SHADOW_AUTHORING_ARM_DIFFICULTY,
|
|
439
|
+
inputTokens: SHADOW_AUTHORING_ARM_INPUT_TOKENS,
|
|
440
|
+
expectedOutputTokens: SHADOW_AUTHORING_ARM_OUTPUT_TOKENS,
|
|
441
|
+
candidates: [SHADOW_AUTHORING_ARM_MODEL],
|
|
442
|
+
spentTodayUsd: SHADOW_AUTHORING_SPENT_TODAY_USD,
|
|
443
|
+
dailyCapUsd: SHADOW_AUTHORING_DAILY_CAP_USD,
|
|
444
|
+
});
|
|
445
|
+
const probe: AuthoringShadowArmProbe = { record, line: formatShadowArmProbeRecord(record) };
|
|
446
|
+
const observer = shadowArmProbeObserver ?? defaultShadowArmProbeObserver;
|
|
447
|
+
observer(probe, authorRunId);
|
|
448
|
+
return probe;
|
|
449
|
+
}
|
|
450
|
+
|
|
451
|
+
/** 관측 접합점 갈아끼우기(시험 전용) — 인자 없이 부르면 생산 기본 관측자로 복원한다. */
|
|
452
|
+
export function _setShadowArmProbeObserverForTesting(
|
|
453
|
+
observer?: (probe: AuthoringShadowArmProbe, authorRunId: string) => void,
|
|
454
|
+
): void {
|
|
455
|
+
shadowArmProbeObserver = observer;
|
|
456
|
+
}
|
|
457
|
+
|
|
406
458
|
export type GoalFileLintLevel = 'ERROR' | 'WARN';
|
|
407
459
|
|
|
408
460
|
export type GoalFileLintTag = 'canonical-structure' | 'evidence-section' | 'boundary-size' | 'launch-branch' | 'unanswered-clarification' | 'shell-damage' | 'traced-path' | 'traced-path-new' | 'grounding-evidence' | 'empty-result-population' | 'decision-signal-numeric-source' | 'decision-signal-numeric-coverage' | 'decision-signal-proxy-expectation' | 'out-of-target-requirement' | 'heading-form-marker' | 'blanket-invariant' | 'self-question-subject' | 'artifact-launch-declaration' | 'all-negative-signals' | 'unreadable-signals' | 'alternative-signals' | 'count-observation' | 'identifier-name-observation' | 'self-reported-observation' | 'default-invocation-observation' | 'release-note';
|
|
@@ -2972,7 +3024,17 @@ export function readVerificationMenuDocs(root: string | undefined): { menu: stri
|
|
|
2972
3024
|
return { menu: read(VERIFICATION_MENU_DOC), catalog: read(MOCK_CATALOG_DOC) };
|
|
2973
3025
|
}
|
|
2974
3026
|
|
|
2975
|
-
interface CatalogStage {
|
|
3027
|
+
interface CatalogStage {
|
|
3028
|
+
id: string;
|
|
3029
|
+
name: string;
|
|
3030
|
+
universe: string;
|
|
3031
|
+
injection: string;
|
|
3032
|
+
observation: string;
|
|
3033
|
+
run: string;
|
|
3034
|
+
level: InjectionLadderLevel;
|
|
3035
|
+
strong: string[];
|
|
3036
|
+
weak: string[];
|
|
3037
|
+
}
|
|
2976
3038
|
interface MenuRow { method: string; command: string; stages: string }
|
|
2977
3039
|
|
|
2978
3040
|
const CATALOG_STOP_WORDS = new Set(['bun', 'bin', 'elanous', 'elanous.mjs', 'mjs', 'test', 'git', 'grep', 'head', 'json', 'path', 'paths']);
|
|
@@ -2999,8 +3061,10 @@ function parseCatalogStages(catalog: string): CatalogStage[] {
|
|
|
2999
3061
|
const [, id, name] = header as unknown as [string, string, string];
|
|
3000
3062
|
const universe = catalogField(block, '우주');
|
|
3001
3063
|
const behaviour = catalogField(block, '증명하는 동작');
|
|
3064
|
+
const injection = catalogField(block, '무대 세우기');
|
|
3065
|
+
const observation = catalogField(block, '판정');
|
|
3002
3066
|
const run = catalogField(block, '실행');
|
|
3003
|
-
const text = `${name} ${behaviour} ${run}`;
|
|
3067
|
+
const text = `${name} ${behaviour} ${universe} ${injection} ${observation} ${run}`;
|
|
3004
3068
|
const strong = new Set<string>();
|
|
3005
3069
|
const weak = new Set<string>();
|
|
3006
3070
|
for (const span of text.match(/`[^`]+`/gu) ?? []) {
|
|
@@ -3015,7 +3079,8 @@ function parseCatalogStages(catalog: string): CatalogStage[] {
|
|
|
3015
3079
|
if (word.length >= 2 && !CATALOG_KOREAN_STOP_WORDS.has(word)) weak.add(word);
|
|
3016
3080
|
}
|
|
3017
3081
|
for (const word of strong) weak.delete(word);
|
|
3018
|
-
return [{ id, name: name.trim(),
|
|
3082
|
+
return [{ id, name: name.trim(), universe, injection, observation, run,
|
|
3083
|
+
level: ladderLevelForUniverse(universe), strong: [...strong], weak: [...weak] }];
|
|
3019
3084
|
});
|
|
3020
3085
|
}
|
|
3021
3086
|
|
|
@@ -3095,6 +3160,10 @@ export function authorVerificationPlan(input: VerificationPlanInput): Verificati
|
|
|
3095
3160
|
const operationalNote = operational
|
|
3096
3161
|
? ` · 운영 실물: 메뉴 «${operationalRow?.method ?? '운영 실물 로그 관측'}» — 운영 데이터가 입력일 때만${operationalRow ? ` (${oneLine(operationalRow.command.replace(/`/gu, ''), 120)})` : ''}`
|
|
3097
3162
|
: '';
|
|
3163
|
+
const completionEvidenceCommandValue = /^\s*(?:[-*]\s*)?완료\s*경계\s*증거\s*명령\s*:\s*(.+?)\s*$/mu.exec(ask)?.[1];
|
|
3164
|
+
const completionEvidenceCommand = completionEvidenceCommandValue
|
|
3165
|
+
? validateGoalDoneEvidenceCommand(completionEvidenceCommandValue).command
|
|
3166
|
+
: undefined;
|
|
3098
3167
|
const testFile = firstTestTarget(input.targetPaths);
|
|
3099
3168
|
const cellId = ask.match(/\b[A-Z][A-Z0-9]+(?:-[A-Z0-9]+)+\b/u)?.[0];
|
|
3100
3169
|
const behaviour = oneLine((input.behaviour || '').split(/\s*(?:판정선|판정\s*신호)\s*(?:\(반증\))?\s*:/u)[0] || 'ask 에서 동작 문장을 고르지 못했다 — 사람이 ① 을 채운다', 120);
|
|
@@ -3109,7 +3178,7 @@ export function authorVerificationPlan(input: VerificationPlanInput): Verificati
|
|
|
3109
3178
|
const row = menuRows.find((candidate) => candidate.stages.includes(best!.stage.id));
|
|
3110
3179
|
const run = /`([^`]+)`/u.exec(best.stage.run)?.[1];
|
|
3111
3180
|
stage = { source: 'catalog', id: best.stage.id, level: best.stage.level };
|
|
3112
|
-
stageLine = `- ② 무대: ${best.stage.id} ${best.stage.name} · ${best.stage.level} (${INJECTION_LADDER[best.stage.level]})${row ? ` · 메뉴: ${row.method}` : ''}${run ? ` · 실행: \`${run}\`` : ''}${operationalNote}`;
|
|
3181
|
+
stageLine = `- ② 무대: ${best.stage.id} ${best.stage.name} · 우주: ${oneLine(best.stage.universe, 90)} · 사건 주입: ${oneLine(best.stage.injection, 120)} · 관측: ${oneLine(best.stage.observation, 120)} · ${best.stage.level} (${INJECTION_LADDER[best.stage.level]})${row ? ` · 메뉴: ${row.method}` : ''}${run ? ` · 실행: \`${run}\`` : ''}${operationalNote}`;
|
|
3113
3182
|
} else {
|
|
3114
3183
|
const screen = /TUI|화면|렌더|위젯|ux-sim|fake-llm|fake-bin|fake-clock|타이머/iu.test(ask);
|
|
3115
3184
|
const level: InjectionLadderLevel = screen ? 'L2' : 'L1';
|
|
@@ -3146,6 +3215,9 @@ export function authorVerificationPlan(input: VerificationPlanInput): Verificati
|
|
|
3146
3215
|
const symbol = wiringSymbol(ask);
|
|
3147
3216
|
const productionPaths = input.targetPaths.filter((path) => !/\.test\./u.test(path) && !/\.md$/u.test(path));
|
|
3148
3217
|
const wiring = `git grep -n -F '${symbol ?? '<새 함수>'}(' HEAD -- ${productionPaths.length ? productionPaths.join(' ') : 'src'}`;
|
|
3218
|
+
const e2 = completionEvidenceCommand
|
|
3219
|
+
? `E2 완료 경계 증거 명령 \`${completionEvidenceCommand}\` 을 origin/main 에서 rc0 확인`
|
|
3220
|
+
: 'E2 완료 경계 증거 명령은 ask에 없거나 유효하지 않아 저작자가 채움';
|
|
3149
3221
|
return {
|
|
3150
3222
|
lines: [
|
|
3151
3223
|
VERIFICATION_PLAN_HEADING,
|
|
@@ -3153,7 +3225,7 @@ export function authorVerificationPlan(input: VerificationPlanInput): Verificati
|
|
|
3153
3225
|
stageLine,
|
|
3154
3226
|
`- ③ 먼저 쓸 시험(RED): \`${testFile}\` › '${testName}' — ① 의 동작이 아직 없어 단언이 실패한다(구현 전에 먼저 쓰고 실패를 확인한다)`,
|
|
3155
3227
|
`- ④ GREEN 뒤 같은 명령: \`${testCommand}\` → 0 fail`,
|
|
3156
|
-
`- ⑤ 생산 진입점 배선(MS-05): \`${wiring}\` — 호출부를 커밋한 뒤 PR head
|
|
3228
|
+
`- ⑤ 생산 진입점 배선(MS-05 · G1 v4): \`${wiring}\` — 호출부를 커밋한 뒤 PR head에서 돌린다 · 정의·주석·시험 행이 아닌 생산 호출 문장 1건 이상(0건만으로 미배선 판정 금지) · E1 착지 뒤 PR head가 main의 조상인지 확인 · ${e2} · E3 생산 진입점 시험 또는 mock 무대 · E4 운영 실물은 필수 아님`,
|
|
3157
3229
|
],
|
|
3158
3230
|
stage,
|
|
3159
3231
|
menuPresent: input.menu !== null,
|
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import { join } from 'node:path';
|
|
2
|
+
import { createGraphUnitResolver } from './graph-unit-resolver.js';
|
|
3
|
+
import { flattenGraphUnits } from './graph-unit-flatten.js';
|
|
4
|
+
import {
|
|
5
|
+
implementLoopUnitEquivalence,
|
|
6
|
+
implementLoopUnitSpec,
|
|
7
|
+
stageUnitSeamsForGraph,
|
|
8
|
+
type ImplementLoopUnitEquivalence,
|
|
9
|
+
type ImplementStageUnitId,
|
|
10
|
+
type ImplementStageUnitSeam,
|
|
11
|
+
} from './graph-templates.js';
|
|
12
|
+
import type { GraphTemplateSpec } from './graph-yaml.js';
|
|
13
|
+
|
|
14
|
+
/** 한 부품이 «실제로» 어느 파일에서 해석됐나 — 원장·관측이 「어느 판의 부품으로 걸었나」를 답한다. */
|
|
15
|
+
export interface ResolvedStageUnit {
|
|
16
|
+
readonly stage: ImplementStageUnitId;
|
|
17
|
+
readonly call: string;
|
|
18
|
+
readonly unitId: string;
|
|
19
|
+
readonly version: number;
|
|
20
|
+
readonly path: string;
|
|
21
|
+
readonly hash: string;
|
|
22
|
+
readonly entry: string;
|
|
23
|
+
readonly nodes: readonly string[];
|
|
24
|
+
readonly exits: readonly string[];
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/** ⛔ 「부품이 없다」와 「부품을 못 읽었다」를 가른다 — 성공이면 reason 은 undefined 다. */
|
|
28
|
+
export interface StageUnitResolution {
|
|
29
|
+
readonly units: readonly ResolvedStageUnit[];
|
|
30
|
+
readonly flattened?: GraphTemplateSpec;
|
|
31
|
+
readonly equivalence?: ImplementLoopUnitEquivalence;
|
|
32
|
+
readonly reason?: string;
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/** ⭐ 하나의 NodeContext — 골·근거·되먹임·예산·체크포인트가 저작→구현으로 «같은 객체»로 흐른다. */
|
|
36
|
+
export interface StageNodeContext {
|
|
37
|
+
readonly goal: {
|
|
38
|
+
readonly goalId?: string;
|
|
39
|
+
readonly goalType?: string;
|
|
40
|
+
readonly graphId: string;
|
|
41
|
+
readonly graphVersion: string;
|
|
42
|
+
};
|
|
43
|
+
readonly grounding: {
|
|
44
|
+
readonly units: readonly ResolvedStageUnit[];
|
|
45
|
+
readonly flattenedNodeCount: number | null;
|
|
46
|
+
/** null 이면 평탄화 자체를 못 했다 — 「불변」으로 읽지 않는다(reason 이 그 자리를 덮는다). */
|
|
47
|
+
readonly equivalence: ImplementLoopUnitEquivalence | null;
|
|
48
|
+
/** 부품 해석은 됐지만 합성 평탄화가 실패한 원인을 보존한다. */
|
|
49
|
+
readonly resolutionReason?: string;
|
|
50
|
+
};
|
|
51
|
+
readonly feedback: { readonly attempts?: number };
|
|
52
|
+
readonly budget: { readonly unitCount: number; readonly visitBudget: number | null };
|
|
53
|
+
readonly checkpoint: { readonly runId: string; readonly round?: number };
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
/** 등록 부품을 graphs/units 에서 `id@version` 으로 해석하고, 합성 선언을 평탄화해 불변식을 값으로 낸다. */
|
|
57
|
+
export function resolveStageUnits(
|
|
58
|
+
seams: readonly ImplementStageUnitSeam[],
|
|
59
|
+
graphsDir: string,
|
|
60
|
+
): StageUnitResolution {
|
|
61
|
+
if (seams.length === 0) return { units: [] };
|
|
62
|
+
// ⛔ 호출자 경로가 곧 탐색 규약이다(graph-unit-resolver: dirname(caller)/units → dirname(caller) → repo/graphs/units).
|
|
63
|
+
const callerPath = join(graphsDir, 'implement-loop.yaml');
|
|
64
|
+
const resolver = createGraphUnitResolver();
|
|
65
|
+
const units: ResolvedStageUnit[] = [];
|
|
66
|
+
try {
|
|
67
|
+
for (const seam of seams) {
|
|
68
|
+
const unit = resolver(seam.call, callerPath);
|
|
69
|
+
// 부품 «단독» 평탄화 — unit 계약(entries·exits·terminal_nodes)이 그 자리에서 성립하는지 검증한다.
|
|
70
|
+
flattenGraphUnits(unit.template, unit.path, resolver);
|
|
71
|
+
units.push({
|
|
72
|
+
stage: seam.stage,
|
|
73
|
+
call: seam.call,
|
|
74
|
+
unitId: unit.template.graphId,
|
|
75
|
+
version: unit.template.version,
|
|
76
|
+
path: unit.path,
|
|
77
|
+
hash: unit.hash,
|
|
78
|
+
entry: seam.entry,
|
|
79
|
+
nodes: seam.nodes,
|
|
80
|
+
exits: unit.template.unit?.exits ?? [],
|
|
81
|
+
});
|
|
82
|
+
}
|
|
83
|
+
const flattened = flattenGraphUnits(
|
|
84
|
+
implementLoopUnitSpec(),
|
|
85
|
+
join(graphsDir, 'self-implement-units.yaml'),
|
|
86
|
+
resolver,
|
|
87
|
+
);
|
|
88
|
+
return { units, flattened, equivalence: implementLoopUnitEquivalence(flattened) };
|
|
89
|
+
} catch (error) {
|
|
90
|
+
return { units, reason: error instanceof Error ? error.message : String(error) };
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
export function buildStageNodeContext(input: {
|
|
95
|
+
readonly resolution: StageUnitResolution;
|
|
96
|
+
readonly graphId: string;
|
|
97
|
+
readonly graphVersion: string;
|
|
98
|
+
readonly runId: string;
|
|
99
|
+
readonly attempts?: number;
|
|
100
|
+
readonly round?: number;
|
|
101
|
+
readonly goalId?: string;
|
|
102
|
+
readonly goalType?: string;
|
|
103
|
+
}): StageNodeContext {
|
|
104
|
+
const { resolution } = input;
|
|
105
|
+
const visitBudget = resolution.flattened === undefined
|
|
106
|
+
? null
|
|
107
|
+
: resolution.flattened.nodes.reduce((total, node) => total + node.maxVisits, 0);
|
|
108
|
+
return {
|
|
109
|
+
goal: {
|
|
110
|
+
...(input.goalId === undefined ? {} : { goalId: input.goalId }),
|
|
111
|
+
...(input.goalType === undefined ? {} : { goalType: input.goalType }),
|
|
112
|
+
graphId: input.graphId,
|
|
113
|
+
graphVersion: input.graphVersion,
|
|
114
|
+
},
|
|
115
|
+
grounding: {
|
|
116
|
+
units: resolution.units,
|
|
117
|
+
flattenedNodeCount: resolution.flattened?.nodes.length ?? null,
|
|
118
|
+
equivalence: resolution.equivalence ?? null,
|
|
119
|
+
...(resolution.reason === undefined ? {} : { resolutionReason: resolution.reason }),
|
|
120
|
+
},
|
|
121
|
+
feedback: input.attempts === undefined ? {} : { attempts: input.attempts },
|
|
122
|
+
budget: { unitCount: resolution.units.length, visitBudget },
|
|
123
|
+
checkpoint: { runId: input.runId, ...(input.round === undefined ? {} : { round: input.round }) },
|
|
124
|
+
};
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
/** 원장 관측 payload — ⛔ 큰 구조(평탄화 그래프 전체)를 싣지 않고 «판정에 쓰는 값»만 싣는다. */
|
|
128
|
+
export function stageNodeContextObservation(context: StageNodeContext): Record<string, unknown> {
|
|
129
|
+
const equivalence = context.grounding.equivalence;
|
|
130
|
+
return {
|
|
131
|
+
graphId: context.goal.graphId,
|
|
132
|
+
graphVersion: context.goal.graphVersion,
|
|
133
|
+
runId: context.checkpoint.runId,
|
|
134
|
+
...(context.checkpoint.round === undefined ? {} : { round: context.checkpoint.round }),
|
|
135
|
+
...(context.grounding.resolutionReason === undefined ? {} : { resolutionReason: context.grounding.resolutionReason }),
|
|
136
|
+
units: context.grounding.units.map((unit) => ({
|
|
137
|
+
stage: unit.stage, call: unit.call, unitId: unit.unitId, version: unit.version, hash: unit.hash,
|
|
138
|
+
entry: unit.entry, nodes: unit.nodes, exits: unit.exits,
|
|
139
|
+
})),
|
|
140
|
+
flattenedNodeCount: context.grounding.flattenedNodeCount,
|
|
141
|
+
kindMismatches: equivalence?.kindMismatches.length ?? null,
|
|
142
|
+
missingEdges: equivalence?.missingEdges.length ?? null,
|
|
143
|
+
extraEdges: equivalence?.extraEdges.length ?? null,
|
|
144
|
+
visitBudget: context.budget.visitBudget,
|
|
145
|
+
};
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/** 라운드마다 같은 부품이 «여전히» 그 파일·그 판인가 — 파일이 도는 중에 바뀌면 걸음이 신원과 갈린다. */
|
|
149
|
+
export function stageUnitDrift(
|
|
150
|
+
units: readonly ResolvedStageUnit[],
|
|
151
|
+
graphsDir: string,
|
|
152
|
+
): { readonly missing: readonly string[]; readonly changed: readonly string[] } {
|
|
153
|
+
if (units.length === 0) return { missing: [], changed: [] };
|
|
154
|
+
const callerPath = join(graphsDir, 'implement-loop.yaml');
|
|
155
|
+
const resolver = createGraphUnitResolver();
|
|
156
|
+
const missing: string[] = [];
|
|
157
|
+
const changed: string[] = [];
|
|
158
|
+
for (const unit of units) {
|
|
159
|
+
try {
|
|
160
|
+
const current = resolver(unit.call, callerPath);
|
|
161
|
+
if (current.hash !== unit.hash) changed.push(unit.call);
|
|
162
|
+
} catch {
|
|
163
|
+
missing.push(unit.call);
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
return { missing, changed };
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
/** 그래프의 단계 부품을 «생산 진입점 문장» 하나로 — orchestrator 가 이 함수를 부른다. */
|
|
170
|
+
export function resolveGraphStageUnits(graphId: string, graphsDir: string): StageUnitResolution {
|
|
171
|
+
return resolveStageUnits(stageUnitSeamsForGraph(graphId), graphsDir);
|
|
172
|
+
}
|
|
@@ -5,7 +5,7 @@ import { fileURLToPath } from 'node:url';
|
|
|
5
5
|
import ts from 'typescript';
|
|
6
6
|
import { GOAL_TYPES, type GoalType } from './goal-author.js';
|
|
7
7
|
import type { GraphRunContractSpec } from './graph-run-contract.js';
|
|
8
|
-
import { edgeMapOf, loadGraphTemplates, type GraphNodeContract, type GraphNodeKind, type GraphNodeSpec, type GraphTemplateSpec } from './graph-yaml.js';
|
|
8
|
+
import { edgeMapOf, loadGraphTemplates, type GraphEdgeSpec, type GraphNodeContract, type GraphNodeKind, type GraphNodeSpec, type GraphTemplateSpec } from './graph-yaml.js';
|
|
9
9
|
|
|
10
10
|
/** ⭐ RFC §5 «3단계» — 템플릿을 «데이터»로 둔다(RFC §4.1 어휘).
|
|
11
11
|
*
|
|
@@ -96,6 +96,167 @@ const RESEARCH_LOOP: GraphTemplate = {
|
|
|
96
96
|
},
|
|
97
97
|
};
|
|
98
98
|
|
|
99
|
+
/** ⭐ SELFIMPL-NODE-SEAMS-BACK — 한 NodeContext 가 저작→구현으로 흐르는 다섯 입력 칸.
|
|
100
|
+
*
|
|
101
|
+
* ⛔ 이 다섯은 «부품의 계약»이다 — units/<stage>/<stage>.yaml 의 unit.inputs 와 글자 그대로 같아야 한다
|
|
102
|
+
* (flattenGraphUnits 가 호출 노드의 contract 와 unit.inputs 를 «길이·원소» 둘 다로 대조한다). */
|
|
103
|
+
export const NODE_CONTEXT_INPUTS = ['goal', 'context', 'feedback', 'budget', 'checkpoint'] as const;
|
|
104
|
+
|
|
105
|
+
/** 등록 부품의 이름 — 요구가 이름으로 든 다섯 단계(구현·gate·리뷰·git·착지). */
|
|
106
|
+
export type ImplementStageUnitId = 'implement' | 'gate' | 'review' | 'git' | 'landing';
|
|
107
|
+
|
|
108
|
+
export interface ImplementStageUnitExit {
|
|
109
|
+
/** unit.exits 의 이름 — flattenGraphUnits 가 호출 간선 map 의 키와 «정확히» 대조한다. */
|
|
110
|
+
readonly exit: string;
|
|
111
|
+
/** 그 출구가 향하는 «파이프라인 노드» — PIPELINE_EDGES_BY_NODE 의 목적지에서만 고른다. */
|
|
112
|
+
readonly to: string;
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
export interface ImplementStageUnitSeam {
|
|
116
|
+
readonly stage: ImplementStageUnitId;
|
|
117
|
+
/** `id@version` — createGraphUnitResolver 규약 그대로. */
|
|
118
|
+
readonly call: string;
|
|
119
|
+
/** 그 부품이 소유한 파이프라인 노드(PIPELINE_EDGES_BY_NODE 의 키). */
|
|
120
|
+
readonly nodes: readonly string[];
|
|
121
|
+
/** 이 부품에서 처음 밟는 노드(= 호출 노드의 call_entry). */
|
|
122
|
+
readonly entry: string;
|
|
123
|
+
/** 합성 호출되는 단계만 계약을 갖는다; landing은 종결 노드라 호출 계약이 없다. */
|
|
124
|
+
readonly outputs?: readonly string[];
|
|
125
|
+
readonly exits?: readonly ImplementStageUnitExit[];
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
/** ⛔ 출처는 «둘»이다 — kind 는 IMPLEMENT_LOOP, edges 는 PIPELINE_EDGES_BY_NODE. 여기서 새 어휘를 만들지 않는다.
|
|
129
|
+
*
|
|
130
|
+
* 📌 착지(landing) 부품은 합성 그래프에서 «평범한 merge 노드»로 남는다: flattenGraphUnits 는 호출 노드마다
|
|
131
|
+
* 나가는 outcome map 을 요구하는데 종결 노드(merge)에는 나가는 간선이 없다 — 즉 «종결 노드는 호출일 수 없다».
|
|
132
|
+
* 그래서 landing 은 등록·해석·단독 평탄화(계약 검증)로 생산 경로를 지나고, 합성 그래프의 종결은 merge 가 맡는다. */
|
|
133
|
+
export const IMPLEMENT_STAGE_UNITS: readonly ImplementStageUnitSeam[] = [
|
|
134
|
+
{ stage: 'implement', call: 'implement@1', nodes: ['implement'], entry: 'implement',
|
|
135
|
+
outputs: ['diff', 'evidence', 'result'],
|
|
136
|
+
exits: [{ exit: 'done', to: 'gate' }, { exit: 'rework', to: 'gate' }, { exit: 'failed', to: 'gate' }] },
|
|
137
|
+
{ stage: 'gate', call: 'gate@1', nodes: ['gate'], entry: 'gate',
|
|
138
|
+
outputs: ['gate-verdict', 'evidence'],
|
|
139
|
+
exits: [{ exit: 'pass', to: 'review' }, { exit: 'fail', to: 'rework' },
|
|
140
|
+
{ exit: 'sync', to: 'main-sync' }, { exit: 'open', to: 'open-pr' }] },
|
|
141
|
+
{ stage: 'review', call: 'review@1', nodes: ['review'], entry: 'review',
|
|
142
|
+
outputs: ['verdict', 'must-fix', 'evidence'],
|
|
143
|
+
exits: [{ exit: 'pass', to: 'main-sync' }, { exit: 'fail', to: 'rework' },
|
|
144
|
+
{ exit: 'sync', to: 'main-sync' }, { exit: 'open', to: 'open-pr' }] },
|
|
145
|
+
{ stage: 'git', call: 'git@1', nodes: ['main-sync', 'open-pr'], entry: 'main-sync',
|
|
146
|
+
outputs: ['commit', 'pr-number', 'evidence'],
|
|
147
|
+
exits: [{ exit: 'to-regate', to: 'regate' }, { exit: 'to-open-pr', to: 'open-pr' },
|
|
148
|
+
{ exit: 'to-merge', to: 'merge' }] },
|
|
149
|
+
{ stage: 'landing', call: 'landing@1', nodes: ['merge'], entry: 'merge',
|
|
150
|
+
// 합성 그래프의 merge는 종결 노드라 landing 부품의 종료 매핑을 만들지 않는다.
|
|
151
|
+
},
|
|
152
|
+
];
|
|
153
|
+
|
|
154
|
+
/** 그 그래프가 «부품으로 떼어 놓은» 단계 목록 — self-implement 밖의 그래프는 빈 배열(동작 불변). */
|
|
155
|
+
export function stageUnitSeamsForGraph(graphId: string): readonly ImplementStageUnitSeam[] {
|
|
156
|
+
return graphId === PIPELINE_GRAPH_ID ? IMPLEMENT_STAGE_UNITS : [];
|
|
157
|
+
}
|
|
158
|
+
|
|
159
|
+
/** 파이프라인 노드의 kind — IMPLEMENT_LOOP 과 «같은 출처»에서 읽는다(두 벌로 갈리지 않게). */
|
|
160
|
+
export function pipelineNodeKind(nodeId: string): string | undefined {
|
|
161
|
+
return IMPLEMENT_LOOP.nodes.find((node) => node.nodeId === nodeId)?.kind;
|
|
162
|
+
}
|
|
163
|
+
|
|
164
|
+
const UNIT_CALL_CONTRACT = (outputs: readonly string[]): GraphNodeContract => ({
|
|
165
|
+
inputs: [...NODE_CONTEXT_INPUTS],
|
|
166
|
+
tools: 'none',
|
|
167
|
+
outputs: [...outputs],
|
|
168
|
+
});
|
|
169
|
+
|
|
170
|
+
/** ⭐ 부품 호출로 «재조립한» self-implement 선언 — 실행 그래프가 아니라 «정적 검증용 합성»이다.
|
|
171
|
+
*
|
|
172
|
+
* ⛔ 실행 그래프(graphs/implement-loop.yaml)는 건드리지 않는다(보존 계약: 도는 동작 불변).
|
|
173
|
+
* 이 spec 은 flattenGraphUnits 의 정적 검증(entry/exit 매핑·inputs/outputs 계약·이름 충돌·순환/깊이≤3)을
|
|
174
|
+
* «실제 등록 부품»에 걸어, 부품 분해가 기존 kind+edges 를 그대로 재현함을 값으로 낸다. */
|
|
175
|
+
export function implementLoopUnitSpec(): GraphTemplateSpec {
|
|
176
|
+
const call = (seam: ImplementStageUnitSeam, callEntry?: string): GraphNodeSpec => ({
|
|
177
|
+
nodeId: callEntry ?? seam.entry,
|
|
178
|
+
kind: 'subgraph',
|
|
179
|
+
recipe: 'none',
|
|
180
|
+
maxVisits: 1,
|
|
181
|
+
call: seam.call,
|
|
182
|
+
...(callEntry === undefined ? {} : { callEntry }),
|
|
183
|
+
contract: UNIT_CALL_CONTRACT(seam.outputs ?? []),
|
|
184
|
+
});
|
|
185
|
+
const seamOf = (stage: ImplementStageUnitId): ImplementStageUnitSeam =>
|
|
186
|
+
IMPLEMENT_STAGE_UNITS.find((seam) => seam.stage === stage)!;
|
|
187
|
+
const outcome = (stage: ImplementStageUnitId, from: string): GraphEdgeSpec => ({
|
|
188
|
+
from,
|
|
189
|
+
on: 'outcome',
|
|
190
|
+
map: Object.fromEntries((seamOf(stage).exits ?? []).map(({ exit, to }) => [exit, to])),
|
|
191
|
+
});
|
|
192
|
+
const nodes: GraphNodeSpec[] = [
|
|
193
|
+
call(seamOf('implement')),
|
|
194
|
+
call(seamOf('gate')),
|
|
195
|
+
call(seamOf('review')),
|
|
196
|
+
call(seamOf('git'), 'main-sync'),
|
|
197
|
+
call(seamOf('git'), 'open-pr'),
|
|
198
|
+
{ nodeId: 'rework', kind: pipelineNodeKind('rework')!, recipe: 'none', maxVisits: 6 },
|
|
199
|
+
{ nodeId: 'regate', kind: pipelineNodeKind('regate')!, recipe: 'none', maxVisits: 2 },
|
|
200
|
+
{ nodeId: 'merge', kind: pipelineNodeKind('merge')!, recipe: 'none', maxVisits: 1 },
|
|
201
|
+
];
|
|
202
|
+
const edges: GraphEdgeSpec[] = [
|
|
203
|
+
outcome('implement', 'implement'),
|
|
204
|
+
outcome('gate', 'gate'),
|
|
205
|
+
outcome('review', 'review'),
|
|
206
|
+
outcome('git', 'main-sync'),
|
|
207
|
+
outcome('git', 'open-pr'),
|
|
208
|
+
{ from: 'rework', to: 'implement' },
|
|
209
|
+
{ from: 'regate', to: 'open-pr' },
|
|
210
|
+
];
|
|
211
|
+
return {
|
|
212
|
+
graphId: PIPELINE_GRAPH_ID,
|
|
213
|
+
version: 1,
|
|
214
|
+
entryNode: 'implement',
|
|
215
|
+
terminalNodes: ['merge'],
|
|
216
|
+
nodes,
|
|
217
|
+
edges,
|
|
218
|
+
};
|
|
219
|
+
}
|
|
220
|
+
|
|
221
|
+
export interface ImplementLoopUnitEquivalence {
|
|
222
|
+
/** 파이프라인 노드마다 «합성 그래프의 kind» 가 IMPLEMENT_LOOP 과 다른 것. */
|
|
223
|
+
readonly kindMismatches: readonly { node: string; expected: string; actual: string | undefined }[];
|
|
224
|
+
/** PIPELINE_EDGES_BY_NODE 에 있는데 평탄화 결과에 «없는» 간선. */
|
|
225
|
+
readonly missingEdges: readonly string[];
|
|
226
|
+
/** 평탄화 결과에 있는데 PIPELINE_EDGES_BY_NODE 에 «없는» 간선 — 0 이어야 동작 불변이다. */
|
|
227
|
+
readonly extraEdges: readonly string[];
|
|
228
|
+
}
|
|
229
|
+
|
|
230
|
+
/** flattenGraphUnits 는 호출 노드의 자식을 `${callNodeId}__${nodeId}` 로 접두한다 — 그 접두를 벗겨 되돌린다. */
|
|
231
|
+
export function normalizeFlattenedNodeId(nodeId: string): string {
|
|
232
|
+
const at = nodeId.lastIndexOf('__');
|
|
233
|
+
return at < 0 ? nodeId : nodeId.slice(at + 2);
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
/** ⭐ 판정선: 평탄화 결과가 기존 kind+edges 와 «같은가»를 세 방향으로 낸다. */
|
|
237
|
+
export function implementLoopUnitEquivalence(flattened: GraphTemplateSpec): ImplementLoopUnitEquivalence {
|
|
238
|
+
const kindMismatches: { node: string; expected: string; actual: string | undefined }[] = [];
|
|
239
|
+
const actualKinds = new Map<string, string>();
|
|
240
|
+
for (const node of flattened.nodes) actualKinds.set(normalizeFlattenedNodeId(node.nodeId), node.kind);
|
|
241
|
+
for (const nodeId of Object.keys(PIPELINE_EDGES_BY_NODE)) {
|
|
242
|
+
const expected = pipelineNodeKind(nodeId);
|
|
243
|
+
const actual = actualKinds.get(nodeId);
|
|
244
|
+
if (expected !== undefined && actual !== expected) kindMismatches.push({ node: nodeId, expected, actual });
|
|
245
|
+
}
|
|
246
|
+
const edgesOf = (map: Readonly<Record<string, readonly string[]>>): Set<string> =>
|
|
247
|
+
new Set(Object.entries(map).flatMap(([from, targets]) => targets.map((to) => `${from}->${to}`)));
|
|
248
|
+
const normalizedFlattened = Object.fromEntries(
|
|
249
|
+
Object.entries(edgeMapOf(flattened)).map(([from, targets]) => [normalizeFlattenedNodeId(from), targets.map(normalizeFlattenedNodeId)]),
|
|
250
|
+
);
|
|
251
|
+
const actual = edgesOf(normalizedFlattened);
|
|
252
|
+
const expected = edgesOf(PIPELINE_EDGES_BY_NODE as unknown as Record<string, readonly string[]>);
|
|
253
|
+
return {
|
|
254
|
+
kindMismatches,
|
|
255
|
+
missingEdges: [...expected].filter((edge) => !actual.has(edge)).sort(),
|
|
256
|
+
extraEdges: [...actual].filter((edge) => !expected.has(edge)).sort(),
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
|
|
99
260
|
/** ⭐⭐ RFC §5 «배선» — 선언의 «출처»가 YAML 이다(대표 지시: TypeScript 는 저장에서 빠진다).
|
|
100
261
|
*
|
|
101
262
|
* ⛔ 이 상수들(IMPLEMENT_LOOP·RESEARCH_LOOP)은 «폴백»이다 — YAML 을 못 읽었을 때만 쓴다.
|