@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.
- package/AGENTS.md +2 -2
- package/CHANGELOG.md +33 -0
- package/README.md +4 -6
- package/dist/application/dag/generate-task-dag.js +12 -1
- package/dist/commands/init.js +3 -3
- package/dist/executors/shell-executor.js +188 -2
- package/dist/governance/exec-plans.js +4 -0
- package/dist/worker/cli.js +13 -12
- package/dist/worker/console/doctor.js +55 -2
- package/dist/worker/console/index.js +1 -0
- package/dist/worker/console/loopback.js +2 -2
- package/dist/worker/console/observe-link.js +7 -2
- package/dist/worker/console/operator-actions.js +30 -2
- package/dist/worker/console/operator-selection.js +92 -0
- package/dist/worker/console/operator-surface-health.js +23 -0
- package/dist/worker/console/recovery-cta.js +2 -2
- package/dist/worker/console/routes.js +45 -19
- package/dist/worker/console/security.js +29 -4
- package/dist/worker/console/server.js +106 -8
- package/dist/worker/console/static/assets/index-3vsjZJHq.js +16 -0
- package/dist/worker/console/static/assets/index-i1wV4LrY.css +1 -0
- package/dist/worker/console/static/index.html +2 -2
- package/dist/worker/observe/routes.js +63 -21
- package/dist/worker/observe/server.js +3 -10
- package/dist/worker/observe/static/index.html +6 -3
- package/dist/worker/observe/static/styles.css +53 -0
- package/dist/workflows/dag/backend-test-markdown-workflow.js +163 -41
- package/dist/workflows/dag/backend-test-result-contract.js +30 -7
- package/dist/workflows/dag/frontend-prewrite-gate.js +77 -0
- package/dist/workflows/dag/frontend-repair.js +7 -1
- package/dist/workflows/dag/frontend-review-context.js +43 -0
- package/dist/workflows/dag/frontend-verification-trace.js +34 -15
- package/dist/workflows/dag/governance-profile.js +14 -6
- package/dist/workflows/dag/init-hybrid.js +143 -399
- package/dist/workflows/dag/types.js +30 -0
- package/dist/workflows/dag/validate.js +22 -1
- package/docs/README.md +4 -2
- package/docs/architecture/evolution.md +6 -6
- package/docs/architecture/worker-and-feature.md +9 -9
- package/docs/templates/agent-dag.schema.json +40 -0
- package/docs/templates/backend-test-dag.generate-pytest.prompt.md +23 -192
- package/docs/templates/backend-test-dag.json +8 -8
- package/docs/templates/backend-test-dag.review-cases.prompt.md +22 -75
- package/package.json +1 -1
- package/skills/agent-worker/references/agent-worker-operator.md +2 -2
- package/skills/frontend-implementation/references/node-contracts.md +6 -8
- package/skills/frontend-review/SKILL.md +5 -8
- package/skills/loop-agent/references/command-reference.md +4 -2
- package/skills/loop-agent/references/harness-policy.md +1 -1
- package/skills/loop-agent/references/hybrid-dag.md +2 -2
- package/dist/worker/console/static/assets/index-KUSib7aM.js +0 -16
- 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,
|
|
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: "
|
|
1541
|
-
executor: "
|
|
1542
|
-
complexity: "
|
|
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
|
-
|
|
1565
|
-
|
|
1566
|
-
|
|
1567
|
-
|
|
1568
|
-
|
|
1569
|
-
|
|
1570
|
-
|
|
1571
|
-
|
|
1572
|
-
|
|
1573
|
-
|
|
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
|
-
//
|
|
1657
|
-
//
|
|
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
|
-
|
|
1687
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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,
|
|
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
|
|
1994
|
-
"
|
|
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-
|
|
2007
|
-
depends_on: ["frontend-plan-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-
|
|
2031
|
-
"frontend-mock-assess-pi",
|
|
1957
|
+
"frontend-design-review-pi",
|
|
2032
1958
|
],
|
|
2033
|
-
runIf: "$.nodes['frontend-design-
|
|
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-
|
|
2046
|
-
"This node runs only when frontend-design-
|
|
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-
|
|
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-
|
|
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
|
|
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
|
-
"
|
|
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
|
-
"
|
|
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-
|
|
2012
|
+
id: "frontend-prewrite-gate-shell",
|
|
2145
2013
|
depends_on: [
|
|
2146
2014
|
"frontend-final-design-review-pi",
|
|
2147
|
-
"frontend-design-
|
|
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
|
|
2157
|
-
subtask_prompt: "
|
|
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
|
-
|
|
2161
|
-
|
|
2162
|
-
|
|
2163
|
-
|
|
2164
|
-
|
|
2165
|
-
|
|
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-
|
|
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-
|
|
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
|
|
2197
|
-
"frontend-
|
|
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-
|
|
2216
|
-
depends_on:
|
|
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: "
|
|
2226
|
-
subtask_prompt: "
|
|
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:
|
|
2248
|
-
|
|
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
|
-
|
|
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-
|
|
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: "
|
|
2355
|
-
subtask_prompt: "Re-run frozen
|
|
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:
|
|
2358
|
-
|
|
2359
|
-
|
|
2360
|
-
|
|
2361
|
-
|
|
2362
|
-
|
|
2363
|
-
|
|
2364
|
-
|
|
2365
|
-
|
|
2366
|
-
|
|
2367
|
-
|
|
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-
|
|
2164
|
+
id: "frontend-review-context-shell",
|
|
2383
2165
|
depends_on: [
|
|
2384
|
-
"frontend-
|
|
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: "
|
|
2419
|
-
subtask_prompt: "Capture the
|
|
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: [
|
|
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-
|
|
2430
|
-
"frontend-
|
|
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-
|
|
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-
|
|
2440
|
-
"frontend-contract-pi",
|
|
2195
|
+
"frontend-prewrite-gate-shell",
|
|
2441
2196
|
"frontend-plan-pi",
|
|
2442
|
-
"frontend-design-
|
|
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
|
|
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
|
|
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-
|
|
2503
|
-
"frontend-
|
|
2504
|
-
"frontend-behavior-reverify-shell",
|
|
2253
|
+
"frontend-review-context-shell",
|
|
2254
|
+
"frontend-reverify-shell",
|
|
2505
2255
|
"frontend-repair-pi",
|
|
2506
|
-
"frontend-
|
|
2507
|
-
"frontend-
|
|
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
|
|
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
|
|
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
|
|
3308
|
-
"
|
|
3309
|
-
"
|
|
3310
|
-
"
|
|
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
|
|
3323
|
-
"Check AC completeness/meaning, endpoint, fields/shape, status/error codes, rules, states, documented boundaries/auth, positive/negative coverage, executable steps and assertable results.
|
|
3324
|
-
"Correct testcase/md/** directly: add documented omissions, remove unsupported cases, fix mappings/expectations, merge duplicates, improve
|
|
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
|
|
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
|
|
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
|
|
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",
|