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