Skip to content

Where people and agents ship software together. The open-source git platform for the whole job: issues, agents, checks and deploys to the edge.

382 linesCodeBlameRaw
1import assert from "node:assert/strict";
2import { test } from "node:test";
3
4import type { SignalAuthor, SignalPull, SignalWeek, Usage, WorkspaceSignals } from "@g1t/contracts";
5
6import {
7 type SignalContext,
8 type WeekTotals,
9 agentStep,
10 blockedSignal,
11 dayList,
12 emptySignals,
13 findings,
14 mergeSignals,
15 newGround,
16 newHabits,
17 pulse,
18 quarterStart,
19 quietHeadline,
20 reviewSignal,
21 reworkSignal,
22 rhythm,
23 shippedSignal,
24 short,
25 signalsRange,
26 silos,
27 spendFlow,
28 spendSignal,
29 spoken,
30 stalledSignal,
31 weekStarts,
32 weekTotals,
33 weeklySpend,
34} from "./signals.ts";
35
36const NOW = Date.parse("2026-10-18T15:00:00Z");
37const DAY = 86_400_000;
38const repos = { r1: { namespace: "acme", name: "web" }, r2: { namespace: "acme", name: "tax" } };
39
40function week(start: string, fields: Partial<WeekTotals> = {}): WeekTotals {
41 return { start, merged: 0, agentMerged: 0, agentReworked: 0, agentDrafted: 0, agentDraftSeconds: 0, reviewed: 0, reviewSeconds: 0, stalled: 0, ...fields };
42}
43
44function usage(fields: Partial<Usage> = {}): Usage {
45 return {
46 since: "",
47 spentMicros: 0,
48 costMicros: 0,
49 providerMicros: 0,
50 usedMicros: 0,
51 free: false,
52 runs: 0,
53 byDay: [],
54 byTask: [],
55 byRepo: [],
56 byPull: [],
57 byModel: [],
58 addedMicros: 0,
59 ...fields,
60 };
61}
62
63function ctx(fields: Partial<SignalContext> = {}): SignalContext {
64 return { slug: "acme", now: NOW, repos, signals: emptySignals(), weeks: [], quarterUsage: null, quarter: "2026-10-01", ...fields };
65}
66
67function pull(fields: Partial<SignalPull>): SignalPull {
68 return {
69 repoId: "r1",
70 number: 1,
71 title: "A change",
72 status: "merged",
73 agent: false,
74 ownerId: "u1",
75 ownerName: "ana",
76 createdAt: "2026-10-05T00:00:00Z",
77 mergedAt: "2026-10-06T00:00:00Z",
78 item: null,
79 milestone: null,
80 ...fields,
81 };
82}
83
84function author(fields: Partial<SignalAuthor>): SignalAuthor {
85 return {
86 repoId: "r1",
87 ownerId: "u1",
88 ownerName: "ana",
89 firstMergedAt: "2026-01-01T00:00:00Z",
90 lastMergedAt: "2026-10-10T00:00:00Z",
91 merged: 10,
92 recent: 10,
93 ...fields,
94 };
95}
96
97test("weeks of seven days end with the last day, and the quarter starts on its first month", () => {
98 assert.deepEqual(weekStarts("2026-10-18", 3), ["2026-09-28", "2026-10-05", "2026-10-12"]);
99 assert.deepEqual(dayList("2026-10-18", 3), ["2026-10-16", "2026-10-17", "2026-10-18"]);
100 assert.equal(quarterStart("2026-10-18"), "2026-10-01");
101 assert.equal(quarterStart("2026-03-31"), "2026-01-01");
102 assert.equal(quarterStart("2026-08-02"), "2026-07-01");
103 // The reach covers a milestone's build even early in a quarter.
104 assert.equal(signalsRange(NOW).since, "2026-06-20");
105});
106
107test("batches add up per repository, and quiet weeks stay in the line", () => {
108 const rows: SignalWeek[] = [
109 { repoId: "r1", ...week("2026-10-12", { merged: 2, agentMerged: 1 }) },
110 { repoId: "r2", ...week("2026-10-12", { merged: 3, agentMerged: 3, stalled: 1 }) },
111 { repoId: "r9", ...week("2026-01-01", { merged: 9 }) },
112 ];
113 const totals = weekTotals(rows, ["2026-10-05", "2026-10-12"]);
114 assert.deepEqual(
115 totals.map((w) => [w.start, w.merged, w.agentMerged, w.stalled]),
116 [
117 ["2026-10-05", 0, 0, 0],
118 ["2026-10-12", 5, 4, 1],
119 ],
120 );
121 assert.equal(weekTotals(rows, ["2026-10-12"], new Set(["r1"]))[0]!.merged, 2);
122 const a: WorkspaceSignals = {
123 ...emptySignals(),
124 items: [{ number: 4, title: "Old", state: "open", milestone: null }],
125 waiting: [{ repoId: "r1", number: 2, title: "b", createdAt: "2026-10-02", agent: false, draftSeconds: null, item: null, blocks: [] }],
126 };
127 const b: WorkspaceSignals = {
128 ...emptySignals(),
129 items: [{ number: 4, title: "Old", state: "open", milestone: null }],
130 waiting: [{ repoId: "r2", number: 1, title: "a", createdAt: "2026-10-01", agent: false, draftSeconds: null, item: null, blocks: [] }],
131 };
132 const merged = mergeSignals([a, b]);
133 assert.equal(merged.items.length, 1, "an item named by two batches is one item");
134 assert.deepEqual(
135 merged.waiting.map((w) => w.number),
136 [1, 2],
137 "the oldest waits first across batches",
138 );
139});
140
141test("usage by day falls into its week", () => {
142 const spend = weeklySpend(
143 usage({
144 byDay: [
145 { key: "2026-10-12/review", micros: 5, runs: 1 },
146 { key: "2026-10-18/run", micros: 7, runs: 1 },
147 { key: "2026-10-11/run", micros: 3, runs: 1 },
148 ],
149 }),
150 ["2026-10-05", "2026-10-12"],
151 );
152 assert.deepEqual(spend, [3, 12]);
153 assert.equal(weeklySpend(null, ["2026-10-12"]), null, "usage that did not answer is not zero");
154});
155
156test("the pulse says each figure against last week, and whether that is good news", () => {
157 const weeks = [
158 week("2026-10-05", { merged: 60, agentMerged: 52, agentReworked: 11, stalled: 16 }),
159 week("2026-10-12", { merged: 70, agentMerged: 61, agentReworked: 11, stalled: 23 }),
160 ];
161 const tiles = pulse({ slug: "acme", weeks, spend: [52 * 72_000_000, 61 * 86_000_000] });
162 const by = Object.fromEntries(tiles.map((tile) => [tile.key, tile]));
163 assert.equal(by.merges!.value, "61");
164 assert.deepEqual(by.merges!.delta, { text: "+9", tone: "good" });
165 assert.equal(by.spend!.value, "$86");
166 assert.deepEqual(by.spend!.delta, { text: "+$14", tone: "bad" }, "spend going up is not good news");
167 assert.deepEqual(by.stalled!.delta, { text: "+7", tone: "bad" });
168 assert.equal(by.rework!.value, "18%");
169 assert.equal(by.rework!.delta!.text, "−3.1 pts");
170 assert.equal(by.rework!.delta!.tone, "good");
171 const unknown = pulse({ slug: "acme", weeks, spend: null });
172 assert.equal(unknown.find((tile) => tile.key === "spend")!.value, "—", "no usage, no figure");
173 assert.equal(unknown.find((tile) => tile.key === "spend")!.delta, null);
174});
175
176test("the change holding up the most work items leads, with what it holds up", () => {
177 const signals = {
178 ...emptySignals(),
179 waiting: [
180 { repoId: "r1", number: 7, title: "Small", createdAt: "2026-10-10T00:00:00Z", agent: true, draftSeconds: 600, item: 3, blocks: [4] },
181 {
182 repoId: "r2",
183 number: 4821,
184 title: "Nexus threshold configuration",
185 createdAt: "2026-10-16T15:00:00Z",
186 agent: true,
187 draftSeconds: 600,
188 item: 5,
189 blocks: [8, 9, 10],
190 },
191 { repoId: "gone", number: 1, title: "Unreadable", createdAt: "2026-10-01T00:00:00Z", agent: false, draftSeconds: null, item: 1, blocks: [2, 3, 4, 5] },
192 ],
193 };
194 const signal = blockedSignal(ctx({ signals }))!;
195 assert.equal(signal.headline, "Three work items are waiting on one unreviewed change.");
196 assert.deepEqual(signal.facts, ["tax#4821 Nexus threshold configuration", "open 2 days", "holds up #8, #9, #10"]);
197 assert.equal(signal.link!.to, "/acme/tax/pull/4821");
198 assert.equal(blockedSignal(ctx()), null);
199});
200
201test("a quick draft waiting long for review is said with both times; a slowdown alone is said against the weeks before", () => {
202 const weeks = [
203 week("2026-09-28", { reviewed: 4, reviewSeconds: 4 * 0.8 * 86400 }),
204 week("2026-10-05", { reviewed: 4, reviewSeconds: 4 * 1.2 * 86400 }),
205 week("2026-10-12", { reviewed: 10, reviewSeconds: 10 * 2.1 * 86400, agentDrafted: 5, agentDraftSeconds: 5 * 48 * 60 }),
206 ];
207 const gap = reviewSignal(ctx({ weeks }))!;
208 assert.equal(gap.headline, "Changes an agent drafts in under an hour are waiting 2.1 days for first review.");
209 assert.deepEqual(gap.facts, ["48m to draft", "2.1d to first review", "this week"]);
210 assert.equal(gap.trend!.range, "19h → 2.1d over 3 weeks");
211 const slower = reviewSignal(ctx({ weeks: weeks.map((w, i) => (i === 2 ? { ...w, agentDrafted: 0, agentDraftSeconds: 0 } : w)) }))!;
212 assert.match(slower.headline, /^First reviews are taking 2\.1 days, up from a day in the weeks before\.$/);
213 assert.equal(reviewSignal(ctx({ weeks: [week("2026-10-12")] })), null, "no reviews, nothing to say");
214});
215
216test("spend that concentrates in one milestone is a finding; spread-out spend is not", () => {
217 const signals = {
218 ...emptySignals(),
219 milestones: [{ number: 1, title: "the Checkout replatform", state: "open", dueOn: null, createdAt: "2026-08-01T00:00:00Z", closedAt: null }],
220 items: [{ number: 5, title: "Tax cutover", state: "open", milestone: 1 }],
221 pulls: [pull({ number: 1, item: 5, milestone: 1 }), pull({ number: 2 }), pull({ repoId: "r2", number: 3 })],
222 };
223 const quarterUsage = usage({
224 byPull: [
225 { key: "acme/web#1", micros: 28_300_000_000, runs: 1 },
226 { key: "acme/web#2", micros: 14_000_000_000, runs: 1 },
227 { key: "acme/tax#3", micros: 10_100_000_000, runs: 1 },
228 ],
229 });
230 const signal = spendSignal(ctx({ signals, quarterUsage }))!;
231 assert.equal(signal.headline, "More than half of this quarter's agent spend is going into the Checkout replatform.");
232 assert.deepEqual(signal.facts, ["$28.3K of $52.4K", "quarter to date"]);
233 const even = usage({ byPull: quarterUsage.byPull.map((slice) => ({ ...slice, micros: 1_000_000 })) });
234 assert.equal(spendSignal(ctx({ signals, quarterUsage: even })), null);
235 assert.equal(spendSignal(ctx({ signals, quarterUsage: null })), null);
236});
237
238test("a milestone closed this week says when against its due date, and what it took", () => {
239 const closedAt = "2026-10-13T18:00:00Z";
240 const signals = {
241 ...emptySignals(),
242 milestones: [{ number: 2, title: "Single sign-on", state: "closed", dueOn: "2026-11-03", createdAt: "2026-07-28T00:00:00Z", closedAt }],
243 pulls: [
244 pull({ milestone: 2, number: 1 }),
245 pull({ milestone: 2, number: 2, repoId: "r2" }),
246 pull({ milestone: 2, number: 3, status: "closed", mergedAt: null }),
247 ],
248 };
249 const signal = shippedSignal(ctx({ signals }))!;
250 assert.equal(signal.headline, "Single sign-on shipped on Tuesday, three weeks ahead of schedule.");
251 assert.deepEqual(signal.facts, ["11 weeks in build", "2 changes", "2 projects"]);
252 const old = { ...signals, milestones: [{ ...signals.milestones[0]!, closedAt: "2026-09-01T00:00:00Z" }] };
253 assert.equal(shippedSignal(ctx({ signals: old })), null, "only the last week's");
254});
255
256test("stalled changes and rework are findings only when they moved", () => {
257 assert.equal(
258 stalledSignal(ctx({ weeks: [week("a", { stalled: 16 }), week("b", { stalled: 23 })] }))!.headline,
259 "23 changes have been open over a week, 7 more than last week.",
260 );
261 assert.equal(stalledSignal(ctx({ weeks: [week("a", { stalled: 16 }), week("b", { stalled: 17 })] })), null);
262 const steady = [1, 2, 3, 4].map((i) => week(`w${i}`, { agentMerged: 10, agentReworked: 1 }));
263 assert.match(
264 reworkSignal(ctx({ weeks: [...steady, week("now", { agentMerged: 10, agentReworked: 4 })] }))!.headline,
265 /^People asked for changes on 40% .* up from 10%\.$/,
266 );
267 assert.equal(reworkSignal(ctx({ weeks: [...steady, week("now", { agentMerged: 10, agentReworked: 1 })] })), null);
268});
269
270test("who works where: new ground, one person carrying a project, and a first agent merge", () => {
271 const recent = new Date(NOW - 3 * DAY).toISOString();
272 const authors = [
273 author({ ownerId: "u1", ownerName: "ana", repoId: "r1", recent: 9, merged: 40 }),
274 author({ ownerId: "u2", ownerName: "bo", repoId: "r1", firstMergedAt: recent, recent: 1, merged: 1 }),
275 author({ ownerId: "u2", ownerName: "bo", repoId: "r2", firstMergedAt: "2026-02-01T00:00:00Z", merged: 12, recent: 2 }),
276 ];
277 assert.deepEqual(
278 newGround(authors, NOW).map((row) => [row.name, row.repoId, row.elsewhere]),
279 [["bo", "r1", 12]],
280 );
281 const [silo] = silos(authors, NOW);
282 assert.equal(silo!.name, "ana");
283 assert.equal(silo!.share, 0.9);
284 assert.deepEqual(silo!.joining, [{ ownerId: "u2", name: "bo" }]);
285 const pulls = [1, 2, 3].map((n) => pull({ number: n, mergedAt: `2026-09-0${n}T00:00:00Z` }));
286 const habits = newHabits([...pulls, pull({ number: 9, agent: true, mergedAt: recent })], NOW);
287 assert.deepEqual(
288 habits.map((row) => [row.name, row.byHand]),
289 [["ana", 3]],
290 );
291 const signal = findings(ctx({ signals: { ...emptySignals(), authors } })).find((s) => s.key === "ground")!;
292 assert.equal(signal.headline, "bo is starting to work in web, which ana has carried almost alone.");
293});
294
295test("findings come highest first, and a quiet week still says something", () => {
296 const signals = {
297 ...emptySignals(),
298 waiting: [{ repoId: "r1", number: 2, title: "Fix", createdAt: "2026-10-16T00:00:00Z", agent: false, draftSeconds: null, item: 1, blocks: [3, 4] }],
299 };
300 const found = findings(ctx({ signals, weeks: [week("a", { stalled: 1 }), week("b", { stalled: 10 })] }));
301 assert.deepEqual(
302 found.map((s) => s.key),
303 ["blocked", "stalled"],
304 );
305 assert.equal(quietHeadline(week("x")), "A quiet week: nothing has merged yet, and nothing is stuck.");
306 assert.equal(
307 quietHeadline(week("x", { merged: 4, agentMerged: 2 })),
308 "Four changes merged this week, 50% of them an agent's, and nothing needs a closer look.",
309 );
310});
311
312test("waits are said in words and in a few characters", () => {
313 assert.equal(spoken(48 * 60), "48 minutes");
314 assert.equal(spoken(5 * 3600), "5 hours");
315 assert.equal(spoken(2.1 * 86400), "2.1 days");
316 assert.equal(short(48 * 60), "48m");
317 assert.equal(short(5.5 * 3600), "5.5h");
318 assert.equal(short(null), "—");
319});
320
321test("the spend flow threads each pull request through its milestone, work item and project", () => {
322 const signals = {
323 ...emptySignals(),
324 milestones: [{ number: 1, title: "Checkout replatform", state: "open", dueOn: null, createdAt: "2026-08-01T00:00:00Z", closedAt: null }],
325 items: [{ number: 5, title: "Tax service cutover", state: "open", milestone: 1 }],
326 pulls: [
327 pull({ number: 1, item: 5, milestone: 1, agent: true, createdAt: "2026-10-02T00:00:00Z" }),
328 pull({ number: 2, item: 5, milestone: 1, repoId: "r2", createdAt: "2026-10-03T00:00:00Z" }),
329 pull({ number: 3, createdAt: "2026-10-04T00:00:00Z" }),
330 pull({ number: 4, createdAt: "2026-05-01T00:00:00Z", mergedAt: "2026-05-02T00:00:00Z" }),
331 ],
332 };
333 const flow = spendFlow({
334 slug: "acme",
335 repos,
336 signals,
337 quarter: "2026-10-01",
338 quarterUsage: usage({ byPull: [{ key: "acme/web#1", micros: 900, runs: 1 }] }),
339 });
340 assert.deepEqual(
341 flow.map((node) => [node.label, node.pulls, node.agent, node.micros]),
342 [
343 ["Checkout replatform", 2, 1, 900],
344 ["No milestone", 1, 0, 0],
345 ],
346 "last quarter's work is left out; the costliest comes first",
347 );
348 const item = flow[0]!.children[0]!;
349 assert.equal(item.label, "Tax service cutover");
350 assert.deepEqual(
351 item.children.map((set) => [set.label, set.list!.map((p) => p.number)]),
352 [
353 ["web", [1]],
354 ["tax", [2]],
355 ],
356 );
357 assert.equal(agentStep(0.71), 3);
358 assert.equal(agentStep(0.1), 0);
359});
360
361test("the rhythm adds each group's days and leaves out groups with nothing", () => {
362 const days = [
363 { repoId: "r1", day: "2026-10-17", opened: 2, merged: 1, agentMerged: 1, reworked: 0, reviews: 3, sessions: 4 },
364 { repoId: "r2", day: "2026-10-18", opened: 1, merged: 0, agentMerged: 0, reworked: 1, reviews: 0, sessions: 0 },
365 ];
366 const rows = rhythm(
367 days,
368 ["2026-10-17", "2026-10-18"],
369 [
370 { key: "pay", label: "Payments", note: "3 people", to: "/t/pay", repoIds: ["r1", "r2"] },
371 { key: "idle", label: "Idle", note: "", to: "/t/idle", repoIds: ["r9"] },
372 ],
373 );
374 assert.equal(rows.length, 1);
375 assert.deepEqual(
376 rows[0]!.days.map((day) => [day.opened, day.reviews, day.sessions, day.reworked]),
377 [
378 [2, 3, 4, 0],
379 [1, 0, 0, 1],
380 ],
381 );
382});