@tea-agent/loop-agent 0.39.0-next.3 → 0.39.0-next.31

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 (238) hide show
  1. package/AGENTS.md +4 -1
  2. package/CHANGELOG.md +270 -65
  3. package/README.md +11 -5
  4. package/bin/loop-agent.js +7 -3
  5. package/dist/application/dag/generate-task-dag.js +9 -0
  6. package/dist/application/task-lifecycle/advance.js +4 -0
  7. package/dist/build-stamp.json +3 -3
  8. package/dist/cli/command-definitions.js +16 -5
  9. package/dist/cli/program.js +16 -2
  10. package/dist/cli/update/notifier.js +2 -2
  11. package/dist/cli.js +2 -1
  12. package/dist/commands/dag-rerun.js +55 -1
  13. package/dist/commands/init-model-catalog.js +464 -0
  14. package/dist/commands/init-upgrade.js +265 -97
  15. package/dist/commands/init.js +428 -27
  16. package/dist/commands/inspect-next.js +8 -0
  17. package/dist/commands/task-advance.js +31 -0
  18. package/dist/executors/dag-pi-executor.js +118 -14
  19. package/dist/executors/pi-event-serializer.js +42 -1
  20. package/dist/executors/pi-executor.js +51 -0
  21. package/dist/executors/pi-extension-resolver.js +233 -0
  22. package/dist/executors/pi-playwright-cli-tool.js +51 -12
  23. package/dist/executors/pi-sdk-executor.js +187 -59
  24. package/dist/executors/shell-executor.js +533 -29
  25. package/dist/executors/shell-write-guard.js +7 -0
  26. package/dist/shared/dag-prompt-override.js +28 -0
  27. package/dist/shared/operator/capabilities.js +181 -27
  28. package/dist/shared/playwright-cli-command-policy.js +15 -0
  29. package/dist/shared/update/console-notifier.js +100 -0
  30. package/dist/{cli → shared}/update/npm-client.js +41 -8
  31. package/dist/{cli → shared}/update/state.js +41 -13
  32. package/dist/task/config-types.js +22 -0
  33. package/dist/task/contract/constants.js +1 -0
  34. package/dist/task/contract/diff.js +26 -0
  35. package/dist/task/contract/project.js +5 -0
  36. package/dist/task/contract/schema.js +6 -1
  37. package/dist/task/source-prepare/build-draft.js +15 -0
  38. package/dist/task/source-prepare/parse-intent.js +24 -4
  39. package/dist/worker/cli.js +31 -1
  40. package/dist/worker/console/chat/deferred-turn.js +91 -0
  41. package/dist/worker/console/chat/mcp-inventory.js +221 -0
  42. package/dist/worker/console/chat/pi-runtime.js +165 -83
  43. package/dist/worker/console/chat/repo-walk.js +10 -1
  44. package/dist/worker/console/chat/routes.js +478 -55
  45. package/dist/worker/console/chat/semantic-activity.js +20 -8
  46. package/dist/worker/console/chat/session-store.js +146 -2
  47. package/dist/worker/console/chat/turn-process.js +17 -30
  48. package/dist/worker/console/dag-execution-receipt.js +33 -0
  49. package/dist/worker/console/harness-pi-model-matrix.js +137 -0
  50. package/dist/worker/console/operator-actions.js +244 -4
  51. package/dist/worker/console/operator-user-error.js +20 -1
  52. package/dist/worker/console/pi-readiness.js +12 -5
  53. package/dist/worker/console/recovery-cta.js +4 -4
  54. package/dist/worker/console/recovery-error-copy.js +4 -4
  55. package/dist/worker/console/routes.js +43 -2
  56. package/dist/worker/console/security.js +83 -10
  57. package/dist/worker/console/server.js +42 -6
  58. package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-DSvF6RXQ.js → abnfDiagram-N423BO3Z-gauhD9kD.js} +1 -1
  59. package/dist/worker/console/static/assets/{arc-DuI4ogtJ.js → arc-pm3c2Rsl.js} +1 -1
  60. package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-DdBbgD4y.js → architectureDiagram-T3A2C74G-D_JAg3wH.js} +1 -1
  61. package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-xQC2HELm.js → blockDiagram-VBNYF7ZC-Dk7-ex52.js} +1 -1
  62. package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DPMSgwIZ.js → c4Diagram-5PPSVZJV-Uval9oRI.js} +1 -1
  63. package/dist/worker/console/static/assets/channel-CVrnUdZl.js +1 -0
  64. package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-WTEKTxin.js → chunk-2GRJ4B5K-BSYjHs-v.js} +1 -1
  65. package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-B6vZ0Pv_.js → chunk-2Q5K7J3B-KGUuBXI8.js} +1 -1
  66. package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BrerNAix.js → chunk-5RXB4S5H-JqAtxD9N.js} +1 -1
  67. package/dist/worker/console/static/assets/{chunk-5VM5RSS4-D_ch2aaI.js → chunk-5VM5RSS4-D6EJOVQK.js} +1 -1
  68. package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-VvfacNrq.js → chunk-6Q2QTUOP-B1JriSjm.js} +1 -1
  69. package/dist/worker/console/static/assets/{chunk-GF5L2VYU-B-uGFIg2.js → chunk-GF5L2VYU-D62b96Jd.js} +1 -1
  70. package/dist/worker/console/static/assets/{chunk-JWPE2WC7-BlysCtod.js → chunk-JWPE2WC7-BsNKEC_r.js} +1 -1
  71. package/dist/worker/console/static/assets/{chunk-KBJHAD2P-BjAUAfcT.js → chunk-KBJHAD2P-B56v6-ZP.js} +1 -1
  72. package/dist/worker/console/static/assets/{chunk-RYQCIY6F-BeZnBmb-.js → chunk-RYQCIY6F-D2KPnd8K.js} +1 -1
  73. package/dist/worker/console/static/assets/{chunk-XXDRQBXY-Bbfe3UJG.js → chunk-XXDRQBXY-kzKSCaaL.js} +1 -1
  74. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-aX91WTya.js +1 -0
  75. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-aX91WTya.js +1 -0
  76. package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-BKJQnYVM.js → cose-bilkent-JH36ORCC-C6N6KNJd.js} +1 -1
  77. package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-B1wtI3hU.js → cynefin-VYW2F7L2-DiyymT2D.js} +1 -1
  78. package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-DCF6DBSu.js → cynefinDiagram-MW4NZA55-BeKAXvf3.js} +1 -1
  79. package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-BJyNGRlP.js → dagre-VZM6K2ZE-TkIdXfPF.js} +1 -1
  80. package/dist/worker/console/static/assets/{diagram-7IWD3JNH-B7j1-VsZ.js → diagram-7IWD3JNH-BFmSG3ks.js} +1 -1
  81. package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-BREJ140a.js → diagram-B4RE2ZJO-DqpJT2Fs.js} +1 -1
  82. package/dist/worker/console/static/assets/{diagram-LBJQPF4R-CDPHmHGH.js → diagram-LBJQPF4R-r5ATN43t.js} +1 -1
  83. package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BtZLrez1.js → diagram-Q27KOJAE-DEcSCMuR.js} +1 -1
  84. package/dist/worker/console/static/assets/{diagram-UB23O5K3-mzybu8oU.js → diagram-UB23O5K3-VOvYRLVc.js} +1 -1
  85. package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-Dk3I2uO6.js → ebnfDiagram-BXEA7PRR-D7f4Cb1u.js} +1 -1
  86. package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-BT97u_tQ.js → erDiagram-JOGREHBK-ziUf3U0G.js} +1 -1
  87. package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-CMOtYzui.js → flowDiagram-UKHOOZJN-BoRdQ-1y.js} +1 -1
  88. package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-DiNydkuY.js → ganttDiagram-PKOTCBZU-B1-GncNm.js} +1 -1
  89. package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Cwt6fLkl.js → gitGraphDiagram-DS77QQ5N-CTW-ph8W.js} +1 -1
  90. package/dist/worker/console/static/assets/index-C8rOIAJr.css +1 -0
  91. package/dist/worker/console/static/assets/index-DEbyrEfW.js +404 -0
  92. package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-AsGIGKKB.js → infoDiagram-6WML65LV-BFA337tZ.js} +1 -1
  93. package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-BL8ITZh3.js → ishikawaDiagram-WSZJBQD7-BtEujgRR.js} +1 -1
  94. package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-VPKAUX8M.js → journeyDiagram-NVQOT4AX-C8ZwD2Jp.js} +1 -1
  95. package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BL56hfGp.js → kanban-definition-27J2QSJJ-Ck-z8B11.js} +1 -1
  96. package/dist/worker/console/static/assets/{linear-BmSG3nIZ.js → linear-CAyXjQjN.js} +1 -1
  97. package/dist/worker/console/static/assets/{mermaid.core-DWGK9kwP.js → mermaid.core-CcWKn6tS.js} +5 -5
  98. package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS--vvKLjo0.js → mindmap-definition-FAOFIHXS-C2NuDO7E.js} +1 -1
  99. package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-B41mxb2-.js → pegDiagram-VL7TDLO6-BFub3PDz.js} +1 -1
  100. package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-DTlu77sw.js → pieDiagram-7S7Q4E2Y-BJx5THZ5.js} +1 -1
  101. package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-Bk5A7alv.js → quadrantDiagram-CIZ2JOQS-DhalkDWV.js} +1 -1
  102. package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Csf9jzQy.js → railroadDiagram-AXF67PYL-CVcBM36o.js} +1 -1
  103. package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-CeptoSNx.js → requirementDiagram-LRYGKXZP-D_vy4n0w.js} +1 -1
  104. package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-A-DLCLer.js → sankeyDiagram-W5VNT64P-DGYdJL1D.js} +1 -1
  105. package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-22VbPdOI.js → sequenceDiagram-SI44F4Z6-C1xJFg3k.js} +1 -1
  106. package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-DWvAyBC9.js → sizeCapture-X5ZJPWSS-D_Fc43df.js} +1 -1
  107. package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-qICZ75yT.js → stateDiagram-OKZ733FA-BhGbIjbu.js} +1 -1
  108. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DUt1lyFL.js +1 -0
  109. package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-xi7lcMyp.js → swimlanes-SLNWSIFB-DVkNcO-V.js} +2 -2
  110. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-BM6SGr7j.js +8 -0
  111. package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-Bu6Nl6O2.js → timeline-definition-Z64GVDOM-BQU9ufV0.js} +1 -1
  112. package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-BzMz4Bn9.js → vennDiagram-T6HMQDX7-BCQhRmYB.js} +1 -1
  113. package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CxaJnzc5.js → wardleyDiagram-T6FBY63Y-DWerOyHO.js} +1 -1
  114. package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-5JK-omQK.js → xychartDiagram-ELKLHX3M-DxLeebQU.js} +1 -1
  115. package/dist/worker/console/static/index.html +2 -2
  116. package/dist/worker/console/static-src/app/console-types.js +39 -0
  117. package/dist/worker/console/static-src/app/useOperatorActions.js +1 -1
  118. package/dist/worker/console/static-src/app/useRecoveryActions.js +2 -2
  119. package/dist/worker/console/static-src/operator-chat/chat-sse-events.js +82 -22
  120. package/dist/worker/console/static-src/operator-chat/mutation-gate.js +45 -0
  121. package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +328 -0
  122. package/dist/worker/console/static-src/operator-chat/resource-diagnostics.js +204 -0
  123. package/dist/worker/console/static-src/operator-chat/turn-stream-controller.js +8 -1
  124. package/dist/worker/console/static-src/operator-chat/turn-submission.js +42 -0
  125. package/dist/worker/console/static-src/operator-chat/useChatSessions.js +18 -0
  126. package/dist/worker/console/static-src/operator-chat/useChatStream.js +216 -10
  127. package/dist/worker/console/static-src/operator-chat/useChatThread.js +50 -22
  128. package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +26 -1
  129. package/dist/worker/loop-agent/loop-agent-client.js +7 -3
  130. package/dist/worker/observe/node-input.js +74 -3
  131. package/dist/worker/observe/node-process.js +377 -0
  132. package/dist/worker/observe/routes.js +36 -3
  133. package/dist/worker/observe/shell-handler-keys.js +34 -0
  134. package/dist/worker/observe/static/api.js +66 -0
  135. package/dist/worker/observe/static/constants.js +8 -1
  136. package/dist/worker/observe/static/dag-history-labels.js +4 -0
  137. package/dist/worker/observe/static/format.js +23 -0
  138. package/dist/worker/observe/static/markdown-render.js +20 -1
  139. package/dist/worker/observe/static/operator-chrome.js +4 -0
  140. package/dist/worker/observe/static/state.js +13 -2
  141. package/dist/worker/observe/static/styles.css +73 -0
  142. package/dist/worker/observe/static/views/dag-inspector.js +612 -8
  143. package/dist/worker/observe/static/views/dag.js +8 -1
  144. package/dist/worker/observe/static/views/failures.js +5 -2
  145. package/dist/worker/observe/static/views/session-timeline.js +78 -9
  146. package/dist/workflows/dag/backend-test-case-coverage-analysis.js +827 -53
  147. package/dist/workflows/dag/backend-test-case-manifest.js +4 -0
  148. package/dist/workflows/dag/backend-test-execution-contract.js +18 -9
  149. package/dist/workflows/dag/backend-test-gap-fill.js +205 -0
  150. package/dist/workflows/dag/backend-test-intake-context.js +32 -0
  151. package/dist/workflows/dag/backend-test-layout.js +133 -0
  152. package/dist/workflows/dag/backend-test-markdown-workflow.js +167 -32
  153. package/dist/workflows/dag/backend-test-module-stem.js +5 -0
  154. package/dist/workflows/dag/backend-test-pytest-collection.js +368 -33
  155. package/dist/workflows/dag/backend-test-result-contract.js +1 -1
  156. package/dist/workflows/dag/backend-test-scenario-param.js +884 -140
  157. package/dist/workflows/dag/backend-test-scenario-partitions.js +321 -0
  158. package/dist/workflows/dag/backend-test-writer-completeness.js +100 -56
  159. package/dist/workflows/dag/contract-output-registry.js +15 -0
  160. package/dist/workflows/dag/contract-validator-registrations.js +3 -1
  161. package/dist/workflows/dag/convergence/controller.js +141 -0
  162. package/dist/workflows/dag/dynamic-runtime/map.js +24 -8
  163. package/dist/workflows/dag/dynamic-runtime/shared.js +1 -1
  164. package/dist/workflows/dag/failure-category.js +12 -0
  165. package/dist/workflows/dag/frontend-implementation-contract.js +493 -2
  166. package/dist/workflows/dag/frontend-plan-render.js +90 -0
  167. package/dist/workflows/dag/frontend-prewrite-gate.js +221 -31
  168. package/dist/workflows/dag/frontend-repair.js +14 -0
  169. package/dist/workflows/dag/frontend-risk.js +15 -2
  170. package/dist/workflows/dag/frontend-test-case-checklist.js +26 -2
  171. package/dist/workflows/dag/frontend-test-case-manifest.js +5 -0
  172. package/dist/workflows/dag/frontend-test-case-quality.js +5 -13
  173. package/dist/workflows/dag/frontend-test-environment-probe.js +227 -0
  174. package/dist/workflows/dag/frontend-test-markdown.js +61 -0
  175. package/dist/workflows/dag/frontend-test-result-contract.js +160 -28
  176. package/dist/workflows/dag/frontend-test-standard-scenarios.js +68 -0
  177. package/dist/workflows/dag/frontend-verification-trace.js +29 -4
  178. package/dist/workflows/dag/init-hybrid.js +895 -127
  179. package/dist/workflows/dag/node-execution.js +194 -6
  180. package/dist/workflows/dag/prompt.js +60 -1
  181. package/dist/workflows/dag/rerun-feedback.js +212 -0
  182. package/dist/workflows/dag/rerun-plan.js +224 -27
  183. package/dist/workflows/dag/rerun-run.js +61 -6
  184. package/dist/workflows/dag/rerun-task.js +61 -2
  185. package/dist/workflows/dag/retry-policy.js +113 -0
  186. package/dist/workflows/dag/structured-output-repair.js +712 -0
  187. package/dist/workflows/dag/types.js +157 -1
  188. package/dist/workflows/dag/validate.js +41 -1
  189. package/docs/init-surface.manifest.json +5 -0
  190. package/docs/operations/README.md +1 -1
  191. package/docs/operations/local-development-environment.md +1 -5
  192. package/docs/skills/vetted-skill-registry.md +14 -0
  193. package/docs/templates/README.md +1 -1
  194. package/docs/templates/agent-dag.schema.json +44 -0
  195. package/docs/templates/backend-test-dag.json +60 -35
  196. package/docs/templates/frontend-implementation-contract.schema.json +9 -2
  197. package/docs/templates/frontend-test-dag.json +8 -10
  198. package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +1 -1
  199. package/docs/templates/init-managed-agents.md +13 -3
  200. package/harness.json +5 -3
  201. package/package.json +12 -4
  202. package/scripts/next-info.mjs +356 -0
  203. package/scripts/next-publish-gate.mjs +238 -0
  204. package/scripts/release-source-binding.mjs +251 -0
  205. package/skills/analyze-product-requirements/SKILL.md +8 -5
  206. package/skills/analyze-product-requirements/references/acceptance-criteria.md +1 -1
  207. package/skills/analyze-product-requirements/references/clarification-and-knowledge.md +10 -6
  208. package/skills/analyze-product-requirements/references/example.md +50 -0
  209. package/skills/analyze-product-requirements/references/forward-test-cases.md +11 -7
  210. package/skills/analyze-product-requirements/references/kb-integration.md +5 -5
  211. package/skills/analyze-product-requirements/references/product-analysis-schema.md +8 -4
  212. package/skills/analyze-product-requirements/references/product-requirement-schema.md +2 -2
  213. package/skills/analyze-product-requirements/references/requirement-clarification-schema.md +1 -1
  214. package/skills/analyze-product-requirements/scripts/test-validators.mjs +11 -1
  215. package/skills/analyze-product-requirements/scripts/validate-product-analysis.mjs +20 -1
  216. package/skills/analyze-product-requirements/scripts/validate-requirement-clarification.mjs +9 -0
  217. package/skills/codebase-scout/SKILL.md +1 -1
  218. package/skills/fe-test-ui-scout/SKILL.md +65 -0
  219. package/skills/fe-test-ui-scout/references/ledger-schema.md +62 -0
  220. package/skills/fe-test-ui-scout/references/recon-protocol.md +54 -0
  221. package/skills/frontend-design-review/references/review-checklist.md +2 -0
  222. package/skills/frontend-implementation/references/design-spec.md +16 -19
  223. package/skills/frontend-implementation/references/node-contracts.md +9 -6
  224. package/skills/improve-codebase-architecture/SKILL.md +81 -0
  225. package/skills/improve-codebase-architecture/deepening.md +37 -0
  226. package/skills/improve-codebase-architecture/html-report.md +123 -0
  227. package/skills/improve-codebase-architecture/interface-design.md +44 -0
  228. package/skills/improve-codebase-architecture/language.md +53 -0
  229. package/skills/loop-agent/references/command-reference.md +11 -4
  230. package/skills/playwright-cli/SKILL.md +22 -0
  231. package/skills/playwright-cli-case-generator/SKILL.md +20 -1
  232. package/dist/worker/console/static/assets/channel-DLVz9TYW.js +0 -1
  233. package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-BeAuGcO9.js +0 -1
  234. package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-BeAuGcO9.js +0 -1
  235. package/dist/worker/console/static/assets/index-DQxiso1w.js +0 -325
  236. package/dist/worker/console/static/assets/index-_j0Hzo69.css +0 -1
  237. package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DzKvfHTX.js +0 -1
  238. package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Cxqr_qM1.js +0 -8
@@ -0,0 +1,123 @@
1
+ # HTML Report Format
2
+
3
+ The architectural review is rendered as a single self-contained HTML file in the OS temp directory. Tailwind and Mermaid both come from CDNs. Mermaid handles graph-shaped diagrams reliably; hand-built divs and inline SVG handle the more editorial visuals (mass diagrams, cross-sections). Mix the two — don't lean on Mermaid for everything, it'll start to look generic.
4
+
5
+ ## Scaffold
6
+
7
+ ```html
8
+ <!doctype html>
9
+ <html lang="en">
10
+ <head>
11
+ <meta charset="utf-8" />
12
+ <title>Architecture review — {{repo name}}</title>
13
+ <script src="https://cdn.tailwindcss.com"></script>
14
+ <script type="module">
15
+ import mermaid from "https://cdn.jsdelivr.net/npm/mermaid@11/dist/mermaid.esm.min.mjs";
16
+ mermaid.initialize({ startOnLoad: true, theme: "neutral", securityLevel: "loose" });
17
+ </script>
18
+ <style>
19
+ /* small custom layer for things Tailwind doesn't cover cleanly:
20
+ dashed seam lines, hand-drawn-feeling arrow heads, etc. */
21
+ .seam { stroke-dasharray: 4 4; }
22
+ .leak { stroke: #dc2626; }
23
+ .deep { background: linear-gradient(135deg, #0f172a, #1e293b); }
24
+ </style>
25
+ </head>
26
+ <body class="bg-stone-50 text-slate-900 font-sans">
27
+ <main class="max-w-5xl mx-auto px-6 py-12 space-y-12">
28
+ <header>...</header>
29
+ <section id="candidates" class="space-y-10">...</section>
30
+ <section id="top-recommendation">...</section>
31
+ </main>
32
+ </body>
33
+ </html>
34
+ ```
35
+
36
+ ## Header
37
+
38
+ Repo name, date, and a compact legend: solid box = module, dashed line = seam, red arrow = leakage, thick dark box = deep module. No introduction paragraph — straight into the candidates.
39
+
40
+ ## Candidate card
41
+
42
+ The diagrams carry the weight. Prose is sparse, plain, and uses the glossary terms ([language.md](language.md)) without ceremony.
43
+
44
+ Each candidate is one `<article>`:
45
+
46
+ - **Title** — short, names the deepening (e.g. "Collapse the Order intake pipeline").
47
+ - **Badge row** — recommendation strength (`Strong` = emerald, `Worth exploring` = amber, `Speculative` = slate), plus a tag for the dependency category (`in-process`, `local-substitutable`, `ports & adapters`, `mock`).
48
+ - **Files** — monospaced list, `font-mono text-sm`.
49
+ - **Before / After diagram** — the centrepiece. Two columns, side by side. See patterns below.
50
+ - **Problem** — one sentence. What hurts.
51
+ - **Solution** — one sentence. What changes.
52
+ - **Wins** — bullets, ≤6 words each. e.g. "Tests hit one interface", "Pricing logic stops leaking", "Delete 4 shallow wrappers".
53
+ - **ADR callout** (if applicable) — one line in an amber-tinted box.
54
+
55
+ No paragraphs of explanation. If the diagram needs a paragraph to be understood, redraw the diagram.
56
+
57
+ ## Diagram patterns
58
+
59
+ Pick the pattern that fits the candidate. Mix them. Don't make every diagram look the same — variety is part of the point.
60
+
61
+ ### Mermaid graph (the workhorse for dependencies / call flow)
62
+
63
+ Use a Mermaid `flowchart` or `graph` when the point is "X calls Y calls Z, and look at the mess." Wrap it in a Tailwind-styled card so it doesn't feel parachuted in. Style with classDef to colour leakage edges red and the deep module dark. Sequence diagrams work well for "before: 6 round-trips; after: 1."
64
+
65
+ ```html
66
+ <div class="rounded-lg border border-slate-200 bg-white p-4">
67
+ <pre class="mermaid">
68
+ flowchart LR
69
+ A[OrderHandler] --> B[OrderValidator]
70
+ B --> C[OrderRepo]
71
+ C -.leak.-> D[PricingClient]
72
+ classDef leak stroke:#dc2626,stroke-width:2px;
73
+ class C,D leak
74
+ </pre>
75
+ </div>
76
+ ```
77
+
78
+ ### Hand-built boxes-and-arrows (when Mermaid's layout fights you)
79
+
80
+ Modules as `<div>`s with borders and labels. Arrows as inline SVG `<line>` or `<path>` elements positioned absolutely over a relative container. Reach for this when you want the "after" diagram to feel like one thick-bordered deep module with greyed-out internals — Mermaid won't render that with the right weight.
81
+
82
+ ### Cross-section (good for layered shallowness)
83
+
84
+ Stack horizontal bands (`h-12 border-l-4`) to show layers a call passes through. Before: 6 thin layers each doing nothing. After: 1 thick band labelled with the consolidated responsibility.
85
+
86
+ ### Mass diagram (good for "interface as wide as implementation")
87
+
88
+ Two rectangles per module — one for interface surface area, one for implementation. Before: interface rectangle is nearly as tall as the implementation rectangle (shallow). After: interface rectangle is short, implementation rectangle is tall (deep).
89
+
90
+ ### Call-graph collapse
91
+
92
+ Before: a tree of function calls rendered as nested boxes. After: the same tree collapsed into one box, with the now-internal calls shown faded inside it.
93
+
94
+ ## Style guidance
95
+
96
+ - Lean editorial, not corporate-dashboard. Generous whitespace. Serif optional for headings (`font-serif` works well with stone/slate).
97
+ - Colour sparingly: one accent (emerald or indigo) plus red for leakage and amber for warnings.
98
+ - Keep diagrams ~320px tall so before/after sits comfortably side by side without scrolling.
99
+ - Use `text-xs uppercase tracking-wider` for module labels inside diagrams — they should read as schematic, not as UI.
100
+ - The only scripts are the Tailwind CDN and the Mermaid ESM import. The report is otherwise static — no app code, no interactivity beyond Mermaid's own rendering.
101
+
102
+ ## Top recommendation section
103
+
104
+ One larger card. Candidate name, one sentence on why, anchor link to its card. That's it.
105
+
106
+ ## Tone
107
+
108
+ Plain English, concise — but the architectural nouns and verbs come straight from [language.md](language.md). Concision is not an excuse to drift.
109
+
110
+ **Use exactly:** module, interface, implementation, depth, deep, shallow, seam, adapter, leverage, locality.
111
+
112
+ **Never substitute:** component, service, unit (for module) · API, signature (for interface) · boundary (for seam) · layer, wrapper (for module, when you mean module).
113
+
114
+ **Phrasings that fit the style:**
115
+
116
+ - "Order intake module is shallow — interface nearly matches the implementation."
117
+ - "Pricing leaks across the seam."
118
+ - "Deepen: one interface, one place to test."
119
+ - "Two adapters justify the seam: HTTP in prod, in-memory in tests."
120
+
121
+ **Wins bullets** name the gain in glossary terms: *"locality: bugs concentrate in one module"*, *"leverage: one interface, N call sites"*, *"interface shrinks; implementation absorbs the wrappers"*. Don't write *"easier to maintain"* or *"cleaner code"* — those terms aren't in the glossary and don't earn their place.
122
+
123
+ No hedging, no throat-clearing, no "it's worth noting that…". If a sentence could be a bullet, make it a bullet. If a bullet could be cut, cut it. If a term isn't in [language.md](language.md), reach for one that is before inventing a new one.
@@ -0,0 +1,44 @@
1
+ # Interface Design
2
+
3
+ When the user wants to explore alternative interfaces for a chosen deepening candidate, use this parallel sub-agent pattern. Based on "Design It Twice" (Ousterhout) — your first idea is unlikely to be the best.
4
+
5
+ Uses the vocabulary in [language.md](language.md) — **module**, **interface**, **seam**, **adapter**, **leverage**.
6
+
7
+ ## Process
8
+
9
+ ### 1. Frame the problem space
10
+
11
+ Before spawning sub-agents, write a user-facing explanation of the problem space for the chosen candidate:
12
+
13
+ - The constraints any new interface would need to satisfy
14
+ - The dependencies it would rely on, and which category they fall into (see [deepening.md](deepening.md))
15
+ - A rough illustrative code sketch to ground the constraints — not a proposal, just a way to make the constraints concrete
16
+
17
+ Show this to the user, then immediately proceed to Step 2. The user reads and thinks while the sub-agents work in parallel.
18
+
19
+ ### 2. Spawn sub-agents
20
+
21
+ Spawn 3+ sub-agents in parallel using the Agent tool. Each must produce a **radically different** interface for the deepened module.
22
+
23
+ Prompt each sub-agent with a separate technical brief (file paths, coupling details, dependency category from [deepening.md](deepening.md), what sits behind the seam). The brief is independent of the user-facing problem-space explanation in Step 1. Give each agent a different design constraint:
24
+
25
+ - Agent 1: "Minimize the interface — aim for 1–3 entry points max. Maximise leverage per entry point."
26
+ - Agent 2: "Maximise flexibility — support many use cases and extension."
27
+ - Agent 3: "Optimise for the most common caller — make the default case trivial."
28
+ - Agent 4 (if applicable): "Design around ports & adapters for cross-seam dependencies."
29
+
30
+ Include both [language.md](language.md) vocabulary and CONTEXT.md vocabulary in the brief so each sub-agent names things consistently with the architecture language and the project's domain language.
31
+
32
+ Each sub-agent outputs:
33
+
34
+ 1. Interface (types, methods, params — plus invariants, ordering, error modes)
35
+ 2. Usage example showing how callers use it
36
+ 3. What the implementation hides behind the seam
37
+ 4. Dependency strategy and adapters (see [deepening.md](deepening.md))
38
+ 5. Trade-offs — where leverage is high, where it's thin
39
+
40
+ ### 3. Present and compare
41
+
42
+ Present designs sequentially so the user can absorb each one, then compare them in prose. Contrast by **depth** (leverage at the interface), **locality** (where change concentrates), and **seam placement**.
43
+
44
+ After comparing, give your own recommendation: which design you think is strongest and why. If elements from different designs would combine well, propose a hybrid. Be opinionated — the user wants a strong read, not a menu.
@@ -0,0 +1,53 @@
1
+ # Language
2
+
3
+ Shared vocabulary for every suggestion this skill makes. Use these terms exactly — don't substitute "component," "service," "API," or "boundary." Consistent language is the whole point.
4
+
5
+ ## Terms
6
+
7
+ **Module**
8
+ Anything with an interface and an implementation. Deliberately scale-agnostic — applies equally to a function, class, package, or tier-spanning slice.
9
+ _Avoid_: unit, component, service.
10
+
11
+ **Interface**
12
+ Everything a caller must know to use the module correctly. Includes the type signature, but also invariants, ordering constraints, error modes, required configuration, and performance characteristics.
13
+ _Avoid_: API, signature (too narrow — those refer only to the type-level surface).
14
+
15
+ **Implementation**
16
+ What's inside a module — its body of code. Distinct from **Adapter**: a thing can be a small adapter with a large implementation (a Postgres repo) or a large adapter with a small implementation (an in-memory fake). Reach for "adapter" when the seam is the topic; "implementation" otherwise.
17
+
18
+ **Depth**
19
+ Leverage at the interface — the amount of behaviour a caller (or test) can exercise per unit of interface they have to learn. A module is **deep** when a large amount of behaviour sits behind a small interface. A module is **shallow** when the interface is nearly as complex as the implementation.
20
+
21
+ **Seam** _(from Michael Feathers)_
22
+ A place where you can alter behaviour without editing in that place. The *location* at which a module's interface lives. Choosing where to put the seam is its own design decision, distinct from what goes behind it.
23
+ _Avoid_: boundary (overloaded with DDD's bounded context).
24
+
25
+ **Adapter**
26
+ A concrete thing that satisfies an interface at a seam. Describes *role* (what slot it fills), not substance (what's inside).
27
+
28
+ **Leverage**
29
+ What callers get from depth. More capability per unit of interface they have to learn. One implementation pays back across N call sites and M tests.
30
+
31
+ **Locality**
32
+ What maintainers get from depth. Change, bugs, knowledge, and verification concentrate at one place rather than spreading across callers. Fix once, fixed everywhere.
33
+
34
+ ## Principles
35
+
36
+ - **Depth is a property of the interface, not the implementation.** A deep module can be internally composed of small, mockable, swappable parts — they just aren't part of the interface. A module can have **internal seams** (private to its implementation, used by its own tests) as well as the **external seam** at its interface.
37
+ - **The deletion test.** Imagine deleting the module. If complexity vanishes, the module wasn't hiding anything (it was a pass-through). If complexity reappears across N callers, the module was earning its keep.
38
+ - **The interface is the test surface.** Callers and tests cross the same seam. If you want to test *past* the interface, the module is probably the wrong shape.
39
+ - **One adapter means a hypothetical seam. Two adapters means a real one.** Don't introduce a seam unless something actually varies across it.
40
+
41
+ ## Relationships
42
+
43
+ - A **Module** has exactly one **Interface** (the surface it presents to callers and tests).
44
+ - **Depth** is a property of a **Module**, measured against its **Interface**.
45
+ - A **Seam** is where a **Module**'s **Interface** lives.
46
+ - An **Adapter** sits at a **Seam** and satisfies the **Interface**.
47
+ - **Depth** produces **Leverage** for callers and **Locality** for maintainers.
48
+
49
+ ## Rejected framings
50
+
51
+ - **Depth as ratio of implementation-lines to interface-lines** (Ousterhout): rewards padding the implementation. We use depth-as-leverage instead.
52
+ - **"Interface" as the TypeScript `interface` keyword or a class's public methods**: too narrow — interface here includes every fact a caller must know.
53
+ - **"Boundary"**: overloaded with DDD's bounded context. Say **seam** or **interface**.
@@ -100,6 +100,8 @@ loop-agent --help
100
100
  ```bash
101
101
  loop-agent inspect # 当前 repo(自动检测)
102
102
  loop-agent --repo-root /path/to/target-repo inspect # 指定 repo
103
+ loop-agent inspect next # 当前 npm next 绑定(version / SHA / unpublished commits)
104
+ loop-agent inspect next --json
103
105
  ```
104
106
 
105
107
  ### 健康检查
@@ -132,13 +134,18 @@ SDK 回归或 SDK 可选依赖不可用时用 `cli-only` 诊断。CLI fallback
132
134
 
133
135
  ```bash
134
136
  loop-agent init instructions --repo-root <target-repo>
137
+ loop-agent init model-catalog --repo-root <target-repo> --json
135
138
  loop-agent init --repo-root <target-repo> --profile full --merge \
136
- --provider deepseek --model deepseek/deepseek-v4-flash
139
+ --low-model deepseek/deepseek-chat \
140
+ --med-model deepseek/deepseek-v4-flash \
141
+ --high-model deepseek/deepseek-v4-pro
137
142
  loop-agent init doctor --repo-root <target-repo>
138
143
  loop-agent init check-update --repo-root <target-repo> --json
139
144
  loop-agent init check-update --repo-root <target-repo> --markdown
140
145
  loop-agent init update --repo-root <target-repo> --bootstrap-surface
141
146
  loop-agent init update --repo-root <target-repo> --apply-safe
147
+ loop-agent init update --repo-root <target-repo> --apply-safe \
148
+ --low-model <current-or-selected> --med-model <current-or-selected> --high-model <current-or-selected>
142
149
  loop-agent init reconcile --repo-root <target-repo> [--json|--markdown] # compatibility low-level diagnostic
143
150
  loop-agent init upgrade --repo-root <target-repo> --json
144
151
  loop-agent init upgrade --repo-root <target-repo> --run-id <run-id> --status --json
@@ -146,13 +153,13 @@ loop-agent init upgrade --repo-root <target-repo> --run-id <run-id> --continue -
146
153
  loop-agent init upgrade --repo-root <target-repo> --run-id <run-id> --report --markdown
147
154
  ```
148
155
 
149
- fresh init 将精确引用写到 `executors.pi.LOW/MED/HIGH`。fresh `loop-agent init` 会将合格且完整的 `provider/model` 引用投影到 `executors.pi.LOW/MED/HIGH`,即 `executors.pi.LOW`、`executors.pi.MED` `executors.pi.HIGH`。三个 tier 齐全时不会写入 `defaultModel`,也不会恢复或建议旧顶层 routing 字段。
156
+ fresh init 将精确引用写到 `executors.pi.LOW/MED/HIGH`。模型先运行只读 `init model-catalog`:Pi SDK runtime 与 OpenCode 非 verbose 列表由代码确定性发现,只向模型暴露 provider/model、能力/成本/窗口元数据、Pi setup、兼容性与 credential-ready 布尔值,不暴露原始配置和凭据。已有档位仍存在于 Pi 时原样保留,只重选失效/缺失档位;代码在 update 时拒绝替换仍有效档位。Pi 无定义时先向用户补齐必要模型元数据并帮助字段级配置 `models.json`;只有认证缺失时保留 harness 并修复认证。三个 tier 齐全时不会写入 `defaultModel`,也不会恢复旧顶层 routing 字段。
150
157
 
151
158
  `init check-update` 是只读升级报告,用于发现目标项目是否落后于当前包内初始化 surface。输出会区分 deterministic actions、model merge tasks、human decisions 和 recommended next。`--markdown` 会渲染可直接交给模型执行的合并指引,包含 `allowedPaths`、`forbiddenPaths`、`mergeRules` 和 `verification`。
152
159
 
153
- `init update --bootstrap-surface` 为旧项目写入 `.harness/init-surface.json` 的 `inferred-baseline`,不伪装成历史 recorded baseline。`init update --apply-safe` 只执行确定性安全动作:补缺失文件、创建目录、刷新 managed block;已有但无法确认与当前包一致的文件会进入 model merge tasks,不会被覆盖。模型 merge 只会自动展开不含 tier 或其他旧字段的唯一、完整且可证明等价的旧 `defaultModel: "provider/model"`;顶层 `model`、`models`、`modelProfiles`、`modelRouting`、`verify`、`sequentialWorkflowRole`、部分/对象 tier、bare model、冲突 provider 或未知语义均 fail closed,并保留原始 `harness.json`。
160
+ `init update --bootstrap-surface` 为旧项目写入 `.harness/init-surface.json` 的 `inferred-baseline`,不伪装成历史 recorded baseline。`init update --apply-safe` 只执行确定性安全动作:补缺失文件、创建目录、刷新 managed block;`harness.json` 永不走整文件 `refresh-owned-file`,即使它仍与旧 recorded hash 一致,也只允许字段级确定性迁移或 bounded merge。带完整三档参数的 update 只替换 catalog 已判定失效的档位,仍有效档位的对象形态与 thinking 配置保持不变。模型 merge 只会自动展开不含 tier 或其他旧字段的唯一、完整且可证明等价的旧 `defaultModel: "provider/model"`;其他歧义均 fail closed 并保留原文件。
154
161
 
155
- `init upgrade` 是写入型升级入口:首次运行冻结 controller identity、检查 npm latest、扫描 surface、自动执行安全动作,并把 run facts 持久化到 `.harness/init-upgrades/<run-id>/`。`--status` `--report` 严格只读;`--continue` 会重新核验 identity、当前 hash 与不变量。版本选择、无法判定冲突、凭据、破坏性删除或 active writer 才进入 human decision。普通语义冲突返回具体单文件 `allowedPaths` merge task,主会话必须合并后继续,不能把 `needs-model-merge` 作为完成。默认管理项目级 OpenCode/Pi recovery 与 `.pi/settings.json` nested merge,保留显式 disabled,Pi trust 后才加载;默认不读写 `~/.pi/agent/settings.json`。旧 `init reconcile` 保留为兼容低层诊断。
162
+ `init upgrade` 是写入型升级入口:首次运行冻结 controller identity 与脱敏模型目录,检查 npm latest,并用一次 surface scan 形成完整计划。固定投影按 recorded bytes 确定性增删改;recorded `harness.json` 按属性树增删字段并保留项目值、同步 schema;项目自适应内容由模型决定。多个语义合并在同一计划中串行排队,每次仍只开放一个文件的 `allowedPaths`;接受后直接激活下一项,不重复版本发现/规划,队列清空后只跑一次最终验证。确定性收敛最多两轮。完成态的 verification/report 均有 controller hash anchor,`--status`、`--report` 和已完成 run 的幂等 `--continue` 只读持久化证据,不重新跑项目校验。默认管理项目级 OpenCode/Pi recovery 与 `.pi/settings.json` nested merge,默认不读写 `~/.pi/agent/settings.json`。旧 `init reconcile` 保留为兼容低层诊断。
156
163
 
157
164
  升级在 managed block 收敛后生成只读 gitignore 迁移评估(`.harness/init-upgrades/<run-id>/gitignore-migration.json`):inventory 已跟踪的 `.harness/**` 与 `.agents/**`,建议 index-only 命令 `git rm -r --cached --ignore-unmatch .harness` / `.agents`(只改 index、保留工作区文件;`scripts/**` 与 `ai_workspace/loop-agent/**` 永不出现)。`.agents` 已跟踪内容会触发 human-decision 暂停等待审查;非 Git 仓库、git 查询失败或存在 staged 条目时 `status: blocked` 且无命令建议。controller 不自动修改 Git index。
158
165
 
@@ -25,6 +25,7 @@ close
25
25
  goto
26
26
  snapshot
27
27
  find
28
+ find-unique
28
29
  click
29
30
  dblclick
30
31
  fill
@@ -71,6 +72,16 @@ playwright-cli close
71
72
  普通交互和控制台输出均不能单独取得 passed authority。通过的 case 还需要同一 child 的有序
72
73
  controller receipts:successful `open` → successful `find` → successful post-execution cleanup。
73
74
 
75
+ ### 唯一性断言优先用 find-unique
76
+
77
+ 当语义要求「全页恰好一个」时,用 `playwright-cli find-unique "字面"` 代替人工数命中数:它内部
78
+ 执行 find 并在解析命中数 ≠ 1 时以非零退出码失败(零命中/多命中/输出不可解析均 fail),错误
79
+ 信息直接给出 `expected exactly 1 match, got N`。它只接受一个文本字面量、不接受 `--regex` 等
80
+ flag。台账中标注 `==1` 的锚点、以及「唯一命中」类 AC 应优先用它;`>=N` 存在性断言仍用
81
+ `find`(find-unique 会拒绝多命中)。controller 会解析两类命令的命中数写入 receipt,finalize
82
+ 时用 case 文档声明的 `find "字面" >=N / ==N` 对照 receipt 复核,缺失或不满足会把 passed
83
+ 降级为 blocked(assertion-not-receipt-backed),因此声明的断言必须真的执行。
84
+
74
85
  ## 受限证据采集
75
86
 
76
87
  - UI 状态:先 `snapshot`,完成交互后以成功 `find` 证明用户可见结果。
@@ -91,3 +102,14 @@ controller receipts:successful `open` → successful `find` → successful pos
91
102
  当环境、数据、权限、时序、异常路径或响应内容无法用 RAG、已验证 context URL 和 runtime allowlist 证明时,
92
103
  写入 `blocked` evidence,并提供具体 `blockedReason`。不要引入替代执行路径,也不要把隐藏状态或
93
104
  未观察到的网络结果当作通过证据。
105
+
106
+ ### 唯一控件早停(unique-control-unavailable)
107
+
108
+ - 适用:AC 点名的具体控件在到达目标状态后的**首个 post-navigation snapshot** 中缺失,且页面没有
109
+ setup-required 门(如「需先完成 Pi setup」)。
110
+ - 判定:用 case 给出的字面做**单次** `find`;返回 0 命中即为充分证据,直接写
111
+ `status=blocked`、`blockedReason=unique-control-unavailable`,在 execution.md 中引用该次 find 结果。
112
+ - 禁止:换字面重试、反复 snapshot、绕路导航、多轮探索或请求 rerun。这些都产生无放大的 token
113
+ 成本且不改变结论(Wave 3 教训:反复探测不存在控件耗掉约 717k input tokens)。
114
+ - 若 snapshot 显示存在 setup-required 门或状态前置未满足,按其对应 blockedReason 记录
115
+ (环境/状态类),不属于本早停。
@@ -14,11 +14,21 @@ description: 根据 FE-test RAG 知识包生成可由受限 playwright_cli runti
14
14
  ## 输入与边界
15
15
 
16
16
  - 只读取 `testcase/frontend/rag/context.md`、`coverage-map.md` 与已有 `testcase/frontend/cases/`。
17
+ - 若存在 `testcase/frontend/rag/ui-anchors.md` 锚点台账,必须一并读取并作为 UI 断言的唯一事实源;台账缺失时按 RAG 知识包生成,但不得引用台账外的具体控件字面(缺失信息标 `blocked`)。
17
18
  - 只写 `testcase/frontend/cases/**`;不得回读 PRD、读取 `.harness/`,或写
18
19
  `testcase/frontend/evidence/**`。
19
20
  - 所有 API、字段限制、状态流转、数据来源、SLA、URL 与账号要求必须能在 RAG 知识包中追溯。
20
21
  缺失信息标记 `blocked` 或“需人工确认”,不得猜测。
21
22
 
23
+ ### 锚点台账规则(存在 ui-anchors.md 时)
24
+
25
+ - case 中每条拟通过的 `find "<字面>"` 断言必须能在台账对应「页面 × 状态」节找到
26
+ 状态为 `有效` 的行;台账 `不可断言` / `失效` 行的字面**禁止**作为通过断言。
27
+ - AC 点名的控件在台账对应状态节缺失(0 命中或无行)时,该 AC 的 case 生成
28
+ `blocked` 语义说明(或从本批剔除该 AC),`blockedReason` 用
29
+ `unique-control-unavailable`,不得生成探测性步骤反复 find。
30
+ - 台账行备注中的替代断言方案(如拆节点后的短字面二选一)按备注执行。
31
+
22
32
  ## 输出
23
33
 
24
34
  - 写 `index.md`、`manifest.draft.json`(生成阶段;materialize 会写成 `manifest.json`)与独立 case 文件
@@ -51,7 +61,16 @@ description: 根据 FE-test RAG 知识包生成可由受限 playwright_cli runti
51
61
  占位符仅表示从紧邻其前、最新一次 `snapshot` 输出解析出的真实 `eNN` ref。生成的 case 必须在每次
52
62
  引用元素前写明 fresh snapshot;`eX`/`eY` 不是可传给 structured tool 的 literal ref,新的 snapshot
53
63
  会使旧 ref 失效,不得复用 stale ref。
54
- 5. 明确的 UI/API 预期与数据清理结果;无法满足的环境或数据依赖必须写为 `blocked`。
64
+ 5. **期望命中数不得内联进命令行(硬约束)**:如需声明 find 期望命中数,写在「预期结果」区或
65
+ 列表项的说明文字中(如 “预期唯一命中”);命令行只写纯命令 `playwright-cli find "<字面>"`。
66
+ 禁止 `find "<字面>">=N`、`≥N`、`(≥N)` 等计数后缀内联进命令 token。
67
+ 6. **唯一性断言优先 find-unique**:台账或 AC 标注 `==1`/「唯一命中」的锚点,生成
68
+ `playwright-cli find-unique "<字面>"`(仅一个文本字面量,无 flag;多命中/零命中即命令失败);
69
+ `>=N` 存在性断言仍用 `find`。finalize 会用 case 文档中 `find "字面" >=N / ==N` 声明对照
70
+ controller receipt 的解析命中数复核,声明的断言未真正执行或命中数不满足会把 passed 降级为
71
+ blocked(assertion-not-receipt-backed)——因此「测试点」里声明的每个 find 断言都必须在步骤中
72
+ 真实执行且字面完全一致。
73
+ 7. 明确的 UI/API 预期与数据清理结果;无法满足的环境或数据依赖必须写为 `blocked`。
55
74
 
56
75
  所有文件型输出均由 controller 绑定到执行节点提供的
57
76
  `testcase/frontend/evidence/<case-id>/` 工作目录。截图一律使用 canonical 语法
@@ -1 +0,0 @@
1
- import{ag as o,ah as n}from"./mermaid.core-DWGK9kwP.js";const t=(a,r)=>o.lang.round(n.parse(a)[r]);export{t as c};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-B-uGFIg2.js";import{_ as i}from"./mermaid.core-DWGK9kwP.js";import"./chunk-5VM5RSS4-D_ch2aaI.js";import"./chunk-XXDRQBXY-Bbfe3UJG.js";import"./chunk-KBJHAD2P-BjAUAfcT.js";import"./chunk-2GRJ4B5K-WTEKTxin.js";import"./index-DQxiso1w.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};
@@ -1 +0,0 @@
1
- import{s as a,c as s,a as e,C as t}from"./chunk-GF5L2VYU-B-uGFIg2.js";import{_ as i}from"./mermaid.core-DWGK9kwP.js";import"./chunk-5VM5RSS4-D_ch2aaI.js";import"./chunk-XXDRQBXY-Bbfe3UJG.js";import"./chunk-KBJHAD2P-BjAUAfcT.js";import"./chunk-2GRJ4B5K-WTEKTxin.js";import"./index-DQxiso1w.js";var n={parser:e,get db(){return new t},renderer:s,styles:a,init:i(r=>{r.class||(r.class={}),r.class.arrowMarkerAbsolute=r.arrowMarkerAbsolute},"init")};export{n as diagram};