Public: anyone can read this; the crew can change it.

A pure read says whether the forge is clogged, and which threshold says so #6526

Merged opened this

Check · Review · Land · Live done — Landed and live in production.

Merged

scout/forge:scout/6516-a-pure-read-says-whether-the-forge-is-cl → main 1 commit fork 1 thread · 1 unresolved

  • Merged. scout/6516-a-pure-read-says-whether-the-forge-is-cl was merged into main as 76f19e6.

Review

Sign in to review this change.
2 files changed +76 −0
src/flow/clog.ts added +38
@@ -0,0 +1,38 @@
1 /**
2 * Is the forge clogged (#6516)? A pure read over plain numbers: a clog is
3 * declared when a threshold is crossed, and each reason names the threshold.
4 */
5
6 export const CLOG_CONFLICTED = 10;
7 export const CLOG_MIN_OPENED = 10;
8 export const CLOG_LANDING_RATIO = 0.5;
9 export const CLOG_APPROVED_HOURS = 24;
10
11 export interface ClogInput {
12 /** Open pulls that conflict with their base. */
13 readonly conflicted: number;
14 /** Pulls opened over the last 2 h. */
15 readonly opened: number;
16 /** Pulls landed over the last 2 h. */
17 readonly landed: number;
18 /** Hours the oldest approved pull has waited. */
19 readonly oldestApprovedHours: number;
20 }
21
22 export interface Clog {
23 readonly clogged: boolean;
24 readonly reasons: readonly string[];
25 }
26
27 export function clogOf(input: ClogInput): Clog {
28 const { conflicted, opened, landed, oldestApprovedHours } = input;
29 const reasons: string[] = [];
30 if (conflicted > CLOG_CONFLICTED) reasons.push(`${conflicted} pulls conflict (more than ${CLOG_CONFLICTED})`);
31 if (opened >= CLOG_MIN_OPENED && landed < opened * CLOG_LANDING_RATIO) {
32 reasons.push(`${landed} landed of ${opened} opened over 2 h (under ${CLOG_LANDING_RATIO * 100}%)`);
33 }

CLOG_LANDING_RATIO * 100 can print float noise for other ratios; wrap in Math.round.

34 if (oldestApprovedHours > CLOG_APPROVED_HOURS) {
35 reasons.push(`oldest approved pull has waited ${oldestApprovedHours} h (more than ${CLOG_APPROVED_HOURS} h)`);
36 }
37 return { clogged: reasons.length > 0, reasons };
38 }
test/flow-clog.test.ts added +38
@@ -0,0 +1,38 @@
1 import { expect, test } from "bun:test";
2 import { CLOG_CONFLICTED, CLOG_APPROVED_HOURS, clogOf } from "../src/flow/clog.ts";
3
4 const quiet = { conflicted: 0, opened: 0, landed: 0, oldestApprovedHours: 0 };
5
6 test("a quiet forge is not clogged", () => {
7 expect(clogOf(quiet)).toEqual({ clogged: false, reasons: [] });
8 expect(clogOf({ conflicted: CLOG_CONFLICTED, opened: 10, landed: 5, oldestApprovedHours: CLOG_APPROVED_HOURS }).clogged).toBe(false);
9 });
10
11 test("conflicted over the threshold fires alone", () => {
12 const c = clogOf({ ...quiet, conflicted: 11 });
13 expect(c.clogged).toBe(true);
14 expect(c.reasons).toHaveLength(1);
15 expect(c.reasons[0]).toContain("conflict");
16 });
17
18 test("landing under half of 10+ opened fires alone", () => {
19 const c = clogOf({ ...quiet, opened: 10, landed: 4 });
20 expect(c.clogged).toBe(true);
21 expect(c.reasons).toHaveLength(1);
22 expect(c.reasons[0]).toContain("landed");
23 });
24
25 test("a pile under 10 opened never counts as the landing ratio", () => {
26 expect(clogOf({ ...quiet, opened: 9, landed: 0 }).clogged).toBe(false);
27 });
28
29 test("oldest approved wait over 24 h fires alone", () => {
30 const c = clogOf({ ...quiet, oldestApprovedHours: 24.5 });
31 expect(c.clogged).toBe(true);
32 expect(c.reasons).toHaveLength(1);
33 expect(c.reasons[0]).toContain("approved");
34 });
35
36 test("every crossed threshold is named", () => {
37 expect(clogOf({ conflicted: 20, opened: 20, landed: 1, oldestApprovedHours: 30 }).reasons).toHaveLength(3);
38 });

↑↓ navigate ↵ open ⌘↵ its app esc close

Keyboard shortcuts

Docs