Files
oh-my-opencode/packages/omo-codex/plugin/components/ulw-loop/test/evidence-criteria-gate.test.ts
T
YeonGyu-Kim 8c6e8e4986 refactor(omo-codex): rename ultragoal component to ulw-loop
Fully rename the ultragoal component to ulw-loop so the identifier
matches the ulw-loop skill it powers. Renames the component directory,
nested skill, TS identifiers (UlwLoop / ULW_LOOP_* / ulwLoop*), the
omo ulw-loop CLI subcommand, the .omo/ulw-loop state directory, the
OMO_ULW_LOOP_STEER directive token, and the @code-yeongyu/codex-ulw-loop
package. Also threads Atlas-style right-sized parallel worker delegation
and a Prometheus-style QA + maximum-parallelism plan into the ulw-loop
skill, with a critical post-subagent QA gate.

Updates aggregate wiring (plugin package components, hooks.json,
sync-skills), the install-codex agent-link test fixture, and user docs.
2026-05-29 12:38:22 +09:00

101 lines
2.8 KiB
TypeScript

import { describe, expect, it } from "vitest";
import { requireAllCriteriaPass } from "../src/evidence.js";
import type { UlwLoopItem, UlwLoopSuccessCriterion } from "../src/types.js";
import { UlwLoopError } from "../src/types.js";
const NOW = "2026-05-23T00:00:00.000Z";
function makeCriterion(overrides: Partial<UlwLoopSuccessCriterion> = {}): UlwLoopSuccessCriterion {
return {
id: "C001",
scenario: "happy path login returns 200",
userModel: "happy",
expectedEvidence: "curl /login -d {valid} returns 200 + token",
capturedEvidence: null,
status: "pending",
...overrides,
};
}
function makeGoal(overrides: Partial<UlwLoopItem> = {}): UlwLoopItem {
return {
id: "G001",
title: "Auth endpoint",
objective: "Build JWT auth",
status: "in_progress",
successCriteria: [
makeCriterion({ id: "C001" }),
makeCriterion({ id: "C002", userModel: "edge" }),
makeCriterion({ id: "C003", userModel: "regression" }),
],
attempt: 1,
createdAt: NOW,
updatedAt: NOW,
...overrides,
};
}
describe("requireAllCriteriaPass", () => {
it("does NOT throw when all criteria pass", () => {
// given
const goal = makeGoal({
successCriteria: [
makeCriterion({ id: "C001", status: "pass" }),
makeCriterion({ id: "C002", status: "pass" }),
],
});
// when / then
expect(() => requireAllCriteriaPass(goal)).not.toThrow();
});
it("throws UlwLoopError when any criterion pending", () => {
// given
const goal = makeGoal({
successCriteria: [
makeCriterion({ id: "C001", status: "pass" }),
makeCriterion({ id: "C002", status: "pending" }),
makeCriterion({ id: "C003", status: "pass" }),
],
});
// when / then
expect(() => requireAllCriteriaPass(goal)).toThrow(UlwLoopError);
});
it("throws when any fail/blocked too", () => {
// given
const goal1 = makeGoal({ successCriteria: [makeCriterion({ id: "C001", status: "fail" })] });
const goal2 = makeGoal({ successCriteria: [makeCriterion({ id: "C001", status: "blocked" })] });
// when / then
expect(() => requireAllCriteriaPass(goal1)).toThrow(UlwLoopError);
expect(() => requireAllCriteriaPass(goal2)).toThrow(UlwLoopError);
});
it("UlwLoopError includes details.goalId + details.unresolved", () => {
// given
const goal = makeGoal({
id: "G001",
successCriteria: [
makeCriterion({ id: "C001", status: "pass" }),
makeCriterion({ id: "C002", status: "pending" }),
makeCriterion({ id: "C003", status: "pass" }),
],
});
// when / then
try {
requireAllCriteriaPass(goal);
expect.fail("expected throw");
} catch (error) {
expect(error).toBeInstanceOf(UlwLoopError);
if (!(error instanceof UlwLoopError)) throw error;
expect(error.code).toBe("ulw_loop_criteria_not_all_pass");
expect(error.details?.["goalId"]).toBe("G001");
expect(Array.isArray(error.details?.["unresolved"])).toBe(true);
}
});
});