Fork Horse repository, listed by its owner. Publisher snapshot.
packages/forkhorse-dashboard/test/fork-graph-fixtures.ts
Snapshot at 34e3175
1import type { StateResponse } from "../src/contracts.ts";
2import { fixtureState, fixtureReceipt } from "./fixtures.ts";
3export const forkScenarios = [
4 "fork-hero",
5 "fork-history",
6 "fork-hour-edge",
7 "fork-states",
8 "fork-in-progress",
9 "fork-resolved",
10 "fork-old",
11 "fork-many",
12 "fork-empty",
13 "fork-dense",
14 "fork-live",
15];
16/** Clock-relative, explicitly fictional loopback fixtures. No browser clock freezing needed. */
17export function forkFixtureState(id: string, now = Date.now()): StateResponse {
18 const state = fixtureState("quiet");
19 state.project.id = id;
20 state.project.repoName = "fixture-project";
21 const at = (minutes: number) => new Date(now - minutes * 60000).toISOString();
22 state.agents = [
23 { name: "fixture-alpha", createdAt: null },
24 { name: "fixture-beta", createdAt: null },
25 { name: "fixture-gamma", createdAt: at(400) },
26 ];
27 if (id === "fork-empty") return state;
28 const names = state.agents.map((a) => a.name);
29 state.packets = [];
30 state.forks = [];
31 state.claims = [];
32 state.reviews = [];
33 state.activity = [];
34 state.ledger = [];
35 for (let i = 0; i < (id === "fork-many" ? 11 : id === "fork-states" ? 7 : 3); i++) {
36 const agent = names[i % 3],
37 packet = `fixture-${String(i + 1).padStart(2, "0")}`,
38 repoName = `fixture-fork-${i + 1}`,
39 sha = String(i + 1)
40 .repeat(40)
41 .slice(0, 40);
42 state.packets.push({
43 id: packet,
44 title: `Fixture packet ${i + 1}`,
45 goal: "Fixture graph evidence",
46 paths: [`fixture-${i}/**`],
47 acceptance: ["Fixture checks"],
48 });
49 state.forks.push({
50 agent,
51 repoName,
52 head: sha,
53 remote: "https://git.idiot.tax/fixture",
54 createdAt: at(220),
55 });
56 if (i !== 0)
57 state.claims.push({
58 packet,
59 agent,
60 repoName,
61 paths: [`fixture-${i}/**`],
62 createdAt: at(id === "fork-old" ? 500 : 180 - i * 20),
63 });
64 const status =
65 id === "fork-states"
66 ? (
67 [
68 "passed",
69 "passed",
70 "running",
71 "failed",
72 "timed-out",
73 "infrastructure-error",
74 "passed",
75 ] as const
76 )[i]
77 : i === 2
78 ? "running"
79 : "passed";
80 const approved = id === "fork-states" ? i < 2 : i !== 2;
81 const receipt = {
82 ...fixtureReceipt(status),
83 startedAt: at(75 - i * 10),
84 finishedAt: status === "running" ? null : at(70 - i * 10),
85 };
86 state.reviews.push({
87 id: `fixture-review-${i}`,
88 packet,
89 repoName,
90 agent,
91 sha,
92 base: "a".repeat(40),
93 receiptDigest: receipt.digest,
94 receipt,
95 approval: approved ? { sha, receiptDigest: receipt.digest } : null,
96 approvedAt: approved ? at(60 - i * 10) : null,
97 stale: false,
98 promoted: i === 0,
99 createdAt: at(100 - i * 10),
100 });
101 if (i === 1)
102 state.reviews.unshift({
103 ...state.reviews.at(-1)!,
104 id: "fixture-failed",
105 createdAt: at(120),
106 approval: null,
107 approvedAt: null,
108 receipt: { ...fixtureReceipt("failed"), startedAt: at(115), finishedAt: at(110) },
109 });
110 for (const [j, minute] of [150 - i * 10, 90 - i * 10].entries())
111 state.activity.push({
112 sequence: i * 2 + j + 1,
113 namespace: "fixture",
114 repoName,
115 agent,
116 ref: "refs/heads/main",
117 before: "a".repeat(40),
118 after: sha,
119 changedPaths: [`fixture-${i}/index.ts`],
120 eventTimestamp: at(minute + 2),
121 recordedAt: at(minute),
122 });
123 if (i === 0)
124 state.ledger.push({
125 id: "fixture-merge",
126 review: "fixture-review-0",
127 repoName: state.project.repoName,
128 ref: "refs/heads/main",
129 before: "a".repeat(40),
130 after: sha,
131 receiptDigest: receipt.digest,
132 recordedAt: at(30),
133 });
134 }
135 if (id === "fork-in-progress") {
136 // A claimed fork with no review remains In progress.
137 state.reviews = state.reviews.filter((review) => review.packet !== "fixture-02");
138 }
139 if (id === "fork-hour-edge") {
140 // Put an hour five seconds inside the recent window, independent of capture time.
141 state.claims[0].createdAt = new Date(
142 Math.floor(now / 3600000) * 3600000 - 4 * 3600000 - 5000,
143 ).toISOString();
144 }
145 if (id === "fork-history") {
146 const latest = state.reviews.find((r) => r.id === "fixture-review-1")!;
147 const basePush = state.activity.find((a) => a.repoName === latest.repoName)!;
148 for (const [i, minutes] of [130, 125, 115, 105, 95, 85].entries()) {
149 state.activity.push({
150 ...basePush,
151 sequence: 100 + i,
152 recordedAt: at(minutes),
153 eventTimestamp: at(minutes),
154 });
155 state.reviews.unshift({
156 ...latest,
157 id: `fixture-history-review-${i}`,
158 createdAt: at(minutes - 1),
159 approvedAt: at(minutes - 3),
160 receipt: { ...latest.receipt!, finishedAt: at(minutes - 2) },
161 });
162 }
163 const merged = state.reviews.find((r) => r.id === "fixture-review-0")!;
164 for (const [i, minutes] of [95, 70, 29, 27, 2].entries()) {
165 const sha = String(i + 4).repeat(40);
166 const review = {
167 ...merged,
168 id: `fixture-history-merge-${i}`,
169 sha,
170 createdAt: at(minutes + 5),
171 approvedAt: at(minutes + 2),
172 receipt: { ...merged.receipt!, finishedAt: at(minutes + 3) },
173 };
174 state.reviews.push(review);
175 state.ledger.push({
176 ...state.ledger[0],
177 id: `fixture-ledger-${i}`,
178 review: review.id,
179 after: sha,
180 recordedAt: at(minutes),
181 });
182 }
183 }
184 state.blockers = [
185 {
186 id: "fixture-collision",
187 packet: "fixture-03",
188 pushingPacket: "fixture-02",
189 claimingAgent: names[2],
190 pushingAgent: names[1],
191 repoName: "fixture-fork-2",
192 sha: "2".repeat(40),
193 paths: ["fixture-2/index.ts"],
194 at: at(85),
195 resolved: id === "fork-resolved" ? { at: at(40), by: "owner" } : null,
196 },
197 ];
198 if (id === "fork-dense") {
199 const review = state.reviews.find((r) => r.id === "fixture-review-1")!;
200 review.createdAt = at(45);
201 review.approvedAt = at(43);
202 review.receipt!.finishedAt = at(44);
203 state.activity.push({
204 ...state.activity[2],
205 sequence: 99,
206 recordedAt: at(46),
207 eventTimestamp: at(46),
208 });
209 state.blockers[0].at = at(44.5);
210 }
211 state.races = [
212 {
213 packet: "fixture-race",
214 status: "open",
215 finishedAt: null,
216 winner: null,
217 ledgerEntryId: null,
218 entrants: names.slice(0, 2).map((agent, i) => ({
219 agent,
220 repoName: `fixture-race-fork-${i}`,
221 claimedAt: at(35 - i * 2),
222 firstPushAt: i ? null : at(25),
223 reviewRequestedAt: null,
224 receiptPassedAt: null,
225 approvedAt: null,
226 promotedAt: null,
227 place: null,
228 closedAt: null,
229 closedBy: null,
230 })),
231 },
232 ];
233 state.packets.push({
234 id: "fixture-race",
235 title: "Fixture race",
236 goal: "Fixture",
237 paths: [],
238 acceptance: [],
239 mode: "race",
240 });
241 return state;
242}
243