pi-goal-list-loop-audit 0.38.13 → 0.38.14
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
CHANGED
|
@@ -1,5 +1,10 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.14 — human end-of-objective briefing (2026-09-04)
|
|
4
|
+
|
|
5
|
+
### Changed
|
|
6
|
+
Every `✓ done` chat notify is now a human briefing: outcome first in its own words, only informing labels after it (`none` / `not recorded` / empty filler dropped; `none — <content>` keeps the content). Word-boundary cuts, auditor/no-audit trailer, archive keeps the full six-label record. Runbook in `audit/HUMAN-BRIEF-2026-09-04.md`.
|
|
7
|
+
|
|
3
8
|
## 0.38.13 — good completion summary (2026-09-04)
|
|
4
9
|
|
|
5
10
|
### Changed
|
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.14 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
|
|
@@ -116,6 +116,49 @@ export function compactCompletionSummary(text: string | undefined, maxValueLengt
|
|
|
116
116
|
return parts.join(" · ");
|
|
117
117
|
}
|
|
118
118
|
|
|
119
|
+
/** A recap value informs the human only when it is not an empty / none /
|
|
120
|
+
* not-recorded placeholder. `None — <real content>` (a common agent habit)
|
|
121
|
+
* keeps just the content. Returns null for filler. */
|
|
122
|
+
export function briefValueContent(value: string): string | null {
|
|
123
|
+
const clean = value.replace(/\s+/g, " ").trim();
|
|
124
|
+
if (!clean) return null;
|
|
125
|
+
// System placeholder vocabulary: the `— explanation` is still a placeholder.
|
|
126
|
+
if (/^not recorded\b/i.test(clean)) return null;
|
|
127
|
+
// Agent habit: `none — <real content>` hides information behind filler.
|
|
128
|
+
const prefixed = /^none\s*[—–:\-]\s*(.+)$/i.exec(clean);
|
|
129
|
+
const body = (prefixed?.[1] ?? clean).trim();
|
|
130
|
+
if (/^(none|n\/a|nil|nothing)(\s+for\s+this\s+\w+)?\.?$/i.test(body)) return null;
|
|
131
|
+
return body;
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
export interface HumanCompletionBrief {
|
|
135
|
+
outcome: string;
|
|
136
|
+
details: string[];
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
/** The human briefing: outcome first in its own words, then only the
|
|
140
|
+
* labels that carry real content (filler like `Unresolved: none` or
|
|
141
|
+
* `Changed: not recorded` is dropped, never shown). The durable archive
|
|
142
|
+
* keeps the full six-label record; this is the end-of-objective voice
|
|
143
|
+
* that informs the user at a glance. */
|
|
144
|
+
export function humanCompletionBrief(
|
|
145
|
+
text: string | undefined,
|
|
146
|
+
outcomeBudget = 140,
|
|
147
|
+
valueBudget = 120,
|
|
148
|
+
): HumanCompletionBrief {
|
|
149
|
+
const lines = completionSummaryLines(text, Math.max(outcomeBudget, valueBudget));
|
|
150
|
+
const rawOutcome = (lines[0] ?? "").replace(/^Outcome:\s*/, "");
|
|
151
|
+
const outcome = clipSummaryValue(briefValueContent(rawOutcome) ?? "done", outcomeBudget);
|
|
152
|
+
const details: string[] = [];
|
|
153
|
+
for (const line of lines.slice(1)) {
|
|
154
|
+
const separator = line.indexOf(":");
|
|
155
|
+
if (separator < 0) continue;
|
|
156
|
+
const content = briefValueContent(line.slice(separator + 1));
|
|
157
|
+
if (content) details.push(`${line.slice(0, separator)}: ${clipSummaryValue(content, valueBudget)}`);
|
|
158
|
+
}
|
|
159
|
+
return { outcome, details };
|
|
160
|
+
}
|
|
161
|
+
|
|
119
162
|
/** Multi-line projection: one `Label: value` line per label with generous
|
|
120
163
|
* word-bounded values. This is the user-facing `✓ done` block — six short
|
|
121
164
|
* facts that stay scannable in chat. The single-line projection remains
|
|
@@ -236,6 +279,15 @@ export function compactTerminalCompletionSummary(
|
|
|
236
279
|
return compactCompletionSummary(resolveCompletionSummary(facts, candidate).summary, maxValueLength);
|
|
237
280
|
}
|
|
238
281
|
|
|
282
|
+
/** Brief twin of compactTerminalCompletionSummary for the `✓ done` chat
|
|
283
|
+
* notifies: same resolved facts, outcome + informing labels only. */
|
|
284
|
+
export function terminalHumanBrief(
|
|
285
|
+
facts: CompletionSummaryFacts,
|
|
286
|
+
candidate = facts.goal.completionSummary,
|
|
287
|
+
): HumanCompletionBrief {
|
|
288
|
+
return humanCompletionBrief(resolveCompletionSummary(facts, candidate).summary);
|
|
289
|
+
}
|
|
290
|
+
|
|
239
291
|
/** Multi-line twin of compactTerminalCompletionSummary for the `✓ done`
|
|
240
292
|
* chat notifies: same resolved facts, one `Label: value` line each. */
|
|
241
293
|
export function terminalCompletionSummaryLines(
|
|
@@ -240,7 +240,7 @@ import {
|
|
|
240
240
|
pushCapped as pushRepetitionCapped,
|
|
241
241
|
} from "../goal-loop-repetition.js";
|
|
242
242
|
import { buildStatusText, buildWidgetLines, type AuditDisplayProgress } from "../goal-loop-display.js";
|
|
243
|
-
import { compactCompletionSummary, compactTerminalCompletionSummary, isGenericCompletionSummary, missingCompletionSummaryLabels,
|
|
243
|
+
import { compactCompletionSummary, compactTerminalCompletionSummary, isGenericCompletionSummary, missingCompletionSummaryLabels, terminalHumanBrief } from "../completion-summary.js";
|
|
244
244
|
import {
|
|
245
245
|
defaultAgentDir,
|
|
246
246
|
resolveEffectiveSubagentModel,
|
|
@@ -1416,7 +1416,7 @@ async function retryStoredCompletionAudit(origin: CompletionAuditOrigin = "provi
|
|
|
1416
1416
|
archivePath: path.relative(liveCtx.cwd, archivedGoalPath(liveCtx.cwd, state.goal.id)) || archivedGoalPath(liveCtx.cwd, state.goal.id),
|
|
1417
1417
|
}, state.goal.completionSummary);
|
|
1418
1418
|
// Computed pre-archive: archiveCurrentGoal clears state.goal.
|
|
1419
|
-
const
|
|
1419
|
+
const brief = terminalHumanBrief({
|
|
1420
1420
|
goal: state.goal,
|
|
1421
1421
|
status: "complete",
|
|
1422
1422
|
stopReason: terminalReason,
|
|
@@ -1438,10 +1438,10 @@ async function retryStoredCompletionAudit(origin: CompletionAuditOrigin = "provi
|
|
|
1438
1438
|
appendLedger(liveCtx.cwd, "goal_archive_failed_after_approval", { goalId, attemptId: claim.attemptId, origin });
|
|
1439
1439
|
return;
|
|
1440
1440
|
}
|
|
1441
|
-
// v0.38.
|
|
1442
|
-
//
|
|
1443
|
-
//
|
|
1444
|
-
liveCtx.ui.notify(`✓ done — auditor ${result.model} approved${approvalVia}
|
|
1441
|
+
// v0.38.14: the chat notify is the human briefing — outcome first,
|
|
1442
|
+
// filler labels dropped — while the external notify keeps the compact
|
|
1443
|
+
// single line (pager/sound safe).
|
|
1444
|
+
liveCtx.ui.notify(`✓ done — ${brief.outcome}\n${[...brief.details, `— auditor ${result.model} approved${approvalVia}.`].join("\n")}`, "info");
|
|
1445
1445
|
notifyExternal(liveCtx, `Goal complete (auditor approved, ${origin}): ${recap}`);
|
|
1446
1446
|
return;
|
|
1447
1447
|
}
|
|
@@ -250,7 +250,7 @@ import {
|
|
|
250
250
|
pushCapped as pushRepetitionCapped,
|
|
251
251
|
} from "../goal-loop-repetition.js";
|
|
252
252
|
import { buildStatusText, buildWidgetLines, type AuditDisplayProgress } from "../goal-loop-display.js";
|
|
253
|
-
import { compactCompletionSummary, compactTerminalCompletionSummary, resolveCompletionSummary,
|
|
253
|
+
import { compactCompletionSummary, compactTerminalCompletionSummary, resolveCompletionSummary, terminalHumanBrief } from "../completion-summary.js";
|
|
254
254
|
import {
|
|
255
255
|
defaultAgentDir,
|
|
256
256
|
resolveEffectiveSubagentModel,
|
|
@@ -1216,15 +1216,16 @@ function registerAgentTools(pi: any): void {
|
|
|
1216
1216
|
details: {},
|
|
1217
1217
|
};
|
|
1218
1218
|
}
|
|
1219
|
-
const
|
|
1219
|
+
const brief = terminalHumanBrief({
|
|
1220
1220
|
goal: terminalGoal,
|
|
1221
1221
|
status: "complete",
|
|
1222
1222
|
stopReason: terminalReason,
|
|
1223
1223
|
archivePath: path.relative(ctx.cwd, archivedGoalPath(ctx.cwd, terminalGoal.id)) || archivedGoalPath(ctx.cwd, terminalGoal.id),
|
|
1224
1224
|
});
|
|
1225
|
-
|
|
1225
|
+
const briefBlock = [...brief.details, `— completed without audit (your choice).`].join("\n");
|
|
1226
|
+
ctx.ui.notify(`✓ done — ${brief.outcome}\n${briefBlock}`, "info");
|
|
1226
1227
|
notifyExternal(ctx, `Goal complete without audit (user choice): ${recap}`);
|
|
1227
|
-
return { content: [{ type: "text", text: `Goal marked complete without audit (user choice).\n\n${
|
|
1228
|
+
return { content: [{ type: "text", text: `Goal marked complete without audit (user choice).\n\n${briefBlock}` }], details: {} };
|
|
1228
1229
|
}
|
|
1229
1230
|
scheduleContinuation(ctx, true);
|
|
1230
1231
|
return {
|
|
@@ -1250,7 +1251,7 @@ function registerAgentTools(pi: any): void {
|
|
|
1250
1251
|
archivePath: path.relative(ctx.cwd, archivedGoalPath(ctx.cwd, state.goal.id)) || archivedGoalPath(ctx.cwd, state.goal.id),
|
|
1251
1252
|
}, state.goal.completionSummary);
|
|
1252
1253
|
// Computed pre-archive: archiveCurrentGoal clears state.goal.
|
|
1253
|
-
const
|
|
1254
|
+
const brief = terminalHumanBrief({
|
|
1254
1255
|
goal: state.goal,
|
|
1255
1256
|
status: "complete",
|
|
1256
1257
|
stopReason: terminalReason,
|
|
@@ -1271,7 +1272,7 @@ function registerAgentTools(pi: any): void {
|
|
|
1271
1272
|
appendLedger(ctx.cwd, "goal_archive_failed_after_approval", { goalId: state.goal?.id, origin: "manual-verify", model: result.model });
|
|
1272
1273
|
return { content: [{ type: "text", text: "The auditor approved, but the terminal archive could not be persisted. The goal is paused; fix persistence, resume, and retry complete_goal." }], details: {} };
|
|
1273
1274
|
}
|
|
1274
|
-
ctx.ui.notify(`✓ done — auditor ${result.model} approved
|
|
1275
|
+
ctx.ui.notify(`✓ done — ${brief.outcome}\n${[...brief.details, `— auditor ${result.model} approved.`].join("\n")}`, "info");
|
|
1275
1276
|
notifyExternal(ctx, `Goal complete (auditor approved): ${recap}`);
|
|
1276
1277
|
return { content: [{ type: "text", text: `Goal approved by auditor ${result.model}.` }], details: {} };
|
|
1277
1278
|
}
|
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.14",
|
|
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",
|