@tea-agent/loop-agent 0.30.0 → 0.31.1
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 +58 -0
- package/dist/executors/dag-pi-executor.js +72 -4
- package/dist/executors/pi-sdk-executor.js +61 -0
- package/dist/executors/shell-executor.js +136 -79
- package/dist/worker/observability/dag-execution-trajectory.js +591 -0
- package/dist/worker/observability/read-model.js +258 -31
- package/dist/worker/observe/dag-node-execution-output.js +180 -0
- package/dist/worker/observe/routes.js +53 -6
- package/dist/worker/observe/static/dag-edge-routing.js +368 -0
- package/dist/worker/observe/static/dag-history-labels.js +95 -0
- package/dist/worker/observe/static/dag-layout.d.ts +12 -7
- package/dist/worker/observe/static/dag-layout.js +101 -21
- package/dist/worker/observe/static/favicon.svg +37 -0
- package/dist/worker/observe/static/format.js +31 -1
- package/dist/worker/observe/static/index.html +1 -1
- package/dist/worker/observe/static/state.js +102 -0
- package/dist/worker/observe/static/styles.css +267 -7
- package/dist/worker/observe/static/views/dag-graph.js +414 -154
- package/dist/worker/observe/static/views/dag-inspector.js +478 -27
- package/dist/worker/observe/static/views/dag-trajectory.js +313 -0
- package/dist/worker/observe/static/views/dag.js +20 -3
- package/dist/workflows/dag/backend-test-pytest-collection.js +162 -7
- package/dist/workflows/dag/backend-test-result-contract.js +105 -67
- package/dist/workflows/dag/backend-test-scenario-param.js +92 -30
- package/dist/workflows/dag/backend-test-writer-completeness.js +55 -0
- package/dist/workflows/dag/init-hybrid.js +46 -49
- package/dist/workflows/dag/rerun-task.js +86 -0
- package/docs/architecture/README.md +4 -0
- package/docs/architecture/dag-execution.md +1 -1
- package/docs/architecture/worker-and-feature.md +1 -1
- package/docs/governance/README.md +3 -0
- package/docs/operations/README.md +1 -0
- package/docs/templates/backend-test-dag.json +40 -60
- package/docs/templates/frontend-test-dag.json +1 -1
- package/harness.json +3 -3
- package/package.json +3 -2
- package/scripts/kb-bootstrap-init-skeleton.sh +1 -1
|
@@ -140,7 +140,7 @@
|
|
|
140
140
|
]
|
|
141
141
|
},
|
|
142
142
|
"outputContract": "Write a Chinese, human-readable testcase/md/README.md as the single Markdown-first entry page with Coverage Scope, Coverage Matrix and a machine-parseable module index. Do not write module case cards here; do not execute pytest or modify production code/config.",
|
|
143
|
-
"subtask_prompt": "This is a required file-generation node. After reading the bounded inputs, immediately use write tools to create testcase/md/README.md. Do not end after analysis or planning, and do not return before a non-empty bounded diff exists. Write ONLY testcase/md/README.md in this node; module case cards are written by downstream sharded nodes.\n\nOutput budget protocol (hard, max output <=16K per turn): Never paste full Matrix, case bodies, or source text into assistant chat. README holds only Scope+Matrix+module index; never inline full case bodies. If a Completeness Gate / OUTPUT_LIMIT_RECOVERY retry is injected, continue only listed target paths.\n\nThe first non-empty response line must be exactly IMPLEMENTATION_OUTCOME: changed after the README has been written, or IMPLEMENTATION_OUTCOME: blocked when precise missing evidence prevents safe generation. already-satisfied is not valid for this node.\n\nRead the upstream environment report. Generate the Markdown-first backend test README under testcase/md/README.md.\n\nWrite human-readable content in Simplified Chinese by default. Keep English only for machine-readable IDs and technical literals such as Case/AC/REQ/BR IDs, HTTP methods, paths, field names, enum values, commands, filenames, code symbols and exact source citations.\n\nCreate testcase/md/README.md as the concise entry page: test objective, target/environment, isolation/cleanup, module summary and a linked case index table with Case ID, Chinese case name, scenario type, endpoint and expected status/result. Avoid repeating every case body in README.\n\nBefore the Coverage Matrix, write a mandatory machine-readable `## Coverage Scope` section in README using exactly `| Field | Value |`, immediately followed by the separator row `|---|---|`, and these six unique rows: `Change Classification`, `Coverage Policy`, `Affected Operations`, `Affected Rule Keys`, `Regression Floor`, `Scope Evidence`. Always set `Change Classification` to `new-operation` and `Coverage Policy` to `full-contract`; do NOT reason about whether operations are new or existing. Cover all in-scope rules from the requirement document at full depth; treat the product requirement as the coverage baseline and use API contract evidence (fields/status/enum/boundary/format) to supplement scenario dimensions. Scope is limited to operations/rules the requirement document (or its referenced API contract) explicitly describes; do not expand to unrelated operations that the requirement does not mention. List affected operations exactly as `METHOD /path`, stable rule keys separated by semicolons, and precise source pointers as Scope Evidence.\n\nCoverage depth is full over the in-scope rules: fully cover every documented status, request/response field rule, requiredness, enum, boundary, format, auth and business state of each affected operation the requirement describes, but do not re-test unrelated operations the requirement does not mention. Inspect shared validator/helper/DTO/query builder evidence and expand Affected Operations when the same affected path can affect them; unresolved impact stays visible as GAP/CONFLICT.\n\nBefore writing cases, build the mandatory machine-readable Coverage Matrix inside `testcase/md/README.md` itself. Its section heading line must be exactly `## Coverage Matrix` with no numeric prefix/suffix; never place the canonical Matrix only in a module file. Use this exact header: `| Rule Key | Priority | Source | Endpoint/Field | Dimension | Rule | Required Test Points | Case IDs | Status |`. Every data row must contain exactly 9 pipe-delimited cells and must never omit `Dimension`; use concise dimensions such as requirement, operation, response-status, requiredness, enum, boundary, format, business-state or error. Use only P0/P1/P2 and COVERED/PARTIAL/GAP/CONFLICT. Use stable `TP-<UPPERCASE-HYPHENATED-ID>` test points separated by semicolons.\n\nEach Rule Key must appear in exactly one Matrix row. Preserve each AC/REQ/BR Rule Key as one row; if one product rule spans multiple dimensions, use a concise composite Dimension in that single row instead of duplicating the key. Derive OpenAPI Rule Keys exactly as the deterministic analyzer does: operation token is `<HTTP-METHOD>-<PATH>` with braces removed and every non-alphanumeric run replaced by a hyphen, uppercase (for example POST `/api/resource-notes` → `POST-API-RESOURCE-NOTES`); response statuses use `API-<OPERATION>-RESPONSE-STATUS`; body/parameter fields use `API-<OPERATION>-<FIELD>-REQUIRED|ENUM|MIN-LENGTH|MAX-LENGTH|MINIMUM|MAXIMUM|PATTERN|FORMAT`. Do not invent aliases such as API-CREATE-FIELDS when a deterministic key applies.\n\nCoverage priority is strict inside the declared scope: P0 product requirements/task hard constraints always remain in scope; P1 exhaustively supplements documented operations, fields, business rules, statuses and errors only for Affected Operations; P2 adds bounded protocol robustness only when it is relevant to the change and does not invent product behavior. Coverage percentages describe the declared affected scope, never whole-API completeness unless every operation is explicitly listed. Conflicts or undefined expectations must stay visible as GAP/CONFLICT with precise source pointers, never guessed.\n\nFor uniqueness/lifecycle rules cover absent, active-existing, deleted-existing, create-delete-recreate, restore-then-recreate and documented scope/case-normalization states. For every enum cover every valid value plus bounded invalid equivalence classes (unknown, case variant, whitespace, empty, null/missing and wrong types as applicable). For every length/number rule cover min-1, min, nominal, max and max+1. For format rules cover each allowed class separately plus a valid mixed value, and representative forbidden classes including uppercase, internal/leading/trailing whitespace, tab/newline, unsupported punctuation, slash, emoji or control characters when the source contract supports that expectation.\n\nMandatory module index: include a `## Module Index` table in README that lists every planned module as a canonical relative link of the exact form `[label](./<stem>.md)` plus a `testcase/md/<stem>.md` path cell, so a downstream deterministic manifest can parse the module list. Name each module file with a stable lowercase business stem such as `health` or `resource_notes`. Do not use Case-ID-like module filenames such as `BE-HEALTH.md` or `BE-NOTES.md`. The relative link target MUST equal the on-disk filename stem the sharded writer will create. For every automatable case, `自动化映射` must name exactly `testcase/test_<module>.py`, where <module> is that Markdown filename without `.md`, lowercased, with non-alphanumeric characters replaced by underscores. Example: `testcase/md/health.md` → `testcase/test_health.py`; `testcase/md/resource_notes.md` → `testcase/test_resource_notes.py`. Never invent a different pytest path in Markdown than the module stem implies.\n\nBefore finalizing README, calculate the predicted collected-item count as `sum(max(1, number of variant Test Points in each Case))`. If the task declares an item budget, the prediction must not exceed it. Reduce excess only by removing duplicate execution and converting same-request checkpoints to assertions; never drop required rules, boundaries, enums, operation-specific inputs, or business states. Record the prediction in README. Use only environment-supported fixtures/targets/isolation, record evidence gaps in Chinese, and do not emit JSON, pytest, or execute commands.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and copy `path` exactly into Markdown Source References. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails.\n\nRead only precise indexed references needed for AC/API/field/rule evidence; references remain authoritative over derived text."
|
|
143
|
+
"subtask_prompt": "This is a required file-generation node. After reading the bounded inputs, immediately use write tools to create testcase/md/README.md. Do not end after analysis or planning, and do not return before a non-empty bounded diff exists. Write ONLY testcase/md/README.md in this node; module case cards are written by downstream sharded nodes.\n\nOutput budget protocol (hard, max output <=16K per turn): Never paste full Matrix, case bodies, or source text into assistant chat. README holds only Scope+Matrix+module index; never inline full case bodies. If a Completeness Gate / OUTPUT_LIMIT_RECOVERY retry is injected, continue only listed target paths.\n\nThe first non-empty response line must be exactly IMPLEMENTATION_OUTCOME: changed after the README has been written, or IMPLEMENTATION_OUTCOME: blocked when precise missing evidence prevents safe generation. already-satisfied is not valid for this node.\n\nRead the upstream environment report. Generate the Markdown-first backend test README under testcase/md/README.md.\n\nWrite human-readable content in Simplified Chinese by default. Keep English only for machine-readable IDs and technical literals such as Case/AC/REQ/BR IDs, HTTP methods, paths, field names, enum values, commands, filenames, code symbols and exact source citations.\n\nCreate testcase/md/README.md as the concise entry page: test objective, target/environment, isolation/cleanup, module summary and a linked case index table with Case ID, Chinese case name, scenario type, endpoint and expected status/result. Avoid repeating every case body in README.\n\nBefore the Coverage Matrix, write a mandatory machine-readable `## Coverage Scope` section in README using exactly `| Field | Value |`, immediately followed by the separator row `|---|---|`, and these six unique rows: `Change Classification`, `Coverage Policy`, `Affected Operations`, `Affected Rule Keys`, `Regression Floor`, `Scope Evidence`. Always set `Change Classification` to `new-operation` and `Coverage Policy` to `full-contract`; do NOT reason about whether operations are new or existing. Cover all in-scope rules from the requirement document at full depth; treat the product requirement as the coverage baseline and use API contract evidence (fields/status/enum/boundary/format) to supplement scenario dimensions. Scope is limited to operations/rules the requirement document (or its referenced API contract) explicitly describes; do not expand to unrelated operations that the requirement does not mention. List affected operations exactly as `METHOD /path`, stable rule keys separated by semicolons, and precise source pointers as Scope Evidence.\n\nCoverage depth is full over the in-scope rules: fully cover every documented status, request/response field rule, requiredness, enum, boundary, format, auth and business state of each affected operation the requirement describes, but do not re-test unrelated operations the requirement does not mention. Inspect shared validator/helper/DTO/query builder evidence and expand Affected Operations when the same affected path can affect them; unresolved impact stays visible as GAP/CONFLICT.\n\nBefore writing cases, build the mandatory machine-readable Coverage Matrix inside `testcase/md/README.md` itself. Its section heading line must be exactly `## Coverage Matrix` with no numeric prefix/suffix; never place the canonical Matrix only in a module file. Use this exact header: `| Rule Key | Priority | Source | Endpoint/Field | Dimension | Rule | Required Test Points | Case IDs | Status |`. Every data row must contain exactly 9 pipe-delimited cells and must never omit `Dimension`; use concise dimensions such as requirement, operation, response-status, requiredness, enum, boundary, format, business-state or error. Use only P0/P1/P2 and COVERED/PARTIAL/GAP/CONFLICT. Use stable `TP-<UPPERCASE-HYPHENATED-ID>` test points separated by semicolons.\n\nEach Rule Key must appear in exactly one Matrix row. Preserve each AC/REQ/BR Rule Key as one row; if one product rule spans multiple dimensions, use a concise composite Dimension in that single row instead of duplicating the key. Derive OpenAPI Rule Keys exactly as the deterministic analyzer does: operation token is `<HTTP-METHOD>-<PATH>` with braces removed and every non-alphanumeric run replaced by a hyphen, uppercase (for example POST `/api/resource-notes` → `POST-API-RESOURCE-NOTES`); response statuses use `API-<OPERATION>-RESPONSE-STATUS`; body/parameter fields use `API-<OPERATION>-<FIELD>-REQUIRED|ENUM|MIN-LENGTH|MAX-LENGTH|MINIMUM|MAXIMUM|PATTERN|FORMAT`. Do not invent aliases such as API-CREATE-FIELDS when a deterministic key applies.\n\nCoverage priority is strict inside the declared scope: P0 product requirements/task hard constraints always remain in scope; P1 exhaustively supplements documented operations, fields, business rules, statuses and errors only for Affected Operations; P2 adds bounded protocol robustness only when it is relevant to the change and does not invent product behavior. Coverage percentages describe the declared affected scope, never whole-API completeness unless every operation is explicitly listed. Conflicts or undefined expectations must stay visible as GAP/CONFLICT with precise source pointers, never guessed.\n\nFor uniqueness/lifecycle rules cover absent, active-existing, deleted-existing, create-delete-recreate, restore-then-recreate and documented scope/case-normalization states. For every enum cover every valid value plus bounded invalid equivalence classes (unknown, case variant, whitespace, empty, null/missing and wrong types as applicable). For every length/number rule cover min-1, min, nominal, max and max+1. For format rules cover each allowed class separately plus a valid mixed value, and representative forbidden classes including uppercase, internal/leading/trailing whitespace, tab/newline, unsupported punctuation, slash, emoji or control characters when the source contract supports that expectation.\n\nMandatory module index: include a `## Module Index` table in README that lists every planned module as a canonical relative link of the exact form `[label](./<stem>.md)` plus a `testcase/md/<stem>.md` path cell, so a downstream deterministic manifest can parse the module list. Group by stable business resource/domain, not by CRUD operation: one resource's list/detail/create/update/delete cases belong in one module such as `resource_notes`; split only when a single module would exceed the per-child 16K output budget, and keep the total module count at the smallest safe value. Name each module file with a stable lowercase business stem such as `health` or `resource_notes`. Do not use Case-ID-like module filenames such as `BE-HEALTH.md` or `BE-NOTES.md`. The relative link target MUST equal the on-disk filename stem the sharded writer will create. For every automatable case, `自动化映射` must name exactly `testcase/test_<module>.py`, where <module> is that Markdown filename without `.md`, lowercased, with non-alphanumeric characters replaced by underscores. Example: `testcase/md/health.md` → `testcase/test_health.py`; `testcase/md/resource_notes.md` → `testcase/test_resource_notes.py`. Never invent a different pytest path in Markdown than the module stem implies.\n\nBefore finalizing README, calculate the predicted collected-item count as `sum(max(1, number of variant Test Points in each Case))`. If the task declares an item budget, the prediction must not exceed it. Reduce excess only by removing duplicate execution and converting same-request checkpoints to assertions; never drop required rules, boundaries, enums, operation-specific inputs, or business states. Record the prediction in README. Use only environment-supported fixtures/targets/isolation, record evidence gaps in Chinese, and do not emit JSON, pytest, or execute commands.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and copy `path` exactly into Markdown Source References. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails.\n\nRead only precise indexed references needed for AC/API/field/rule evidence; references remain authoritative over derived text."
|
|
144
144
|
},
|
|
145
145
|
{
|
|
146
146
|
"id": "materialize-backend-md-module-manifest-shell",
|
|
@@ -199,7 +199,8 @@
|
|
|
199
199
|
"maxExpandedNodes": 64,
|
|
200
200
|
"childIdPrefix": "generate-backend-md-case",
|
|
201
201
|
"tokenBudget": {
|
|
202
|
-
"maxTokensPerCase": 16384
|
|
202
|
+
"maxTokensPerCase": 16384,
|
|
203
|
+
"maxTotalTokens": 600000
|
|
203
204
|
},
|
|
204
205
|
"childTask": {
|
|
205
206
|
"executor": "pi",
|
|
@@ -247,9 +248,8 @@
|
|
|
247
248
|
"generate-backend-md-cases-map"
|
|
248
249
|
],
|
|
249
250
|
"role": "reviewer",
|
|
250
|
-
"executor": "
|
|
251
|
-
"
|
|
252
|
-
"complexity": "MED",
|
|
251
|
+
"executor": "static",
|
|
252
|
+
"complexity": "LOW",
|
|
253
253
|
"writePolicy": "exclusive",
|
|
254
254
|
"writeSet": [
|
|
255
255
|
"testcase/md/**"
|
|
@@ -262,8 +262,11 @@
|
|
|
262
262
|
".harness/dag-runs/**",
|
|
263
263
|
"artifacts/**"
|
|
264
264
|
],
|
|
265
|
-
"outputContract": "
|
|
266
|
-
"subtask_prompt": "Independently review generated Markdown cases against the task requirements and environment evidence. Treat the files as human-facing test documentation: require clear preconditions, executable steps and assertable expected results; improve names, purpose, metadata and automation mapping where useful while preserving exact machine IDs and technical literals.\n\nOutput budget protocol: default to local edit per file; never dump full Matrix/case bodies into assistant chat. Review order is README (Scope/Matrix) then one module file per turn. When adding omitted in-scope cases, write one file per tool call and keep every required section. Do not bulk-delete in-scope cases to save tokens.\n\nFor every variant Test Point, ensure the Markdown scenario intent is machine-checkable
|
|
265
|
+
"outputContract": "Deterministic advisory handoff that reserves testcase/md/** in the approved DAG write set for upstream map children; no model invocation or writes.",
|
|
266
|
+
"subtask_prompt": "Independently review generated Markdown cases against the task requirements and environment evidence. Treat the files as human-facing test documentation: require clear preconditions, executable steps and assertable expected results; improve names, purpose, metadata and automation mapping where useful while preserving exact machine IDs and technical literals.\n\nOutput budget protocol: default to local edit per file; never dump full Matrix/case bodies into assistant chat. Review order is README (Scope/Matrix) then one module file per turn. When adding omitted in-scope cases, write one file per tool call and keep every required section. Do not bulk-delete in-scope cases to save tokens.\n\nFor every variant Test Point, ensure the Markdown scenario intent is machine-checkable with an exact transport target: `场景意图: <TP-ID>; operation=<METHOD /path>; target=<body.field|query.field|path.field|header.field|request>; intent=<empty|missing|null|min-1|min|max|max+1|pattern-invalid|enum-invalid|wrong-type|nominal-operation|custom-literal:V>; bound=<n optional>; example=<optional>; expectedCode=<optional>`. Never use vague targets such as field=resource/health. Keep pytest params aligned to the exact target.\n\nTreat the requirement document as the coverage baseline; scope is limited to operations/rules it (or its referenced API contract) describes, and API contract evidence supplements scenario dimensions. For every in-scope operation, check applicable lifecycle/uniqueness states (including deleted-existing when in scope), valid enum values, bounded invalid classes, min-1/min/nominal/max/max+1, allowed/forbidden format classes, required/null/missing/wrong-type semantics, status/error codes, auth and state transitions. Inspect shared validator/helper/DTO/query builder evidence and expand Affected Operations when the same affected path can affect them; unresolved impact stays visible as GAP/CONFLICT. Directly add in-scope omissions; reject scope expansion to operations absent from the requirement document; undefined impact remains GAP/CONFLICT rather than invented behavior.\n\nCheck AC completeness/meaning, endpoint, fields/shape, status/error codes, rules, states, documented boundaries/auth, positive/negative coverage, executable steps and assertable results. Require the exact `## Coverage Scope` Field/Value table with the `|---|---|` separator row, a valid classification-policy pair, non-empty Affected Operations/Rule Keys/Scope Evidence, and the classification-specific Regression Floor. Require the exact unnumbered `## Coverage Matrix` heading in `testcase/md/README.md`, exact headers, exactly 9 cells in every data row (including a non-empty Dimension), deterministic OpenAPI Rule Keys for every in-scope affected operation, exactly one Matrix row per Rule Key (merge multi-dimension product rows), and bidirectional Matrix Rule/Test Point ↔ Case bindings. Never describe affected-scope coverage as whole-API completeness. Every explicit AC ID must appear in at least one Case `验收标准`; every explicit in-scope AC/REQ/BR Rule Key cited by a Case must have exactly one Coverage Matrix row, and no Case may cite a source Rule Key omitted from the Matrix. Every Matrix Case ID must share at least one of that row's Required Test Points and the Case must cite that Rule Key. Perform an explicit execution-redundancy review: merge checkpoint-only parameter rows, repeated default/read-back assertions, DELETE status/body/follow-up-read checks, response schema/Content-Type checks, PUT full-update/timestamp checks, repeated list setup and identical null/empty inputs when endpoint, input partition, precondition state and expected outcome are the same. Preserve separate POST/PUT, boundary, enum, wrong-type, role/tenant and distinct business-state variants. Directly repair malformed headings/rows/keys and binding modes rather than merely commenting on them. Reject avoidable English prose, duplicated bilingual wording, repeated boilerplate, oversized unstructured sections, a `### 操作步骤` section that contains only a table without any numbered executable line, vague results such as ‘符合预期’, Case-ID-like module filenames (for example `BE-HEALTH.md`), dropped exact `### 操作步骤`/`### 预期结果` headings, and missing or drifted script/function mapping where it can be derived.\n\nCorrect testcase/md/** directly: add documented omissions, remove unsupported cases, rename module files to stable lowercase stems when needed, normalize every Case ID to hyphen-separated module segments plus exactly three zero-padded digits (`BE-RESOURCE_NOTES-01` → `BE-RESOURCE-NOTES-001`; `BE-RN-011A` must be renumbered or merged) consistently across headings/index/mappings, fix automation mappings so each case points at `testcase/test_<module>.py` derived from that module filename and declares exactly one primary symbol, assign every Test Point exactly one of `变体测试点`/`场景断言测试点`/`横切证据测试点`, ensure every binding-list Test Point is also present in that Case's `### 测试点`, expand every variant parameter row into its own atomic TP ID, make every non-cross-cutting TP Case-specific and owned by exactly one Case, require every primary symbol to start with the canonical Case prefix, ensure every explicit AC ID appears in an applicable Case `验收标准`, merge execution duplicates, improve navigation/tables/Chinese wording, or record gaps in Chinese. Remove every credential/header value, placeholder, fake token and anti-example from Markdown. Sensitive key names may remain only as a plain list; values must be described as runtime-only and omitted, with no colon/value pair or literal example anywhere, including details blocks and explanatory text. Keep Case IDs, AC/REQ/BR IDs, HTTP methods, paths, fields, enum values, filenames, code symbols and source citations as exact machine-readable identifiers; only normalize Case ID separator/sequence formatting as specified above. Recalculate predicted collected items as `sum(max(1, variant count per Case))`; when the task declares a budget, directly merge redundant journeys/reclassify same-request checkpoints until the prediction is within budget, while preserving all required coverage. The validator accepts Chinese and legacy English section aliases; retain or converge to the Chinese human-readable headings without losing structure.\n\nRead only precise referenced source paths plus requirement sections needed for uncovered ACs. Do not scan the repository, modify source/**, generate pytest, execute tests, or emit JSON.\n\n## Derived task contract: 需求.md\n\n# Backend test\n- AC-001 proof\n\n## Authoritative reference index\n\n[]\n\nFor each index entry, use `readPath` for Pi read-tool calls and keep `path` as the exact Markdown Source References citation. Bound files under .harness/tasks/<taskId>/source/** are read-only inputs: reading them is allowed even though writing .harness/** is forbidden. Never resolve `path` relative to the repository root, search for substitutes, or fall back to docs/** when a bound read fails.",
|
|
267
|
+
"static": {
|
|
268
|
+
"resultMarkdown": "Markdown module writers completed. Deterministic node 6 validation owns advisory structure/coverage findings; no model review or rewrite was invoked."
|
|
269
|
+
}
|
|
267
270
|
},
|
|
268
271
|
{
|
|
269
272
|
"id": "validate-backend-md-cases-shell",
|
|
@@ -298,41 +301,20 @@
|
|
|
298
301
|
"validate-backend-md-cases-shell"
|
|
299
302
|
],
|
|
300
303
|
"role": "implementer",
|
|
301
|
-
"executor": "
|
|
302
|
-
"
|
|
303
|
-
"
|
|
304
|
-
"
|
|
305
|
-
"writeSet": [
|
|
306
|
-
"testcase/**/helpers/**",
|
|
307
|
-
"testcase/**/factories/**"
|
|
308
|
-
],
|
|
309
|
-
"allowedPaths": [
|
|
310
|
-
"testcase/**",
|
|
311
|
-
"docs/test-reports/**",
|
|
312
|
-
"testcase/**/helpers/**",
|
|
313
|
-
"testcase/**/factories/**"
|
|
314
|
-
],
|
|
304
|
+
"executor": "static",
|
|
305
|
+
"complexity": "LOW",
|
|
306
|
+
"writePolicy": "none",
|
|
307
|
+
"allowedPaths": [],
|
|
315
308
|
"forbiddenPaths": [
|
|
316
309
|
".harness/**",
|
|
317
310
|
".harness/dag-runs/**",
|
|
318
311
|
"artifacts/**"
|
|
319
312
|
],
|
|
320
|
-
"
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
"
|
|
324
|
-
|
|
325
|
-
"retryCategories": [
|
|
326
|
-
"writer-empty-diff",
|
|
327
|
-
"incomplete-write-set"
|
|
328
|
-
]
|
|
329
|
-
},
|
|
330
|
-
"writerOutcomePolicy": {
|
|
331
|
-
"type": "implementation-outcome-v1",
|
|
332
|
-
"requireChangedFiles": true
|
|
333
|
-
},
|
|
334
|
-
"outputContract": "Write the shared pytest support assets (HTTP logging/redaction helper, request factories, shared fixtures) under testcase/**/helpers/** and testcase/**/factories/** only. Do not write per-module test_*.py here; those are written by downstream sharded nodes. No JSON and no pytest execution.",
|
|
335
|
-
"subtask_prompt": "Convert testcase/md/** into pytest using upstream environment and advisory validation evidence plus only bounded pytest config/conftest. This node writes ONLY the shared pytest support assets (HTTP logging/redaction helper, request factories, shared fixtures); each module's test_<module>.py is written by a downstream sharded node that imports these helpers. A FAIL advisory report does not authorize inventing missing behavior; use the final Markdown facts that are present.\n\nOutput budget protocol (hard, max output <=16K per turn): Write helpers/factories one file per write/edit tool call. Never paste full Python modules into assistant chat. Do not reduce params/assertions/skips semantics to fit. If OUTPUT_LIMIT_RECOVERY is injected, continue only listed missing/broken shared files.\n\nAlign every variant pytest.param payload with the Markdown scenario intent (empty/missing/null/length/pattern/enum/wrong-type/nominal). Prefer literal payloads over Faker for intent-critical fields so pre-execution scenario-param checks can verify them.\n\nGenerate a reusable HTTP logging helper (or equivalent client wrapper) and call it for every interface request. The request log must include method, URL/path, and request parameters (query plus JSON/body/payload summary). The response log must include status code and response result (JSON/text/body summary), and both records must be visible in pytest stdout/stderr without changing assertions.\n\nHTTP response header names are case-insensitive. If the helper stores a lower-case normalized header map, every Content-Type or other header assertion must query the lower-case key (for example `content-type`) or use an explicitly case-insensitive accessor; never call a case-sensitive plain dict with `Content-Type` when the stored key is lower-case. Preserve the actual media-type assertion rather than dropping it.\n\nCompare timestamps and other semantically equivalent protocol values by parsed meaning, not byte-for-byte serialization. In particular, normalize valid ISO-8601 instants before equality/order assertions so differences such as omitted trailing fractional seconds do not create TestBug failures; preserve exact-string assertions only when the Markdown explicitly requires representation equality.\n\nBefore logging, recursively redact sensitive keys and header values including authorization, proxy-authorization, cookie, set-cookie, token, password, secret, api key and credentials. Never print full Authorization/Cookie values. Apply bounded truncation to serialized request and response bodies (with an explicit truncation marker) so large payloads cannot flood pytest or report artifacts.\n\nDo not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON. For best-effort cleanup, catch only the narrow transport exception actually raised by the selected HTTP client (for example `requests.RequestException` or `urllib.error.URLError`); never use bare `except`, `Exception`, or `BaseException` with `pass`."
|
|
313
|
+
"outputContract": "Deterministic pytest generation handoff. Per-module map children write self-contained test_<module>.py files with bounded local fixtures, HTTP logging/redaction and payload builders; no model invocation, JSON, shared-asset writes or pytest execution.",
|
|
314
|
+
"subtask_prompt": "Convert testcase/md/** into pytest using upstream environment and advisory validation evidence plus only bounded pytest config/conftest. This node writes ONLY the shared pytest support assets (HTTP logging/redaction helper, request factories, shared fixtures); each module's test_<module>.py is written by a downstream sharded node that imports these helpers. A FAIL advisory report does not authorize inventing missing behavior; use the final Markdown facts that are present.\n\nOutput budget protocol (hard, max output <=16K per turn): Write helpers/factories one file per write/edit tool call. Never paste full Python modules into assistant chat. Do not reduce params/assertions/skips semantics to fit. If OUTPUT_LIMIT_RECOVERY is injected, continue only listed missing/broken shared files.\n\nAlign every variant pytest.param payload with the Markdown scenario intent (empty/missing/null/length/pattern/enum/wrong-type/nominal). Prefer literal payloads over Faker for intent-critical fields so pre-execution scenario-param checks can verify them.\n\nGenerate a reusable HTTP logging helper (or equivalent client wrapper) and call it for every interface request. The request log must include method, URL/path, and request parameters (query plus JSON/body/payload summary). The response log must include status code and response result (JSON/text/body summary), and both records must be visible in pytest stdout/stderr without changing assertions. If shared pytest fixtures are generated, keep their dependency graph in one provider module and require each downstream test module to register that provider with an exact pytest_plugins tuple; importing only the outer fixture is insufficient and will be rejected by fixture-resolution preflight.\n\nHTTP response header names are case-insensitive. If the helper stores a lower-case normalized header map, every Content-Type or other header assertion must query the lower-case key (for example `content-type`) or use an explicitly case-insensitive accessor; never call a case-sensitive plain dict with `Content-Type` when the stored key is lower-case. Preserve the actual media-type assertion rather than dropping it.\n\nCompare timestamps and other semantically equivalent protocol values by parsed meaning, not byte-for-byte serialization. In particular, normalize valid ISO-8601 instants before equality/order assertions so differences such as omitted trailing fractional seconds do not create TestBug failures; preserve exact-string assertions only when the Markdown explicitly requires representation equality.\n\nBefore logging, recursively redact sensitive keys and header values including authorization, proxy-authorization, cookie, set-cookie, token, password, secret, api key and credentials. Never print full Authorization/Cookie values. Apply bounded truncation to serialized request and response bodies (with an explicit truncation marker) so large payloads cannot flood pytest or report artifacts.\n\nDo not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON. For best-effort cleanup, catch only the narrow transport exception actually raised by the selected HTTP client (for example `requests.RequestException` or `urllib.error.URLError`); never use bare `except`, `Exception`, or `BaseException` with `pass`.",
|
|
315
|
+
"static": {
|
|
316
|
+
"resultMarkdown": "Shared pytest plan is deterministic: each downstream module writer owns one self-contained test_<module>.py and must not depend on generated shared helper/factory files."
|
|
317
|
+
}
|
|
336
318
|
},
|
|
337
319
|
{
|
|
338
320
|
"id": "materialize-backend-pytest-module-manifest-shell",
|
|
@@ -377,7 +359,7 @@
|
|
|
377
359
|
".harness/dag-runs/**",
|
|
378
360
|
"artifacts/**"
|
|
379
361
|
],
|
|
380
|
-
"outputContract": "Serial aggregate of sharded pytest module writers. Each child writes exactly one testcase/test_<stem>.py with its own 16K Pi budget
|
|
362
|
+
"outputContract": "Serial aggregate of sharded pytest module writers. Each child writes exactly one self-contained testcase/test_<stem>.py with its own 16K Pi budget and no generated shared-asset dependency.",
|
|
381
363
|
"subtask_prompt": "Expand the README module manifest into one sharded pytest writer child per module and run them serially. Child failures fail-close the map barrier.",
|
|
382
364
|
"static": {
|
|
383
365
|
"resultMarkdown": "Backend-test pytest module map expansion barrier."
|
|
@@ -391,7 +373,8 @@
|
|
|
391
373
|
"maxExpandedNodes": 64,
|
|
392
374
|
"childIdPrefix": "generate-backend-pytest-case",
|
|
393
375
|
"tokenBudget": {
|
|
394
|
-
"maxTokensPerCase": 16384
|
|
376
|
+
"maxTokensPerCase": 16384,
|
|
377
|
+
"maxTotalTokens": 600000
|
|
395
378
|
},
|
|
396
379
|
"childTask": {
|
|
397
380
|
"executor": "pi",
|
|
@@ -401,7 +384,7 @@
|
|
|
401
384
|
"verification-before-completion"
|
|
402
385
|
],
|
|
403
386
|
"toolProfile": "write",
|
|
404
|
-
"complexity": "
|
|
387
|
+
"complexity": "MED",
|
|
405
388
|
"writePolicy": "exclusive",
|
|
406
389
|
"allowedPaths": [
|
|
407
390
|
"testcase/test_{{item.stem}}.py"
|
|
@@ -434,7 +417,7 @@
|
|
|
434
417
|
]
|
|
435
418
|
},
|
|
436
419
|
"outputContract": "Write exactly one pytest module file testcase/test_<stem>.py whose actual test function region contains the exact Case ID, preferably in the function name or docstring. testcase/md/<module>.md (excluding README.md) maps one-to-one to testcase/test_<module>.py; never merge or split modules. No JSON and no pytest execution.",
|
|
437
|
-
"subtaskPromptTemplate": "Convert the single Markdown module testcase/md/{{item.stem}}.md into
|
|
420
|
+
"subtaskPromptTemplate": "Convert the single Markdown module testcase/md/{{item.stem}}.md into one self-contained pytest module. After reading the module Markdown and the bounded pytest config/conftest, immediately use write tools to create the single file testcase/test_{{item.stem}}.py. Define any bounded HTTP client fixture, request logging/redaction/truncation helper and payload builders needed by this module inside that same file; do not import generated testcase/**/helpers/** or testcase/**/factories/** assets. Do not end after analysis or planning. Do not modify Markdown, conftest, helpers/factories, or any other module's pytest script.\n\nOutput budget protocol (hard, max output <=16K per turn): Write exactly one test_{{item.stem}}.py. Never paste full Python modules into assistant chat. Do not merge or split modules. Do not reduce params/assertions/skips to fit. If OUTPUT_LIMIT_RECOVERY is injected, continue only listed missing/broken scripts.\n\nAlign every variant pytest.param payload with the Markdown scenario intent (empty/missing/null/length/pattern/enum/wrong-type/nominal). Prefer literal payloads over Faker for intent-critical fields so pre-execution scenario-param checks can verify them.\n\nEnsure every final Markdown Case ID in this module appears in exactly one primary pytest test function or pytest test class method region, using the exact `primary symbol` declared by Markdown. The symbol must start with `test_BE_<MODULE>_<NNN>_` so every parameterized collected item remains associated with its Case. Module-level functions and class-based pytest methods are both supported. Only `变体测试点` may use stable `pytest.param(..., id=\"TP-...\")` IDs, and every atomic variant ID must appear exactly once with a genuine input/state/outcome change. Use `pytest.param(..., id=...)` for every row; do not use decorator-level `ids=[...]`, generated suffixes, or IDs that extend/shorten the exact Markdown TP. Do not parameterize `场景断言测试点` or `横切证据测试点`; execute all assertion checkpoints within the same business journey/item and use shared helpers for cross-cutting evidence. The primary symbol docstring must contain exact metadata lines `Case-ID: BE-...`, `Assertion-Test-Points: TP-...;TP-...` and `Cross-Cutting-Test-Points: TP-...;TP-...` (use `none` when empty). No Test Point may be invented, renamed, omitted or bound in two modes. The generated pytest collection shape must equal the Markdown prediction `sum(max(1, variant count per Case))`; keep it at or below the task's explicit budget by removing duplicate execution, never by collapsing multiple parameter rows under a coarse family TP. Assertions come only from 预期结果 and setup comes only from 前置条件/测试数据/自动化映射.\n\nName the generated pytest file so it corresponds one-to-one with its source Markdown module file: this module stem `{{item.stem}}` maps to exactly one `testcase/test_{{item.stem}}.py`. The <module> stem is the Markdown filename without the `.md` extension, lowercased and with non-alphanumeric characters replaced by underscores. For example, `resource_notes` → `testcase/test_resource_notes.py`, `health` → `testcase/test_health.py`. If Markdown automation mapping names a different path than this module stem path, still write the module stem path and do not invent prefixes. Never merge multiple Markdown modules into one pytest file, never split one module across several files, and never invent pytest filenames unrelated to the Markdown modules.\n\nKeep this module self-contained: define module-local fixtures and helpers directly in testcase/test_{{item.stem}}.py, so pytest discovers every fixture dependency without external plugin registration. The request log must include method, URL/path, and request parameters (query plus JSON/body/payload summary). The response log must include status code and response result (JSON/text/body summary), and both records must be visible in pytest stdout/stderr without changing assertions. Recursively redact sensitive values and apply bounded truncation before logging.\n\nDo not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON. For best-effort cleanup, catch only the narrow transport exception actually raised by the selected HTTP client (for example `requests.RequestException` or `urllib.error.URLError`); never use bare `except`, `Exception`, or `BaseException` with `pass`."
|
|
438
421
|
}
|
|
439
422
|
}
|
|
440
423
|
},
|
|
@@ -456,8 +439,8 @@
|
|
|
456
439
|
".harness/dag-runs/**",
|
|
457
440
|
"artifacts/**"
|
|
458
441
|
],
|
|
459
|
-
"outputContract": "Run-owned reports/backend-test-pytest-collection-initial.md and contracts/backend-test-pytest-collection-initial.json with bounded diagnostics, asset hashes, collected item IDs and deterministic repair eligibility.",
|
|
460
|
-
"subtask_prompt": "Resolve final Markdown-mapped scripts before any business test body execution.
|
|
442
|
+
"outputContract": "Run-owned reports/backend-test-pytest-collection-initial.md and contracts/backend-test-pytest-collection-initial.json (collection-v3) with bounded collection/fixture diagnostics, repairPaths, asset hashes, collected item IDs and deterministic repair eligibility.",
|
|
443
|
+
"subtask_prompt": "Resolve final Markdown-mapped scripts before any business test body execution. Run scenario-param assess/at-most-one deterministic repair first, then pytest --collect-only and a no-business-body pytest --setup-plan fixture-resolution preflight. A safe missing mapped script, generated-local syntax/import defect, or generated fixture dependency/plugin-registration defect is REPAIRABLE; dependency, third-party plugin, production-module, environment, safety and unknown failures remain blocked. Materialize hash-bound collection-v3 facts with repairPaths and fixtureResolutionStatus.",
|
|
461
444
|
"shell": {
|
|
462
445
|
"commands": [],
|
|
463
446
|
"backendTestPipeline": "markdown-collection-assess",
|
|
@@ -499,7 +482,7 @@
|
|
|
499
482
|
"type": "implementation-outcome-v1"
|
|
500
483
|
},
|
|
501
484
|
"outputContract": "First non-empty line is IMPLEMENTATION_OUTCOME: changed|already-satisfied|blocked, followed by a concise repair summary. Modify only generated pytest scripts/helpers/factories and preserve every Markdown Case, Test Point, primary symbol and assertion meaning.",
|
|
502
|
-
"subtask_prompt": "Repair the generated backend pytest asset as one bounded program using the direct upstream collection assessment. This is the only repair attempt and happens before any business test body execution.\n\nFix only
|
|
485
|
+
"subtask_prompt": "Repair the generated backend pytest asset as one bounded program using the direct upstream collection assessment. This is the only repair attempt and happens before any business test body execution.\n\nFix only readiness-proven generated testcase-local defects on initial facts repairPaths: create exact safe missing mapped test_*.py paths, repair syntax/import/symbol/decorator/parameterization, or close generated fixture dependencies and plugin registration. For fixture defects inspect both provider and importer; when a shared fixture depends on sibling fixtures, register the whole provider module through an exact pytest_plugins declaration rather than importing only the outer fixture. Do not create unrelated pytest scripts.\n\nPreserve final testcase/md/** semantics, every Case ID, Rule/Test Point binding, primary symbol, parameter ID, expected status/body/schema assertion, HTTP logging, redaction and truncation behavior.\n\nUse local edit only on assessment-listed paths; keep summaries short; never rewrite unrelated modules.\n\nDo not read task source/** or reinterpret requirements. Do not modify Markdown, conftest, pytest config, production code or dependencies.\n\nDo not add skip/skipif/xfail, remove tests, reduce collected items, loosen assertions, swallow exceptions, use try/except ImportError fallback, mutate sys.path/PYTHONPATH, or replace the real API with mocks.\n\nDo not execute pytest; the deterministic effective collection gate owns the final collection attempt."
|
|
503
486
|
},
|
|
504
487
|
{
|
|
505
488
|
"id": "effective-backend-pytest-collection-gate-shell",
|
|
@@ -520,8 +503,8 @@
|
|
|
520
503
|
".harness/dag-runs/**",
|
|
521
504
|
"artifacts/**"
|
|
522
505
|
],
|
|
523
|
-
"outputContract": "Run-owned
|
|
524
|
-
"subtask_prompt": "If initial collection passed, verify unchanged asset hashes and reuse it
|
|
506
|
+
"outputContract": "Run-owned effective collection-v3 facts plus contracts/backend-test-execution-readiness.json proving exact final assets are collectable, fixture-resolvable and hash-bound; initial PASS is reused, repair path records attempt=1.",
|
|
507
|
+
"subtask_prompt": "If initial collection+fixture readiness passed, verify unchanged asset hashes and reuse it. If the single repair ran, rerun scenario-param preflight, final collection and no-business-body fixture resolution once. BLOCKED facts, repair failure, residual fixture failure or hash drift prevent business pytest execution. Materialize canonical backend-test-execution-readiness.json.",
|
|
525
508
|
"shell": {
|
|
526
509
|
"commands": [],
|
|
527
510
|
"backendTestPipeline": "markdown-collection-effective",
|
|
@@ -549,7 +532,7 @@
|
|
|
549
532
|
"artifacts/**"
|
|
550
533
|
],
|
|
551
534
|
"outputContract": "Run-owned reports/backend-test-traceability.md, reports/backend-test-markdown-pytest-correspondence.md, contracts/backend-test-markdown-pytest-correspondence-facts.json, reports/backend-test-scenario-param-consistency.md and contracts/backend-test-scenario-param-consistency-facts.json (initial+final) with optional repair audit; PASS/FAIL/UNAVAILABLE correspondence facts bound after effective collection.",
|
|
552
|
-
"subtask_prompt": "Deterministically scan only Markdown-mapped pytest scripts
|
|
535
|
+
"subtask_prompt": "Deterministically scan only final readiness-authorized Markdown-mapped pytest scripts. Produce bidirectional Markdown module/Case/Test Point ↔ pytest file/primary symbol correspondence and logging findings. scenario-param assessment/repair already ran before collection; consume and display its final PASS/PARTIAL/FAIL/UNAVAILABLE facts without modifying pytest assets after readiness was frozen. Correspondence findings remain advisory; Never block pytest solely on correspondence FAIL.",
|
|
553
536
|
"shell": {
|
|
554
537
|
"commands": [],
|
|
555
538
|
"backendTestPipeline": "markdown-traceability",
|
|
@@ -603,7 +586,7 @@
|
|
|
603
586
|
"artifacts/**"
|
|
604
587
|
],
|
|
605
588
|
"outputContract": "One scoped pytest execution over Markdown-mapped scripts producing a valid pytest-html report with per-case captured output, self-contained reports/backend-test.html, reports/backend-test.md, reports/backend-test-facts.md, a deterministic self-contained reports/backend-test-l5-dashboard.html (machine-computed L-5 metrics, no JSON), and an optional contracts/code-coverage-v1.json when jacocoCoverage is configured (JaCoCo TCP dump → jacoco.xml → parsed; failure-safe); exit 0/1 with valid evidence continues.",
|
|
606
|
-
"subtask_prompt": "
|
|
589
|
+
"subtask_prompt": "Read canonical contracts/backend-test-execution-readiness.json, verify final asset hashes, then resolve the final Markdown Automation Notes/自动化映射 to a unique, safe set of testcase/**/test_*.py targets and execute only those scripts exactly once. Prefer the deterministic module one-to-one path when a mapped script is missing but the module stem file exists. Generate a native pytest-html self-contained report, then render the primary self-contained Chinese HTML report from the same pytest-html plus final Markdown case metadata without rerun. Keep 测试结论 and quality status; make node 6 Markdown validation + case coverage and node 13 traceability + Markdown-to-pytest correspondence expandable to their full escaped details; show each failure overview item with its original pytest message plus deterministic evidence-based reason analysis; list failure/error case cards before the remaining cases while preserving stable order. Each polished per-case result card includes concise scenario, automation test name, result, duration, and redacted bounded HTTP request parameters/response results for both passed and failed cases. Do not render a technical/execution evidence section in HTML; retain auditable paths and hashes in facts.",
|
|
607
590
|
"shell": {
|
|
608
591
|
"commands": [
|
|
609
592
|
"mkdir -p \"${HARNESS_DAG_RUN_DIR}/reports\"; echo \"pytest targets are resolved at runtime from final Markdown 自动化映射\""
|
|
@@ -620,23 +603,20 @@
|
|
|
620
603
|
"execute-backend-pytest-and-html-report-shell"
|
|
621
604
|
],
|
|
622
605
|
"role": "closeout",
|
|
623
|
-
"executor": "
|
|
624
|
-
"complexity": "
|
|
625
|
-
"
|
|
626
|
-
"
|
|
627
|
-
"writeSet": [
|
|
628
|
-
"docs/test-reports/**"
|
|
629
|
-
],
|
|
630
|
-
"allowedPaths": [
|
|
631
|
-
"docs/test-reports/**"
|
|
632
|
-
],
|
|
606
|
+
"executor": "static",
|
|
607
|
+
"complexity": "LOW",
|
|
608
|
+
"writePolicy": "none",
|
|
609
|
+
"allowedPaths": [],
|
|
633
610
|
"forbiddenPaths": [
|
|
634
611
|
".harness/**",
|
|
635
612
|
".harness/dag-runs/**",
|
|
636
613
|
"artifacts/**"
|
|
637
614
|
],
|
|
638
|
-
"outputContract": "
|
|
639
|
-
"subtask_prompt": "Generate the final Markdown report only from authoritative run-owned artifacts. Read node 1 reports/backend-test-environment.md; node 6 backend-md-case-validation.md and backend-test-case-coverage-analysis.md; nodes 10/12 backend-test-pytest-collection initial/effective reports and facts; node 13 backend-test-traceability.md, backend-test-markdown-pytest-correspondence.md and backend-test-scenario-param-consistency.md; node 14 contracts/backend-test-case-manifest.json; and node 15 backend-test-result.json, backend-test-facts.md, backend-test-failure-analysis.md, pytest-html/HTML and L-5 dashboard. Do not use node 2/3/4/7/8/9 assistant prose as facts. Do not emit JSON.\n\nUse this exact human-facing section order: 测试结论 → 执行概览 → 质量校验 → 失败分析 → 风险与建议 → 证据与 L-5. Put the decision and key numbers first, use compact tables/bullets, and keep headings concise. Do not paste entire upstream reports, duplicate per-case tables already present in facts, or repeat the same evidence in multiple sections; link to paths/hashes and quote only the findings needed for the conclusion. Prefer linking reports/backend-test-failure-analysis.md for structured failure analysis rather than inventing classifications.\n\nOutput budget: list evidence paths first, then write a short fixed six-section report; never paste upstream full text into chat.\n\nThe L-5 metrics and visualization are produced deterministically by node 15 at reports/backend-test-l5-dashboard.html. Link to that dashboard as the authoritative L-5 view. Pytest execution facts come from node 15; coverage/correspondence numbers and materializationStatus come from node 14; collection authorization comes from nodes 10/12; detailed coverage findings come from node 6; detailed mapping findings come from node 13. Never recompute these values. If machine manifest and human reports disagree, report evidence inconsistency rather than silently choosing.\n\nAlways state the exact Coverage Scope classification, policy, affected operations, regression floor, completeness claim, PASS/FAIL/UNAVAILABLE status and findings from node 6 case validation + coverage, plus node 13 traceability + correspondence. Affected-scope or affected-operations-full coverage must never be described as whole-API completeness unless every operation is explicitly listed. Their FAIL status does not block pytest, but it must remain visible and must never be rewritten as PASS.\n\nInclude environment, case quality/review, automation mapping, exact pytest facts, failure classification/analysis, risks, regression recommendations, evidence paths/hashes, coverage availability, and L-5 READY/NOT READY. Distinguish Markdown Case count, primary pytest symbol count, collected pytest item count, variant/assertion/cross-cutting Test Point counts and execution amplification; never describe pytest item count as the number of business scenarios.\n\nNever override Shell/pytest-html facts. L-5 requires pass=100%, AC=100%, automation>=90%, line>=80%, branch>=70%, skipped=0 and no blocking Critical risk.\n\
|
|
615
|
+
"outputContract": "Deterministic evidence handoff linking the node 15 Markdown facts, HTML report, failure analysis and L-5 dashboard; no model invocation, JSON or writes.",
|
|
616
|
+
"subtask_prompt": "Generate the final Markdown report only from authoritative run-owned artifacts. Read node 1 reports/backend-test-environment.md; node 6 backend-md-case-validation.md and backend-test-case-coverage-analysis.md; nodes 10/12 backend-test-pytest-collection initial/effective reports and facts; node 13 backend-test-traceability.md, backend-test-markdown-pytest-correspondence.md and backend-test-scenario-param-consistency.md; node 14 contracts/backend-test-case-manifest.json; and node 15 backend-test-result.json, backend-test-facts.md, backend-test-failure-analysis.md, pytest-html/HTML and L-5 dashboard. Do not use node 2/3/4/7/8/9 assistant prose as facts. Do not emit JSON.\n\nUse this exact human-facing section order: 测试结论 → 执行概览 → 质量校验 → 失败分析 → 风险与建议 → 证据与 L-5. Put the decision and key numbers first, use compact tables/bullets, and keep headings concise. Do not paste entire upstream reports, duplicate per-case tables already present in facts, or repeat the same evidence in multiple sections; link to paths/hashes and quote only the findings needed for the conclusion. Prefer linking reports/backend-test-failure-analysis.md for structured failure analysis rather than inventing classifications.\n\nOutput budget: list evidence paths first, then write a short fixed six-section report; never paste upstream full text into chat.\n\nThe L-5 metrics and visualization are produced deterministically by node 15 at reports/backend-test-l5-dashboard.html. Link to that dashboard as the authoritative L-5 view. Pytest execution facts come from node 15; coverage/correspondence numbers and materializationStatus come from node 14; collection authorization comes from nodes 10/12; detailed coverage findings come from node 6; detailed mapping findings come from node 13. Never recompute these values. If machine manifest and human reports disagree, report evidence inconsistency rather than silently choosing.\n\nAlways state the exact Coverage Scope classification, policy, affected operations, regression floor, completeness claim, PASS/FAIL/UNAVAILABLE status and findings from node 6 case validation + coverage, plus node 13 traceability + correspondence. Affected-scope or affected-operations-full coverage must never be described as whole-API completeness unless every operation is explicitly listed. Their FAIL status does not block pytest, but it must remain visible and must never be rewritten as PASS.\n\nInclude environment, case quality/review, automation mapping, exact pytest facts, failure classification/analysis, risks, regression recommendations, evidence paths/hashes, coverage availability, and L-5 READY/NOT READY. Distinguish Markdown Case count, primary pytest symbol count, collected pytest item count, variant/assertion/cross-cutting Test Point counts and execution amplification; never describe pytest item count as the number of business scenarios.\n\nNever override Shell/pytest-html facts. L-5 requires pass=100%, AC=100%, automation>=90%, line>=80%, branch>=70%, skipped=0 and no blocking Critical risk.\n\nNode 15 already rendered the authoritative Markdown and HTML outputs; this node only hands off their stable paths without recomputation.",
|
|
617
|
+
"static": {
|
|
618
|
+
"resultMarkdown": "# Backend-test deterministic closeout\n\nAuthoritative execution facts: `reports/backend-test.md` and `contracts/backend-test-result.json`.\nFailure analysis: `reports/backend-test-failure-analysis.md`.\nHTML report: `reports/backend-test.html`.\nL-5 dashboard: `reports/backend-test-l5-dashboard.html`."
|
|
619
|
+
}
|
|
640
620
|
}
|
|
641
621
|
],
|
|
642
622
|
"sourceBinding": {
|
|
@@ -18,7 +18,7 @@
|
|
|
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, 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
|
|
21
|
+
"Case executors use structured playwright_cli custom tool under commandPolicy capability-allowlist; playwright-cli stays capability-gated while ordinary writers have bash.",
|
|
22
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
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.",
|
|
24
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.",
|
package/harness.json
CHANGED
|
@@ -80,9 +80,9 @@
|
|
|
80
80
|
"executors": {
|
|
81
81
|
"pi": {
|
|
82
82
|
"description": "Pi planning, review, diagnosis, and bounded writing when DAG toolProfile=write",
|
|
83
|
-
"LOW": "
|
|
84
|
-
"MED": "
|
|
85
|
-
"HIGH": "
|
|
83
|
+
"LOW": "minimax-m3",
|
|
84
|
+
"MED": "grok-4.5",
|
|
85
|
+
"HIGH": "gpt-5.6-sol"
|
|
86
86
|
}
|
|
87
87
|
}
|
|
88
88
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tea-agent/loop-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.31.1",
|
|
4
4
|
"type": "module",
|
|
5
5
|
"bin": {
|
|
6
6
|
"loop-agent": "bin/loop-agent.js",
|
|
@@ -44,7 +44,8 @@
|
|
|
44
44
|
"cursor": "node --import tsx/esm src/cli.ts cursor-prompt",
|
|
45
45
|
"pi-prompt": "node --import tsx/esm src/cli.ts pi-prompt",
|
|
46
46
|
"clean": "node -e \"require('node:fs').rmSync('dist',{recursive:true,force:true})\"",
|
|
47
|
-
"
|
|
47
|
+
"brand:sync": "node scripts/sync-brand-assets.mjs",
|
|
48
|
+
"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",
|
|
48
49
|
"console:build": "vite build --config src/worker/console/vite.config.ts",
|
|
49
50
|
"prepack": "npm run build",
|
|
50
51
|
"prepublishOnly": "node scripts/check-npm-publish-policy.mjs && npm run typecheck && npm test && npm run build",
|
|
@@ -168,7 +168,7 @@ loop-agent task advance <id> --task-kind knowledge-graph-bootstrap --allowed-pat
|
|
|
168
168
|
# bash scripts/kb-query.sh --mode by_feature --feature F-2026-004 --json
|
|
169
169
|
```
|
|
170
170
|
|
|
171
|
-
See `docs/
|
|
171
|
+
See `docs/architecture/knowledge-graph-and-query-spec.md` and `docs/design/active/knowledge-graph-ai-bootstrap.md`.
|
|
172
172
|
EOF
|
|
173
173
|
)
|
|
174
174
|
|