omnius 1.0.688 → 1.0.689
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/dist/index.js +249 -294
- package/docs/DISCOVERY.json +38 -0
- package/docs/DISCOVERY.md +1 -0
- package/docs/work-orders/runtime-health-remediation/TRACKER.md +2 -0
- package/docs/work-orders/runtime-health-remediation/WO-20-exact-session-continuation.md +88 -0
- package/npm-shrinkwrap.json +2 -2
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -663967,7 +663967,7 @@ ${loadPrompt("agentic/system-small.md")}`;
|
|
|
663967
663967
|
if (this.options.subAgent || this.options.recursionDepth > 0)
|
|
663968
663968
|
return [];
|
|
663969
663969
|
const normalizedGoal = goal.replace(/\s+/g, " ").trim();
|
|
663970
|
-
if (normalizedGoal.length < 120 && !this.
|
|
663970
|
+
if (normalizedGoal.length < 120 && !this._resumeInterrupted)
|
|
663971
663971
|
return [];
|
|
663972
663972
|
return [
|
|
663973
663973
|
{
|
|
@@ -664035,44 +664035,6 @@ ${loadPrompt("agentic/system-small.md")}`;
|
|
|
664035
664035
|
}
|
|
664036
664036
|
];
|
|
664037
664037
|
}
|
|
664038
|
-
_isContinuationResumeGoal(goal) {
|
|
664039
|
-
const tokens3 = goal.toLowerCase().replace(/[^a-z0-9]+/g, " ").split(/\s+/).filter(Boolean);
|
|
664040
|
-
if (tokens3.length === 0 || tokens3.length > 14)
|
|
664041
|
-
return false;
|
|
664042
|
-
const continuationTerms = /* @__PURE__ */ new Set([
|
|
664043
|
-
"again",
|
|
664044
|
-
"and",
|
|
664045
|
-
"back",
|
|
664046
|
-
"carry",
|
|
664047
|
-
"complete",
|
|
664048
|
-
"continue",
|
|
664049
|
-
"finish",
|
|
664050
|
-
"from",
|
|
664051
|
-
"last",
|
|
664052
|
-
"latest",
|
|
664053
|
-
"left",
|
|
664054
|
-
"my",
|
|
664055
|
-
"off",
|
|
664056
|
-
"please",
|
|
664057
|
-
"previous",
|
|
664058
|
-
"prior",
|
|
664059
|
-
"proceed",
|
|
664060
|
-
"request",
|
|
664061
|
-
"resume",
|
|
664062
|
-
"task",
|
|
664063
|
-
"that",
|
|
664064
|
-
"the",
|
|
664065
|
-
"this",
|
|
664066
|
-
"to",
|
|
664067
|
-
"try",
|
|
664068
|
-
"work"
|
|
664069
|
-
]);
|
|
664070
|
-
const hasResumeVerb = tokens3.some((token) => token === "continue" || token === "resume" || token === "proceed" || token === "complete" || token === "finish");
|
|
664071
|
-
if (!hasResumeVerb)
|
|
664072
|
-
return false;
|
|
664073
|
-
const continuationTokenCount = tokens3.filter((token) => continuationTerms.has(token)).length;
|
|
664074
|
-
return continuationTokenCount / tokens3.length >= 0.7;
|
|
664075
|
-
}
|
|
664076
664038
|
/**
|
|
664077
664039
|
* Build a compact workboard context string for injection into the
|
|
664078
664040
|
* system prompt. Returns null when no active board exists or when
|
|
@@ -677190,7 +677152,7 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
677190
677152
|
this._memexArchive.clear();
|
|
677191
677153
|
this._todoOutputLedger.clear();
|
|
677192
677154
|
setTodoSessionId(this._sessionId);
|
|
677193
|
-
const continuesPriorTask = this._allowImplicitContinuation || this.
|
|
677155
|
+
const continuesPriorTask = this._allowImplicitContinuation || this._resumeInterrupted;
|
|
677194
677156
|
if (!continuesPriorTask) {
|
|
677195
677157
|
this._hidePriorSessionTodosForFreshTask(persistentTaskGoal);
|
|
677196
677158
|
}
|
|
@@ -731239,6 +731201,7 @@ __export(omnius_directory_exports, {
|
|
|
731239
731201
|
appendCompactionAudit: () => appendCompactionAudit,
|
|
731240
731202
|
buildContextRestorePrompt: () => buildContextRestorePrompt,
|
|
731241
731203
|
buildContextRestoreSnapshot: () => buildContextRestoreSnapshot,
|
|
731204
|
+
buildExactContinuationSnapshot: () => buildExactContinuationSnapshot,
|
|
731242
731205
|
buildHandoffPrompt: () => buildHandoffPrompt,
|
|
731243
731206
|
cleanPromptForDiary: () => cleanPromptForDiary,
|
|
731244
731207
|
clearTaskHandoff: () => clearTaskHandoff,
|
|
@@ -731260,6 +731223,8 @@ __export(omnius_directory_exports, {
|
|
|
731260
731223
|
loadSessionHistory: () => loadSessionHistory,
|
|
731261
731224
|
loadTuiSessionState: () => loadTuiSessionState,
|
|
731262
731225
|
loadUsageHistory: () => loadUsageHistory,
|
|
731226
|
+
pendingTaskMatchesInterruptionIdentity: () => pendingTaskMatchesInterruptionIdentity,
|
|
731227
|
+
pendingTaskMatchesRunningInterruption: () => pendingTaskMatchesRunningInterruption,
|
|
731263
731228
|
readIndexData: () => readIndexData,
|
|
731264
731229
|
readIndexMeta: () => readIndexMeta,
|
|
731265
731230
|
readTaskHandoff: () => readTaskHandoff2,
|
|
@@ -731659,21 +731624,64 @@ function loadRecentSessions(repoRoot, limit2 = 5) {
|
|
|
731659
731624
|
return [];
|
|
731660
731625
|
}
|
|
731661
731626
|
}
|
|
731627
|
+
function isValidPendingTask(value2, repoRoot) {
|
|
731628
|
+
if (!value2 || typeof value2 !== "object") return false;
|
|
731629
|
+
const task = value2;
|
|
731630
|
+
if (typeof task.prompt !== "string" || !task.prompt.trim() || typeof task.progressSummary !== "string" || !Array.isArray(task.filesModified) || !task.filesModified.every((item) => typeof item === "string") || typeof task.bruteForce !== "boolean" || typeof task.savedAt !== "string" || !Number.isFinite(Date.parse(task.savedAt)) || typeof task.toolCallCount !== "number" || !Number.isFinite(task.toolCallCount) || task.toolCallCount < 0) {
|
|
731631
|
+
return false;
|
|
731632
|
+
}
|
|
731633
|
+
if (task.schema !== void 0 && task.schema !== "omnius.pending-task.v2") {
|
|
731634
|
+
return false;
|
|
731635
|
+
}
|
|
731636
|
+
if (task.projectRoot !== void 0 && resolve77(task.projectRoot) !== resolve77(repoRoot)) {
|
|
731637
|
+
return false;
|
|
731638
|
+
}
|
|
731639
|
+
if (task.interruption !== void 0) {
|
|
731640
|
+
const interruption = task.interruption;
|
|
731641
|
+
if (typeof interruption.sessionId !== "string" || !interruption.sessionId.trim() || typeof interruption.runId !== "string" || !interruption.runId.trim() || !Number.isInteger(interruption.taskEpoch) || interruption.taskEpoch < 1 || !Number.isInteger(interruption.ownerGeneration) || interruption.ownerGeneration < 1 || interruption.phase !== "pausing" && interruption.phase !== "paused") {
|
|
731642
|
+
return false;
|
|
731643
|
+
}
|
|
731644
|
+
}
|
|
731645
|
+
if (task.resumeOnStartup === true && !task.interruption) return false;
|
|
731646
|
+
return true;
|
|
731647
|
+
}
|
|
731648
|
+
function pendingTaskMatchesRunningInterruption(pendingTask, candidate) {
|
|
731649
|
+
return candidate?.phase === "running" && pendingTaskMatchesInterruptionIdentity(pendingTask, candidate);
|
|
731650
|
+
}
|
|
731651
|
+
function pendingTaskMatchesInterruptionIdentity(pendingTask, candidate) {
|
|
731652
|
+
const expected = pendingTask.interruption;
|
|
731653
|
+
return Boolean(
|
|
731654
|
+
expected && candidate && candidate.sessionId === expected.sessionId && candidate.runId === expected.runId && candidate.taskEpoch === expected.taskEpoch && candidate.ownerGeneration === expected.ownerGeneration
|
|
731655
|
+
);
|
|
731656
|
+
}
|
|
731662
731657
|
function savePendingTask(repoRoot, task) {
|
|
731663
731658
|
const historyDir = join162(repoRoot, OMNIUS_DIR2, "history");
|
|
731664
731659
|
mkdirSync95(historyDir, { recursive: true });
|
|
731665
|
-
|
|
731666
|
-
|
|
731667
|
-
|
|
731668
|
-
|
|
731669
|
-
|
|
731660
|
+
const filePath = join162(historyDir, PENDING_TASK_FILE);
|
|
731661
|
+
const tempPath = `${filePath}.tmp-${process.pid}`;
|
|
731662
|
+
const checkpoint = {
|
|
731663
|
+
...task,
|
|
731664
|
+
schema: "omnius.pending-task.v2",
|
|
731665
|
+
projectRoot: resolve77(repoRoot)
|
|
731666
|
+
};
|
|
731667
|
+
const payload = JSON.stringify(checkpoint, null, 2) + "\n";
|
|
731668
|
+
writeFileSync85(tempPath, payload, "utf-8");
|
|
731669
|
+
try {
|
|
731670
|
+
renameSync30(tempPath, filePath);
|
|
731671
|
+
} catch {
|
|
731672
|
+
writeFileSync85(filePath, payload, "utf-8");
|
|
731673
|
+
try {
|
|
731674
|
+
unlinkSync37(tempPath);
|
|
731675
|
+
} catch {
|
|
731676
|
+
}
|
|
731677
|
+
}
|
|
731670
731678
|
}
|
|
731671
731679
|
function loadPendingTask(repoRoot) {
|
|
731672
731680
|
const filePath = join162(repoRoot, OMNIUS_DIR2, "history", PENDING_TASK_FILE);
|
|
731673
731681
|
try {
|
|
731674
731682
|
if (!existsSync148(filePath)) return null;
|
|
731675
731683
|
const data = JSON.parse(readFileSync124(filePath, "utf-8"));
|
|
731676
|
-
return data;
|
|
731684
|
+
return isValidPendingTask(data, repoRoot) ? data : null;
|
|
731677
731685
|
} catch {
|
|
731678
731686
|
return null;
|
|
731679
731687
|
}
|
|
@@ -732047,6 +732055,13 @@ function saveSessionContext(repoRoot, entry) {
|
|
|
732047
732055
|
ctx3.entries.push(normalizedEntry);
|
|
732048
732056
|
}
|
|
732049
732057
|
}
|
|
732058
|
+
ctx3.entries = ctx3.entries.map((item, index) => ({ item, index })).sort((a2, b) => {
|
|
732059
|
+
const left = Date.parse(a2.item.savedAt || "");
|
|
732060
|
+
const right = Date.parse(b.item.savedAt || "");
|
|
732061
|
+
const leftTime = Number.isFinite(left) ? left : 0;
|
|
732062
|
+
const rightTime = Number.isFinite(right) ? right : 0;
|
|
732063
|
+
return leftTime - rightTime || a2.index - b.index;
|
|
732064
|
+
}).map(({ item }) => item);
|
|
732050
732065
|
if (ctx3.entries.length > ctx3.maxEntries) {
|
|
732051
732066
|
ctx3.entries = ctx3.entries.slice(-ctx3.maxEntries);
|
|
732052
732067
|
}
|
|
@@ -732180,80 +732195,12 @@ function isManualSessionEntry(entry) {
|
|
|
732180
732195
|
const summary = normalizeSessionText(entry.summary || entry.assistantResponse, 160).toLowerCase();
|
|
732181
732196
|
return entry.source === "manual" || task === "(manual save)" || entry.toolCalls === 0 && summary.startsWith("manual context save");
|
|
732182
732197
|
}
|
|
732183
|
-
function isDeicticContinuationGoal(goal) {
|
|
732184
|
-
const tokens3 = normalizeSessionText(cleanPromptForDiary(goal), 180).toLowerCase().replace(/[^a-z0-9]+/g, " ").split(/\s+/).filter(Boolean);
|
|
732185
|
-
if (tokens3.length === 0 || tokens3.length > 14) return false;
|
|
732186
|
-
const hasResumeVerb = tokens3.some(
|
|
732187
|
-
(token) => token === "continue" || token === "resume" || token === "proceed" || token === "complete" || token === "finish"
|
|
732188
|
-
);
|
|
732189
|
-
if (!hasResumeVerb) return false;
|
|
732190
|
-
const deicticCount = tokens3.filter((token) => DEICTIC_CONTINUATION_TERMS.has(token)).length;
|
|
732191
|
-
return deicticCount / tokens3.length >= 0.7;
|
|
732192
|
-
}
|
|
732193
732198
|
function readRestoreWorkboard(repoRoot, runId) {
|
|
732194
732199
|
if (!runId) return null;
|
|
732195
732200
|
return readJsonOrNull(
|
|
732196
732201
|
join162(repoRoot, OMNIUS_DIR2, "workboards", runId, "active.json")
|
|
732197
732202
|
);
|
|
732198
732203
|
}
|
|
732199
|
-
function scoreRestoreLedger(ledger, workboard) {
|
|
732200
|
-
const status = ledger.status || "open";
|
|
732201
|
-
if (status === "approved") return -1e3;
|
|
732202
|
-
const evidence = ledger.evidence ?? [];
|
|
732203
|
-
const unresolvedCount = ledger.unresolved?.length ?? 0;
|
|
732204
|
-
const activeCards = (workboard?.cards ?? []).filter(
|
|
732205
|
-
(card) => card.status === "open" || card.status === "in_progress" || card.status === "needs_changes" || card.status === "blocked"
|
|
732206
|
-
).length;
|
|
732207
|
-
const mutationTools = /* @__PURE__ */ new Set(["file_edit", "file_patch", "batch_edit", "file_write"]);
|
|
732208
|
-
const mutationEvidence = evidence.filter((item) => mutationTools.has(item.toolName || "")).length;
|
|
732209
|
-
const failedMutationEvidence = evidence.filter(
|
|
732210
|
-
(item) => mutationTools.has(item.toolName || "") && item.success === false
|
|
732211
|
-
).length;
|
|
732212
|
-
const targetPathEvidence = evidence.filter((item) => (item.targetPaths?.length ?? 0) > 0).length;
|
|
732213
|
-
const blockedEvidence = evidence.filter((item) => {
|
|
732214
|
-
const summary = String(item.summary ?? "").toLowerCase();
|
|
732215
|
-
return summary.includes("[focus supervisor block]") || summary.includes("stale") || summary.includes("blocked");
|
|
732216
|
-
}).length;
|
|
732217
|
-
let score = 0;
|
|
732218
|
-
if (status === "open") score += 10;
|
|
732219
|
-
else if (status === "incomplete_verification") score += 18;
|
|
732220
|
-
else if (status === "request_changes" || status === "blocked") score += 16;
|
|
732221
|
-
else score += 4;
|
|
732222
|
-
score += Math.min(evidence.length, 20);
|
|
732223
|
-
score += Math.min(unresolvedCount, 10) * 4;
|
|
732224
|
-
score += Math.min(activeCards, 8) * 3;
|
|
732225
|
-
score += Math.min(mutationEvidence, 8) * 5;
|
|
732226
|
-
score += Math.min(failedMutationEvidence, 8) * 3;
|
|
732227
|
-
score += Math.min(targetPathEvidence, 6) * 2;
|
|
732228
|
-
score += Math.min(blockedEvidence, 6) * 2;
|
|
732229
|
-
const goal = normalizeSessionText(ledger.goal, 260);
|
|
732230
|
-
if (goal.length >= 80) score += 5;
|
|
732231
|
-
if (isDeicticContinuationGoal(goal) && mutationEvidence === 0 && unresolvedCount === 0 && activeCards === 0) {
|
|
732232
|
-
score -= 25;
|
|
732233
|
-
}
|
|
732234
|
-
return score;
|
|
732235
|
-
}
|
|
732236
|
-
function selectActiveTaskAnchor(repoRoot) {
|
|
732237
|
-
const ledgerDir = join162(repoRoot, OMNIUS_DIR2, "completion-ledgers");
|
|
732238
|
-
try {
|
|
732239
|
-
if (!existsSync148(ledgerDir)) return null;
|
|
732240
|
-
const candidates = readdirSync48(ledgerDir).filter((name10) => name10.endsWith(".json")).map((name10) => {
|
|
732241
|
-
const filePath = join162(ledgerDir, name10);
|
|
732242
|
-
const ledger = readJsonOrNull(filePath);
|
|
732243
|
-
if (!ledger || !ledger.goal) return null;
|
|
732244
|
-
const runId = ledger.runId || name10.replace(/\.json$/, "");
|
|
732245
|
-
const workboard = readRestoreWorkboard(repoRoot, runId);
|
|
732246
|
-
const score = scoreRestoreLedger(ledger, workboard);
|
|
732247
|
-
const mtimeMs = statSync58(filePath).mtimeMs;
|
|
732248
|
-
return { ledger: { ...ledger, runId }, workboard, score, mtimeMs };
|
|
732249
|
-
}).filter((item) => Boolean(item));
|
|
732250
|
-
candidates.sort((a2, b) => b.score - a2.score || b.mtimeMs - a2.mtimeMs);
|
|
732251
|
-
const selected = candidates.find((candidate) => candidate.score >= 18);
|
|
732252
|
-
return selected ?? null;
|
|
732253
|
-
} catch {
|
|
732254
|
-
return null;
|
|
732255
|
-
}
|
|
732256
|
-
}
|
|
732257
732204
|
function formatActiveTaskAnchor(selected) {
|
|
732258
732205
|
const ledger = selected.ledger;
|
|
732259
732206
|
const evidence = ledger.evidence ?? [];
|
|
@@ -732285,31 +732232,9 @@ ${evidenceLines.join("\n")}
|
|
|
732285
732232
|
${unresolvedLines.join("\n")}
|
|
732286
732233
|
` : "") + (boardCards.length > 0 ? `Active workboard cards:
|
|
732287
732234
|
${boardCards.join("\n")}
|
|
732288
|
-
` : "") + `Continuation rule:
|
|
732235
|
+
` : "") + `Continuation rule: this frontier is active only because its exact durable interruption identity was selected.
|
|
732289
732236
|
</active-task-anchor>`;
|
|
732290
732237
|
}
|
|
732291
|
-
function uniqueSessionIds(ids) {
|
|
732292
|
-
const seen = /* @__PURE__ */ new Set();
|
|
732293
|
-
const out = [];
|
|
732294
|
-
for (const raw of ids) {
|
|
732295
|
-
const id2 = String(raw || "").trim();
|
|
732296
|
-
if (!id2 || seen.has(id2)) continue;
|
|
732297
|
-
seen.add(id2);
|
|
732298
|
-
out.push(id2);
|
|
732299
|
-
}
|
|
732300
|
-
return out;
|
|
732301
|
-
}
|
|
732302
|
-
function collectRestoreSessionIds(ctx3, activeTask, historySessionId) {
|
|
732303
|
-
const entries2 = ctx3?.entries ?? [];
|
|
732304
|
-
const usefulEntries = entries2.filter((entry) => !isManualSessionEntry(entry));
|
|
732305
|
-
const chronological = usefulEntries.length > 0 ? usefulEntries : entries2;
|
|
732306
|
-
return uniqueSessionIds([
|
|
732307
|
-
activeTask?.ledger.runId,
|
|
732308
|
-
...[...chronological].reverse().map((entry) => entry.sessionId),
|
|
732309
|
-
...[...entries2].reverse().map((entry) => entry.sessionId),
|
|
732310
|
-
historySessionId
|
|
732311
|
-
]);
|
|
732312
|
-
}
|
|
732313
732238
|
function childMapForTodos(todos) {
|
|
732314
732239
|
const byId = new Set(todos.map((todo) => todo.id));
|
|
732315
732240
|
const byParent = /* @__PURE__ */ new Map();
|
|
@@ -732382,20 +732307,8 @@ ${treeLines.join("\n")}${omitted > 0 ? `
|
|
|
732382
732307
|
Continuation contract: this is the live checklist from the restored run. Continue it and update it with todo_write; do not recreate a parallel plan unless the new user request explicitly changes direction.
|
|
732383
732308
|
</restored-todo-state>`;
|
|
732384
732309
|
}
|
|
732385
|
-
function
|
|
732386
|
-
|
|
732387
|
-
const todos = readTodos(sessionId).filter((todo) => todo && todo.id && todo.content);
|
|
732388
|
-
if (todos.length === 0) continue;
|
|
732389
|
-
return {
|
|
732390
|
-
sessionId,
|
|
732391
|
-
todos,
|
|
732392
|
-
block: buildRestoredTodoBlock(sessionId, todos)
|
|
732393
|
-
};
|
|
732394
|
-
}
|
|
732395
|
-
return null;
|
|
732396
|
-
}
|
|
732397
|
-
function buildRestoreHistoryAnchor(repoRoot) {
|
|
732398
|
-
const [latest] = listSessions(repoRoot);
|
|
732310
|
+
function buildRestoreHistoryAnchor(repoRoot, exactSessionId) {
|
|
732311
|
+
const latest = exactSessionId ? listSessions(repoRoot).find((entry) => entry.id === exactSessionId) : listSessions(repoRoot)[0];
|
|
732399
732312
|
if (!latest?.id) return null;
|
|
732400
732313
|
const lines = loadSessionHistory(repoRoot, latest.id) ?? [];
|
|
732401
732314
|
const recordedLineCount = lines.filter((line) => String(line ?? "").trim()).length;
|
|
@@ -732411,6 +732324,76 @@ Recall contract: do not replay or ingest the transcript wholesale. Use the struc
|
|
|
732411
732324
|
</restored-interface-history>`;
|
|
732412
732325
|
return { sessionId: latest.id, path: path16, lineCount: recordedLineCount, block };
|
|
732413
732326
|
}
|
|
732327
|
+
function buildExactContinuationSnapshot(repoRoot, pendingTask) {
|
|
732328
|
+
const identity3 = pendingTask.interruption;
|
|
732329
|
+
if (!identity3) return null;
|
|
732330
|
+
if (pendingTask.projectRoot && resolve77(pendingTask.projectRoot) !== resolve77(repoRoot)) {
|
|
732331
|
+
return null;
|
|
732332
|
+
}
|
|
732333
|
+
const ledgerPath2 = join162(
|
|
732334
|
+
repoRoot,
|
|
732335
|
+
OMNIUS_DIR2,
|
|
732336
|
+
"completion-ledgers",
|
|
732337
|
+
`${identity3.runId}.json`
|
|
732338
|
+
);
|
|
732339
|
+
const rawLedger = readJsonOrNull(ledgerPath2);
|
|
732340
|
+
const ledger = rawLedger && (!rawLedger.runId || rawLedger.runId === identity3.runId) && (!rawLedger.taskEpoch || rawLedger.taskEpoch === identity3.taskEpoch) ? { ...rawLedger, runId: identity3.runId } : null;
|
|
732341
|
+
const rawWorkboard = readRestoreWorkboard(repoRoot, identity3.runId);
|
|
732342
|
+
const workboard = rawWorkboard && (!rawWorkboard.runId || rawWorkboard.runId === identity3.runId) && (!rawWorkboard.taskEpoch || rawWorkboard.taskEpoch === identity3.taskEpoch) ? rawWorkboard : null;
|
|
732343
|
+
const activeTaskAnchor = ledger ? formatActiveTaskAnchor({ ledger, workboard }) : null;
|
|
732344
|
+
const exactTodos = readTodos(identity3.sessionId).filter(
|
|
732345
|
+
(todo) => todo && todo.id && todo.content
|
|
732346
|
+
);
|
|
732347
|
+
const restoredTodos = exactTodos.length > 0 ? {
|
|
732348
|
+
sessionId: identity3.sessionId,
|
|
732349
|
+
todos: exactTodos,
|
|
732350
|
+
block: buildRestoredTodoBlock(identity3.sessionId, exactTodos)
|
|
732351
|
+
} : null;
|
|
732352
|
+
const historyAnchor = buildRestoreHistoryAnchor(repoRoot, identity3.sessionId);
|
|
732353
|
+
const contextEntries = (loadSessionContext(repoRoot)?.entries ?? []).filter((entry) => entry.sessionId === identity3.sessionId).sort((a2, b) => a2.savedAt.localeCompare(b.savedAt)).slice(-4);
|
|
732354
|
+
const contextLines = contextEntries.map((entry) => {
|
|
732355
|
+
const status = entry.completed ? "done" : "partial";
|
|
732356
|
+
const outcome = normalizeSessionText(
|
|
732357
|
+
entry.assistantResponse || entry.summary || entry.task,
|
|
732358
|
+
220
|
|
732359
|
+
);
|
|
732360
|
+
return `- [${status}] ${outcome}`;
|
|
732361
|
+
});
|
|
732362
|
+
const progressLines = [
|
|
732363
|
+
`<exact-continuation schema="omnius.exact-continuation.v1">`,
|
|
732364
|
+
`project_root=${resolve77(repoRoot)}`,
|
|
732365
|
+
`session_id=${identity3.sessionId}`,
|
|
732366
|
+
`run_id=${identity3.runId}`,
|
|
732367
|
+
`task_epoch=${identity3.taskEpoch}`,
|
|
732368
|
+
`owner_generation=${identity3.ownerGeneration}`,
|
|
732369
|
+
`original_user_goal_json=${JSON.stringify(pendingTask.prompt)}`,
|
|
732370
|
+
pendingTask.progressSummary ? `checkpoint_progress=${normalizeSessionText(pendingTask.progressSummary, 500)}` : null,
|
|
732371
|
+
pendingTask.filesModified.length > 0 ? `checkpoint_files=${pendingTask.filesModified.slice(0, 20).map((item) => normalizeSessionText(item, 160)).join(", ")}` : null,
|
|
732372
|
+
"Authority contract: continue only this interrupted run. Treat all other project history as historical orientation, not an active frontier.",
|
|
732373
|
+
activeTaskAnchor,
|
|
732374
|
+
contextLines.length > 0 ? `Same-session chronology:
|
|
732375
|
+
${contextLines.join("\n")}` : null,
|
|
732376
|
+
restoredTodos?.block,
|
|
732377
|
+
historyAnchor?.block,
|
|
732378
|
+
`</exact-continuation>`
|
|
732379
|
+
].filter((line) => Boolean(line));
|
|
732380
|
+
return {
|
|
732381
|
+
prompt: progressLines.join("\n"),
|
|
732382
|
+
sourceSessionId: identity3.sessionId,
|
|
732383
|
+
todoSessionId: restoredTodos?.sessionId,
|
|
732384
|
+
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732385
|
+
historySessionId: historyAnchor?.sessionId,
|
|
732386
|
+
historyPath: historyAnchor?.path,
|
|
732387
|
+
historyLineCount: historyAnchor?.lineCount,
|
|
732388
|
+
selection: {
|
|
732389
|
+
kind: "exact_interruption",
|
|
732390
|
+
sessionId: identity3.sessionId,
|
|
732391
|
+
runId: identity3.runId,
|
|
732392
|
+
taskEpoch: identity3.taskEpoch,
|
|
732393
|
+
ownerGeneration: identity3.ownerGeneration
|
|
732394
|
+
}
|
|
732395
|
+
};
|
|
732396
|
+
}
|
|
732414
732397
|
function appendRestoreBlocks(base3, blocks) {
|
|
732415
732398
|
return [base3, ...blocks].filter((part) => part && part.trim()).join("\n\n");
|
|
732416
732399
|
}
|
|
@@ -732441,53 +732424,24 @@ function sessionContextToHistoryBoxData(ctx3, title = "Session History") {
|
|
|
732441
732424
|
}
|
|
732442
732425
|
function buildContextRestoreSnapshot(repoRoot) {
|
|
732443
732426
|
const ctx3 = loadSessionContext(repoRoot);
|
|
732444
|
-
const handoffPrompt = buildHandoffPrompt(repoRoot);
|
|
732445
|
-
const activeTask = selectActiveTaskAnchor(repoRoot);
|
|
732446
|
-
const activeTaskAnchor = activeTask ? formatActiveTaskAnchor(activeTask) : null;
|
|
732447
732427
|
const historyAnchor = buildRestoreHistoryAnchor(repoRoot);
|
|
732448
|
-
const
|
|
732449
|
-
|
|
732450
|
-
|
|
732451
|
-
|
|
732452
|
-
|
|
732453
|
-
const usefulEntries2 = (ctx3?.entries ?? []).filter((entry) => !isManualSessionEntry(entry));
|
|
732454
|
-
const baseCtx = ctx3 && ctx3.entries.length > 0 ? `
|
|
732455
|
-
|
|
732456
|
-
<session-recap>
|
|
732457
|
-
Recent tasks: ${(usefulEntries2.length > 0 ? usefulEntries2 : ctx3.entries).slice(-3).map(
|
|
732458
|
-
(e2) => `[${e2.completed ? "done" : "partial"}] ${normalizeSessionText(e2.summary || e2.task, 80)}`
|
|
732459
|
-
).join(", ")}
|
|
732460
|
-
</session-recap>` : "";
|
|
732461
|
-
const prompt2 = appendRestoreBlocks(
|
|
732462
|
-
safeHandoffPrompt + (activeTaskAnchor ? `
|
|
732463
|
-
|
|
732464
|
-
${activeTaskAnchor}` : "") + baseCtx,
|
|
732465
|
-
[restoredTodos?.block, historyAnchor?.block]
|
|
732466
|
-
);
|
|
732467
|
-
return {
|
|
732468
|
-
prompt: prompt2,
|
|
732469
|
-
sourceSessionId,
|
|
732470
|
-
todoSessionId: restoredTodos?.sessionId,
|
|
732471
|
-
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732472
|
-
historySessionId: historyAnchor?.sessionId,
|
|
732473
|
-
historyPath: historyAnchor?.path,
|
|
732474
|
-
historyLineCount: historyAnchor?.lineCount
|
|
732475
|
-
};
|
|
732476
|
-
}
|
|
732428
|
+
const usefulEntries = (ctx3?.entries ?? []).filter(
|
|
732429
|
+
(entry) => !isManualSessionEntry(entry)
|
|
732430
|
+
);
|
|
732431
|
+
const chronological = usefulEntries.length > 0 ? usefulEntries : ctx3?.entries ?? [];
|
|
732432
|
+
const sourceSessionId = chronological.at(-1)?.sessionId ?? historyAnchor?.sessionId;
|
|
732477
732433
|
if (!ctx3 || ctx3.entries.length === 0) {
|
|
732478
|
-
const prompt2 = appendRestoreBlocks(
|
|
732434
|
+
const prompt2 = appendRestoreBlocks("", [historyAnchor?.block]);
|
|
732479
732435
|
if (!prompt2.trim()) return null;
|
|
732480
732436
|
return {
|
|
732481
732437
|
prompt: prompt2,
|
|
732482
732438
|
sourceSessionId,
|
|
732483
|
-
|
|
732484
|
-
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732439
|
+
todoCount: 0,
|
|
732485
732440
|
historySessionId: historyAnchor?.sessionId,
|
|
732486
732441
|
historyPath: historyAnchor?.path,
|
|
732487
732442
|
historyLineCount: historyAnchor?.lineCount
|
|
732488
732443
|
};
|
|
732489
732444
|
}
|
|
732490
|
-
const usefulEntries = ctx3.entries.filter((entry) => !isManualSessionEntry(entry));
|
|
732491
732445
|
const recent = (usefulEntries.length > 0 ? usefulEntries : ctx3.entries).slice(-20);
|
|
732492
732446
|
const chronology = recent.map((e2) => {
|
|
732493
732447
|
const status = e2.completed ? "done" : "partial";
|
|
@@ -732511,9 +732465,7 @@ Provenance: ${last2.provenance} (file_read to expand)` : "";
|
|
|
732511
732465
|
KG summary: .omnius/context/kg-summary/latest.md (file_read to expand; legacy pointer: .omnius/context/kg-summary-latest.md)`;
|
|
732512
732466
|
const prompt = appendRestoreBlocks(
|
|
732513
732467
|
`<session-recap>
|
|
732514
|
-
|
|
732515
|
-
|
|
732516
|
-
` : "") + `Project chronology (older to newer):
|
|
732468
|
+
Project chronology (older to newer):
|
|
732517
732469
|
Scope: full retained rolling window (${recent.length} entr${recent.length === 1 ? "y" : "ies"}).
|
|
732518
732470
|
${chronology.join("\n")}
|
|
732519
732471
|
` + (latestCompleted ? `
|
|
@@ -732521,16 +732473,14 @@ ${latestCompleted}
|
|
|
732521
732473
|
` : "\n") + `
|
|
732522
732474
|
Recent structured task state (older to newer; transcript omitted from model context):
|
|
732523
732475
|
${recentTaskState}
|
|
732524
|
-
|
|
732525
|
-
|
|
732526
|
-
|
|
732527
|
-
[restoredTodos?.block, historyAnchor?.block]
|
|
732476
|
+
This chronology is historical orientation only. It does not select an active task, todo tree, or run. Use an exact interruption checkpoint or an explicit lifecycle command for continuation authority.${prov}${kg}
|
|
732477
|
+
</session-recap>`,
|
|
732478
|
+
[historyAnchor?.block]
|
|
732528
732479
|
);
|
|
732529
732480
|
return {
|
|
732530
732481
|
prompt,
|
|
732531
732482
|
sourceSessionId,
|
|
732532
|
-
|
|
732533
|
-
todoCount: restoredTodos?.todos.length ?? 0,
|
|
732483
|
+
todoCount: 0,
|
|
732534
732484
|
historySessionId: historyAnchor?.sessionId,
|
|
732535
732485
|
historyPath: historyAnchor?.path,
|
|
732536
732486
|
historyLineCount: historyAnchor?.lineCount
|
|
@@ -732982,7 +732932,7 @@ function deleteUsageRecord(kind, value2, repoRoot) {
|
|
|
732982
732932
|
remove(join162(repoRoot, OMNIUS_DIR2, USAGE_HISTORY_FILE));
|
|
732983
732933
|
}
|
|
732984
732934
|
}
|
|
732985
|
-
var OMNIUS_DIR2, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, COMPACTION_AUDIT_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, MODEL_CONTEXT_NOISE_LINE_RE, DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES,
|
|
732935
|
+
var OMNIUS_DIR2, LEGACY_DIRS, SUBDIRS, gitignoreWatchers, gitignoreRetryTimers, CONTEXT_FILES, PENDING_TASK_FILE, HANDOFF_FILE, CONTEXT_SAVE_FILE, CONTEXT_LEDGER_FILE, COMPACTION_AUDIT_FILE, MAX_CONTEXT_ENTRIES, MAX_SESSION_DIARY_ENTRIES, MAX_SESSION_DIARY_DETAILED_ENTRIES, MAX_CONTEXT_LEDGER_LINES, MAX_CONTEXT_LEDGER_BYTES, SAME_TASK_REPLACE_WINDOW_MS, LOCK_TIMEOUT_MS, LOCK_RETRY_MS, LOCK_RETRY_MAX, MODEL_CONTEXT_NOISE_LINE_RE, DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES, SESSIONS_DIR, SESSIONS_INDEX, TUI_STATE_SUFFIX, AUTHORED_SESSION_LINE, VISUAL_CHROME_LINE, SESSION_TITLE_STATUS_LINE, SKIP_DIRS2, HOME_SKIP_DIRS, USAGE_HISTORY_FILE, MAX_HISTORY_RECORDS;
|
|
732986
732936
|
var init_omnius_directory = __esm({
|
|
732987
732937
|
"packages/cli/src/tui/omnius-directory.ts"() {
|
|
732988
732938
|
init_dist5();
|
|
@@ -733019,34 +732969,6 @@ var init_omnius_directory = __esm({
|
|
|
733019
732969
|
LOCK_RETRY_MAX = 100;
|
|
733020
732970
|
MODEL_CONTEXT_NOISE_LINE_RE = /^\s*(?:🔊|E Task timeout reached|E Incomplete:|⚠ Task incomplete|Tokens:\s*[\d,]+|▹\s*continue\b|·\s*(?:Starting fresh|Context (?:auto-)?restored|Nexus P2P network connected|REST API:|Voice feedback enabled|Memory maintenance:|Memory:|reclaimed\s+(?:\d|space\b)|physical footprint:)|.*\bSHELL TRANSCRIPT\b.*).*$/i;
|
|
733021
732971
|
DEFAULT_RESTORED_SESSION_HISTORY_MAX_LINES = 600;
|
|
733022
|
-
DEICTIC_CONTINUATION_TERMS = /* @__PURE__ */ new Set([
|
|
733023
|
-
"again",
|
|
733024
|
-
"and",
|
|
733025
|
-
"back",
|
|
733026
|
-
"carry",
|
|
733027
|
-
"complete",
|
|
733028
|
-
"continue",
|
|
733029
|
-
"finish",
|
|
733030
|
-
"from",
|
|
733031
|
-
"last",
|
|
733032
|
-
"latest",
|
|
733033
|
-
"left",
|
|
733034
|
-
"my",
|
|
733035
|
-
"off",
|
|
733036
|
-
"please",
|
|
733037
|
-
"previous",
|
|
733038
|
-
"prior",
|
|
733039
|
-
"proceed",
|
|
733040
|
-
"request",
|
|
733041
|
-
"resume",
|
|
733042
|
-
"task",
|
|
733043
|
-
"that",
|
|
733044
|
-
"the",
|
|
733045
|
-
"this",
|
|
733046
|
-
"to",
|
|
733047
|
-
"try",
|
|
733048
|
-
"work"
|
|
733049
|
-
]);
|
|
733050
732972
|
SESSIONS_DIR = "sessions";
|
|
733051
732973
|
SESSIONS_INDEX = "sessions-index.json";
|
|
733052
732974
|
TUI_STATE_SUFFIX = ".tui-state.json";
|
|
@@ -767195,7 +767117,7 @@ sleep 1
|
|
|
767195
767117
|
}
|
|
767196
767118
|
const paused = ctx3.pauseTask?.() ?? false;
|
|
767197
767119
|
if (interruptionAccepted(paused)) {
|
|
767198
|
-
ctx3.savePendingTaskState?.();
|
|
767120
|
+
ctx3.savePendingTaskState?.({ reason: "pause", resumeOnStartup: false });
|
|
767199
767121
|
renderInfo(interruptionMessage(paused, "Task paused."));
|
|
767200
767122
|
} else {
|
|
767201
767123
|
renderWarning(interruptionMessage(paused, "Could not pause the task."));
|
|
@@ -777335,7 +777257,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
777335
777257
|
`Updated Omnius v${currentVersion} → v${terminal.installed_version ?? info.latestVersion}; daemon v${terminal.daemon_version ?? info.latestVersion}${terminal.tray_was_running ? ", indicator restarted" : ""}.`
|
|
777336
777258
|
);
|
|
777337
777259
|
ctx3.contextSave?.();
|
|
777338
|
-
ctx3.savePendingTaskState?.();
|
|
777260
|
+
ctx3.savePendingTaskState?.({ reason: "update", resumeOnStartup: true });
|
|
777339
777261
|
if (ctx3.hasActiveTask?.()) ctx3.abortActiveTask?.({ preserveResume: true });
|
|
777340
777262
|
ctx3.killEphemeral?.({ preserveInfrastructure: true });
|
|
777341
777263
|
process.exit(120);
|
|
@@ -777924,7 +777846,7 @@ async function handleUpdate(subcommand, ctx3) {
|
|
|
777924
777846
|
!daemonUpgrade.ok ? `Daemon still at ${daemonUpgrade.observedVersion ?? "unknown"} — restarting client anyway` : daemonUpgrade.action === "restarted" ? `Daemon upgraded to ${expectedDaemonVersion}` : `Daemon verified at ${expectedDaemonVersion}`
|
|
777925
777847
|
);
|
|
777926
777848
|
ctx3.contextSave?.();
|
|
777927
|
-
const hadActiveTask = ctx3.savePendingTaskState?.() ?? false;
|
|
777849
|
+
const hadActiveTask = ctx3.savePendingTaskState?.({ reason: "update", resumeOnStartup: true }) ?? false;
|
|
777928
777850
|
const resumeFlag = hadActiveTask ? "1" : "update-only";
|
|
777929
777851
|
installOverlay.stop("Restarting with new version...");
|
|
777930
777852
|
await new Promise((r2) => setTimeout(r2, 1500));
|
|
@@ -832606,9 +832528,6 @@ async function runSelfImprovementCycle(repoRoot) {
|
|
|
832606
832528
|
} catch {
|
|
832607
832529
|
}
|
|
832608
832530
|
}
|
|
832609
|
-
function isExplicitRestoredTaskContinuation(input) {
|
|
832610
|
-
return /^(?:continue|resume|pick\s+up|carry\s+on)\b/i.test(input.trim());
|
|
832611
|
-
}
|
|
832612
832531
|
function startTask(task, config, repoRoot, voice, stream, taskStores, bruteForce, statusBar, sudoCallback, costTracker, onComplete, taskType, contextWindowSize, modelCaps, personality, deepContext, onCompaction, emotionEngine, flowEnabled, slashCommandHandler, thinkingEnabled, askUserCallback, selfModifyEnabled, sessionMetrics, realtimeEnabled, restoredRunSessionId, restoredOrientation, actualUserGoal, actionTreeStore, resumeInterrupted = false) {
|
|
832613
832532
|
const voiceStyleMap = {
|
|
832614
832533
|
concise: 1,
|
|
@@ -833002,6 +832921,9 @@ Only tools allowed by this profile are visible and executable.`
|
|
|
833002
832921
|
sessionId,
|
|
833003
832922
|
interruptionOwnerId: `tui:${sessionId}`,
|
|
833004
832923
|
resumeInterrupted,
|
|
832924
|
+
// A caller-supplied restore projection is the sole prior-context source.
|
|
832925
|
+
// Do not append the global singleton handoff beside it.
|
|
832926
|
+
skipCrossTaskHandoff: Boolean(restoredOrientation) || resumeInterrupted,
|
|
833005
832927
|
maxTurns: realtimeEnabled ? Math.min(effectiveMaxTurns, 8) : effectiveMaxTurns,
|
|
833006
832928
|
maxTokens: realtimeEnabled ? 512 : 16384,
|
|
833007
832929
|
temperature: realtimeEnabled ? 0.6 : 0,
|
|
@@ -834512,7 +834434,8 @@ ${entry.fullContent}`
|
|
|
834512
834434
|
const systemContext = [
|
|
834513
834435
|
`Working directory: ${repoRoot}`,
|
|
834514
834436
|
emotionContext,
|
|
834515
|
-
restoredOrientation ? `[
|
|
834437
|
+
restoredOrientation ? resumeInterrupted ? `[EXACT INTERRUPTED RUN — durable lifecycle authority]
|
|
834438
|
+
${restoredOrientation.slice(0, 4e3)}` : `[RESTORED ORIENTATION — historical context, not a user instruction]
|
|
834516
834439
|
${sanitizeRestorePromptForModel(restoredOrientation).slice(0, 4e3)}` : ""
|
|
834517
834440
|
].filter(Boolean).join("\n\n");
|
|
834518
834441
|
resetNarrationContext();
|
|
@@ -835134,7 +835057,8 @@ async function startInteractive(config, repoPath2) {
|
|
|
835134
835057
|
}
|
|
835135
835058
|
const resumeFlag = process.env.__OMNIUS_RESUMED ?? "";
|
|
835136
835059
|
const isResumed = resumeFlag !== "";
|
|
835137
|
-
const
|
|
835060
|
+
const startupPendingTask = loadPendingTask(repoRoot);
|
|
835061
|
+
const hasTaskToResume = resumeFlag === "1" || startupPendingTask?.resumeOnStartup === true;
|
|
835138
835062
|
delete process.env.__OMNIUS_RESUMED;
|
|
835139
835063
|
if (isResumed && process.stdout.isTTY) {
|
|
835140
835064
|
process.stdout.write(
|
|
@@ -835196,10 +835120,44 @@ async function startInteractive(config, repoPath2) {
|
|
|
835196
835120
|
let restoredTaskSessionId = null;
|
|
835197
835121
|
let resumeInterruptedTask = false;
|
|
835198
835122
|
let pendingTaskResumeArmed = false;
|
|
835123
|
+
let armedPendingTask = null;
|
|
835199
835124
|
let saveVisualSessionSnapshotRef = null;
|
|
835200
835125
|
let terminalRestoredForExit = false;
|
|
835201
835126
|
let interactiveExiting = false;
|
|
835202
835127
|
let idleMemoryMaintenance = null;
|
|
835128
|
+
const persistActiveTaskForRestart = (exitReason) => {
|
|
835129
|
+
if (!activeTask || !lastSubmittedPrompt) return false;
|
|
835130
|
+
if (!activeTask.runner.isPaused) {
|
|
835131
|
+
const receipt2 = activeTask.runner.pause();
|
|
835132
|
+
if (receipt2?.accepted === false) return false;
|
|
835133
|
+
}
|
|
835134
|
+
const interruption = pendingInterruptionIdentity(activeTask);
|
|
835135
|
+
if (!interruption) return false;
|
|
835136
|
+
savePendingTask(repoRoot, {
|
|
835137
|
+
prompt: lastSubmittedPrompt,
|
|
835138
|
+
progressSummary: `Task paused for ${exitReason}. ${activeTask.toolCallCount} tool calls completed.`,
|
|
835139
|
+
filesModified: Array.from(activeTask.filesTouched),
|
|
835140
|
+
bruteForce: bruteForceEnabled,
|
|
835141
|
+
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
835142
|
+
toolCallCount: activeTask.toolCallCount,
|
|
835143
|
+
exitReason,
|
|
835144
|
+
resumeOnStartup: true,
|
|
835145
|
+
interruption
|
|
835146
|
+
});
|
|
835147
|
+
return true;
|
|
835148
|
+
};
|
|
835149
|
+
const armPendingTaskResume = (pendingTask) => {
|
|
835150
|
+
restoredTaskSessionId = pendingTask.interruption?.sessionId ?? null;
|
|
835151
|
+
resumeInterruptedTask = Boolean(pendingTask.interruption);
|
|
835152
|
+
pendingTaskResumeArmed = true;
|
|
835153
|
+
armedPendingTask = pendingTask;
|
|
835154
|
+
const exactSnapshot = buildExactContinuationSnapshot(repoRoot, pendingTask);
|
|
835155
|
+
restoredSessionContext = exactSnapshot?.prompt ?? [
|
|
835156
|
+
`Original user goal: ${pendingTask.prompt}`,
|
|
835157
|
+
pendingTask.progressSummary,
|
|
835158
|
+
pendingTask.filesModified.length > 0 ? `Modified: ${pendingTask.filesModified.slice(0, 20).join(", ")}` : ""
|
|
835159
|
+
].filter(Boolean).join("\n");
|
|
835160
|
+
};
|
|
835203
835161
|
const restoreTerminalForExit = () => {
|
|
835204
835162
|
if (!process.stdout.isTTY || terminalRestoredForExit) return;
|
|
835205
835163
|
terminalRestoredForExit = true;
|
|
@@ -835231,18 +835189,7 @@ async function startInteractive(config, repoPath2) {
|
|
|
835231
835189
|
}
|
|
835232
835190
|
if (activeTask) {
|
|
835233
835191
|
if (interruption === "pause") {
|
|
835234
|
-
|
|
835235
|
-
if (receipt2?.accepted !== false && lastSubmittedPrompt) {
|
|
835236
|
-
savePendingTask(repoRoot, {
|
|
835237
|
-
prompt: lastSubmittedPrompt,
|
|
835238
|
-
progressSummary: `Task paused during process shutdown. ${activeTask.toolCallCount} tool calls completed.`,
|
|
835239
|
-
filesModified: Array.from(activeTask.filesTouched),
|
|
835240
|
-
bruteForce: bruteForceEnabled,
|
|
835241
|
-
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
835242
|
-
toolCallCount: activeTask.toolCallCount,
|
|
835243
|
-
interruption: pendingInterruptionIdentity(activeTask)
|
|
835244
|
-
});
|
|
835245
|
-
}
|
|
835192
|
+
persistActiveTaskForRestart("shutdown");
|
|
835246
835193
|
} else {
|
|
835247
835194
|
activeTask.runner.abort();
|
|
835248
835195
|
discardPendingTask(repoRoot);
|
|
@@ -837089,9 +837036,9 @@ This is an independent background session started from /background.`
|
|
|
837089
837036
|
if (options2.injectNextTask !== false) {
|
|
837090
837037
|
restoredSessionContext = snapshot.prompt;
|
|
837091
837038
|
}
|
|
837092
|
-
const restoredId = snapshot.
|
|
837093
|
-
|
|
837094
|
-
|
|
837039
|
+
const restoredId = options2.bindTaskIdentity && snapshot.selection ? snapshot.selection.sessionId : null;
|
|
837040
|
+
if (restoredId && snapshot.selection?.kind === "exact_interruption") {
|
|
837041
|
+
restoredTaskSessionId = restoredId;
|
|
837095
837042
|
try {
|
|
837096
837043
|
process.env["OMNIUS_SESSION_ID"] = restoredId;
|
|
837097
837044
|
} catch {
|
|
@@ -838195,8 +838142,14 @@ The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analy
|
|
|
838195
838142
|
} catch {
|
|
838196
838143
|
}
|
|
838197
838144
|
},
|
|
838198
|
-
savePendingTaskState() {
|
|
838145
|
+
savePendingTaskState(options2) {
|
|
838199
838146
|
if (lastSubmittedPrompt && activeTask) {
|
|
838147
|
+
if (!activeTask.runner.isPaused) {
|
|
838148
|
+
const receipt2 = activeTask.runner.pause();
|
|
838149
|
+
if (receipt2?.accepted === false) return false;
|
|
838150
|
+
}
|
|
838151
|
+
const interruption = pendingInterruptionIdentity(activeTask);
|
|
838152
|
+
if (!interruption) return false;
|
|
838200
838153
|
const activeToolCallCount = activeTask.toolCallCount;
|
|
838201
838154
|
const activeFilesTouched = Array.from(activeTask.filesTouched);
|
|
838202
838155
|
savePendingTask(repoRoot, {
|
|
@@ -838206,7 +838159,9 @@ The user pasted a clipboard image saved at ${relPath}. Use the OCR, vision analy
|
|
|
838206
838159
|
bruteForce: bruteForceEnabled,
|
|
838207
838160
|
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
838208
838161
|
toolCallCount: activeToolCallCount,
|
|
838209
|
-
|
|
838162
|
+
exitReason: options2?.reason ?? "pause",
|
|
838163
|
+
resumeOnStartup: options2?.resumeOnStartup === true,
|
|
838164
|
+
interruption
|
|
838210
838165
|
});
|
|
838211
838166
|
return true;
|
|
838212
838167
|
}
|
|
@@ -839881,19 +839836,11 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
839881
839836
|
resumeTask() {
|
|
839882
839837
|
const pendingTask = loadPendingTask(repoRoot);
|
|
839883
839838
|
if (!pendingTask) return false;
|
|
839884
|
-
|
|
839885
|
-
resumeInterruptedTask = Boolean(pendingTask.interruption);
|
|
839886
|
-
pendingTaskResumeArmed = true;
|
|
839839
|
+
armPendingTaskResume(pendingTask);
|
|
839887
839840
|
setTimeout(() => {
|
|
839888
|
-
const resumeContext = [
|
|
839889
|
-
`Continuing previous task: ${pendingTask.prompt}`,
|
|
839890
|
-
pendingTask.progressSummary ? `Progress: ${pendingTask.progressSummary}` : "",
|
|
839891
|
-
pendingTask.filesModified.length > 0 ? `Modified: ${pendingTask.filesModified.slice(0, 5).join(", ")}` : "",
|
|
839892
|
-
"Continue where you left off."
|
|
839893
|
-
].filter(Boolean).join("\n");
|
|
839894
839841
|
const shortPrompt = pendingTask.prompt.slice(0, 40) + (pendingTask.prompt.length > 40 ? "..." : "");
|
|
839895
839842
|
writeContent(() => renderInfo(`Picking up: ${shortPrompt}`));
|
|
839896
|
-
rl.emit("line",
|
|
839843
|
+
rl.emit("line", pendingTask.prompt);
|
|
839897
839844
|
}, 100);
|
|
839898
839845
|
return true;
|
|
839899
839846
|
},
|
|
@@ -840151,7 +840098,7 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
840151
840098
|
}
|
|
840152
840099
|
statusBar.ensureMonitorTimer();
|
|
840153
840100
|
showPrompt();
|
|
840154
|
-
if (!isResumed) {
|
|
840101
|
+
if (!isResumed && !hasTaskToResume) {
|
|
840155
840102
|
const savedCtx = loadSessionContext(repoRoot);
|
|
840156
840103
|
if (savedCtx && savedCtx.entries.length > 0) {
|
|
840157
840104
|
const lastEntry = savedCtx.entries[savedCtx.entries.length - 1];
|
|
@@ -840277,30 +840224,13 @@ Respond concisely and safely. Remember: you are talking to the general public.`;
|
|
|
840277
840224
|
}
|
|
840278
840225
|
startReminderDispatcher();
|
|
840279
840226
|
if (hasTaskToResume) {
|
|
840280
|
-
const pendingTask = loadPendingTask(repoRoot);
|
|
840227
|
+
const pendingTask = startupPendingTask ?? loadPendingTask(repoRoot);
|
|
840281
840228
|
if (pendingTask) {
|
|
840282
|
-
|
|
840283
|
-
resumeInterruptedTask = Boolean(pendingTask.interruption);
|
|
840284
|
-
pendingTaskResumeArmed = true;
|
|
840229
|
+
armPendingTaskResume(pendingTask);
|
|
840285
840230
|
setTimeout(() => {
|
|
840286
|
-
const restoreSnapshot = buildContextRestoreSnapshot(repoRoot);
|
|
840287
|
-
if (restoreSnapshot) {
|
|
840288
|
-
applyRestoreSnapshot(restoreSnapshot, {
|
|
840289
|
-
replayVisual: false,
|
|
840290
|
-
injectNextTask: false
|
|
840291
|
-
});
|
|
840292
|
-
}
|
|
840293
|
-
const sessionCtx = restoreSnapshot?.prompt ?? buildContextRestorePrompt(repoRoot);
|
|
840294
|
-
const resumeContext = [
|
|
840295
|
-
sessionCtx || "",
|
|
840296
|
-
`Continuing task after update: ${pendingTask.prompt}`,
|
|
840297
|
-
pendingTask.progressSummary ? `Progress: ${pendingTask.progressSummary}` : "",
|
|
840298
|
-
pendingTask.filesModified.length > 0 ? `Modified: ${pendingTask.filesModified.slice(0, 5).join(", ")}` : "",
|
|
840299
|
-
"Continue where you left off."
|
|
840300
|
-
].filter(Boolean).join("\n");
|
|
840301
840231
|
const shortPrompt = pendingTask.prompt.slice(0, 40) + (pendingTask.prompt.length > 40 ? "..." : "");
|
|
840302
840232
|
writeContent(() => renderInfo(`Picking up: ${shortPrompt}`));
|
|
840303
|
-
rl.emit("line",
|
|
840233
|
+
rl.emit("line", pendingTask.prompt);
|
|
840304
840234
|
}, 100);
|
|
840305
840235
|
}
|
|
840306
840236
|
}
|
|
@@ -840492,10 +840422,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
840492
840422
|
if (quitMatch === "quit" || quitMatch === "exit" || quitMatch === "q") {
|
|
840493
840423
|
interactiveExiting = true;
|
|
840494
840424
|
saveVisualSessionSnapshot();
|
|
840495
|
-
if (activeTask)
|
|
840496
|
-
activeTask.runner.abort();
|
|
840497
|
-
discardPendingTask(repoRoot);
|
|
840498
|
-
}
|
|
840425
|
+
if (activeTask) persistActiveTaskForRestart("quit");
|
|
840499
840426
|
idleMemoryMaintenance?.stop();
|
|
840500
840427
|
taskManager.stopAll();
|
|
840501
840428
|
if (blessEngine?.isActive) blessEngine.stop();
|
|
@@ -840513,10 +840440,7 @@ ${result.content.slice(0, 2e3)}${result.content.length > 2e3 ? "\n[truncated]" :
|
|
|
840513
840440
|
if (cmdResult === "exit") {
|
|
840514
840441
|
interactiveExiting = true;
|
|
840515
840442
|
saveVisualSessionSnapshot();
|
|
840516
|
-
if (activeTask)
|
|
840517
|
-
activeTask.runner.abort();
|
|
840518
|
-
discardPendingTask(repoRoot);
|
|
840519
|
-
}
|
|
840443
|
+
if (activeTask) persistActiveTaskForRestart("quit");
|
|
840520
840444
|
idleMemoryMaintenance?.stop();
|
|
840521
840445
|
taskManager.stopAll();
|
|
840522
840446
|
if (telegramBridge) await telegramBridge.stopAndWait();
|
|
@@ -841078,6 +841002,10 @@ ${formatTaskCompletionMeta(previousMetaForIntake)}`
|
|
|
841078
841002
|
);
|
|
841079
841003
|
}
|
|
841080
841004
|
if (promptRecallCancelled) return;
|
|
841005
|
+
const pendingTaskForAdmission = pendingTaskResumeArmed ? armedPendingTask : null;
|
|
841006
|
+
if (pendingTaskForAdmission) {
|
|
841007
|
+
fullInput = pendingTaskForAdmission.prompt;
|
|
841008
|
+
}
|
|
841081
841009
|
lastSubmittedPrompt = fullInput;
|
|
841082
841010
|
const taskPreview = fullInput.length > 100 ? fullInput.slice(0, 100) + "..." : fullInput;
|
|
841083
841011
|
emotionEngine.setCurrentTask(taskPreview);
|
|
@@ -841094,18 +841022,19 @@ ${formatTaskCompletionMeta(previousMetaForIntake)}`
|
|
|
841094
841022
|
} catch {
|
|
841095
841023
|
}
|
|
841096
841024
|
let taskInput = fullInput;
|
|
841097
|
-
const reuseRestoredTaskSession = Boolean(restoredTaskSessionId) &&
|
|
841025
|
+
const reuseRestoredTaskSession = Boolean(restoredTaskSessionId) && resumeInterruptedTask && Boolean(pendingTaskForAdmission?.interruption);
|
|
841098
841026
|
let taskSessionId = reuseRestoredTaskSession ? restoredTaskSessionId : null;
|
|
841099
841027
|
const adoptInterruptedGeneration = reuseRestoredTaskSession && resumeInterruptedTask;
|
|
841100
841028
|
const consumePendingTaskAfterAdmission = pendingTaskResumeArmed;
|
|
841101
841029
|
let restoredOrientation = null;
|
|
841102
841030
|
if (restoredSessionContext) {
|
|
841103
|
-
restoredOrientation = sanitizeRestorePromptForModel(restoredSessionContext);
|
|
841031
|
+
restoredOrientation = pendingTaskForAdmission ? restoredSessionContext : sanitizeRestorePromptForModel(restoredSessionContext);
|
|
841104
841032
|
restoredSessionContext = null;
|
|
841105
841033
|
}
|
|
841106
841034
|
restoredTaskSessionId = null;
|
|
841107
841035
|
resumeInterruptedTask = false;
|
|
841108
841036
|
pendingTaskResumeArmed = false;
|
|
841037
|
+
armedPendingTask = null;
|
|
841109
841038
|
if (taskIntakePacket) {
|
|
841110
841039
|
taskInput = `${taskIntakePacket}
|
|
841111
841040
|
|
|
@@ -841162,14 +841091,23 @@ ${taskInput}`;
|
|
|
841162
841091
|
realtimeEnabled,
|
|
841163
841092
|
taskSessionId,
|
|
841164
841093
|
restoredOrientation,
|
|
841165
|
-
fullInput,
|
|
841094
|
+
pendingTaskForAdmission?.prompt ?? fullInput,
|
|
841166
841095
|
idleActionTree,
|
|
841167
841096
|
adoptInterruptedGeneration
|
|
841168
841097
|
);
|
|
841169
841098
|
activeTask = task;
|
|
841170
841099
|
if (consumePendingTaskAfterAdmission) {
|
|
841171
841100
|
const adopted = task.runner.interruptionState;
|
|
841172
|
-
if (!
|
|
841101
|
+
if (pendingTaskForAdmission && !pendingTaskForAdmission.interruption || pendingTaskForAdmission && pendingTaskMatchesRunningInterruption(
|
|
841102
|
+
pendingTaskForAdmission,
|
|
841103
|
+
adopted ? {
|
|
841104
|
+
sessionId: adopted.sessionId,
|
|
841105
|
+
runId: adopted.runId,
|
|
841106
|
+
taskEpoch: adopted.taskEpoch,
|
|
841107
|
+
ownerGeneration: adopted.owner.generation,
|
|
841108
|
+
phase: adopted.phase
|
|
841109
|
+
} : null
|
|
841110
|
+
)) {
|
|
841173
841111
|
discardPendingTask(repoRoot);
|
|
841174
841112
|
}
|
|
841175
841113
|
}
|
|
@@ -841227,6 +841165,21 @@ ${taskInput}`;
|
|
|
841227
841165
|
scheduleAgentSNREval(lastSubmittedPrompt);
|
|
841228
841166
|
}
|
|
841229
841167
|
if (activeTask) {
|
|
841168
|
+
if (pendingTaskForAdmission?.interruption) {
|
|
841169
|
+
const state5 = activeTask.runner.interruptionState;
|
|
841170
|
+
if (state5 && state5.phase !== "running" && state5.phase !== "pausing" && state5.phase !== "paused" && state5.phase !== "resuming" && pendingTaskMatchesInterruptionIdentity(
|
|
841171
|
+
pendingTaskForAdmission,
|
|
841172
|
+
{
|
|
841173
|
+
sessionId: state5.sessionId,
|
|
841174
|
+
runId: state5.runId,
|
|
841175
|
+
taskEpoch: state5.taskEpoch,
|
|
841176
|
+
ownerGeneration: state5.owner.generation,
|
|
841177
|
+
phase: state5.phase
|
|
841178
|
+
}
|
|
841179
|
+
)) {
|
|
841180
|
+
discardPendingTask(repoRoot);
|
|
841181
|
+
}
|
|
841182
|
+
}
|
|
841230
841183
|
sessionFilesTouched = Array.from(activeTask.filesTouched);
|
|
841231
841184
|
sessionToolCallCount = activeTask.toolCallCount;
|
|
841232
841185
|
sessionAvailableTools = Array.from(activeTask.availableTools);
|
|
@@ -841506,7 +841459,7 @@ Rationale: ${proposal.rationale}${provenanceNote}${dmnDevDiscipline(proposal.cat
|
|
|
841506
841459
|
peerMesh = null;
|
|
841507
841460
|
inferenceRouter = null;
|
|
841508
841461
|
}
|
|
841509
|
-
if (activeTask)
|
|
841462
|
+
if (activeTask) persistActiveTaskForRestart("shutdown");
|
|
841510
841463
|
taskManager.stopAll();
|
|
841511
841464
|
killAllFullSubAgents();
|
|
841512
841465
|
idleMemoryMaintenance?.stop();
|
|
@@ -841600,6 +841553,8 @@ ${c3.dim("(Use /quit to exit)")}
|
|
|
841600
841553
|
bruteForce: bruteForceEnabled,
|
|
841601
841554
|
savedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
841602
841555
|
toolCallCount: activeTask.toolCallCount,
|
|
841556
|
+
exitReason: "pause",
|
|
841557
|
+
resumeOnStartup: false,
|
|
841603
841558
|
interruption: pendingInterruptionIdentity(activeTask)
|
|
841604
841559
|
});
|
|
841605
841560
|
}
|
package/docs/DISCOVERY.json
CHANGED
|
@@ -33786,6 +33786,44 @@
|
|
|
33786
33786
|
}
|
|
33787
33787
|
]
|
|
33788
33788
|
},
|
|
33789
|
+
{
|
|
33790
|
+
"id": "guide.work-orders-runtime-health-remediation-wo-20-exact-session-continuation-uppercase",
|
|
33791
|
+
"kind": "guide",
|
|
33792
|
+
"title": "WO-20: Exact session continuation across exit and restart",
|
|
33793
|
+
"summary": "On 2026-09-03, the telegramtest TUI displayed the latest pentest task during startup, but the first restored model context combined a completed breach.py handoff with an unrelated, older page.tsx todo tree. The user then entered continue, and Omnius continued the stale tree instead of the task that was active before /quit.",
|
|
33794
|
+
"keywords": [
|
|
33795
|
+
"work",
|
|
33796
|
+
"orders",
|
|
33797
|
+
"runtime",
|
|
33798
|
+
"health",
|
|
33799
|
+
"remediation",
|
|
33800
|
+
"WO",
|
|
33801
|
+
"20",
|
|
33802
|
+
"exact",
|
|
33803
|
+
"session",
|
|
33804
|
+
"continuation",
|
|
33805
|
+
"md"
|
|
33806
|
+
],
|
|
33807
|
+
"maturity": "internal",
|
|
33808
|
+
"audiences": [
|
|
33809
|
+
"maintainer",
|
|
33810
|
+
"large-context-agent"
|
|
33811
|
+
],
|
|
33812
|
+
"layer": "documentation",
|
|
33813
|
+
"interfaces": [
|
|
33814
|
+
{
|
|
33815
|
+
"type": "file",
|
|
33816
|
+
"target": "docs/work-orders/runtime-health-remediation/WO-20-exact-session-continuation.md"
|
|
33817
|
+
}
|
|
33818
|
+
],
|
|
33819
|
+
"references": [
|
|
33820
|
+
{
|
|
33821
|
+
"type": "documentation",
|
|
33822
|
+
"target": "docs/work-orders/runtime-health-remediation/WO-20-exact-session-continuation.md",
|
|
33823
|
+
"relation": "canonical-artifact"
|
|
33824
|
+
}
|
|
33825
|
+
]
|
|
33826
|
+
},
|
|
33789
33827
|
{
|
|
33790
33828
|
"id": "guide.work-orders-telegram-dropbear-context-rca-workorder",
|
|
33791
33829
|
"kind": "guide",
|
package/docs/DISCOVERY.md
CHANGED
|
@@ -558,6 +558,7 @@ Daemon equivalents are `GET /v1/discovery/bootstrap`, `GET /v1/discovery?q=<inte
|
|
|
558
558
|
| `guide.work-orders-runtime-health-remediation-wo-18-interruption-evidence-uppercase` | WO-18 interruption lifecycle evidence | Scope: /pause, /resume, /stop, safe-boundary ownership, recovery, and stale-effect prevention. This record is independent of the shared remediation tracker and records only verified WO-18 implementation evidence. |
|
|
559
559
|
| `guide.work-orders-runtime-health-remediation-wo-19-clean-build-evidence-uppercase` | WO-19 Clean Build Evidence | WO-19 is implemented in commit 5f253c05. |
|
|
560
560
|
| `guide.work-orders-runtime-health-remediation-wo-19-clean-build-reproducibility-uppercase` | WO-19: Clean Build and Optional-Dependency Reproducibility | Status: deterministic acceptance complete Risk: medium Depends on: WO-00 |
|
|
561
|
+
| `guide.work-orders-runtime-health-remediation-wo-20-exact-session-continuation-uppercase` | WO-20: Exact session continuation across exit and restart | On 2026-09-03, the telegramtest TUI displayed the latest pentest task during startup, but the first restored model context combined a completed breach.py handoff with an unrelated, older page.tsx todo tree. The user then entered continue, and Omnius continued the stale tree instead of the task that was active before /quit. |
|
|
561
562
|
| `guide.work-orders-telegram-dropbear-context-rca-workorder` | Telegram Dropbear Context Engineering RCA Work Order | Observed run: /home/roko/Documents/Projects/Adjacent/telegramtest/.omnius, run id 1782873796963-i5r7mv. |
|
|
562
563
|
| `guide.work-orders-wo-am-gaps-uppercase` | Associative Memory Gap Work Orders | Generated: 2026-04-13 Source: Deep audit of multimodal associative memory systems Status: READY FOR IMPLEMENTATION |
|
|
563
564
|
| `guide.work-orders-world-class-memory-compiler-readme-uppercase` | World-Class Memory Compiler Program | Status: active implementation program Owner: Omnius orchestration and memory packages Last updated: 2026-07-13 |
|
|
@@ -309,3 +309,5 @@ deterministically repaired P0 or P1 defect.
|
|
|
309
309
|
accessibility, and mocked inference end-to-end tests.
|
|
310
310
|
- [x] WO-18 pause, stop, and resume use one durable interruption lifecycle and
|
|
311
311
|
pass cancellation, restart, ownership, external-effect, and isolation tests.
|
|
312
|
+
- [x] WO-20 exit and restart preserve one exact typed task continuation. Generic
|
|
313
|
+
context restoration cannot mix or activate unrelated historical artifacts.
|
|
@@ -0,0 +1,88 @@
|
|
|
1
|
+
# WO-20: Exact session continuation across exit and restart
|
|
2
|
+
|
|
3
|
+
## Incident
|
|
4
|
+
|
|
5
|
+
On 2026-09-03, the `telegram_test` TUI displayed the latest pentest task during
|
|
6
|
+
startup, but the first restored model context combined a completed `breach.py`
|
|
7
|
+
handoff with an unrelated, older `page.tsx` todo tree. The user then entered
|
|
8
|
+
`continue`, and Omnius continued the stale tree instead of the task that was
|
|
9
|
+
active before `/quit`.
|
|
10
|
+
|
|
11
|
+
## Root causes
|
|
12
|
+
|
|
13
|
+
- `/quit`, `/exit`, readline close, and fallback exit abort an active runner.
|
|
14
|
+
The explicit quit paths also delete `.omnius/history/pending-task.json`.
|
|
15
|
+
- Startup selects handoff, completion ledger, todo state, context chronology,
|
|
16
|
+
and visual history independently. These projections need not identify the
|
|
17
|
+
same session or run.
|
|
18
|
+
- Generic restore mutates the process-wide task session, even though the
|
|
19
|
+
restored transcript is historical orientation only.
|
|
20
|
+
- The host interprets words such as `continue` with a regular expression and
|
|
21
|
+
uses that classification to reuse a restored task identity.
|
|
22
|
+
- A resumed task is submitted as a generated wrapper. The wrapper can replace
|
|
23
|
+
the original user goal in new completion, workboard, and handoff records.
|
|
24
|
+
- Pending-task consumption checks only phase and session. It does not prove the
|
|
25
|
+
recovered run, epoch, and owner generation.
|
|
26
|
+
- Updating an existing session-context entry changes its timestamp in place,
|
|
27
|
+
but does not move it into chronological order. Tail readers can therefore
|
|
28
|
+
report an older task as latest.
|
|
29
|
+
|
|
30
|
+
## Required invariants
|
|
31
|
+
|
|
32
|
+
- [x] An active task receives a typed, atomic continuation checkpoint before a
|
|
33
|
+
resumable exit.
|
|
34
|
+
- [x] `/quit`, `/exit`, readline close, and graceful process termination pause
|
|
35
|
+
and preserve the active run. Explicit `/stop`, Ctrl+C, and double-Esc remain
|
|
36
|
+
terminal and delete the pending checkpoint.
|
|
37
|
+
- [x] A checkpoint identifies the project, original goal, session, run, task
|
|
38
|
+
epoch, owner generation, lifecycle phase, exit reason, and capture time.
|
|
39
|
+
- [x] Manual startup automatically adopts a checkpoint explicitly marked for
|
|
40
|
+
restart, without requiring an updater environment variable.
|
|
41
|
+
- [x] Exact continuation context is scoped to the checkpoint session and run.
|
|
42
|
+
A global handoff, ledger, todo tree, or transcript cannot replace it.
|
|
43
|
+
- [x] Generic context restore is orientation only. It does not bind task/todo
|
|
44
|
+
identity or mutate `OMNIUS_SESSION_ID`.
|
|
45
|
+
- [x] Continuation authority comes from typed lifecycle state or an explicit
|
|
46
|
+
command. It never comes from semantic keyword or regular-expression
|
|
47
|
+
classification of user prose.
|
|
48
|
+
- [x] The resumed runner receives the exact original user goal. Progress and
|
|
49
|
+
historical orientation remain separate context.
|
|
50
|
+
- [x] A pending checkpoint is consumed only after the runner proves the same
|
|
51
|
+
session, run, epoch, and owner generation in the running phase.
|
|
52
|
+
- [x] Session-context entries remain ordered by their effective save time after
|
|
53
|
+
merge or replacement.
|
|
54
|
+
- [x] Corrupt, cross-project, incomplete, or identity-mismatched checkpoints
|
|
55
|
+
fail closed and remain available for diagnosis unless explicitly stopped.
|
|
56
|
+
|
|
57
|
+
## Deterministic verification
|
|
58
|
+
|
|
59
|
+
- [x] Pending checkpoint round-trip and schema validation.
|
|
60
|
+
- [x] Exact four-field adoption match and one-field-at-a-time mismatch table.
|
|
61
|
+
- [x] Quit wiring has no abort/discard path for an active resumable run.
|
|
62
|
+
- [x] Restart continuation remains exact in the presence of a newer handoff,
|
|
63
|
+
higher-scoring stale ledger, unrelated todos, and unrelated visual history.
|
|
64
|
+
- [x] Generic restore cannot bind a subsequent fresh task to historical todos.
|
|
65
|
+
- [x] A resumed run persists the original goal, not a synthetic continuation
|
|
66
|
+
wrapper.
|
|
67
|
+
- [x] Session-context merge reorders the updated entry chronologically.
|
|
68
|
+
- [x] Focused CLI typecheck/build and affected tests pass.
|
|
69
|
+
|
|
70
|
+
## Delivery evidence
|
|
71
|
+
|
|
72
|
+
Implemented in the CLI session directory, TUI lifecycle coordinator, command
|
|
73
|
+
surface, and runner continuation gate. Verification on 2026-09-03:
|
|
74
|
+
|
|
75
|
+
- Focused CLI interruption, restore, session-diary, and command suites: 52
|
|
76
|
+
passed.
|
|
77
|
+
- Focused orchestrator context and interruption suites: 67 passed.
|
|
78
|
+
- Complete orchestrator suite: 2,292 passed, 14 skipped.
|
|
79
|
+
- Complete CLI suite: 2,425 passed. Two unrelated tests timed out while the CLI
|
|
80
|
+
and orchestrator suites ran concurrently; both passed alone, 35 of 35.
|
|
81
|
+
- CLI and orchestrator typechecks passed.
|
|
82
|
+
- CLI and orchestrator builds passed.
|
|
83
|
+
- A two-process, no-inference harness wrote the checkpoint in one process and
|
|
84
|
+
recovered the exact `harness-session/harness-run/epoch-3` selection in a
|
|
85
|
+
second process.
|
|
86
|
+
|
|
87
|
+
No live inference or service restart was required for this host-side
|
|
88
|
+
state-machine repair.
|
package/npm-shrinkwrap.json
CHANGED
|
@@ -1,12 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "omnius",
|
|
3
|
-
"version": "1.0.
|
|
3
|
+
"version": "1.0.689",
|
|
4
4
|
"lockfileVersion": 3,
|
|
5
5
|
"requires": true,
|
|
6
6
|
"packages": {
|
|
7
7
|
"": {
|
|
8
8
|
"name": "omnius",
|
|
9
|
-
"version": "1.0.
|
|
9
|
+
"version": "1.0.689",
|
|
10
10
|
"bundleDependencies": [
|
|
11
11
|
"image-to-ascii"
|
|
12
12
|
],
|
package/package.json
CHANGED