mirror of
https://github.com/wassname/pi-lgtm.git
synced 2026-06-27 16:46:17 +08:00
add lgtm evidence history and artifact metadata
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { getDisplayStatus, getGateStatus, getReviewBadges } from "../src/review-badges.js";
|
||||
import { getCompletionMode, getDisplayStatus, getGateStatus, getReviewBadges, getReviewState } from "../src/review-badges.js";
|
||||
import type { Task } from "../src/types.js";
|
||||
|
||||
function makeTask(overrides: Partial<Task> = {}): Task {
|
||||
@@ -60,6 +60,20 @@ describe("getReviewBadges", () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe("review state helpers", () => {
|
||||
it("reports completion mode as direct before any lgtm evidence", () => {
|
||||
expect(getCompletionMode(makeTask())).toBe("direct");
|
||||
});
|
||||
|
||||
it("reports completion mode as lgtm after evidence history exists", () => {
|
||||
expect(getCompletionMode(makeTask({ metadata: { lgtm_history: [{ iteration: 1 }] } }))).toBe("lgtm");
|
||||
});
|
||||
|
||||
it("reports superseded when only history remains", () => {
|
||||
expect(getReviewState(makeTask({ metadata: { lgtm_history: [{ iteration: 1 }] } }))).toBe("superseded");
|
||||
});
|
||||
});
|
||||
|
||||
describe("getGateStatus", () => {
|
||||
it("reports ready when human sign-off is open", () => {
|
||||
expect(getGateStatus(makeTask({
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
import { mkdtempSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { archiveCurrentEvidence, buildArtifactRecords, getCurrentEvidenceIteration, getEvidenceHistory } from "../src/index.js";
|
||||
import { appendRobotReviewMetadata, getLatestRobotReview, getRobotReviews, shouldOpenHumanSignoffGate } from "../src/robot-review.js";
|
||||
import type { Task } from "../src/types.js";
|
||||
|
||||
@@ -45,6 +49,38 @@ describe("robot review helpers", () => {
|
||||
expect(reviews[0].accepted).toBe(true);
|
||||
});
|
||||
|
||||
it("builds artifact records with absolute path and sha256", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "pi-lgtm-"));
|
||||
const path = join(dir, "evidence.log");
|
||||
writeFileSync(path, "hello\n");
|
||||
|
||||
const [artifact] = buildArtifactRecords([path]);
|
||||
expect(artifact.path).toBe(path);
|
||||
expect(artifact.bytes).toBe(6);
|
||||
expect(artifact.sha256).toHaveLength(64);
|
||||
});
|
||||
|
||||
it("archives current evidence with reason", () => {
|
||||
const task = makeTask({
|
||||
metadata: {
|
||||
lgtm_evidence: "literal output",
|
||||
lgtm_failure_likely: "wrong seed",
|
||||
lgtm_failure_sneaky: "wrong threshold",
|
||||
lgtm_falsification_test: "pytest -k check",
|
||||
lgtm_verification_hints: ["see line 5"],
|
||||
lgtm_remaining_uncertainty: "not load tested",
|
||||
lgtm_submitted_at: "2026-06-07T00:00:00.000Z",
|
||||
lgtm_commands: [{ cmd: "pytest", exit_code: 0 }],
|
||||
},
|
||||
});
|
||||
|
||||
const archived = archiveCurrentEvidence(task, "threshold changed");
|
||||
const taskWithHistory = makeTask({ metadata: archived });
|
||||
expect(getCurrentEvidenceIteration(task)?.iteration).toBe(1);
|
||||
expect(getEvidenceHistory(taskWithHistory)).toHaveLength(1);
|
||||
expect(getEvidenceHistory(taskWithHistory)[0].supersede_reason).toBe("threshold changed");
|
||||
});
|
||||
|
||||
it("appends robot reviews as iterations", () => {
|
||||
const task = makeTask();
|
||||
const metadata1 = appendRobotReviewMetadata(task, {
|
||||
|
||||
@@ -189,6 +189,17 @@ describe("TaskStore (in-memory)", () => {
|
||||
expect(() => store.update("1", { status: "completed" })).toThrow("/lgtm");
|
||||
});
|
||||
|
||||
it("blocks TaskUpdate(status=completed) after evidence was superseded into history", () => {
|
||||
store.create("Superseded", "Desc", "done");
|
||||
store.update("1", {
|
||||
metadata: {
|
||||
lgtm_history: [{ iteration: 1, supersede_reason: "threshold changed" }],
|
||||
},
|
||||
pending_approval: false,
|
||||
});
|
||||
expect(() => store.update("1", { status: "completed" })).toThrow("completion_mode=lgtm");
|
||||
});
|
||||
|
||||
it("returns not found for update on non-existent task", () => {
|
||||
const { task, changedFields } = store.update("999", { status: "in_progress" });
|
||||
expect(task).toBeUndefined();
|
||||
|
||||
Reference in New Issue
Block a user