@cat-factory/server 0.322.0 → 0.323.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.
@@ -0,0 +1,22 @@
1
+ import type { ExecutionInstance } from '@cat-factory/contracts';
2
+ /**
3
+ * How many resumes this run's review has already spent.
4
+ *
5
+ * Read off the RUN rather than tracked per caller, so the budget belongs to the review: a caller
6
+ * that alternates keys, retries from a second process, or resumes after the app already did gets
7
+ * the same answer. Taken as the maximum across the steps because a chain can carry more than one
8
+ * `pr-reviewer` step and the count lives on each step's own review state.
9
+ */
10
+ export declare function prReviewResumesSpent(execution: Pick<ExecutionInstance, 'steps'>): number;
11
+ /**
12
+ * The refusal when a run's review has spent its public resume budget, or `null` while it has some
13
+ * left.
14
+ *
15
+ * The message names the evidence a caller should read INSTEAD of resuming again (`slices` against
16
+ * `reportedSlices` says whether every slice is in, `lastActivityAt` whether anything is still
17
+ * moving) plus the two exits. It carries no `details.reason`, like the wrong-status refusal beside
18
+ * it: what a caller branches on is `resumeAttempts` against `maxResumeAttempts` on the decision
19
+ * itself, which it can read BEFORE spending a call rather than after being refused one.
20
+ */
21
+ export declare function prReviewResumeRefusal(execution: Pick<ExecutionInstance, 'steps'>): string | null;
22
+ //# sourceMappingURL=resumeBudget.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resumeBudget.d.ts","sourceRoot":"","sources":["../../../../src/modules/publicApi/decisions/resumeBudget.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,wBAAwB,CAAA;AAa/D;;;;;;;GAOG;AACH,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG,MAAM,CAKxF;AAED;;;;;;;;;GASG;AACH,wBAAgB,qBAAqB,CAAC,SAAS,EAAE,IAAI,CAAC,iBAAiB,EAAE,OAAO,CAAC,GAAG,MAAM,GAAG,IAAI,CAQhG"}
@@ -0,0 +1,41 @@
1
+ import { PUBLIC_PR_REVIEW_MAX_RESUME_ATTEMPTS } from '@cat-factory/contracts';
2
+ // The ceiling on `POST /api/v1/runs/:runId/decisions/pr-review/resume`, kept out of the route so
3
+ // the rule is unit-testable: the state it reasons about (several resumed reviews across a run's
4
+ // steps) is not reachable through the wire, since a resume needs a reviewer wedged mid-review.
5
+ //
6
+ // WHY THE PUBLIC SURFACE BOUNDS A LOOP THE APP DOES NOT. A resume STOPS the running reviewer and
7
+ // dispatches a fresh container, so an uncapped one is unbounded spend on a run nobody is watching:
8
+ // a poller resuming every ten minutes on a review that legitimately takes twenty kills it, over
9
+ // and over, each time it is about to finish. A person clicking Resume in the review window is
10
+ // looking at what they nudged, which is the judgement a headless caller cannot supply, so the
11
+ // ceiling belongs to the surface without the eyes rather than to the engine.
12
+ /**
13
+ * How many resumes this run's review has already spent.
14
+ *
15
+ * Read off the RUN rather than tracked per caller, so the budget belongs to the review: a caller
16
+ * that alternates keys, retries from a second process, or resumes after the app already did gets
17
+ * the same answer. Taken as the maximum across the steps because a chain can carry more than one
18
+ * `pr-reviewer` step and the count lives on each step's own review state.
19
+ */
20
+ export function prReviewResumesSpent(execution) {
21
+ return execution.steps.reduce((most, step) => Math.max(most, step.prReview?.resumeAttempts ?? 0), 0);
22
+ }
23
+ /**
24
+ * The refusal when a run's review has spent its public resume budget, or `null` while it has some
25
+ * left.
26
+ *
27
+ * The message names the evidence a caller should read INSTEAD of resuming again (`slices` against
28
+ * `reportedSlices` says whether every slice is in, `lastActivityAt` whether anything is still
29
+ * moving) plus the two exits. It carries no `details.reason`, like the wrong-status refusal beside
30
+ * it: what a caller branches on is `resumeAttempts` against `maxResumeAttempts` on the decision
31
+ * itself, which it can read BEFORE spending a call rather than after being refused one.
32
+ */
33
+ export function prReviewResumeRefusal(execution) {
34
+ const spent = prReviewResumesSpent(execution);
35
+ if (spent < PUBLIC_PR_REVIEW_MAX_RESUME_ATTEMPTS)
36
+ return null;
37
+ return (`This review has already been resumed ${spent} times, which is all this API will spend on ` +
38
+ 'one review. Read `slices`, `reportedSlices` and `lastActivityAt` to see whether it is still ' +
39
+ 'working; resume it again from the app, or end the run with POST /api/v1/tasks/:taskId/stop.');
40
+ }
41
+ //# sourceMappingURL=resumeBudget.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"resumeBudget.js","sourceRoot":"","sources":["../../../../src/modules/publicApi/decisions/resumeBudget.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,oCAAoC,EAAE,MAAM,wBAAwB,CAAA;AAG7E,iGAAiG;AACjG,gGAAgG;AAChG,+FAA+F;AAC/F,EAAE;AACF,iGAAiG;AACjG,mGAAmG;AACnG,gGAAgG;AAChG,8FAA8F;AAC9F,8FAA8F;AAC9F,6EAA6E;AAE7E;;;;;;;GAOG;AACH,MAAM,UAAU,oBAAoB,CAAC,SAA2C;IAC9E,OAAO,SAAS,CAAC,KAAK,CAAC,MAAM,CAC3B,CAAC,IAAI,EAAE,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,GAAG,CAAC,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,cAAc,IAAI,CAAC,CAAC,EAClE,CAAC,CACF,CAAA;AACH,CAAC;AAED;;;;;;;;;GASG;AACH,MAAM,UAAU,qBAAqB,CAAC,SAA2C;IAC/E,MAAM,KAAK,GAAG,oBAAoB,CAAC,SAAS,CAAC,CAAA;IAC7C,IAAI,KAAK,GAAG,oCAAoC;QAAE,OAAO,IAAI,CAAA;IAC7D,OAAO,CACL,wCAAwC,KAAK,8CAA8C;QAC3F,8FAA8F;QAC9F,6FAA6F,CAC9F,CAAA;AACH,CAAC"}