pi-goal-list-loop-audit 0.38.41 → 0.38.43
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 +21 -0
- package/docs/INDEX.md +1 -1
- package/extensions/completion-summary.ts +35 -10
- package/extensions/context-checkpoint.ts +28 -95
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 0.38.43 — ship merged PR #50, drop orphaned helpers (2026-09-10)
|
|
4
|
+
|
|
5
|
+
### Fixed
|
|
6
|
+
|
|
7
|
+
- **PR #50 (Bjynt, merged):** authoritative + overflow checkpoints replace dynamic fields (task state, pending completion, auditor TODOs, latest audit, stopReason/pauseKind) with the byte-stable `see .pi-glla/active.jsonl` pointer, so tool calls stop invalidating the provider KV-cache prefix. Tests pin dynamic absence, pointer presence, and smaller byte fixtures.
|
|
8
|
+
- **Follow-up cleanup:** removed the now-callerless `taskState`, `pendingCompletionState`, `compactAuditEvidence`, `auditLabel`, `boundedTail`, and the orphaned `OVERFLOW_AUDIT_CHARS`.
|
|
9
|
+
|
|
10
|
+
### Verification
|
|
11
|
+
|
|
12
|
+
- Full `release:check` 0 failures; `tsc --noEmit` clean.
|
|
13
|
+
|
|
14
|
+
## 0.38.42 — trailer cleanup: model-free folded approval (2026-09-09)
|
|
15
|
+
|
|
16
|
+
### Fixed
|
|
17
|
+
|
|
18
|
+
- **One canonical approval bullet in chat and transcript (field 20260909_140404):** the `provider/model` slug leaves both surfaces — chat shows `auditor approved on the provider retry (1 verdict).`, via-retry news kept. A lone approval folds with the verdict count; the standalone audit bullet survives only with news (multiple, disapproved, or impossible verdicts). The full model ID stays in the archive record; machine-path layering (chat stripped, transcript full) unchanged.
|
|
19
|
+
|
|
20
|
+
### Verification
|
|
21
|
+
|
|
22
|
+
- Render-unit pins both ways (fold + survive) and both surfaces (no model ID) plus an archive-keeps-model source pin; full `release:check` 0 failures; `tsc --noEmit` clean.
|
|
23
|
+
|
|
3
24
|
## 0.38.41 — grilling standard codified (2026-09-09)
|
|
4
25
|
|
|
5
26
|
### 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.43 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
|
|
@@ -237,7 +237,10 @@ export function withoutStaleNext(details: string[] | undefined): string[] {
|
|
|
237
237
|
* Five 120-char label lines scan as soup, not a summary (field
|
|
238
238
|
* 2026-09-04); the stale Next never reaches the chat.
|
|
239
239
|
* v0.38.25: optional `counts` audit-goal counts line rides between the
|
|
240
|
-
* approval trailer and the record pointer (the pointer stays last).
|
|
240
|
+
* approval trailer and the record pointer (the pointer stays last).
|
|
241
|
+
* v0.38.42: retained for backward compatibility + direct unit tests —
|
|
242
|
+
* buildTerminalApprovalRender constructs chat lines inline because the
|
|
243
|
+
* fold changes trailer arity, which this fixed-shape helper cannot express. */
|
|
241
244
|
export function buildApprovalChatLines(notice: {
|
|
242
245
|
outcome: string;
|
|
243
246
|
details: string[] | undefined;
|
|
@@ -262,7 +265,15 @@ export function buildApprovalChatLines(notice: {
|
|
|
262
265
|
/** v0.38.39 (field 20260909_013733): the trailer rides as bullets too —
|
|
263
266
|
* the Codex close is uniform `•` lines (`• Changed:` … `• record:`),
|
|
264
267
|
* never a `•` block followed by dangling `—` lines. The `— ` sigil is
|
|
265
|
-
* stripped at render; the input strings keep it for non-chat surfaces.
|
|
268
|
+
* stripped at render; the input strings keep it for non-chat surfaces.
|
|
269
|
+
* v0.38.42 (field 20260909_140404): the chat/transcript approval bullet
|
|
270
|
+
* carries no model ID — the `provider/model` slug is machine trivia
|
|
271
|
+
* outside an audit (the full model ID stays in the archive record).
|
|
272
|
+
* The `auditor <model> approved` shape collapses to `auditor approved`;
|
|
273
|
+
* any other approval voice passes through untouched. */
|
|
274
|
+
function stripApprovalModel(line: string): string {
|
|
275
|
+
return line.replace(/auditor\s+\S+\s+approved/, "auditor approved");
|
|
276
|
+
}
|
|
266
277
|
function trailerBullet(line: string): string {
|
|
267
278
|
return `• ${line.replace(/^—\s*/, "")}`;
|
|
268
279
|
}
|
|
@@ -343,19 +354,33 @@ export function buildTerminalApprovalRender(input: TerminalApprovalRenderInput):
|
|
|
343
354
|
? { ...baseBrief, details: [...baseBrief.details, `Left out: ${clipSummaryValue(leftOutContent, 120)}`] }
|
|
344
355
|
: baseBrief;
|
|
345
356
|
const countsLine = input.countsLine ?? buildAuditCountsLine(input.goal, input.auditNote);
|
|
357
|
+
// v0.38.42 (field 20260909_140404): one canonical approval bullet in
|
|
358
|
+
// chat and transcript — no model ID in either, via-retry news kept. A
|
|
359
|
+
// lone approval says the same thing as the counts line, so they fold
|
|
360
|
+
// into one bullet carrying the verdict count; the standalone audit
|
|
361
|
+
// bullet survives only with news (multiple, disapproved, or impossible
|
|
362
|
+
// verdicts). The returned `approval` field keeps the full input string
|
|
363
|
+
// for archive/persist consumers — the model ID leaves chat/transcript,
|
|
364
|
+
// never the record.
|
|
365
|
+
const history = input.goal.auditHistory ?? [];
|
|
366
|
+
const chatApproval = stripApprovalModel(input.approval);
|
|
367
|
+
const foldCounts = history.length === 1
|
|
368
|
+
&& history[0]?.approved === true
|
|
369
|
+
&& /approved/.test(chatApproval);
|
|
370
|
+
const approvalBullet = foldCounts
|
|
371
|
+
? `• ${chatApproval.replace(/^—\s*/, "").replace(/\.\s*$/, "")} (${history.length} verdict).`
|
|
372
|
+
: trailerBullet(chatApproval);
|
|
346
373
|
return {
|
|
347
374
|
chatLines: [
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
counts: countsLine,
|
|
354
|
-
}),
|
|
375
|
+
`✓ done — ${brief.outcome}`,
|
|
376
|
+
...withoutStaleNext(brief.details).map((detail) => `• ${detail}`),
|
|
377
|
+
approvalBullet,
|
|
378
|
+
...(foldCounts ? [] : [trailerBullet(countsLine)]),
|
|
379
|
+
trailerBullet(input.record),
|
|
355
380
|
...(input.extras ?? []),
|
|
356
381
|
],
|
|
357
382
|
recap,
|
|
358
|
-
transcriptLines: [...withoutStaleNext(brief.details).map((detail) => `• ${detail}`),
|
|
383
|
+
transcriptLines: [...withoutStaleNext(brief.details).map((detail) => `• ${detail}`), approvalBullet],
|
|
359
384
|
countsLine,
|
|
360
385
|
outcome: brief.outcome,
|
|
361
386
|
approval: input.approval,
|
|
@@ -49,14 +49,6 @@ function boundedText(value: unknown, maxChars: number): string {
|
|
|
49
49
|
return normalized.slice(0, Math.max(0, maxChars - suffix.length)) + suffix;
|
|
50
50
|
}
|
|
51
51
|
|
|
52
|
-
function boundedTail(value: unknown, maxChars: number): string {
|
|
53
|
-
if (typeof value !== "string") return "";
|
|
54
|
-
const normalized = value.replace(/\r\n?/g, "\n").replace(/\u0000/g, "");
|
|
55
|
-
if (normalized.length <= maxChars) return normalized;
|
|
56
|
-
const prefix = "[head truncated; full audit evidence remains in durable state]\n…";
|
|
57
|
-
return prefix + normalized.slice(-Math.max(0, maxChars - prefix.length));
|
|
58
|
-
}
|
|
59
|
-
|
|
60
52
|
function safeInline(value: unknown, maxChars: number): string {
|
|
61
53
|
return boundedText(value, maxChars)
|
|
62
54
|
.replace(/\n+/g, " ")
|
|
@@ -87,7 +79,7 @@ function loopNumber(value: unknown): string {
|
|
|
87
79
|
* provider call. Any byte change here invalidates the cache prefix for every
|
|
88
80
|
* token after it. This block therefore renders ONLY fields that are stable
|
|
89
81
|
* for the life of the loop run (target / measure / bounds config). Live
|
|
90
|
-
* counters (iteration, best, last, stall,
|
|
82
|
+
* counters (iteration, best, last, stall, history, tokens, timestamps) are
|
|
91
83
|
* intentionally NOT repeated here: they already ride the newest retained
|
|
92
84
|
* `[LOOP ITERATION …]` prompt (message-list suffix) and durable
|
|
93
85
|
* `.pi-glla/active.jsonl`. Rendering them here changed the prefix on every
|
|
@@ -103,38 +95,6 @@ function loopCheckpointLines(loop: LoopState): string[] {
|
|
|
103
95
|
];
|
|
104
96
|
}
|
|
105
97
|
|
|
106
|
-
function auditLabel(audit: { approved?: unknown; disapproved?: unknown; impossible?: unknown; error?: unknown; regressionShieldPassed?: unknown }): string {
|
|
107
|
-
if (audit.approved === true && audit.regressionShieldPassed === false) return "shield-blocked";
|
|
108
|
-
if (audit.approved === true) return "approved";
|
|
109
|
-
if (audit.impossible === true) return "impossible";
|
|
110
|
-
if (audit.disapproved === true) return "disapproved";
|
|
111
|
-
if (audit.error) return "infrastructure failure";
|
|
112
|
-
return "no verdict";
|
|
113
|
-
}
|
|
114
|
-
|
|
115
|
-
function taskState(goal: Goal): string {
|
|
116
|
-
const tasks = goal.taskList?.tasks ?? [];
|
|
117
|
-
if (tasks.length === 0) return "(no task list)";
|
|
118
|
-
const lines = tasks.slice(0, 40).map((task) =>
|
|
119
|
-
`${safeInline(task.id, 40)} [${safeInline(task.status, 30) || "unknown"}] ${safeInline(task.title, 180)}`,
|
|
120
|
-
);
|
|
121
|
-
if (tasks.length > lines.length) lines.push(`[…${tasks.length - lines.length} task(s) omitted; re-read durable task state]`);
|
|
122
|
-
return lines.join("\n");
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
function pendingCompletionState(goal: Goal): string {
|
|
126
|
-
const pending = goal.pendingCompletion;
|
|
127
|
-
if (!pending) return "(none)";
|
|
128
|
-
return [
|
|
129
|
-
`phase=${safeInline(pending.phase, 40) || "legacy/recovery-pending"}`,
|
|
130
|
-
`attemptId=${safeInline(pending.attemptId, 100) || "(none)"}`,
|
|
131
|
-
`recoveryReason=${safeInline(pending.recoveryReason, 180) || "(none)"}`,
|
|
132
|
-
`failureClass=${safeInline(pending.auditorFailureClass, 40) || "(none)"}`,
|
|
133
|
-
`failureCount=${typeof pending.auditorFailureCount === "number" ? pending.auditorFailureCount : "(none)"}`,
|
|
134
|
-
`fallbackExhausted=${pending.auditorFallbackExhausted === true ? "true" : "false"}`,
|
|
135
|
-
].join("; ");
|
|
136
|
-
}
|
|
137
|
-
|
|
138
98
|
// The ordinary checkpoint keeps the complete bounded representation for
|
|
139
99
|
// readable, normal-sized state. Once that representation exceeds the hard
|
|
140
100
|
// cap, these are explicit reservations for the fields that must survive a
|
|
@@ -144,7 +104,6 @@ const OVERFLOW_OBJECTIVE_CHARS = 1_400;
|
|
|
144
104
|
const OVERFLOW_CONTRACT_CHARS = 1_400;
|
|
145
105
|
const OVERFLOW_LOOP_TARGET_CHARS = 1_100;
|
|
146
106
|
const OVERFLOW_LOOP_MEASURE_CHARS = 360;
|
|
147
|
-
const OVERFLOW_AUDIT_CHARS = 1_100;
|
|
148
107
|
const OVERFLOW_EMERGENCY_LINE_CHARS = 500;
|
|
149
108
|
|
|
150
109
|
function compactLoopCheckpointLines(loop: LoopState): string[] {
|
|
@@ -158,29 +117,6 @@ function compactLoopCheckpointLines(loop: LoopState): string[] {
|
|
|
158
117
|
];
|
|
159
118
|
}
|
|
160
119
|
|
|
161
|
-
function compactAuditEvidence(
|
|
162
|
-
latestAudit: { approved?: unknown; disapproved?: unknown; impossible?: unknown; error?: unknown; regressionShieldPassed?: unknown; at?: unknown; model?: unknown; revision?: unknown; report?: unknown } | undefined,
|
|
163
|
-
maxChars: number,
|
|
164
|
-
): string {
|
|
165
|
-
if (!latestAudit) return "(no audits captured)";
|
|
166
|
-
const metadata = [
|
|
167
|
-
`label=${auditLabel(latestAudit)}`,
|
|
168
|
-
`at=${safeInline(latestAudit.at, 80) || "(unknown)"}`,
|
|
169
|
-
`model=${safeInline(latestAudit.model, 100) || "(unknown)"}`,
|
|
170
|
-
`revision=${typeof latestAudit.revision === "number" ? latestAudit.revision : "legacy/unspecified"}`,
|
|
171
|
-
`shield=${latestAudit.regressionShieldPassed === false ? "failed" : latestAudit.regressionShieldPassed === true ? "passed" : "unspecified"}`,
|
|
172
|
-
].join("\n");
|
|
173
|
-
const opening = "<audit-evidence>";
|
|
174
|
-
const closing = "</audit-evidence>";
|
|
175
|
-
const reportBudget = maxChars - metadata.length - opening.length - closing.length - 2;
|
|
176
|
-
if (reportBudget <= 0) return boundedText(metadata, maxChars);
|
|
177
|
-
const report = safeBlock(
|
|
178
|
-
boundedTail(latestAudit.report || "(no report captured)", reportBudget),
|
|
179
|
-
reportBudget,
|
|
180
|
-
);
|
|
181
|
-
return `${metadata}\n${opening}\n${report}\n${closing}`;
|
|
182
|
-
}
|
|
183
|
-
|
|
184
120
|
function buildOverflowCheckpoint(
|
|
185
121
|
input: AuthoritativeCheckpointInput,
|
|
186
122
|
goal: Goal | null | undefined,
|
|
@@ -204,7 +140,9 @@ function buildOverflowCheckpoint(
|
|
|
204
140
|
goal
|
|
205
141
|
? `Verification contract: ${safeBlock(goal.verificationContract, OVERFLOW_CONTRACT_CHARS) || "(none recorded)"}`
|
|
206
142
|
: "Verification contract: (none — metric/loop bounds above are authoritative)",
|
|
207
|
-
|
|
143
|
+
goal
|
|
144
|
+
? `Dynamic state (task state / pending completion / auditor TODOs / latest audit): see .pi-glla/active.jsonl — read before acting`
|
|
145
|
+
: `Dynamic state (loop progress): see .pi-glla/active.jsonl — read before acting`,
|
|
208
146
|
loop
|
|
209
147
|
? "Lifecycle fence: continue only for this active loop target, current loop state, and session owner; if a goal is present, preserve its id/revision as paused context. Use durable state and artifacts as the authority after compaction, restart, or session replacement."
|
|
210
148
|
: "Lifecycle fence: continue only for this goal id and current revision/session owner; use durable state and artifacts as the authority after compaction, restart, or session replacement.",
|
|
@@ -214,12 +152,6 @@ function buildOverflowCheckpoint(
|
|
|
214
152
|
loop
|
|
215
153
|
? "Loop history summary: omitted by design — live history rides the newest retained loop prompt (keeps this checkpoint byte-stable for prefix-cache stability)"
|
|
216
154
|
: null,
|
|
217
|
-
goal
|
|
218
|
-
? `Auto-continuation: ${goal.autoContinue === true ? "enabled" : "disabled/unknown"}; stopReason=${safeInline(goal.stopReason, 220) || "(none)"}; pauseKind=${safeInline(goal.pauseKind, 40) || "(none)"}`
|
|
219
|
-
: `Auto-continuation: ${loop?.active === true ? "loop active" : "loop inactive"}; stopReason=${safeInline(loop?.stopReason, 220) || "(none)"}; pauseKind=(none)`,
|
|
220
|
-
`Pending completion: ${boundedText(goal ? pendingCompletionState(goal) : "(none — loop has no detached auditor claim)", 420)}`,
|
|
221
|
-
`Pending auditor TODOs:\n${boundedText(goal?.pendingTasks?.length ? goal.pendingTasks.slice(0, 12).map((task, index) => `${index + 1}. ${safeInline(task, 160)}`).join("\n") : "(none)", 520)}`,
|
|
222
|
-
`Task state:\n${boundedText(goal ? taskState(goal) : "(no goal task list)", 520)}`,
|
|
223
155
|
].filter((line): line is string => line !== null);
|
|
224
156
|
|
|
225
157
|
const lines = [...requiredLines];
|
|
@@ -243,26 +175,28 @@ function buildOverflowCheckpoint(
|
|
|
243
175
|
* long continuation template remains available in the newest retained
|
|
244
176
|
* payload, while this checkpoint protects state when older payloads are
|
|
245
177
|
* removed from the effective context.
|
|
178
|
+
*
|
|
179
|
+
* CACHE-STABILITY INVARIANT: This checkpoint is inserted EARLY in the message
|
|
180
|
+
* history (at the first removed goal-event payload position). Any byte change
|
|
181
|
+
* here invalidates the provider's KV cache prefix for all subsequent tokens.
|
|
182
|
+
* Therefore, ONLY stable fields are included:
|
|
183
|
+
* - Goal/loop identity, policy, revision, session generation
|
|
184
|
+
* - Objective, verification contract (stable for the life of the goal)
|
|
185
|
+
* - Loop target, measure, bounds (stable for the life of the loop)
|
|
186
|
+
* - Lifecycle fences
|
|
187
|
+
*
|
|
188
|
+
* DYNAMIC FIELDS EXCLUDED (they belong in the newest retained payload at the
|
|
189
|
+
* message suffix, not the checkpoint prefix):
|
|
190
|
+
* - Task state (changes on complete_task)
|
|
191
|
+
* - Pending completion (changes on complete_goal)
|
|
192
|
+
* - Pending auditor TODOs (changes on auditor disapproval)
|
|
193
|
+
* - Latest audit report (changes on auditor completion)
|
|
194
|
+
* - stopReason, pauseKind (change on pause/resume)
|
|
195
|
+
* - Auto-continuation setting (goal.autoContinue) is STABLE — included
|
|
246
196
|
*/
|
|
247
197
|
export function buildAuthoritativeContextCheckpoint(input: AuthoritativeCheckpointInput): string {
|
|
248
198
|
const { goal, loop } = input;
|
|
249
199
|
const latestAudit = goal?.auditHistory?.[goal.auditHistory.length - 1];
|
|
250
|
-
const auditReport = latestAudit?.report ? boundedTail(latestAudit.report, 2_000) : "(no report captured)";
|
|
251
|
-
const auditEvidence = latestAudit
|
|
252
|
-
? [
|
|
253
|
-
`label=${auditLabel(latestAudit)}`,
|
|
254
|
-
`at=${safeInline(latestAudit.at, 80) || "(unknown)"}`,
|
|
255
|
-
`model=${safeInline(latestAudit.model, 100) || "(unknown)"}`,
|
|
256
|
-
`revision=${typeof latestAudit.revision === "number" ? latestAudit.revision : "legacy/unspecified"}`,
|
|
257
|
-
`shield=${latestAudit.regressionShieldPassed === false ? "failed" : latestAudit.regressionShieldPassed === true ? "passed" : "unspecified"}`,
|
|
258
|
-
`<audit-evidence>\n${safeBlock(auditReport, 2_000)}\n</audit-evidence>`,
|
|
259
|
-
].join("\n")
|
|
260
|
-
: goal
|
|
261
|
-
? "(no audits on this goal yet)"
|
|
262
|
-
: "(no goal audits; active loop state is authoritative)";
|
|
263
|
-
const pendingTasks = goal?.pendingTasks?.length
|
|
264
|
-
? goal.pendingTasks.slice(0, 12).map((task, index) => `${index + 1}. ${safeInline(task, 240)}`).join("\n")
|
|
265
|
-
: "(none)";
|
|
266
200
|
const repairTarget = goal?.repairTarget
|
|
267
201
|
? [
|
|
268
202
|
`id=${safeInline(goal.repairTarget.id, 80)}`,
|
|
@@ -290,12 +224,11 @@ export function buildAuthoritativeContextCheckpoint(input: AuthoritativeCheckpoi
|
|
|
290
224
|
? `Verification contract: ${safeBlock(goal.verificationContract, 2_000) || "(none recorded)"}`
|
|
291
225
|
: "Verification contract: (none — metric/loop bounds above are authoritative)",
|
|
292
226
|
goal
|
|
293
|
-
? `Auto-continuation: ${goal.autoContinue === true ? "enabled" : "disabled/unknown"}
|
|
294
|
-
: `Auto-continuation: ${loop?.active === true ? "loop active" : "loop inactive"}
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
`Task state:\n${goal ? taskState(goal) : "(no goal task list)"}`,
|
|
227
|
+
? `Auto-continuation: ${goal.autoContinue === true ? "enabled" : "disabled/unknown"}`
|
|
228
|
+
: `Auto-continuation: ${loop?.active === true ? "loop active" : "loop inactive"}`,
|
|
229
|
+
goal
|
|
230
|
+
? `Dynamic state (task state / pending completion / auditor TODOs / latest audit): see .pi-glla/active.jsonl — read before acting`
|
|
231
|
+
: `Dynamic state (loop progress): see .pi-glla/active.jsonl — read before acting`,
|
|
299
232
|
`Repair/replan target:\n${repairTarget}`,
|
|
300
233
|
loop
|
|
301
234
|
? "Lifecycle fence: continue only for this active loop target, current loop state, and session owner; if a goal is present, preserve its id/revision as paused context. Use durable state and artifacts as the authority after compaction, restart, or session replacement."
|
|
@@ -315,7 +248,7 @@ function customType(message: unknown): string | null {
|
|
|
315
248
|
// Audit 2026-09-06: a substring-based `isGllaControlMessage` predicate used
|
|
316
249
|
// to live here (any message containing "[GOAL CHECKPOINT" / "[STALL
|
|
317
250
|
// WARNING" counted as control plane). It had zero callers — the live
|
|
318
|
-
// projection keys on customType only —
|
|
251
|
+
// projection keys on customType only — any future caller would inherit
|
|
319
252
|
// the forgeable-substring hazard (crafted text projected out of context).
|
|
320
253
|
// Deleted instead of hardened: control-plane identity is customType.
|
|
321
254
|
function isGoalEventPayload(message: unknown): boolean {
|
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.43",
|
|
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",
|