@tea-agent/loop-agent 0.18.1 → 0.20.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (52) hide show
  1. package/AGENTS.md +2 -2
  2. package/CHANGELOG.md +33 -0
  3. package/README.md +4 -6
  4. package/dist/application/dag/generate-task-dag.js +12 -1
  5. package/dist/commands/init.js +3 -3
  6. package/dist/executors/shell-executor.js +188 -2
  7. package/dist/governance/exec-plans.js +4 -0
  8. package/dist/worker/cli.js +13 -12
  9. package/dist/worker/console/doctor.js +55 -2
  10. package/dist/worker/console/index.js +1 -0
  11. package/dist/worker/console/loopback.js +2 -2
  12. package/dist/worker/console/observe-link.js +7 -2
  13. package/dist/worker/console/operator-actions.js +30 -2
  14. package/dist/worker/console/operator-selection.js +92 -0
  15. package/dist/worker/console/operator-surface-health.js +23 -0
  16. package/dist/worker/console/recovery-cta.js +2 -2
  17. package/dist/worker/console/routes.js +45 -19
  18. package/dist/worker/console/security.js +29 -4
  19. package/dist/worker/console/server.js +106 -8
  20. package/dist/worker/console/static/assets/index-3vsjZJHq.js +16 -0
  21. package/dist/worker/console/static/assets/index-i1wV4LrY.css +1 -0
  22. package/dist/worker/console/static/index.html +2 -2
  23. package/dist/worker/observe/routes.js +63 -21
  24. package/dist/worker/observe/server.js +3 -10
  25. package/dist/worker/observe/static/index.html +6 -3
  26. package/dist/worker/observe/static/styles.css +53 -0
  27. package/dist/workflows/dag/backend-test-markdown-workflow.js +163 -41
  28. package/dist/workflows/dag/backend-test-result-contract.js +30 -7
  29. package/dist/workflows/dag/frontend-prewrite-gate.js +77 -0
  30. package/dist/workflows/dag/frontend-repair.js +7 -1
  31. package/dist/workflows/dag/frontend-review-context.js +43 -0
  32. package/dist/workflows/dag/frontend-verification-trace.js +34 -15
  33. package/dist/workflows/dag/governance-profile.js +14 -6
  34. package/dist/workflows/dag/init-hybrid.js +143 -399
  35. package/dist/workflows/dag/types.js +30 -0
  36. package/dist/workflows/dag/validate.js +22 -1
  37. package/docs/README.md +4 -2
  38. package/docs/architecture/evolution.md +6 -6
  39. package/docs/architecture/worker-and-feature.md +9 -9
  40. package/docs/templates/agent-dag.schema.json +40 -0
  41. package/docs/templates/backend-test-dag.generate-pytest.prompt.md +23 -192
  42. package/docs/templates/backend-test-dag.json +8 -8
  43. package/docs/templates/backend-test-dag.review-cases.prompt.md +22 -75
  44. package/package.json +1 -1
  45. package/skills/agent-worker/references/agent-worker-operator.md +2 -2
  46. package/skills/frontend-implementation/references/node-contracts.md +6 -8
  47. package/skills/frontend-review/SKILL.md +5 -8
  48. package/skills/loop-agent/references/command-reference.md +4 -2
  49. package/skills/loop-agent/references/harness-policy.md +1 -1
  50. package/skills/loop-agent/references/hybrid-dag.md +2 -2
  51. package/dist/worker/console/static/assets/index-KUSib7aM.js +0 -16
  52. package/dist/worker/console/static/assets/index-ucIzpaGJ.css +0 -1
@@ -1512,9 +1512,8 @@ function buildFrontendMockVerifyNode(sources, implementId, readOnlyPaths, forbid
1512
1512
  },
1513
1513
  };
1514
1514
  }
1515
- function buildBlockedFrontendMockDag(sources, sourceContext, readOnlyPaths, forbiddenPaths, globalConstraints) {
1515
+ function buildBlockedFrontendMockDag(sources, readOnlyPaths, forbiddenPaths, globalConstraints) {
1516
1516
  const { taskConfig } = sources;
1517
- const mockContextBlock = resolveFrontendMockContextBlock(sources);
1518
1517
  const spec = {
1519
1518
  version: 3,
1520
1519
  title: `Frontend implementation DAG (BLOCKED Mock): ${taskConfig.title}`,
@@ -1533,46 +1532,25 @@ function buildBlockedFrontendMockDag(sources, sourceContext, readOnlyPaths, forb
1533
1532
  },
1534
1533
  skillsByRole: FRONTEND_SKILLS_BY_ROLE,
1535
1534
  executorModels: sources.executorModelMatrix ?? DEFAULT_DAG_EXECUTOR_MODELS,
1536
- tasks: [
1537
- {
1538
- id: "frontend-contract-pi",
1535
+ tasks: [{
1536
+ id: "frontend-mock-blocked-shell",
1539
1537
  depends_on: [],
1540
- role: "planner",
1541
- executor: "pi",
1542
- complexity: "MED",
1543
- writePolicy: "read-only",
1544
- allowedPaths: readOnlyPaths,
1545
- forbiddenPaths,
1546
- skills: FRONTEND_IMPLEMENTATION_SKILLS,
1547
- outputContract: "Markdown contract with Scope, Non-goals, Acceptance Criteria, UI States, Target Runtime Environment, Risks, and Verification Expectations. No file writes.",
1548
- subtask_prompt: [
1549
- "Read task source and produce a concise frontend implementation contract.",
1550
- "Cover scope, non-goals, acceptance criteria, UI states, target runtime environment, risks, and verification expectations.",
1551
- "Read-only: do not modify code, docs, artifacts, or repository files.",
1552
- sourceContext,
1553
- ].join("\n\n"),
1554
- },
1555
- {
1556
- id: "frontend-scout-pi",
1557
- depends_on: ["frontend-contract-pi"],
1558
- role: "scout",
1559
- executor: "pi",
1560
- complexity: mapTaskComplexity(taskConfig.complexity),
1538
+ role: "verifier",
1539
+ executor: "shell",
1540
+ complexity: "LOW",
1561
1541
  writePolicy: "read-only",
1562
1542
  allowedPaths: readOnlyPaths,
1563
1543
  forbiddenPaths,
1564
- skills: FRONTEND_IMPLEMENTATION_SKILLS,
1565
- outputContract: "Markdown scout report covering frontend stack, routes, components, styling system, existing design conventions, state/data flow, test entry points, reuse opportunities, and risks. No file writes.",
1566
- subtask_prompt: [
1567
- "Inspect frontend code, routing, components, styles, package scripts, and tests.",
1568
- "Return code and design observations, existing reuse opportunities, and verification entry points.",
1569
- "Read-only: do not modify repository files.",
1570
- sourceContext,
1571
- ].join("\n\n"),
1572
- },
1573
- buildFrontendMockAssessNode(sources, sourceContext, mockContextBlock, "No verification entrypoints were materialized because the generation-time Mock contract is blocked.", readOnlyPaths, forbiddenPaths),
1574
- buildFrontendMockContractGateNode("blocked", taskConfig.frontendMock?.policy ?? "auto", readOnlyPaths, forbiddenPaths),
1575
- ],
1544
+ outputContract: "Deterministic generation-time Mock blocker. Always exits nonzero and never reaches a writer.",
1545
+ subtask_prompt: "Fail closed because required Mock verification entrypoints were not materialized. Resolve the task contract and regenerate the DAG.",
1546
+ shell: {
1547
+ commands: [
1548
+ "node -e \"console.error('frontend Mock contract blocked: required verification entrypoints are unavailable'); process.exit(1)\"",
1549
+ ],
1550
+ cwd: ".",
1551
+ timeoutMs: 60000,
1552
+ },
1553
+ }],
1576
1554
  };
1577
1555
  applyDefaultReadOnlyRetryPolicy(spec);
1578
1556
  parseDagSpec(spec);
@@ -1653,13 +1631,13 @@ function pruneFrontendTasksForRisk(tasks, risk) {
1653
1631
  if (risk.forceFullGates || risk.selectedRisk !== "small") {
1654
1632
  return tasks;
1655
1633
  }
1656
- // small topology: drop the initial design review + conditional revision cycle;
1657
- // keep mock assess/gate, single design review (final), contract, implement, verify, repair chain, review.
1634
+ // Small topology keeps one design review and removes only the conditional
1635
+ // revision/final-review branch. The deterministic prewrite gate consumes the
1636
+ // surviving plan and design review directly.
1658
1637
  const drop = new Set([
1659
- "frontend-design-gate-pi",
1660
1638
  "frontend-plan-revision-pi",
1639
+ "frontend-final-design-review-pi",
1661
1640
  ]);
1662
- // If we drop plan-revision, contract shell must depend on plan-pi instead; final design review depends on plan.
1663
1641
  const filtered = tasks.filter((task) => !drop.has(task.id));
1664
1642
  const byId = new Map(filtered.map((task) => [task.id, task]));
1665
1643
  const remap = (deps) => {
@@ -1672,10 +1650,6 @@ function pruneFrontendTasksForRisk(tasks, risk) {
1672
1650
  next.push("frontend-plan-pi");
1673
1651
  continue;
1674
1652
  }
1675
- if (dep === "frontend-design-gate-pi") {
1676
- // skip removed gates
1677
- continue;
1678
- }
1679
1653
  if (byId.has(dep) || dep === "frontend-implement-pi")
1680
1654
  next.push(dep);
1681
1655
  }
@@ -1683,76 +1657,29 @@ function pruneFrontendTasksForRisk(tasks, risk) {
1683
1657
  };
1684
1658
  return filtered.map((task) => {
1685
1659
  const depends_on = remap(task.depends_on);
1686
- // Ensure final design review still has plan + mock + contract path
1687
- if (task.id === "frontend-final-design-review-pi") {
1688
- for (const need of [
1689
- "frontend-plan-pi",
1690
- "frontend-mock-assess-pi",
1691
- "frontend-implementation-contract-shell",
1692
- ]) {
1693
- if (byId.has(need) && !depends_on.includes(need))
1694
- depends_on.push(need);
1695
- }
1660
+ if (task.id === "frontend-prewrite-gate-shell") {
1661
+ const gate = task.shell?.frontendPrewriteGate;
1696
1662
  return {
1697
1663
  ...task,
1698
- depends_on,
1664
+ depends_on: ["frontend-plan-pi", "frontend-design-review-pi"],
1699
1665
  dependsPolicy: "all",
1700
- runIf: undefined,
1666
+ shell: gate
1667
+ ? {
1668
+ ...task.shell,
1669
+ commands: task.shell?.commands ?? [],
1670
+ frontendPrewriteGate: {
1671
+ ...gate,
1672
+ planFromNodeId: "frontend-plan-pi",
1673
+ planFallbackFromNodeIds: [],
1674
+ reviewFromNodeId: "frontend-design-review-pi",
1675
+ reviewFallbackFromNodeIds: [],
1676
+ },
1677
+ }
1678
+ : task.shell,
1701
1679
  };
1702
1680
  }
1703
- if (task.id === "frontend-requirement-coverage-shell") {
1704
- const shell = task.shell?.requirementCoverageGate
1705
- ? {
1706
- ...task.shell,
1707
- requirementCoverageGate: {
1708
- ...task.shell.requirementCoverageGate,
1709
- fromNodeIds: task.shell.requirementCoverageGate.fromNodeIds.map((nodeId) => nodeId === "frontend-plan-revision-pi"
1710
- ? "frontend-plan-pi"
1711
- : nodeId),
1712
- fallbackFromNodeIds: undefined,
1713
- },
1714
- }
1715
- : task.shell;
1716
- return { ...task, depends_on, shell };
1717
- }
1718
- if (task.id === "frontend-implementation-contract-shell") {
1719
- const nextDeps = depends_on.filter((dep) => dep !== "frontend-plan-revision-pi");
1720
- if (!nextDeps.includes("frontend-plan-pi") &&
1721
- byId.has("frontend-plan-pi")) {
1722
- nextDeps.push("frontend-plan-pi");
1723
- }
1724
- const shell = task.shell
1725
- ? {
1726
- ...task.shell,
1727
- jsonArtifactGate: task.shell.jsonArtifactGate
1728
- ? {
1729
- ...task.shell.jsonArtifactGate,
1730
- fromNodeId: "frontend-plan-pi",
1731
- fallbackFromNodeIds: undefined,
1732
- }
1733
- : task.shell.jsonArtifactGate,
1734
- }
1735
- : task.shell;
1736
- return { ...task, depends_on: nextDeps, shell };
1737
- }
1738
- if (task.id === "frontend-final-design-gate-shell") {
1739
- const shell = task.shell?.verdictGate
1740
- ? {
1741
- ...task.shell,
1742
- verdictGate: {
1743
- ...task.shell.verdictGate,
1744
- fallbackFromNodeIds: undefined,
1745
- },
1746
- }
1747
- : task.shell;
1748
- return { ...task, depends_on, dependsPolicy: "all", shell };
1749
- }
1750
1681
  if (task.id === "frontend-implement-pi") {
1751
- // still requires final design gate
1752
- for (const need of [
1753
- "frontend-final-design-gate-shell",
1754
- "frontend-implementation-contract-shell",
1755
- ]) {
1682
+ for (const need of ["frontend-prewrite-gate-shell"]) {
1756
1683
  if (byId.has(need) && !depends_on.includes(need))
1757
1684
  depends_on.push(need);
1758
1685
  }
@@ -1867,7 +1794,7 @@ function buildFrontendHybridDagFromTask(sources) {
1867
1794
  ];
1868
1795
  // Guard: blocked mode — generate assessment-only DAG with no writer reachable
1869
1796
  if (mockMode === "blocked") {
1870
- return buildBlockedFrontendMockDag(frontendSources, sourceContext, readOnlyPaths, forbiddenPaths, globalConstraints);
1797
+ return buildBlockedFrontendMockDag(frontendSources, readOnlyPaths, forbiddenPaths, globalConstraints);
1871
1798
  }
1872
1799
  const staticFallbackCommands = ["npm run typecheck", "npm run build"];
1873
1800
  const behaviorFallbackCommands = ["npm test"];
@@ -1909,6 +1836,11 @@ function buildFrontendHybridDagFromTask(sources) {
1909
1836
  fallbackCommands: behaviorFallbackCommands,
1910
1837
  finalFullRequired: true,
1911
1838
  });
1839
+ const mockVerifyTemplate = mockMode === "required" && hasMockVerifyCommands
1840
+ ? buildFrontendMockVerifyNode(frontendSources, implementId, readOnlyPaths, forbiddenPaths)
1841
+ : undefined;
1842
+ const mockShellCommands = mockVerifyTemplate?.shell?.commands ?? [];
1843
+ const mockVerifyEvidence = mockVerifyTemplate?.shell?.verifyEvidence;
1912
1844
  const fixedVerificationContext = [
1913
1845
  "## Fixed frontend verification entrypoints",
1914
1846
  "These shell entrypoints are fixed at DAG generation and are the only commands the static and behavior shell nodes execute. A strategy or plan may add tests behind an existing entrypoint inside writeSet, but must not invent or replace commands or assume subtask_prompt executes a command.",
@@ -1968,16 +1900,11 @@ function buildFrontendHybridDagFromTask(sources) {
1968
1900
  sourceContext,
1969
1901
  ].join("\n\n"),
1970
1902
  },
1971
- // Mock assessment is always read-only and runs before planning.
1972
- buildFrontendMockAssessNode(frontendSources, sourceContext, mockContextBlock, fixedVerificationContext, readOnlyPaths, forbiddenPaths),
1973
- buildFrontendMockContractGateNode(mockMode, taskConfig.frontendMock?.policy ?? "auto", readOnlyPaths, forbiddenPaths),
1974
1903
  {
1975
1904
  id: "frontend-plan-pi",
1976
1905
  depends_on: [
1977
1906
  "frontend-contract-pi",
1978
1907
  "frontend-scout-pi",
1979
- "frontend-mock-assess-pi",
1980
- "frontend-mock-contract-gate-shell",
1981
1908
  ],
1982
1909
  role: "planner",
1983
1910
  executor: "pi",
@@ -1990,8 +1917,8 @@ function buildFrontendHybridDagFromTask(sources) {
1990
1917
  skills: FRONTEND_IMPLEMENTATION_SKILLS,
1991
1918
  outputContract: "Markdown implementation plan with Requirement Coverage, Implementation Steps, Target Files, UI State Handling, Styling / Component Strategy, Interaction Notes, Mock / API Strategy, Dependency Policy, Verification Plan, Real Integration Gap, and Residual Risks, followed by exactly one fenced json object conforming to frontend-implementation-contract-v1 when this node is the effective plan source. No file writes.",
1992
1919
  subtask_prompt: [
1993
- "Based on frontend-contract-pi, frontend-scout-pi, and the gated frontend-mock-assess-pi strategy, return a minimal frontend implementation plan.",
1994
- "Carry the selected Mock / API strategy, endpoint/fixture mapping, explicit activation, production-default-off rule, verification commands, and Real Integration Gap into the plan.",
1920
+ "Based on frontend-contract-pi, frontend-scout-pi, task sources, and the generation-time Mock capability evidence, return a minimal frontend implementation plan.",
1921
+ "Select the Mock / API strategy inside the plan and structured contract. Carry endpoint/fixture mapping, explicit activation, production-default-off rule, verification commands, and Real Integration Gap into both outputs.",
1995
1922
  "Include ordered steps, target files, UI state handling, styling/component strategy, interaction notes, Mock/API strategy, dependency policy, deterministic verification entrypoints, and residual risks. Use only the fixed entrypoints below; implementation may add tests behind them but cannot replace them.",
1996
1923
  "End with exactly one fenced json object conforming to frontend-implementation-contract-v1 so small topology can materialize the contract without plan-revision.",
1997
1924
  requirementCoverageInstruction,
@@ -2003,8 +1930,8 @@ function buildFrontendHybridDagFromTask(sources) {
2003
1930
  ].join("\n\n"),
2004
1931
  },
2005
1932
  {
2006
- id: "frontend-design-gate-pi",
2007
- depends_on: ["frontend-plan-pi", "frontend-mock-assess-pi"],
1933
+ id: "frontend-design-review-pi",
1934
+ depends_on: ["frontend-plan-pi"],
2008
1935
  role: "reviewer",
2009
1936
  executor: "pi",
2010
1937
  complexity: "MED",
@@ -2027,10 +1954,9 @@ function buildFrontendHybridDagFromTask(sources) {
2027
1954
  id: "frontend-plan-revision-pi",
2028
1955
  depends_on: [
2029
1956
  "frontend-plan-pi",
2030
- "frontend-design-gate-pi",
2031
- "frontend-mock-assess-pi",
1957
+ "frontend-design-review-pi",
2032
1958
  ],
2033
- runIf: "$.nodes['frontend-design-gate-pi'].firstVerdictLine == 'VERDICT: request-revision'",
1959
+ runIf: "$.nodes['frontend-design-review-pi'].firstVerdictLine == 'VERDICT: request-revision'",
2034
1960
  role: "planner",
2035
1961
  executor: "pi",
2036
1962
  complexity: "MED",
@@ -2042,8 +1968,8 @@ function buildFrontendHybridDagFromTask(sources) {
2042
1968
  skills: FRONTEND_IMPLEMENTATION_SKILLS,
2043
1969
  outputContract: "When the initial design review requests revision, return a complete Markdown revision plan followed by exactly one fenced json object conforming to frontend-implementation-contract-v1. The JSON is the authoritative materialization input. No file writes.",
2044
1970
  subtask_prompt: [
2045
- "Consume frontend-plan-pi (original plan) and frontend-design-gate-pi (first design review findings).",
2046
- "This node runs only when frontend-design-gate-pi emitted VERDICT: request-revision. Produce a complete revised implementation plan that addresses every Required Plan Correction from the design findings.",
1971
+ "Consume frontend-plan-pi (original plan) and frontend-design-review-pi (first design review findings).",
1972
+ "This node runs only when frontend-design-review-pi emitted VERDICT: request-revision. Produce a complete revised implementation plan that addresses every Required Plan Correction from the design findings.",
2047
1973
  "The revised plan must include Requirement Coverage, Implementation Steps, Target Files, UI State Handling, Styling / Component Strategy, Interaction Notes, Mock / API Strategy, Dependency Policy, Verification Plan, Real Integration Gap, and Residual Risks.",
2048
1974
  requirementCoverageInstruction,
2049
1975
  "Do not turn MOCK_STRATEGY: blocked into an implementable strategy without new repository or contract evidence that resolves every blocker.",
@@ -2053,73 +1979,15 @@ function buildFrontendHybridDagFromTask(sources) {
2053
1979
  frontendContractSchemaBlock,
2054
1980
  ].join("\n\n"),
2055
1981
  },
2056
- ...(requirementIds.length > 0
2057
- ? [
2058
- {
2059
- id: "frontend-requirement-coverage-shell",
2060
- depends_on: ["frontend-plan-revision-pi", "frontend-plan-pi"],
2061
- dependsPolicy: "all-or-condition-skip",
2062
- role: "verifier",
2063
- executor: "shell",
2064
- complexity: "LOW",
2065
- writePolicy: "read-only",
2066
- allowedPaths: readOnlyPaths,
2067
- forbiddenPaths,
2068
- outputContract: "Deterministic current-run evidence that the original or revised frontend plan retains every explicit REQ-/BR-/AC- identifier from the bound task sources.",
2069
- subtask_prompt: "Block final design review when the current run's plan facts omit any explicit requirement identifier from the authoritative task sources.",
2070
- shell: {
2071
- commands: [],
2072
- requirementCoverageGate: {
2073
- fromNodeIds: ["frontend-plan-revision-pi"],
2074
- fallbackFromNodeIds: ["frontend-plan-pi"],
2075
- requiredIds: requirementIds,
2076
- label: "frontend requirement coverage",
2077
- },
2078
- cwd: ".",
2079
- timeoutMs: 60000,
2080
- },
2081
- },
2082
- ]
2083
- : []),
2084
- {
2085
- id: "frontend-implementation-contract-shell",
2086
- depends_on: ["frontend-plan-revision-pi", "frontend-plan-pi"],
2087
- dependsPolicy: "all-or-condition-skip",
2088
- role: "verifier",
2089
- executor: "shell",
2090
- complexity: "LOW",
2091
- writePolicy: "read-only",
2092
- allowedPaths: readOnlyPaths,
2093
- forbiddenPaths,
2094
- outputContract: "Run-owned validated frontend-implementation-contract-v1 artifact path, schema id, and SHA-256.",
2095
- subtask_prompt: "Materialize the effective frontend plan as a source-bound structured contract; fail closed on missing or invalid output.",
2096
- shell: {
2097
- commands: [],
2098
- jsonArtifactGate: {
2099
- fromNodeId: "frontend-plan-revision-pi",
2100
- fallbackFromNodeIds: ["frontend-plan-pi"],
2101
- schemaId: "frontend-implementation-contract-v1",
2102
- artifactName: "frontend-implementation-contract.json",
2103
- outputDir: "contracts",
2104
- },
2105
- cwd: ".",
2106
- timeoutMs: 60000,
2107
- },
2108
- },
2109
1982
  {
2110
1983
  id: "frontend-final-design-review-pi",
2111
1984
  depends_on: [
2112
1985
  "frontend-plan-revision-pi",
2113
1986
  "frontend-plan-pi",
2114
- "frontend-design-gate-pi",
2115
- "frontend-mock-assess-pi",
2116
- "frontend-implementation-contract-shell",
2117
- ...(requirementIds.length > 0
2118
- ? ["frontend-requirement-coverage-shell"]
2119
- : []),
1987
+ "frontend-design-review-pi",
2120
1988
  ],
2121
1989
  dependsPolicy: "all-or-condition-skip",
2122
- runIf: "$.nodes['frontend-design-gate-pi'].firstVerdictLine == 'VERDICT: request-revision'",
1990
+ runIf: "$.nodes['frontend-design-review-pi'].firstVerdictLine == 'VERDICT: request-revision'",
2123
1991
  role: "reviewer",
2124
1992
  executor: "pi",
2125
1993
  complexity: "MED",
@@ -2129,11 +1997,11 @@ function buildFrontendHybridDagFromTask(sources) {
2129
1997
  skills: FRONTEND_DESIGN_REVIEW_SKILLS,
2130
1998
  outputContract: "For the effective frontend plan, return plain Markdown whose first non-empty line is VERDICT: pass or VERDICT: request-revision, followed by Findings and Checked Items. No file writes.",
2131
1999
  subtask_prompt: [
2132
- "Audit the effective frontend plan before implementation. In the standard topology this node runs after request-revision and consumes frontend-plan-revision-pi; in a small-risk topology where that branch is pruned, audit frontend-plan-pi directly.",
2000
+ "Audit the revised frontend plan before implementation. This node runs only after request-revision and consumes frontend-plan-revision-pi.",
2133
2001
  "First non-empty line must be exactly VERDICT: pass or VERDICT: request-revision.",
2134
- "When an initial design review requested revision, verify that every Required Plan Correction has been fully addressed. In the small-risk topology, independently audit the original plan against the full checklist because there is no initial-review finding set.",
2002
+ "Verify that every Required Plan Correction from the initial design review has been fully addressed.",
2135
2003
  "Recheck the selected Mock / API strategy, contract-to-fixture mapping, authorized paths/dependencies, explicit activation, production-default-off behavior, behavior verification, and Real Integration Gap. MOCK_STRATEGY: blocked cannot receive VERDICT: pass.",
2136
- "The frontend requirement coverage gate has verified that every explicit REQ-/BR-/AC- identifier remains present in the current-run plan evidence; review the mapped behavior rather than accepting identifier presence alone.",
2004
+ "Review every explicit REQ-/BR-/AC- mapping; the downstream prewrite gate also checks identifier retention deterministically.",
2137
2005
  "Request revision if any design gap remains, if corrections are incomplete, or if the revised plan introduces new unaddressed issues.",
2138
2006
  "Read-only: do not modify repository files.",
2139
2007
  fixedVerificationContext,
@@ -2141,10 +2009,12 @@ function buildFrontendHybridDagFromTask(sources) {
2141
2009
  ].join("\n\n"),
2142
2010
  },
2143
2011
  {
2144
- id: "frontend-final-design-gate-shell",
2012
+ id: "frontend-prewrite-gate-shell",
2145
2013
  depends_on: [
2146
2014
  "frontend-final-design-review-pi",
2147
- "frontend-design-gate-pi",
2015
+ "frontend-design-review-pi",
2016
+ "frontend-plan-revision-pi",
2017
+ "frontend-plan-pi",
2148
2018
  ],
2149
2019
  dependsPolicy: "all-or-condition-skip",
2150
2020
  role: "verifier",
@@ -2153,16 +2023,24 @@ function buildFrontendHybridDagFromTask(sources) {
2153
2023
  writePolicy: "read-only",
2154
2024
  allowedPaths: readOnlyPaths,
2155
2025
  forbiddenPaths,
2156
- outputContract: "Deterministic effective design verdict gate: resolve the selected design review output and exit 0 only on VERDICT: pass. This is the sole authorization for frontend implementation writes.",
2157
- subtask_prompt: "Deterministic gate: block frontend implementation unless the effective design review emitted VERDICT: pass.",
2026
+ outputContract: "Deterministic prewrite authorization: resolve effective plan/review, require VERDICT: pass, retain every requirement id, validate Mock policy, and materialize the canonical implementation contract.",
2027
+ subtask_prompt: "Fail closed unless the effective reviewed plan is source-bound, requirement-complete, Mock-policy compliant, schema-valid, and approved.",
2158
2028
  shell: {
2159
2029
  commands: [],
2160
- verdictGate: {
2161
- fromNodeId: "frontend-final-design-review-pi",
2162
- fallbackFromNodeIds: ["frontend-design-gate-pi"],
2163
- accept: ["VERDICT: pass"],
2164
- label: "frontend final design gate",
2165
- lineMode: "first-verdict-line",
2030
+ frontendPrewriteGate: {
2031
+ schemaVersion: 1,
2032
+ planFromNodeId: "frontend-plan-revision-pi",
2033
+ planFallbackFromNodeIds: ["frontend-plan-pi"],
2034
+ reviewFromNodeId: "frontend-final-design-review-pi",
2035
+ reviewFallbackFromNodeIds: ["frontend-design-review-pi"],
2036
+ requiredRequirementIds: requirementIds,
2037
+ allowedMockStrategies: taskConfig.frontendMock?.policy === "disabled"
2038
+ ? ["not-needed"]
2039
+ : taskConfig.frontendMock?.policy === "required"
2040
+ ? ["native", "browser-intercept", "request-adapter"]
2041
+ : ["native", "browser-intercept", "request-adapter", "not-needed"],
2042
+ artifactName: "frontend-implementation-contract.json",
2043
+ outputDir: "contracts",
2166
2044
  },
2167
2045
  cwd: ".",
2168
2046
  timeoutMs: 60000,
@@ -2171,12 +2049,10 @@ function buildFrontendHybridDagFromTask(sources) {
2171
2049
  {
2172
2050
  id: implementId,
2173
2051
  depends_on: [
2174
- "frontend-final-design-gate-shell",
2175
- "frontend-implementation-contract-shell",
2052
+ "frontend-prewrite-gate-shell",
2176
2053
  "frontend-plan-revision-pi",
2177
2054
  "frontend-final-design-review-pi",
2178
2055
  "frontend-plan-pi",
2179
- "frontend-mock-assess-pi",
2180
2056
  ],
2181
2057
  dependsPolicy: "all-or-condition-skip",
2182
2058
  role: "implementer",
@@ -2190,11 +2066,11 @@ function buildFrontendHybridDagFromTask(sources) {
2190
2066
  skills: FRONTEND_IMPLEMENTATION_SKILLS,
2191
2067
  outputContract: "Markdown delivery summary with Contract Ref (path/schema/hash), Changed Files, Requirements Implemented, UI States, Tests Changed, Verification Attempts, Deviations, and Residual Risks. Follow fixed stages: contract confirm → tests → component/state → API/Mock → focused checks → diff cleanup.",
2192
2068
  subtask_prompt: [
2193
- "Implement against the validated run-owned Frontend Implementation Contract from frontend-implementation-contract-shell (path/schema/hash). Do not rebuild the contract from Markdown alone.",
2069
+ "Implement against the validated run-owned Frontend Implementation Contract from frontend-prewrite-gate-shell (path/schema/hash). Do not rebuild the contract from Markdown alone.",
2194
2070
  "Execute in fixed stages and report each in the delivery summary: (1) Contract confirm, (2) Tests sync, (3) Component/UI state implementation, (4) API/Mock wiring per contract.mockApi, (5) Focused checks behind frozen entrypoints only, (6) Diff cleanup.",
2195
2071
  "Map every requirement id and applicable UI state from the contract to concrete files. Do not invent shell verification commands; only frozen static/behavior entrypoints will run.",
2196
- "Implement only the approved Mock strategy from frontend-mock-assess-pi as carried in the contract. Preserve the real request path as the default, require explicit test/dev activation, and never comment out or replace the real request with inline data.",
2197
- "frontend-final-design-gate-shell confirmed the effective initial-or-final design verdict is pass. Stay within writeSet and preserve unrelated files.",
2072
+ "Implement only the approved Mock strategy carried by the validated contract. Preserve the real request path as the default, require explicit test/dev activation, and never comment out or replace the real request with inline data.",
2073
+ "frontend-prewrite-gate-shell confirmed the effective plan/review, requirement coverage, Mock policy, and contract. Stay within writeSet and preserve unrelated files.",
2198
2074
  "For native, browser-intercept, or request-adapter, implement contract-aligned fixtures/states and a dev/test-only activation boundary in this same writer. For not-needed, do not add Mock files or a framework and state the positive reason.",
2199
2075
  "Do not write root artifacts/** unless explicitly included in writeSet. Do not claim Browser/visual verification.",
2200
2076
  writerDeliveryContract(taskConfig),
@@ -2204,122 +2080,37 @@ function buildFrontendHybridDagFromTask(sources) {
2204
2080
  .filter((value) => Boolean(value))
2205
2081
  .join("\n\n"),
2206
2082
  },
2207
- // Optional dedicated Mock verification exists only when trusted commands
2208
- // were frozen at generation time. Behavior verification remains required.
2209
- ...(mockMode === "required" && hasMockVerifyCommands
2210
- ? [
2211
- buildFrontendMockVerifyNode(frontendSources, implementId, readOnlyPaths, forbiddenPaths),
2212
- ]
2213
- : []),
2214
2083
  {
2215
- id: "frontend-static-verify-shell",
2216
- depends_on: mockMode === "required" && hasMockVerifyCommands
2217
- ? ["frontend-mock-verify-shell"]
2218
- : [implementId],
2084
+ id: "frontend-verify-assess-shell",
2085
+ depends_on: [implementId],
2219
2086
  role: "verifier",
2220
2087
  executor: "shell",
2221
2088
  complexity: "LOW",
2222
2089
  writePolicy: "read-only",
2223
2090
  allowedPaths: readOnlyPaths,
2224
2091
  forbiddenPaths,
2225
- outputContract: "Archived shell stdout/stderr with exit codes for deterministic static verification; no worktree writes.",
2226
- subtask_prompt: "Run deterministic static verification for the frontend implementation, including a production/default-real-path build with Mock activation off when Mock applies. Report only what the commands actually exercise.",
2227
- shell: {
2228
- commands: staticShellCommands,
2229
- verifyEvidence: staticVerifyEvidence,
2230
- cwd: ".",
2231
- timeoutMs: 300000,
2232
- nonZeroExitPolicy: "record",
2233
- },
2234
- },
2235
- {
2236
- id: "frontend-behavior-verify-shell",
2237
- depends_on: ["frontend-static-verify-shell"],
2238
- role: "verifier",
2239
- executor: "shell",
2240
- complexity: "LOW",
2241
- writePolicy: "read-only",
2242
- allowedPaths: behaviorPaths,
2243
- forbiddenPaths,
2244
- outputContract: "Archived shell stdout/stderr with exit codes for deterministic behavior verification; no worktree writes.",
2245
- subtask_prompt: "Run the fixed deterministic behavior entrypoints for the selected strategy. For native, browser-intercept, or request-adapter, cover the approved Mock activation and applicable success/loading/empty/error states; for not-needed, exercise applicable real or no-remote behavior. Report only what the commands actually exercise.",
2092
+ outputContract: "Run frozen Mock/static/behavior commands, materialize verification trace and repair assessment, and fail closed for non-repairable failures.",
2093
+ subtask_prompt: "Execute the frontend verification bundle. Preserve per-command evidence; eligible repairable failures select the bounded repair branch.",
2246
2094
  shell: {
2247
- commands: behaviorShellCommands,
2248
- verifyEvidence: behaviorVerifyEvidence,
2095
+ commands: [],
2096
+ frontendVerificationBundle: {
2097
+ schemaVersion: 1,
2098
+ mockCommands: mockShellCommands,
2099
+ staticCommands: staticShellCommands,
2100
+ behaviorCommands: behaviorShellCommands,
2101
+ mockEvidence: mockVerifyEvidence,
2102
+ staticEvidence: staticVerifyEvidence,
2103
+ behaviorEvidence: behaviorVerifyEvidence,
2104
+ mode: "initial",
2105
+ },
2249
2106
  cwd: ".",
2250
2107
  timeoutMs: 300000,
2251
- nonZeroExitPolicy: "record",
2252
- },
2253
- },
2254
- {
2255
- id: "frontend-verification-trace-shell",
2256
- depends_on: [
2257
- "frontend-behavior-verify-shell",
2258
- "frontend-static-verify-shell",
2259
- "frontend-implementation-contract-shell",
2260
- ],
2261
- role: "verifier",
2262
- executor: "shell",
2263
- complexity: "LOW",
2264
- writePolicy: "read-only",
2265
- allowedPaths: readOnlyPaths,
2266
- forbiddenPaths,
2267
- outputContract: "Deterministic verification trace: contract verificationTargets bound to current-run static/behavior commandLabels; target files/symbols exist; Browser/visual not-run. No worktree writes.",
2268
- subtask_prompt: "Validate AC/UI/verification targets against frozen shell evidence and workspace files. Do not invent commands. Does not prove semantic test quality.",
2269
- shell: {
2270
- commands: ["frontend-verification-trace-gate"],
2271
- cwd: ".",
2272
- timeoutMs: 120000,
2273
- nonZeroExitPolicy: "record",
2274
- },
2275
- },
2276
- {
2277
- id: "frontend-failure-assess-shell",
2278
- depends_on: [
2279
- "frontend-verification-trace-shell",
2280
- "frontend-behavior-verify-shell",
2281
- "frontend-static-verify-shell",
2282
- "frontend-implementation-contract-shell",
2283
- ],
2284
- role: "verifier",
2285
- executor: "shell",
2286
- complexity: "LOW",
2287
- writePolicy: "read-only",
2288
- allowedPaths: readOnlyPaths,
2289
- forbiddenPaths,
2290
- outputContract: "Run-owned frontend-repair-assessment-v1 at contracts/frontend-repair-assessment.json classifying verify/trace failures as repairable or not.",
2291
- subtask_prompt: "Assess current-run static/behavior/trace failure facts against the validated contract. Do not repair code.",
2292
- shell: {
2293
- commands: ["frontend-failure-assess-gate"],
2294
- cwd: ".",
2295
- timeoutMs: 60000,
2296
- },
2297
- },
2298
- {
2299
- id: "frontend-repair-contract-shell",
2300
- depends_on: ["frontend-failure-assess-shell"],
2301
- role: "verifier",
2302
- executor: "shell",
2303
- complexity: "LOW",
2304
- writePolicy: "read-only",
2305
- allowedPaths: readOnlyPaths,
2306
- forbiddenPaths,
2307
- outputContract: "Deterministic repair eligibility gate: pass when no failure or repairable assessment; fail-closed on non-repairable classes.",
2308
- subtask_prompt: "Validate frontend-repair-assessment writeSet subset, attempt limit, and eligibility before repair writer.",
2309
- shell: {
2310
- commands: ["frontend-repair-contract-gate"],
2311
- cwd: ".",
2312
- timeoutMs: 60000,
2313
2108
  },
2314
2109
  },
2315
2110
  {
2316
2111
  id: "frontend-repair-pi",
2317
- depends_on: [
2318
- "frontend-repair-contract-shell",
2319
- "frontend-failure-assess-shell",
2320
- implementId,
2321
- ],
2322
- runIf: "$.nodes['frontend-failure-assess-shell'].json.eligible == true",
2112
+ depends_on: ["frontend-verify-assess-shell", implementId],
2113
+ runIf: "$.nodes['frontend-verify-assess-shell'].json.eligible == true",
2323
2114
  role: "implementer",
2324
2115
  executor: "pi",
2325
2116
  toolProfile: "write",
@@ -2343,7 +2134,7 @@ function buildFrontendHybridDagFromTask(sources) {
2343
2134
  .join("\n\n"),
2344
2135
  },
2345
2136
  {
2346
- id: "frontend-static-reverify-shell",
2137
+ id: "frontend-reverify-shell",
2347
2138
  depends_on: ["frontend-repair-pi"],
2348
2139
  role: "verifier",
2349
2140
  executor: "shell",
@@ -2351,61 +2142,30 @@ function buildFrontendHybridDagFromTask(sources) {
2351
2142
  writePolicy: "read-only",
2352
2143
  allowedPaths: readOnlyPaths,
2353
2144
  forbiddenPaths,
2354
- outputContract: "Archived static re-verification after repair using the same frozen commands; fail on nonzero.",
2355
- subtask_prompt: "Re-run frozen static entrypoints after repair. Fresh evidence only; do not rewrite prior failure artifacts.",
2145
+ outputContract: "Post-repair Mock/static/behavior re-verification plus refreshed canonical trace; any failure blocks review.",
2146
+ subtask_prompt: "Re-run the frozen frontend verification bundle after bounded repair and fail on any command or trace failure.",
2356
2147
  shell: {
2357
- commands: staticShellCommands,
2358
- verifyEvidence: staticVerifyEvidence,
2359
- cwd: ".",
2360
- timeoutMs: 300000,
2361
- },
2362
- },
2363
- {
2364
- id: "frontend-behavior-reverify-shell",
2365
- depends_on: ["frontend-static-reverify-shell"],
2366
- role: "verifier",
2367
- executor: "shell",
2368
- complexity: "LOW",
2369
- writePolicy: "read-only",
2370
- allowedPaths: behaviorPaths,
2371
- forbiddenPaths,
2372
- outputContract: "Archived behavior re-verification after repair using the same frozen commands; fail on nonzero.",
2373
- subtask_prompt: "Re-run frozen behavior entrypoints after repair.",
2374
- shell: {
2375
- commands: behaviorShellCommands,
2376
- verifyEvidence: behaviorVerifyEvidence,
2148
+ commands: [],
2149
+ frontendVerificationBundle: {
2150
+ schemaVersion: 1,
2151
+ mockCommands: mockShellCommands,
2152
+ staticCommands: staticShellCommands,
2153
+ behaviorCommands: behaviorShellCommands,
2154
+ mockEvidence: mockVerifyEvidence,
2155
+ staticEvidence: staticVerifyEvidence,
2156
+ behaviorEvidence: behaviorVerifyEvidence,
2157
+ mode: "repair",
2158
+ },
2377
2159
  cwd: ".",
2378
2160
  timeoutMs: 300000,
2379
2161
  },
2380
2162
  },
2381
2163
  {
2382
- id: "frontend-verification-retrace-shell",
2164
+ id: "frontend-review-context-shell",
2383
2165
  depends_on: [
2384
- "frontend-behavior-reverify-shell",
2385
- "frontend-static-reverify-shell",
2386
- "frontend-implementation-contract-shell",
2387
- ],
2388
- role: "verifier",
2389
- executor: "shell",
2390
- complexity: "LOW",
2391
- writePolicy: "read-only",
2392
- allowedPaths: readOnlyPaths,
2393
- forbiddenPaths,
2394
- outputContract: "Re-run verification trace against contract and reverify shell evidence after repair.",
2395
- subtask_prompt: "Trace AC/UI/verification targets against post-repair static/behavior evidence.",
2396
- shell: {
2397
- commands: ["frontend-verification-trace-gate"],
2398
- cwd: ".",
2399
- timeoutMs: 120000,
2400
- },
2401
- },
2402
- {
2403
- id: "frontend-worktree-diff-shell",
2404
- depends_on: [
2405
- "frontend-verification-retrace-shell",
2406
- "frontend-behavior-reverify-shell",
2407
- "frontend-static-reverify-shell",
2166
+ "frontend-reverify-shell",
2408
2167
  "frontend-repair-pi",
2168
+ "frontend-verify-assess-shell",
2409
2169
  implementId,
2410
2170
  ],
2411
2171
  dependsPolicy: "all-or-condition-skip",
@@ -2415,10 +2175,11 @@ function buildFrontendHybridDagFromTask(sources) {
2415
2175
  writePolicy: "read-only",
2416
2176
  allowedPaths: readOnlyPaths,
2417
2177
  forbiddenPaths,
2418
- outputContract: "Run-owned actual worktree diff_patch (artifacts/diff_patch.patch) plus contracts/frontend-worktree-diff.json inventory/hash for review. No product worktree writes.",
2419
- subtask_prompt: "Capture the authoritative actual diff after implementation and any selected repair/reverify branch so frontend-review-pi can audit changed files without relying on failure-path patches or model summaries.",
2178
+ outputContract: "Canonical frontend review context containing validated contract, effective verification trace, repair assessment, and actual worktree diff.",
2179
+ subtask_prompt: "Capture the actual diff and bind it to the effective initial-or-post-repair verification evidence for final review.",
2420
2180
  shell: {
2421
- commands: ["frontend-worktree-diff-gate"],
2181
+ commands: [],
2182
+ frontendReviewContext: { schemaVersion: 1 },
2422
2183
  cwd: ".",
2423
2184
  timeoutMs: 120000,
2424
2185
  },
@@ -2426,26 +2187,16 @@ function buildFrontendHybridDagFromTask(sources) {
2426
2187
  {
2427
2188
  id: "frontend-review-pi",
2428
2189
  depends_on: [
2429
- "frontend-worktree-diff-shell",
2430
- "frontend-verification-retrace-shell",
2431
- "frontend-static-reverify-shell",
2432
- "frontend-behavior-reverify-shell",
2190
+ "frontend-review-context-shell",
2191
+ "frontend-reverify-shell",
2433
2192
  "frontend-repair-pi",
2434
- "frontend-verification-trace-shell",
2435
- "frontend-static-verify-shell",
2436
- "frontend-behavior-verify-shell",
2437
- "frontend-failure-assess-shell",
2193
+ "frontend-verify-assess-shell",
2438
2194
  implementId,
2439
- "frontend-implementation-contract-shell",
2440
- "frontend-contract-pi",
2195
+ "frontend-prewrite-gate-shell",
2441
2196
  "frontend-plan-pi",
2442
- "frontend-design-gate-pi",
2197
+ "frontend-design-review-pi",
2443
2198
  "frontend-plan-revision-pi",
2444
2199
  "frontend-final-design-review-pi",
2445
- "frontend-mock-assess-pi",
2446
- ...(mockMode === "required" && hasMockVerifyCommands
2447
- ? ["frontend-mock-verify-shell"]
2448
- : []),
2449
2200
  ],
2450
2201
  dependsPolicy: "all-or-condition-skip",
2451
2202
  role: "reviewer",
@@ -2460,11 +2211,11 @@ function buildFrontendHybridDagFromTask(sources) {
2460
2211
  "Review the frontend implementation and verification evidence.",
2461
2212
  "First non-empty line must be exactly VERDICT: pass or VERDICT: request-revision.",
2462
2213
  "Any Critical or Important finding must force VERDICT: request-revision.",
2463
- "Read the validated frontend-implementation-contract, the effective initial-or-post-repair frontend verification trace, the corresponding static/behavior shell facts, and the run-owned actual diff from frontend-worktree-diff-shell (contracts/frontend-worktree-diff.json + artifacts/diff_patch.patch). Do not claim actual diff is missing when those artifacts exist; do not invent a diff from the implementation summary alone. Trace proves command/file/symbol binding only—not semantic correctness.",
2214
+ "Read contracts/frontend-review-context.json from frontend-review-context-shell. It binds the validated implementation contract, effective initial-or-post-repair verification trace, repair assessment, and the run-owned actual diff (contracts/frontend-worktree-diff.json + artifacts/diff_patch.patch). Do not claim actual diff is missing when those artifacts exist; do not invent a diff from the implementation summary alone. Trace proves command/file/symbol binding only—not semantic correctness.",
2464
2215
  "Flag .skip/.only, deleted or weakened tests, unauthorized config changes, Mock-only evidence claimed as real integration, and Browser/visual claims (always not-run in this workflow).",
2465
2216
  "Use the direct contract and the effective plan/design branch: original plan plus initial pass when revision was skipped, or revised plan plus final design review when revision ran. Do not infer them from the implementation summary.",
2466
2217
  "Treat a commented-out real request, default-enabled Mock, production entrypoint importing test mocks, API/fixture contract drift, unauthorized Mock dependency/path, or missing behavior evidence for the selected strategy as at least Important. Mock strategies require Mock-backed evidence. not-needed requires applicable real/no-remote behavior evidence unless auto mode explicitly skipped Mock because no project Mock capability exists; in that case verify that the real request remains the default and the Real Integration Gap is preserved.",
2467
- "Inspect the production/default-real-path static evidence directly and require Mock activation to be off for that check.",
2218
+ "Inspect the frontend-verify-assess-shell or selected frontend-reverify-shell evidence in the review context directly, including the production/default-real-path static check, and require Mock activation to be off for that check.",
2468
2219
  "Distinguish Mock-backed evidence from real API integration evidence and preserve the Real Integration Gap when the backend was not exercised.",
2469
2220
  "Review implementation quality, behavior/state coverage, verification evidence, and maintainability. Read-only: do not modify files.",
2470
2221
  sourceContext,
@@ -2499,19 +2250,11 @@ function buildFrontendHybridDagFromTask(sources) {
2499
2250
  depends_on: [
2500
2251
  "frontend-review-gate-shell",
2501
2252
  "frontend-review-pi",
2502
- "frontend-verification-retrace-shell",
2503
- "frontend-static-reverify-shell",
2504
- "frontend-behavior-reverify-shell",
2253
+ "frontend-review-context-shell",
2254
+ "frontend-reverify-shell",
2505
2255
  "frontend-repair-pi",
2506
- "frontend-verification-trace-shell",
2507
- "frontend-static-verify-shell",
2508
- "frontend-behavior-verify-shell",
2509
- "frontend-failure-assess-shell",
2510
- "frontend-implementation-contract-shell",
2511
- "frontend-mock-assess-pi",
2512
- ...(mockMode === "required" && hasMockVerifyCommands
2513
- ? ["frontend-mock-verify-shell"]
2514
- : []),
2256
+ "frontend-verify-assess-shell",
2257
+ "frontend-prewrite-gate-shell",
2515
2258
  ],
2516
2259
  dependsPolicy: "all-or-condition-skip",
2517
2260
  role: "closeout",
@@ -2526,7 +2269,7 @@ function buildFrontendHybridDagFromTask(sources) {
2526
2269
  outputContract: "Markdown closeout summary with Changes, Mock Decision / Strategy / Files / Verification / Production Boundary, Verification Evidence, Review Result, Frontend Status, Real Integration Status, Known Risks, and Follow-up. No file writes.",
2527
2270
  subtask_prompt: [
2528
2271
  "Return a frontend closeout summary covering Mock decision/strategy/files/verification/production boundary, changes, verification evidence, review result, known risks, and follow-up.",
2529
- "Include a coverage matrix for each requirement id, applicable UI state, and verification target/check with status passed|failed|not-run|blocked|unavailable. Always state Browser accessibility verification: not-run and Visual regression: not-run. Use the effective initial-or-post-repair frontend verification trace facts; do not invent Browser evidence from component tests.",
2272
+ "Include a coverage matrix for each requirement id, applicable UI state, and verification target/check with status passed|failed|not-run|blocked|unavailable. Always state Browser accessibility verification: not-run and Visual regression: not-run. Use contracts/frontend-review-context.json and the effective frontend-verify-assess-shell or frontend-reverify-shell facts; do not invent Browser evidence from component tests.",
2530
2273
  `When only Mock-backed evidence passed, state exactly Frontend status: mock-validated and Real integration: pending, summarize the Real Integration Gap, and name ${taskConfig.taskId}-real-api-integration-verify as the explicit follow-up task to create/run after backend readiness. This follow-up is not auto-created or auto-executed. Never describe Mock evidence as real API integration.`,
2531
2274
  `When Mock was skipped in auto mode and no real API evidence passed, state exactly Frontend status: locally-validated and Real integration: pending, summarize the Real Integration Gap, and name ${taskConfig.taskId}-real-api-integration-verify as the explicit follow-up task when backend readiness matters.`,
2532
2275
  "Read-only: do not modify code, docs, artifacts, or .harness/dag-runs/.",
@@ -3301,13 +3044,14 @@ async function buildBackendTestHybridDag(sources) {
3301
3044
  id: "generate-backend-md-cases-pi", depends_on: [environment.id], role: "implementer",
3302
3045
  executor: "pi", toolProfile: "write", complexity: "MED", writePolicy: "exclusive",
3303
3046
  writeSet: ["testcase/md/**"], allowedPaths: ["testcase/md/**"], forbiddenPaths: forbidden,
3304
- outputContract: "Write testcase/md/README.md plus module Markdown cases using BE-<MODULE>-<NNN>. Use Chinese for human-readable content while preserving required machine-readable identifiers and section headings; no JSON, pytest execution, production code or config writes.",
3047
+ outputContract: "Write a Chinese, human-readable testcase/md/README.md plus module Markdown case cards using BE-<MODULE>-<NNN>; keep machine IDs/literals exact and do not execute pytest or modify production code/config.",
3305
3048
  subtask_prompt: [
3306
3049
  "Read the upstream environment report. Generate a Markdown-first backend test strategy and cases under testcase/md/**.",
3307
- "Write human-readable content in Simplified Chinese by default: document titles, case titles, strategy explanations, preconditions, test-data descriptions, step descriptions, expected-result descriptions, automation notes, table headers and evidence-gap explanations. Keep English only where it is part of a machine-readable contract or established technical literal, including Case IDs, AC/REQ/BR IDs, exact section headings, HTTP methods, paths, field names, enum values, commands, filenames, code symbols and source citations. Do not add an English translation when Chinese already conveys the meaning.",
3308
- "Every case heading is `## BE-<MODULE>-<NNN> <中文用例标题>` and contains these exact machine-readable headings: `### Acceptance Criteria`, `### Source References`, `### Preconditions`, `### Test Data`, `### Steps`, `### Expected Results`, and `### Automation Notes`. API cases also contain `### Endpoint` with Method and Path. Under those headings, write descriptions in Chinese while preserving exact IDs, values and protocol literals.",
3309
- "Create testcase/md/README.md in Chinese. It should concisely explain the test objective, environment/target, isolation and cleanup strategy, module index, traceability summary, assertion principles, evidence gaps and non-goals. Prefer readable Chinese tables and lists over repeated boilerplate.",
3310
- "Expected Results must be concrete, independently assertable Chinese statements. Each result should name the observable HTTP status, response field/value, state transition or membership condition instead of vague phrases such as ‘works correctly’ or ‘符合预期’. Steps must be executable and ordered. Use only environment-supported fixtures/targets/isolation. Record evidence gaps in Chinese instead of inventing behavior or credentials. Do not emit JSON, pytest, or execute commands.",
3050
+ "Write 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.",
3051
+ "Create 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.",
3052
+ "Write each module as readable case cards. Every case starts with `## BE-<MODULE>-<NNN>|<中文用例名称>` and uses these Chinese headings: `### 测试目的`, `### 验收标准`, `### 需求依据`, `### 前置条件`, optional `### 测试数据`, `### 操作步骤`, `### 预期结果`, and `### 自动化映射`. API metadata may use a compact table under the case heading. The deterministic validator also accepts legacy English headings, but new output should use this Chinese presentation.",
3053
+ "Place steps and their expected results in a compact readable table when that improves clarity; otherwise keep numbered executable steps and numbered/bulleted independently assertable results. Every result must name the observable HTTP status, response field/value, state transition or membership condition, never vague wording such as ‘符合预期’.",
3054
+ "In `自动化映射`, record the planned script path and pytest function name when known. Put implementation-only restrictions in a concise `<details>` block rather than dominating the main case flow. Use only environment-supported fixtures/targets/isolation, record evidence gaps in Chinese, and do not emit JSON, pytest, or execute commands.",
3311
3055
  intake.boundedSourceContext, "## Authoritative reference index", JSON.stringify(intake.referenceIndex, null, 2),
3312
3056
  "For 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.",
3313
3057
  "Read only precise indexed references needed for AC/API/field/rule evidence; references remain authoritative over derived text.",
@@ -3319,9 +3063,9 @@ async function buildBackendTestHybridDag(sources) {
3319
3063
  writeSet: ["testcase/md/**"], allowedPaths: ["testcase/md/**"], forbiddenPaths: forbidden,
3320
3064
  outputContract: "Review source fidelity and directly revise only testcase/md/**; return concise Markdown, never JSON.",
3321
3065
  subtask_prompt: [
3322
- "Independently review generated Markdown cases against each case Source References and environment evidence. Preserve and improve the Simplified Chinese presentation: human-readable titles, prose, table headers, steps, expected results and notes should be Chinese unless the token is a machine-readable ID, exact required heading, HTTP/API literal, field/enum value, path, filename, command or code symbol.",
3323
- "Check AC completeness/meaning, endpoint, fields/shape, status/error codes, rules, states, documented boundaries/auth, positive/negative coverage, executable steps and assertable results. Also reject avoidable English prose, duplicated bilingual wording, vague Chinese results such as ‘符合预期’, and literal translations that obscure the observable assertion.",
3324
- "Correct testcase/md/** directly: add documented omissions, remove unsupported cases, fix mappings/expectations, merge duplicates, improve unclear Chinese wording, or record gaps in Chinese. Do not translate or alter Case IDs, AC/REQ/BR IDs, exact required section headings, HTTP methods, paths, field names, enum values, filenames, code symbols or Source References. Avoid cosmetic rewrites that do not improve correctness or readability.",
3066
+ "Independently review generated Markdown cases against each case 需求依据 and environment evidence. Treat the files as human-facing test documentation: require a clear Chinese name and scenario/purpose, compact metadata, readable steps/results, and a concise automation mapping while preserving exact machine IDs and technical literals.",
3067
+ "Check AC completeness/meaning, endpoint, fields/shape, status/error codes, rules, states, documented boundaries/auth, positive/negative coverage, executable steps and assertable results. Reject avoidable English prose, duplicated bilingual wording, repeated boilerplate, oversized unstructured sections, vague results such as ‘符合预期’, and missing script/function mapping where it can be derived.",
3068
+ "Correct testcase/md/** directly: add documented omissions, remove unsupported cases, fix mappings/expectations, merge duplicates, improve navigation/tables/Chinese wording, or record gaps in Chinese. Keep Case IDs, AC/REQ/BR IDs, HTTP methods, paths, fields, enum values, filenames, code symbols and source citations exact. The validator accepts Chinese and legacy English section aliases; retain or converge to the Chinese human-readable headings without losing structure.",
3325
3069
  "Read 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.",
3326
3070
  intake.boundedSourceContext, "## Authoritative reference index", JSON.stringify(intake.referenceIndex, null, 2),
3327
3071
  "For 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.",
@@ -3336,11 +3080,11 @@ async function buildBackendTestHybridDag(sources) {
3336
3080
  outputContract: "Convert every final automatable Markdown case into pytest assets whose actual test function region contains the exact Case ID, preferably in the function name or docstring; no JSON and no pytest execution.",
3337
3081
  subtask_prompt: [
3338
3082
  "Convert validated testcase/md/** to pytest using upstream environment and validation evidence plus only bounded pytest config/conftest.",
3339
- "Ensure every final Markdown Case ID appears in at least one real top-level test_* function region, preferably as `test_BE_<MODULE>_<NNN>_<description>` or in that function's docstring. Multiple test functions may cover one Case ID; assertions come only from Expected Results and setup comes only from Preconditions/Test Data/Automation Notes.",
3340
- "Do not read source/**, add cases, reassign ACs, modify conftest/config/production code, use skip/xfail, swallow assertions, execute pytest, or emit JSON.",
3083
+ "Ensure every final Markdown Case ID appears in at least one real pytest test function or pytest test class method region, preferably as `test_BE_<MODULE>_<NNN>_<description>` and in that function/method docstring. Module-level functions and class-based pytest methods are both supported. Multiple test functions may cover one Case ID; assertions come only from 预期结果/Expected Results and setup comes only from 前置条件/测试数据/自动化映射 or their legacy English aliases.",
3084
+ "Do 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`.",
3341
3085
  ].join("\n\n"),
3342
3086
  };
3343
- const traceability = shellNode("backend-test-traceability-gate-shell", [generatePytest.id], "markdown-traceability", "Fail closed only when a real Markdown case heading has no associated top-level pytest test function. Accept exact Case IDs in the function name or its decorator/body/docstring region; report multiple mappings and extra automation Case IDs without blocking. Continue to reject skip/xfail or swallowed exceptions.", "Run-owned reports/backend-test-traceability.md proving every real Markdown Case ID is covered by at least one pytest test function.");
3087
+ const traceability = shellNode("backend-test-traceability-gate-shell", [generatePytest.id], "markdown-traceability", "Fail closed only when a real Markdown case heading has no associated pytest test function or class method. Accept exact Case IDs in the function/method name or its decorator/body/docstring region; report multiple mappings and extra automation Case IDs without blocking. Continue to reject skip/xfail or swallowed exceptions.", "Run-owned reports/backend-test-traceability.md proving every real Markdown Case ID is covered by at least one pytest test function.");
3344
3088
  const pytestCommand = [
3345
3089
  'mkdir -p "${HARNESS_DAG_RUN_DIR}/reports"',
3346
3090
  'PYTHONUTF8=1 PYTHONIOENCODING=utf-8 PYTHONDONTWRITEBYTECODE=1 python -m pytest testcase/ -v -p no:cacheprovider --junitxml="${HARNESS_DAG_RUN_DIR}/reports/backend-test.junit.xml"',
@@ -3348,7 +3092,7 @@ async function buildBackendTestHybridDag(sources) {
3348
3092
  'if { [ "${STATUS}" -eq 0 ] || [ "${STATUS}" -eq 1 ]; } && [ -s "${HARNESS_DAG_RUN_DIR}/reports/backend-test.junit.xml" ]; then exit 0; fi',
3349
3093
  'exit "${STATUS}"',
3350
3094
  ].join("; ");
3351
- const execute = shellNode("execute-backend-pytest-and-html-report-shell", [traceability.id], "markdown-execute-html", "Execute pytest exactly once. Validate JUnit, render self-contained HTML from that JUnit without rerun, and preserve failures as facts.", "One pytest execution producing valid JUnit, self-contained HTML and reports/backend-test-facts.md; exit 0/1 with valid evidence continues.", [pytestCommand], 300000);
3095
+ const execute = shellNode("execute-backend-pytest-and-html-report-shell", [traceability.id], "markdown-execute-html", "Execute pytest exactly once. Validate JUnit, render the primary self-contained Chinese HTML report from the same JUnit plus final Markdown case metadata without rerun, list every case with name/scenario/script/function/result/duration, and preserve failure summaries plus expandable technical details as facts.", "One pytest execution producing valid JUnit, self-contained HTML and reports/backend-test-facts.md; exit 0/1 with valid evidence continues.", [pytestCommand], 300000);
3352
3096
  const canWriteReport = taskAllowsBackendTestReportWrite(sources);
3353
3097
  const report = {
3354
3098
  id: "backend-test-report-and-l5-pi", depends_on: [execute.id], role: "closeout", executor: "pi", complexity: "MED",