@tea-agent/loop-agent 0.24.11-beta.0 → 0.25.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +53 -4
- package/README.md +4 -4
- package/dist/application/dag/generate-task-dag.js +25 -8
- package/dist/commands/dag-init-hybrid.js +3 -2
- package/dist/commands/delegate.js +11 -11
- package/dist/commands/init.js +29 -14
- package/dist/commands/instructions.js +1 -2
- package/dist/executors/dag-pi-executor.js +74 -13
- package/dist/executors/pi-executor.js +25 -7
- package/dist/executors/pi-prompt-transport.js +198 -0
- package/dist/executors/pi-sdk-executor.js +1 -1
- package/dist/executors/process-tree.js +33 -0
- package/dist/executors/shell-executor.js +362 -24
- package/dist/executors/shell-verification.js +4 -2
- package/dist/infrastructure/harness/task-store.js +31 -0
- package/dist/shared/operator/capabilities.js +6 -0
- package/dist/task/read-model.js +3 -7
- package/dist/task/runtime.js +12 -3
- package/dist/verification/maven/cache.js +142 -0
- package/dist/verification/maven/index.js +120 -0
- package/dist/verification/maven/plan-commands.js +421 -0
- package/dist/verification/maven/pom-static.js +136 -0
- package/dist/verification/maven/scope-resolve.js +153 -0
- package/dist/verification/maven/stale.js +130 -0
- package/dist/verification/maven/types.js +23 -0
- package/dist/verification/maven/workspace-graph.js +322 -0
- package/dist/worker/cli.js +236 -21
- package/dist/worker/delivery/final-verification.js +12 -0
- package/dist/worker/delivery/git-transaction.js +32 -7
- package/dist/worker/delivery/package.js +9 -5
- package/dist/worker/delivery/verification-bundle.js +26 -5
- package/dist/worker/feature/advance.js +301 -0
- package/dist/worker/feature/doctor.js +223 -0
- package/dist/worker/feature/next-action.js +11 -3
- package/dist/worker/feature/scaffold.js +798 -0
- package/dist/worker/observe/dag-run-artifacts.js +90 -0
- package/dist/worker/observe/node-input.js +444 -0
- package/dist/worker/observe/routes.js +17 -0
- package/dist/worker/observe/static/api.js +9 -0
- package/dist/worker/observe/static/constants.js +9 -0
- package/dist/worker/observe/static/state.js +14 -0
- package/dist/worker/observe/static/styles.css +74 -0
- package/dist/worker/observe/static/views/dag-inspector.js +371 -15
- package/dist/worker/outcomes/projector.js +5 -1
- package/dist/worker/run-task/run-task.js +18 -2
- package/dist/worker/runner/run-ready.js +41 -1
- package/dist/workflows/dag/backend-test-markdown-workflow.js +300 -9
- package/dist/workflows/dag/backend-test-result-contract.js +103 -0
- package/dist/workflows/dag/failure-category.js +5 -1
- package/dist/workflows/dag/frontend-implementation-contract.js +4 -0
- package/dist/workflows/dag/frontend-prewrite-gate.js +0 -17
- package/dist/workflows/dag/frontend-test-result-contract.js +106 -41
- package/dist/workflows/dag/init-hybrid.js +224 -39
- package/dist/workflows/dag/node-execution.js +3 -2
- package/dist/workflows/dag/reconcile-run.js +24 -0
- package/dist/workflows/dag/types.js +57 -0
- package/dist/workflows/dag/validate.js +19 -2
- package/dist/workflows/loop/actions/dag-action.js +2 -1
- package/docs/architecture/dag-execution.md +5 -1
- package/docs/architecture/runtime-boundaries.md +11 -1
- package/docs/architecture/worker-and-feature.md +2 -0
- package/docs/init-surface.manifest.json +3 -0
- package/docs/templates/backend-test-dag.json +3 -3
- package/docs/templates/product-line/README.md +17 -1
- package/docs/templates/product-line/feature-scaffold-batch.example.yaml +31 -0
- package/docs/templates/product-line/scaffold-samples/README.md +36 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/acceptance.yaml +13 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/design.md +14 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/feature.yaml +3 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/requirement.md +6 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/tasks/BE-IMPL-001.yaml +83 -0
- package/docs/templates/product-line/scaffold-samples/backend-only/tasks/task-graph.yaml +14 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/acceptance.yaml +15 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/design.md +18 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/feature.yaml +3 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/requirement.md +6 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/BE-IMPL-001.yaml +84 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/CONTRACT-001.yaml +84 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/FE-IMPL-001.yaml +86 -0
- package/docs/templates/product-line/scaffold-samples/fe-with-api/tasks/task-graph.yaml +40 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/acceptance.yaml +13 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/design.md +14 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/feature.yaml +3 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/requirement.md +6 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/FE-IMPL-001.yaml +85 -0
- package/docs/templates/product-line/scaffold-samples/frontend-only/tasks/task-graph.yaml +14 -0
- package/examples/l5-report-coms-process-definition.html +322 -0
- package/package.json +1 -1
- package/skills/agent-worker/references/agent-worker-operator.md +84 -0
- package/skills/frontend-implementation/references/node-contracts.md +2 -2
- package/skills/loop-agent/SKILL.md +14 -16
- package/skills/loop-agent/references/command-reference.md +33 -12
- package/skills/loop-agent/references/harness-policy.md +28 -6
- package/skills/loop-agent/references/hybrid-dag.md +8 -7
- package/skills/loop-agent/references/post-implementation-and-patterns.md +19 -9
- package/skills/loop-agent/references/source-and-plan-practice.md +161 -0
- package/skills/loop-agent/references/task-workflow.md +13 -5
|
@@ -0,0 +1,322 @@
|
|
|
1
|
+
<!doctype html>
|
|
2
|
+
<html lang="zh-CN">
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta name="viewport" content="width=device-width, initial-scale=1">
|
|
6
|
+
<title>后端测试成熟度报告 · 流程定义管理 · L-5</title>
|
|
7
|
+
<style>
|
|
8
|
+
:root{--page:#f5f7fb;--surface:#fff;--ink:#17243b;--muted:#718097;--line:#e4e9f1;--navy:#17365d;--blue:#4775ef;--blue-soft:#edf3ff;--green:#15815c;--green-soft:#e7f7f0;--amber:#c87918;--amber-soft:#fff4e5;--red:#d34661;--red-soft:#fff0f3;--shadow:0 8px 24px rgba(24,54,93,.055)}
|
|
9
|
+
*{box-sizing:border-box}body{margin:0;background:radial-gradient(circle at 8% 0,#edf4ff 0,transparent 36rem),var(--page);color:var(--ink);font:15px/1.6 Inter,system-ui,-apple-system,BlinkMacSystemFont,"Segoe UI","Microsoft YaHei",sans-serif}
|
|
10
|
+
main{width:min(1180px,calc(100% - 56px));margin:auto;padding:42px 0 72px}
|
|
11
|
+
.topbar{position:relative;overflow:hidden;padding:34px 38px;border:1px solid #294b78;border-radius:26px;background:linear-gradient(125deg,#102849 0%,#173d6d 57%,#245b91 100%);box-shadow:0 18px 40px rgba(16,40,73,.18);display:flex;align-items:flex-start;justify-content:space-between;gap:28px}
|
|
12
|
+
.topbar:before,.topbar:after{content:"";position:absolute;border:1px solid rgba(165,211,255,.18);border-radius:50%;pointer-events:none}.topbar:before{width:370px;height:370px;right:-155px;top:-225px}.topbar:after{width:240px;height:240px;right:55px;bottom:-190px}
|
|
13
|
+
.topbar>div:first-child{position:relative;z-index:1}
|
|
14
|
+
.eyebrow{color:#9fc6ee;font-size:11px;font-weight:800;letter-spacing:.2em}
|
|
15
|
+
.title{margin:12px 0 10px;color:#f7fbff;font-size:clamp(30px,3.8vw,46px);font-weight:800;letter-spacing:-.055em;line-height:1.1}
|
|
16
|
+
.meta{color:#bdd2e9;font-size:13px}
|
|
17
|
+
.decision{position:relative;z-index:1;min-width:220px;padding:16px 18px;border:1px solid rgba(255,177,192,.35);border-radius:18px;background:rgba(255,245,247,.1);box-shadow:0 8px 24px rgba(0,0,0,.08)}
|
|
18
|
+
.decision-top{display:flex;align-items:center;gap:9px;color:#fff1f4;font-size:17px;font-weight:800}
|
|
19
|
+
.decision-dot{width:11px;height:11px;border-radius:50%;background:var(--red);box-shadow:0 0 0 5px rgba(211,70,97,.1)}
|
|
20
|
+
.decision small{display:block;margin:7px 0 0 20px;color:#f3bec8;font-size:12px}
|
|
21
|
+
.stats{display:grid;grid-template-columns:repeat(4,1fr);gap:14px;margin-top:18px}
|
|
22
|
+
.stat{position:relative;min-height:132px;padding:21px 22px;overflow:hidden;background:var(--surface);border:1px solid #e1e8f2;border-radius:15px;box-shadow:0 6px 18px rgba(25,53,92,.045)}
|
|
23
|
+
.stat:before{content:"";position:absolute;top:0;left:0;right:0;height:3px;background:var(--blue)}
|
|
24
|
+
.stat:nth-child(2):before{background:var(--amber)}.stat:nth-child(3):before{background:#7589d9}.stat:nth-child(4):before{background:var(--green)}
|
|
25
|
+
.stat-label{color:#748198;font-size:13px;font-weight:650}
|
|
26
|
+
.stat-value{margin-top:19px;color:#13213a;font-size:35px;font-weight:800;letter-spacing:-.06em;line-height:1}
|
|
27
|
+
.stat-foot{margin-top:9px;color:var(--muted);font-size:12px}
|
|
28
|
+
.stat-foot.warn{color:var(--amber)}.stat-foot.good{color:var(--green)}.stat-foot.fail{color:var(--red)}
|
|
29
|
+
.layout{display:grid;grid-template-columns:1.28fr .86fr;gap:20px;margin-top:20px}
|
|
30
|
+
.panel{background:var(--surface);border:1px solid #e0e7f0;border-radius:15px;box-shadow:0 7px 20px rgba(25,53,92,.04)}
|
|
31
|
+
.panel-pad{padding:22px}
|
|
32
|
+
.panel-heading{display:flex;align-items:center;justify-content:space-between;gap:14px;margin-bottom:18px}
|
|
33
|
+
.panel-heading h2{margin:0;color:var(--navy);font-size:19px;letter-spacing:-.025em}
|
|
34
|
+
.panel-heading h2:before{content:"";display:inline-block;width:4px;height:17px;margin:0 9px 0 0;vertical-align:-2px;border-radius:5px;background:var(--blue)}
|
|
35
|
+
.panel-note{color:var(--muted);font-size:13px}
|
|
36
|
+
.gate{padding:14px 15px;border:1px solid #e5ebf3;border-radius:11px;background:#fcfdff}
|
|
37
|
+
.gate+.gate{margin-top:8px}
|
|
38
|
+
.gate-head{display:flex;align-items:center;gap:10px}
|
|
39
|
+
.gate-name{flex:1;color:#263c5e;font-size:13px;font-weight:750}
|
|
40
|
+
.gate-value{font-size:15px;font-weight:800}
|
|
41
|
+
.gate-value.pass{color:var(--green)}.gate-value.warn{color:var(--amber)}.gate-value.fail{color:var(--red)}
|
|
42
|
+
.meter{height:6px;margin:10px 0 7px;background:#e7edf5;border-radius:99px;overflow:hidden}
|
|
43
|
+
.meter i{display:block;height:100%;border-radius:inherit;background:var(--blue)}
|
|
44
|
+
.meter i.pass{background:var(--green)}.meter i.warn{background:#e9a040}.meter i.fail{background:var(--red)}
|
|
45
|
+
.gate-foot{display:flex;justify-content:space-between;color:var(--muted);font-size:12px}
|
|
46
|
+
.badge{display:inline-flex;align-items:center;padding:3px 9px;border-radius:999px;font-size:11px;font-weight:800}
|
|
47
|
+
.badge.pass{color:var(--green);background:var(--green-soft)}.badge.warn{color:var(--amber);background:var(--amber-soft)}.badge.fail{color:var(--red);background:var(--red-soft)}
|
|
48
|
+
.evidence{margin-top:10px;padding-top:9px;border-top:1px solid #e5ebf3}
|
|
49
|
+
.evidence summary{display:flex;align-items:center;gap:6px;color:var(--blue);font-size:12px;font-weight:750;cursor:pointer;list-style:none}
|
|
50
|
+
.evidence summary:before{content:"+";display:inline-grid;place-items:center;width:15px;height:15px;border:1px solid currentColor;border-radius:50%;font-size:13px;line-height:1}
|
|
51
|
+
.evidence[open] summary:before{content:"−"}
|
|
52
|
+
.evidence-body{margin-top:7px;color:var(--muted);font-size:12px}
|
|
53
|
+
.evidence-body code{color:var(--navy);font:11px ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
54
|
+
.cause{padding:14px 0;border-bottom:1px solid var(--line)}
|
|
55
|
+
.cause:first-of-type{padding-top:0}.cause:last-child{padding-bottom:0;border-bottom:0}
|
|
56
|
+
.cause-head{display:flex;align-items:center;gap:10px}
|
|
57
|
+
.cause-label{padding:4px 9px;border-radius:7px;font-size:12px;font-weight:800}
|
|
58
|
+
.cause-label.crit{background:var(--red-soft);color:var(--red)}.cause-label.env{background:var(--amber-soft);color:var(--amber)}.cause-label.none{background:#eef2f7;color:#65738b}
|
|
59
|
+
.cause-title{flex:1;color:#2a3c5a;font-size:14px;font-weight:700}
|
|
60
|
+
.cause-count{font-size:16px;font-weight:800}
|
|
61
|
+
.cause-bar{height:5px;margin-top:10px;background:#edf1f6;border-radius:99px;overflow:hidden}
|
|
62
|
+
.cause-bar i{display:block;height:100%;border-radius:inherit}
|
|
63
|
+
.overview{display:grid;grid-template-columns:1fr 1.35fr;gap:12px;margin-top:18px}
|
|
64
|
+
.overview-chart,.signal-chart{padding:20px 22px;border:1px solid #dfe7f1;border-radius:15px;background:rgba(255,255,255,.82);box-shadow:0 7px 20px rgba(25,53,92,.04)}
|
|
65
|
+
.chart-heading{display:flex;align-items:flex-start;justify-content:space-between;gap:16px}
|
|
66
|
+
.chart-heading h2{margin:3px 0 0;color:var(--navy);font-size:17px;letter-spacing:-.02em}
|
|
67
|
+
.chart-kicker{color:#8796aa;font-size:10px;font-weight:800;letter-spacing:.16em}
|
|
68
|
+
.chart-caption{color:var(--muted);font-size:11px;white-space:nowrap}
|
|
69
|
+
.donut-wrap{position:relative;display:flex;align-items:center;gap:20px;margin-top:15px}
|
|
70
|
+
.donut{width:116px;height:116px;flex:0 0 116px;transform:rotate(-90deg)}
|
|
71
|
+
.donut circle{fill:none;stroke-width:12}
|
|
72
|
+
.donut-track{stroke:#edf1f6}
|
|
73
|
+
.donut-pass{stroke:var(--green);stroke-dasharray:263.4 289;stroke-linecap:round}
|
|
74
|
+
.donut-fail{stroke:var(--red);stroke-dasharray:13.8 289;stroke-dashoffset:-263.4}
|
|
75
|
+
.donut-center{position:absolute;display:flex;width:116px;height:116px;flex-direction:column;align-items:center;justify-content:center;pointer-events:none}
|
|
76
|
+
.donut-center strong{color:var(--navy);font-size:20px;letter-spacing:-.05em}
|
|
77
|
+
.donut-center span{color:var(--muted);font-size:10px}
|
|
78
|
+
.outcome-list{display:grid;gap:6px;flex:1}
|
|
79
|
+
.outcome-list div{display:grid;grid-template-columns:10px 1fr auto;align-items:center;gap:7px;color:var(--muted);font-size:12px}
|
|
80
|
+
.outcome-list strong{color:var(--ink);font-size:14px}
|
|
81
|
+
.legend-dot{width:8px;height:8px;border-radius:50%;background:var(--green)}
|
|
82
|
+
.legend-dot.fail{background:var(--red)}.legend-dot.blocked{background:#aab5c4}
|
|
83
|
+
.signal-chart{display:flex;flex-direction:column}
|
|
84
|
+
.signal-row{margin-top:14px}
|
|
85
|
+
.signal-row>div:first-child{display:flex;justify-content:space-between;align-items:baseline;color:#2b405f;font-size:12px}
|
|
86
|
+
.signal-row strong{color:var(--navy);font-size:14px}
|
|
87
|
+
.signal-track{position:relative;height:8px;margin:7px 0 4px;background:#edf1f6;border-radius:99px}
|
|
88
|
+
.signal-track i{display:block;height:100%;border-radius:inherit;background:linear-gradient(90deg,#7d9bf5,var(--blue))}
|
|
89
|
+
.signal-track i.good{background:linear-gradient(90deg,#52b88b,var(--green))}
|
|
90
|
+
.signal-track i.warn{background:linear-gradient(90deg,#e9a040,#f0b85a)}
|
|
91
|
+
.signal-track b{position:absolute;top:-3px;width:2px;height:14px;background:#273b59;border-radius:2px}
|
|
92
|
+
.signal-row small{color:var(--muted);font-size:10px}
|
|
93
|
+
.module-grid{display:grid;grid-template-columns:repeat(2,1fr);gap:10px}
|
|
94
|
+
.module{padding:13px 14px;border:1px solid var(--line);border-radius:11px;background:#fbfcfe}
|
|
95
|
+
.module-head{display:flex;justify-content:space-between;align-items:center;gap:8px}
|
|
96
|
+
.module-name{color:#2a3c5a;font-size:12px;font-weight:700;font-family:ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
97
|
+
.module-bar{height:6px;margin:9px 0 6px;background:#edf1f6;border-radius:99px;overflow:hidden;display:flex}
|
|
98
|
+
.module-bar i{display:block;height:100%}
|
|
99
|
+
.module-bar i.p{background:var(--green)}.module-bar i.f{background:var(--red)}
|
|
100
|
+
.module-foot{display:flex;justify-content:space-between;color:var(--muted);font-size:11px}
|
|
101
|
+
.defects{display:grid;grid-template-columns:1fr;gap:12px}
|
|
102
|
+
.defect{border:1px solid #ecd4d9;border-radius:13px;background:linear-gradient(135deg,#fffdfd,#fff8f9);overflow:hidden}
|
|
103
|
+
.defect summary{display:flex;align-items:center;gap:10px;padding:15px;cursor:pointer;list-style:none}
|
|
104
|
+
.defect summary::-webkit-details-marker{display:none}
|
|
105
|
+
.bug-id{color:#c43b58;font:700 12px ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
106
|
+
.bug-title{flex:1;color:var(--navy);font-size:14px;font-weight:750}
|
|
107
|
+
.bug-body{padding:0 15px 15px;border-top:1px solid #f3dce1}
|
|
108
|
+
.bug-fields{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:9px;margin-top:14px}
|
|
109
|
+
.bug-field{padding:9px 10px;border-radius:8px;background:#fff}
|
|
110
|
+
.bug-field label{display:block;color:var(--muted);font-size:11px}
|
|
111
|
+
.bug-field span{display:block;margin-top:2px;color:var(--ink);font-size:12px;font-weight:650}
|
|
112
|
+
.suggestions{display:grid;grid-template-columns:repeat(3,1fr);gap:12px}
|
|
113
|
+
.suggestion{padding:17px;border:1px solid #e3eafa;border-radius:13px;background:linear-gradient(135deg,#fbfcff,#f4f7ff)}
|
|
114
|
+
.priority{display:inline-grid;place-items:center;width:28px;height:24px;border-radius:7px;background:var(--blue-soft);color:var(--blue);font-size:11px;font-weight:850}
|
|
115
|
+
.suggestion strong{display:block;margin-top:11px;color:var(--navy);font-size:14px}
|
|
116
|
+
.suggestion span{display:block;margin-top:5px;color:var(--muted);font-size:12px}
|
|
117
|
+
.details{margin-top:20px}
|
|
118
|
+
.case{border-top:1px solid var(--line)}
|
|
119
|
+
details summary{cursor:pointer;list-style:none}details summary::-webkit-details-marker{display:none}
|
|
120
|
+
details:not(.evidence) summary:after{content:"⌄";margin-left:auto;color:#91a0b5;font-size:16px;transition:transform .2s ease}
|
|
121
|
+
details[open]:not(.evidence) summary:after{transform:rotate(180deg)}
|
|
122
|
+
.case-summary{display:flex;align-items:center;gap:11px;padding:16px 2px}
|
|
123
|
+
.case-id{padding:4px 9px;border-radius:6px;background:#edf2f8;color:var(--navy);font:700 12px ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
124
|
+
.case-title{flex:1;color:#263c5e;font-weight:750}
|
|
125
|
+
.case-meta{color:var(--muted);font-size:13px}
|
|
126
|
+
.case-body{display:grid;grid-template-columns:repeat(2,minmax(0,1fr));gap:10px;padding:0 0 18px}
|
|
127
|
+
.case-box{padding:13px;border:1px solid var(--line);border-radius:10px;background:#fbfcfe}
|
|
128
|
+
.case-box h3{margin:0 0 5px;color:var(--muted);font-size:12px}
|
|
129
|
+
.case-box pre,.case-box div{margin:0;white-space:pre-wrap;color:#344054;font:12px/1.6 ui-monospace,SFMono-Regular,Menlo,monospace}
|
|
130
|
+
.footnote{margin:18px 0 0;color:var(--muted);font-size:12px}
|
|
131
|
+
.quality-grid{display:grid;grid-template-columns:1fr 1fr;gap:8px}
|
|
132
|
+
.q{display:flex;align-items:center;justify-content:space-between;padding:11px 13px;border:1px solid var(--line);border-radius:10px;background:#fbfcfe}
|
|
133
|
+
.q-name{color:#2a3c5a;font-size:13px;font-weight:650}.q-status{font-size:11px;font-weight:800}
|
|
134
|
+
.q-status.pass{color:var(--green)}.q-status.fail{color:var(--red)}.q-status.un{color:var(--muted)}
|
|
135
|
+
@media(max-width:900px){main{width:min(100% - 32px,1180px)}.stats{grid-template-columns:repeat(2,1fr)}.layout{grid-template-columns:1fr}.suggestions{grid-template-columns:1fr}.overview{grid-template-columns:1fr}}
|
|
136
|
+
@media(max-width:560px){main{width:calc(100% - 20px);padding-top:25px}.topbar{display:block;padding:28px 23px;border-radius:21px}.decision{margin-top:18px}.stats,.defects,.bug-fields,.case-body,.quality-grid,.module-grid{grid-template-columns:1fr}.stat{min-height:118px;padding:17px}.stat-value{font-size:31px}.panel-pad{padding:18px}.panel-heading{align-items:flex-start;flex-direction:column}.case-meta{display:none}}
|
|
137
|
+
</style>
|
|
138
|
+
</head>
|
|
139
|
+
<body>
|
|
140
|
+
<main>
|
|
141
|
+
<header class="topbar">
|
|
142
|
+
<div>
|
|
143
|
+
<div class="eyebrow">BACKEND TEST · L-5 QUALITY VIEW</div>
|
|
144
|
+
<h1 class="title">流程定义管理 · 测试成熟度报告</h1>
|
|
145
|
+
<p class="meta">COMS / 流程定义管理(管理属性)· Campaign · 2026-07-29 · Windows-11 · Python 3.12.9</p>
|
|
146
|
+
</div>
|
|
147
|
+
<div class="decision">
|
|
148
|
+
<div class="decision-top"><i class="decision-dot"></i>L-5 NOT READY</div>
|
|
149
|
+
<small>4 个阻断项需要处理</small>
|
|
150
|
+
</div>
|
|
151
|
+
</header>
|
|
152
|
+
|
|
153
|
+
<section class="stats" aria-label="关键指标">
|
|
154
|
+
<div class="stat"><div class="stat-label">测试通过率</div><div class="stat-value">95.24%</div><div class="stat-foot warn">20 / 21 · 目标 100%(未达标)</div></div>
|
|
155
|
+
<div class="stat"><div class="stat-label">AC 验收覆盖</div><div class="stat-value">92.86%</div><div class="stat-foot warn">13 / 14 · AC-BE-001 未通过</div></div>
|
|
156
|
+
<div class="stat"><div class="stat-label">自动化覆盖率</div><div class="stat-value">100%</div><div class="stat-foot good">21 / 21 用例已映射</div></div>
|
|
157
|
+
<div class="stat"><div class="stat-label">Critical 风险</div><div class="stat-value">1</div><div class="stat-foot fail">阻断级接口契约偏差</div></div>
|
|
158
|
+
</section>
|
|
159
|
+
|
|
160
|
+
<section class="overview" aria-label="执行概览">
|
|
161
|
+
<div class="overview-chart">
|
|
162
|
+
<div class="chart-heading"><div><span class="chart-kicker">RUN OUTCOME</span><h2>本轮执行结果</h2></div><span class="chart-caption">21 个用例 · 6.14s</span></div>
|
|
163
|
+
<div class="donut-wrap">
|
|
164
|
+
<svg class="donut" viewBox="0 0 120 120" role="img" aria-label="20 通过,1 失败,0 错误">
|
|
165
|
+
<circle class="donut-track" cx="60" cy="60" r="46"></circle>
|
|
166
|
+
<circle class="donut-pass" cx="60" cy="60" r="46"></circle>
|
|
167
|
+
<circle class="donut-fail" cx="60" cy="60" r="46"></circle>
|
|
168
|
+
</svg>
|
|
169
|
+
<div class="donut-center"><strong>95.2%</strong><span>通过率</span></div>
|
|
170
|
+
<div class="outcome-list">
|
|
171
|
+
<div><i class="legend-dot"></i><span>通过</span><strong>20</strong></div>
|
|
172
|
+
<div><i class="legend-dot fail"></i><span>失败</span><strong>1</strong></div>
|
|
173
|
+
<div><i class="legend-dot blocked"></i><span>错误 / 跳过</span><strong>0</strong></div>
|
|
174
|
+
</div>
|
|
175
|
+
</div>
|
|
176
|
+
</div>
|
|
177
|
+
<div class="signal-chart">
|
|
178
|
+
<div class="chart-heading"><div><span class="chart-kicker">QUALITY SIGNALS</span><h2>质量信号</h2></div><span class="chart-caption">按 L-5 门槛判定</span></div>
|
|
179
|
+
<div class="signal-row"><div><span>需求 / AC 覆盖</span><strong>92.86%</strong></div><div class="signal-track"><i class="warn" style="width:92.86%"></i><b style="left:100%"></b></div><small>13 / 14 · 目标 100%</small></div>
|
|
180
|
+
<div class="signal-row"><div><span>自动化覆盖率</span><strong>100%</strong></div><div class="signal-track"><i class="good" style="width:100%"></i><b style="left:90%"></b></div><small>21 / 21 · 目标 ≥90%</small></div>
|
|
181
|
+
<div class="signal-row"><div><span>用例跳过数</span><strong>0</strong></div><div class="signal-track"><i class="good" style="width:100%"></i><b style="left:100%"></b></div><small>0 / 21 · 目标 0</small></div>
|
|
182
|
+
<div class="signal-row"><div><span>Line 代码覆盖</span><strong>—</strong></div><div class="signal-track"><i style="width:0%"></i><b style="left:80%"></b></div><small>unavailable · 无 coverage 产物</small></div>
|
|
183
|
+
</div>
|
|
184
|
+
</section>
|
|
185
|
+
|
|
186
|
+
<section class="layout">
|
|
187
|
+
<article class="panel panel-pad">
|
|
188
|
+
<div class="panel-heading"><h2>L-5 门禁摘要</h2><span class="panel-note">阻断项与执行门槛</span></div>
|
|
189
|
+
|
|
190
|
+
<div class="gate">
|
|
191
|
+
<div class="gate-head"><span class="gate-name">测试通过率</span><strong class="gate-value warn">95.24%</strong><span class="badge warn">未达标</span></div>
|
|
192
|
+
<div class="meter"><i class="warn" style="width:95.24%"></i></div>
|
|
193
|
+
<div class="gate-foot"><span>20 / 21 个用例</span><span>目标 100%</span></div>
|
|
194
|
+
<details class="evidence"><summary>查看计算依据</summary><div class="evidence-body">失败 1 条,错误 0 条,跳过 0 条。证据:<code>reports/backend-test-facts.md · pytest-exit=1</code></div></details>
|
|
195
|
+
</div>
|
|
196
|
+
|
|
197
|
+
<div class="gate">
|
|
198
|
+
<div class="gate-head"><span class="gate-name">AC 字段安全验收(AC-BE-001)</span><strong class="gate-value fail">FAIL</strong><span class="badge fail">阻断</span></div>
|
|
199
|
+
<div class="meter"><i class="fail" style="width:0%"></i></div>
|
|
200
|
+
<div class="gate-foot"><span>列表返回 <code>nodeList: null</code></span><span>目标:不返回 nodeList/approver</span></div>
|
|
201
|
+
<details class="evidence"><summary>查看阻断原因</summary><div class="evidence-body">列表记录违反「不应返回 nodeList/approver」的字段安全契约。关联:<code>BE-PD-010 · AC-BE-001</code></div></details>
|
|
202
|
+
</div>
|
|
203
|
+
|
|
204
|
+
<div class="gate">
|
|
205
|
+
<div class="gate-head"><span class="gate-name">Markdown 用例质量校验(节点4)</span><strong class="gate-value fail">FAIL</strong><span class="badge fail">质量缺陷</span></div>
|
|
206
|
+
<div class="meter"><i class="fail" style="width:0%"></i></div>
|
|
207
|
+
<div class="gate-foot"><span>21 条用例均缺结构化预期结果</span><span>advisory · 不阻断 pytest</span></div>
|
|
208
|
+
<details class="evidence"><summary>查看发现</summary><div class="evidence-body">首条发现:BE-PD-002 has no structured expected result。全部 21 条用例缺少结构化预期结果。证据:<code>reports/backend-md-case-validation.md</code></div></details>
|
|
209
|
+
</div>
|
|
210
|
+
|
|
211
|
+
<div class="gate">
|
|
212
|
+
<div class="gate-head"><span class="gate-name">Critical 风险</span><strong class="gate-value fail">1</strong><span class="badge fail">阻断</span></div>
|
|
213
|
+
<div class="meter"><i class="fail" style="width:35%"></i></div>
|
|
214
|
+
<div class="gate-foot"><span>1 个阻断项</span><span>目标 0</span></div>
|
|
215
|
+
<details class="evidence"><summary>查看阻断原因</summary><div class="evidence-body">后端接口契约偏差:列表接口返回 <code>nodeList</code> 字段。关联:<code>BE-PD-010 · AC-BE-001 · ProductBug</code></div></details>
|
|
216
|
+
</div>
|
|
217
|
+
|
|
218
|
+
<div class="gate">
|
|
219
|
+
<div class="gate-head"><span class="gate-name">Line 代码覆盖</span><strong class="gate-value warn">unavailable</strong><span class="badge warn">证据缺口</span></div>
|
|
220
|
+
<div class="meter"><i class="warn" style="width:0%"></i></div>
|
|
221
|
+
<div class="gate-foot"><span>本轮未产出 coverage artifact</span><span>目标 ≥80%</span></div>
|
|
222
|
+
</div>
|
|
223
|
+
</article>
|
|
224
|
+
|
|
225
|
+
<article class="panel panel-pad">
|
|
226
|
+
<div class="panel-heading"><h2>模块通过情况</h2><span class="panel-note">6 个脚本 · 21 用例</span></div>
|
|
227
|
+
<div class="module-grid">
|
|
228
|
+
<div class="module"><div class="module-head"><span class="module-name">test_process_definition_create.py</span><span class="badge pass">8/8</span></div><div class="module-bar"><i class="p" style="width:100%"></i></div><div class="module-foot"><span>创建</span><span>100%</span></div></div>
|
|
229
|
+
<div class="module"><div class="module-head"><span class="module-name">test_process_definition_update.py</span><span class="badge pass">3/3</span></div><div class="module-bar"><i class="p" style="width:100%"></i></div><div class="module-foot"><span>更新</span><span>100%</span></div></div>
|
|
230
|
+
<div class="module"><div class="module-head"><span class="module-name">test_process_definition_list.py</span><span class="badge fail">4/5</span></div><div class="module-bar"><i class="p" style="width:80%"></i><i class="f" style="width:20%"></i></div><div class="module-foot"><span>列表</span><span>80%</span></div></div>
|
|
231
|
+
<div class="module"><div class="module-head"><span class="module-name">test_process_definition_delete.py</span><span class="badge pass">2/2</span></div><div class="module-bar"><i class="p" style="width:100%"></i></div><div class="module-foot"><span>删除</span><span>100%</span></div></div>
|
|
232
|
+
<div class="module"><div class="module-head"><span class="module-name">test_process_definition_detail.py</span><span class="badge pass">2/2</span></div><div class="module-bar"><i class="p" style="width:100%"></i></div><div class="module-foot"><span>详情</span><span>100%</span></div></div>
|
|
233
|
+
<div class="module"><div class="module-head"><span class="module-name">test_process_definition_monitor_status.py</span><span class="badge pass">1/1</span></div><div class="module-bar"><i class="p" style="width:100%"></i></div><div class="module-foot"><span>监控状态</span><span>100%</span></div></div>
|
|
234
|
+
</div>
|
|
235
|
+
</article>
|
|
236
|
+
</section>
|
|
237
|
+
|
|
238
|
+
<section class="panel panel-pad full">
|
|
239
|
+
<div class="panel-heading"><h2>失败诊断</h2><span class="panel-note">1 个失败 · Critical</span></div>
|
|
240
|
+
<div class="cause">
|
|
241
|
+
<div class="cause-head"><span class="cause-label crit">ProductBug</span><span class="cause-title">后端接口契约偏差:列表返回 nodeList</span><strong class="cause-count">1</strong></div>
|
|
242
|
+
<div class="cause-bar"><i style="width:100%;background:var(--red)"></i></div>
|
|
243
|
+
<details class="evidence"><summary>查看诊断详情</summary>
|
|
244
|
+
<div class="evidence-body">
|
|
245
|
+
失败用例:<code>BE-PD-010 list_default_pagination</code><br>
|
|
246
|
+
失败位置:<code>testcase/test_process_definition_list.py:48</code> AssertionError<br>
|
|
247
|
+
失败断言:<code>assert 'nodeList' not in item</code><br>
|
|
248
|
+
实际响应:列表每条记录包含 <code>"nodeList": null</code>,违反「列表记录不应返回 nodeList/approver」的字段安全契约<br>
|
|
249
|
+
关联 AC:<code>AC-BE-001(列表字段安全)</code>
|
|
250
|
+
</div>
|
|
251
|
+
</details>
|
|
252
|
+
</div>
|
|
253
|
+
</section>
|
|
254
|
+
|
|
255
|
+
<section class="panel panel-pad full">
|
|
256
|
+
<div class="panel-heading"><h2>质量校验矩阵</h2><span class="panel-note">6 项校验 · 来自节点 4 / 6</span></div>
|
|
257
|
+
<div class="quality-grid">
|
|
258
|
+
<div class="q"><span class="q-name">环境硬门(Shell)</span><span class="q-status pass">PASS</span></div>
|
|
259
|
+
<div class="q"><span class="q-name">Markdown 用例校验(节点4)</span><span class="q-status fail">FAIL · 21</span></div>
|
|
260
|
+
<div class="q"><span class="q-name">Markdown → pytest 追溯(节点6)</span><span class="q-status pass">PASS · 0</span></div>
|
|
261
|
+
<div class="q"><span class="q-name">Markdown 敏感信息</span><span class="q-status pass">PASS</span></div>
|
|
262
|
+
<div class="q"><span class="q-name">HTTP 请求/响应日志(节点6 advisory)</span><span class="q-status pass">PASS · 0</span></div>
|
|
263
|
+
<div class="q"><span class="q-name">代码覆盖率</span><span class="q-status un">UNAVAILABLE</span></div>
|
|
264
|
+
</div>
|
|
265
|
+
<p class="footnote">节点4 FAIL 与节点6 PASS 均为 advisory,未阻断 pytest 执行,但其 FAIL 状态保持可见,不重写为 PASS。</p>
|
|
266
|
+
</section>
|
|
267
|
+
|
|
268
|
+
<section class="panel panel-pad full">
|
|
269
|
+
<div class="panel-heading"><h2>缺陷记录</h2><span class="panel-note">1 条 · 已关联用例与证据</span></div>
|
|
270
|
+
<div class="defects">
|
|
271
|
+
<details class="defect" open>
|
|
272
|
+
<summary><span class="bug-id">BE-PD-010</span><span class="bug-title">列表接口返回 nodeList 字段,违反字段安全契约</span><span class="badge fail">未修复</span></summary>
|
|
273
|
+
<div class="bug-body">
|
|
274
|
+
<div class="bug-fields">
|
|
275
|
+
<div class="bug-field"><label>级别</label><span>P0 · Critical · ProductBug</span></div>
|
|
276
|
+
<div class="bug-field"><label>模块</label><span>流程定义管理 / 列表查询</span></div>
|
|
277
|
+
<div class="bug-field"><label>关联 AC / Case</label><span>AC-BE-001 · BE-PD-010</span></div>
|
|
278
|
+
<div class="bug-field"><label>失败分类</label><span>assertion_error · 接口契约偏差</span></div>
|
|
279
|
+
</div>
|
|
280
|
+
<details class="evidence"><summary>查看缺陷证据</summary>
|
|
281
|
+
<div class="evidence-body">
|
|
282
|
+
断言:<code>assert 'nodeList' not in item</code><br>
|
|
283
|
+
实际响应:列表每条记录包含 <code>"nodeList": null</code><br>
|
|
284
|
+
脚本:<code>testcase/test_process_definition_list.py::test_BE_PD_010_list_default_pagination</code><br>
|
|
285
|
+
接口转发链:<code>POST /mc-coms/redirect/api/forward → mc-bpm/process-definition/list</code>
|
|
286
|
+
</div>
|
|
287
|
+
</details>
|
|
288
|
+
</div>
|
|
289
|
+
</details>
|
|
290
|
+
</div>
|
|
291
|
+
</section>
|
|
292
|
+
|
|
293
|
+
<section class="panel panel-pad full">
|
|
294
|
+
<div class="panel-heading"><h2>下一轮回归建议</h2><span class="panel-note">3 条行动项</span></div>
|
|
295
|
+
<div class="suggestions">
|
|
296
|
+
<div class="suggestion"><span class="priority">P0</span><strong>修复列表接口字段安全契约</strong><span>移除列表记录中的 <code>nodeList</code> / <code>approver</code> 字段,满足 AC-BE-001 后重跑 BE-PD-010。</span></div>
|
|
297
|
+
<div class="suggestion"><span class="priority">P1</span><strong>补齐 Markdown 用例结构化预期结果</strong><span>21 条用例均缺结构化预期结果(节点4 FAIL),需为每条用例补齐可断言的预期。</span></div>
|
|
298
|
+
<div class="suggestion"><span class="priority">P2</span><strong>产出独立 coverage artifact</strong><span>本轮代码覆盖率为 unavailable,需启用 pytest-cov 并产出可校验的覆盖率产物。</span></div>
|
|
299
|
+
</div>
|
|
300
|
+
</section>
|
|
301
|
+
|
|
302
|
+
<section class="panel panel-pad full details">
|
|
303
|
+
<div class="panel-heading"><h2>阻断用例明细</h2><span class="panel-note">点击展开请求/响应</span></div>
|
|
304
|
+
<details class="case" open>
|
|
305
|
+
<summary class="case-summary"><span class="case-id">BE-PD-010</span><span class="case-title">list_default_pagination</span><span class="case-meta">失败 · AssertionError</span><span class="badge fail">FAIL</span></summary>
|
|
306
|
+
<div class="case-body">
|
|
307
|
+
<div class="case-box"><h3>失败原因</h3><div>列表记录包含 <code>nodeList: null</code>,违反字段安全契约</div></div>
|
|
308
|
+
<div class="case-box"><h3>自动化脚本</h3><pre>testcase/test_process_definition_list.py::test_BE_PD_010_list_default_pagination</pre></div>
|
|
309
|
+
<div class="case-box"><h3>请求参数</h3><pre>POST /mc-coms/redirect/api/forward
|
|
310
|
+
→ mc-bpm/process-definition/list
|
|
311
|
+
(分页默认参数)</pre></div>
|
|
312
|
+
<div class="case-box"><h3>响应结果</h3><pre>200 OK
|
|
313
|
+
list[i].nodeList = null ← 违反契约
|
|
314
|
+
assert 'nodeList' not in item → FAILED</pre></div>
|
|
315
|
+
</div>
|
|
316
|
+
</details>
|
|
317
|
+
</section>
|
|
318
|
+
|
|
319
|
+
<p class="footnote">报告由 backend-test DAG 节点 8(backend-test-report-and-l5-pi)基于本轮真实执行产物生成。证据:<code>reports/backend-test.html</code> · <code>reports/backend-test.md</code> · <code>reports/backend-test-facts.md</code>。L-5 判定依据:pass=100%、AC=100%、automation≥90%、line≥80%、branch≥70%、skipped=0、无阻断级 Critical 风险。</p>
|
|
320
|
+
</main>
|
|
321
|
+
</body>
|
|
322
|
+
</html>
|
package/package.json
CHANGED
|
@@ -31,6 +31,8 @@ Leaf DAG nodes 不得递归启动 `agent-worker`。Worker 负责 DAG 之外的 s
|
|
|
31
31
|
|
|
32
32
|
## Feature and Task Pool Flow
|
|
33
33
|
|
|
34
|
+
0. **新建 Packet(确定性脚手架,无模型)** — 包内自洽说明见下节 *Feature Packet Scaffold*;不依赖 website 文档站。
|
|
35
|
+
|
|
34
36
|
1. 阅读 Feature Packet,校验其 TaskSpecs 与 dependency graph。
|
|
35
37
|
2. 从持久化的 Task Pool state 推导下一步动作;不要从 chat history 重建 lifecycle state。canonical state 键是 `{ featureId, taskId }`(路径 `.harness/task-pool/states/<featureId>/<taskId>.json`)。
|
|
36
38
|
3. 对可写 batch 只冻结一次 controller,并将其 identity 传播到下游 evidence。
|
|
@@ -55,6 +57,88 @@ Leaf DAG nodes 不得递归启动 `agent-worker`。Worker 负责 DAG 之外的 s
|
|
|
55
57
|
8. Inspect(原 Observe)只读:推荐 `agent-worker console serve` 的 `/inspect/#/...`;兼容 `observe serve|snapshot`。canonical Task 路由为 `/api/features/:featureId/tasks/:taskId` 与 `#/feature/:featureId/task/:taskId`。8790 `/api/health` 为 `OperatorSurfaceHealthV1`;8787 仍为 `ObserveHealthV1`。
|
|
56
58
|
9. Official Console:`agent-worker console serve|doctor`(默认 loopback;可 `--host 0.0.0.0` / `--debug`)。Recovery CTA 为 report/doctor/decision/resume/reconcile/regenerate/打开检视;无 Cancel、无主 CTA「直接改代码」。主会话 Compatibility Assist 不得替代 Console/CLI 执法。
|
|
57
59
|
|
|
60
|
+
## Feature Packet Scaffold
|
|
61
|
+
|
|
62
|
+
确定性入口:一个纯 BE/FE 需求 → 一个 `features/F-YYYY-NNN/` Packet → Task Pool 串行掘进。主会话只跑 CLI,不手写 TaskGraph。
|
|
63
|
+
|
|
64
|
+
### 边界(v1)
|
|
65
|
+
|
|
66
|
+
| 做 | 不做 |
|
|
67
|
+
| --- | --- |
|
|
68
|
+
| 模板 + 槽位确定性生成 | 一键 LLM 生成完整合同 |
|
|
69
|
+
| `profile: generic` 短图 | 默认 `fullstack-v1` / 复制 `F-2026-005` 全图 |
|
|
70
|
+
| 显式 `--verify-command` | 猜测项目测试命令 |
|
|
71
|
+
| 一需求一 Feature 目录 | 跨 Feature 自动 depends / 并行 Pool |
|
|
72
|
+
| 写盘前同源 `task validate-feature` | 读/写 `.harness/**` 或构造 `LoopAgentClient` |
|
|
73
|
+
|
|
74
|
+
### 三模板
|
|
75
|
+
|
|
76
|
+
| 模板 | 最小图 |
|
|
77
|
+
| --- | --- |
|
|
78
|
+
| `backend-only` | `BE-IMPL-001`(需 ≥1 `--be-path`) |
|
|
79
|
+
| `frontend-only` | `FE-IMPL-001`(需 ≥1 `--fe-path`) |
|
|
80
|
+
| `fe-with-api` | `CONTRACT-001` → `BE-IMPL-001` + `FE-IMPL-001`(consumers 仅实现节点;两端 path 都要) |
|
|
81
|
+
|
|
82
|
+
v1 **不**生成 `BE-TEST` / `FE-TEST` / `FINAL-VERIFY`。`feature_id` 强制 `F-YYYY-NNN`(≥3 位序号)。输出固定 `<repo>/features/<feature-id>`;无 `--force` / `--out`;已存在目录(含空目录)一律拒绝。
|
|
83
|
+
|
|
84
|
+
### 日常命令
|
|
85
|
+
|
|
86
|
+
```text
|
|
87
|
+
# 可选 dry-run:完整 parse/render/validate,零写入
|
|
88
|
+
agent-worker feature scaffold --repo <repo> --template backend-only \
|
|
89
|
+
--feature-id F-2026-010 --title "..." \
|
|
90
|
+
--be-path services/example/** \
|
|
91
|
+
--verify-command "npm run typecheck" --verify-command "npm test" \
|
|
92
|
+
--dry-run --json
|
|
93
|
+
|
|
94
|
+
agent-worker feature scaffold --repo <repo> --template frontend-only \
|
|
95
|
+
--feature-id F-2026-011 --title "..." \
|
|
96
|
+
--fe-path apps/web/src/settings/** \
|
|
97
|
+
--verify-command "npm test" --json
|
|
98
|
+
|
|
99
|
+
agent-worker feature scaffold --repo <repo> --template fe-with-api \
|
|
100
|
+
--feature-id F-2026-012 --title "..." \
|
|
101
|
+
--be-path services/api/** --fe-path apps/web/src/api/** \
|
|
102
|
+
[--contract-path docs/contracts/F-2026-012/api.md] \
|
|
103
|
+
--verify-command "npm test" --json
|
|
104
|
+
|
|
105
|
+
# 机器门禁 → 只读决策 → 串行掘进(固定 published controller)
|
|
106
|
+
agent-worker task validate-feature features/F-2026-010
|
|
107
|
+
agent-worker feature review --feature-dir features/F-2026-010 --repo <repo> --json
|
|
108
|
+
agent-worker feature run --feature-dir features/F-2026-010 --repo <repo> \
|
|
109
|
+
--loop-agent-bin <published> \
|
|
110
|
+
--expected-controller-version <version> \
|
|
111
|
+
--expected-controller-fingerprint sha256:<hex> \
|
|
112
|
+
--git-mode checkpoint --limit 1 --json
|
|
113
|
+
|
|
114
|
+
# Failed 只走官方恢复
|
|
115
|
+
agent-worker task retry <taskId> --feature-id F-2026-010 --repo <repo> --reason "..."
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
### Batch
|
|
119
|
+
|
|
120
|
+
```text
|
|
121
|
+
agent-worker feature scaffold --repo <repo> --batch <yaml-or-json> [--dry-run] [--json]
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- 与单条 flags 互斥;每条必须显式 `feature_id` / `title` / `template` / `verify_commands`。
|
|
125
|
+
- 任一非法、冲突、目标已存在或写盘失败 → **整批零写入**(已提交目录回滚)。
|
|
126
|
+
- 示例形状(包内模板若存在):`docs/templates/product-line/feature-scaffold-batch.example.yaml`。
|
|
127
|
+
- 三模板生成快照(只读、防漂移,非 live Feature):`docs/templates/product-line/scaffold-samples/{backend-only,frontend-only,fe-with-api}/`。
|
|
128
|
+
|
|
129
|
+
### 多需求策略
|
|
130
|
+
|
|
131
|
+
1. 一个需求条目 → 一个 Feature 目录。
|
|
132
|
+
2. 多个 FE/BE 需求:batch scaffold 后 **串行** `feature run --limit 1`(先完 F-010 再 F-011)。
|
|
133
|
+
3. 后端可独立交付时:先 `backend-only`,再 `frontend-only`(跨 Feature 依赖只写文档,不做自动 depends_on)。
|
|
134
|
+
4. 同 Feature 内 BE+FE 原子交付用 `fe-with-api`。
|
|
135
|
+
|
|
136
|
+
### 内容与完成定义
|
|
137
|
+
|
|
138
|
+
- scaffold 只给骨架;`requirement.md` / AC 文案由人或后续「只填槽、不改 graph」skill 填充。
|
|
139
|
+
- v1 完成 = Packet 可 scaffold 且 Pool 可掘进到图内 Task **Done**;`verify-final` / Delivery / Closeout 为 v1.5(ADR 0007),非 scaffold 必经。
|
|
140
|
+
- 已知恢复限制:mid-run `SIGKILL` 可能导致 Pool `Running` 且 `runs.jsonl` 缺失时 reconcile 失败(FC-B);勿对 worker 随意 SIGKILL;Failed 后用 `task retry`。
|
|
141
|
+
|
|
58
142
|
## Versioned Self-Hosting
|
|
59
143
|
|
|
60
144
|
- Published version N 是整个 maintenance batch 的 controller;不要在任务中途切换。
|
|
@@ -6,8 +6,8 @@ Pre-write nodes are read-only. Preserve IDs, labels, commands, language, require
|
|
|
6
6
|
|
|
7
7
|
- **`frontend-contract-pi`**: `Scope`, `Non-goals`, `Acceptance Criteria`, `UI States`, `Target Runtime Environment`, `Risks`, `Verification Expectations`. No guessed requirements.
|
|
8
8
|
- **`frontend-scout-pi`**: routes, components, tokens, data/API/Mock, scripts, tests, assets. Fact vs inference vs gap. Query the knowledge base when available and always search+read `openspec/schemas/`, `openspec/project-specs/`, and `ai_workspace/` before repo fallback. Output stack, routes, components, styling, conventions, state/data, test entry points, reuse, risks.
|
|
9
|
-
- **`frontend-plan-pi` + conditional design loop**: AC → explicit observable `expectedOutcome`, interactions → explicit `trigger` + `expectedBehavior`, then steps, in-bound files, applicable UI states, reuse, deps, Mock/API strategy, activation/rollback, frozen verify entrypoints, real-integration gap, and exactly one `frontend-implementation-contract-v1` JSON object. IDs plus file paths are not sufficient behavior semantics. Use `uiStates: []` for logic-only changes with no user-visible UI state; do not invent UI states. Applicable states require behavior/implementation/verification, while non-applicable states require a reason and omit empty behavior placeholders. Prefer native Mock; browser intercept only with existing e2e; request-adapter only for a reversible seam. `auto`
|
|
10
|
-
- **`frontend-prewrite-gate-shell`**: the sole write authorization. Resolve effective plan/review, require exact pass, retain every REQ/BR/AC id, enforce Mock policy, validate schema/source binding, and materialize `contracts/frontend-implementation-contract.json`. Fallback is allowed only when a conditional primary is absent; an existing malformed primary fails closed. Generation-time blocked Mock produces one deterministic blocking shell node and no writer.
|
|
9
|
+
- **`frontend-plan-pi` + conditional design loop**: AC → explicit observable `expectedOutcome`, interactions → explicit `trigger` + `expectedBehavior`, then steps, in-bound files, applicable UI states, reuse, deps, Mock/API strategy, activation/rollback, frozen verify entrypoints, real-integration gap, and exactly one `frontend-implementation-contract-v1` JSON object. IDs plus file paths are not sufficient behavior semantics. Use `uiStates: []` for logic-only changes with no user-visible UI state; do not invent UI states. Applicable states require behavior/implementation/verification, while non-applicable states require a reason and omit empty behavior placeholders. Prefer native Mock; browser intercept only with existing e2e; request-adapter only for a reversible seam. `auto` with absent/ambiguous project Mock capability must select `not-needed`, keep real requests default, and record the gap; `required` cannot select `not-needed`. Initial design pass uses the original plan; only exact `request-revision` runs read-only revision plus final review. Small-risk runs one design review only.
|
|
10
|
+
- **`frontend-prewrite-gate-shell`**: the sole write authorization. Resolve effective plan/review, require exact pass, retain every REQ/BR/AC id, enforce Mock policy, validate schema/source binding and writeSet containment, and materialize `contracts/frontend-implementation-contract.json`. A planned fixture or consumer may be a future writer output and need not exist before authorization. Fallback is allowed only when a conditional primary is absent; an existing malformed primary fails closed. Generation-time blocked Mock produces one deterministic blocking shell node and no writer.
|
|
11
11
|
- **`frontend-implement-pi`**: sole regular exclusive writer and consumer of `frontend-bounded-implement`, not this discovery skill. Stay in `writeSet`; real requests default-on; Mock reversible, dev/test-only, production-off. Atomic handler/intercept/adapter with consumer+tests. Stop on forbidden paths or guesses. First line must be `IMPLEMENTATION_OUTCOME: changed|already-satisfied|blocked`; runtime checks it against the attributed diff. Optional mock-verify when frozen; static+behavior always; behavior must prove page consumption. Skipped-Mock `not-needed` keeps real integration pending unless the real backend path has fresh evidence.
|
|
12
12
|
|
|
13
13
|
## Contract / trace / stages (M1–M2)
|
|
@@ -13,13 +13,12 @@ references:
|
|
|
13
13
|
|
|
14
14
|
# loop-agent Workflow
|
|
15
15
|
|
|
16
|
-
Entry
|
|
16
|
+
Entry: routing and hard rules. Required details come from frontmatter references;`command-reference.md` stays optional below.
|
|
17
17
|
|
|
18
18
|
## 默认立场
|
|
19
19
|
|
|
20
20
|
- 主入口是 **Agent DAG**(经 `loop-agent` / 可选 `agent-worker` CLI)。
|
|
21
|
-
-
|
|
22
|
-
- **主会话 = operator-only**:编排 CLI、审 writeSet、只读 status/doctor/report、记 human gate、跑 Shell verification 与 handoff。
|
|
21
|
+
- 宿主仅作 **Compatibility / Operator Assist**:主会话编排 CLI、审 writeSet、读 status/doctor/report、处理 human gate、验证与 handoff;不写业务代码。
|
|
23
22
|
- **严禁**主会话绕过 CLI 用宿主 Edit/Write 改业务实现,或 CLI 失败后「救火改文件」。
|
|
24
23
|
- DAG `pi` executor 默认 read-only;`toolProfile: "write"` 时为 bounded writer;sidecar 须 per call 收窄。
|
|
25
24
|
- Shell verification 是事实源;长期结论写回 `ai_workspace/loop-agent/`、`docs/decisions/` 或 `skills/`。
|
|
@@ -28,10 +27,12 @@ Entry for `loop-agent`: trigger, routing, hard rules. Details live in `reference
|
|
|
28
27
|
|
|
29
28
|
```bash
|
|
30
29
|
loop-agent new-task <task-id> "Title"
|
|
31
|
-
# Prefer
|
|
32
|
-
|
|
33
|
-
loop-agent dag
|
|
34
|
-
|
|
30
|
+
# Prefer import-prd when a PRD exists; plan create for non-trivial work
|
|
31
|
+
# (see references/source-and-plan-practice.md)
|
|
32
|
+
loop-agent dag run-task <task-id> --profile auto --strict-models
|
|
33
|
+
# default draft: .harness/tasks/<task-id>/dag.json
|
|
34
|
+
loop-agent dag validate --dag .harness/tasks/<task-id>/dag.json --strict-models --strict-governance
|
|
35
|
+
loop-agent run-dag --dag .harness/tasks/<task-id>/dag.json --cwd <repo-root>
|
|
35
36
|
```
|
|
36
37
|
|
|
37
38
|
执行前审阅 `profileRouting`、`governanceProfile`、writer `writeSet`、`forbiddenPaths`、decision gate mode。
|
|
@@ -45,19 +46,16 @@ loop-agent run-dag --dag <dag.json> --cwd <repo-root>
|
|
|
45
46
|
| Operator commands、`agent-worker` | `references/command-reference.md` |
|
|
46
47
|
| 独立验证、failure handling、closeout | `references/verification-and-failure-handling.md` |
|
|
47
48
|
|
|
48
|
-
## Source Layout
|
|
49
|
-
|
|
50
|
-
CLI `src/cli/`;DAG `src/workflows/dag/`;loop `src/workflows/loop/`;executors `src/executors/`;worker `src/worker/`;governance `src/governance/`。不新增平行兼容入口。
|
|
51
|
-
|
|
52
49
|
## Hard Rules
|
|
53
50
|
|
|
54
|
-
1.
|
|
51
|
+
1. Use vertical tracer bullets across real integration layers;each needs independent acceptance and verification.
|
|
55
52
|
2. Autonomy ≠ governance profile: declare AFK/HITL in human gate; choose `--profile` by risk.
|
|
56
53
|
3. Source materials mandatory: `source/需求.md`、`source/执行约束.md`、优先 `source/references/*` originals。
|
|
57
|
-
4.
|
|
58
|
-
5.
|
|
59
|
-
6.
|
|
60
|
-
7.
|
|
54
|
+
4. Structured task config only: `referenceDocs` uses `{ path, name? }[]`, never a string array;`verifyCommands` uses `{ label, command, timeoutMs? }[]`, never a string array。
|
|
55
|
+
5. Agent DAG is the implementation workflow;review three-way checks references + derived source + implementation。
|
|
56
|
+
6. 主会话不绕过 CLI 直接写业务代码;失败只走 doctor/reconcile/human gate/重跑。
|
|
57
|
+
7. DAG `pi` executor read-only unless `toolProfile: "write"`;completed run facts read-only;不得从 read-only DAG/sidecar 写 root `artifacts/`。
|
|
58
|
+
8. No hidden state in chat only;verify before completion.
|
|
61
59
|
|
|
62
60
|
## References
|
|
63
61
|
|