@substrate-ai/sdlc 0.19.54
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/events.d.ts +336 -0
- package/dist/events.d.ts.map +1 -0
- package/dist/events.js +11 -0
- package/dist/events.js.map +1 -0
- package/dist/gating/conflict-detector.d.ts +59 -0
- package/dist/gating/conflict-detector.d.ts.map +1 -0
- package/dist/gating/conflict-detector.js +101 -0
- package/dist/gating/conflict-detector.js.map +1 -0
- package/dist/gating/dispatch-gate.d.ts +42 -0
- package/dist/gating/dispatch-gate.d.ts.map +1 -0
- package/dist/gating/dispatch-gate.js +197 -0
- package/dist/gating/dispatch-gate.js.map +1 -0
- package/dist/gating/index.d.ts +9 -0
- package/dist/gating/index.d.ts.map +1 -0
- package/dist/gating/index.js +8 -0
- package/dist/gating/index.js.map +1 -0
- package/dist/gating/types.d.ts +98 -0
- package/dist/gating/types.d.ts.map +1 -0
- package/dist/gating/types.js +8 -0
- package/dist/gating/types.js.map +1 -0
- package/dist/handlers/event-bridge.d.ts +56 -0
- package/dist/handlers/event-bridge.d.ts.map +1 -0
- package/dist/handlers/event-bridge.js +140 -0
- package/dist/handlers/event-bridge.js.map +1 -0
- package/dist/handlers/index.d.ts +15 -0
- package/dist/handlers/index.d.ts.map +1 -0
- package/dist/handlers/index.js +14 -0
- package/dist/handlers/index.js.map +1 -0
- package/dist/handlers/sdlc-code-review-handler.d.ts +119 -0
- package/dist/handlers/sdlc-code-review-handler.d.ts.map +1 -0
- package/dist/handlers/sdlc-code-review-handler.js +131 -0
- package/dist/handlers/sdlc-code-review-handler.js.map +1 -0
- package/dist/handlers/sdlc-create-story-handler.d.ts +97 -0
- package/dist/handlers/sdlc-create-story-handler.d.ts.map +1 -0
- package/dist/handlers/sdlc-create-story-handler.js +91 -0
- package/dist/handlers/sdlc-create-story-handler.js.map +1 -0
- package/dist/handlers/sdlc-dev-story-handler.d.ts +121 -0
- package/dist/handlers/sdlc-dev-story-handler.d.ts.map +1 -0
- package/dist/handlers/sdlc-dev-story-handler.js +288 -0
- package/dist/handlers/sdlc-dev-story-handler.js.map +1 -0
- package/dist/handlers/sdlc-phase-handler.d.ts +32 -0
- package/dist/handlers/sdlc-phase-handler.d.ts.map +1 -0
- package/dist/handlers/sdlc-phase-handler.js +166 -0
- package/dist/handlers/sdlc-phase-handler.js.map +1 -0
- package/dist/handlers/types.d.ts +132 -0
- package/dist/handlers/types.d.ts.map +1 -0
- package/dist/handlers/types.js +10 -0
- package/dist/handlers/types.js.map +1 -0
- package/dist/index.d.ts +8 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +14 -0
- package/dist/index.js.map +1 -0
- package/dist/learning/failure-classifier.d.ts +23 -0
- package/dist/learning/failure-classifier.d.ts.map +1 -0
- package/dist/learning/failure-classifier.js +75 -0
- package/dist/learning/failure-classifier.js.map +1 -0
- package/dist/learning/finding-classifier.d.ts +25 -0
- package/dist/learning/finding-classifier.d.ts.map +1 -0
- package/dist/learning/finding-classifier.js +37 -0
- package/dist/learning/finding-classifier.js.map +1 -0
- package/dist/learning/finding-lifecycle.d.ts +69 -0
- package/dist/learning/finding-lifecycle.d.ts.map +1 -0
- package/dist/learning/finding-lifecycle.js +162 -0
- package/dist/learning/finding-lifecycle.js.map +1 -0
- package/dist/learning/finding-store.d.ts +16 -0
- package/dist/learning/finding-store.d.ts.map +1 -0
- package/dist/learning/finding-store.js +26 -0
- package/dist/learning/finding-store.js.map +1 -0
- package/dist/learning/findings-injector.d.ts +34 -0
- package/dist/learning/findings-injector.d.ts.map +1 -0
- package/dist/learning/findings-injector.js +140 -0
- package/dist/learning/findings-injector.js.map +1 -0
- package/dist/learning/index.d.ts +8 -0
- package/dist/learning/index.d.ts.map +1 -0
- package/dist/learning/index.js +10 -0
- package/dist/learning/index.js.map +1 -0
- package/dist/learning/relevance-scorer.d.ts +25 -0
- package/dist/learning/relevance-scorer.d.ts.map +1 -0
- package/dist/learning/relevance-scorer.js +49 -0
- package/dist/learning/relevance-scorer.js.map +1 -0
- package/dist/learning/types.d.ts +55 -0
- package/dist/learning/types.d.ts.map +1 -0
- package/dist/learning/types.js +36 -0
- package/dist/learning/types.js.map +1 -0
- package/dist/orchestrator/graph-orchestrator.d.ts +208 -0
- package/dist/orchestrator/graph-orchestrator.d.ts.map +1 -0
- package/dist/orchestrator/graph-orchestrator.js +213 -0
- package/dist/orchestrator/graph-orchestrator.js.map +1 -0
- package/dist/run-manifest/cli-flags.d.ts +11 -0
- package/dist/run-manifest/cli-flags.d.ts.map +1 -0
- package/dist/run-manifest/cli-flags.js +10 -0
- package/dist/run-manifest/cli-flags.js.map +1 -0
- package/dist/run-manifest/index.d.ts +10 -0
- package/dist/run-manifest/index.d.ts.map +1 -0
- package/dist/run-manifest/index.js +10 -0
- package/dist/run-manifest/index.js.map +1 -0
- package/dist/run-model/cli-flags.d.ts +27 -0
- package/dist/run-model/cli-flags.d.ts.map +1 -0
- package/dist/run-model/cli-flags.js +31 -0
- package/dist/run-model/cli-flags.js.map +1 -0
- package/dist/run-model/index.d.ts +21 -0
- package/dist/run-model/index.d.ts.map +1 -0
- package/dist/run-model/index.js +19 -0
- package/dist/run-model/index.js.map +1 -0
- package/dist/run-model/per-story-state.d.ts +62 -0
- package/dist/run-model/per-story-state.d.ts.map +1 -0
- package/dist/run-model/per-story-state.js +70 -0
- package/dist/run-model/per-story-state.js.map +1 -0
- package/dist/run-model/recovery-history.d.ts +56 -0
- package/dist/run-model/recovery-history.d.ts.map +1 -0
- package/dist/run-model/recovery-history.js +83 -0
- package/dist/run-model/recovery-history.js.map +1 -0
- package/dist/run-model/run-manifest.d.ts +146 -0
- package/dist/run-model/run-manifest.d.ts.map +1 -0
- package/dist/run-model/run-manifest.js +481 -0
- package/dist/run-model/run-manifest.js.map +1 -0
- package/dist/run-model/schemas.d.ts +117 -0
- package/dist/run-model/schemas.d.ts.map +1 -0
- package/dist/run-model/schemas.js +83 -0
- package/dist/run-model/schemas.js.map +1 -0
- package/dist/run-model/supervisor-lock.d.ts +104 -0
- package/dist/run-model/supervisor-lock.d.ts.map +1 -0
- package/dist/run-model/supervisor-lock.js +284 -0
- package/dist/run-model/supervisor-lock.js.map +1 -0
- package/dist/run-model/types.d.ts +74 -0
- package/dist/run-model/types.d.ts.map +1 -0
- package/dist/run-model/types.js +8 -0
- package/dist/run-model/types.js.map +1 -0
- package/dist/run-model/verification-result.d.ts +60 -0
- package/dist/run-model/verification-result.d.ts.map +1 -0
- package/dist/run-model/verification-result.js +55 -0
- package/dist/run-model/verification-result.js.map +1 -0
- package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts +21 -0
- package/dist/verification/checks/acceptance-criteria-evidence-check.d.ts.map +1 -0
- package/dist/verification/checks/acceptance-criteria-evidence-check.js +159 -0
- package/dist/verification/checks/acceptance-criteria-evidence-check.js.map +1 -0
- package/dist/verification/checks/build-check.d.ts +52 -0
- package/dist/verification/checks/build-check.d.ts.map +1 -0
- package/dist/verification/checks/build-check.js +160 -0
- package/dist/verification/checks/build-check.js.map +1 -0
- package/dist/verification/checks/index.d.ts +15 -0
- package/dist/verification/checks/index.d.ts.map +1 -0
- package/dist/verification/checks/index.js +15 -0
- package/dist/verification/checks/index.js.map +1 -0
- package/dist/verification/checks/phantom-review-check.d.ts +29 -0
- package/dist/verification/checks/phantom-review-check.d.ts.map +1 -0
- package/dist/verification/checks/phantom-review-check.js +70 -0
- package/dist/verification/checks/phantom-review-check.js.map +1 -0
- package/dist/verification/checks/trivial-output-check.d.ts +47 -0
- package/dist/verification/checks/trivial-output-check.d.ts.map +1 -0
- package/dist/verification/checks/trivial-output-check.js +72 -0
- package/dist/verification/checks/trivial-output-check.js.map +1 -0
- package/dist/verification/index.d.ts +13 -0
- package/dist/verification/index.d.ts.map +1 -0
- package/dist/verification/index.js +13 -0
- package/dist/verification/index.js.map +1 -0
- package/dist/verification/types.d.ts +149 -0
- package/dist/verification/types.d.ts.map +1 -0
- package/dist/verification/types.js +12 -0
- package/dist/verification/types.js.map +1 -0
- package/dist/verification/verification-pipeline.d.ts +65 -0
- package/dist/verification/verification-pipeline.d.ts.map +1 -0
- package/dist/verification/verification-pipeline.js +149 -0
- package/dist/verification/verification-pipeline.js.map +1 -0
- package/graphs/sdlc-pipeline.dot +42 -0
- package/package.json +22 -0
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* StoredVerificationSummary Zod schemas — Story 52-7.
|
|
3
|
+
*
|
|
4
|
+
* Defines the typed schemas for persisting VerificationSummary results to the
|
|
5
|
+
* run manifest's `per_story_state[storyKey].verification_result` field.
|
|
6
|
+
*
|
|
7
|
+
* Design notes:
|
|
8
|
+
* - These schemas mirror the shape of VerificationSummary / VerificationCheckResult
|
|
9
|
+
* from packages/sdlc/src/verification/types.ts WITHOUT importing from that module.
|
|
10
|
+
* This avoids a circular import between run-model and verification.
|
|
11
|
+
* - `status` uses `z.enum` (closed set) since verification statuses are fixed at
|
|
12
|
+
* `pass|warn|fail` only — distinct from PerStoryStatusSchema which uses the open
|
|
13
|
+
* extensible union pattern from v0.19.6.
|
|
14
|
+
* - All imports use `.js` extensions per monorepo convention.
|
|
15
|
+
*/
|
|
16
|
+
import { z } from 'zod';
|
|
17
|
+
// ---------------------------------------------------------------------------
|
|
18
|
+
// StoredVerificationCheckResultSchema
|
|
19
|
+
// ---------------------------------------------------------------------------
|
|
20
|
+
/**
|
|
21
|
+
* Schema for a single per-check verification result stored in the manifest.
|
|
22
|
+
*
|
|
23
|
+
* Mirrors VerificationCheckResult from packages/sdlc/src/verification/types.ts
|
|
24
|
+
* without importing from that module (avoids circular dependency).
|
|
25
|
+
*/
|
|
26
|
+
export const StoredVerificationCheckResultSchema = z.object({
|
|
27
|
+
/** Human-readable check identifier (e.g. 'BuildCheck', 'TrivialOutputCheck'). */
|
|
28
|
+
checkName: z.string(),
|
|
29
|
+
/** Check outcome status. */
|
|
30
|
+
status: z.enum(['pass', 'warn', 'fail']),
|
|
31
|
+
/** Human-readable details about the check outcome. */
|
|
32
|
+
details: z.string(),
|
|
33
|
+
/** Duration of this check in milliseconds. */
|
|
34
|
+
duration_ms: z.number().nonnegative(),
|
|
35
|
+
});
|
|
36
|
+
// ---------------------------------------------------------------------------
|
|
37
|
+
// StoredVerificationSummarySchema
|
|
38
|
+
// ---------------------------------------------------------------------------
|
|
39
|
+
/**
|
|
40
|
+
* Schema for the aggregated verification pipeline summary stored in the manifest.
|
|
41
|
+
*
|
|
42
|
+
* Mirrors VerificationSummary from packages/sdlc/src/verification/types.ts
|
|
43
|
+
* without importing from that module (avoids circular dependency).
|
|
44
|
+
*/
|
|
45
|
+
export const StoredVerificationSummarySchema = z.object({
|
|
46
|
+
/** Story key that was verified (e.g. '52-7'). */
|
|
47
|
+
storyKey: z.string(),
|
|
48
|
+
/** Per-check results in the order they were executed. */
|
|
49
|
+
checks: z.array(StoredVerificationCheckResultSchema),
|
|
50
|
+
/** Worst-case aggregate status: fail > warn > pass. */
|
|
51
|
+
status: z.enum(['pass', 'warn', 'fail']),
|
|
52
|
+
/** Total duration of the verification pipeline run in milliseconds. */
|
|
53
|
+
duration_ms: z.number().nonnegative(),
|
|
54
|
+
});
|
|
55
|
+
//# sourceMappingURL=verification-result.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"verification-result.js","sourceRoot":"","sources":["../../src/run-model/verification-result.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EAAE,CAAC,EAAE,MAAM,KAAK,CAAA;AAEvB,8EAA8E;AAC9E,sCAAsC;AACtC,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,mCAAmC,GAAG,CAAC,CAAC,MAAM,CAAC;IAC1D,iFAAiF;IACjF,SAAS,EAAE,CAAC,CAAC,MAAM,EAAE;IACrB,4BAA4B;IAC5B,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,sDAAsD;IACtD,OAAO,EAAE,CAAC,CAAC,MAAM,EAAE;IACnB,8CAA8C;IAC9C,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;CACtC,CAAC,CAAA;AAIF,8EAA8E;AAC9E,kCAAkC;AAClC,8EAA8E;AAE9E;;;;;GAKG;AACH,MAAM,CAAC,MAAM,+BAA+B,GAAG,CAAC,CAAC,MAAM,CAAC;IACtD,iDAAiD;IACjD,QAAQ,EAAE,CAAC,CAAC,MAAM,EAAE;IACpB,yDAAyD;IACzD,MAAM,EAAE,CAAC,CAAC,KAAK,CAAC,mCAAmC,CAAC;IACpD,uDAAuD;IACvD,MAAM,EAAE,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,CAAC,CAAC;IACxC,uEAAuE;IACvE,WAAW,EAAE,CAAC,CAAC,MAAM,EAAE,CAAC,WAAW,EAAE;CACtC,CAAC,CAAA"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AcceptanceCriteriaEvidenceCheck.
|
|
3
|
+
*
|
|
4
|
+
* Tier A verification check that compares a story's declared acceptance
|
|
5
|
+
* criteria against structured dev-story output. The check is intentionally
|
|
6
|
+
* deterministic: no LLM calls, no shell commands, no repository inspection.
|
|
7
|
+
*/
|
|
8
|
+
import type { VerificationCheck, VerificationContext, VerificationResult } from '../types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Extract normalized AC ids from story markdown.
|
|
11
|
+
*
|
|
12
|
+
* Supports the BMAD default format (`### AC1:`), explicit references such as
|
|
13
|
+
* `AC: #1`, and plain numbered criteria inside the Acceptance Criteria section.
|
|
14
|
+
*/
|
|
15
|
+
export declare function extractAcceptanceCriteriaIds(storyContent: string): string[];
|
|
16
|
+
export declare class AcceptanceCriteriaEvidenceCheck implements VerificationCheck {
|
|
17
|
+
readonly name = "acceptance-criteria-evidence";
|
|
18
|
+
readonly tier: "A";
|
|
19
|
+
run(context: VerificationContext): Promise<VerificationResult>;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=acceptance-criteria-evidence-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acceptance-criteria-evidence-check.d.ts","sourceRoot":"","sources":["../../../src/verification/checks/acceptance-criteria-evidence-check.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAEV,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,aAAa,CAAA;AA4CpB;;;;;GAKG;AACH,wBAAgB,4BAA4B,CAAC,YAAY,EAAE,MAAM,GAAG,MAAM,EAAE,CAkB3E;AA2BD,qBAAa,+BAAgC,YAAW,iBAAiB;IACvE,QAAQ,CAAC,IAAI,kCAAiC;IAC9C,QAAQ,CAAC,IAAI,EAAG,GAAG,CAAS;IAEtB,GAAG,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA0ErE"}
|
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* AcceptanceCriteriaEvidenceCheck.
|
|
3
|
+
*
|
|
4
|
+
* Tier A verification check that compares a story's declared acceptance
|
|
5
|
+
* criteria against structured dev-story output. The check is intentionally
|
|
6
|
+
* deterministic: no LLM calls, no shell commands, no repository inspection.
|
|
7
|
+
*/
|
|
8
|
+
const EXPLICIT_AC_REF = /\bAC\s*:?\s*#?\s*(\d+)\b/gi;
|
|
9
|
+
const NUMBERED_CRITERION = /^\s*(?:[-*]\s*)?(?:\[[ xX]\]\s*)?(\d+)[.)]\s+\S/;
|
|
10
|
+
function normalizeAcId(value) {
|
|
11
|
+
const parsed = Number.parseInt(value, 10);
|
|
12
|
+
if (!Number.isFinite(parsed) || parsed <= 0)
|
|
13
|
+
return undefined;
|
|
14
|
+
return `AC${parsed}`;
|
|
15
|
+
}
|
|
16
|
+
function sortAcIds(ids) {
|
|
17
|
+
return Array.from(ids).sort((a, b) => {
|
|
18
|
+
const aNum = Number.parseInt(a.replace(/^AC/i, ''), 10);
|
|
19
|
+
const bNum = Number.parseInt(b.replace(/^AC/i, ''), 10);
|
|
20
|
+
return aNum - bNum;
|
|
21
|
+
});
|
|
22
|
+
}
|
|
23
|
+
function addExplicitAcRefs(text, ids) {
|
|
24
|
+
EXPLICIT_AC_REF.lastIndex = 0;
|
|
25
|
+
let match;
|
|
26
|
+
while ((match = EXPLICIT_AC_REF.exec(text)) !== null) {
|
|
27
|
+
const id = normalizeAcId(match[1] ?? '');
|
|
28
|
+
if (id !== undefined)
|
|
29
|
+
ids.add(id);
|
|
30
|
+
}
|
|
31
|
+
}
|
|
32
|
+
function extractAcceptanceSection(storyContent) {
|
|
33
|
+
const lines = storyContent.split(/\r?\n/);
|
|
34
|
+
const start = lines.findIndex((line) => /^##\s+Acceptance Criteria\s*$/i.test(line.trim()));
|
|
35
|
+
if (start === -1)
|
|
36
|
+
return undefined;
|
|
37
|
+
let end = lines.length;
|
|
38
|
+
for (let i = start + 1; i < lines.length; i += 1) {
|
|
39
|
+
if (/^##\s+\S/.test(lines[i] ?? '')) {
|
|
40
|
+
end = i;
|
|
41
|
+
break;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
return lines.slice(start + 1, end).join('\n');
|
|
45
|
+
}
|
|
46
|
+
/**
|
|
47
|
+
* Extract normalized AC ids from story markdown.
|
|
48
|
+
*
|
|
49
|
+
* Supports the BMAD default format (`### AC1:`), explicit references such as
|
|
50
|
+
* `AC: #1`, and plain numbered criteria inside the Acceptance Criteria section.
|
|
51
|
+
*/
|
|
52
|
+
export function extractAcceptanceCriteriaIds(storyContent) {
|
|
53
|
+
const ids = new Set();
|
|
54
|
+
const acceptanceSection = extractAcceptanceSection(storyContent);
|
|
55
|
+
const textToScan = acceptanceSection ?? storyContent;
|
|
56
|
+
addExplicitAcRefs(textToScan, ids);
|
|
57
|
+
if (acceptanceSection !== undefined) {
|
|
58
|
+
for (const line of acceptanceSection.split(/\r?\n/)) {
|
|
59
|
+
const match = line.match(NUMBERED_CRITERION);
|
|
60
|
+
if (match?.[1] !== undefined) {
|
|
61
|
+
const id = normalizeAcId(match[1]);
|
|
62
|
+
if (id !== undefined)
|
|
63
|
+
ids.add(id);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
}
|
|
67
|
+
return sortAcIds(ids);
|
|
68
|
+
}
|
|
69
|
+
function extractClaimedAcceptanceCriteriaIds(values) {
|
|
70
|
+
const ids = new Set();
|
|
71
|
+
for (const value of values ?? []) {
|
|
72
|
+
addExplicitAcRefs(value, ids);
|
|
73
|
+
const bareNumber = value.trim().match(/^#?(\d+)\b/);
|
|
74
|
+
if (bareNumber?.[1] !== undefined) {
|
|
75
|
+
const id = normalizeAcId(bareNumber[1]);
|
|
76
|
+
if (id !== undefined)
|
|
77
|
+
ids.add(id);
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
return sortAcIds(ids);
|
|
81
|
+
}
|
|
82
|
+
function normalizeTestOutcome(value) {
|
|
83
|
+
if (value === undefined)
|
|
84
|
+
return undefined;
|
|
85
|
+
return value.toLowerCase().includes('fail') ? 'fail' : 'pass';
|
|
86
|
+
}
|
|
87
|
+
function formatIds(ids) {
|
|
88
|
+
return ids.join(', ');
|
|
89
|
+
}
|
|
90
|
+
export class AcceptanceCriteriaEvidenceCheck {
|
|
91
|
+
name = 'acceptance-criteria-evidence';
|
|
92
|
+
tier = 'A';
|
|
93
|
+
async run(context) {
|
|
94
|
+
const start = Date.now();
|
|
95
|
+
const storyContent = context.storyContent?.trim();
|
|
96
|
+
if (!storyContent) {
|
|
97
|
+
return {
|
|
98
|
+
status: 'warn',
|
|
99
|
+
details: 'acceptance-criteria-evidence: story content unavailable - skipping AC evidence check',
|
|
100
|
+
duration_ms: Date.now() - start,
|
|
101
|
+
};
|
|
102
|
+
}
|
|
103
|
+
const expectedIds = extractAcceptanceCriteriaIds(storyContent);
|
|
104
|
+
if (expectedIds.length === 0) {
|
|
105
|
+
return {
|
|
106
|
+
status: 'warn',
|
|
107
|
+
details: 'acceptance-criteria-evidence: no numbered acceptance criteria found in story',
|
|
108
|
+
duration_ms: Date.now() - start,
|
|
109
|
+
};
|
|
110
|
+
}
|
|
111
|
+
const devResult = context.devStoryResult;
|
|
112
|
+
if (devResult === undefined) {
|
|
113
|
+
return {
|
|
114
|
+
status: 'warn',
|
|
115
|
+
details: `acceptance-criteria-evidence: dev-story result unavailable for ${formatIds(expectedIds)}`,
|
|
116
|
+
duration_ms: Date.now() - start,
|
|
117
|
+
};
|
|
118
|
+
}
|
|
119
|
+
const acFailures = devResult.ac_failures ?? [];
|
|
120
|
+
if (acFailures.length > 0) {
|
|
121
|
+
return {
|
|
122
|
+
status: 'fail',
|
|
123
|
+
details: `acceptance-criteria-evidence: dev-story reported AC failures: ${acFailures.join('; ')}`,
|
|
124
|
+
duration_ms: Date.now() - start,
|
|
125
|
+
};
|
|
126
|
+
}
|
|
127
|
+
const testOutcome = normalizeTestOutcome(devResult.tests);
|
|
128
|
+
if (testOutcome === 'fail') {
|
|
129
|
+
return {
|
|
130
|
+
status: 'fail',
|
|
131
|
+
details: 'acceptance-criteria-evidence: dev-story reported failing tests',
|
|
132
|
+
duration_ms: Date.now() - start,
|
|
133
|
+
};
|
|
134
|
+
}
|
|
135
|
+
const claimedIds = new Set(extractClaimedAcceptanceCriteriaIds(devResult.ac_met));
|
|
136
|
+
const missingIds = expectedIds.filter((id) => !claimedIds.has(id));
|
|
137
|
+
if (missingIds.length > 0) {
|
|
138
|
+
return {
|
|
139
|
+
status: 'fail',
|
|
140
|
+
details: `acceptance-criteria-evidence: missing dev-story AC evidence for ${formatIds(missingIds)}` +
|
|
141
|
+
`; expected ${formatIds(expectedIds)}, claimed ${formatIds(sortAcIds(claimedIds)) || 'none'}`,
|
|
142
|
+
duration_ms: Date.now() - start,
|
|
143
|
+
};
|
|
144
|
+
}
|
|
145
|
+
if (testOutcome === undefined) {
|
|
146
|
+
return {
|
|
147
|
+
status: 'warn',
|
|
148
|
+
details: `acceptance-criteria-evidence: AC evidence covers ${formatIds(expectedIds)} but test outcome is unavailable`,
|
|
149
|
+
duration_ms: Date.now() - start,
|
|
150
|
+
};
|
|
151
|
+
}
|
|
152
|
+
return {
|
|
153
|
+
status: 'pass',
|
|
154
|
+
details: `acceptance-criteria-evidence: AC evidence covers ${formatIds(expectedIds)}; tests=${testOutcome}`,
|
|
155
|
+
duration_ms: Date.now() - start,
|
|
156
|
+
};
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
//# sourceMappingURL=acceptance-criteria-evidence-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"acceptance-criteria-evidence-check.js","sourceRoot":"","sources":["../../../src/verification/checks/acceptance-criteria-evidence-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BuildCheck — Story 51-4.
|
|
3
|
+
*
|
|
4
|
+
* Tier A verification check that runs the project's build command after each
|
|
5
|
+
* story dispatch to catch compile-time regressions immediately.
|
|
6
|
+
*
|
|
7
|
+
* Architecture constraints (DC-6, FR-V9, FR-V11):
|
|
8
|
+
* - No LLM calls — pure shell invocation.
|
|
9
|
+
* - Hard 60-second timeout. On timeout the entire process group is killed.
|
|
10
|
+
* - Runs in Tier A, third in canonical order: after PhantomReviewCheck and
|
|
11
|
+
* TrivialOutputCheck.
|
|
12
|
+
*
|
|
13
|
+
* Build command detection priority (mirrors dispatcher-impl.ts logic without
|
|
14
|
+
* importing from the monolith to avoid circular dependencies):
|
|
15
|
+
* 1. turbo.json → 'turbo build'
|
|
16
|
+
* 2. pnpm-lock.yaml → 'pnpm run build'
|
|
17
|
+
* 3. yarn.lock → 'yarn build'
|
|
18
|
+
* 4. bun.lockb → 'bun run build'
|
|
19
|
+
* 5. package.json → 'npm run build'
|
|
20
|
+
* 6. Non-Node markers → '' (skip)
|
|
21
|
+
* 7. Nothing found → '' (skip)
|
|
22
|
+
*/
|
|
23
|
+
import type { VerificationCheck, VerificationContext, VerificationResult } from '../types.js';
|
|
24
|
+
/** Hard timeout for the build command in milliseconds (FR-V11). */
|
|
25
|
+
export declare const BUILD_CHECK_TIMEOUT_MS = 60000;
|
|
26
|
+
/**
|
|
27
|
+
* Detect the build command for a project based on files present in `workingDir`.
|
|
28
|
+
*
|
|
29
|
+
* Returns an empty string when no recognized build system is found, which
|
|
30
|
+
* causes BuildCheck to return a 'warn' result without blocking the pipeline.
|
|
31
|
+
*
|
|
32
|
+
* NOTE: Do NOT import from src/modules/agent-dispatch/dispatcher-impl.ts —
|
|
33
|
+
* that would create a circular dependency from packages/sdlc/ → monolith src/.
|
|
34
|
+
* This function inlines the detection logic independently.
|
|
35
|
+
*/
|
|
36
|
+
export declare function detectBuildCommand(workingDir: string): string;
|
|
37
|
+
/**
|
|
38
|
+
* Runs the project's build command and returns pass/warn/fail based on exit code.
|
|
39
|
+
*
|
|
40
|
+
* AC1: exit code 0 → pass
|
|
41
|
+
* AC2: non-zero exit code → fail with truncated output in details
|
|
42
|
+
* AC3: timeout → kill process group, return fail with timeout message
|
|
43
|
+
* AC4: no recognized build system → warn without blocking
|
|
44
|
+
* AC5: explicit buildCommand override respected; empty string → warn (skip)
|
|
45
|
+
* AC6: name === 'build', tier === 'A'
|
|
46
|
+
*/
|
|
47
|
+
export declare class BuildCheck implements VerificationCheck {
|
|
48
|
+
readonly name = "build";
|
|
49
|
+
readonly tier: "A";
|
|
50
|
+
run(context: VerificationContext): Promise<VerificationResult>;
|
|
51
|
+
}
|
|
52
|
+
//# sourceMappingURL=build-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-check.d.ts","sourceRoot":"","sources":["../../../src/verification/checks/build-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,kBAAkB,EAAE,MAAM,aAAa,CAAA;AAS7F,mEAAmE;AACnE,eAAO,MAAM,sBAAsB,QAAS,CAAA;AAS5C;;;;;;;;;GASG;AACH,wBAAgB,kBAAkB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CA8B7D;AAMD;;;;;;;;;GASG;AACH,qBAAa,UAAW,YAAW,iBAAiB;IAClD,QAAQ,CAAC,IAAI,WAAU;IACvB,QAAQ,CAAC,IAAI,EAAG,GAAG,CAAS;IAEtB,GAAG,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA2ErE"}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BuildCheck — Story 51-4.
|
|
3
|
+
*
|
|
4
|
+
* Tier A verification check that runs the project's build command after each
|
|
5
|
+
* story dispatch to catch compile-time regressions immediately.
|
|
6
|
+
*
|
|
7
|
+
* Architecture constraints (DC-6, FR-V9, FR-V11):
|
|
8
|
+
* - No LLM calls — pure shell invocation.
|
|
9
|
+
* - Hard 60-second timeout. On timeout the entire process group is killed.
|
|
10
|
+
* - Runs in Tier A, third in canonical order: after PhantomReviewCheck and
|
|
11
|
+
* TrivialOutputCheck.
|
|
12
|
+
*
|
|
13
|
+
* Build command detection priority (mirrors dispatcher-impl.ts logic without
|
|
14
|
+
* importing from the monolith to avoid circular dependencies):
|
|
15
|
+
* 1. turbo.json → 'turbo build'
|
|
16
|
+
* 2. pnpm-lock.yaml → 'pnpm run build'
|
|
17
|
+
* 3. yarn.lock → 'yarn build'
|
|
18
|
+
* 4. bun.lockb → 'bun run build'
|
|
19
|
+
* 5. package.json → 'npm run build'
|
|
20
|
+
* 6. Non-Node markers → '' (skip)
|
|
21
|
+
* 7. Nothing found → '' (skip)
|
|
22
|
+
*/
|
|
23
|
+
import { spawn } from 'node:child_process';
|
|
24
|
+
import { existsSync } from 'node:fs';
|
|
25
|
+
import { join } from 'node:path';
|
|
26
|
+
// ---------------------------------------------------------------------------
|
|
27
|
+
// Constants
|
|
28
|
+
// ---------------------------------------------------------------------------
|
|
29
|
+
/** Hard timeout for the build command in milliseconds (FR-V11). */
|
|
30
|
+
export const BUILD_CHECK_TIMEOUT_MS = 60_000;
|
|
31
|
+
/** Maximum characters to include in details string from build output. */
|
|
32
|
+
const MAX_OUTPUT_CHARS = 2000;
|
|
33
|
+
// ---------------------------------------------------------------------------
|
|
34
|
+
// Build command detection
|
|
35
|
+
// ---------------------------------------------------------------------------
|
|
36
|
+
/**
|
|
37
|
+
* Detect the build command for a project based on files present in `workingDir`.
|
|
38
|
+
*
|
|
39
|
+
* Returns an empty string when no recognized build system is found, which
|
|
40
|
+
* causes BuildCheck to return a 'warn' result without blocking the pipeline.
|
|
41
|
+
*
|
|
42
|
+
* NOTE: Do NOT import from src/modules/agent-dispatch/dispatcher-impl.ts —
|
|
43
|
+
* that would create a circular dependency from packages/sdlc/ → monolith src/.
|
|
44
|
+
* This function inlines the detection logic independently.
|
|
45
|
+
*/
|
|
46
|
+
export function detectBuildCommand(workingDir) {
|
|
47
|
+
// Priority 1: turbo.json
|
|
48
|
+
if (existsSync(join(workingDir, 'turbo.json'))) {
|
|
49
|
+
return 'turbo build';
|
|
50
|
+
}
|
|
51
|
+
// Priority 2: pnpm-lock.yaml
|
|
52
|
+
if (existsSync(join(workingDir, 'pnpm-lock.yaml'))) {
|
|
53
|
+
return 'pnpm run build';
|
|
54
|
+
}
|
|
55
|
+
// Priority 3: yarn.lock
|
|
56
|
+
if (existsSync(join(workingDir, 'yarn.lock'))) {
|
|
57
|
+
return 'yarn build';
|
|
58
|
+
}
|
|
59
|
+
// Priority 4: bun.lockb
|
|
60
|
+
if (existsSync(join(workingDir, 'bun.lockb'))) {
|
|
61
|
+
return 'bun run build';
|
|
62
|
+
}
|
|
63
|
+
// Priority 5: package.json (no turbo/lockfile match above)
|
|
64
|
+
if (existsSync(join(workingDir, 'package.json'))) {
|
|
65
|
+
return 'npm run build';
|
|
66
|
+
}
|
|
67
|
+
// Non-Node build markers: no universal build step, skip
|
|
68
|
+
const nonNodeMarkers = ['pyproject.toml', 'poetry.lock', 'setup.py', 'Cargo.toml', 'go.mod'];
|
|
69
|
+
for (const marker of nonNodeMarkers) {
|
|
70
|
+
if (existsSync(join(workingDir, marker))) {
|
|
71
|
+
return '';
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Nothing found
|
|
75
|
+
return '';
|
|
76
|
+
}
|
|
77
|
+
// ---------------------------------------------------------------------------
|
|
78
|
+
// BuildCheck
|
|
79
|
+
// ---------------------------------------------------------------------------
|
|
80
|
+
/**
|
|
81
|
+
* Runs the project's build command and returns pass/warn/fail based on exit code.
|
|
82
|
+
*
|
|
83
|
+
* AC1: exit code 0 → pass
|
|
84
|
+
* AC2: non-zero exit code → fail with truncated output in details
|
|
85
|
+
* AC3: timeout → kill process group, return fail with timeout message
|
|
86
|
+
* AC4: no recognized build system → warn without blocking
|
|
87
|
+
* AC5: explicit buildCommand override respected; empty string → warn (skip)
|
|
88
|
+
* AC6: name === 'build', tier === 'A'
|
|
89
|
+
*/
|
|
90
|
+
export class BuildCheck {
|
|
91
|
+
name = 'build';
|
|
92
|
+
tier = 'A';
|
|
93
|
+
async run(context) {
|
|
94
|
+
const start = Date.now();
|
|
95
|
+
// Resolve the command to run
|
|
96
|
+
const cmd = context.buildCommand !== undefined
|
|
97
|
+
? context.buildCommand
|
|
98
|
+
: detectBuildCommand(context.workingDir);
|
|
99
|
+
// Empty command → skip (warn)
|
|
100
|
+
if (cmd === '') {
|
|
101
|
+
return {
|
|
102
|
+
status: 'warn',
|
|
103
|
+
details: `build-skip: no build command detected for project at ${context.workingDir}`,
|
|
104
|
+
duration_ms: Date.now() - start,
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
// Spawn the build process as a detached process group so we can kill the
|
|
108
|
+
// entire group on timeout (FR-V11).
|
|
109
|
+
return new Promise((resolve) => {
|
|
110
|
+
const child = spawn(cmd, [], {
|
|
111
|
+
cwd: context.workingDir,
|
|
112
|
+
detached: true,
|
|
113
|
+
shell: true,
|
|
114
|
+
stdio: ['ignore', 'pipe', 'pipe'],
|
|
115
|
+
});
|
|
116
|
+
let output = '';
|
|
117
|
+
child.stdout?.on('data', (chunk) => {
|
|
118
|
+
output += chunk.toString();
|
|
119
|
+
});
|
|
120
|
+
child.stderr?.on('data', (chunk) => {
|
|
121
|
+
output += chunk.toString();
|
|
122
|
+
});
|
|
123
|
+
// Hard timeout: kill the process group and return fail
|
|
124
|
+
const timeoutHandle = setTimeout(() => {
|
|
125
|
+
try {
|
|
126
|
+
process.kill(-child.pid, 'SIGKILL');
|
|
127
|
+
}
|
|
128
|
+
catch {
|
|
129
|
+
// Process already exited between timeout fire and kill call
|
|
130
|
+
}
|
|
131
|
+
resolve({
|
|
132
|
+
status: 'fail',
|
|
133
|
+
details: `build-timeout: command exceeded ${BUILD_CHECK_TIMEOUT_MS}ms`,
|
|
134
|
+
duration_ms: Date.now() - start,
|
|
135
|
+
});
|
|
136
|
+
}, BUILD_CHECK_TIMEOUT_MS);
|
|
137
|
+
child.on('close', (code) => {
|
|
138
|
+
clearTimeout(timeoutHandle);
|
|
139
|
+
if (code === 0) {
|
|
140
|
+
resolve({
|
|
141
|
+
status: 'pass',
|
|
142
|
+
details: 'build passed',
|
|
143
|
+
duration_ms: Date.now() - start,
|
|
144
|
+
});
|
|
145
|
+
}
|
|
146
|
+
else {
|
|
147
|
+
const truncated = output.length > MAX_OUTPUT_CHARS
|
|
148
|
+
? output.slice(0, MAX_OUTPUT_CHARS) + '... (truncated)'
|
|
149
|
+
: output;
|
|
150
|
+
resolve({
|
|
151
|
+
status: 'fail',
|
|
152
|
+
details: `build failed (exit ${code}): ${truncated}`,
|
|
153
|
+
duration_ms: Date.now() - start,
|
|
154
|
+
});
|
|
155
|
+
}
|
|
156
|
+
});
|
|
157
|
+
});
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
//# sourceMappingURL=build-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"build-check.js","sourceRoot":"","sources":["../../../src/verification/checks/build-check.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel export for VerificationCheck implementations.
|
|
3
|
+
*
|
|
4
|
+
* Check registration order (Tier A before Tier B, and within Tier A in
|
|
5
|
+
* pipeline sequence order per architecture section 3.5):
|
|
6
|
+
* 1. PhantomReviewCheck — story 51-2
|
|
7
|
+
* 2. TrivialOutputCheck — story 51-3
|
|
8
|
+
* 3. AcceptanceCriteriaEvidenceCheck
|
|
9
|
+
* 4. BuildCheck — story 51-4
|
|
10
|
+
*/
|
|
11
|
+
export { PhantomReviewCheck } from './phantom-review-check.js';
|
|
12
|
+
export { TrivialOutputCheck, DEFAULT_TRIVIAL_OUTPUT_THRESHOLD } from './trivial-output-check.js';
|
|
13
|
+
export { AcceptanceCriteriaEvidenceCheck, extractAcceptanceCriteriaIds } from './acceptance-criteria-evidence-check.js';
|
|
14
|
+
export { BuildCheck, BUILD_CHECK_TIMEOUT_MS, detectBuildCommand } from './build-check.js';
|
|
15
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/verification/checks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAA;AAChG,OAAO,EAAE,+BAA+B,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAA;AACvH,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Barrel export for VerificationCheck implementations.
|
|
3
|
+
*
|
|
4
|
+
* Check registration order (Tier A before Tier B, and within Tier A in
|
|
5
|
+
* pipeline sequence order per architecture section 3.5):
|
|
6
|
+
* 1. PhantomReviewCheck — story 51-2
|
|
7
|
+
* 2. TrivialOutputCheck — story 51-3
|
|
8
|
+
* 3. AcceptanceCriteriaEvidenceCheck
|
|
9
|
+
* 4. BuildCheck — story 51-4
|
|
10
|
+
*/
|
|
11
|
+
export { PhantomReviewCheck } from './phantom-review-check.js';
|
|
12
|
+
export { TrivialOutputCheck, DEFAULT_TRIVIAL_OUTPUT_THRESHOLD } from './trivial-output-check.js';
|
|
13
|
+
export { AcceptanceCriteriaEvidenceCheck, extractAcceptanceCriteriaIds } from './acceptance-criteria-evidence-check.js';
|
|
14
|
+
export { BuildCheck, BUILD_CHECK_TIMEOUT_MS, detectBuildCommand } from './build-check.js';
|
|
15
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../src/verification/checks/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAA;AAC9D,OAAO,EAAE,kBAAkB,EAAE,gCAAgC,EAAE,MAAM,2BAA2B,CAAA;AAChG,OAAO,EAAE,+BAA+B,EAAE,4BAA4B,EAAE,MAAM,yCAAyC,CAAA;AACvH,OAAO,EAAE,UAAU,EAAE,sBAAsB,EAAE,kBAAkB,EAAE,MAAM,kBAAkB,CAAA"}
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PhantomReviewCheck — Story 51-2.
|
|
3
|
+
*
|
|
4
|
+
* Tier A verification check that detects when a code review dispatch failed
|
|
5
|
+
* but was recorded as a passing verdict. Stories that were never actually
|
|
6
|
+
* reviewed should not be counted as verified.
|
|
7
|
+
*
|
|
8
|
+
* Architecture constraints (FR-V9):
|
|
9
|
+
* - No LLM calls.
|
|
10
|
+
* - No shell invocations — pure static signal inspection over VerificationContext fields.
|
|
11
|
+
* - Runs first in Tier A (before TrivialOutputCheck, before BuildCheck).
|
|
12
|
+
*/
|
|
13
|
+
import type { VerificationCheck, VerificationContext, VerificationResult } from '../types.js';
|
|
14
|
+
/**
|
|
15
|
+
* Detects phantom reviews — dispatches that failed or produced no output but
|
|
16
|
+
* were recorded as passing verdicts.
|
|
17
|
+
*
|
|
18
|
+
* AC1: dispatch failed (non-zero exit, timeout, crash) → fail
|
|
19
|
+
* AC2: empty or null rawOutput → fail
|
|
20
|
+
* AC3: schema_validation_failed error → fail
|
|
21
|
+
* AC5: valid review (non-empty rawOutput, no dispatchFailed) → pass
|
|
22
|
+
* AC6: name='phantom-review', tier='A'
|
|
23
|
+
*/
|
|
24
|
+
export declare class PhantomReviewCheck implements VerificationCheck {
|
|
25
|
+
readonly name = "phantom-review";
|
|
26
|
+
readonly tier: "A";
|
|
27
|
+
run(context: VerificationContext): Promise<VerificationResult>;
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=phantom-review-check.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-review-check.d.ts","sourceRoot":"","sources":["../../../src/verification/checks/phantom-review-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAEH,OAAO,KAAK,EACV,iBAAiB,EACjB,mBAAmB,EACnB,kBAAkB,EACnB,MAAM,aAAa,CAAA;AAMpB;;;;;;;;;GASG;AACH,qBAAa,kBAAmB,YAAW,iBAAiB;IAC1D,QAAQ,CAAC,IAAI,oBAAmB;IAChC,QAAQ,CAAC,IAAI,EAAG,GAAG,CAAS;IAEtB,GAAG,CAAC,OAAO,EAAE,mBAAmB,GAAG,OAAO,CAAC,kBAAkB,CAAC;CA6CrE"}
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* PhantomReviewCheck — Story 51-2.
|
|
3
|
+
*
|
|
4
|
+
* Tier A verification check that detects when a code review dispatch failed
|
|
5
|
+
* but was recorded as a passing verdict. Stories that were never actually
|
|
6
|
+
* reviewed should not be counted as verified.
|
|
7
|
+
*
|
|
8
|
+
* Architecture constraints (FR-V9):
|
|
9
|
+
* - No LLM calls.
|
|
10
|
+
* - No shell invocations — pure static signal inspection over VerificationContext fields.
|
|
11
|
+
* - Runs first in Tier A (before TrivialOutputCheck, before BuildCheck).
|
|
12
|
+
*/
|
|
13
|
+
// ---------------------------------------------------------------------------
|
|
14
|
+
// PhantomReviewCheck
|
|
15
|
+
// ---------------------------------------------------------------------------
|
|
16
|
+
/**
|
|
17
|
+
* Detects phantom reviews — dispatches that failed or produced no output but
|
|
18
|
+
* were recorded as passing verdicts.
|
|
19
|
+
*
|
|
20
|
+
* AC1: dispatch failed (non-zero exit, timeout, crash) → fail
|
|
21
|
+
* AC2: empty or null rawOutput → fail
|
|
22
|
+
* AC3: schema_validation_failed error → fail
|
|
23
|
+
* AC5: valid review (non-empty rawOutput, no dispatchFailed) → pass
|
|
24
|
+
* AC6: name='phantom-review', tier='A'
|
|
25
|
+
*/
|
|
26
|
+
export class PhantomReviewCheck {
|
|
27
|
+
name = 'phantom-review';
|
|
28
|
+
tier = 'A';
|
|
29
|
+
async run(context) {
|
|
30
|
+
const start = Date.now();
|
|
31
|
+
const review = context.reviewResult;
|
|
32
|
+
// No review signals available — treat as pass (check cannot determine failure)
|
|
33
|
+
if (!review) {
|
|
34
|
+
return {
|
|
35
|
+
status: 'pass',
|
|
36
|
+
details: 'phantom-review: no review result in context — skipping check',
|
|
37
|
+
duration_ms: Date.now() - start,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
// AC1 + AC3: dispatch itself failed (non-zero exit, timeout, crash, or schema validation failure)
|
|
41
|
+
if (review.dispatchFailed === true) {
|
|
42
|
+
const reason = review.error === 'schema_validation_failed'
|
|
43
|
+
? 'schema validation failed'
|
|
44
|
+
: `dispatch failed${review.error ? ` — ${review.error}` : ''}`;
|
|
45
|
+
return {
|
|
46
|
+
status: 'fail',
|
|
47
|
+
details: `phantom-review: ${reason}`,
|
|
48
|
+
duration_ms: Date.now() - start,
|
|
49
|
+
};
|
|
50
|
+
}
|
|
51
|
+
// AC2: agent produced no output — only flag when rawOutput is explicitly empty
|
|
52
|
+
// string (dispatch ran but returned nothing). When rawOutput is undefined, the
|
|
53
|
+
// dispatch result may not have captured it (e.g., parsed YAML result without
|
|
54
|
+
// raw output preservation) — treat as pass since dispatchFailed was not set.
|
|
55
|
+
if (review.rawOutput !== undefined && review.rawOutput.trim().length === 0) {
|
|
56
|
+
return {
|
|
57
|
+
status: 'fail',
|
|
58
|
+
details: 'phantom-review: empty review output',
|
|
59
|
+
duration_ms: Date.now() - start,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
// AC5: valid review — non-empty output, no dispatch failure
|
|
63
|
+
return {
|
|
64
|
+
status: 'pass',
|
|
65
|
+
details: 'phantom-review: review output is valid',
|
|
66
|
+
duration_ms: Date.now() - start,
|
|
67
|
+
};
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
//# sourceMappingURL=phantom-review-check.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"phantom-review-check.js","sourceRoot":"","sources":["../../../src/verification/checks/phantom-review-check.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AAQH,8EAA8E;AAC9E,qBAAqB;AACrB,8EAA8E;AAE9E;;;;;;;;;GASG;AACH,MAAM,OAAO,kBAAkB;IACpB,IAAI,GAAG,gBAAgB,CAAA;IACvB,IAAI,GAAG,GAAY,CAAA;IAE5B,KAAK,CAAC,GAAG,CAAC,OAA4B;QACpC,MAAM,KAAK,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;QACxB,MAAM,MAAM,GAAG,OAAO,CAAC,YAAY,CAAA;QAEnC,+EAA+E;QAC/E,IAAI,CAAC,MAAM,EAAE,CAAC;YACZ,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,8DAA8D;gBACvE,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAChC,CAAA;QACH,CAAC;QAED,kGAAkG;QAClG,IAAI,MAAM,CAAC,cAAc,KAAK,IAAI,EAAE,CAAC;YACnC,MAAM,MAAM,GACV,MAAM,CAAC,KAAK,KAAK,0BAA0B;gBACzC,CAAC,CAAC,0BAA0B;gBAC5B,CAAC,CAAC,kBAAkB,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,MAAM,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC,EAAE,EAAE,CAAA;YAClE,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,mBAAmB,MAAM,EAAE;gBACpC,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAChC,CAAA;QACH,CAAC;QAED,+EAA+E;QAC/E,+EAA+E;QAC/E,6EAA6E;QAC7E,6EAA6E;QAC7E,IAAI,MAAM,CAAC,SAAS,KAAK,SAAS,IAAI,MAAM,CAAC,SAAS,CAAC,IAAI,EAAE,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAC3E,OAAO;gBACL,MAAM,EAAE,MAAM;gBACd,OAAO,EAAE,qCAAqC;gBAC9C,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;aAChC,CAAA;QACH,CAAC;QAED,4DAA4D;QAC5D,OAAO;YACL,MAAM,EAAE,MAAM;YACd,OAAO,EAAE,wCAAwC;YACjD,WAAW,EAAE,IAAI,CAAC,GAAG,EAAE,GAAG,KAAK;SAChC,CAAA;IACH,CAAC;CACF"}
|