Fork Horse repository, listed by its owner. Publisher snapshot.
packages/forkhorse-dashboard/test/race-fixtures.ts
Snapshot at 34e3175
1import type { Race, RaceEntrant, StateResponse } from "../src/contracts.ts";
2import { fixtureReceipt, fixtureState, HEAD } from "./fixtures.ts";
3
4export const raceScenarios = [
5 "race-open",
6 "race-finished",
7 "race-photo",
8 "race-photo-unattempted",
9 "race-empty",
10 "race-loading",
11 "race-error",
12 "race-unknown",
13 "race-standard",
14 "race-advisory",
15 "race-reused-forks",
16 "race-timed-out",
17 "race-couldnt-run",
18 "race-two-digit",
19];
20const at = (seconds: number) =>
21 new Date(Date.parse("2026-10-13T14:02:00Z") + seconds * 1000).toISOString();
22const entrant = (
23 agent: string,
24 claimed: number,
25): RaceEntrant & {
26 closedBy: null | "release" | "owner" | "race-finished";
27 usage: { reported: null; metered: null };
28 budget: "unchecked";
29} => ({
30 agent,
31 repoName: `race--${agent}-1`,
32 claimedAt: at(claimed),
33 firstPushAt: null,
34 reviewRequestedAt: null,
35 receiptPassedAt: null,
36 approvedAt: null,
37 promotedAt: null,
38 place: null,
39 closedAt: null,
40 closedBy: null,
41 promoteRejected: null,
42 usage: { reported: null, metered: null },
43 budget: "unchecked",
44});
45// The contract test checks these slices against core's public declarations without
46// pulling the Worker environment into the browser package's compiler.
47export type RaceFixture = Omit<StateResponse, "races"> & {
48 agents: { name: string; createdAt: string | null }[];
49 races: (Race &
50 Required<Pick<Race, "finishedAt" | "winner" | "ledgerEntryId" | "places">> & {
51 tokenBudget: null;
52 judge: null;
53 verdict: null;
54 entrants: ReturnType<typeof entrant>[];
55 })[];
56 reviews: (StateResponse["reviews"][number] & {
57 receipt: NonNullable<StateResponse["reviews"][number]["receipt"]>;
58 returned: null;
59 })[];
60};
61/** Fixed offline FH-052/053 snapshots. Never implies an enrolled/live race. */
62export function raceFixtureState(scenario = "race-open"): RaceFixture {
63 const state: RaceFixture = {
64 ...fixtureState("quiet"),
65 agents: [],
66 races: [],
67 ledger: [],
68 reviews: [],
69 };
70 state.project.id = scenario;
71 state.project.repoName = "race-fixture";
72 state.project.settings = { requireReceipt: scenario !== "race-advisory" };
73 // Response order deliberately differs from stable identity and lane order.
74 state.agents = [
75 { name: "cedar", createdAt: "2026-10-13T14:00:00Z" },
76 { name: "amber", createdAt: null },
77 { name: "birch", createdAt: null },
78 ];
79 if (scenario === "race-two-digit") {
80 // Nine earlier enrollments exercise identities 10, 11 and 12, not race places.
81 state.agents.unshift(...Array.from({ length: 9 }, (_, index) => ({
82 name: `agent-${String(index + 1).padStart(2, "0")}`, createdAt: null,
83 })));
84 }
85 state.packets = [
86 {
87 id: "race-01",
88 title: "Add retries to the webhook client",
89 goal: "Retry transient webhook errors.",
90 paths: ["src/webhooks/**"],
91 acceptance: ["Retries stay bounded"],
92 mode: scenario === "race-standard" ? "standard" : "race",
93 },
94 ];
95 const birch = entrant("birch", 0),
96 cedar = entrant("cedar", 10),
97 amber = entrant("amber", 60);
98 Object.assign(birch, {
99 firstPushAt: at(240),
100 reviewRequestedAt: at(360),
101 receiptPassedAt: at(540),
102 });
103 Object.assign(cedar, {
104 firstPushAt: at(180),
105 reviewRequestedAt: at(300),
106 receiptPassedAt: at(480),
107 approvedAt: at(600),
108 });
109 const finished = ["race-finished", "race-photo", "race-photo-unattempted", "race-reused-forks", "race-timed-out", "race-couldnt-run", "race-two-digit"].includes(scenario);
110 const race: RaceFixture["races"][number] = {
111 packet: "race-01",
112 tokenBudget: null,
113 judge: null,
114 verdict: null,
115 status: finished ? ("finished" as const) : ("open" as const),
116 finishedAt: finished ? at(720) : null,
117 winner: finished ? "cedar" : null,
118 ledgerEntryId: finished ? "ledger-race-1" : null,
119 places: finished
120 ? [
121 { agent: "cedar", place: 1 },
122 { agent: "birch", place: 2 },
123 { agent: "amber", place: 3 },
124 ]
125 : [],
126 entrants: [amber, cedar, birch],
127 };
128 if (finished) {
129 Object.assign(cedar, {
130 promotedAt: at(720),
131 place: 1,
132 closedAt: at(720),
133 closedBy: "race-finished",
134 });
135 Object.assign(birch, {
136 approvedAt: scenario.startsWith("race-photo") ? at(660) : null,
137 place: 2,
138 closedAt: at(720),
139 closedBy: "race-finished",
140 });
141 Object.assign(amber, {
142 firstPushAt: at(420),
143 reviewRequestedAt: at(540),
144 place: 3,
145 closedAt: at(720),
146 closedBy: "race-finished",
147 });
148 if (scenario === "race-photo")
149 birch.promoteRejected = {
150 at: "2026-10-13T14:14:00.400Z",
151 expected: HEAD,
152 found: "c".repeat(40),
153 };
154 state.ledger = [
155 {
156 id: "ledger-race-1",
157 review: "race-review-cedar",
158 repoName: cedar.repoName,
159 ref: "refs/heads/main",
160 before: HEAD,
161 after: "c".repeat(40),
162 receiptDigest: "d".repeat(64),
163 recordedAt: at(720),
164 race: race.packet,
165 },
166 ];
167 }
168 if (scenario === "race-reused-forks") {
169 race.entrants = [cedar, birch];
170 race.places = race.places.filter((entry) => entry.agent !== "amber");
171 }
172 if (scenario === "race-advisory") cedar.receiptPassedAt = null;
173 if (scenario === "race-empty") race.entrants = [];
174 state.races = scenario === "race-standard" || scenario === "race-unknown" ? [] : [race];
175 state.forks = [birch, cedar, amber].map((entry, index) => ({
176 agent: entry.agent,
177 repoName: entry.repoName,
178 head: ["b", "c", "e"][index].repeat(40),
179 remote: `https://git.idiot.tax/${entry.repoName}`,
180 createdAt: entry.claimedAt,
181 }));
182 state.claims = race.entrants
183 .filter((entry) => !entry.closedAt)
184 .map((entry) => ({
185 packet: race.packet,
186 agent: entry.agent,
187 repoName: entry.repoName,
188 paths: state.packets[0].paths,
189 createdAt: entry.claimedAt,
190 }));
191 state.reviews = race.entrants
192 .filter((entry) => entry.reviewRequestedAt)
193 .map((entry) => {
194 const fork = state.forks.find((candidate) => candidate.repoName === entry.repoName)!;
195 const receipt = fixtureReceipt(
196 entry.agent === "amber" || (scenario === "race-advisory" && entry.agent === "cedar")
197 ? "failed"
198 : "passed",
199 );
200 if (entry.agent === "amber" && (scenario === "race-timed-out" || scenario === "race-couldnt-run"))
201 receipt.status = scenario === "race-timed-out" ? "timed-out" : "infrastructure-error";
202 receipt.startedAt = entry.reviewRequestedAt!;
203 receipt.finishedAt = entry.receiptPassedAt ?? at(600);
204 receipt.durationMs = Date.parse(receipt.finishedAt) - Date.parse(receipt.startedAt);
205 receipt.checks = [
206 {
207 name: "brand",
208 tier: "quick",
209 runtime: "dynamic-worker",
210 outcome: receipt.status,
211 durationMs: 13000,
212 },
213 ];
214 return {
215 id: `race-review-${entry.agent}`,
216 packet: race.packet,
217 repoName: entry.repoName,
218 agent: entry.agent,
219 sha: fork.head,
220 base: HEAD,
221 receiptDigest: receipt.digest,
222 receipt,
223 approval: entry.approvedAt ? { sha: fork.head, receiptDigest: receipt.digest } : null,
224 stale: finished && !entry.promotedAt,
225 promoted: !!entry.promotedAt,
226 returned: null,
227 createdAt: entry.reviewRequestedAt!,
228 };
229 });
230 state.activity = race.entrants
231 .filter((entry) => entry.firstPushAt)
232 .map((entry, index) => ({
233 sequence: index + 1,
234 namespace: "fixture",
235 repoName: entry.repoName,
236 agent: entry.agent,
237 ref: "refs/heads/main",
238 before: HEAD,
239 after: state.forks.find((fork) => fork.repoName === entry.repoName)!.head,
240 changedPaths: ["src/webhooks/client.ts"],
241 eventTimestamp: entry.firstPushAt!,
242 recordedAt: entry.firstPushAt!,
243 }));
244 // A canonical event at the first claim establishes loaded history coverage.
245 state.activity.unshift({
246 sequence: 0, namespace: "fixture", repoName: state.project.repoName, agent: null,
247 ref: "refs/heads/main", before: "f".repeat(40), after: HEAD, changedPaths: [],
248 eventTimestamp: at(0), recordedAt: at(0),
249 });
250 if (scenario === "race-reused-forks") {
251 const history = [birch, cedar].flatMap((entry, forkIndex) =>
252 Array.from({ length: forkIndex === 0 ? 19 : 2 }, (_, index) => ({
253 ...state.activity.find((event) => event.repoName === entry.repoName)!,
254 recordedAt: at(-60 * (index + 1)),
255 eventTimestamp: at(-60 * (index + 1)),
256 })),
257 );
258 state.activity = [...history, ...state.activity]
259 .toSorted((a, b) => Date.parse(a.recordedAt) - Date.parse(b.recordedAt))
260 .map((event, index) => ({ ...event, sequence: index + 1 }));
261 }
262 return state;
263}
264