pi-goal-list-loop-audit 0.29.8 → 0.29.9
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.
|
@@ -9,6 +9,18 @@
|
|
|
9
9
|
*/
|
|
10
10
|
|
|
11
11
|
export const BACKOFF_HARD_CAP_MS = 5 * 60 * 1000;
|
|
12
|
+
|
|
13
|
+
// v0.29.9: ms until the next clock-hour boundary (+ grace). Coding-plan
|
|
14
|
+
// rate-limit windows typically expire at the top of the hour, so a probe
|
|
15
|
+
// scheduled there catches the reset within seconds instead of mid-window.
|
|
16
|
+
// Robust when the premise is wrong too: a non-clock-aligned window is
|
|
17
|
+
// still caught within the hour.
|
|
18
|
+
export function msUntilNextHourBoundary(nowMs: number, graceMs = 60_000): number {
|
|
19
|
+
const d = new Date(nowMs);
|
|
20
|
+
d.setMinutes(0, 0, 0);
|
|
21
|
+
d.setHours(d.getHours() + 1);
|
|
22
|
+
return d.getTime() + graceMs - nowMs;
|
|
23
|
+
}
|
|
12
24
|
export const BACKOFF_IDLE_RETRY_MS = 50; // when adding another iter to queue
|
|
13
25
|
export const BACKOFF_ERROR_BASE_MS = 5_000; // first error retry
|
|
14
26
|
export const BACKOFF_ERROR_MAX_MS = 60_000; // max error retry (separate from stuck cap)
|
package/extensions/loops/goal.ts
CHANGED
|
@@ -183,6 +183,7 @@ import {
|
|
|
183
183
|
shouldWedgeAlert,
|
|
184
184
|
PENDING_LATCH_STUCK_MS,
|
|
185
185
|
shouldFirePendingLatchWatchdog,
|
|
186
|
+
msUntilNextHourBoundary,
|
|
186
187
|
} from "../goal-loop-backoff.js";
|
|
187
188
|
|
|
188
189
|
// =================================================================
|
|
@@ -5540,17 +5541,40 @@ export default function (pi: ExtensionAPI): void {
|
|
|
5540
5541
|
// v0.29.1: brake-cycle CAP. The v0.28.25 ladder slows the thrash
|
|
5541
5542
|
// (1m→16m) but never STOPS it — junk-runner/hellhunter/pully each
|
|
5542
5543
|
// burned 4+ pause↔retry cycles against provider windows that last
|
|
5543
|
-
// hours. After 6 consecutive brakes: park
|
|
5544
|
+
// hours. After 6 consecutive brakes: park. v0.29.9: the park keeps
|
|
5545
|
+
// probing at the top of each hour (clock-aligned window resets).
|
|
5544
5546
|
if (errorBrakeStreak >= 6) {
|
|
5547
|
+
// v0.29.9: park — but keep probing at the top of each hour
|
|
5548
|
+
// (user: "simply adding an hourly retry … just to pick up work
|
|
5549
|
+
// faster assuming the retry expired"). Coding-plan rate-limit
|
|
5550
|
+
// windows typically expire on clock-hour boundaries, so a probe
|
|
5551
|
+
// scheduled for :01 catches the reset within seconds. One dunk
|
|
5552
|
+
// per hour, free (429s are rejected pre-billing); a successful
|
|
5553
|
+
// probe resets the whole error cycle. If the wall is something
|
|
5554
|
+
// else (auth, outage), the hourly probe is a harmless failed
|
|
5555
|
+
// resume attempt that re-parks via the same brake.
|
|
5545
5556
|
updateGoal({
|
|
5546
5557
|
status: "paused",
|
|
5547
5558
|
pauseKind: "error",
|
|
5548
5559
|
pauseReason: `${reason} — 6 error-brakes in a row; the provider has been erroring for an extended window`,
|
|
5549
|
-
pauseSuggestedAction: "
|
|
5560
|
+
pauseSuggestedAction: "Probing at the top of each hour — rate-limit windows typically expire on clock-hour boundaries. /goal resume retries now.",
|
|
5550
5561
|
}, ctx);
|
|
5551
|
-
ctx.ui.notify(`${goalNoun()} parked: ${reason} — 6 brakes in a row
|
|
5552
|
-
notifyExternal(ctx, `${goalNoun()} parked: provider erroring across 6 error-brake cycles.`);
|
|
5562
|
+
ctx.ui.notify(`${goalNoun()} parked: ${reason} — 6 brakes in a row. Hourly top-of-hour probes will pick work back up when the window opens; /goal resume retries now.`, "warning");
|
|
5563
|
+
notifyExternal(ctx, `${goalNoun()} parked: provider erroring across 6 error-brake cycles — hourly top-of-hour probes scheduled.`);
|
|
5553
5564
|
appendLedger(ctx.cwd, "error_brake_capped", { streak: errorBrakeStreak, reason });
|
|
5565
|
+
const probeMs = msUntilNextHourBoundary(Date.now());
|
|
5566
|
+
scheduleQuotaRetry(ctx, probeMs / 1000, reason, () => {
|
|
5567
|
+
// Re-check: only probe if STILL parked by the error-brake cap —
|
|
5568
|
+
// a user pause/resume/cancel meanwhile is never stomped.
|
|
5569
|
+
if (state.goal && state.goal.status === "paused" && state.goal.pauseKind === "error"
|
|
5570
|
+
&& (state.goal.pauseReason ?? "").includes("error-brakes in a row")) {
|
|
5571
|
+
appendLedger(ctx.cwd, "hourly_rate_probe", { goalId: state.goal.id, streak: errorBrakeStreak });
|
|
5572
|
+
updateGoal({ status: "active" }, ctx);
|
|
5573
|
+
appendLedger(ctx.cwd, "goal_resumed", { via: "hourly-rate-probe" });
|
|
5574
|
+
ctx.ui.notify("Hourly probe: resuming (rate-limit windows typically expire at the top of the hour).", "info");
|
|
5575
|
+
scheduleContinuation(ctx, true);
|
|
5576
|
+
}
|
|
5577
|
+
}, "Hourly rate-limit probe");
|
|
5554
5578
|
return;
|
|
5555
5579
|
}
|
|
5556
5580
|
// v0.28.25: the cooldown escalates per CONSECUTIVE brake — a fleet-wide
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goal-list-loop-audit",
|
|
3
|
-
"version": "0.29.
|
|
3
|
+
"version": "0.29.9",
|
|
4
4
|
"description": "Goal. Loop. Audit. Done. \u2014 a pi-coding-agent extension that supervises long-running work, with isolated auditor on each completion. Beat bamboozling by design: the auditor runs in a fresh session with no extensions, no skills, no editor \u2014 only the read tools needed to verify your goal.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"author": "dracon",
|