v0.2.0: Git-native architecture (#1)

This commit was merged in pull request #1.
This commit is contained in:
2026-05-29 12:59:45 +00:00
parent 9cf5c000d9
commit 6e637e4af0
50 changed files with 5852 additions and 135 deletions
+114
View File
@@ -0,0 +1,114 @@
import * as fs from "node:fs";
import * as path from "node:path";
import * as os from "node:os";
import { StructuralVerification } from "../verification/structural.js";
describe("StructuralVerification", () => {
let tempDir: string;
beforeEach(() => {
tempDir = fs.mkdtempSync(path.join(os.tmpdir(), "ci-structural-test-"));
});
afterEach(() => {
fs.rmSync(tempDir, { recursive: true, force: true });
});
function setupProjectStructure(hasPhaseDir = true, hasPlan = true, hasCIConfig = true, hasSpec = true) {
if (hasPhaseDir) {
const phaseDir = path.join(tempDir, ".planning", "phases", "phase-1");
fs.mkdirSync(phaseDir, { recursive: true });
if (hasPlan) {
fs.writeFileSync(path.join(phaseDir, "PLAN.md"), "# Plan\n\nTasks:\n- [ ] Task 1\n- [ ] Task 2\n");
}
}
if (hasCIConfig) {
const ciDir = path.join(tempDir, ".ci");
fs.mkdirSync(ciDir, { recursive: true });
fs.writeFileSync(path.join(ciDir, "config.json"), JSON.stringify({ autonomy: { level: "full" } }, null, 2));
}
if (hasSpec) {
const specDir = path.join(tempDir, ".ci");
if (!fs.existsSync(specDir)) fs.mkdirSync(specDir, { recursive: true });
fs.writeFileSync(path.join(specDir, "specification.md"), "# Project\n## Objective\nBuild a REST API for task management\n\n## Requirements\n- User auth\n- CRUD\n");
}
}
it("passes when all structural elements exist", async () => {
setupProjectStructure(true, true, true, true);
const verifier = new StructuralVerification();
const result = await verifier.verify(tempDir, 1);
expect(result.layer).toBe(1);
expect(result.name).toBe("Structural");
expect(result.checks.length).toBeGreaterThan(0);
const phaseDirCheck = result.checks.find((c) => c.name === "Phase directory exists");
expect(phaseDirCheck?.status).toBe("pass");
const planCheck = result.checks.find((c) => c.name === "PLAN.md exists");
expect(planCheck?.status).toBe("pass");
const configCheck = result.checks.find((c) => c.name === "CI config valid");
expect(configCheck?.status).toBe("pass");
const specCheck = result.checks.find((c) => c.name === "Specification exists");
expect(specCheck?.status).toBe("pass");
});
it("fails when phase directory is missing", async () => {
setupProjectStructure(false, false, true, true);
const verifier = new StructuralVerification();
const result = await verifier.verify(tempDir, 1);
const phaseDirCheck = result.checks.find((c) => c.name === "Phase directory exists");
expect(phaseDirCheck?.status).toBe("fail");
});
it("fails when PLAN.md is missing", async () => {
setupProjectStructure(true, false, true, true);
const verifier = new StructuralVerification();
const result = await verifier.verify(tempDir, 1);
const planCheck = result.checks.find((c) => c.name === "PLAN.md exists");
expect(planCheck?.status).toBe("fail");
});
it("fails when CI config has invalid JSON", async () => {
const ciDir = path.join(tempDir, ".ci");
fs.mkdirSync(ciDir, { recursive: true });
fs.writeFileSync(path.join(ciDir, "config.json"), "not valid json{{{");
fs.mkdirSync(path.join(tempDir, ".planning", "phases", "phase-1"), { recursive: true });
const verifier = new StructuralVerification();
const result = await verifier.verify(tempDir, 1);
const configCheck = result.checks.find((c) => c.name === "CI config valid");
expect(configCheck?.status).toBe("fail");
});
it("detects TODO/FIXME patterns in source files", async () => {
const srcDir = path.join(tempDir, "src");
fs.mkdirSync(srcDir, { recursive: true });
fs.writeFileSync(path.join(srcDir, "app.ts"), "export function main() { /* TODO: implement */ }");
fs.mkdirSync(path.join(tempDir, ".planning", "phases", "phase-1"), { recursive: true });
fs.writeFileSync(path.join(tempDir, ".planning", "phases", "phase-1", "PLAN.md"), "# Plan");
const ciDir = path.join(tempDir, ".ci");
fs.mkdirSync(ciDir, { recursive: true });
fs.writeFileSync(path.join(ciDir, "config.json"), "{}");
fs.writeFileSync(path.join(ciDir, "specification.md"), "# Test\n## Objective\nBuild it");
const verifier = new StructuralVerification();
const result = await verifier.verify(tempDir, 1);
const stubsCheck = result.checks.find((c) => c.name === "No stubs/TODOs");
expect(stubsCheck?.status).toMatch(/warning|fail/);
});
it("reports duration", async () => {
setupProjectStructure(true, true, true, true);
const verifier = new StructuralVerification();
const result = await verifier.verify(tempDir, 1);
expect(result.duration_ms).toBeGreaterThanOrEqual(0);
});
});