@tea-agent/loop-agent 0.16.26 → 0.17.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 +45 -1
- package/README.md +14 -3
- package/dist/cli/command-definitions.js +43 -0
- package/dist/cli/program.js +26 -0
- package/dist/commands/dag-approve.js +4 -0
- package/dist/commands/dag-resume.js +1 -0
- package/dist/commands/dag-validate.js +6 -0
- package/dist/commands/operator.js +44 -0
- package/dist/commands/task-contract.js +271 -0
- package/dist/executors/dag-pi-executor.js +55 -7
- package/dist/executors/pi-executor.js +206 -13
- package/dist/executors/pi-sdk-executor.js +21 -6
- package/dist/executors/shell-executor.js +55 -8
- package/dist/executors/shell-presets.js +16 -3
- package/dist/shared/operator/capabilities.js +255 -0
- package/dist/shared/operator/envelope.js +59 -0
- package/dist/shared/operator/index.js +4 -0
- package/dist/shared/operator/registry.js +38 -0
- package/dist/shared/operator/types.js +5 -0
- package/dist/task/contract/adopt.js +166 -0
- package/dist/task/contract/apply.js +326 -0
- package/dist/task/contract/canonicalize.js +60 -0
- package/dist/task/contract/constants.js +29 -0
- package/dist/task/contract/diff.js +177 -0
- package/dist/task/contract/hash.js +42 -0
- package/dist/task/contract/import-revision.js +96 -0
- package/dist/task/contract/index.js +17 -0
- package/dist/task/contract/journal.js +155 -0
- package/dist/task/contract/lock.js +153 -0
- package/dist/task/contract/observe.js +296 -0
- package/dist/task/contract/paths.js +19 -0
- package/dist/task/contract/project.js +170 -0
- package/dist/task/contract/recover.js +312 -0
- package/dist/task/contract/request-ledger.js +37 -0
- package/dist/task/contract/schema.js +151 -0
- package/dist/task/contract/transaction.js +160 -0
- package/dist/task/contract/types.js +1 -0
- package/dist/task/contract/validate-draft.js +106 -0
- package/dist/task/index.js +3 -0
- package/dist/task/operator/capabilities.js +6 -0
- package/dist/task/operator/envelope.js +2 -0
- package/dist/task/operator/index.js +5 -0
- package/dist/task/operator/registry.js +2 -0
- package/dist/task/operator/types.js +1 -0
- package/dist/task/runtime.js +5 -1
- package/dist/task/source-references.js +7 -0
- package/dist/worker/cli.js +150 -32
- package/dist/worker/console/app-data.js +185 -0
- package/dist/worker/console/dag-confirmation.js +313 -0
- package/dist/worker/console/doctor.js +169 -0
- package/dist/worker/console/draft-store.js +80 -0
- package/dist/worker/console/index.js +15 -0
- package/dist/worker/console/interview/assessment.js +67 -0
- package/dist/worker/console/interview/session.js +100 -0
- package/dist/worker/console/interview/tools.js +109 -0
- package/dist/worker/console/loopback.js +16 -0
- package/dist/worker/console/observe-health-match.js +174 -0
- package/dist/worker/console/observe-link.js +33 -0
- package/dist/worker/console/operation-runner.js +166 -0
- package/dist/worker/console/operation-sse.js +158 -0
- package/dist/worker/console/operation-store.js +147 -0
- package/dist/worker/console/operator-actions.js +769 -0
- package/dist/worker/console/pi-readiness.js +266 -0
- package/dist/worker/console/recovery-cta.js +133 -0
- package/dist/worker/console/repo-fingerprint.js +29 -0
- package/dist/worker/console/resource-loader.js +95 -0
- package/dist/worker/console/routes.js +368 -0
- package/dist/worker/console/security.js +126 -0
- package/dist/worker/console/server.js +149 -0
- package/dist/worker/console/sibling-controller.js +28 -0
- package/dist/worker/console/static/assets/index-BEIdBogJ.js +9 -0
- package/dist/worker/console/static/assets/index-Rt0TqimP.css +1 -0
- package/dist/worker/console/static/index.html +13 -0
- package/dist/worker/console/vite.config.js +27 -0
- package/dist/worker/materialize/harness-task-materializer.js +34 -0
- package/dist/worker/observe/health.js +57 -0
- package/dist/worker/observe/routes.js +16 -9
- package/dist/workflows/dag/backend-test-analysis-contract.js +34 -9
- package/dist/workflows/dag/dynamic-runtime/shared.js +1 -0
- package/dist/workflows/dag/frontend-repair.js +1 -10
- package/dist/workflows/dag/init-hybrid.js +269 -116
- package/dist/workflows/dag/node-execution.js +25 -1
- package/dist/workflows/dag/retry-policy.js +16 -1
- package/dist/workflows/dag/runner.js +9 -0
- package/dist/workflows/dag/task-contract-binding.js +138 -0
- package/dist/workflows/dag/types.js +74 -10
- package/dist/workflows/dag/validate.js +25 -7
- package/docs/README.md +2 -0
- package/docs/architecture/evolution.md +2 -0
- package/docs/architecture/system-overview.md +6 -0
- package/docs/architecture/worker-and-feature.md +7 -0
- package/docs/templates/agent-dag.schema.json +49 -2
- package/docs/templates/backend-test-dag.classify.prompt.md +1 -1
- package/docs/templates/backend-test-dag.generate-pytest.prompt.md +5 -5
- package/docs/templates/backend-test-dag.json +26 -154
- package/docs/templates/backend-test-dag.retrospect.prompt.md +1 -1
- package/docs/templates/backend-test-dag.review-cases.prompt.md +2 -2
- package/package.json +8 -2
- package/skills/agent-worker/SKILL.md +1 -0
- package/skills/agent-worker/references/agent-worker-operator.md +3 -2
- package/skills/frontend-design-review/SKILL.md +25 -16
- package/skills/frontend-implementation/references/node-contracts.md +5 -5
- package/skills/loop-agent/references/command-reference.md +48 -1
- package/skills/loop-agent/references/hybrid-dag.md +4 -4
|
@@ -28,9 +28,10 @@
|
|
|
28
28
|
"Root artifacts/ is reserved for explicit exclusive write nodes, not read-only scout/reviewer output",
|
|
29
29
|
"exclusive implementer nodes must use narrow, concrete writeSet paths; never keep ** or repo root",
|
|
30
30
|
"Replace REPLACE/WITH/NARROW/IMPLEMENT/PATHS/** with concrete paths before executing the implementation writer",
|
|
31
|
-
"backend-test-dag uses exactly
|
|
32
|
-
"Case
|
|
33
|
-
"
|
|
31
|
+
"backend-test-dag uses exactly 12 real top-level tasks and executes pytest exactly once.",
|
|
32
|
+
"Case review is advisory evidence consumed by canonical context, retrospective, and L-5; it does not authorize or block the pytest writer.",
|
|
33
|
+
"Deterministic traceability is the only generated-asset hard gate before pytest.",
|
|
34
|
+
"Analysis, execution, manifest, case review, traceability, single-run result, classification, canonical context, retrospective and L-5 evidence remain run-owned and fail-closed.",
|
|
34
35
|
"Functional test case IDs must use BE-<MODULE>-<NNN> format.",
|
|
35
36
|
"pytest writers may only create the initially declared testcase assets; production code, config, skip/xfail, swallowed failures and mock substitution are forbidden."
|
|
36
37
|
],
|
|
@@ -68,8 +69,8 @@
|
|
|
68
69
|
"executorModels": {
|
|
69
70
|
"pi": {
|
|
70
71
|
"LOW": "gpt-5.3-codex-spark",
|
|
71
|
-
"MED": "
|
|
72
|
-
"HIGH": "gpt-5.
|
|
72
|
+
"MED": "glm-5.2",
|
|
73
|
+
"HIGH": "gpt-5.5"
|
|
73
74
|
}
|
|
74
75
|
},
|
|
75
76
|
"tasks": [
|
|
@@ -191,7 +192,8 @@
|
|
|
191
192
|
"id": "review-backend-cases-pi",
|
|
192
193
|
"depends_on": [
|
|
193
194
|
"backend-test-case-manifest-shell",
|
|
194
|
-
"validate-backend-test-contracts-shell"
|
|
195
|
+
"validate-backend-test-contracts-shell",
|
|
196
|
+
"generate-backend-pytest-pi"
|
|
195
197
|
],
|
|
196
198
|
"role": "reviewer",
|
|
197
199
|
"executor": "pi",
|
|
@@ -206,8 +208,8 @@
|
|
|
206
208
|
".harness/dag-runs/**",
|
|
207
209
|
"artifacts/**"
|
|
208
210
|
],
|
|
209
|
-
"outputContract": "
|
|
210
|
-
"subtask_prompt": "Review the generated backend functional test cases under testcase/md/ and the validated Case Manifest v1.\n\n## Mandatory First Line:\n\nFirst non-empty line must be exactly: VERDICT: pass or VERDICT: request-revision\n\n## Review Checklist:\n\n- ID format: every case uses BE-<MODULE>-<NNN> (full ids only in bodies and matrices)\n\n- Positive coverage: each in-scope acceptance criterion (AC-xxx) has happy-path case\n\n- Negative coverage: error scenarios (invalid input, not found, state violations)\n\n- Traceability: each explicit AC maps to a case ID or an evidenceGap in contracts/backend-test-case-manifest.json\n\n- Case structure: ID, Title, Precondition, Steps, Expected Result\n\n- No duplicate IDs across files\n\n- Manifest consistency (Critical): every AC claimed in MD case bodies/matrices must match manifest caseId→acIds; never accept 'all cases cover AC-xxx' unless every case maps that AC\n\n## Conditional Coverage (check ONLY if mentioned in upstream analysis):\n\n- Boundary coverage: check ONLY if analyze-inputs-pi mentions value ranges, length limits, numeric bounds, or format constraints\n\n- State transition coverage: check ONLY if analyze-inputs-pi mentions state machine\n\n- Authentication coverage: check ONLY if analyze-inputs-pi mentions auth mechanism\n\n- Timeout coverage: check ONLY if analyze-inputs-pi mentions timeout handling\n\n- Concurrency coverage: check ONLY if analyze-inputs-pi mentions concurrency/idempotency rules\n\n- If not mentioned, do NOT flag as missing\n\n## Do NOT treat as Critical alone:\n\n- Missing test_*.py / automation still planned (expected before generate-backend-pytest-pi)\n\n- Out-of-scope ACs already listed in manifest evidenceGaps (Flyway, frontend e2e, mvn test)\n\n## Verdict Rules:\n\n- All Critical checks pass + Important findings ≤ 2 → VERDICT: pass\n\n- Any Critical fails OR Important > 2 → VERDICT: request-revision\n\n- Any request-revision verdict
|
|
211
|
+
"outputContract": "advisory case review evidence whose first non-empty line is VERDICT: pass or VERDICT: request-revision; followed by Findings and Coverage Assessment. No file writes; this review neither authorizes nor blocks pytest generation.",
|
|
212
|
+
"subtask_prompt": "Review the generated backend functional test cases under testcase/md/ and the validated Case Manifest v1.\n\n## Mandatory First Line:\n\nFirst non-empty line must be exactly: VERDICT: pass or VERDICT: request-revision\n\n## Review Checklist:\n\n- ID format: every case uses BE-<MODULE>-<NNN> (full ids only in bodies and matrices)\n\n- Positive coverage: each in-scope acceptance criterion (AC-xxx) has happy-path case\n\n- Negative coverage: error scenarios (invalid input, not found, state violations)\n\n- Traceability: each explicit AC maps to a case ID or an evidenceGap in contracts/backend-test-case-manifest.json\n\n- Case structure: ID, Title, Precondition, Steps, Expected Result\n\n- No duplicate IDs across files\n\n- Manifest consistency (Critical): every AC claimed in MD case bodies/matrices must match manifest caseId→acIds; never accept 'all cases cover AC-xxx' unless every case maps that AC\n\n## Conditional Coverage (check ONLY if mentioned in upstream analysis):\n\n- Boundary coverage: check ONLY if analyze-inputs-pi mentions value ranges, length limits, numeric bounds, or format constraints\n\n- State transition coverage: check ONLY if analyze-inputs-pi mentions state machine\n\n- Authentication coverage: check ONLY if analyze-inputs-pi mentions auth mechanism\n\n- Timeout coverage: check ONLY if analyze-inputs-pi mentions timeout handling\n\n- Concurrency coverage: check ONLY if analyze-inputs-pi mentions concurrency/idempotency rules\n\n- If not mentioned, do NOT flag as missing\n\n## Do NOT treat as Critical alone:\n\n- Missing test_*.py / automation still planned (expected before generate-backend-pytest-pi)\n\n- Out-of-scope ACs already listed in manifest evidenceGaps (Flyway, frontend e2e, mvn test)\n\n## Verdict Rules:\n\n- All Critical checks pass + Important findings ≤ 2 → VERDICT: pass\n\n- Any Critical fails OR Important > 2 → VERDICT: request-revision\n\n- Any request-revision verdict is advisory evidence for canonical context, retrospective, and L-5; it does not authorize or block the pytest writer.\n\n## Output After Verdict:\n\n1. Coverage Assessment table (AC → full BE-* case IDs) using manifest + MD\n\n2. Findings list (Critical/Important/Informational)\n\n3. Statistics (total cases, positive/negative/boundary breakdown)\n\n4. Required follow-up actions (only when request-revision; no in-run writer)\n\n## Constraints:\n\n- Read-only: do not modify files\n\n- Read validated analysis + case manifest artifacts; do not recompute coverage percentages\n\n- Use testcase/md/ files for case review",
|
|
211
213
|
"retryPolicy": {
|
|
212
214
|
"maxAttempts": 3,
|
|
213
215
|
"backoff": "exponential",
|
|
@@ -221,44 +223,10 @@
|
|
|
221
223
|
]
|
|
222
224
|
}
|
|
223
225
|
},
|
|
224
|
-
{
|
|
225
|
-
"id": "review-backend-cases-gate-shell",
|
|
226
|
-
"depends_on": [
|
|
227
|
-
"review-backend-cases-pi"
|
|
228
|
-
],
|
|
229
|
-
"role": "verifier",
|
|
230
|
-
"executor": "shell",
|
|
231
|
-
"complexity": "LOW",
|
|
232
|
-
"writePolicy": "read-only",
|
|
233
|
-
"allowedPaths": [
|
|
234
|
-
"testcase/**",
|
|
235
|
-
"docs/test-reports/**"
|
|
236
|
-
],
|
|
237
|
-
"forbiddenPaths": [
|
|
238
|
-
".harness/**",
|
|
239
|
-
".harness/dag-runs/**",
|
|
240
|
-
"artifacts/**"
|
|
241
|
-
],
|
|
242
|
-
"outputContract": "Deterministic backend case review gate: exit 0 only when the first and only review emits VERDICT: pass.",
|
|
243
|
-
"subtask_prompt": "Block pytest generation when backend case review requests revision; do not authorize an in-run writer.",
|
|
244
|
-
"shell": {
|
|
245
|
-
"commands": [],
|
|
246
|
-
"verdictGate": {
|
|
247
|
-
"fromNodeId": "review-backend-cases-pi",
|
|
248
|
-
"accept": [
|
|
249
|
-
"VERDICT: pass"
|
|
250
|
-
],
|
|
251
|
-
"label": "backend case review",
|
|
252
|
-
"lineMode": "first-verdict-line"
|
|
253
|
-
},
|
|
254
|
-
"cwd": ".",
|
|
255
|
-
"timeoutMs": 60000
|
|
256
|
-
}
|
|
257
|
-
},
|
|
258
226
|
{
|
|
259
227
|
"id": "generate-backend-pytest-pi",
|
|
260
228
|
"depends_on": [
|
|
261
|
-
"
|
|
229
|
+
"backend-test-case-manifest-shell",
|
|
262
230
|
"validate-backend-test-contracts-shell"
|
|
263
231
|
],
|
|
264
232
|
"role": "implementer",
|
|
@@ -280,48 +248,15 @@
|
|
|
280
248
|
".harness/dag-runs/**",
|
|
281
249
|
"artifacts/**"
|
|
282
250
|
],
|
|
283
|
-
"subtask_prompt": "Convert the
|
|
251
|
+
"subtask_prompt": "Convert the validated test cases under testcase/md/ into pytest automation code.\n\n\n\n## Inputs (MUST use validated contracts):\n\n- Validated cases under testcase/md/ and contracts/backend-test-case-manifest.json (case review runs independently as advisory evidence).\n\n- Validated Backend Test Analysis v2 under contracts/backend-test-analysis.json.\n\n\n\n- Validated Backend Test Execution Contract v1 under contracts/backend-test-execution.json (execution gate).\n\nUse only fixture names, env NAMES, testRoot, targetMode, and field/API facts already present in those contracts or reviewed cases. Do not invent production credentials or secret values.\n\nWhen targetMode is in-process (including demoted local npm/node managed servers): bootstrap the service inside function-scoped pytest fixtures under testcase/** — e.g. subprocess node server.js / startWelcomeServer with PORT=0 — and never require host-injected base URL env vars (clean-env shell will not provide WELCOME_BASE_URL / API_BASE_URL).\n\nDo not depend on requiredEnvNames being present at process start for in-process mode; if the contract still lists an env name, the fixture must set it or start the server without that env.\n\n\n\n## Output Steps (do in order):\n\n1. First, output a brief summary: how many files, how many test functions planned\n\n2. Then write each test file under testcase/\n\n\n\n## Format Rules:\n\n- File prefix: test_<module>.py\n\n- Function name: test_BE_<MODULE>_<NNN>_<description>\n\n- Docstring first line: BE-<MODULE>-<NNN>: <Case Title>\n\n- 1:1 mapping: each functional case → one pytest function\n\n\n\n## Implementation Rules:\n\n- Use assert statements, not unittest assertions\n\n- Use @pytest.mark.parametrize for boundary cases when the case defines edge values\n\n- Use markers: @pytest.mark.positive, @pytest.mark.negative, @pytest.mark.boundary\n\n\n\n## Test Data Preparation Rules (MUST follow):\n\n\n\n### When Setup is Needed\n\nSetup phase is REQUIRED only when test cases need pre-existing data:\n\n- Query/Read APIs: need data to exist before querying\n\n- Update/Delete APIs: need data to exist before modifying\n\n- State transition tests: need data in specific state\n\n\n\nSetup phase is NOT needed for:\n\n- Create APIs: testing the creation itself\n\n- Validation tests: testing input validation with invalid data\n\n\n\n### Data Setup Strategy\n\nWhen setup is needed:\n\n1. Prefer function-scoped fixtures for isolation; use module/session scope only when cases explicitly share immutable fixtures\n\n2. Prefer API-based setup from the upstream analyze-inputs-pi API list and reviewed cases\n\n3. If a required helper/factory is missing, create NEW files only under testcase/**/helpers/** or testcase/**/factories/**\n\n\n\n### Data Construction Priority\n\n1. API-first: construct data via documented APIs from analyze-inputs-pi / reviewed cases\n\n2. Reuse existing conftest fixtures when present (read-only)\n\n3. Direct DB writes are LAST RESORT and only if conftest already exposes a safe test DB fixture with rollback/isolation\n\n4. If neither API nor safe DB fixture exists, skip the case with an explicit gap note — do NOT invent production DB credentials or write live data\n\n\n\n### API Data Construction\n\n- Prefer the analyze-inputs-pi API Endpoints section and reviewed cases for method/path/fields\n\n- Chain API calls only when cases document multi-step preconditions\n\n- Store created resource IDs in fixtures for reuse\n\n- Do NOT broadly search host route/controller trees for secrets, .env, private keys, or production configs\n\n- Read host API definitions only when needed to resolve a field name already referenced by reviewed cases; stay out of credential/config paths\n\n\n\n### Database Data Construction (restricted)\n\n- Allowed only via existing conftest test-DB fixtures with transaction rollback or equivalent isolation\n\n- Never hardcode connection strings, passwords, tokens, or cloud credentials\n\n- Never target production/shared non-test databases\n\n- If isolation is unclear, report the gap instead of writing DB rows\n\n\n\n## Assertion Rules (MUST follow):\n\n\n\n### Positive Path\n\nMUST assert ALL of the following:\n\n1. HTTP status code: as defined in API spec (e.g. 200, 201)\n\n2. Response structure: key fields exist in response body\n\n3. Specific values: each field equals expected value from test case\n\n4. Data type: each field is correct type\n\n\n\n### Negative Path\n\nMUST assert ALL of the following:\n\n1. HTTP status code: as defined in API spec (e.g. 400, 404, 500)\n\n2. Error code field: field name from API spec (e.g. code, error_code, errcode, ret)\n\n3. Error message field: field name from API spec (e.g. message, msg, errmsg, error)\n\n\n\n### Field Name Resolution\n\nField names MUST come from the upstream analyze-inputs-pi output (API Endpoints section) or reviewed cases, NOT guessed. For example:\n\n- If API spec defines {\"ret\": 0, \"msg\": \"success\"}, assert response.json()['ret'] and response.json()['msg']\n\n- If API spec defines {\"code\": 4001, \"message\": \"error\"}, assert response.json()['code'] and response.json()['message']\n\n\n\n## Conditional Implementation (include ONLY if test cases exist):\n\n- Authentication tests: implement ONLY if testcase/md/ contains auth-related cases\n\n- Timeout tests: implement ONLY if testcase/md/ contains timeout-related cases\n\n- Boundary tests: implement ONLY when cases define value ranges, length limits, or format constraints\n\n- Use @pytest.mark.auth for auth tests, @pytest.mark.timeout for timeout tests\n\n- If no such cases exist, do NOT add these tests\n\n\n\n## Constraints:\n\n- Only create NEW files under writeSet: testcase/**/test_*.py, testcase/**/helpers/**, testcase/**/factories/**\n\n- Do NOT modify existing framework files (conftest.py, pytest.ini, pyproject.toml, setup.cfg, __init__.py)\n\n- If a test filename exists, add suffix: test_order.py → test_order_01.py\n\n- Do NOT re-read source documents — use reviewed cases under testcase/md/ and upstream analyze-inputs-pi output only\n\n- Read existing conftest.py/pytest.ini to understand conventions, but do NOT modify them\n\n- Do NOT execute pytest/python -m pytest or npm test in this node; the single execution is owned by the dedicated shell node. Local smoke runs create __pycache__/.pytest_cache and are unnecessary here."
|
|
284
252
|
},
|
|
285
253
|
{
|
|
286
|
-
"id": "
|
|
254
|
+
"id": "backend-test-traceability-gate-shell",
|
|
287
255
|
"depends_on": [
|
|
288
256
|
"generate-backend-pytest-pi",
|
|
289
|
-
"validate-backend-test-contracts-shell",
|
|
290
|
-
"backend-test-case-manifest-shell"
|
|
291
|
-
],
|
|
292
|
-
"role": "reviewer",
|
|
293
|
-
"executor": "pi",
|
|
294
|
-
"complexity": "MED",
|
|
295
|
-
"writePolicy": "read-only",
|
|
296
|
-
"allowedPaths": [
|
|
297
|
-
"testcase/**"
|
|
298
|
-
],
|
|
299
|
-
"forbiddenPaths": [
|
|
300
|
-
".harness/**",
|
|
301
|
-
".harness/dag-runs/**",
|
|
302
|
-
"artifacts/**"
|
|
303
|
-
],
|
|
304
|
-
"outputContract": "Pure Backend Test Semantic Review v1 JSON: verdict, findings[], summary. No file writes.",
|
|
305
|
-
"subtask_prompt": "Review generated pytest semantics before the single execution.\n\nUse only compact authoritative inputs: contracts/backend-test-analysis.json, contracts/backend-test-case-manifest.json, testcase/md/**, and generated testcase/**/test_*.py/helpers/factories.\n\nReturn exactly one pure JSON object with only verdict, findings, summary; no Markdown fence or surrounding prose.\n\nverdict must be pass or request-revision. Each findings[] item must contain exactly severity, caseId, testFile, testSymbol, contractRefs, issue, requiredChange.\n\nseverity must be exactly Critical, Important, or Informational; contractRefs must be a non-empty string array. A request-revision verdict requires at least one finding; pass must not contain Critical findings.\n\nMinimal shape: {\"verdict\":\"pass\",\"findings\":[],\"summary\":\"No contract-backed semantic contradiction found.\"}\n\nCheck responseBody.kind (array vs object/items), ordering, field comparison (especially parseable-only date-time precision), documented status/error fields, and each caseId→symbol assertion meaning.\n\nDo not use aliases such as file, symbol, refs, finding, or requiredFix; the strict contract requires testFile, testSymbol, contractRefs, issue, requiredChange.\n\nrequest-revision only for concrete semantic contradiction with reviewed cases/formal analysis evidence. No style findings.\n\nRead-only; do not edit tests or production code.",
|
|
306
|
-
"retryPolicy": {
|
|
307
|
-
"maxAttempts": 3,
|
|
308
|
-
"backoff": "exponential",
|
|
309
|
-
"initialDelayMs": 2000,
|
|
310
|
-
"maxDelayMs": 30000,
|
|
311
|
-
"retryCategories": [
|
|
312
|
-
"timeout",
|
|
313
|
-
"network",
|
|
314
|
-
"rate-limit",
|
|
315
|
-
"unavailable"
|
|
316
|
-
]
|
|
317
|
-
}
|
|
318
|
-
},
|
|
319
|
-
{
|
|
320
|
-
"id": "validate-semantic-review-and-traceability-shell",
|
|
321
|
-
"depends_on": [
|
|
322
|
-
"review-generated-backend-pytest-pi",
|
|
323
257
|
"backend-test-case-manifest-shell"
|
|
324
258
|
],
|
|
259
|
+
"dependsPolicy": "all-or-condition-skip",
|
|
325
260
|
"role": "verifier",
|
|
326
261
|
"executor": "shell",
|
|
327
262
|
"complexity": "LOW",
|
|
@@ -335,39 +270,12 @@
|
|
|
335
270
|
".harness/dag-runs/**",
|
|
336
271
|
"artifacts/**"
|
|
337
272
|
],
|
|
338
|
-
"outputContract": "
|
|
339
|
-
"subtask_prompt": "
|
|
273
|
+
"outputContract": "Deterministic traceability: generated cases have real file/symbol; skipped/unsupported have gapReason; convention symbols scanned under testcase/**/test_*.py.",
|
|
274
|
+
"subtask_prompt": "Fail closed when generated automation claims do not resolve to workspace pytest symbols, or skip/unsupported lacks gapReason.",
|
|
340
275
|
"shell": {
|
|
341
|
-
"commands": [
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
"timeoutMs": 60000
|
|
345
|
-
}
|
|
346
|
-
},
|
|
347
|
-
{
|
|
348
|
-
"id": "backend-test-semantic-gate-shell",
|
|
349
|
-
"depends_on": [
|
|
350
|
-
"validate-semantic-review-and-traceability-shell",
|
|
351
|
-
"review-generated-backend-pytest-pi"
|
|
352
|
-
],
|
|
353
|
-
"role": "verifier",
|
|
354
|
-
"executor": "shell",
|
|
355
|
-
"complexity": "LOW",
|
|
356
|
-
"writePolicy": "read-only",
|
|
357
|
-
"allowedPaths": [
|
|
358
|
-
"testcase/**",
|
|
359
|
-
"docs/test-reports/**"
|
|
360
|
-
],
|
|
361
|
-
"forbiddenPaths": [
|
|
362
|
-
".harness/**",
|
|
363
|
-
".harness/dag-runs/**",
|
|
364
|
-
"artifacts/**"
|
|
365
|
-
],
|
|
366
|
-
"outputContract": "Pass-only authorization by reading contracts/backend-test-semantic-review.json; only verdict=pass proceeds to the single pytest execution.",
|
|
367
|
-
"subtask_prompt": "Read the canonical semantic review artifact written by validate-semantic-review-and-traceability-shell. Authorize only when verdict is pass. Do not materialize, do not parse raw Pi Markdown or VERDICT lines, and do not authorize an in-run pytest writer.",
|
|
368
|
-
"shell": {
|
|
369
|
-
"commands": [],
|
|
370
|
-
"backendTestPipeline": "semantic-initial",
|
|
276
|
+
"commands": [
|
|
277
|
+
"backend-test-traceability-gate"
|
|
278
|
+
],
|
|
371
279
|
"cwd": ".",
|
|
372
280
|
"timeoutMs": 60000
|
|
373
281
|
}
|
|
@@ -375,7 +283,7 @@
|
|
|
375
283
|
{
|
|
376
284
|
"id": "execute-and-parse-backend-pytest-shell",
|
|
377
285
|
"depends_on": [
|
|
378
|
-
"backend-test-
|
|
286
|
+
"backend-test-traceability-gate-shell",
|
|
379
287
|
"validate-backend-test-contracts-shell"
|
|
380
288
|
],
|
|
381
289
|
"role": "verifier",
|
|
@@ -450,7 +358,9 @@
|
|
|
450
358
|
"id": "materialize-classification-and-result-context-shell",
|
|
451
359
|
"depends_on": [
|
|
452
360
|
"classify-backend-test-result-pi",
|
|
453
|
-
"backend-test-case-manifest-shell"
|
|
361
|
+
"backend-test-case-manifest-shell",
|
|
362
|
+
"review-backend-cases-pi",
|
|
363
|
+
"backend-test-traceability-gate-shell"
|
|
454
364
|
],
|
|
455
365
|
"role": "verifier",
|
|
456
366
|
"executor": "shell",
|
|
@@ -465,8 +375,8 @@
|
|
|
465
375
|
".harness/dag-runs/**",
|
|
466
376
|
"artifacts/**"
|
|
467
377
|
],
|
|
468
|
-
"outputContract": "Materialize Classification v1, copy the unique initial Result to canonical contracts/backend-test-result.json, and emit Result + Manifest + Classification context.",
|
|
469
|
-
"subtask_prompt": "Validate classification and materialize canonical single-run result context without repair eligibility or rerun.",
|
|
378
|
+
"outputContract": "Materialize Classification v1, copy the unique initial Result to canonical contracts/backend-test-result.json, and emit Result + Manifest + Classification + advisory case review + traceability context.",
|
|
379
|
+
"subtask_prompt": "Validate classification and materialize canonical single-run result context with auditable case review and traceability evidence, without repair eligibility or rerun.",
|
|
470
380
|
"shell": {
|
|
471
381
|
"commands": [],
|
|
472
382
|
"backendTestPipeline": "classification-result-context",
|
|
@@ -496,7 +406,7 @@
|
|
|
496
406
|
"artifacts/**"
|
|
497
407
|
],
|
|
498
408
|
"outputContract": "Maturity rating in assistant output plus a report written under docs/test-reports/**.",
|
|
499
|
-
"subtask_prompt": "Read the complete JSON from direct upstream materialize-classification-and-result-context-shell and generate a test retrospective report.\n\nThat JSON contains result, manifest (including coverageSummary), and classification. Treat those fields as authoritative; do not rely on pointer/hash summaries.\n\n\n\n## Output Steps (do in order):\n\n1. First, output the maturity rating on the first line: Rating: A/B/C/D\n\n2. Then write the full report under docs/test-reports/\n\n\n\n## Stats authority (deterministic only):\n\n- Pass rate, failed/error/skipped counts, and failure list MUST come from contracts/backend-test-result.json only.\n\n- AC coverage ratio / case counts MUST come from contracts/backend-test-case-manifest.json coverageSummary (or gate-derived fields). Do NOT invent coverage %.\n\n- Automation coverage MUST use coverageSummary.generatedCount / coverageSummary.caseCount. If either field is missing, write unavailable; do not estimate.\n\n- Code coverage MUST come only from the validated contracts/code-coverage-v1.json artifact generated by coverage.py/pytest-cov or JaCoCo. Show line, branch, function/method, covered, total, ratio, threshold, status, source scope, requirement IDs, tool, commit, and artifact hash.\n\n- Stability MUST come from independent Stability Evidence: use successfulRuns / recordedRuns, same suite/version, and require n≥5; a single run is unavailable.\n\n- Use classify-backend-test-result-pi JSON as interpretive evidence only.\n\n- NEVER rewrite a failed result as passed.
|
|
409
|
+
"subtask_prompt": "Read the complete JSON from direct upstream materialize-classification-and-result-context-shell and generate a test retrospective report.\n\nThat JSON contains result, manifest (including coverageSummary), and classification. Treat those fields as authoritative; do not rely on pointer/hash summaries.\n\n\n\n## Output Steps (do in order):\n\n1. First, output the maturity rating on the first line: Rating: A/B/C/D\n\n2. Then write the full report under docs/test-reports/\n\n\n\n## Stats authority (deterministic only):\n\n- Pass rate, failed/error/skipped counts, and failure list MUST come from contracts/backend-test-result.json only.\n\n- AC coverage ratio / case counts MUST come from contracts/backend-test-case-manifest.json coverageSummary (or gate-derived fields). Do NOT invent coverage %.\n\n- Automation coverage MUST use coverageSummary.generatedCount / coverageSummary.caseCount. If either field is missing, write unavailable; do not estimate.\n\n- Code coverage MUST come only from the validated contracts/code-coverage-v1.json artifact generated by coverage.py/pytest-cov or JaCoCo. Show line, branch, function/method, covered, total, ratio, threshold, status, source scope, requirement IDs, tool, commit, and artifact hash.\n\n- Stability MUST come from independent Stability Evidence: use successfulRuns / recordedRuns, same suite/version, and require n≥5; a single run is unavailable.\n\n- Use classify-backend-test-result-pi JSON as interpretive evidence only.\n\n- NEVER rewrite a failed result as passed. Result v1 is authoritative for testOutcome; pipeline completion and L-5 readiness are separate conclusions.\n\n\n\n\n\n## Report Structure:\n\n1. Maturity Rating with rationale\n\n2. Test Coverage Summary (Result v1 pass rate, AC coverage, automation coverage, code coverage, and stability evidence)\n\n3. Failed Test Analysis (failure/error details, category, confidence, evidence, and owner direction)\n\n4. Defects (local Bug ledger in the same report directory; unavailable when absent)\n\n5. Risks (Critical/High/Medium/Low, impact, controls, residual risk, treatment; Critical risks block L-5, High risks do not automatically block)\n\n6. Regression Recommendations (immediate, related, periodic, deferred; every item links to failure/risk/AC/case IDs)\n\n7. L-5 conclusion with blocking items\n\n\n\n## Rating Criteria:\n\n- L-5 ready requires pass rate=100%, AC coverage=100%, automation coverage≥90%, stability≥95% with n≥5, line coverage≥80%, branch coverage≥70%, skipped=0, and no blocking Critical risk.\n\n- Any required metric fail or unavailable means L-5 not-ready. Function/method coverage is displayed but not a gate. Preserve the existing A/B/C/D single-run rating separately.\n\n\n\n## Constraints:\n\n- Stay within writeSet: docs/test-reports/**\n\n- Do NOT re-read source documents — use upstream outputs only\n\n- Do not write root artifacts/**"
|
|
500
410
|
},
|
|
501
411
|
{
|
|
502
412
|
"id": "l5-metrics-pi",
|
|
@@ -530,44 +440,6 @@
|
|
|
530
440
|
"unavailable"
|
|
531
441
|
]
|
|
532
442
|
}
|
|
533
|
-
},
|
|
534
|
-
{
|
|
535
|
-
"id": "backend-test-outcome-gate-shell",
|
|
536
|
-
"depends_on": [
|
|
537
|
-
"l5-metrics-pi"
|
|
538
|
-
],
|
|
539
|
-
"role": "verifier",
|
|
540
|
-
"executor": "shell",
|
|
541
|
-
"complexity": "LOW",
|
|
542
|
-
"writePolicy": "read-only",
|
|
543
|
-
"allowedPaths": [
|
|
544
|
-
"testcase/**",
|
|
545
|
-
"docs/test-reports/**"
|
|
546
|
-
],
|
|
547
|
-
"forbiddenPaths": [
|
|
548
|
-
".harness/**",
|
|
549
|
-
".harness/dag-runs/**",
|
|
550
|
-
"artifacts/**"
|
|
551
|
-
],
|
|
552
|
-
"outputContract": "Shell exit 0 only when Result v1 outcome=passed with failed=0 and error=0; non-zero otherwise. Ignores retrospective Markdown.",
|
|
553
|
-
"subtask_prompt": "Gate the backend-test DAG on run-owned Result v1 shell facts only (not retrospective prose).",
|
|
554
|
-
"shell": {
|
|
555
|
-
"commands": [
|
|
556
|
-
"test -n \"${HARNESS_DAG_RUN_DIR:-}\" || { echo \"missing HARNESS_DAG_RUN_DIR for backend-test outcome gate\" >&2; exit 2; }; RESULT=\"${HARNESS_DAG_RUN_DIR}/contracts/backend-test-result.json\"; test -f \"${RESULT}\" || { echo \"missing backend-test result: ${RESULT}\" >&2; exit 2; }; node -e 'const fs=require(\"fs\");const r=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\"));const outcome=String(r.outcome||\"\");const ok=outcome===\"passed\"&&Number(r.failed||0)===0&&Number(r.error||0)===0;console.log(\"backend-test outcome=\"+outcome+\" passed=\"+r.passed+\" failed=\"+r.failed+\" error=\"+r.error+\" executionStatus=\"+r.executionStatus);if(!ok){process.exit(1);}' \"${RESULT}\""
|
|
557
|
-
],
|
|
558
|
-
"verifyEvidence": {
|
|
559
|
-
"phase": "final",
|
|
560
|
-
"quota": "full",
|
|
561
|
-
"commandSource": "inline",
|
|
562
|
-
"commandCount": 1,
|
|
563
|
-
"commandLabels": [
|
|
564
|
-
"test -n \"${HARNESS_DAG_RUN_DIR:-}\" || { echo \"missing HARNESS_DAG_RUN_DIR for backend-test outcome gate\" >&2; exit 2; }; RESULT=\"${HARNESS_DAG_RUN_DIR}/contracts/backend-test-result.json\"; test -f \"${RESULT}\" || { echo \"missing backend-test result: ${RESULT}\" >&2; exit 2; }; node -e 'const fs=require(\"fs\");const r=JSON.parse(fs.readFileSync(process.argv[1],\"utf8\"));const outcome=String(r.outcome||\"\");const ok=outcome===\"passed\"&&Number(r.failed||0)===0&&Number(r.error||0)===0;console.log(\"backend-test outcome=\"+outcome+\" passed=\"+r.passed+\" failed=\"+r.failed+\" error=\"+r.error+\" executionStatus=\"+r.executionStatus);if(!ok){process.exit(1);}' \"${RESULT}\""
|
|
565
|
-
],
|
|
566
|
-
"finalFullRequired": true
|
|
567
|
-
},
|
|
568
|
-
"cwd": ".",
|
|
569
|
-
"timeoutMs": 60000
|
|
570
|
-
}
|
|
571
443
|
}
|
|
572
444
|
],
|
|
573
445
|
"sourceBinding": {
|
|
@@ -31,7 +31,7 @@ You are the Backend Test DAG **test retrospective** agent.
|
|
|
31
31
|
|
|
32
32
|
Your job is to read upstream Result v1 + classification (+ review report) and generate a retrospective report with a maturity rating. Write the report under `docs/test-reports/` only. Stay within `writeSet`. Do not write root `artifacts/**`.
|
|
33
33
|
|
|
34
|
-
This node runs on **both pass and assertion-fail** paths
|
|
34
|
+
This node runs on **both pass and assertion-fail** paths after canonical context. Treat Result v1 as the sole testOutcome authority; pipeline completion and L-5 readiness are separate conclusions. **Never** rewrite a failed result as passed in this report. The context also carries advisory case review and deterministic traceability evidence, which must be reflected in the retrospective.
|
|
35
35
|
|
|
36
36
|
### Output Steps (do in order)
|
|
37
37
|
|
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
## Purpose
|
|
4
4
|
|
|
5
|
-
Use this prompt for the single read-only **backend test case review** node: `executor: "pi"`, `role: "reviewer"`, `writePolicy: "read-only"`. The reviewer audits generated backend functional test cases for completeness, format compliance, and traceability to source requirements.
|
|
5
|
+
Use this prompt for the single read-only **backend test case review** node: `executor: "pi"`, `role: "reviewer"`, `writePolicy: "read-only"`. The reviewer audits generated backend functional test cases for completeness, format compliance, and traceability to source requirements. The verdict is advisory evidence consumed by canonical context, retrospective, and L-5; it neither authorizes nor blocks the pytest writer.
|
|
6
6
|
|
|
7
7
|
Do **not** create `executor: reviewer`. Reviewer is a **role** on `executor: pi`.
|
|
8
8
|
|
|
@@ -86,4 +86,4 @@ Do NOT re-read source documents. Use the validated analysis artifact, case manif
|
|
|
86
86
|
|
|
87
87
|
### Fail-fast note
|
|
88
88
|
|
|
89
|
-
There is no final review or in-run revision writer. Any `request-revision` verdict
|
|
89
|
+
There is no final review or in-run revision writer. Any `request-revision` verdict remains auditable advisory evidence and must be reported downstream; it does not stop pytest generation.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tea-agent/loop-agent",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.17.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
|
-
"build": "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});\"",
|
|
47
|
+
"build": "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
|
+
"console:build": "vite build --config src/worker/console/vite.config.ts",
|
|
48
49
|
"prepack": "npm run build",
|
|
49
50
|
"prepublishOnly": "node scripts/check-npm-publish-policy.mjs && npm run typecheck && npm test && npm run build",
|
|
50
51
|
"lint": "tsc --noEmit",
|
|
@@ -71,9 +72,14 @@
|
|
|
71
72
|
},
|
|
72
73
|
"devDependencies": {
|
|
73
74
|
"@types/node": "^24.6.0",
|
|
75
|
+
"@types/react": "^19.1.8",
|
|
76
|
+
"@types/react-dom": "^19.1.6",
|
|
74
77
|
"@types/semver": "^7.7.1",
|
|
78
|
+
"react": "^19.1.0",
|
|
79
|
+
"react-dom": "^19.1.0",
|
|
75
80
|
"tsx": "^4.20.6",
|
|
76
81
|
"typescript": "^5.9.3",
|
|
82
|
+
"vite": "^7.0.0",
|
|
77
83
|
"vitest": "^3.2.4"
|
|
78
84
|
}
|
|
79
85
|
}
|
|
@@ -16,6 +16,7 @@ references:
|
|
|
16
16
|
- **允许**:`agent-worker` / `loop-agent` CLI;只读 `pool doctor`、`observe`、status/report;冻结 controller identity;选择 Ready 工作与 recovery 命令。
|
|
17
17
|
- **禁止**:绕过 CLI 直接 Edit 业务实现;Worker/DAG 失败后主会话「救火改文件」。
|
|
18
18
|
- **失败时只允许**:保留 evidence → `task retry` / `task reconcile` / `pool mark-failed` / human gate → 再经 CLI 重跑;实现写入仍只经 published `loop-agent` DAG。
|
|
19
|
+
- **Official vs Compatibility**:`agent-worker console serve` 是 Official 本地控制面;openCode 等主会话仍是 Compatibility Assist,二者**不是**同等保证。Console 与 Observe 分进程;深链依赖 Observe health match,Console 不 proxy Observe。
|
|
19
20
|
|
|
20
21
|
## Route the Work
|
|
21
22
|
|
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
主会话使用本 reference 时是 **operator**,不是 implementer:
|
|
8
8
|
|
|
9
9
|
| 允许 | 禁止 |
|
|
10
|
-
|
|
10
|
+
| --- | --- |
|
|
11
11
|
| `agent-worker` / `loop-agent` CLI | 宿主 Edit/Write 直接改业务实现 |
|
|
12
12
|
| 只读 doctor / observe / report / status | Worker 或 DAG 失败后「救火改文件」 |
|
|
13
13
|
| 冻结 controller identity、选 Ready、retry/reconcile | 跳过 published controller 手写实现收尾 |
|
|
@@ -52,7 +52,8 @@ Leaf DAG nodes 不得递归启动 `agent-worker`。Worker 负责 DAG 之外的 s
|
|
|
52
52
|
```
|
|
53
53
|
|
|
54
54
|
doctor 只读;migrate 默认零写入,apply 失败全回滚且不改 JSONL。
|
|
55
|
-
8. Observe(`observe serve|snapshot`)只读;canonical Task 路由为 `/api/features/:featureId/tasks/:taskId` 与 `#/feature/:featureId/task/:taskId`。
|
|
55
|
+
8. Observe(`observe serve|snapshot`)只读;canonical Task 路由为 `/api/features/:featureId/tasks/:taskId` 与 `#/feature/:featureId/task/:taskId`。`GET /api/health` 为 versioned DTO(fingerprint + routeCapabilities)。Console `observeLink` 仅 match 后深链;offline 展示 `agent-worker observe serve --repo . --port 8787`。
|
|
56
|
+
9. Official Console:`agent-worker console serve|doctor`(loopback)。Recovery CTA 为 report/doctor/decision/resume/reconcile/regenerate;无 Cancel、无主 CTA「直接改代码」。主会话 Compatibility Assist 不得替代 Console/CLI 执法。
|
|
56
57
|
|
|
57
58
|
## Versioned Self-Hosting
|
|
58
59
|
|
|
@@ -9,19 +9,29 @@ references:
|
|
|
9
9
|
|
|
10
10
|
# Frontend Design Review
|
|
11
11
|
|
|
12
|
-
For
|
|
13
|
-
|
|
14
|
-
base connector is TODO: never invent results. If
|
|
15
|
-
`<repoRoot>/openspec/**` search/read evidence before
|
|
12
|
+
For frontend design review nodes. Read the checklist; audit contract, scout, Mock
|
|
13
|
+
strategy, effective plan, task bounds, and traceable design evidence. The knowledge-
|
|
14
|
+
base connector is TODO: never invent results. If unavailable or unmatched, require
|
|
15
|
+
`<repoRoot>/openspec/**` search/read evidence before repository conventions.
|
|
16
16
|
|
|
17
17
|
## Verdict Contract
|
|
18
18
|
|
|
19
19
|
First non-empty line: exactly `VERDICT: pass` or `VERDICT: request-revision`.
|
|
20
|
-
Any blocker requires request-revision
|
|
20
|
+
Any blocker requires request-revision. An initial pass is the effective verdict;
|
|
21
|
+
there is no intermediate first-design shell gate.
|
|
21
22
|
|
|
22
|
-
|
|
23
|
-
`
|
|
24
|
-
remaining, incomplete, or
|
|
23
|
+
In standard/full topology, revision and final review run only after initial
|
|
24
|
+
`VERDICT: request-revision`. Verify every Required Plan Correction against the
|
|
25
|
+
complete revision; reject remaining, incomplete, or new gaps. An initial pass uses
|
|
26
|
+
the original plan and skips both conditional nodes.
|
|
27
|
+
|
|
28
|
+
Small-risk topology instead removes initial review and revision, then runs
|
|
29
|
+
`frontend-final-design-review-pi` as the sole review of the original plan. Do not
|
|
30
|
+
expect initial findings or a revision there.
|
|
31
|
+
|
|
32
|
+
The deterministic gate prefers final-review output and falls back to initial review
|
|
33
|
+
only when no current-run final output exists. Existing malformed/non-pass primary
|
|
34
|
+
output fails closed.
|
|
25
35
|
|
|
26
36
|
## Blocking Conditions
|
|
27
37
|
|
|
@@ -35,20 +45,19 @@ remaining, incomplete, or newly introduced gaps.
|
|
|
35
45
|
inline fake data; commented real requests; Mock-on production defaults; test-only
|
|
36
46
|
production imports; or Mock evidence reported as real integration.
|
|
37
47
|
|
|
38
|
-
Knowledge-base absence is advisory if relevant `openspec/` rules were
|
|
39
|
-
|
|
48
|
+
Knowledge-base absence is advisory if relevant `openspec/` rules were read and
|
|
49
|
+
applied. Block skipped fallback, unresolved conflict, or unresolved UI decisions.
|
|
40
50
|
|
|
41
51
|
## Method And Output
|
|
42
52
|
|
|
43
|
-
Map criteria to steps/files/states/checks, audit paths/evidence, classify Blocking
|
|
44
|
-
Advisory, and never edit files.
|
|
53
|
+
Map criteria to steps/files/states/checks, audit paths/evidence, classify Blocking
|
|
54
|
+
or Advisory, and never edit files.
|
|
45
55
|
|
|
46
56
|
### Spec Evidence Rules
|
|
47
57
|
|
|
48
|
-
Run `grep`/`find`, then explicit `read` calls for applicable specs
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
`openspec/` before accepting repository conventions.
|
|
58
|
+
Run `grep`/`find`, then explicit `read` calls for applicable specs/checklist. Only
|
|
59
|
+
successful paired reads count as “已读取规范文件”; summaries do not. List each path/
|
|
60
|
+
section in `Checked Items`; search/read `openspec/` before accepting conventions.
|
|
52
61
|
|
|
53
62
|
```markdown
|
|
54
63
|
VERDICT: pass
|
|
@@ -8,20 +8,20 @@ Pre-write nodes are read-only. Preserve IDs, labels, commands, language, require
|
|
|
8
8
|
- **`frontend-scout-pi`**: routes, components, tokens, data/API/Mock, scripts, tests, assets. Fact vs inference vs gap. Knowledge base first; else search+read `<repoRoot>/openspec/**` before repo fallback. Output stack, routes, components, styling, conventions, state/data, test entry points, reuse, risks.
|
|
9
9
|
- **`frontend-mock-assess-pi` + gate**: declares `firstProtocolLine: "MOCK_STRATEGY:"`; canonical output first line
|
|
10
10
|
`MOCK_STRATEGY: native|browser-intercept|request-adapter|not-needed|blocked`
|
|
11
|
-
Pi output mapping promotes the first
|
|
12
|
-
- **`frontend-plan-pi` + design loop**: AC → steps, in-bound files, UI states, reuse, deps, activation/rollback, frozen verify entrypoints, real-integration gap.
|
|
11
|
+
Pi output mapping promotes the first explicitly labeled Mock strategy line ahead of any preamble, including common bullet, quote, inline-code, fullwidth-colon, `Mock strategy`, and split label/value drift, without inventing or replacing its value; missing, unlabeled, malformed, or blocked strategies still fail closed. Prefer native Mock; browser intercept only with existing e2e; request-adapter only for reversible local preview. Default `auto` may select `not-needed` when contract/scout evidence confirms no project Mock capability, without adding Mock files/deps, while keeping real requests default and recording the Real Integration Gap. Other `not-needed` cases need positive no-remote/stable-backend evidence; invalid when `frontendMock.policy=required`. `blocked` for missing/conflicting contracts, unsafe paths/deps, unread specs, production-default-on, unverifiable entrypoints. Output Mock Decision, API/spec/service evidence, backend readiness, selection evidence, endpoint/fixture matrix, activation, targets, production safety, verification plan, real-integration gap, blocking issues. Never invent fields, store secrets, comment real requests, import test mocks into production, or treat Mock as real integration. Gate uses `first-non-empty` only; never authorizes writes. Unsafe required contracts → no writer.
|
|
12
|
+
- **`frontend-plan-pi` + conditional design loop**: AC → steps, in-bound files, UI states, reuse, deps, activation/rollback, frozen verify entrypoints, real-integration gap. Initial `VERDICT: pass` uses the original plan directly. Only exact `VERDICT: request-revision` runs read-only plan revision plus final review; there is no `frontend-first-design-gate-shell` or pass-path `PASS_NO_REVISION_NEEDED` node. The effective final gate prefers final review when present, otherwise initial review, and only exact pass authorizes writes; malformed/missing/request-revision fails closed → replan/rerun (not dev-fix). The plan-pi prompt includes the complete `frontend-implementation-contract-v1` JSON Schema loaded from the loop-agent package `docs/templates/` path, plus deterministic source binding, risk level, and allowed implementation targets. The model does not need to search or guess contract fields; `schemaId`, `targetFiles`, `requirementCoverage` are explicitly forbidden.
|
|
13
13
|
- **`frontend-implement-pi`**: sole exclusive writer. Stay in `writeSet`; real requests default-on; Mock reversible, dev/test-only, production-off. Atomic handler/intercept/adapter with consumer+tests. Stop on forbidden paths or guesses. Output changed files, behavior, UI states, styling notes, verification attempted, residual risks. Optional mock-verify when frozen; static+behavior always; behavior must prove page consumption. Skipped-Mock `not-needed` keeps real integration pending unless the real backend path has fresh evidence.
|
|
14
14
|
|
|
15
15
|
## Contract / trace / stages (M1–M2)
|
|
16
16
|
|
|
17
|
-
- Contract shell: `jsonArtifactGate` → `contracts/frontend-implementation-contract.json` from
|
|
17
|
+
- Contract shell: `jsonArtifactGate` → `contracts/frontend-implementation-contract.json` from the effective plan (one fenced JSON or pure JSON); schemaId `frontend-implementation-contract-v1`. Revision is primary and original plan is fallback only when the conditional revision output is absent. Requirement coverage uses the same primary/fallback rule. An existing malformed/schema-invalid/incomplete primary fails closed; fallback never masks it. Final design + implement depend on the artifact; `MOCK_STRATEGY: blocked` not implementable.
|
|
18
18
|
- Trace shell: `frontend-verification-trace-gate` binds contract `verificationTargets` to static/behavior records (`commandLabels`, file exists, optional symbol). Assess `MOCK_STRATEGY:` must match `mockApi.strategy` when present. Writes `contracts/frontend-verification-trace.json`. Browser/visual always `not-run`.
|
|
19
19
|
- Implement stages: (1) contract confirm (2) tests sync (3) component/UI (4) API/Mock (5) frozen checks (6) diff cleanup. Summary: Contract Ref, Changed Files, Requirements, UI States, Tests, Verification Attempts, Deviations, Residual Risks.
|
|
20
20
|
|
|
21
21
|
## Repair (M3)
|
|
22
22
|
|
|
23
|
-
static/behavior/trace may `nonZeroExitPolicy: record`. Assess
|
|
23
|
+
static/behavior/trace may `nonZeroExitPolicy: record`. Assess emits pure JSON and writes `contracts/frontend-repair-assessment.json`. Only `eligible=true` runs `frontend-repair-pi` (same writeSet as implement; no re-spec; max 1 attempt), reverify, and retrace. No-failure condition-skips that branch, while diff/review/read-only `frontend-closeout-pi` continue on initial evidence. Repair-contract fails closed on non-repairable (contract/path/dependency/credential/deploy/spec-unclear), writeSet expansion, ERROR, or hard skip; `all-or-condition-skip` never softens those failures.
|
|
24
24
|
|
|
25
25
|
## Risk & capability (M4–M6)
|
|
26
26
|
|
|
27
|
-
Deterministic risk (no model); high-risk beats small; supervised never small. Small may drop
|
|
27
|
+
Deterministic risk (no model); high-risk beats small; supervised never small. Small may drop the initial design review + conditional revision branch; its retained final review audits `frontend-plan-pi`, and contract shell retargets to that plan without fallback. Capability seed injects adapters; openspec/task sources outrank. A11y: static/component tools only when present; Browser a11y always not-run.
|