@kud/gh 0.13.0 → 0.15.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/inbox.d.ts CHANGED
@@ -127,18 +127,26 @@ export type InboxQueryOptions = {
127
127
  * full first: 100 — ~11s 502, twice
128
128
  * minimal first: 100 1 pt 2.1s 200
129
129
  *
130
- * The 502 is the search timing out at GitHub's proxy rather than a node-count
131
- * refusal — cutting the review-thread window by 65% still 502s at ~11s — so
132
- * `first: 50` is the ceiling with a foot over the line, and a full fragment
133
- * cannot reach 99 at any window. A two-tier fetch can: the full shape at the
134
- * default cap for the rows that get a verdict, then `{ shape: "minimal",
135
- * limits: { reviewRequests: 100 } }` for the rest.
130
+ * The 502 is a wall-clock refusal rather than a node-count one — cutting the
131
+ * review-thread window by 65% still 502s at ~11s — so `first: 50` is the
132
+ * ceiling with a foot over the line, and a full fragment cannot reach 99 at
133
+ * any window. A two-tier fetch can: the full shape at the default cap for the
134
+ * rows that get a verdict, then `{ shape: "minimal", limits: {
135
+ * reviewRequests: 100 } }` for the rest.
136
+ *
137
+ * This note used to name the SEARCH as what was timing out, and that was
138
+ * wrong in a way worth keeping visible: it made the fix look like "address
139
+ * the rows directly and the problem goes away". It does not. A `nodes(ids:)`
140
+ * lookup with the same selections dies at the same size and the same eleven
141
+ * seconds — see `HEALTH_BATCH_SIZE`, where it is measured. What the request
142
+ * came through was never the variable; how many nodes it had to expand was.
136
143
  *
137
144
  * A caller doing that owes the overflow rows an honest verdict. A minimal row
138
145
  * carries no health, and health absent is not health `waiting` — see
139
146
  * `computeHealth`'s note on why this set is all-or-nothing, and
140
147
  * `@kud/gh-workflow`'s `whoseMove`, which answers `unknown` rather than
141
- * guessing.
148
+ * guessing. `healthIdsFrom` / `buildHealthQueries` / `mergeHealth` are the
149
+ * third tier that pays that debt where the caller wants the verdicts.
142
150
  */
143
151
  limits?: Partial<Record<InboxSource, number>>;
144
152
  };
@@ -201,14 +209,44 @@ export declare const buildInboxQueries: (options?: InboxQueryOptions & {
201
209
  * moment.
202
210
  */
203
211
  export declare const mergeInboxData: (parts: any[]) => any;
204
- /** What a source matched, against what it was allowed to return. */
212
+ /**
213
+ * What a source matched, against what it was allowed to return.
214
+ *
215
+ * TWO FACTS AND AN ESTIMATE, and keeping them apart is the whole of this type.
216
+ * `shown` and `cap` are ours — what we asked for and what came back. `total` is
217
+ * GitHub's, and it has been caught wrong.
218
+ */
205
219
  export type SourceCoverage = {
206
- /** Everything the search matched, from GitHub's own `issueCount`. */
220
+ /**
221
+ * What GitHub's `issueCount` said the search matched.
222
+ *
223
+ * AN ESTIMATE. It may be shown to a reader as an approximation and it may
224
+ * never decide whether anything is reported — see the note on `capped`.
225
+ */
207
226
  total: number;
208
- /** What actually came back — at most this source's cap. */
227
+ /** How many rows actually came back. */
209
228
  shown: number;
210
- /** `total > shown`: the rows are a sample of the set, not the set. */
211
- truncated: boolean;
229
+ /** The `first:` this source asked for on this fetch. */
230
+ cap: number;
231
+ /**
232
+ * We asked for N and got N, so the rows are a sample of the set.
233
+ *
234
+ * Derived from our own request rather than from `total`, which is the entire
235
+ * point: a cap is a fact we hold, and it cannot be wrong about itself.
236
+ */
237
+ capped: boolean;
238
+ /**
239
+ * Under its cap, and the count still claims more matched.
240
+ *
241
+ * Nothing was capped and rows are missing anyway, so this is an incomplete
242
+ * ANSWER rather than a truncation, and it belongs with whatever vocabulary a
243
+ * host uses for a source that failed. Reporting it as a cap names a mechanism
244
+ * that was not operating, which is worse than saying nothing.
245
+ *
246
+ * It rests on `total` and therefore inherits its unreliability: read it as a
247
+ * suspicion, never as a count of what is missing.
248
+ */
249
+ partial: boolean;
212
250
  };
213
251
  /**
214
252
  * What each source could see, against what it was allowed to show.
@@ -221,17 +259,136 @@ export type SourceCoverage = {
221
259
  * 30-row window reorders it, evicts something, and the eviction is reported as
222
260
  * news about the row that left — which never moved at all.
223
261
  *
224
- * So a consumer should treat presence changes on a truncated source as carrying
225
- * no information, and say what it is not showing instead. Both halves need this
226
- * number, and until 2026-09-07 it was fetched for exactly one source out of
227
- * eight and read by nobody — the guarantee lived in a comment and not in the
228
- * code.
262
+ * So a consumer should treat presence changes on a capped source as carrying no
263
+ * information, and say what it is not showing instead.
264
+ *
265
+ * `issueCount` USED TO DECIDE THAT, AND IT CANNOT. Until 2026-09-09 this
266
+ * returned `truncated: total > shown`, which reads as a cap and is not one:
267
+ * `issueCount` is an index aggregate computed on a different path from the node
268
+ * materialisation, and the two are not a consistent snapshot. Measured that day
269
+ * against a live account, one sweep, immediately after an eight-source document
270
+ * had returned HTTP 502:
271
+ *
272
+ * myPRs issueCount 8 nodes 16 cap 30
273
+ * reviewed issueCount 13 nodes 10 cap 20
274
+ * repoIssues issueCount 111 nodes 83 cap 100
275
+ * repoPRs issueCount 4 nodes 5 cap 30
276
+ * recentlyDone issueCount 19 nodes 14 cap 30
277
+ *
278
+ * The first and fourth rows are the proof, and they are the reason this is a
279
+ * rule rather than a hunch: THE COUNT CAME BACK SMALLER THAN THE SAMPLE DRAWN
280
+ * FROM IT. A total that is exceeded by its own subset is not a total. Re-run
281
+ * seconds later, every pair agreed, and 24 subsequent runs of the real query
282
+ * agreed too — so the number is not merely stale, it is untrustworthy at
283
+ * unpredictable moments, which is worse. What made it go wrong was never
284
+ * established and does not need to be: the replacement does not consult it.
285
+ *
286
+ * What that cost downstream is a host reporting five capped sources of which
287
+ * not one was near its cap, explaining each with a sentence about caps. A true
288
+ * sentence about a false situation is the hardest kind of wrong to read, and
289
+ * the reader correctly could not parse it.
229
290
  *
230
291
  * A source that answered with no `issueCount` reports `total: shown`, which
231
- * reads as "not truncated". That is the deliberate direction to fail in: a
232
- * missing count must never invent a truncation and silence real news.
292
+ * reads as neither capped nor partial unless the cap says otherwise. That is
293
+ * the deliberate direction to fail in: a missing count must never invent a
294
+ * truncation and silence real news.
295
+ *
296
+ * `limits` must be the ones the fetch ACTUALLY asked for, not the defaults, or
297
+ * the cap this compares against is a different number from the one GitHub
298
+ * honoured — a two-tier host raising `reviewRequests` to 100 and then measuring
299
+ * against 20 would call every fetch capped forever.
300
+ */
301
+ export declare const sourceCoverage: (data: any, limits?: Partial<Record<InboxSource, number>>) => Partial<Record<InboxSource, SourceCoverage>>;
302
+ /**
303
+ * The sources whose rows are a sample rather than the set.
304
+ *
305
+ * This is what a two-tier host asks before spending a second round trip, so it
306
+ * has to be the CAP question and not the count one — an overflow fetch fired on
307
+ * a bad `issueCount` buys nothing and costs a request.
308
+ *
309
+ * Coverage is computed once rather than per source. It was once rebuilt inside
310
+ * the filter, which walked all eight sources eight times to answer about eight.
311
+ */
312
+ export declare const cappedSources: (data: any, limits?: Partial<Record<InboxSource, number>>) => InboxSource[];
313
+ /**
314
+ * How many PR ids one health request may carry.
315
+ *
316
+ * The third tier's whole reason for existing, so it is a measurement rather than
317
+ * a taste. Measured 2026-09-09 on a live account with 102 matching review
318
+ * requests, asking for the real `PR_HEALTH` + `PR_CONVERSATION` selections by
319
+ * node id:
320
+ *
321
+ * nodes(ids:) 100 — ~11s 502, twice
322
+ * nodes(ids:) 50 28 pts 8.7s 200 (6,200 nodes)
323
+ * nodes(ids:) 25 14 pts 4.0s 200 (3,100 nodes)
324
+ * 4 × 25 in parallel 56 pts 6.0s wall 200 ×4
325
+ *
326
+ * WHICH CORRECTS THE NOTE ON `limits` ABOVE, and the correction is the useful
327
+ * half: the 502 at `first: 100` was read there as the SEARCH timing out at
328
+ * GitHub's proxy. It is not. A direct node lookup — no search index involved at
329
+ * all — fails identically, at the same size and the same eleven seconds. What
330
+ * dies is the resolver's wall clock expanding ~12,000 nodes of check rollups and
331
+ * review threads, whichever door the request came through. The search endpoint
332
+ * was innocent.
333
+ *
334
+ * So batching is the MECHANISM here, not an optimisation of it: a tier three
335
+ * that fired one 100-id request would reproduce the exact failure it exists to
336
+ * fix. Cost per PR is 0.56 points either way — GraphQL prices nodes, not
337
+ * requests — so splitting buys reliability at no extra budget, exactly as
338
+ * `INBOX_SOURCES_PER_QUERY` does one level up.
339
+ */
340
+ export declare const HEALTH_BATCH_SIZE = 25;
341
+ /**
342
+ * PR node ids on this data that arrived WITHOUT the health selection.
343
+ *
344
+ * The filter is load-bearing rather than tidiness. A two-tier fetch merges the
345
+ * cheap overflow after the full rows precisely so a URL collision keeps the
346
+ * full one, which means a naive "every id here" would re-fetch the rows that
347
+ * already carry a verdict — on a 102-row account that is ~11 points bought to
348
+ * learn what tier one already answered.
349
+ *
350
+ * `sources` narrows it further, and a caller should use it: only the PR sources
351
+ * can be enriched at all, and the issue sources that truncate carry no health to
352
+ * begin with.
353
+ */
354
+ export declare const healthIdsFrom: (data: any, sources?: readonly InboxSource[]) => string[];
355
+ /**
356
+ * One `nodes(ids:)` document carrying the health and conversation selections for
357
+ * PRs already identified elsewhere.
358
+ *
359
+ * BOTH fragments, and health alone would be a bug. `computeHealth`'s precedence
360
+ * reads `unresolvedThreads` out of `reviewThreads`, which lives in
361
+ * `PR_CONVERSATION` — so a health-only enrichment would report `waiting` on a PR
362
+ * with open threads, which is the silent wrong token this whole set is
363
+ * all-or-nothing to prevent, one layer down.
364
+ *
365
+ * It also costs almost nothing to include: `reviewThreads` is ~100 of the ~124
366
+ * nodes a PR drags, so the rest of the conversation rides along nearly free —
367
+ * and an enriched overflow row comes out FULLY equal to a tier-one row, with its
368
+ * last actor and activity age intact, rather than a second-class one carrying a
369
+ * token and no story behind it.
370
+ */
371
+ export declare const buildHealthQuery: (ids: readonly string[]) => string;
372
+ /**
373
+ * The same, split into documents small enough to answer — to be issued in
374
+ * parallel and handed to `mergeHealth`.
375
+ *
376
+ * Prefer this to `buildHealthQuery` for anything but a handful of ids. See
377
+ * `HEALTH_BATCH_SIZE` for why the split is the mechanism.
378
+ */
379
+ export declare const buildHealthQueries: (ids: readonly string[], batchSize?: number) => string[];
380
+ /**
381
+ * Merge tier-three health onto the rows that were fetched without it.
382
+ *
383
+ * By node id, and all-or-nothing per node — a batch that failed merges nothing,
384
+ * a node that merges nothing keeps no health keys, `healthOf` reads the absence
385
+ * and `whoseMove` answers `unknown`. The invariant holds by CONSTRUCTION rather
386
+ * than by a flag anyone has to remember to pass, which is the same reason
387
+ * `@kud/gh-workflow` tests presence instead of trusting its caller.
388
+ *
389
+ * Returns a new object; the input is not mutated, because a caller merging the
390
+ * enriched copy alongside the original relies on the original still being what
391
+ * it was.
233
392
  */
234
- export declare const sourceCoverage: (data: any) => Partial<Record<InboxSource, SourceCoverage>>;
235
- /** The sources whose rows are a sample rather than the set. */
236
- export declare const truncatedSources: (data: any) => InboxSource[];
393
+ export declare const mergeHealth: (data: any, parts: readonly any[]) => any;
237
394
  //# sourceMappingURL=inbox.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CASrD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAA;AAE3C,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,UAAU,GACV,YAAY,GACZ,gBAAgB,GAChB,SAAS,GACT,cAAc,CAAA;AAElB,oEAAoE;AACpE,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAS/C,CAAA;AAED,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OA8BG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;CAC9C,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GACpB,UAAS,iBAAsB,KAC9B,MAAM,CAAC,WAAW,EAAE,MAAM,CAQ5B,CAAA;AAgSD,eAAO,MAAM,eAAe,GAAI,UAAS,iBAAsB,WAsB9D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAS,iBAAiB,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,KAC7D,MAAM,EAYR,CAAA;AASD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,GAAG,EAAE,KAAG,GA8B7C,CAAA;AAED,oEAAoE;AACpE,MAAM,MAAM,cAAc,GAAG;IAC3B,qEAAqE;IACrE,KAAK,EAAE,MAAM,CAAA;IACb,2DAA2D;IAC3D,KAAK,EAAE,MAAM,CAAA;IACb,sEAAsE;IACtE,SAAS,EAAE,OAAO,CAAA;CACnB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,GAAG,KACR,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAc7C,CAAA;AAED,+DAA+D;AAC/D,eAAO,MAAM,gBAAgB,GAAI,MAAM,GAAG,KAAG,WAAW,EACmB,CAAA"}
1
+ {"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"AAQA;;;;;;;;;;;;;GAaG;AACH;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,YAAY,KAAK,CAAA;AAE9B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA8CG;AACH,eAAO,MAAM,aAAa,EAAE,MAAM,CAAC,WAAW,EAAE,MAAM,CASrD,CAAA;AAED,MAAM,MAAM,UAAU,GAAG,MAAM,GAAG,SAAS,CAAA;AAE3C,0EAA0E;AAC1E,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,gBAAgB,GAChB,UAAU,GACV,UAAU,GACV,YAAY,GACZ,gBAAgB,GAChB,SAAS,GACT,cAAc,CAAA;AAElB,oEAAoE;AACpE,eAAO,MAAM,aAAa,EAAE,SAAS,WAAW,EAS/C,CAAA;AAED,2CAA2C;AAC3C,MAAM,MAAM,iBAAiB,GAAG;IAC9B,2DAA2D;IAC3D,IAAI,CAAC,EAAE,MAAM,CAAA;IACb,8DAA8D;IAC9D,cAAc,CAAC,EAAE,MAAM,CAAA;IACvB;;;;;OAKG;IACH,KAAK,CAAC,EAAE,UAAU,CAAA;IAClB;;;;;;;OAOG;IACH,OAAO,CAAC,EAAE,SAAS,WAAW,EAAE,CAAA;IAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;OAsCG;IACH,MAAM,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAC,CAAA;CAC9C,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,SAAS,GACpB,UAAS,iBAAsB,KAC9B,MAAM,CAAC,WAAW,EAAE,MAAM,CAQ5B,CAAA;AAgSD,eAAO,MAAM,eAAe,GAAI,UAAS,iBAAsB,WAsB9D,CAAA;AAED;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,eAAO,MAAM,uBAAuB,IAAI,CAAA;AAExC;;;;;;;GAOG;AACH,eAAO,MAAM,iBAAiB,GAC5B,UAAS,iBAAiB,GAAG;IAAE,eAAe,CAAC,EAAE,MAAM,CAAA;CAAO,KAC7D,MAAM,EAYR,CAAA;AASD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,cAAc,GAAI,OAAO,GAAG,EAAE,KAAG,GA8B7C,CAAA;AAED;;;;;;GAMG;AACH,MAAM,MAAM,cAAc,GAAG;IAC3B;;;;;OAKG;IACH,KAAK,EAAE,MAAM,CAAA;IACb,wCAAwC;IACxC,KAAK,EAAE,MAAM,CAAA;IACb,wDAAwD;IACxD,GAAG,EAAE,MAAM,CAAA;IACX;;;;;OAKG;IACH,MAAM,EAAE,OAAO,CAAA;IACf;;;;;;;;;;OAUG;IACH,OAAO,EAAE,OAAO,CAAA;CACjB,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiDG;AACH,eAAO,MAAM,cAAc,GACzB,MAAM,GAAG,EACT,SAAQ,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAM,KAChD,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,CAuB7C,CAAA;AAED;;;;;;;;;GASG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,GAAG,EACT,SAAQ,OAAO,CAAC,MAAM,CAAC,WAAW,EAAE,MAAM,CAAC,CAAM,KAChD,WAAW,EAGb,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AACH,eAAO,MAAM,iBAAiB,KAAK,CAAA;AA0BnC;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,aAAa,GACxB,MAAM,GAAG,EACT,UAAU,SAAS,WAAW,EAAE,KAC/B,MAAM,EAaR,CAAA;AAED;;;;;;;;;;;;;;;GAeG;AACH,eAAO,MAAM,gBAAgB,GAAI,KAAK,SAAS,MAAM,EAAE,WAYtD,CAAA;AAED;;;;;;GAMG;AACH,eAAO,MAAM,kBAAkB,GAC7B,KAAK,SAAS,MAAM,EAAE,EACtB,YAAW,MAA0B,KACpC,MAAM,EAMR,CAAA;AAoBD;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,WAAW,GAAI,MAAM,GAAG,EAAE,OAAO,SAAS,GAAG,EAAE,KAAG,GA0B9D,CAAA"}
package/dist/inbox.js CHANGED
@@ -207,7 +207,7 @@ const SOURCES = {
207
207
  myPRs: ({ scope, health, conversation }, first) => ` myPRs: search(query: "${scope}is:pr is:open author:@me", type: ISSUE, first: ${first}) {
208
208
  issueCount
209
209
  nodes { __typename ... on PullRequest {
210
- number title createdAt url headRefName isDraft
210
+ id number title createdAt url headRefName isDraft
211
211
  repository { nameWithOwner }
212
212
  author { login }
213
213
  ${health}
@@ -217,7 +217,7 @@ const SOURCES = {
217
217
  reviewRequests: ({ scope, health, conversation }, first) => ` reviewRequests: search(query: "${scope}is:pr is:open review-requested:@me", type: ISSUE, first: ${first}) {
218
218
  issueCount
219
219
  nodes { __typename ... on PullRequest {
220
- number title createdAt url headRefName isDraft
220
+ id number title createdAt url headRefName isDraft
221
221
  repository { nameWithOwner }
222
222
  author { login }
223
223
  ${health}
@@ -227,7 +227,7 @@ const SOURCES = {
227
227
  reviewed: ({ scope, health, conversation }, first) => ` reviewed: search(query: "${scope}is:pr is:open reviewed-by:@me -author:@me -review-requested:@me", type: ISSUE, first: ${first}) {
228
228
  issueCount
229
229
  nodes { __typename ... on PullRequest {
230
- number title createdAt url headRefName isDraft
230
+ id number title createdAt url headRefName isDraft
231
231
  repository { nameWithOwner }
232
232
  author { login }
233
233
  ${health}
@@ -244,7 +244,7 @@ const SOURCES = {
244
244
  ${issueLabels}
245
245
  }
246
246
  ... on PullRequest {
247
- number title createdAt url headRefName isDraft repository { nameWithOwner } author { login }
247
+ id number title createdAt url headRefName isDraft repository { nameWithOwner } author { login }
248
248
  ${health}
249
249
  ${conversation}
250
250
  }
@@ -301,7 +301,7 @@ const SOURCES = {
301
301
  repoPRs: ({ scope, owned, health, conversation }, first) => ` repoPRs: search(query: "${scope}${owned}is:pr is:open -author:@me archived:false", type: ISSUE, first: ${first}) {
302
302
  issueCount
303
303
  nodes { __typename ... on PullRequest {
304
- number title createdAt url headRefName isDraft
304
+ id number title createdAt url headRefName isDraft
305
305
  repository { nameWithOwner }
306
306
  author { login }
307
307
  ${health}
@@ -311,7 +311,7 @@ const SOURCES = {
311
311
  recentlyDone: ({ scope, doneSince }, first) => ` recentlyDone: search(query: "${scope}is:pr author:@me -is:open closed:>=${doneSince}", type: ISSUE, first: ${first}) {
312
312
  issueCount
313
313
  nodes { __typename ... on PullRequest {
314
- number title state isDraft createdAt mergedAt closedAt url
314
+ id number title state isDraft createdAt mergedAt closedAt url
315
315
  repository { nameWithOwner }
316
316
  }}
317
317
  }`,
@@ -466,30 +466,253 @@ export const mergeInboxData = (parts) => {
466
466
  * 30-row window reorders it, evicts something, and the eviction is reported as
467
467
  * news about the row that left — which never moved at all.
468
468
  *
469
- * So a consumer should treat presence changes on a truncated source as carrying
470
- * no information, and say what it is not showing instead. Both halves need this
471
- * number, and until 2026-09-07 it was fetched for exactly one source out of
472
- * eight and read by nobody — the guarantee lived in a comment and not in the
473
- * code.
469
+ * So a consumer should treat presence changes on a capped source as carrying no
470
+ * information, and say what it is not showing instead.
471
+ *
472
+ * `issueCount` USED TO DECIDE THAT, AND IT CANNOT. Until 2026-09-09 this
473
+ * returned `truncated: total > shown`, which reads as a cap and is not one:
474
+ * `issueCount` is an index aggregate computed on a different path from the node
475
+ * materialisation, and the two are not a consistent snapshot. Measured that day
476
+ * against a live account, one sweep, immediately after an eight-source document
477
+ * had returned HTTP 502:
478
+ *
479
+ * myPRs issueCount 8 nodes 16 cap 30
480
+ * reviewed issueCount 13 nodes 10 cap 20
481
+ * repoIssues issueCount 111 nodes 83 cap 100
482
+ * repoPRs issueCount 4 nodes 5 cap 30
483
+ * recentlyDone issueCount 19 nodes 14 cap 30
484
+ *
485
+ * The first and fourth rows are the proof, and they are the reason this is a
486
+ * rule rather than a hunch: THE COUNT CAME BACK SMALLER THAN THE SAMPLE DRAWN
487
+ * FROM IT. A total that is exceeded by its own subset is not a total. Re-run
488
+ * seconds later, every pair agreed, and 24 subsequent runs of the real query
489
+ * agreed too — so the number is not merely stale, it is untrustworthy at
490
+ * unpredictable moments, which is worse. What made it go wrong was never
491
+ * established and does not need to be: the replacement does not consult it.
492
+ *
493
+ * What that cost downstream is a host reporting five capped sources of which
494
+ * not one was near its cap, explaining each with a sentence about caps. A true
495
+ * sentence about a false situation is the hardest kind of wrong to read, and
496
+ * the reader correctly could not parse it.
474
497
  *
475
498
  * A source that answered with no `issueCount` reports `total: shown`, which
476
- * reads as "not truncated". That is the deliberate direction to fail in: a
477
- * missing count must never invent a truncation and silence real news.
499
+ * reads as neither capped nor partial unless the cap says otherwise. That is
500
+ * the deliberate direction to fail in: a missing count must never invent a
501
+ * truncation and silence real news.
502
+ *
503
+ * `limits` must be the ones the fetch ACTUALLY asked for, not the defaults, or
504
+ * the cap this compares against is a different number from the one GitHub
505
+ * honoured — a two-tier host raising `reviewRequests` to 100 and then measuring
506
+ * against 20 would call every fetch capped forever.
478
507
  */
479
- export const sourceCoverage = (data) => {
508
+ export const sourceCoverage = (data, limits = {}) => {
480
509
  const out = {};
481
510
  if (!data)
482
511
  return out;
512
+ const caps = limitsFor({ limits });
483
513
  for (const source of INBOX_SOURCES) {
484
514
  const answered = data[source];
485
515
  if (!answered)
486
516
  continue;
487
517
  const shown = answered.nodes?.length ?? 0;
488
518
  const total = typeof answered.issueCount === "number" ? answered.issueCount : shown;
489
- out[source] = { total, shown, truncated: total > shown };
519
+ const cap = caps[source];
520
+ out[source] = {
521
+ total,
522
+ shown,
523
+ cap,
524
+ capped: shown >= cap,
525
+ partial: shown < cap && total > shown,
526
+ };
527
+ }
528
+ return out;
529
+ };
530
+ /**
531
+ * The sources whose rows are a sample rather than the set.
532
+ *
533
+ * This is what a two-tier host asks before spending a second round trip, so it
534
+ * has to be the CAP question and not the count one — an overflow fetch fired on
535
+ * a bad `issueCount` buys nothing and costs a request.
536
+ *
537
+ * Coverage is computed once rather than per source. It was once rebuilt inside
538
+ * the filter, which walked all eight sources eight times to answer about eight.
539
+ */
540
+ export const cappedSources = (data, limits = {}) => {
541
+ const coverage = sourceCoverage(data, limits);
542
+ return INBOX_SOURCES.filter((source) => coverage[source]?.capped);
543
+ };
544
+ /**
545
+ * How many PR ids one health request may carry.
546
+ *
547
+ * The third tier's whole reason for existing, so it is a measurement rather than
548
+ * a taste. Measured 2026-09-09 on a live account with 102 matching review
549
+ * requests, asking for the real `PR_HEALTH` + `PR_CONVERSATION` selections by
550
+ * node id:
551
+ *
552
+ * nodes(ids:) 100 — ~11s 502, twice
553
+ * nodes(ids:) 50 28 pts 8.7s 200 (6,200 nodes)
554
+ * nodes(ids:) 25 14 pts 4.0s 200 (3,100 nodes)
555
+ * 4 × 25 in parallel 56 pts 6.0s wall 200 ×4
556
+ *
557
+ * WHICH CORRECTS THE NOTE ON `limits` ABOVE, and the correction is the useful
558
+ * half: the 502 at `first: 100` was read there as the SEARCH timing out at
559
+ * GitHub's proxy. It is not. A direct node lookup — no search index involved at
560
+ * all — fails identically, at the same size and the same eleven seconds. What
561
+ * dies is the resolver's wall clock expanding ~12,000 nodes of check rollups and
562
+ * review threads, whichever door the request came through. The search endpoint
563
+ * was innocent.
564
+ *
565
+ * So batching is the MECHANISM here, not an optimisation of it: a tier three
566
+ * that fired one 100-id request would reproduce the exact failure it exists to
567
+ * fix. Cost per PR is 0.56 points either way — GraphQL prices nodes, not
568
+ * requests — so splitting buys reliability at no extra budget, exactly as
569
+ * `INBOX_SOURCES_PER_QUERY` does one level up.
570
+ */
571
+ export const HEALTH_BATCH_SIZE = 25;
572
+ /*
573
+ * A node the health fragment was never asked for.
574
+ *
575
+ * Tested on `reviewDecision` alone, and that is sound rather than sloppy: the
576
+ * selection is dropped WHOLE (see `PR_HEALTH`), so one key's absence is the
577
+ * whole set's absence. `@kud/gh-workflow`'s `hasHealthSelection` tests all three
578
+ * with `||` for a different job — it guards against a caller who built the node
579
+ * by hand — and importing it here is not available anyway, since the flow runs
580
+ * this way and not back.
581
+ */
582
+ const lacksHealth = (node) => Boolean(node) && !("reviewDecision" in node);
583
+ /*
584
+ * Rows whose verdict is already settled without the selection, and which
585
+ * therefore buy nothing by being enriched: `computeHealth` short-circuits on
586
+ * `state` and `isDraft` before it reads a single check.
587
+ *
588
+ * A COST filter, not a correctness one — merging health onto a merged PR changes
589
+ * no answer, it just spends 0.56 points to learn something already known.
590
+ */
591
+ const settledWithoutHealth = (node) => node?.state === "MERGED" || node?.state === "CLOSED" || node?.isDraft === true;
592
+ /**
593
+ * PR node ids on this data that arrived WITHOUT the health selection.
594
+ *
595
+ * The filter is load-bearing rather than tidiness. A two-tier fetch merges the
596
+ * cheap overflow after the full rows precisely so a URL collision keeps the
597
+ * full one, which means a naive "every id here" would re-fetch the rows that
598
+ * already carry a verdict — on a 102-row account that is ~11 points bought to
599
+ * learn what tier one already answered.
600
+ *
601
+ * `sources` narrows it further, and a caller should use it: only the PR sources
602
+ * can be enriched at all, and the issue sources that truncate carry no health to
603
+ * begin with.
604
+ */
605
+ export const healthIdsFrom = (data, sources) => {
606
+ const ids = [];
607
+ if (!data)
608
+ return ids;
609
+ for (const source of sources ?? INBOX_SOURCES)
610
+ for (const node of data[source]?.nodes ?? []) {
611
+ if (node?.__typename !== "PullRequest")
612
+ continue;
613
+ if (typeof node.id !== "string")
614
+ continue;
615
+ if (!lacksHealth(node) || settledWithoutHealth(node))
616
+ continue;
617
+ ids.push(node.id);
618
+ }
619
+ return [...new Set(ids)];
620
+ };
621
+ /**
622
+ * One `nodes(ids:)` document carrying the health and conversation selections for
623
+ * PRs already identified elsewhere.
624
+ *
625
+ * BOTH fragments, and health alone would be a bug. `computeHealth`'s precedence
626
+ * reads `unresolvedThreads` out of `reviewThreads`, which lives in
627
+ * `PR_CONVERSATION` — so a health-only enrichment would report `waiting` on a PR
628
+ * with open threads, which is the silent wrong token this whole set is
629
+ * all-or-nothing to prevent, one layer down.
630
+ *
631
+ * It also costs almost nothing to include: `reviewThreads` is ~100 of the ~124
632
+ * nodes a PR drags, so the rest of the conversation rides along nearly free —
633
+ * and an enriched overflow row comes out FULLY equal to a tier-one row, with its
634
+ * last actor and activity age intact, rather than a second-class one carrying a
635
+ * token and no story behind it.
636
+ */
637
+ export const buildHealthQuery = (ids) => `
638
+ {
639
+ rateLimit { cost nodeCount remaining resetAt }
640
+ nodes(ids: [${ids.map((id) => JSON.stringify(id)).join(", ")}]) {
641
+ __typename
642
+ ... on PullRequest {
643
+ id
644
+ ${PR_HEALTH}
645
+ ${PR_CONVERSATION}
646
+ }
647
+ }
648
+ }
649
+ `;
650
+ /**
651
+ * The same, split into documents small enough to answer — to be issued in
652
+ * parallel and handed to `mergeHealth`.
653
+ *
654
+ * Prefer this to `buildHealthQuery` for anything but a handful of ids. See
655
+ * `HEALTH_BATCH_SIZE` for why the split is the mechanism.
656
+ */
657
+ export const buildHealthQueries = (ids, batchSize = HEALTH_BATCH_SIZE) => {
658
+ const size = Math.max(1, Math.trunc(batchSize));
659
+ const queries = [];
660
+ for (let i = 0; i < ids.length; i += size)
661
+ queries.push(buildHealthQuery(ids.slice(i, i + size)));
662
+ return queries;
663
+ };
664
+ /*
665
+ * Every health key, and the rollup non-null.
666
+ *
667
+ * GraphQL can answer 200 with `errors` and null fields, and a node arriving with
668
+ * `reviewDecision` present but `statusCheckRollup: null` is the one shape that
669
+ * defeats the guard downstream: `hasHealthSelection` would read true on the
670
+ * first key while `computeHealth` saw zero checks and returned `waiting`. A
671
+ * confident wrong answer, through the only door left open.
672
+ *
673
+ * So the test is per NODE rather than per response. A partial answer should
674
+ * degrade to fewer verdicts, never to a wrong one.
675
+ */
676
+ const carriesHealth = (node) => Boolean(node) &&
677
+ "reviewDecision" in node &&
678
+ "mergeable" in node &&
679
+ node.statusCheckRollup != null;
680
+ /**
681
+ * Merge tier-three health onto the rows that were fetched without it.
682
+ *
683
+ * By node id, and all-or-nothing per node — a batch that failed merges nothing,
684
+ * a node that merges nothing keeps no health keys, `healthOf` reads the absence
685
+ * and `whoseMove` answers `unknown`. The invariant holds by CONSTRUCTION rather
686
+ * than by a flag anyone has to remember to pass, which is the same reason
687
+ * `@kud/gh-workflow` tests presence instead of trusting its caller.
688
+ *
689
+ * Returns a new object; the input is not mutated, because a caller merging the
690
+ * enriched copy alongside the original relies on the original still being what
691
+ * it was.
692
+ */
693
+ export const mergeHealth = (data, parts) => {
694
+ if (!data)
695
+ return data;
696
+ const byId = new Map();
697
+ for (const part of parts)
698
+ for (const node of part?.nodes ?? [])
699
+ if (typeof node?.id === "string" && carriesHealth(node))
700
+ byId.set(node.id, node);
701
+ if (byId.size === 0)
702
+ return data;
703
+ const out = { ...data };
704
+ for (const source of INBOX_SOURCES) {
705
+ const answered = data[source];
706
+ if (!answered?.nodes)
707
+ continue;
708
+ out[source] = {
709
+ ...answered,
710
+ nodes: answered.nodes.map((node) => {
711
+ const found = typeof node?.id === "string" ? byId.get(node.id) : undefined;
712
+ return found ? { ...node, ...found } : node;
713
+ }),
714
+ };
490
715
  }
491
716
  return out;
492
717
  };
493
- /** The sources whose rows are a sample rather than the set. */
494
- export const truncatedSources = (data) => INBOX_SOURCES.filter((source) => sourceCoverage(data)[source]?.truncated);
495
718
  //# sourceMappingURL=inbox.js.map
package/dist/inbox.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"inbox.js","sourceRoot":"","sources":["../src/inbox.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kud/gh",
3
- "version": "0.13.0",
3
+ "version": "0.15.0",
4
4
  "description": "Surface-agnostic GitHub core — gh CLI primitives, PR review comments, health, and webhook logic.",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",