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.

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