feat(P04): verification intelligence — git-native coverage, npm audit, TS compilation

---ci---
project: ci
phase: 4
milestone: v0.5
status: complete
decisions:
  - id: D-028
    decision: Phase 4 Verification Intelligence complete
    rationale: All INTEL requirements covered; 31 suites, 355 tests
    confidence: 0.95
    alternatives: []
requirements:
  covered: [INTEL-01, INTEL-02, INTEL-03]
---/ci---
This commit is contained in:
Jon Chery
2026-05-29 16:46:17 +00:00
parent 5753e2dc96
commit b33431c1a6
3 changed files with 192 additions and 14 deletions
+28
View File
@@ -1,5 +1,6 @@
import * as fs from "node:fs";
import * as path from "node:path";
import { execSync } from "node:child_process";
import { VerificationLayer, VerificationResult, VerificationCheck } from "./types.js";
interface CodeFinding {
@@ -66,6 +67,7 @@ export class QualityVerification extends VerificationLayer {
checks.push(this.checkP2P3Findings(p2p3Findings));
checks.push(this.checkTypeScriptStrictness(projectPath));
checks.push(this.checkConsistentNaming(projectPath));
checks.push(this.checkTypeScriptCompilation(projectPath));
const hasP0Fail = p0Findings.length > 3;
const passed = !hasP0Fail;
@@ -226,6 +228,32 @@ export class QualityVerification extends VerificationLayer {
);
}
private checkTypeScriptCompilation(projectPath: string): VerificationCheck {
const tsconfigPath = path.join(projectPath, "tsconfig.json");
if (!fs.existsSync(tsconfigPath)) {
return this.check("TypeScript compilation", "skipped", "No tsconfig.json found");
}
try {
execSync("npx tsc --noEmit 2>&1", {
cwd: projectPath,
encoding: "utf-8",
timeout: 60000,
stdio: ["pipe", "pipe", "pipe"],
});
return this.check("TypeScript compilation", "pass", "TypeScript compiles without errors");
} catch (err) {
const execErr = err as { stdout?: string };
const output = execErr.stdout || "";
const errorCount = (output.match(/error TS/g) || []).length;
return this.check(
"TypeScript compilation",
errorCount > 5 ? "fail" : "warning",
`${errorCount} TypeScript compilation error(s)`
);
}
}
private collectFiles(dir: string, files: string[]): void {
const entries = fs.readdirSync(dir, { withFileTypes: true });
for (const entry of entries) {