vibe-coding-master 0.7.21 → 0.7.22
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/dist/backend/services/gate-review-service.js +3 -1
- package/dist/backend/templates/handoff.js +22 -0
- package/dist/backend/templates/harness/gate-review.js +33 -5
- package/dist/backend/templates/harness/tester-agent.js +76 -5
- package/dist/shared/validation/artifact-check.js +53 -1
- package/package.json +1 -1
|
@@ -33,7 +33,9 @@ const VALIDATION_ANALYSIS_FIELDS = [
|
|
|
33
33
|
"Changed Behavior And Risk",
|
|
34
34
|
"Coverage Mapping",
|
|
35
35
|
"Baseline Coverage",
|
|
36
|
-
"Integration
|
|
36
|
+
"L2 Integration Coverage",
|
|
37
|
+
"L3 Trigger Assessment",
|
|
38
|
+
"L3 End-To-End Coverage",
|
|
37
39
|
"Boundary And Failure Coverage",
|
|
38
40
|
"Public Contract Coverage",
|
|
39
41
|
"Test Integrity",
|
|
@@ -157,6 +157,28 @@ TBD
|
|
|
157
157
|
|
|
158
158
|
TBD
|
|
159
159
|
|
|
160
|
+
## L3 Coverage
|
|
161
|
+
|
|
162
|
+
L3 Required: yes|no
|
|
163
|
+
|
|
164
|
+
### Trigger Assessment
|
|
165
|
+
|
|
166
|
+
TBD
|
|
167
|
+
|
|
168
|
+
### Affected End-To-End Flows
|
|
169
|
+
|
|
170
|
+
| Flow | Trigger | Case ID | Test File | Entry Point | Final Observable Result | Action | Result |
|
|
171
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
172
|
+
| TBD | TBD | TBD | TBD | TBD | TBD | TBD | TBD |
|
|
173
|
+
|
|
174
|
+
### L3 Commands And Evidence
|
|
175
|
+
|
|
176
|
+
TBD
|
|
177
|
+
|
|
178
|
+
### Not-Required Evidence
|
|
179
|
+
|
|
180
|
+
TBD
|
|
181
|
+
|
|
160
182
|
## Commands Run Or Checked
|
|
161
183
|
|
|
162
184
|
TBD
|
|
@@ -150,6 +150,31 @@ UI, CLI/tooling, hook, session,
|
|
|
150
150
|
persistence, worktree, external-process, and other important user or system
|
|
151
151
|
paths have integration or E2E coverage that exercises real behavior.
|
|
152
152
|
|
|
153
|
+
Independently apply the Tester L3 trigger rules to the accepted task, actual
|
|
154
|
+
production changes, public contracts, and documented L3 flows. Do not accept
|
|
155
|
+
\`L3 Required: no\` merely because Tester selected it.
|
|
156
|
+
|
|
157
|
+
For every affected end-to-end flow:
|
|
158
|
+
|
|
159
|
+
- Verify that the trigger assessment matches the actual production path.
|
|
160
|
+
- Inspect the actual L3 test file and case.
|
|
161
|
+
- Verify that the case starts from the documented system entry point and reaches
|
|
162
|
+
the final observable result through the project-owned production path.
|
|
163
|
+
- Verify that internal production wiring is not mocked, replaced, or bypassed.
|
|
164
|
+
- Verify that the assertions directly cover the changed behavior and any changed
|
|
165
|
+
failure, retry, recovery, or lifecycle path.
|
|
166
|
+
- Verify that an existing case was updated when its prior assertions did not
|
|
167
|
+
cover the change.
|
|
168
|
+
- Verify the recorded command and result.
|
|
169
|
+
|
|
170
|
+
Request changes when required L3 coverage is missing, replaced by L2, not
|
|
171
|
+
executed, mapped only to an old case without relevant assertions, bypasses the
|
|
172
|
+
production path, or is classified as unnecessary without satisfying every
|
|
173
|
+
not-required condition.
|
|
174
|
+
|
|
175
|
+
A required L3 gap is acceptable only when \`test-report.md\` contains the user's
|
|
176
|
+
exact approval for that specific Coverage Gap.
|
|
177
|
+
|
|
153
178
|
Inspect boundary, failure, cancellation, retry, restart, recovery,
|
|
154
179
|
concurrency, repeated-action, stale-state, cleanup, and compatibility paths
|
|
155
180
|
when they are relevant to the changed behavior. Check that tests were not
|
|
@@ -160,9 +185,8 @@ Do not approve only because \`Test Result: pass\` or all recorded commands are
|
|
|
160
185
|
green. Request changes when the report is incomplete or inconsistent with the
|
|
161
186
|
actual tests, validation level does not match risk, an important behavior has
|
|
162
187
|
no concrete coverage mapping, a required check was skipped, required coverage
|
|
163
|
-
is unavailable, or a current-task coverage gap remains.
|
|
164
|
-
|
|
165
|
-
required coverage without exact user approval is not an approval reason.
|
|
188
|
+
is unavailable, or a current-task coverage gap remains. Required coverage
|
|
189
|
+
without exact user approval is not an approval reason.
|
|
166
190
|
|
|
167
191
|
Treat every unresolved required-coverage item as gate-blocking unless
|
|
168
192
|
\`test-report.md\` contains the user's exact approval routed by project-manager.
|
|
@@ -278,7 +302,9 @@ Use this findings structure:
|
|
|
278
302
|
- Changed Behavior And Risk:
|
|
279
303
|
- Coverage Mapping:
|
|
280
304
|
- Baseline Coverage:
|
|
281
|
-
- Integration
|
|
305
|
+
- L2 Integration Coverage:
|
|
306
|
+
- L3 Trigger Assessment:
|
|
307
|
+
- L3 End-To-End Coverage:
|
|
282
308
|
- Boundary And Failure Coverage:
|
|
283
309
|
- Public Contract Coverage:
|
|
284
310
|
- Test Integrity:
|
|
@@ -339,7 +365,9 @@ If there are no findings, write:
|
|
|
339
365
|
- Changed Behavior And Risk:
|
|
340
366
|
- Coverage Mapping:
|
|
341
367
|
- Baseline Coverage:
|
|
342
|
-
- Integration
|
|
368
|
+
- L2 Integration Coverage:
|
|
369
|
+
- L3 Trigger Assessment:
|
|
370
|
+
- L3 End-To-End Coverage:
|
|
343
371
|
- Boundary And Failure Coverage:
|
|
344
372
|
- Public Contract Coverage:
|
|
345
373
|
- Test Integrity:
|
|
@@ -29,9 +29,7 @@ ${renderRoleMemoryRules("tester")}
|
|
|
29
29
|
- If required L0/L1 coverage is missing or weak, add or update the required tests. If the coverage cannot be completed, return \`Test Result: fail\` with concrete blocking evidence.
|
|
30
30
|
- Own L2/L3/L4 final-validation design, execution, and acceptance evidence.
|
|
31
31
|
- Targeted diagnostic L2 checks run by Coder or Architect are implementation evidence only and do not replace Tester final validation.
|
|
32
|
-
-
|
|
33
|
-
- For important new behavior, public workflows, cross-module behavior, UI/CLI/tooling flows, persistence/session/worktree behavior, hooks, or external process behavior, add a new integration/E2E case or extend an existing one with assertions that directly cover the new behavior.
|
|
34
|
-
- Do not treat an existing integration/E2E command as sufficient unless it includes assertions for the new behavior or important regression path. Add or modify the required case; inability to complete required coverage makes \`Test Result: fail\`.
|
|
32
|
+
- Use L2 integration coverage when changed behavior crosses internal module or component boundaries and can be completely proved from a stable integration entry point without triggering the mandatory L3 rules below.
|
|
35
33
|
- When tests were changed during the task, check whether assertions were weakened, removed, over-mocked, or rewritten to match the implementation instead of the approved behavior. Report this as a validation gap unless the approved contract changed.
|
|
36
34
|
- Apply \`docs/CODING_STANDARDS.md\` to changed tests, fixtures, test-only helpers, baseline-test coverage, and test integrity.
|
|
37
35
|
- Before final validation, perform a full cache cleanup, then rerun validation from a clean state.
|
|
@@ -51,7 +49,6 @@ ${renderRoleMemoryRules("tester")}
|
|
|
51
49
|
- Add anti-hardcode coverage when risk warrants it: use non-fixture inputs, boundary values, negative cases, repeated actions, and assertions through public/runtime paths.
|
|
52
50
|
- Do not accept tests that only prove the current implementation shape; tests must prove the approved behavior contract.
|
|
53
51
|
- Treat architect-flagged public contracts, migrations, auth, data flow, routing, or dependency changes as inputs for tester-owned validation design.
|
|
54
|
-
- Record skipped L3 checks in \`.ai/vcm/handoffs/test-report.md\` with the reason.
|
|
55
52
|
- Treat validation coverage gaps for accepted task scope, changed behavior, or required public contracts as blocking validation issues; \`Test Result: pass\` cannot include them.
|
|
56
53
|
- Before exact user approval is routed by project-manager, record missing required coverage under \`Blocking Validation Issues\`, keep \`Coverage Gaps\` as \`None\`, and return \`Test Result: fail\`.
|
|
57
54
|
- Add a Coverage Gap only after project-manager routes the user's exact approval for that specific unresolved gap. Record the approval verbatim in \`User Approval Evidence\`.
|
|
@@ -59,6 +56,59 @@ ${renderRoleMemoryRules("tester")}
|
|
|
59
56
|
- If a required validation check is skipped or cannot complete, \`Test Result\` must be \`fail\`.
|
|
60
57
|
- Update \`docs/TESTING.md\` when validation strategy, commands, level mapping, integration/E2E case definitions, selection rules, final-validation cleanup, test gaps, or test expectations change.
|
|
61
58
|
|
|
59
|
+
### Mandatory L3 End-To-End Coverage
|
|
60
|
+
|
|
61
|
+
L3 validates a complete externally observable flow from a project-defined
|
|
62
|
+
system entry point, through the actual project-owned production path, to its
|
|
63
|
+
final observable result.
|
|
64
|
+
|
|
65
|
+
Do not mock, replace, or bypass the project-owned production path being
|
|
66
|
+
validated. External dependencies may use controlled substitutes only when
|
|
67
|
+
allowed by \`docs/TESTING.md\`.
|
|
68
|
+
|
|
69
|
+
L3 is required when any of the following is true:
|
|
70
|
+
|
|
71
|
+
- The accepted task adds a new externally reachable end-to-end flow.
|
|
72
|
+
- The task changes the input, output, error result, persisted result, external
|
|
73
|
+
side effect, or other observable behavior of an end-to-end flow.
|
|
74
|
+
- The changed production path is covered by an existing L3 case in
|
|
75
|
+
\`docs/TESTING.md\`.
|
|
76
|
+
- The task changes completion, failure, cancellation, retry, recovery, timeout,
|
|
77
|
+
idempotency, duplicate-event, or out-of-order behavior that affects the final
|
|
78
|
+
result of an end-to-end flow.
|
|
79
|
+
- The task changes a public API, event, message, storage, migration, or other
|
|
80
|
+
external contract used by an end-to-end flow.
|
|
81
|
+
- The task changes a cross-component critical invariant that can be proved only
|
|
82
|
+
through the complete production path.
|
|
83
|
+
- The task fixes a defect that passed L1/L2 but occurred in an integrated,
|
|
84
|
+
staging, production, or other complete-system flow.
|
|
85
|
+
|
|
86
|
+
L3 is not required only when all of the following are true:
|
|
87
|
+
|
|
88
|
+
- No externally observable end-to-end behavior is added or changed.
|
|
89
|
+
- No production path covered by a documented L3 case is affected.
|
|
90
|
+
- No end-to-end lifecycle, external contract, or critical invariant is changed.
|
|
91
|
+
- L1 or L2 can completely prove the accepted behavior from a stable test entry
|
|
92
|
+
point.
|
|
93
|
+
|
|
94
|
+
Task size, changed-file count, implementation size, existing unit tests, or a
|
|
95
|
+
green L2 result are not reasons to skip required L3 coverage.
|
|
96
|
+
|
|
97
|
+
For every affected end-to-end flow:
|
|
98
|
+
|
|
99
|
+
- Run an existing L3 case when its assertions already cover the changed behavior.
|
|
100
|
+
- Update an existing L3 case when the flow is covered but the changed behavior
|
|
101
|
+
is not asserted.
|
|
102
|
+
- Add a new L3 case when the task creates a new flow or no existing case covers
|
|
103
|
+
it.
|
|
104
|
+
- Add or update assertions for any failure, retry, recovery, or lifecycle path
|
|
105
|
+
changed by the task.
|
|
106
|
+
|
|
107
|
+
Required L3 coverage cannot be replaced by L2. If the required case cannot be
|
|
108
|
+
added or executed, return \`Test Result: fail\` and record the missing coverage as
|
|
109
|
+
a blocking validation issue unless the user has explicitly approved that exact
|
|
110
|
+
Coverage Gap.
|
|
111
|
+
|
|
62
112
|
### Testing Documentation
|
|
63
113
|
|
|
64
114
|
- Own \`docs/TESTING.md\` as the project's current validation strategy, not as a task log or diagnostic history.
|
|
@@ -76,6 +126,27 @@ ${renderRoleMemoryRules("tester")}
|
|
|
76
126
|
### Outputs
|
|
77
127
|
|
|
78
128
|
- Write \`.ai/vcm/handoffs/test-report.md\` with \`Test Result: pass|fail\`, evidence reviewed, tests added or updated, coverage mapping, commands run or checked, validation results, failed expectations, reproduction steps, skipped checks with reasons, coverage gaps, blocking validation issues, and user approval evidence.
|
|
129
|
+
- \`test-report.md\` must include this L3 section:
|
|
130
|
+
|
|
131
|
+
\`\`\`md
|
|
132
|
+
## L3 Coverage
|
|
133
|
+
|
|
134
|
+
L3 Required: yes|no
|
|
135
|
+
|
|
136
|
+
### Trigger Assessment
|
|
137
|
+
|
|
138
|
+
### Affected End-To-End Flows
|
|
139
|
+
|
|
140
|
+
| Flow | Trigger | Case ID | Test File | Entry Point | Final Observable Result | Action | Result |
|
|
141
|
+
| --- | --- | --- | --- | --- | --- | --- | --- |
|
|
142
|
+
|
|
143
|
+
### L3 Commands And Evidence
|
|
144
|
+
|
|
145
|
+
### Not-Required Evidence
|
|
146
|
+
\`\`\`
|
|
147
|
+
|
|
148
|
+
- When \`L3 Required: yes\`, include at least one complete flow-to-case mapping. \`Action\` must be \`run-existing\`, \`updated\`, or \`added\`.
|
|
149
|
+
- When \`L3 Required: no\`, use \`Not-Required Evidence\` to prove every condition in the L3 not-required rule.
|
|
79
150
|
- In Validation-Only Flow, if tests, fixtures, test-only helpers, or \`docs/TESTING.md\` changed, commit those changes before reporting and record the changed files and commit in \`test-report.md\`. If no tracked files changed, record that no commit was required.
|
|
80
151
|
- \`test-report.md\` is the current validation evidence, not a log; when rewriting it, carry forward still-unresolved findings or explicitly mark them resolved instead of dropping them.
|
|
81
152
|
- In \`Coverage Mapping\`, map each accepted changed behavior or relevant risk to its validation level, actual test file and case or external evidence, exercised entry path and key assertions, result, and any remaining gap.
|
|
@@ -85,7 +156,7 @@ ${renderRoleMemoryRules("tester")}
|
|
|
85
156
|
- When \`Test Result: fail\`, \`Blocking Validation Issues\` must list concrete blocking evidence.
|
|
86
157
|
- When \`Coverage Gaps\` is not \`None\`, \`Test Result\` must be \`fail\`, \`User Approval Evidence\` must contain the user's exact authorization, and every recorded gap must match that authorization.
|
|
87
158
|
- When no gap has been approved, \`User Approval Evidence\` must be \`None\`.
|
|
88
|
-
- For feature or cross-boundary changes,
|
|
159
|
+
- For feature or cross-boundary changes, map required L2 integration coverage and mandatory L3 coverage separately. If required coverage is unavailable, report it as a blocking issue.
|
|
89
160
|
- For changed or newly added tests, state why the assertions prove real behavior rather than fixture-specific, implementation-specific, or mock-only behavior.
|
|
90
161
|
- Report confirmed unresolved issues that should survive current-task cleanup in \`.ai/vcm/handoffs/test-report.md\`; do not write \`.ai/vcm/handoffs/known-issues.md\` (architect-owned).
|
|
91
162
|
|
|
@@ -39,6 +39,11 @@ const REQUIRED_HEADINGS = {
|
|
|
39
39
|
"Evidence Reviewed",
|
|
40
40
|
"Tests Added Or Updated",
|
|
41
41
|
"Coverage Mapping",
|
|
42
|
+
"L3 Coverage",
|
|
43
|
+
"Trigger Assessment",
|
|
44
|
+
"Affected End-To-End Flows",
|
|
45
|
+
"L3 Commands And Evidence",
|
|
46
|
+
"Not-Required Evidence",
|
|
42
47
|
"Commands Run Or Checked",
|
|
43
48
|
"Validation Results",
|
|
44
49
|
"Failed Expectations",
|
|
@@ -139,6 +144,28 @@ function validateArtifactFields(kind, content) {
|
|
|
139
144
|
const invalidFields = result === "pass" || result === "fail"
|
|
140
145
|
? []
|
|
141
146
|
: ["Test Result must be pass or fail."];
|
|
147
|
+
const l3Required = /^\s*L3 Required\s*:\s*(\S+)\s*$/im.exec(content)?.[1]?.toLowerCase();
|
|
148
|
+
if (l3Required !== "yes" && l3Required !== "no") {
|
|
149
|
+
invalidFields.push("L3 Required must be yes or no.");
|
|
150
|
+
}
|
|
151
|
+
const l3TriggerAssessment = readArtifactSectionValue(content, "Trigger Assessment");
|
|
152
|
+
const l3AffectedFlows = readArtifactSectionContent(content, "Affected End-To-End Flows");
|
|
153
|
+
const l3Commands = readArtifactSectionValue(content, "L3 Commands And Evidence");
|
|
154
|
+
const l3NotRequiredEvidence = readArtifactSectionValue(content, "Not-Required Evidence");
|
|
155
|
+
if (l3Required === "yes") {
|
|
156
|
+
if (!hasSubstantiveSectionValue(l3TriggerAssessment)) {
|
|
157
|
+
invalidFields.push("Trigger Assessment is required when L3 Required is yes.");
|
|
158
|
+
}
|
|
159
|
+
if (!hasCompleteL3FlowMapping(l3AffectedFlows)) {
|
|
160
|
+
invalidFields.push("Affected End-To-End Flows are required when L3 Required is yes.");
|
|
161
|
+
}
|
|
162
|
+
if (!hasSubstantiveSectionValue(l3Commands)) {
|
|
163
|
+
invalidFields.push("L3 Commands And Evidence are required when L3 Required is yes.");
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
if (l3Required === "no" && !hasSubstantiveSectionValue(l3NotRequiredEvidence)) {
|
|
167
|
+
invalidFields.push("Not-Required Evidence is required when L3 Required is no.");
|
|
168
|
+
}
|
|
142
169
|
const coverageGaps = readArtifactSectionValue(content, "Coverage Gaps");
|
|
143
170
|
const blockingIssues = readArtifactSectionValue(content, "Blocking Validation Issues");
|
|
144
171
|
const userApproval = readArtifactSectionValue(content, "User Approval Evidence");
|
|
@@ -187,6 +214,25 @@ function validateArtifactFields(kind, content) {
|
|
|
187
214
|
}
|
|
188
215
|
return [];
|
|
189
216
|
}
|
|
217
|
+
function hasSubstantiveSectionValue(value) {
|
|
218
|
+
return Boolean(value && !/^(none|tbd)\.?$/i.test(value.trim()));
|
|
219
|
+
}
|
|
220
|
+
function hasCompleteL3FlowMapping(value) {
|
|
221
|
+
if (!value) {
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
const allowedActions = new Set(["run-existing", "updated", "added"]);
|
|
225
|
+
return value
|
|
226
|
+
.split(/\r?\n/)
|
|
227
|
+
.map((line) => line.trim())
|
|
228
|
+
.filter((line) => line.startsWith("|") && line.endsWith("|"))
|
|
229
|
+
.some((line) => {
|
|
230
|
+
const cells = line.slice(1, -1).split("|").map((cell) => cell.trim());
|
|
231
|
+
return cells.length === 8
|
|
232
|
+
&& allowedActions.has(cells[6]?.toLowerCase() ?? "")
|
|
233
|
+
&& cells.every((cell) => Boolean(cell) && !/^(none|tbd)\.?$/i.test(cell));
|
|
234
|
+
});
|
|
235
|
+
}
|
|
190
236
|
function validateDecision(content, allowed) {
|
|
191
237
|
const decision = readArtifactSectionValue(content, "Decision")?.toLowerCase();
|
|
192
238
|
return decision && allowed.includes(decision)
|
|
@@ -194,6 +240,12 @@ function validateDecision(content, allowed) {
|
|
|
194
240
|
: [`Decision must be one of: ${allowed.join(", ")}.`];
|
|
195
241
|
}
|
|
196
242
|
export function readArtifactSectionValue(content, heading) {
|
|
243
|
+
return readArtifactSectionContent(content, heading)
|
|
244
|
+
?.split(/\r?\n/)
|
|
245
|
+
.map((line) => line.trim())
|
|
246
|
+
.find(Boolean);
|
|
247
|
+
}
|
|
248
|
+
function readArtifactSectionContent(content, heading) {
|
|
197
249
|
const match = new RegExp(`^#{1,6}\\s+${escapeRegExp(heading)}\\s*$`, "im").exec(content);
|
|
198
250
|
if (!match || match.index === undefined) {
|
|
199
251
|
return undefined;
|
|
@@ -203,7 +255,7 @@ export function readArtifactSectionValue(content, heading) {
|
|
|
203
255
|
const section = nextHeading?.index === undefined
|
|
204
256
|
? afterHeading
|
|
205
257
|
: afterHeading.slice(0, nextHeading.index);
|
|
206
|
-
return section.
|
|
258
|
+
return section.trim();
|
|
207
259
|
}
|
|
208
260
|
function hasHeading(content, heading) {
|
|
209
261
|
const pattern = new RegExp(`^#{1,6}\\s+${escapeRegExp(heading)}\\s*$`, "im");
|