@tea-agent/loop-agent 0.44.0-next.12 → 0.44.0-next.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +27 -2
- package/README.md +12 -12
- package/dist/adapters/loop-agent.js +34 -0
- package/dist/build-stamp.json +3 -3
- package/dist/cli/command-definitions.js +5 -5
- package/dist/cli/program.js +1 -4
- package/dist/commands/init-legacy-audit.js +330 -0
- package/dist/commands/init-upgrade.js +644 -104
- package/dist/commands/init.js +686 -330
- package/dist/commands/operator-guide.js +99 -0
- package/dist/commands/operator.js +16 -3
- package/dist/executors/dag-pi-executor.js +11 -6
- package/dist/executors/pi-sdk-executor.js +3 -1
- package/dist/executors/pi-writer-tool-policy.js +60 -4
- package/dist/executors/playwright-cli-launcher.js +31 -45
- package/dist/executors/shell-write-guard.js +24 -67
- package/dist/governance/exec-plans.js +10 -1
- package/dist/governance/harness.js +2 -7
- package/dist/governance/manifest-types.js +28 -9
- package/dist/governance/project-capability-scanner.js +263 -0
- package/dist/governance/project-config.js +96 -0
- package/dist/governance/resource-catalog.js +151 -0
- package/dist/infrastructure/console/app-data.js +6 -2
- package/dist/shared/operator/capabilities.js +2 -2
- package/dist/shared/package-metadata.js +23 -7
- package/dist/shared/pi-context-pressure/extension.js +23 -0
- package/dist/shared/pi-context-pressure/index.js +1 -0
- package/dist/shared/pi-context-pressure/telemetry.js +4 -0
- package/dist/shared/pi-context-pressure/tool-result-pruner.js +98 -0
- package/dist/shared/update/npm-client.js +49 -1
- package/dist/task/config-types.js +4 -2
- package/dist/task/source-prepare/build-draft.js +1 -0
- package/dist/task/source-prepare/path-policy.js +17 -7
- package/dist/worker/cli.js +3 -5
- package/dist/worker/console/chat/browser-automation.js +455 -41
- package/dist/worker/console/chat/browser-content.js +74 -0
- package/dist/worker/console/chat/browser-diagnostics.js +250 -0
- package/dist/worker/console/chat/browser-evaluation.js +58 -0
- package/dist/worker/console/chat/browser-operation-queue.js +19 -0
- package/dist/worker/console/chat/browser-pick.js +113 -0
- package/dist/worker/console/chat/browser-routes.js +54 -5
- package/dist/worker/console/chat/browser-screenshot-result.js +47 -0
- package/dist/worker/console/chat/browser-storage.js +89 -0
- package/dist/worker/console/chat/chat-event-store.js +7 -6
- package/dist/worker/console/chat/context-insights.js +84 -19
- package/dist/worker/console/chat/pet/pet-affinity.js +169 -0
- package/dist/worker/console/chat/pet/pet-persist.js +109 -0
- package/dist/worker/console/chat/pet/pet-registry.js +142 -0
- package/dist/worker/console/chat/pet/pet-remarks.js +48 -0
- package/dist/worker/console/chat/pet/pet-routes.js +125 -0
- package/dist/worker/console/chat/pet/pet-service.js +262 -0
- package/dist/worker/console/chat/pet/pet-state.js +99 -0
- package/dist/worker/console/chat/pi-mode-loop-isolation.js +17 -2
- package/dist/worker/console/chat/pi-runtime/custom-tools/browser-tools.js +125 -174
- package/dist/worker/console/chat/pi-runtime.js +8 -3
- package/dist/worker/console/chat/repo-browser.js +80 -2
- package/dist/worker/console/chat/repo-preview-kind.js +155 -0
- package/dist/worker/console/chat/routes.js +43 -7
- package/dist/worker/console/chat/scheduled-goal-request.js +14 -6
- package/dist/worker/console/chat/session-mode.js +1 -1
- package/dist/worker/console/chat/session-store.js +24 -5
- package/dist/worker/console/chat/tools.js +12 -0
- package/dist/worker/console/console-shutdown.js +34 -0
- package/dist/worker/console/server.js +2 -1
- package/dist/worker/console/static/assets/{abnfDiagram-N423BO3Z-r1NAPU_5.js → abnfDiagram-N423BO3Z-DASc69AM.js} +1 -1
- package/dist/worker/console/static/assets/{arc-dT5T4sVL.js → arc-h09p-LAc.js} +1 -1
- package/dist/worker/console/static/assets/{architectureDiagram-T3A2C74G-CP_cOq46.js → architectureDiagram-T3A2C74G-CZ3dtLkh.js} +1 -1
- package/dist/worker/console/static/assets/{blockDiagram-VBNYF7ZC-sToEZxEf.js → blockDiagram-VBNYF7ZC-DMrRhMXG.js} +1 -1
- package/dist/worker/console/static/assets/{c4Diagram-5PPSVZJV-DSxwwi2m.js → c4Diagram-5PPSVZJV-DQxisHV6.js} +1 -1
- package/dist/worker/console/static/assets/channel-D1zgKZfg.js +1 -0
- package/dist/worker/console/static/assets/{chunk-2GRJ4B5K-B9fh0IkF.js → chunk-2GRJ4B5K-CefVN9zh.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-2Q5K7J3B-CAUNl-A6.js → chunk-2Q5K7J3B-DmR1Koq2.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5RXB4S5H-BomeqbNX.js → chunk-5RXB4S5H-NlzrSW7L.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-5VM5RSS4-BNAuTOLE.js → chunk-5VM5RSS4-DfelJv-0.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-6Q2QTUOP-DfzjRD5y.js → chunk-6Q2QTUOP-BK6RFy58.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-GF5L2VYU-C3uE-yc2.js → chunk-GF5L2VYU-BAeh9lz4.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-JWPE2WC7-C3sQMMYr.js → chunk-JWPE2WC7-ChPS5WzG.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-KBJHAD2P-D_AtEYQL.js → chunk-KBJHAD2P-BoVe5IM6.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-RYQCIY6F-DW4TwhKv.js → chunk-RYQCIY6F-C4q_0Lw9.js} +1 -1
- package/dist/worker/console/static/assets/{chunk-XXDRQBXY-CTQDmJcp.js → chunk-XXDRQBXY-Bb9TvjeY.js} +1 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-CXNNsY2M.js +1 -0
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-CXNNsY2M.js +1 -0
- package/dist/worker/console/static/assets/{cose-bilkent-JH36ORCC-iMqPuBsL.js → cose-bilkent-JH36ORCC-DmNnL8Ff.js} +1 -1
- package/dist/worker/console/static/assets/{cynefin-VYW2F7L2-DktIuDWs.js → cynefin-VYW2F7L2-Contvx58.js} +1 -1
- package/dist/worker/console/static/assets/{cynefinDiagram-MW4NZA55-BgVnjyEs.js → cynefinDiagram-MW4NZA55-Cigq7cjk.js} +1 -1
- package/dist/worker/console/static/assets/{dagre-VZM6K2ZE-CR25E4bu.js → dagre-VZM6K2ZE-dEbC0nxb.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-7IWD3JNH-CPM2h5HY.js → diagram-7IWD3JNH-CzIztESV.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-B4RE2ZJO-DqF0x2g1.js → diagram-B4RE2ZJO-Bo14zbaY.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-LBJQPF4R-G8BYp2eb.js → diagram-LBJQPF4R-C4xUyil6.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-Q27KOJAE-BbC4kT_D.js → diagram-Q27KOJAE-CaBY_uYa.js} +1 -1
- package/dist/worker/console/static/assets/{diagram-UB23O5K3-CKZwZ-G5.js → diagram-UB23O5K3-ClUXUeiu.js} +1 -1
- package/dist/worker/console/static/assets/{ebnfDiagram-BXEA7PRR-kJDmheia.js → ebnfDiagram-BXEA7PRR-BbGCgjC6.js} +1 -1
- package/dist/worker/console/static/assets/{erDiagram-JOGREHBK-DFTVHyxB.js → erDiagram-JOGREHBK-Dr-AcwSl.js} +1 -1
- package/dist/worker/console/static/assets/{flowDiagram-UKHOOZJN-BqdN5_os.js → flowDiagram-UKHOOZJN-BG8Gcfyc.js} +1 -1
- package/dist/worker/console/static/assets/{ganttDiagram-PKOTCBZU-SYDjVakh.js → ganttDiagram-PKOTCBZU-CFVaPs5r.js} +1 -1
- package/dist/worker/console/static/assets/{gitGraphDiagram-DS77QQ5N-Bf8bNpGA.js → gitGraphDiagram-DS77QQ5N-ChJ8pm-O.js} +1 -1
- package/dist/worker/console/static/assets/index-B_5GhVIO.js +488 -0
- package/dist/worker/console/static/assets/index-C7YMBluX.css +1 -0
- package/dist/worker/console/static/assets/{infoDiagram-6WML65LV-DIeAmJ45.js → infoDiagram-6WML65LV-C5J9-uCZ.js} +1 -1
- package/dist/worker/console/static/assets/{ishikawaDiagram-WSZJBQD7-oikqUAlo.js → ishikawaDiagram-WSZJBQD7-BcfjqzDv.js} +1 -1
- package/dist/worker/console/static/assets/{journeyDiagram-NVQOT4AX-mKEF_xYT.js → journeyDiagram-NVQOT4AX-BzzCO-rD.js} +1 -1
- package/dist/worker/console/static/assets/{kanban-definition-27J2QSJJ-BdWJHPnN.js → kanban-definition-27J2QSJJ-NCHUZ46h.js} +1 -1
- package/dist/worker/console/static/assets/{linear-DGRlieMH.js → linear-BKZlWCUU.js} +1 -1
- package/dist/worker/console/static/assets/{mermaid.core-4P9yPC9c.js → mermaid.core-DbTaQjFE.js} +5 -5
- package/dist/worker/console/static/assets/{mindmap-definition-FAOFIHXS-5PTSkos6.js → mindmap-definition-FAOFIHXS-CroYl5xQ.js} +1 -1
- package/dist/worker/console/static/assets/{pegDiagram-VL7TDLO6-DONIFpG5.js → pegDiagram-VL7TDLO6-DgMBx-9k.js} +1 -1
- package/dist/worker/console/static/assets/{pieDiagram-7S7Q4E2Y-D_Z4S70M.js → pieDiagram-7S7Q4E2Y-CyWDmbq1.js} +1 -1
- package/dist/worker/console/static/assets/{quadrantDiagram-CIZ2JOQS-CAsjh8iY.js → quadrantDiagram-CIZ2JOQS-BgGEOqSP.js} +1 -1
- package/dist/worker/console/static/assets/{railroadDiagram-AXF67PYL-Cx4Dd6ac.js → railroadDiagram-AXF67PYL-BMZ7oeeV.js} +1 -1
- package/dist/worker/console/static/assets/{requirementDiagram-LRYGKXZP-cQb7mwyH.js → requirementDiagram-LRYGKXZP-DxqyGhcc.js} +1 -1
- package/dist/worker/console/static/assets/{sankeyDiagram-W5VNT64P-Cd-DhUdf.js → sankeyDiagram-W5VNT64P-DnSvNCG8.js} +1 -1
- package/dist/worker/console/static/assets/{sequenceDiagram-SI44F4Z6-AlKYRgIk.js → sequenceDiagram-SI44F4Z6-BiZh6f-R.js} +1 -1
- package/dist/worker/console/static/assets/{sizeCapture-X5ZJPWSS-CUy_ET4e.js → sizeCapture-X5ZJPWSS-BKXSI8WB.js} +1 -1
- package/dist/worker/console/static/assets/{stateDiagram-OKZ733FA-CTuVe6Sa.js → stateDiagram-OKZ733FA-CfSgoYFm.js} +1 -1
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-DgHi3vjb.js +1 -0
- package/dist/worker/console/static/assets/{swimlanes-SLNWSIFB-ChFLJb-v.js → swimlanes-SLNWSIFB-CyGADcHe.js} +2 -2
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-Bgvdt1Y0.js +8 -0
- package/dist/worker/console/static/assets/{timeline-definition-Z64GVDOM-DZZeiAPr.js → timeline-definition-Z64GVDOM-HmPaSPOK.js} +1 -1
- package/dist/worker/console/static/assets/{vennDiagram-T6HMQDX7-t4O91cZU.js → vennDiagram-T6HMQDX7-VA2VBbez.js} +1 -1
- package/dist/worker/console/static/assets/{wardleyDiagram-T6FBY63Y-CV5qGHZu.js → wardleyDiagram-T6FBY63Y-BxjiBPZa.js} +1 -1
- package/dist/worker/console/static/assets/{xychartDiagram-ELKLHX3M-DyXbytUI.js → xychartDiagram-ELKLHX3M--hUY-qFj.js} +1 -1
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/console/static/pets/ember/pet.json +167 -0
- package/dist/worker/console/static/pets/ember/spritesheet.png +0 -0
- package/dist/worker/console/static-src/operator-chat/details-rail-surfaces.js +4 -3
- package/dist/worker/console/static-src/operator-chat/open-preview-in-browser.js +57 -9
- package/dist/worker/console/static-src/operator-chat/use-stat-dialog.js +95 -0
- package/dist/worker/console/static-src/operator-chat/useRepoBrowser.js +6 -0
- package/dist/worker/console/workspace-context.js +15 -0
- package/dist/worker/console/workspace-initialization.js +25 -16
- package/dist/worker/delivery/package.js +4 -1
- package/dist/worker/materialize/harness-task-lineage.js +4 -2
- package/dist/worker/observe/static/console-theme.css +33 -29
- package/dist/worker/observe/static/operator-chrome.js +1 -42
- package/dist/workflows/dag/backend-test-case-coverage-analysis.js +3 -1
- package/dist/workflows/dag/backend-test-layout.js +27 -7
- package/dist/workflows/dag/backend-test-markdown-workflow.js +3 -1
- package/dist/workflows/dag/backend-test-pytest-collection.js +4 -1
- package/dist/workflows/dag/final-verification.js +45 -10
- package/dist/workflows/dag/frontend-test-case-checklist.js +12 -3
- package/dist/workflows/dag/frontend-test-environment-probe.js +0 -2
- package/dist/workflows/dag/frontend-test-layout.js +41 -12
- package/dist/workflows/dag/hybrid/sources.js +35 -16
- package/dist/workflows/dag/hybrid/templates/backend-test.js +70 -55
- package/dist/workflows/dag/hybrid/templates/frontend-test.js +62 -41
- package/dist/workflows/dag/hybrid/templates/kg-bootstrap.js +6 -6
- package/dist/workflows/dag/hybrid/templates/knowledge-sync.js +5 -5
- package/dist/workflows/dag/skill-instructions.js +102 -32
- package/dist/workflows/dag/skill-snapshot.js +3 -0
- package/dist/workflows/dag/skills.js +7 -7
- package/dist/workflows/dag/test-artifact-namespace.js +73 -0
- package/dist/workflows/dag/validate.js +24 -5
- package/dist/workflows/dag/workspace-checkpoint.js +13 -1
- package/docs/architecture/runtime-boundaries.md +28 -22
- package/docs/init-surface.manifest.json +43 -295
- package/docs/templates/README.md +4 -4
- package/docs/templates/agent-dag.base.json +9 -9
- package/docs/templates/agent-dag.final-verification.json +6 -6
- package/docs/templates/agent-dag.supervised-implementation.json +12 -12
- package/docs/templates/backend-test-dag.generate-pytest.prompt.md +3 -3
- package/docs/templates/backend-test-dag.json +708 -708
- package/docs/templates/backend-test-dag.review-cases.prompt.md +3 -3
- package/docs/templates/frontend-implementation-dag.json +2 -2
- package/docs/templates/frontend-test-case-checklist.md +2 -2
- package/docs/templates/frontend-test-dag.generate-cases.prompt.md +7 -7
- package/docs/templates/frontend-test-dag.json +48 -39
- package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +2 -2
- package/docs/templates/frontend-test-dag.retrospect.prompt.md +1 -1
- package/docs/templates/frontend-test-dag.review-cases.prompt.md +1 -1
- package/docs/templates/hybrid-dag.json +9 -9
- package/docs/templates/knowledge-sync-dag.json +8 -8
- package/package.json +12 -3
- package/resource-catalog.v1.json +1973 -0
- package/resources/agent-bridge/loop-agent/SKILL.md +40 -0
- package/resources/init-history/legacy-surface.v1.json +33 -0
- package/skills/fe-test-ui-scout/SKILL.md +4 -4
- package/skills/fe-test-ui-scout/references/ledger-schema.md +1 -1
- package/skills/init-update/SKILL.md +34 -0
- package/skills/init-update/agents/openai.yaml +6 -0
- package/skills/playwright-cli/SKILL.md +1 -1
- package/skills/playwright-cli-case-generator/SKILL.md +4 -4
- package/dist/worker/console/static/assets/channel-CyBY_yGk.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-JCYQIIEL-D5lN4E_E.js +0 -1
- package/dist/worker/console/static/assets/classDiagram-v2-OCEON4UE-D5lN4E_E.js +0 -1
- package/dist/worker/console/static/assets/index-B28Onmfy.css +0 -1
- package/dist/worker/console/static/assets/index-CTMZsDmh.js +0 -486
- package/dist/worker/console/static/assets/stateDiagram-v2-UEYNNEHI-BsWhs8O7.js +0 -1
- package/dist/worker/console/static/assets/swimlanesDiagram-ULZ7WXOC-CJcioYGH.js +0 -8
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
供 `review-and-revise-backend-md-cases-pi` 使用。该节点是 `executor: "pi"`、`role: "reviewer"`、`toolProfile: "write"` 的受限 reviewer,只能直接修订
|
|
5
|
+
供 `review-and-revise-backend-md-cases-pi` 使用。该节点是 `executor: "pi"`、`role: "reviewer"`、`toolProfile: "write"` 的受限 reviewer,只能直接修订 `.harness/testcase/md/**`,不得生成 pytest 或修改任务源、生产代码和配置。
|
|
6
6
|
|
|
7
7
|
## 当前合同
|
|
8
8
|
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
|
|
11
11
|
### 阅读体验
|
|
12
12
|
|
|
13
|
-
-
|
|
13
|
+
- `.harness/testcase/md/README.md` 是简洁入口,包含测试目标、环境、隔离/清理策略、模块汇总和可跳转的用例索引。
|
|
14
14
|
- 模块文件采用中文用例卡片;每条以 `## BE-<MODULE>-<NNN>|<中文用例名称>` 开始;`<NNN>` 必须是三位补零序号(`001`,禁止 `01`)。Reviewer 发现两位序号或模块下划线时,必须在标题、README 索引与自动化映射中一致规范化(如 `BE-RESOURCE_NOTES-01` → `BE-RESOURCE-NOTES-001`)。
|
|
15
15
|
- 新文档优先使用:`测试目的`、`验收标准`、`需求依据`、`前置条件`、`测试数据`、`操作步骤`、`预期结果`、`自动化映射`。
|
|
16
16
|
- validator 同时接受上述中文分节和历史英文分节;机器 ID、HTTP 方法、路径、字段、枚举、文件名、函数名与 source citation 必须保持精确。
|
|
@@ -22,7 +22,7 @@
|
|
|
22
22
|
- 对照每条 `需求依据` 和环境报告检查 AC、接口、字段/响应形状、状态码、错误语义、状态转换、正向/异常/边界场景。
|
|
23
23
|
- 删除无依据场景、合并重复用例、补齐有依据的遗漏;无法确认的内容写入中文证据缺口,不猜测行为或凭据。
|
|
24
24
|
- 拒绝“符合预期”“正常工作”等模糊结果,以及无意义的中英双写和大段重复 boilerplate。
|
|
25
|
-
- 若能确定脚本与函数命名,在 `自动化映射` 中写明计划脚本路径与 pytest 函数/方法名;脚本路径必须等于模块 one-to-one 路径
|
|
25
|
+
- 若能确定脚本与函数命名,在 `自动化映射` 中写明计划脚本路径与 pytest 函数/方法名;脚本路径必须等于模块 one-to-one 路径 `.harness/testcase/test_<module>.py`,`<module>` 来自当前 Markdown 文件名 stem,不得使用 Case-ID 式模块名(如 `BE-HEALTH.md`)或与模块 stem 不一致的映射。
|
|
26
26
|
|
|
27
27
|
## 推荐输出
|
|
28
28
|
|
|
@@ -19,9 +19,9 @@
|
|
|
19
19
|
"Do not infer missing behavior, states, interactions, design decisions, or verification commands. Stop for an explicit task-contract revision instead.",
|
|
20
20
|
"Do not add dependencies unless they are already declared by the project contract."
|
|
21
21
|
],
|
|
22
|
-
"defaults": {"executor":"pi","contextProfile":"slim","skills":["ai-engineering-context"],"writePolicy":"read-only"},
|
|
22
|
+
"defaults": {"executor":"pi","contextProfile":"slim","skills":["builtin:ai-engineering-context"],"writePolicy":"read-only"},
|
|
23
23
|
"skillsByRole": {
|
|
24
|
-
"planner":["loop-agent"], "scout":["ai-engineering-context"], "implementer":["verification-before-completion"], "reviewer":["requesting-code-review"], "verifier":["verification-before-completion","systematic-debugging"], "closeout":["loop-agent","verification-before-completion"]
|
|
24
|
+
"planner":["builtin:loop-agent"], "scout":["builtin:ai-engineering-context"], "implementer":["builtin:verification-before-completion"], "reviewer":["builtin:requesting-code-review"], "verifier":["builtin:verification-before-completion","builtin:systematic-debugging"], "closeout":["builtin:loop-agent","builtin:verification-before-completion"]
|
|
25
25
|
},
|
|
26
26
|
"executorModels": {"pi":{"LOW":"gpt-5.3-codex-spark","MED":"gpt-5.5","HIGH":"gpt-5.5"}},
|
|
27
27
|
"tasks": [
|
|
@@ -15,7 +15,7 @@ LLM review (when `frontendTest.reviewMode=blocking`) must not invent blocking ru
|
|
|
15
15
|
| `unknown-ac` | When task `sourceBinding.requirementIds` lists ACs, every `acIds` entry must be in that set |
|
|
16
16
|
| `case-id-shape` | `caseId` matches `FE-<FEATURE>-<NNN>-...` (never `AC-FE-*`) |
|
|
17
17
|
| `case-id-is-ac` | Do not use acceptance id as `caseId` / filename |
|
|
18
|
-
| `case-path-mismatch` | `casePath === {casesDir}/{caseId}.md`(默认
|
|
18
|
+
| `case-path-mismatch` | `casePath === {casesDir}/{caseId}.md`(默认 `.harness/testcase/frontend/cases/{caseId}.md`) |
|
|
19
19
|
| `case-file-missing` | `casePath` exists |
|
|
20
20
|
|
|
21
21
|
## Tool guidance (non-blocking)
|
|
@@ -40,5 +40,5 @@ LLM review (when `frontendTest.reviewMode=blocking`) must not invent blocking ru
|
|
|
40
40
|
|
|
41
41
|
## Pipeline vs quality
|
|
42
42
|
|
|
43
|
-
- **Pipeline acceptance**: final `{reportsDir}/frontend-test-retrospect-*.md` exists after result materialize (default
|
|
43
|
+
- **Pipeline acceptance**: final `{reportsDir}/frontend-test-retrospect-*.md` exists after result materialize (default `.harness/testcase/frontend/reports/`)
|
|
44
44
|
- **Quality**: `frontend-test-result-v1.outcome=passed` with 0 blocked/failed (opt-in via `frontendTest.strictOutcomeGate`)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Generate frontend functional cases
|
|
2
2
|
|
|
3
|
-
Use `playwright-cli-case-generator`. Read only
|
|
3
|
+
Use `playwright-cli-case-generator`. Read only `.harness/testcase/frontend/rag/context.md`, `coverage-map.md`, and existing `.harness/testcase/frontend/cases/`; write only that cases directory. Produce Markdown cases, `index.md`, and schema-version-1 `manifest.draft.json` (materialize promotes to `manifest.json`). Do not generate pytest or Playwright source code.
|
|
4
4
|
|
|
5
5
|
## HARD ID contract (frequent failure)
|
|
6
6
|
|
|
@@ -11,12 +11,12 @@ Use `playwright-cli-case-generator`. Read only `testcase/frontend/rag/context.md
|
|
|
11
11
|
|
|
12
12
|
- **Never** set `caseId` to `AC-FE-001` or name the file `AC-FE-001.md`.
|
|
13
13
|
- **Never** put `FE-LOGIN-001-core` into `acIds`.
|
|
14
|
-
- `casePath` must be
|
|
15
|
-
- `evidenceDir` must be
|
|
14
|
+
- `casePath` must be `.harness/testcase/frontend/cases/<caseId>.md`.
|
|
15
|
+
- `evidenceDir` must be `.harness/testcase/frontend/evidence/<caseId>/`.
|
|
16
16
|
|
|
17
17
|
Each case is independently executable and includes AC mapping (`acIds`), preconditions, cleanup, a semantic assertion, and its isolated evidence path. Use dimensions `core`, `boundary`, `flow`, or `backend`. Never guess API fields, constraints, SLA, credentials, or unrecorded data. For passed authority, include a successful `playwright-cli find ...` after `open` and before controller post-execution cleanup; `snapshot`, `goto`, `screenshot`, `request`/`console`, and ordinary interactions are not assertions.
|
|
18
18
|
|
|
19
|
-
Every case must copy the concrete absolute base URL from
|
|
19
|
+
Every case must copy the concrete absolute base URL from `.harness/testcase/frontend/rag/context.md` only after the environment shell has marked `environmentProbe: reachable`. Do not derive a different origin and do not leave a base-url placeholder.
|
|
20
20
|
|
|
21
21
|
Every case must start with `playwright-cli open --browser=chrome` followed by that concrete context URL. Do not copy an angle-bracket URL placeholder into a generated executable case line.
|
|
22
22
|
|
|
@@ -49,15 +49,15 @@ For every executable sub-scenario, state the fixture/reset operation, UI reset o
|
|
|
49
49
|
|
|
50
50
|
Each case must require the executor to persist, even when blocked:
|
|
51
51
|
|
|
52
|
-
-
|
|
53
|
-
-
|
|
52
|
+
- `.harness/testcase/frontend/evidence/<case-id>/execution.md`
|
|
53
|
+
- `.harness/testcase/frontend/evidence/<case-id>/case-result.json`
|
|
54
54
|
|
|
55
55
|
`case-result.json` must be valid JSON containing the matching `caseId`, final `status` (`passed`, `failed`, or `blocked`), and an `evidencePaths` array. A rerun must overwrite this same file with its final status and integer `rerunAttempt`; the final report consumes that latest file. A blocked result must include a non-empty `blockedReason`, such as `isolated-test-environment-unavailable` or `token-budget-exhausted`, and must never claim or imply a pass. `execution.md` records attempted or blocked steps, base-URL safety decision, fixture/reset and request-observation availability, timestamps, and the evidence-file list. When available, use fixed headings `### 执行摘要` and `### 实际执行步骤` so the bounded deterministic report extractor can show actual execution facts. Available evidence files are required only when actually produced and must stay under the same case evidence directory.
|
|
56
56
|
|
|
57
57
|
|
|
58
58
|
## Standard scenarios (controller)
|
|
59
59
|
|
|
60
|
-
- Read
|
|
60
|
+
- Read `.harness/testcase/frontend/rag/standard-scenarios.v1.json` when present.
|
|
61
61
|
- Cover each `priority=must` scenario with at least one case or record an explicit GAP in coverage-map.
|
|
62
62
|
- Each case Markdown SHOULD include `## 测试点` and `## 测试步骤` sections.
|
|
63
63
|
- Prefer linking cases via `standardScenarioIds` in manifest.draft notes when possible.
|
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
"Every generated browser start command uses playwright-cli open --browser=chrome followed by the concrete URL selected by retrieve-frontend-test-context-pi from bound task source/config and written to context.md; the environment shell must mark that URL reachable before generation/execution; executable case lines never retain an angle-bracket URL/ref placeholder; subsequent commands stay in that default session and must not use unverified named-session flags.",
|
|
15
15
|
"Case children execute serially. Persist each case result, logs and browser evidence before the next child starts.",
|
|
16
16
|
"A token threshold is a post-case stop check, not a model hard token cap; unstarted cases must be recorded as blocked: token-budget-exhausted.",
|
|
17
|
-
"Default pipeline acceptance is the final frontend-test-result-v1 plus testcase/frontend/reports/frontend-test-report.html",
|
|
17
|
+
"Default pipeline acceptance is the final frontend-test-result-v1 plus .harness/testcase/frontend/reports/frontend-test-report.html",
|
|
18
18
|
"Default frontendTest.reviewMode=off uses mechanical checklist-shell before materialize; set reviewMode=blocking for legacy dual LLM review gate.",
|
|
19
19
|
"playwright-cli-only: generators and executors may call only skill-declared playwright-cli commands; bare playwright / npx playwright / @playwright/test / Playwright source are forbidden with no native Playwright fallback.",
|
|
20
20
|
"Browser-tool preflight (preflight-frontend-browser-tool-shell) must reject CODE_AGENT_PI_BACKEND=cli-only, verify the Pi SDK structured custom-tool surface, and confirm the verified playwright-cli launcher + --help open/close/find/snapshot/click contract before any frontend-test Pi node; it does not select or freeze the tested URL; missing capability/CLI fails with zero Pi calls.",
|
|
@@ -57,16 +57,16 @@
|
|
|
57
57
|
"complexity": "LOW",
|
|
58
58
|
"writePolicy": "exclusive",
|
|
59
59
|
"writeSet": [
|
|
60
|
-
"testcase/frontend/rag/**"
|
|
60
|
+
".harness/testcase/frontend/rag/**"
|
|
61
61
|
],
|
|
62
62
|
"allowedPaths": [
|
|
63
|
-
"testcase/frontend/rag/**"
|
|
63
|
+
".harness/testcase/frontend/rag/**"
|
|
64
64
|
],
|
|
65
65
|
"forbiddenPaths": [
|
|
66
66
|
".harness/**",
|
|
67
67
|
"artifacts/**"
|
|
68
68
|
],
|
|
69
|
-
"outputContract": "Write testcase/frontend/rag/standard-scenarios.v1.json for generate-time standard scenario coverage. Copy docs/templates or harness.json governanceRoot templates (including ai_workspace/loop-agent/templates) when present; otherwise write the minimal STD-FE-SMOKE-ENTRY fallback.",
|
|
69
|
+
"outputContract": "Write .harness/testcase/frontend/rag/standard-scenarios.v1.json for generate-time standard scenario coverage. Copy docs/templates or harness.json governanceRoot templates (including ai_workspace/loop-agent/templates) when present; otherwise write the minimal STD-FE-SMOKE-ENTRY fallback.",
|
|
70
70
|
"subtask_prompt": "Prepare frontend-test package: materialize standard-scenarios.v1.json into the RAG package from docs/templates, governanceRoot/templates, or the init-projected ai_workspace/loop-agent/templates path.",
|
|
71
71
|
"shell": {
|
|
72
72
|
"commands": [],
|
|
@@ -86,11 +86,11 @@
|
|
|
86
86
|
"complexity": "MED",
|
|
87
87
|
"writePolicy": "exclusive",
|
|
88
88
|
"writeSet": [
|
|
89
|
-
"testcase/frontend/rag/**"
|
|
89
|
+
".harness/testcase/frontend/rag/**"
|
|
90
90
|
],
|
|
91
91
|
"allowedPaths": [
|
|
92
92
|
"REPLACE/WITH/SOURCE/PATH/**",
|
|
93
|
-
"testcase/frontend/rag/**"
|
|
93
|
+
".harness/testcase/frontend/rag/**"
|
|
94
94
|
],
|
|
95
95
|
"forbiddenPaths": [
|
|
96
96
|
".harness/**",
|
|
@@ -110,17 +110,17 @@
|
|
|
110
110
|
"complexity": "LOW",
|
|
111
111
|
"writePolicy": "exclusive",
|
|
112
112
|
"writeSet": [
|
|
113
|
-
"testcase/frontend/rag/**"
|
|
113
|
+
".harness/testcase/frontend/rag/**"
|
|
114
114
|
],
|
|
115
115
|
"allowedPaths": [
|
|
116
|
-
"testcase/frontend/rag/**"
|
|
116
|
+
".harness/testcase/frontend/rag/**"
|
|
117
117
|
],
|
|
118
118
|
"forbiddenPaths": [
|
|
119
119
|
".harness/**",
|
|
120
120
|
"artifacts/**"
|
|
121
121
|
],
|
|
122
122
|
"outputContract": "Fail-closed environment preflight: absolute non-production baseUrl + curl HTTP reachability; writes environmentProbe facts; unreachable => blockedReason frontend-base-url-unreachable with errorClass (connection-refused / dns-unresolved / connect-timeout / http-N). Node ERROR so generate/map do not run. Does not start the app.",
|
|
123
|
-
"subtask_prompt": "Parse the concrete baseUrl selected by retrieve-frontend-test-context-pi from testcase/frontend/rag/context.md. Reject production, non-http(s), credentials, query and fragment. Probe with curl (HEAD then GET fallback; connect/max-time; no auth/cookie). 2xx/3xx => reachable and continue. Connection refused records errorClass=connection-refused and tells the operator to start the local app then rerun from this node. 4xx/5xx/DNS/timeout/TLS => blockedReason frontend-base-url-unreachable. Missing curl => blockedReason curl-unavailable. Do not start the app.",
|
|
123
|
+
"subtask_prompt": "Parse the concrete baseUrl selected by retrieve-frontend-test-context-pi from .harness/testcase/frontend/rag/context.md. Reject production, non-http(s), credentials, query and fragment. Probe with curl (HEAD then GET fallback; connect/max-time; no auth/cookie). 2xx/3xx => reachable and continue. Connection refused records errorClass=connection-refused and tells the operator to start the local app then rerun from this node. 4xx/5xx/DNS/timeout/TLS => blockedReason frontend-base-url-unreachable. Missing curl => blockedReason curl-unavailable. Do not start the app.",
|
|
124
124
|
"shell": {
|
|
125
125
|
"commands": [],
|
|
126
126
|
"frontendTestEnvironmentProbe": {},
|
|
@@ -139,13 +139,13 @@
|
|
|
139
139
|
"complexity": "HIGH",
|
|
140
140
|
"writePolicy": "exclusive",
|
|
141
141
|
"writeSet": [
|
|
142
|
-
"testcase/frontend/cases/FE-*.md",
|
|
143
|
-
"testcase/frontend/cases/index.md",
|
|
144
|
-
"testcase/frontend/cases/manifest.draft.json"
|
|
142
|
+
".harness/testcase/frontend/cases/FE-*.md",
|
|
143
|
+
".harness/testcase/frontend/cases/index.md",
|
|
144
|
+
".harness/testcase/frontend/cases/manifest.draft.json"
|
|
145
145
|
],
|
|
146
146
|
"allowedPaths": [
|
|
147
|
-
"testcase/frontend/rag/**",
|
|
148
|
-
"testcase/frontend/cases/**"
|
|
147
|
+
".harness/testcase/frontend/rag/**",
|
|
148
|
+
".harness/testcase/frontend/cases/**"
|
|
149
149
|
],
|
|
150
150
|
"forbiddenPaths": [
|
|
151
151
|
".harness/**",
|
|
@@ -165,11 +165,11 @@
|
|
|
165
165
|
"complexity": "LOW",
|
|
166
166
|
"writePolicy": "exclusive",
|
|
167
167
|
"writeSet": [
|
|
168
|
-
"testcase/frontend/cases/**"
|
|
168
|
+
".harness/testcase/frontend/cases/**"
|
|
169
169
|
],
|
|
170
170
|
"allowedPaths": [
|
|
171
|
-
"testcase/frontend/rag/**",
|
|
172
|
-
"testcase/frontend/cases/**"
|
|
171
|
+
".harness/testcase/frontend/rag/**",
|
|
172
|
+
".harness/testcase/frontend/cases/**"
|
|
173
173
|
],
|
|
174
174
|
"forbiddenPaths": [
|
|
175
175
|
".harness/**",
|
|
@@ -219,7 +219,7 @@
|
|
|
219
219
|
"executor": "pi",
|
|
220
220
|
"role": "implementer",
|
|
221
221
|
"skills": [
|
|
222
|
-
"playwright-cli"
|
|
222
|
+
"builtin:playwright-cli"
|
|
223
223
|
],
|
|
224
224
|
"toolProfile": "write",
|
|
225
225
|
"commandPolicy": {
|
|
@@ -233,17 +233,17 @@
|
|
|
233
233
|
"outputContract": "Compact JSON <=1200 chars. Browser actions must use structured playwright_cli tool.",
|
|
234
234
|
"writePolicy": "exclusive",
|
|
235
235
|
"allowedPaths": [
|
|
236
|
-
"testcase/frontend/cases/{{case.caseId}}.md",
|
|
237
|
-
"testcase/frontend/rag/context.md",
|
|
238
|
-
"testcase/frontend/rag/coverage-map.md",
|
|
239
|
-
"testcase/frontend/evidence/{{case.caseId}}/**"
|
|
236
|
+
".harness/testcase/frontend/cases/{{case.caseId}}.md",
|
|
237
|
+
".harness/testcase/frontend/rag/context.md",
|
|
238
|
+
".harness/testcase/frontend/rag/coverage-map.md",
|
|
239
|
+
".harness/testcase/frontend/evidence/{{case.caseId}}/**"
|
|
240
240
|
],
|
|
241
241
|
"forbiddenPaths": [
|
|
242
242
|
".harness/**",
|
|
243
243
|
"artifacts/**"
|
|
244
244
|
],
|
|
245
245
|
"writeSet": [
|
|
246
|
-
"testcase/frontend/evidence/{{case.caseId}}/**"
|
|
246
|
+
".harness/testcase/frontend/evidence/{{case.caseId}}/**"
|
|
247
247
|
],
|
|
248
248
|
"writeGuardPolicy": "tools-only"
|
|
249
249
|
}
|
|
@@ -259,11 +259,11 @@
|
|
|
259
259
|
"complexity": "LOW",
|
|
260
260
|
"writePolicy": "exclusive",
|
|
261
261
|
"writeSet": [
|
|
262
|
-
"testcase/frontend/evidence/**"
|
|
262
|
+
".harness/testcase/frontend/evidence/**"
|
|
263
263
|
],
|
|
264
264
|
"allowedPaths": [
|
|
265
|
-
"testcase/frontend/cases/**",
|
|
266
|
-
"testcase/frontend/evidence/**"
|
|
265
|
+
".harness/testcase/frontend/cases/**",
|
|
266
|
+
".harness/testcase/frontend/evidence/**"
|
|
267
267
|
],
|
|
268
268
|
"forbiddenPaths": [
|
|
269
269
|
".harness/**",
|
|
@@ -273,7 +273,7 @@
|
|
|
273
273
|
"subtask_prompt": "Select frontend-test cases eligible for bounded rerun.",
|
|
274
274
|
"shell": {
|
|
275
275
|
"commands": [
|
|
276
|
-
"node -e \"const fs=require('fs'),path=require('path');const manifestPath='testcase/frontend/cases/manifest.json';if(!fs.existsSync(manifestPath)){process.stdout.write(JSON.stringify({cases:[]}));process.exit(0);}const manifest=JSON.parse(fs.readFileSync(manifestPath,'utf8'));const cases=[];for(const c of (manifest.cases||[])){const evidenceDir=(c.evidenceDir||('testcase/frontend/evidence/'+c.caseId+'/')).replace(/\\/+$/,'')+'/';const resultPath=path.join(evidenceDir,'case-result.json');const execPath=path.join(evidenceDir,'execution.md');let reason=null;let attempt=0;let missing=false;if(!fs.existsSync(resultPath)){missing=true;reason='missing-result-files';}else{try{const r=JSON.parse(fs.readFileSync(resultPath,'utf8'));attempt=Number(r.rerunAttempt||0)||0;if(r.status==='blocked')reason='blocked';if(!r.status){missing=true;reason='missing-result-files';}}catch(e){missing=true;reason='missing-result-files';}}if(!fs.existsSync(execPath)){const st=reason;if(st!=='blocked'){missing=true;reason=reason||'missing-result-files';}}const should=(reason==='blocked'||missing)&&attempt<1;if(should){cases.push({caseId:c.caseId,casePath:c.casePath||('testcase/frontend/cases/'+c.caseId+'.md'),evidenceDir,dimension:c.dimension||'core',acIds:c.acIds||[],rerunAttempt:attempt+1,reason:reason||'blocked'});}}const out={schemaVersion:1,cases};fs.mkdirSync('testcase/frontend/evidence',{recursive:true});fs.writeFileSync('testcase/frontend/evidence/rerun-candidates.json',JSON.stringify(out,null,2)+'\\n');process.stdout.write(JSON.stringify({cases}));"
|
|
276
|
+
"node -e \"const fs=require('fs'),path=require('path');const manifestPath='.harness/testcase/frontend/cases/manifest.json';if(!fs.existsSync(manifestPath)){process.stdout.write(JSON.stringify({cases:[]}));process.exit(0);}const manifest=JSON.parse(fs.readFileSync(manifestPath,'utf8'));const cases=[];for(const c of (manifest.cases||[])){const evidenceDir=(c.evidenceDir||('.harness/testcase/frontend/evidence/'+c.caseId+'/')).replace(/\\/+$/,'')+'/';const resultPath=path.join(evidenceDir,'case-result.json');const execPath=path.join(evidenceDir,'execution.md');let reason=null;let attempt=0;let missing=false;if(!fs.existsSync(resultPath)){missing=true;reason='missing-result-files';}else{try{const r=JSON.parse(fs.readFileSync(resultPath,'utf8'));attempt=Number(r.rerunAttempt||0)||0;if(r.status==='blocked')reason='blocked';if(!r.status){missing=true;reason='missing-result-files';}}catch(e){missing=true;reason='missing-result-files';}}if(!fs.existsSync(execPath)){const st=reason;if(st!=='blocked'){missing=true;reason=reason||'missing-result-files';}}const should=(reason==='blocked'||missing)&&attempt<1;if(should){cases.push({caseId:c.caseId,casePath:c.casePath||('.harness/testcase/frontend/cases/'+c.caseId+'.md'),evidenceDir,dimension:c.dimension||'core',acIds:c.acIds||[],rerunAttempt:attempt+1,reason:reason||'blocked'});}}const out={schemaVersion:1,cases};fs.mkdirSync('.harness/testcase/frontend/evidence',{recursive:true});fs.writeFileSync('.harness/testcase/frontend/evidence/rerun-candidates.json',JSON.stringify(out,null,2)+'\\n');process.stdout.write(JSON.stringify({cases}));"
|
|
277
277
|
],
|
|
278
278
|
"cwd": ".",
|
|
279
279
|
"timeoutMs": 120000
|
|
@@ -314,7 +314,7 @@
|
|
|
314
314
|
"executor": "pi",
|
|
315
315
|
"role": "implementer",
|
|
316
316
|
"skills": [
|
|
317
|
-
"playwright-cli"
|
|
317
|
+
"builtin:playwright-cli"
|
|
318
318
|
],
|
|
319
319
|
"toolProfile": "write",
|
|
320
320
|
"commandPolicy": {
|
|
@@ -328,17 +328,17 @@
|
|
|
328
328
|
"outputContract": "Compact JSON <=1200 chars. Browser actions must use structured playwright_cli tool.",
|
|
329
329
|
"writePolicy": "exclusive",
|
|
330
330
|
"allowedPaths": [
|
|
331
|
-
"testcase/frontend/cases/{{case.caseId}}.md",
|
|
332
|
-
"testcase/frontend/rag/context.md",
|
|
333
|
-
"testcase/frontend/rag/coverage-map.md",
|
|
334
|
-
"testcase/frontend/evidence/{{case.caseId}}/**"
|
|
331
|
+
".harness/testcase/frontend/cases/{{case.caseId}}.md",
|
|
332
|
+
".harness/testcase/frontend/rag/context.md",
|
|
333
|
+
".harness/testcase/frontend/rag/coverage-map.md",
|
|
334
|
+
".harness/testcase/frontend/evidence/{{case.caseId}}/**"
|
|
335
335
|
],
|
|
336
336
|
"forbiddenPaths": [
|
|
337
337
|
".harness/**",
|
|
338
338
|
"artifacts/**"
|
|
339
339
|
],
|
|
340
340
|
"writeSet": [
|
|
341
|
-
"testcase/frontend/evidence/{{case.caseId}}/**"
|
|
341
|
+
".harness/testcase/frontend/evidence/{{case.caseId}}/**"
|
|
342
342
|
],
|
|
343
343
|
"writeGuardPolicy": "tools-only"
|
|
344
344
|
}
|
|
@@ -354,11 +354,11 @@
|
|
|
354
354
|
"complexity": "LOW",
|
|
355
355
|
"writePolicy": "exclusive",
|
|
356
356
|
"writeSet": [
|
|
357
|
-
"testcase/frontend/evidence/**"
|
|
357
|
+
".harness/testcase/frontend/evidence/**"
|
|
358
358
|
],
|
|
359
359
|
"allowedPaths": [
|
|
360
|
-
"testcase/frontend/cases/**",
|
|
361
|
-
"testcase/frontend/evidence/**"
|
|
360
|
+
".harness/testcase/frontend/cases/**",
|
|
361
|
+
".harness/testcase/frontend/evidence/**"
|
|
362
362
|
],
|
|
363
363
|
"forbiddenPaths": [
|
|
364
364
|
".harness/**",
|
|
@@ -383,10 +383,10 @@
|
|
|
383
383
|
"complexity": "LOW",
|
|
384
384
|
"writePolicy": "exclusive",
|
|
385
385
|
"writeSet": [
|
|
386
|
-
"testcase/frontend/reports/**"
|
|
386
|
+
".harness/testcase/frontend/reports/**"
|
|
387
387
|
],
|
|
388
388
|
"allowedPaths": [
|
|
389
|
-
"testcase/frontend/**"
|
|
389
|
+
".harness/testcase/frontend/**"
|
|
390
390
|
],
|
|
391
391
|
"forbiddenPaths": [
|
|
392
392
|
".harness/**",
|
|
@@ -403,5 +403,14 @@
|
|
|
403
403
|
"timeoutMs": 120000
|
|
404
404
|
}
|
|
405
405
|
}
|
|
406
|
-
]
|
|
406
|
+
],
|
|
407
|
+
"frontendTestLayout": {
|
|
408
|
+
"testRoot": ".harness/testcase/frontend",
|
|
409
|
+
"ragDir": ".harness/testcase/frontend/rag",
|
|
410
|
+
"casesDir": ".harness/testcase/frontend/cases",
|
|
411
|
+
"evidenceDir": ".harness/testcase/frontend/evidence",
|
|
412
|
+
"reportsDir": ".harness/testcase/frontend/reports",
|
|
413
|
+
"fixturesDir": ".harness/testcase/frontend/fixtures",
|
|
414
|
+
"isDefault": true
|
|
415
|
+
}
|
|
407
416
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Retrieve frontend test context
|
|
2
2
|
|
|
3
|
-
Write only
|
|
3
|
+
Write only `.harness/testcase/frontend/rag/context.md` and `coverage-map.md`. Record traceable facts from the task source, routes, components, API/Mock contracts, existing tests and execution contract. Do not invent fields, credentials, limits or test data.
|
|
4
4
|
|
|
5
5
|
## Runtime Base URL resolution (required)
|
|
6
6
|
|
|
@@ -17,5 +17,5 @@ Do not claim the environment is reachable until preflight completes. Preflight d
|
|
|
17
17
|
|
|
18
18
|
## Standard scenario coverage
|
|
19
19
|
|
|
20
|
-
- Copy or reference `docs/templates/frontend-test-standard-scenarios.v1.json`, `harness.json` `governanceRoot`/templates, or the init-projected `ai_workspace/loop-agent/templates/frontend-test-standard-scenarios.v1.json` into
|
|
20
|
+
- Copy or reference `docs/templates/frontend-test-standard-scenarios.v1.json`, `harness.json` `governanceRoot`/templates, or the init-projected `ai_workspace/loop-agent/templates/frontend-test-standard-scenarios.v1.json` into `.harness/testcase/frontend/rag/standard-scenarios.v1.json` when available.
|
|
21
21
|
- Add `## Standard scenario coverage` to coverage-map.md with planned/n/a for each must scenario.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# Frontend test retrospective
|
|
2
2
|
|
|
3
|
-
Write a dated report under
|
|
3
|
+
Write a dated report under `.harness/testcase/frontend/reports/` (for example `frontend-test-retrospect-<date>.md`) after `frontend-test-result-v1` materialization. Do **not** require outcome=pass; failed, incomplete, and blocked runs still need a report.
|
|
4
4
|
|
|
5
5
|
Combine a short AC → case → browser-evidence review with the closeout: case coverage, passed/failed/blocked results (including `token-budget-exhausted`), evidence gaps, browser anomalies, residual risks, and an A/B/C/D maturity rating. Cite the deterministic case-evidence validation outcome. Passed cases should reference the successful `find` assertion plus screenshot or equivalent browser evidence and the ordered post-execution cleanup receipt when available; failed/blocked cases need explicit reasons. Blocked cases never count as passed; a missing or malformed `execution.md` / `case-result.json` is a verification gap, not a pass. Do not write under `docs/**`.
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
Read the RAG files and Markdown cases only. First line must be `VERDICT: pass` or `VERDICT: request-revision`. Report AC coverage, case independence, evidence completeness, unsafe environment/data dependencies, and manifest issues. This verdict is a deterministic safety gate: `request-revision` blocks manifest materialization and browser execution.
|
|
4
4
|
|
|
5
|
-
Every case must retain the exact browser-start command prefix with the resolved absolute baseUrl from
|
|
5
|
+
Every case must retain the exact browser-start command prefix with the resolved absolute baseUrl from `.harness/testcase/frontend/rag/context.md` (prefer task source `config.md`, else `http://localhost:5173`): `playwright-cli open --browser=chrome <resolved-base-url>`; session flags must not precede `open`, and subsequent commands must remain in its default session without `-s=` or assumed named-session binding. Verify every executable sub-scenario specifies fixture/reset, UI reset, fresh snapshot before element refs, a successful `playwright-cli find ...` semantic assertion after `open`, and an evidence write point. `snapshot`, `goto`, `screenshot`, `request`/`console`, and ordinary interactions cannot independently authorize passed. Verify each case requires both `execution.md` and `case-result.json` under its own evidence directory. The JSON result must contain matching `caseId`, `status` (`passed`, `failed`, or `blocked`) and `evidencePaths`; blocked cases must name a non-empty `blockedReason` and cannot count as passed.
|
|
@@ -26,30 +26,30 @@
|
|
|
26
26
|
"executor": "pi",
|
|
27
27
|
"contextProfile": "slim",
|
|
28
28
|
"skills": [
|
|
29
|
-
"ai-engineering-context"
|
|
29
|
+
"builtin:ai-engineering-context"
|
|
30
30
|
],
|
|
31
31
|
"writePolicy": "read-only"
|
|
32
32
|
},
|
|
33
33
|
"skillsByRole": {
|
|
34
34
|
"planner": [
|
|
35
|
-
"loop-agent"
|
|
35
|
+
"builtin:loop-agent"
|
|
36
36
|
],
|
|
37
37
|
"scout": [
|
|
38
|
-
"ai-engineering-context"
|
|
38
|
+
"builtin:ai-engineering-context"
|
|
39
39
|
],
|
|
40
40
|
"implementer": [
|
|
41
|
-
"verification-before-completion"
|
|
41
|
+
"builtin:verification-before-completion"
|
|
42
42
|
],
|
|
43
43
|
"reviewer": [
|
|
44
|
-
"requesting-code-review"
|
|
44
|
+
"builtin:requesting-code-review"
|
|
45
45
|
],
|
|
46
46
|
"verifier": [
|
|
47
|
-
"verification-before-completion",
|
|
48
|
-
"systematic-debugging"
|
|
47
|
+
"builtin:verification-before-completion",
|
|
48
|
+
"builtin:systematic-debugging"
|
|
49
49
|
],
|
|
50
50
|
"closeout": [
|
|
51
|
-
"loop-agent",
|
|
52
|
-
"verification-before-completion"
|
|
51
|
+
"builtin:loop-agent",
|
|
52
|
+
"builtin:verification-before-completion"
|
|
53
53
|
]
|
|
54
54
|
},
|
|
55
55
|
"executorModels": {
|
|
@@ -26,27 +26,27 @@
|
|
|
26
26
|
"executor": "pi",
|
|
27
27
|
"contextProfile": "slim",
|
|
28
28
|
"skills": [
|
|
29
|
-
"ai-engineering-context"
|
|
29
|
+
"builtin:ai-engineering-context"
|
|
30
30
|
],
|
|
31
31
|
"writePolicy": "read-only"
|
|
32
32
|
},
|
|
33
33
|
"skillsByRole": {
|
|
34
34
|
"planner": [
|
|
35
|
-
"loop-agent"
|
|
35
|
+
"builtin:loop-agent"
|
|
36
36
|
],
|
|
37
37
|
"implementer": [
|
|
38
|
-
"verification-before-completion"
|
|
38
|
+
"builtin:verification-before-completion"
|
|
39
39
|
],
|
|
40
40
|
"reviewer": [
|
|
41
|
-
"requesting-code-review"
|
|
41
|
+
"builtin:requesting-code-review"
|
|
42
42
|
],
|
|
43
43
|
"verifier": [
|
|
44
|
-
"verification-before-completion",
|
|
45
|
-
"systematic-debugging"
|
|
44
|
+
"builtin:verification-before-completion",
|
|
45
|
+
"builtin:systematic-debugging"
|
|
46
46
|
],
|
|
47
47
|
"closeout": [
|
|
48
|
-
"loop-agent",
|
|
49
|
-
"verification-before-completion"
|
|
48
|
+
"builtin:loop-agent",
|
|
49
|
+
"builtin:verification-before-completion"
|
|
50
50
|
]
|
|
51
51
|
},
|
|
52
52
|
"tasks": [
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tea-agent/loop-agent",
|
|
3
|
-
"version": "0.44.0-next.
|
|
3
|
+
"version": "0.44.0-next.14",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"loop-agent": "bin/loop-agent.js",
|
|
@@ -27,6 +27,8 @@
|
|
|
27
27
|
"docs/templates/",
|
|
28
28
|
"examples/",
|
|
29
29
|
"harness.json",
|
|
30
|
+
"resource-catalog.v1.json",
|
|
31
|
+
"resources/",
|
|
30
32
|
"skills/",
|
|
31
33
|
"scripts/kb-bootstrap-init-skeleton.sh",
|
|
32
34
|
"scripts/kb-query.mjs",
|
|
@@ -51,13 +53,15 @@
|
|
|
51
53
|
"pi-prompt": "node --import tsx/esm src/cli.ts pi-prompt",
|
|
52
54
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
53
55
|
"brand:sync": "node scripts/sync-brand-assets.mjs",
|
|
54
|
-
"build": "npm run brand:sync && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build && node scripts/write-build-stamp.mjs",
|
|
56
|
+
"build": "npm run brand:sync && npm run resource-catalog:generate && npm run clean && tsc -p tsconfig.build.json && node -e \"const fs=require('node:fs');const p='dist/worker/observe/static';fs.mkdirSync(p,{recursive:true});fs.cpSync('src/worker/observe/static',p,{recursive:true});\" && npm run console:build && node scripts/write-build-stamp.mjs",
|
|
55
57
|
"console:typecheck": "tsc -p src/worker/console/tsconfig.json",
|
|
56
58
|
"console:build": "npm run console:typecheck && vite build --config src/worker/console/vite.config.ts",
|
|
57
59
|
"console:dev": "node --import tsx/esm scripts/console-dev.mjs",
|
|
58
60
|
"prepack": "npm run build",
|
|
59
61
|
"prepublishOnly": "node scripts/check-npm-publish-policy.mjs && npm run typecheck && npm run test:full && npm run build",
|
|
60
62
|
"lint": "npm run typecheck",
|
|
63
|
+
"resource-catalog:generate": "node scripts/generate-resource-catalog.mjs",
|
|
64
|
+
"resource-catalog:check": "node scripts/generate-resource-catalog.mjs --check",
|
|
61
65
|
"typecheck": "node --max-old-space-size=4096 ./node_modules/typescript/bin/tsc --noEmit && npm run console:typecheck",
|
|
62
66
|
"test": "node scripts/run-tests.mjs",
|
|
63
67
|
"test:full": "node scripts/run-tests.mjs --full",
|
|
@@ -79,19 +83,23 @@
|
|
|
79
83
|
"@deepseek-ai/dsh-invariants": "0.1.1-rc.2",
|
|
80
84
|
"@earendil-works/pi-ai": "0.84.4",
|
|
81
85
|
"@earendil-works/pi-coding-agent": "0.84.4",
|
|
86
|
+
"@mozilla/readability": "^0.6.0",
|
|
87
|
+
"@playwright/cli": "0.1.20",
|
|
82
88
|
"@xterm/addon-fit": "^0.11.0",
|
|
83
89
|
"@xterm/xterm": "^6.0.0",
|
|
84
90
|
"commander": "^12.1.0",
|
|
85
91
|
"katex": "^0.16.47",
|
|
92
|
+
"linkedom": "^0.18.13",
|
|
86
93
|
"mermaid": "^11.16.1",
|
|
87
94
|
"mysql2": "^3.24.4",
|
|
88
95
|
"node-pty": "^1.2.0-beta.15",
|
|
89
96
|
"pg": "^8.23.0",
|
|
90
|
-
"playwright-core": "
|
|
97
|
+
"playwright-core": "1.64.0-alpha-2026-09-14",
|
|
91
98
|
"rehype-highlight": "^7.0.2",
|
|
92
99
|
"rehype-katex": "^7.0.1",
|
|
93
100
|
"remark-math": "^6.0.0",
|
|
94
101
|
"semver": "^7.8.5",
|
|
102
|
+
"turndown": "^7.2.4",
|
|
95
103
|
"typebox": "1.3.7",
|
|
96
104
|
"yaml": "^2.9.0",
|
|
97
105
|
"zod": "^3.25.76",
|
|
@@ -107,6 +115,7 @@
|
|
|
107
115
|
"@types/react": "^19.1.8",
|
|
108
116
|
"@types/react-dom": "^19.1.6",
|
|
109
117
|
"@types/semver": "^7.7.1",
|
|
118
|
+
"@types/turndown": "^5.0.6",
|
|
110
119
|
"@vitest/coverage-v8": "^4.1.11",
|
|
111
120
|
"fast-check": "^4.10.0",
|
|
112
121
|
"react": "^19.1.0",
|