pi-goal-list-loop-audit 0.38.30 → 0.38.31
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/CHANGELOG.md +7 -0
- package/docs/INDEX.md +1 -1
- package/extensions/goal-loop-display.ts +35 -6
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.31 — overdue wait-pause stops promising imminent resume (2026-09-08)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
- A recovery-timer wait whose retry time passed long ago on a held/idle host no longer claims `next: resuming now` / `auto-retrying · now` forever while also reading `paused` + `safely parked` (field screenshot 20260908_180721). `resuming now` / `resuming…` / `now` are grace-bounded (90s); past that the card and status bar name the timer (`next: recovery timer`, `auto-retrying · overdue — waiting on recovery timer`, `retry overdue`).
|
|
7
|
+
- Recovery-timer waits end at the auto-retry row: the stock provider-failure `pauseSuggestedAction` boilerplate and the generic `awaiting first turn` / `saved` tail are gone (owner + next are already on the rows above); the previous row closes the tree with `└─`. Decision/error/blocked pauses are unchanged.
|
|
8
|
+
- Regression coverage in `tests/paused-overdue-display.test.ts` (6 pins); two v0.34-era pins that encoded the old permanent-`resuming…` wording updated to the grace contract; `tsc` clean.
|
|
9
|
+
|
|
3
10
|
## 0.38.30 — fresh audit pass: nine low-severity fixes (2026-09-08)
|
|
4
11
|
|
|
5
12
|
### Fixed
|
package/docs/INDEX.md
CHANGED
|
@@ -18,7 +18,7 @@ For shipped docs, the relevant entry points are:
|
|
|
18
18
|
failback; v0.35.9 hardened cross-version npm tarball checks; v0.35.10
|
|
19
19
|
handles multi-entry npm dry-run reports; v0.35.11 accepts both npm report
|
|
20
20
|
shapes; v0.35.12 supports npm 12's keyed pack reports; v0.35.13 fixes stale-API recovery loops.
|
|
21
|
-
v0.35.14–v0.38.
|
|
21
|
+
v0.35.14–v0.38.31 continue through the supervisor freeze (`/glla pause`),
|
|
22
22
|
load hold, auditor picker parity, Windows launch fix, zombie-watchdog
|
|
23
23
|
subagent carve-out, due-wait backstop, the `/glla agents` visibility panel,
|
|
24
24
|
durable state-root selection, blank-until-resume auditor context, frozen
|
|
@@ -1011,6 +1011,14 @@ function goalTotalText(g: Goal, now: number): string {
|
|
|
1011
1011
|
return Number.isFinite(startedAt) ? `total ${fmtElapsed(bucketSilentMs(Math.max(0, now - startedAt)))}` : "";
|
|
1012
1012
|
}
|
|
1013
1013
|
|
|
1014
|
+
/** v0.38.31 (field 2026-09-08 180721): "resuming now" is a transient
|
|
1015
|
+
* truth, not a state. A wait-pause whose retry time passed an hour ago on
|
|
1016
|
+
* a held/idle host is overdue — claiming an imminent resume forever while
|
|
1017
|
+
* the card also says "safely parked" is the same contradiction class as
|
|
1018
|
+
* f8d1c2f. Past the grace window the transition falls through to the
|
|
1019
|
+
* pause-kind label ("recovery timer" for waits) instead. */
|
|
1020
|
+
export const PAUSED_RESUME_GRACE_MS = 90_000;
|
|
1021
|
+
|
|
1014
1022
|
function pausedNextTransition(g: Goal, state: State, now: number): string {
|
|
1015
1023
|
const resume = g.policy === "list" ? "/list resume" : "/goal resume";
|
|
1016
1024
|
const retryAt = state.mainModelRecovery?.retryAt ? Date.parse(state.mainModelRecovery.retryAt) : Number.NaN;
|
|
@@ -1026,7 +1034,11 @@ function pausedNextTransition(g: Goal, state: State, now: number): string {
|
|
|
1026
1034
|
}
|
|
1027
1035
|
const resumeAt = g.pauseResumeAt ? Date.parse(g.pauseResumeAt) : Number.NaN;
|
|
1028
1036
|
if (Number.isFinite(resumeAt)) {
|
|
1029
|
-
|
|
1037
|
+
if (resumeAt > now) return `auto-retry in ${fmtElapsed(resumeAt - now)}`;
|
|
1038
|
+
// Inside the grace window the retry is genuinely imminent. Past it the
|
|
1039
|
+
// timer never fired (held host, idle session) — fall through to the
|
|
1040
|
+
// kind label below instead of promising "resuming now" forever.
|
|
1041
|
+
if (now - resumeAt < PAUSED_RESUME_GRACE_MS) return "resuming now";
|
|
1030
1042
|
}
|
|
1031
1043
|
if (isCompletionAuditNoVerdict(g)) {
|
|
1032
1044
|
const retryAt = g.pendingCompletion?.recoveryRetryAt
|
|
@@ -1207,14 +1219,16 @@ function buildStatusTextBase(state: State, audit?: AuditDisplayProgress | null,
|
|
|
1207
1219
|
if (kind === "wait" || kind === "blocked") {
|
|
1208
1220
|
// v0.34.12: live countdown (the UI ticker keeps rendering through a
|
|
1209
1221
|
// timed wait) — "auto-retry in 23m" beats a static clock time, and a
|
|
1210
|
-
// passed resumeAt says "resuming…" instead of lying about the
|
|
1222
|
+
// freshly-passed resumeAt says "resuming…" instead of lying about the
|
|
1223
|
+
// past. v0.38.31: "resuming…" shares the transition grace window — a
|
|
1224
|
+
// retry time long past with no dispatch reads "retry overdue".
|
|
1211
1225
|
// Every retry-class pause renders the same ⏳ auto-retrying… line +
|
|
1212
1226
|
// countdown; blocked pauses without a recovery timer render as
|
|
1213
1227
|
// ⏸ action needed. A main-model manual hold names its recovery owner.
|
|
1214
1228
|
const rms = g.pauseResumeAt ? Date.parse(g.pauseResumeAt) - now : Number.NaN;
|
|
1215
|
-
const when = Number.isFinite(rms)
|
|
1216
|
-
|
|
1217
|
-
: "";
|
|
1229
|
+
const when = !Number.isFinite(rms) ? ""
|
|
1230
|
+
: rms > 0 ? ` · auto-retry in ${fmtElapsed(rms)}`
|
|
1231
|
+
: -rms >= PAUSED_RESUME_GRACE_MS ? " · retry overdue" : " · resuming…";
|
|
1218
1232
|
if (kind === "blocked") {
|
|
1219
1233
|
const label = state.mainModelRecovery?.manualResumeRequired === true
|
|
1220
1234
|
? "⏸ manual recovery hold"
|
|
@@ -1887,7 +1901,12 @@ function goalLines(g: Goal, state: State, audit: AuditDisplayProgress | null | u
|
|
|
1887
1901
|
recoverySummary.forEach((line) => lines.push(`│ ${paint(theme, "dim", line.replace(/^Main-model recovery: /, ""))}`));
|
|
1888
1902
|
}
|
|
1889
1903
|
else if (Number.isFinite(retryMs)) {
|
|
1890
|
-
|
|
1904
|
+
// v0.38.31: "now" shares the transition grace window — a retry time
|
|
1905
|
+
// that passed long ago with no dispatch is overdue, not imminent.
|
|
1906
|
+
const overdue = -retryMs >= PAUSED_RESUME_GRACE_MS;
|
|
1907
|
+
const when = retryMs > 0 ? `next probe in ${fmtElapsed(retryMs)}`
|
|
1908
|
+
: overdue ? "overdue — waiting on recovery timer"
|
|
1909
|
+
: "now";
|
|
1891
1910
|
lines.push(`├─ ${paint(theme, "dim", `auto-retrying · ${when}`)}`);
|
|
1892
1911
|
} else if (kind === "blocked" && state.mainModelRecovery?.manualResumeRequired === true) {
|
|
1893
1912
|
lines.push(`├─ ${paint(theme, "warning", "manual recovery hold — automatic probes stopped")}`);
|
|
@@ -1928,6 +1947,16 @@ function goalLines(g: Goal, state: State, audit: AuditDisplayProgress | null | u
|
|
|
1928
1947
|
// before the first turn), render "awaiting first turn" instead of "saved"
|
|
1929
1948
|
// — the latter was misleading because no work was ever "saved" before the
|
|
1930
1949
|
// session ended.
|
|
1950
|
+
if (kind === "wait") {
|
|
1951
|
+
// v0.38.31 (field 2026-09-08 180721): a recovery-timer wait carries no
|
|
1952
|
+
// objective-specific tail — owner + next are already on the lifecycle /
|
|
1953
|
+
// transition / auto-retry rows, and the parked suggestedAction is stock
|
|
1954
|
+
// provider-failure boilerplate identical on every recovery wait. End
|
|
1955
|
+
// the card here, closing the previous row as the footer.
|
|
1956
|
+
const tail = lines[lines.length - 1];
|
|
1957
|
+
if (tail !== undefined) lines[lines.length - 1] = tail.replace(/^├─|^│\s*/, "└─ ");
|
|
1958
|
+
return lines;
|
|
1959
|
+
}
|
|
1931
1960
|
const spent: string[] = [];
|
|
1932
1961
|
const tokUsed = g.usage?.tokensUsed ?? 0;
|
|
1933
1962
|
const audits = g.auditHistory?.length ?? 0;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "pi-goal-list-loop-audit",
|
|
3
|
-
"version": "0.38.
|
|
3
|
+
"version": "0.38.31",
|
|
4
4
|
"description": "Mission control for autonomous pi: interview-drafted goals, an audited task queue, and forever-loops (metric, spec, project-audit) that run for hours. A detached extension-less auditor process re-verifies every completion with raw evidence without holding the main pi turn; confirmed drafts, decision pauses and consent gates keep you in charge.",
|
|
5
5
|
"license": "AGPL-3.0-only",
|
|
6
6
|
"author": "dracon",
|