@tea-agent/loop-agent 0.27.1 → 0.28.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.
- package/CHANGELOG.md +24 -0
- package/dist/application/task-lifecycle/observe.js +5 -0
- package/dist/application/task-lifecycle/plan-transitions.js +7 -2
- package/dist/cli/program.js +1 -1
- package/dist/commands/client-recovery.js +439 -20
- package/dist/commands/init.js +42 -6
- package/dist/executors/dag-pi-executor.js +143 -38
- package/dist/executors/pi-playwright-cli-tool.js +955 -0
- package/dist/executors/pi-sdk-executor.js +56 -0
- package/dist/executors/playwright-cli-launcher.js +63 -0
- package/dist/executors/shell-executor.js +128 -0
- package/dist/shared/playwright-cli-command-policy.js +41 -0
- package/dist/worker/observability/read-model.js +66 -8
- package/dist/worker/observe/static/dag-model.js +85 -13
- package/dist/workflows/dag/dynamic-runtime/loop-until.js +4 -0
- package/dist/workflows/dag/dynamic-runtime/map.js +13 -13
- package/dist/workflows/dag/frontend-test-case-checklist.js +201 -8
- package/dist/workflows/dag/frontend-test-result-contract.js +52 -3
- package/dist/workflows/dag/init-hybrid.js +116 -30
- package/dist/workflows/dag/lifecycle.js +33 -2
- package/dist/workflows/dag/node-execution.js +11 -5
- package/dist/workflows/dag/output-protocol.js +25 -83
- package/dist/workflows/dag/report.js +9 -2
- package/dist/workflows/dag/rerun-run.js +62 -3
- package/dist/workflows/dag/run-store.js +6 -1
- package/dist/workflows/dag/runner.js +15 -3
- package/dist/workflows/dag/types.js +27 -0
- package/dist/workflows/dag/validate.js +121 -1
- package/docs/architecture/runtime-boundaries.md +13 -11
- package/docs/init-surface.manifest.json +6 -2
- package/docs/templates/README.md +9 -1
- package/docs/templates/frontend-test-dag.generate-cases.prompt.md +14 -7
- package/docs/templates/frontend-test-dag.json +55 -15
- package/docs/templates/frontend-test-dag.retrieve-context.prompt.md +7 -9
- 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/frontend-test-dag.review-execution.prompt.md +1 -1
- package/harness.json +1 -1
- package/package.json +1 -1
- package/skills/loop-agent/SKILL.md +1 -1
- package/skills/loop-agent/references/command-reference.md +18 -6
- package/skills/playwright-cli/SKILL.md +69 -402
- package/skills/playwright-cli/references/tracing.md +3 -137
- package/skills/playwright-cli/references/video-recording.md +3 -141
- package/skills/playwright-cli-case-generator/SKILL.md +53 -46
|
@@ -11,19 +11,46 @@
|
|
|
11
11
|
"globalConstraints": [
|
|
12
12
|
"Do not generate pytest or Playwright source code.",
|
|
13
13
|
"Only use declared isolated test environments; production URLs and real credentials are blocked.",
|
|
14
|
-
"Every generated browser start command
|
|
14
|
+
"Every generated browser start command uses playwright-cli open --browser=chrome --headed followed by the concrete controller-resolved URL (from task source config.md when present, else http://localhost:5173); 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
17
|
"Default pipeline acceptance is the final retrospect report under testcase/frontend/reports/; case full green is optional quality (frontendTest.strictOutcomeGate).",
|
|
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
|
+
"Browser-tool preflight (preflight-frontend-browser-tool-shell) must reject CODE_AGENT_PI_BACKEND=cli-only, verify the Pi SDK structured custom-tool surface, freeze baseUrl from hash-bound task source config.md (or controller default localhost), and confirm the verified playwright-cli launcher + --help contract before any frontend-test Pi node; missing capability/CLI fails with zero Pi calls.",
|
|
21
|
+
"Case executors use structured playwright_cli custom tool under commandPolicy capability-allowlist; ordinary writers stay without Bash.",
|
|
22
|
+
"File outputs use canonical --filename: playwright-cli screenshot --filename final.png (a real target/ref may precede it), playwright-cli pdf --filename final.pdf, and playwright-cli snapshot --filename snapshot.txt only when a snapshot file is needed; a snapshot without filename is response-only. Never use --path, --output, --file, or an output path as a positional target.",
|
|
23
|
+
"Passed cases require same-child ordered controller receipts: successful open → successful find → successful post-execution cleanup. Pre-start cleanup, snapshot/goto/screenshot/request/console, and ordinary interactions cannot establish passed authority; model prose cannot fake green.",
|
|
20
24
|
"Environment preflight must curl-probe the frozen non-production baseUrl before generate; unreachable or curl-unavailable ends preflight as blocked (frontend-base-url-unreachable|curl-unavailable) so generate/map do not run.",
|
|
21
25
|
"U/D cases must prove current-user data ownership or create cleanable current-user data or authorized Mock; otherwise blocked (current-user-data-unavailable|data-ownership-unverifiable|safe-test-data-setup-unavailable) without cross-user mutation."
|
|
22
26
|
],
|
|
23
27
|
"tasks": [
|
|
24
28
|
{
|
|
25
|
-
"id": "
|
|
29
|
+
"id": "preflight-frontend-browser-tool-shell",
|
|
26
30
|
"depends_on": [],
|
|
31
|
+
"executor": "shell",
|
|
32
|
+
"role": "verifier",
|
|
33
|
+
"complexity": "LOW",
|
|
34
|
+
"writePolicy": "read-only",
|
|
35
|
+
"allowedPaths": [],
|
|
36
|
+
"forbiddenPaths": [
|
|
37
|
+
".harness/**",
|
|
38
|
+
"artifacts/**"
|
|
39
|
+
],
|
|
40
|
+
"outputContract": "Deterministic SDK-only browser-tool preflight before any frontend-test Pi node; freeze a controller-owned origin and fail closed with browser-command-capability-unavailable | playwright-cli-unavailable | playwright-cli-contract-incompatible.",
|
|
41
|
+
"subtask_prompt": "Reject cli-only rollback, verify the Pi SDK structured custom-tool capability, freeze baseUrl from controller-owned task source/default, and verify the controller-resolved playwright-cli launcher plus --help lists open/close/find/snapshot/click. Do not install packages. Do not start a browser session.",
|
|
42
|
+
"shell": {
|
|
43
|
+
"commands": [],
|
|
44
|
+
"frontendBrowserToolPreflight": {},
|
|
45
|
+
"cwd": ".",
|
|
46
|
+
"timeoutMs": 60000
|
|
47
|
+
}
|
|
48
|
+
},
|
|
49
|
+
{
|
|
50
|
+
"id": "retrieve-frontend-test-context-pi",
|
|
51
|
+
"depends_on": [
|
|
52
|
+
"preflight-frontend-browser-tool-shell"
|
|
53
|
+
],
|
|
27
54
|
"executor": "pi",
|
|
28
55
|
"role": "planner",
|
|
29
56
|
"toolProfile": "write",
|
|
@@ -83,7 +110,9 @@
|
|
|
83
110
|
"complexity": "HIGH",
|
|
84
111
|
"writePolicy": "exclusive",
|
|
85
112
|
"writeSet": [
|
|
86
|
-
"testcase/frontend/cases
|
|
113
|
+
"testcase/frontend/cases/FE-*.md",
|
|
114
|
+
"testcase/frontend/cases/index.md",
|
|
115
|
+
"testcase/frontend/cases/manifest.draft.json"
|
|
87
116
|
],
|
|
88
117
|
"allowedPaths": [
|
|
89
118
|
"testcase/frontend/rag/**",
|
|
@@ -93,7 +122,7 @@
|
|
|
93
122
|
".harness/**",
|
|
94
123
|
"artifacts/**"
|
|
95
124
|
],
|
|
96
|
-
"outputContract": "Markdown cases, index.md and manifest.draft.json schemaVersion 1;
|
|
125
|
+
"outputContract": "Markdown cases, index.md and manifest.draft.json schemaVersion 1 only; the exclusive materializer promotes the validated draft to manifest.json, and this generator must not write manifest.json; no test source code.",
|
|
97
126
|
"subtask_prompt_markdown": "./frontend-test-dag.generate-cases.prompt.md"
|
|
98
127
|
},
|
|
99
128
|
{
|
|
@@ -161,7 +190,9 @@
|
|
|
161
190
|
"complexity": "HIGH",
|
|
162
191
|
"writePolicy": "exclusive",
|
|
163
192
|
"writeSet": [
|
|
164
|
-
"testcase/frontend/cases
|
|
193
|
+
"testcase/frontend/cases/FE-*.md",
|
|
194
|
+
"testcase/frontend/cases/index.md",
|
|
195
|
+
"testcase/frontend/cases/manifest.draft.json"
|
|
165
196
|
],
|
|
166
197
|
"allowedPaths": [
|
|
167
198
|
"testcase/frontend/rag/**",
|
|
@@ -171,8 +202,8 @@
|
|
|
171
202
|
".harness/**",
|
|
172
203
|
"artifacts/**"
|
|
173
204
|
],
|
|
174
|
-
"outputContract": "Apply the one permitted frontend case revision; no browser execution or evidence writes.",
|
|
175
|
-
"subtask_prompt": "Apply the sole allowed case revision from the first review. Change only testcase/frontend/cases
|
|
205
|
+
"outputContract": "Apply the one permitted frontend case revision to FE-*.md, index.md, and manifest.draft.json only; must not write manifest.json; no browser execution or evidence writes.",
|
|
206
|
+
"subtask_prompt": "Apply the sole allowed case revision from the first review. Change only testcase/frontend/cases/FE-*.md, testcase/frontend/cases/index.md, and testcase/frontend/cases/manifest.draft.json; preserve AC traceability. Do not write manifest.json, execute browsers, or write evidence."
|
|
176
207
|
},
|
|
177
208
|
{
|
|
178
209
|
"id": "review-frontend-cases-final-pi",
|
|
@@ -250,8 +281,8 @@
|
|
|
250
281
|
".harness/**",
|
|
251
282
|
"artifacts/**"
|
|
252
283
|
],
|
|
253
|
-
"outputContract": "Mechanical checklist: manifest/case paths, Case ID, non-production playwright-cli open prefix, and
|
|
254
|
-
"subtask_prompt": "Run the native deterministic frontend case checklist without spawning Bash, PowerShell, or node -e.",
|
|
284
|
+
"outputContract": "Mechanical checklist: manifest/case paths, Case ID, non-production playwright-cli open prefix, AC mapping, and executable command gate; rejects alternative executable instructions and non-allowlisted playwright-cli commands with ruleId-tagged location evidence.",
|
|
285
|
+
"subtask_prompt": "Inspect and reject alternative executable instructions in fenced command code, list/indented steps, and explicit shell/terminal command lines. Only allowlisted playwright-cli command instructions may pass; ordinary prose and explicit blocked reasons may describe prohibitions. Run the native deterministic frontend case checklist without spawning Bash, PowerShell, or node -e.",
|
|
255
286
|
"shell": {
|
|
256
287
|
"commands": [],
|
|
257
288
|
"frontendTestCaseChecklist": {},
|
|
@@ -267,7 +298,10 @@
|
|
|
267
298
|
"executor": "shell",
|
|
268
299
|
"role": "verifier",
|
|
269
300
|
"complexity": "LOW",
|
|
270
|
-
"writePolicy": "
|
|
301
|
+
"writePolicy": "exclusive",
|
|
302
|
+
"writeSet": [
|
|
303
|
+
"testcase/frontend/cases/**"
|
|
304
|
+
],
|
|
271
305
|
"allowedPaths": [
|
|
272
306
|
"testcase/frontend/cases/**"
|
|
273
307
|
],
|
|
@@ -275,11 +309,11 @@
|
|
|
275
309
|
".harness/**",
|
|
276
310
|
"artifacts/**"
|
|
277
311
|
],
|
|
278
|
-
"outputContract": "Validated frontend manifest payload { cases: [...] }; ruleId-tagged fail-closed validation; atomically
|
|
279
|
-
"subtask_prompt": "
|
|
312
|
+
"outputContract": "Validated frontend manifest payload { cases: [...] }; ruleId-tagged fail-closed validation of manifest.draft.json; the exclusive materializer atomically writes testcase/frontend/cases/manifest.json via temp+rename then deletes draft; stdout is exactly one final JSON line {cases}.",
|
|
313
|
+
"subtask_prompt": "Read and validate only manifest.draft.json after the mechanical checklist passes. Normalize its case payload, atomically materialize manifest.json, then delete the draft. Do not consume a generator-authored manifest.json.",
|
|
280
314
|
"shell": {
|
|
281
315
|
"commands": [
|
|
282
|
-
"node -e \"const fs=require('fs'),path=require('path');const file='testcase/frontend/cases/manifest.json';if(!fs.existsSync(
|
|
316
|
+
"node -e \"const fs=require('fs'),path=require('path');function fail(ruleId,detail){throw new Error('frontend-test manifest blocked: '+ruleId+(detail?': '+detail:''));}const draft='testcase/frontend/cases/manifest.draft.json',file='testcase/frontend/cases/manifest.json',tmp=file+'.tmp';if(!fs.existsSync(draft))fail('draft-missing','missing '+draft);let manifest;try{manifest=JSON.parse(fs.readFileSync(draft,'utf8'));}catch(error){fail('draft-invalid-json',error.message);}if(manifest.schemaVersion!==1)fail('draft-schema','schemaVersion must be 1');if(!Array.isArray(manifest.cases)||!manifest.cases.length)fail('draft-empty-cases','cases must be a non-empty array');const dims=new Set(['core','boundary','flow','backend']),ids=new Set(),paths=new Set(),evidence=new Set();const cases=manifest.cases.map(c=>{if(!c||typeof c.caseId!=='string'||!/^FE-[A-Za-z0-9][A-Za-z0-9-]*$/.test(c.caseId)||ids.has(c.caseId))fail('case-id-shape','invalid or duplicate caseId');ids.add(c.caseId);if(!dims.has(c.dimension))fail('invalid-dimension',String(c.dimension));if(!Array.isArray(c.acIds)||!c.acIds.length||c.acIds.some(a=>typeof a!=='string'||!a.trim()))fail('ac-mapping','invalid acIds');const casePath='testcase/frontend/cases/'+c.caseId+'.md',evidenceDir='testcase/frontend/evidence/'+c.caseId+'/';if(path.isAbsolute(casePath)||casePath.includes('..')||!fs.existsSync(casePath))fail('case-file-missing',casePath);if(paths.has(casePath))fail('duplicate-case-path',casePath);paths.add(casePath);if(evidence.has(evidenceDir))fail('duplicate-evidence-dir',evidenceDir);evidence.add(evidenceDir);return {caseId:c.caseId,casePath,dimension:c.dimension,acIds:[...c.acIds],evidenceDir};});fs.writeFileSync(tmp,JSON.stringify({schemaVersion:1,cases},null,2)+'\\n');fs.renameSync(tmp,file);fs.unlinkSync(draft);process.stdout.write(JSON.stringify({cases}));\""
|
|
283
317
|
],
|
|
284
318
|
"cwd": ".",
|
|
285
319
|
"timeoutMs": 120000
|
|
@@ -323,9 +357,15 @@
|
|
|
323
357
|
"playwright-cli"
|
|
324
358
|
],
|
|
325
359
|
"toolProfile": "write",
|
|
360
|
+
"commandPolicy": {
|
|
361
|
+
"mode": "capability-allowlist",
|
|
362
|
+
"capabilities": [
|
|
363
|
+
"playwright-cli"
|
|
364
|
+
]
|
|
365
|
+
},
|
|
326
366
|
"complexity": "MED",
|
|
327
|
-
"subtaskPromptTemplate": "Primary job: EXECUTE {{case.caseId}} from {{case.casePath}} with skill playwright-cli (fresh Pi session).
|
|
328
|
-
"outputContract": "Compact JSON <=1200 chars.",
|
|
367
|
+
"subtaskPromptTemplate": "Primary job: EXECUTE {{case.caseId}} from {{case.casePath}} with skill playwright-cli (fresh Pi session). Use the structured playwright_cli tool for every browser action. Do not request or search for bash. Translate each playwright-cli line in the case Markdown into one playwright_cli tool call. The controller-owned browser capability freezes baseUrl from hash-bound task source config.md or the localhost default; context/case prose may reference but cannot establish or override that origin. Start only with playwright_cli command=open and controller-injected concrete frozen URL args (default session; no -s=). Dynamic refs: literal eX/eY are documentation placeholders, not tool args. Immediately before every structured playwright_cli call that references an element, parse the actual eNN from the immediately preceding latest snapshot and pass only that actual eNN. Never send literal eX/eY, and never reuse a stale ref after a new snapshot. File outputs are canonical: screenshot uses [--filename, final.png] (or [e5, --filename, final.png] only for a real target), pdf uses [--filename, final.pdf], and snapshot writes a file only with [--filename, snapshot.txt]; snapshot without filename is response-only. Never use --path, --output, --file, or an output path as a positional target. Passed authority requires same-child ordered controller receipts: successful open → successful find → successful post-execution cleanup. Only successful find is meaningful; snapshot, goto, screenshot, request/console, and ordinary interactions cannot establish passed. Only when preflight or playwright_cli tool explicitly fails may you write blocked evidence. Always persist {{case.evidenceDir}}execution.md and {{case.evidenceDir}}case-result.json (caseId, status passed|failed|blocked, evidencePaths; blocked needs blockedReason). Business failed/blocked is not a node failure. Close via playwright_cli command=close. Return compact JSON (<=1200 chars): {caseId,status,evidencePaths,errorSummary,tokens}.",
|
|
368
|
+
"outputContract": "Compact JSON <=1200 chars. Browser actions must use structured playwright_cli tool.",
|
|
329
369
|
"writePolicy": "exclusive",
|
|
330
370
|
"allowedPaths": [
|
|
331
371
|
"testcase/frontend/cases/{{case.caseId}}.md",
|
|
@@ -2,16 +2,14 @@
|
|
|
2
2
|
|
|
3
3
|
Write only `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
|
-
## Base URL
|
|
5
|
+
## Controller-frozen Base URL (required)
|
|
6
6
|
|
|
7
|
-
|
|
7
|
+
The preflight controller resolves and freezes one absolute browser base URL from hash-bound task source `config.md` (or the controller default `http://localhost:5173`) before this Pi node runs. Copy that supplied value and source exactly into `context.md` as `baseUrl: <url>` and `baseUrlSource: <source>`.
|
|
8
8
|
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
6. Include the exact browser start prefix that generators must copy:
|
|
15
|
-
`playwright-cli open --browser=chrome --headed <resolved-base-url>`.
|
|
9
|
+
- Do not derive, replace, or override the origin from model reasoning, route text, case prose, existing RAG files, or other repository content.
|
|
10
|
+
- Never use production hosts or credentials.
|
|
11
|
+
- Write `environmentProbe: pending`. The environment preflight shell will replace this with `reachable`, `unreachable`, or `curl-unavailable` plus a structured `blockedReason` (for example `frontend-base-url-unreachable`).
|
|
12
|
+
- Include the exact browser start prefix using the supplied controller-frozen URL:
|
|
13
|
+
`playwright-cli open --browser=chrome --headed <controller-frozen-base-url>`.
|
|
16
14
|
|
|
17
15
|
Do not claim the environment is reachable until preflight completes. Preflight does not start the application.
|
|
@@ -2,4 +2,4 @@
|
|
|
2
2
|
|
|
3
3
|
Write a dated report under `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
|
-
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 assertion plus screenshot or equivalent browser evidence 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/**`.
|
|
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 `testcase/frontend/rag/context.md` (prefer task source `config.md`, else `http://localhost:5173`): `playwright-cli open --browser=chrome --headed <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, and an evidence write point. 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.
|
|
5
|
+
Every case must retain the exact browser-start command prefix with the resolved absolute baseUrl from `testcase/frontend/rag/context.md` (prefer task source `config.md`, else `http://localhost:5173`): `playwright-cli open --browser=chrome --headed <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.
|
|
@@ -1,3 +1,3 @@
|
|
|
1
1
|
# Review frontend execution evidence
|
|
2
2
|
|
|
3
|
-
Review AC → case → browser-evidence traceability only after deterministic evidence validation. Each manifest case must have `execution.md` and a valid `case-result.json` with matching `caseId`, `status`, and `evidencePaths`; `blocked` requires a non-empty `blockedReason`. A passed case additionally needs
|
|
3
|
+
Review AC → case → browser-evidence traceability only after deterministic evidence validation. Each manifest case must have `execution.md` and a valid `case-result.json` with matching `caseId`, `status`, and `evidencePaths`; `blocked` requires a non-empty `blockedReason`. A passed case additionally needs a successful `find` semantic assertion, screenshot or equivalent browser evidence, and same-child ordered controller-owned `playwright-cli` receipts: successful `open` → successful `find` → successful `post-execution` cleanup. `pre-start` cleanup, snapshot/goto/screenshot/request/console, and ordinary interactions cannot satisfy this gate. Failed and blocked cases need an explicit cause. Treat `token-budget-exhausted` and `browser-command-evidence-missing` as blocked; do not substitute model conclusions or static checks for browser evidence.
|
package/harness.json
CHANGED
package/package.json
CHANGED
|
@@ -64,7 +64,7 @@ loop-agent task status <task-id> --json
|
|
|
64
64
|
6. 主会话不绕过 CLI 直接写业务代码;失败只走 doctor/reconcile/human gate/重跑。
|
|
65
65
|
7. DAG `pi` executor read-only unless `toolProfile: "write"`;completed run facts read-only;不得从 read-only DAG/sidecar 写 root `artifacts/`。
|
|
66
66
|
8. No hidden state in chat only;verify before completion.
|
|
67
|
-
9. Client recovery:`init --client-recovery=auto|project|user|off
|
|
67
|
+
9. Client recovery:`init --client-recovery=auto|project|user|off` 投影 transient-retry + overflow-compact + Pi overflow extension;只有 `user` 写 Pi settings;overflow 与 transient 职责分离;check/update 遵守 ownership。
|
|
68
68
|
|
|
69
69
|
## References
|
|
70
70
|
|
|
@@ -221,8 +221,18 @@ loop-agent --repo-root /path/to/target-repo study init <task-id> "Title" \
|
|
|
221
221
|
--reference-doc plan:/Users/mac/plans/codex-goal-feature.md \
|
|
222
222
|
--reference-glob "codex-rs/**/goal*.rs"
|
|
223
223
|
|
|
224
|
-
# 编辑 source/需求.md + source/执行约束.md
|
|
224
|
+
# 编辑 source/需求.md + source/执行约束.md,然后按标准 task lifecycle 推进:
|
|
225
225
|
loop-agent --repo-root <target-repo> task advance <task-id> --profile auto --dag-output .harness/tasks/<task-id>/dag.json --json
|
|
226
|
+
# 审查 writeSet gate 后,继续同一任务:
|
|
227
|
+
loop-agent --repo-root <target-repo> task advance <task-id> --approve-gate "write-set-review:<digest>" --json
|
|
228
|
+
loop-agent --repo-root <target-repo> task status <task-id> --json
|
|
229
|
+
```
|
|
230
|
+
|
|
231
|
+
`task advance` 会生成并 strict validate 任务 DAG;`--dag-output` 只用于导出可审阅草稿,不要求再把 `dag validate` 或 `dag execute` 当作标准任务的下一步。
|
|
232
|
+
|
|
233
|
+
仅当有意把导出的 JSON 当作**独立的 advanced arbitrary DagSpec** 排查或执行时,才使用以下高级入口;它们不替代上述标准 task lifecycle:
|
|
234
|
+
|
|
235
|
+
```bash
|
|
226
236
|
loop-agent --repo-root <target-repo> dag validate --dag .harness/tasks/<task-id>/dag.json --strict-models --strict-governance
|
|
227
237
|
loop-agent --repo-root <target-repo> dag execute --dag .harness/tasks/<task-id>/dag.json --cwd <target-repo>
|
|
228
238
|
```
|
|
@@ -239,7 +249,7 @@ loop-agent --repo-root <target-repo> dag execute --dag .harness/tasks/<task-id>/
|
|
|
239
249
|
loop-agent reference index <task-id>
|
|
240
250
|
```
|
|
241
251
|
|
|
242
|
-
`reference` 是 compatibility / feature-study 辅助入口,用于维护或检查参考资料索引。常规实现任务不要从 `reference`
|
|
252
|
+
`reference` 是 compatibility / feature-study 辅助入口,用于维护或检查参考资料索引。常规实现任务不要从 `reference` 起步;使用 `task advance` 推进同一任务,并用 `task status` 做只读状态确认。
|
|
243
253
|
|
|
244
254
|
### Task goal lifecycle(compatibility-only / deprecated-candidate)
|
|
245
255
|
|
|
@@ -264,7 +274,9 @@ loop-agent goal clear <task-id>
|
|
|
264
274
|
- 用于保持 continuation 行为一致,减少聊天式历史噪音
|
|
265
275
|
- preflight 含 state/mode guard + 启动前 goal 一致性复检
|
|
266
276
|
|
|
267
|
-
###
|
|
277
|
+
### Advanced arbitrary DagSpec validation 与 execution
|
|
278
|
+
|
|
279
|
+
以下 `dag validate`、`dag execute`、`dag report` 与相关 run-level 命令是 **advanced arbitrary DagSpec / forensic** surface,适用于手写或显式导出的独立 DAG、诊断与证据审阅。它们不创建标准 task lifecycle,也不取代标准 mutation 的 `task advance` 或只读状态查询的 `task status`。
|
|
268
280
|
|
|
269
281
|
```bash
|
|
270
282
|
loop-agent dag validate --dag <temp-dir>/hybrid-dag.json # 常规 validation;无 .harness/dag-runs 副作用
|
|
@@ -278,7 +290,7 @@ cp ai_workspace/loop-agent/templates/agent-dag.supervised-implementation.json <t
|
|
|
278
290
|
loop-agent dag execute --dag <temp-dir>/hybrid-dag.json --cwd <repo-root> # advanced arbitrary DagSpec;stderr 默认输出节点进度与 30s 心跳,stdout 保持最终 JSON
|
|
279
291
|
loop-agent dag execute --dag <temp-dir>/hybrid-dag.json --cwd <repo-root> --progress-interval-ms 60000 # 调整心跳;--quiet 可禁用
|
|
280
292
|
loop-agent dag execute --dag <temp-dir>/hybrid-dag.json --init-only --canvas-path <temp-dir>/hybrid-dag.canvas.tsx # 可选 derived Canvas view
|
|
281
|
-
bash scripts/dag
|
|
293
|
+
bash scripts/run-dag-safe.sh --dag <temp-dir>/hybrid-dag.json --cwd <repo-root> [--timeout-secs 7200] # advanced arbitrary DagSpec 的后台运行 + 轮询,避免外层 bash timeout 杀进程(见 agent-dag-runner.md §Adaptive liveness)
|
|
282
294
|
loop-agent dag init-hybrid <task-id> # 生成可审阅的 DAG draft
|
|
283
295
|
loop-agent dag workflow-plan <task-id> --profile pr-review --output .harness/tasks/<task-id>/workflows/planned/<name>.workflow.json
|
|
284
296
|
loop-agent dag workflow-validate --workflow .harness/tasks/<task-id>/workflows/planned/<name>.workflow.json --strict-governance
|
|
@@ -306,7 +318,7 @@ loop-agent dag resume --run-id <run-id> # approve 后继续
|
|
|
306
318
|
|
|
307
319
|
**In-flight DAG governance**:shell verify node 内用 `HARNESS_ALLOW_ACTIVE_DAG_RUNS=1 bash scripts/check-repo.sh`;run 归档到 `completed/` 后,在 DAG 外跑裸 `bash scripts/check-repo.sh`。
|
|
308
320
|
|
|
309
|
-
- `dag validate` 做 schema/topology/ranks 检查;审 `warnings` 中的显式 `executorModels` drift 与 governance lint
|
|
321
|
+
- `dag validate` 做 arbitrary DagSpec 的 schema/topology/ranks 检查;审 `warnings` 中的显式 `executorModels` drift 与 governance lint。它不替代 `task advance` 的标准任务生成与严格校验。
|
|
310
322
|
- 手写临时 DAG spec 执行前用 `dag validate --strict-models`,model-matrix drift 应 fail fast。
|
|
311
323
|
- read-only artifact-boundary 或 DAG 内 shell governance warning 应 fail fast 时用 `dag validate --strict-governance`。
|
|
312
324
|
- 人工 handoff 视图用 `dag report --markdown`(summary、node timeline、failures、四段 Recovery Plan、artifacts、建议 next action)。仅 derived、advisory;需保存时重定向到平台临时目录或 `ai_workspace/loop-agent/reports/`。
|
|
@@ -321,7 +333,7 @@ loop-agent dag resume --run-id <run-id> # approve 后继续
|
|
|
321
333
|
- 大型 PRD closeout 用 `dag final-verification <task-id>` 生成确定性 DAG,final verification 在 closeout artifact 创建之后。
|
|
322
334
|
- 从 run facts dry-run envelope 解析用 `dag decision inspect|validate`;`validate` 在无效 envelope 时 exit 1;永不自动 resume/retry。
|
|
323
335
|
- Decision Gate prompt 可用 `buildDagDecisionGateEvidence()`(`src/workflows/dag/decision-evidence.ts`)做与 `dag report --json`、`ai_workspace/loop-agent/templates/agent-dag-report.schema.json` 对齐的只读摘要;不 mutate run state,不执行 retry/resume。
|
|
324
|
-
-
|
|
336
|
+
- `dag execute --dry-run` 仅用于 advanced arbitrary DagSpec 的预演:snapshot 写入命令返回的 `runDir`(当前形态为 `.harness/dag-runs/dry-run/<runId>/`);它不创建 active run、不出现在 active overview,也不能作为 `dag resume` 的目标。
|
|
325
337
|
- task source 应从 `harness.json.workflowPolicy.dag.profileRouting` 与确定性 candidate `governanceProfile` 选择治理强度时用 `task advance --profile auto`。无 `--profile` 仅用于旧 standard-compatible 输出;`--profile minimal|standard|reviewed|supervised` 记录治理强度,不替换已识别的专用业务 workflow。
|
|
326
338
|
- 默认 `standard` 任务先读取 `source/需求.md` 中的结构化任务类型,再结合 `allowedPaths` 与 React/Next/Vue 项目能力做确定性分类。确认是前端项目且任务不是明确后端、混合、排除前端或仅文档/测试范围时,自动选择 `frontend-implementation`,不依赖需求关键词;普通后端实现绝不自动进入 `backend-test`。
|
|
327
339
|
- 新生成 DAG 会冻结任务源路径、SHA-256 和显式 `REQ/BR/AC` 到 `sourceBinding`。前端计划漏号时 `frontend-requirement-coverage-shell` 在 writer 前阻断。中断恢复应修复 task source 后重新运行 `task advance`,不要生成只携带上游摘要的 impl-only DAG;strict governance 会拒绝无来源绑定且无只读 planner 上游的 v3 孤立 writer。
|