Initial curated projectbrain source from 8a7b1e0651dbdab97d744cbd2e653ab3970ac6c5
This commit is contained in:
commit
5aa3e8d685
700 files changed
+132801
No files matched your search
@@ -0,0 +1,194 @@
|
||||
import { describe, expect, it } from "vitest";
|
||||
import { isSafeGitProjectSourcePath } from "../src/services/gitSourceSync.js";
|
||||
import { chooseNextAutonomyWork } from "../src/services/autonomyScheduler.js";
|
||||
import {
|
||||
buildRepositoryAutonomyRoadmap,
|
||||
isRepositoryManagedRoadmap,
|
||||
mergeRepositoryAutonomyRoadmap,
|
||||
} from "../src/services/repositoryAutonomy.js";
|
||||
|
||||
const roadmapSource = {
|
||||
path: "ROADMAP.md",
|
||||
content: `# Phoenix roadmap
|
||||
|
||||
## M1 — Safe software foundation
|
||||
Build the strict software foundation while lab qualification can happen independently.
|
||||
|
||||
## M2 — K3s lab
|
||||
Provision only after the external lab gate is cleared.`,
|
||||
contentSha: "roadmap-sha",
|
||||
};
|
||||
|
||||
const backlogSource = (extraTasks: Array<Record<string, unknown>> = []) => ({
|
||||
path: "docs/implementation/backlog.json",
|
||||
contentSha: `backlog-sha-${extraTasks.length}`,
|
||||
content: JSON.stringify({
|
||||
schema_version: "1.0",
|
||||
project: "Phoenix",
|
||||
execution_enabled: false,
|
||||
tasks: [
|
||||
{
|
||||
id: "PHX-001",
|
||||
title: "Read-only lab qualification",
|
||||
milestone: "M1",
|
||||
depends_on: [],
|
||||
requirements: ["R02"],
|
||||
plan: "docs/implementation/01-foundation.md",
|
||||
execution: "qualification",
|
||||
status: "blocked_external",
|
||||
evidence: [],
|
||||
verified_commit: null,
|
||||
},
|
||||
{
|
||||
id: "PHX-002",
|
||||
title: "Strict contracts and development harness",
|
||||
milestone: "M1",
|
||||
depends_on: [],
|
||||
requirements: ["R03"],
|
||||
plan: "docs/implementation/01-foundation.md",
|
||||
execution: "code",
|
||||
status: "planned",
|
||||
evidence: [],
|
||||
verified_commit: null,
|
||||
},
|
||||
{
|
||||
id: "PHX-003",
|
||||
title: "API, database, durable jobs and outbox",
|
||||
milestone: "M1",
|
||||
depends_on: ["PHX-002"],
|
||||
requirements: ["R04"],
|
||||
plan: "docs/implementation/01-foundation.md",
|
||||
execution: "code",
|
||||
status: "planned",
|
||||
evidence: [],
|
||||
verified_commit: null,
|
||||
},
|
||||
{
|
||||
id: "PHX-006",
|
||||
title: "Safe K3s bootstrap",
|
||||
milestone: "M2",
|
||||
depends_on: ["PHX-001", "PHX-002"],
|
||||
requirements: ["R06"],
|
||||
plan: "docs/implementation/01-foundation.md",
|
||||
execution: "lab",
|
||||
status: "planned",
|
||||
evidence: [],
|
||||
verified_commit: null,
|
||||
},
|
||||
...extraTasks,
|
||||
],
|
||||
}),
|
||||
});
|
||||
|
||||
describe("repository-native Auto Mode", () => {
|
||||
it("syncs planning truth without opening the source filter to arbitrary JSON", () => {
|
||||
expect(isSafeGitProjectSourcePath("ROADMAP.md")).toBe(true);
|
||||
expect(isSafeGitProjectSourcePath("docs/implementation/backlog.json")).toBe(true);
|
||||
expect(isSafeGitProjectSourcePath("docs/implementation/roadmap.json")).toBe(true);
|
||||
expect(isSafeGitProjectSourcePath("docs/implementation/random-data.json")).toBe(false);
|
||||
expect(isSafeGitProjectSourcePath("config/backlog.json")).toBe(false);
|
||||
expect(isSafeGitProjectSourcePath(".env")).toBe(false);
|
||||
});
|
||||
|
||||
it("turns a structured repository backlog into dependency-aware autonomous work", () => {
|
||||
const roadmap = buildRepositoryAutonomyRoadmap({
|
||||
roadmap: roadmapSource,
|
||||
backlog: backlogSource(),
|
||||
importedAt: "2026-09-21T12:00:00.000Z",
|
||||
});
|
||||
|
||||
expect(roadmap).toBeDefined();
|
||||
expect(isRepositoryManagedRoadmap(roadmap)).toBe(true);
|
||||
expect(roadmap?.phases.map((phase) => phase.title)).toEqual([
|
||||
"M1 — Safe software foundation",
|
||||
"M2 — K3s lab",
|
||||
]);
|
||||
|
||||
const items = new Map(roadmap?.phases.flatMap((phase) => phase.items).map((item) => [item.id, item]));
|
||||
expect(items.get("PHX-001")).toMatchObject({ status: "pending", waitingExternal: true, source: "roadmap" });
|
||||
expect(items.get("PHX-002")).toMatchObject({ status: "pending", scope: "committed" });
|
||||
expect(items.get("PHX-002")).not.toHaveProperty("waitingExternal");
|
||||
expect(items.get("PHX-003")).toMatchObject({ dependsOn: ["PHX-002"] });
|
||||
expect(items.get("PHX-006")).toMatchObject({ waitingExternal: true, dependsOn: ["PHX-001", "PHX-002"] });
|
||||
expect(roadmap?.phases.every((phase) => phase.brainstormConverged)).toBe(true);
|
||||
|
||||
const next = chooseNextAutonomyWork(roadmap!.phases, roadmap!.currentPhaseIndex, "balanced");
|
||||
expect(next?.item.id).toBe("PHX-002");
|
||||
});
|
||||
|
||||
it("does not let a planning refresh newly complete an existing runtime item", () => {
|
||||
const current = buildRepositoryAutonomyRoadmap({
|
||||
roadmap: roadmapSource,
|
||||
backlog: backlogSource(),
|
||||
importedAt: "2026-09-21T12:00:00.000Z",
|
||||
})!;
|
||||
const currentItem = current.phases.flatMap((phase) => phase.items).find((item) => item.id === "PHX-002")!;
|
||||
currentItem.status = "pending";
|
||||
|
||||
const verifiedBacklog = JSON.parse(backlogSource().content) as { tasks: Array<Record<string, unknown>> };
|
||||
const task = verifiedBacklog.tasks.find((entry) => entry.id === "PHX-002")!;
|
||||
task.status = "verified";
|
||||
task.verified_commit = "deadbeef";
|
||||
|
||||
const incoming = buildRepositoryAutonomyRoadmap({
|
||||
roadmap: { ...roadmapSource, contentSha: "roadmap-sha-verified" },
|
||||
backlog: { ...backlogSource(), content: JSON.stringify(verifiedBacklog), contentSha: "backlog-sha-verified" },
|
||||
importedAt: "2026-09-21T13:00:00.000Z",
|
||||
})!;
|
||||
|
||||
const reconciled = mergeRepositoryAutonomyRoadmap(current, incoming);
|
||||
const item = reconciled.phases.flatMap((phase) => phase.items).find((entry) => entry.id === "PHX-002")!;
|
||||
expect(item.status).toBe("pending");
|
||||
});
|
||||
|
||||
it("preserves verified runtime progress and explicit assignments when repository planning changes", () => {
|
||||
const current = buildRepositoryAutonomyRoadmap({
|
||||
roadmap: roadmapSource,
|
||||
backlog: backlogSource(),
|
||||
importedAt: "2026-09-21T12:00:00.000Z",
|
||||
})!;
|
||||
const phx002 = current.phases.flatMap((phase) => phase.items).find((item) => item.id === "PHX-002")!;
|
||||
phx002.status = "completed";
|
||||
phx002.attempts = 2;
|
||||
phx002.deliveryId = "delivery-phx-002";
|
||||
phx002.completionEvidence = ["merge:abc"];
|
||||
|
||||
current.phases[0].items.unshift({
|
||||
id: "assignment-1",
|
||||
title: "Explicit owner task",
|
||||
instruction: "Keep this assignment across repo refreshes.",
|
||||
source: "user_assignment",
|
||||
status: "pending",
|
||||
attempts: 0,
|
||||
});
|
||||
|
||||
const incoming = buildRepositoryAutonomyRoadmap({
|
||||
roadmap: { ...roadmapSource, contentSha: "roadmap-sha-2" },
|
||||
backlog: backlogSource([{
|
||||
id: "PHX-004",
|
||||
title: "Auth and target guard",
|
||||
milestone: "M1",
|
||||
depends_on: ["PHX-003"],
|
||||
requirements: ["R05"],
|
||||
plan: "docs/implementation/01-foundation.md",
|
||||
execution: "code",
|
||||
status: "planned",
|
||||
evidence: [],
|
||||
verified_commit: null,
|
||||
}]),
|
||||
importedAt: "2026-09-21T13:00:00.000Z",
|
||||
})!;
|
||||
|
||||
const reconciled = mergeRepositoryAutonomyRoadmap(current, incoming);
|
||||
const items = new Map(reconciled.phases.flatMap((phase) => phase.items).map((item) => [item.id, item]));
|
||||
|
||||
expect(items.get("PHX-002")).toMatchObject({
|
||||
status: "completed",
|
||||
attempts: 2,
|
||||
deliveryId: "delivery-phx-002",
|
||||
completionEvidence: expect.arrayContaining(["merge:abc"]),
|
||||
});
|
||||
expect(items.get("assignment-1")).toMatchObject({ source: "user_assignment", status: "pending" });
|
||||
expect(items.get("PHX-004")).toMatchObject({ dependsOn: ["PHX-003"], status: "pending" });
|
||||
});
|
||||
});
|
||||
Reference in new issue
Block a user