omnius 1.0.571 → 1.0.572
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 +1727 -771
- package/npm-shrinkwrap.json +8 -8
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -567847,6 +567847,36 @@ function clip2(value2, max = 500) {
|
|
|
567847
567847
|
function listLines(items, empty2 = "- none observed") {
|
|
567848
567848
|
return items.length > 0 ? items.map((item) => `- ${item}`) : [empty2];
|
|
567849
567849
|
}
|
|
567850
|
+
function formatWorkspaceInventorySummary(inventory) {
|
|
567851
|
+
if (!inventory)
|
|
567852
|
+
return ["- no bounded workspace inventory was provided"];
|
|
567853
|
+
const files = (inventory.files ?? []).slice(0, 40).map((file) => `${file.path}${file.bytes !== void 0 ? ` (bytes=${file.bytes}` : ""}${file.mtimeMs !== void 0 ? `${file.bytes !== void 0 ? ", " : " ("}mtimeMs=${file.mtimeMs})` : file.bytes !== void 0 ? ")" : ""}`);
|
|
567854
|
+
const dirs = (inventory.dirs ?? []).slice(0, 40).map((dir) => `dir:${dir}`);
|
|
567855
|
+
const summary = [
|
|
567856
|
+
`workspace_root=${inventory.root}`,
|
|
567857
|
+
`files=${inventory.files.length}${inventory.truncated ? "+" : ""}`,
|
|
567858
|
+
`dirs=${(inventory.dirs ?? []).length}`,
|
|
567859
|
+
`requested_max=${inventory.maxFiles}x${inventory.maxDirs}`
|
|
567860
|
+
];
|
|
567861
|
+
if (!inventory.truncated)
|
|
567862
|
+
summary.push(`inventory_complete=${inventory.files.length > 0 || (inventory.dirs ?? []).length > 0 ? "yes" : "no"}`);
|
|
567863
|
+
const out = [
|
|
567864
|
+
`Generated at: ${inventory.generatedAtIso}`,
|
|
567865
|
+
summary.join("; ")
|
|
567866
|
+
];
|
|
567867
|
+
if (files.length > 0) {
|
|
567868
|
+
out.push("Representative files:");
|
|
567869
|
+
out.push(...files.map((item) => `- ${item}`));
|
|
567870
|
+
}
|
|
567871
|
+
if (dirs.length > 0) {
|
|
567872
|
+
out.push("Representative directories:");
|
|
567873
|
+
out.push(...dirs.map((item) => `- ${item}`));
|
|
567874
|
+
}
|
|
567875
|
+
if (inventory.truncated) {
|
|
567876
|
+
out.push("- inventory_truncated: run a fresh scan with higher limits to inspect additional paths");
|
|
567877
|
+
}
|
|
567878
|
+
return out;
|
|
567879
|
+
}
|
|
567850
567880
|
function formatEvidenceEntry(entry) {
|
|
567851
567881
|
const parts = [
|
|
567852
567882
|
entry.success === true ? "ok" : entry.success === false ? "failed" : "unknown",
|
|
@@ -567892,6 +567922,7 @@ ${String(input.answerText).trim()}` : ""
|
|
|
567892
567922
|
].filter(Boolean).join(" ");
|
|
567893
567923
|
return `${clip2(file.path, 220)}${meta ? ` (${meta})` : ""}`;
|
|
567894
567924
|
});
|
|
567925
|
+
const workspaceInventory = formatWorkspaceInventorySummary(input.workspaceInventory);
|
|
567895
567926
|
const scenarioSeed = deriveScenarioSeed(input);
|
|
567896
567927
|
const lines = [];
|
|
567897
567928
|
lines.push(`[COMPLETION META-DECOMPOSITION]`);
|
|
@@ -567903,11 +567934,14 @@ ${String(input.answerText).trim()}` : ""
|
|
|
567903
567934
|
lines.push(`Proposed completion claim text:`);
|
|
567904
567935
|
lines.push(proposedClaimText || "(no proposed completion text yet)");
|
|
567905
567936
|
lines.push(``);
|
|
567937
|
+
lines.push(`Open loops and remaining blockers:`);
|
|
567938
|
+
lines.push(...listLines(unresolvedSignals, "- no open loop / blocker signals currently reported"));
|
|
567939
|
+
lines.push(``);
|
|
567906
567940
|
lines.push(`Observed run evidence:`);
|
|
567907
567941
|
lines.push(...listLines(observedEvidence, "- no tool evidence recorded"));
|
|
567908
567942
|
lines.push(``);
|
|
567909
|
-
lines.push(`
|
|
567910
|
-
lines.push(...
|
|
567943
|
+
lines.push(`Workspace inventory (bounded to prevent scan drift):`);
|
|
567944
|
+
lines.push(...workspaceInventory);
|
|
567911
567945
|
lines.push(``);
|
|
567912
567946
|
lines.push(`Modified artifact digest:`);
|
|
567913
567947
|
lines.push(...listLines(modifiedFiles, "- no modified artifacts listed"));
|
|
@@ -567953,6 +567987,52 @@ var init_completionContract = __esm({
|
|
|
567953
567987
|
// packages/orchestrator/dist/completionLedger.js
|
|
567954
567988
|
import { mkdirSync as mkdirSync51, readFileSync as readFileSync66, writeFileSync as writeFileSync42 } from "node:fs";
|
|
567955
567989
|
import { dirname as dirname29 } from "node:path";
|
|
567990
|
+
function setClaimDiscoveryState(ledger, state) {
|
|
567991
|
+
return {
|
|
567992
|
+
...ledger,
|
|
567993
|
+
claimDiscovery: {
|
|
567994
|
+
...state,
|
|
567995
|
+
generatedAtIso: nowIso3(),
|
|
567996
|
+
resolvedEvidenceHandles: state.resolvedEvidenceHandles ?? []
|
|
567997
|
+
},
|
|
567998
|
+
updatedAtIso: nowIso3()
|
|
567999
|
+
};
|
|
568000
|
+
}
|
|
568001
|
+
function claimDiscoveryStateFromSurvey(input) {
|
|
568002
|
+
const normalizedInventory = input.boundedInventory;
|
|
568003
|
+
const paths = [...new Set((Array.isArray(input.candidatePaths) ? input.candidatePaths : []).map((value2) => normalizeEvidencePath(value2)).filter(Boolean).slice(0, 16))];
|
|
568004
|
+
const reasons = /* @__PURE__ */ Object.create(null);
|
|
568005
|
+
for (const [rawPath, rawReason] of Object.entries(input.pathReasons ?? {})) {
|
|
568006
|
+
const path16 = normalizeEvidencePath(rawPath);
|
|
568007
|
+
const reason = cleanText(rawReason, 220);
|
|
568008
|
+
if (path16)
|
|
568009
|
+
reasons[path16] = reason || "candidate selected from bounded workspace inventory";
|
|
568010
|
+
}
|
|
568011
|
+
const openDeltas = paths.map((path16) => ({
|
|
568012
|
+
path: path16,
|
|
568013
|
+
reason: reasons[path16] || "candidate selected from bounded workspace inventory"
|
|
568014
|
+
}));
|
|
568015
|
+
const unresolved = Array.isArray(input.unresolvedQuestions) ? input.unresolvedQuestions.map((item) => cleanText(item, 260)).filter(Boolean) : [];
|
|
568016
|
+
const blockers = Array.isArray(input.survivingBlockers) ? input.survivingBlockers.map((item) => cleanText(item, 220)).filter(Boolean) : [];
|
|
568017
|
+
const hasBlockers = blockers.length > 0;
|
|
568018
|
+
const hasQuestions = unresolved.length > 0;
|
|
568019
|
+
const resolvedStatus = paths.length === 0 ? hasBlockers || hasQuestions ? "blocked" : "skipped" : hasBlockers || hasQuestions ? "blocked" : "active";
|
|
568020
|
+
return {
|
|
568021
|
+
status: resolvedStatus,
|
|
568022
|
+
generatedAtIso: nowIso3(),
|
|
568023
|
+
request: cleanText(input.request, 600),
|
|
568024
|
+
context: cleanText(input.context, 480),
|
|
568025
|
+
boundedInventory: normalizedInventory,
|
|
568026
|
+
candidatePaths: paths,
|
|
568027
|
+
pathReasons: reasons,
|
|
568028
|
+
unresolvedQuestions: unresolved.slice(0, 10),
|
|
568029
|
+
openDeltas,
|
|
568030
|
+
survivingBlockers: blockers.slice(0, 8),
|
|
568031
|
+
evidenceHandles: [...new Set(paths.map((path16) => `workspace:${path16}`))],
|
|
568032
|
+
resolvedEvidenceHandles: [],
|
|
568033
|
+
requiresEvidence: typeof input.requiresEvidence === "boolean" ? input.requiresEvidence : true
|
|
568034
|
+
};
|
|
568035
|
+
}
|
|
567956
568036
|
function nowIso3(now2 = /* @__PURE__ */ new Date()) {
|
|
567957
568037
|
return now2 instanceof Date ? now2.toISOString() : new Date(now2).toISOString();
|
|
567958
568038
|
}
|
|
@@ -568002,6 +568082,180 @@ function formatEvidenceSummary(summary) {
|
|
|
568002
568082
|
function nextId2(prefix, count) {
|
|
568003
568083
|
return `${prefix}_${String(count + 1).padStart(4, "0")}`;
|
|
568004
568084
|
}
|
|
568085
|
+
function extractWorkspaceTokens(text2) {
|
|
568086
|
+
const raw = String(text2 ?? "").toLowerCase().replace(/["'`]/g, " ").replace(/[^\w./@-]+/g, " ");
|
|
568087
|
+
return raw.split(/\s+/).filter((value2) => value2.length >= 4);
|
|
568088
|
+
}
|
|
568089
|
+
function extractPathFragments(text2) {
|
|
568090
|
+
const out = [];
|
|
568091
|
+
const pathPattern = /(?:[\w.-]+\/[\w./-]+\.[A-Za-z0-9]+|[\w.-]+\.(?:ts|tsx|js|jsx|mjs|cjs|py|go|rs|cpp|c|h|hpp|java|kt|json|yml|yaml|toml|md|mdx|sh|bash|cxx|swift|rb|php)|[\w./-]+\.[A-Za-z0-9]+)/g;
|
|
568092
|
+
for (const hit of text2.matchAll(pathPattern)) {
|
|
568093
|
+
const value2 = String(hit[0] ?? "").trim();
|
|
568094
|
+
if (!value2)
|
|
568095
|
+
continue;
|
|
568096
|
+
const normalized = value2.replace(/^\.\/+/, "");
|
|
568097
|
+
if (normalized.length > 2)
|
|
568098
|
+
out.push(normalized);
|
|
568099
|
+
}
|
|
568100
|
+
return [...new Set(out)].slice(0, 12);
|
|
568101
|
+
}
|
|
568102
|
+
function tokenizeClaims(text2) {
|
|
568103
|
+
return String(text2 ?? "").split(/[.\n\r!?;]+/).map((item) => item.trim()).filter((item) => item.length > 6).filter((item) => item.length < 260).slice(0, 30);
|
|
568104
|
+
}
|
|
568105
|
+
function estimateClaimMateriality(text2) {
|
|
568106
|
+
const normalized = text2.toLowerCase();
|
|
568107
|
+
if (/\b(blocker|critical|security|production|release|deploy|migrate|migration|regression|customer|public)\b/.test(normalized)) {
|
|
568108
|
+
return "high";
|
|
568109
|
+
}
|
|
568110
|
+
if (/\b(implement|fix|refactor|resolve|wire|integrat|add|remove|change|update)\b/.test(normalized)) {
|
|
568111
|
+
return "medium";
|
|
568112
|
+
}
|
|
568113
|
+
return "low";
|
|
568114
|
+
}
|
|
568115
|
+
function classifyClaimAttainedState(text2) {
|
|
568116
|
+
const normalized = text2.toLowerCase();
|
|
568117
|
+
if (/\b(block|blocked|blocker|cannot verify|unverified|not verified|hold)\b/.test(normalized)) {
|
|
568118
|
+
return "blocked";
|
|
568119
|
+
}
|
|
568120
|
+
if (/\b(simulat|dry.?run|mock|unit test|paper|offline|software.?in.?loop)\b/.test(normalized)) {
|
|
568121
|
+
return "simulation_only";
|
|
568122
|
+
}
|
|
568123
|
+
if (/\b(hil|hardware.?in.?the.?loop|hardware.?test|on.?device|real.?hardware|physical)\b/.test(normalized)) {
|
|
568124
|
+
return "hardware_verified";
|
|
568125
|
+
}
|
|
568126
|
+
if (/\b(integrat|integrated|bridge|transport|serial|can|hardware|device|physical)\b/.test(normalized)) {
|
|
568127
|
+
return "hardware_integrated";
|
|
568128
|
+
}
|
|
568129
|
+
return "unproven";
|
|
568130
|
+
}
|
|
568131
|
+
function deriveClaimRisks(text2) {
|
|
568132
|
+
const normalized = text2.toLowerCase();
|
|
568133
|
+
if (/\b(start|running|daemon|process|service|alive|ready)\b/.test(normalized)) {
|
|
568134
|
+
return {
|
|
568135
|
+
riskCategory: "process_liveness",
|
|
568136
|
+
requiresIndependentEvidence: true,
|
|
568137
|
+
requiredCheck: "Independent runtime state/health check with process or endpoint probe."
|
|
568138
|
+
};
|
|
568139
|
+
}
|
|
568140
|
+
if (/\b(instal|pip|npm|pnpm|apt|brew|cargo|go install|pip install|docker pull)\b/.test(normalized)) {
|
|
568141
|
+
return {
|
|
568142
|
+
riskCategory: "installation",
|
|
568143
|
+
requiresIndependentEvidence: true,
|
|
568144
|
+
requiredCheck: "Independent command query/inspection proving the toolchain exists after the installation claim."
|
|
568145
|
+
};
|
|
568146
|
+
}
|
|
568147
|
+
if (/\b(fixed|repair|resolved|passed|test pass|fix|bug|regression)\b/.test(normalized)) {
|
|
568148
|
+
return {
|
|
568149
|
+
riskCategory: "fix_confirmation",
|
|
568150
|
+
requiresIndependentEvidence: true,
|
|
568151
|
+
requiredCheck: "Re-run the same failure path or equivalent check and capture the successful evidence."
|
|
568152
|
+
};
|
|
568153
|
+
}
|
|
568154
|
+
if (/\b(simulat|dry.?run|mock|fake|virtual)\b/.test(normalized)) {
|
|
568155
|
+
return {
|
|
568156
|
+
riskCategory: "reality",
|
|
568157
|
+
requiresIndependentEvidence: false,
|
|
568158
|
+
requiredCheck: "Label and preserve as simulation-only unless hardware-path evidence exists."
|
|
568159
|
+
};
|
|
568160
|
+
}
|
|
568161
|
+
return {
|
|
568162
|
+
riskCategory: "coverage",
|
|
568163
|
+
requiresIndependentEvidence: false,
|
|
568164
|
+
requiredCheck: "Collect evidence per claim from supported tool outputs and source observations."
|
|
568165
|
+
};
|
|
568166
|
+
}
|
|
568167
|
+
function claimEvidenceNeeds(text2) {
|
|
568168
|
+
const normalized = text2.toLowerCase();
|
|
568169
|
+
const needs = [];
|
|
568170
|
+
const kind = /\b(test|verify|validate|coverage|run|build|lint|check|execute)\b/.test(normalized) ? "tool_result" : /\b(create|write|modify|edit|delete|remove|add|updated|implemented|fix)\b/.test(normalized) ? "file_change" : "runtime_observation";
|
|
568171
|
+
needs.push({
|
|
568172
|
+
handle: `${kind}:in_scope`,
|
|
568173
|
+
evidenceKind: kind,
|
|
568174
|
+
rationale: `Evidence supporting the in-scope portion of: ${cleanText(text2, 120)}`
|
|
568175
|
+
});
|
|
568176
|
+
if (/\b(runtime|process|service|daemon|endpoint|server)\b/.test(normalized)) {
|
|
568177
|
+
needs.push({
|
|
568178
|
+
handle: "verification:post-change",
|
|
568179
|
+
evidenceKind: "runtime_observation",
|
|
568180
|
+
rationale: "Observed runtime confirmation after the claimed change."
|
|
568181
|
+
});
|
|
568182
|
+
}
|
|
568183
|
+
if (/\b(serial|hardware|device|controller|transport)\b/.test(normalized)) {
|
|
568184
|
+
needs.push({
|
|
568185
|
+
handle: "delivery:hardware-path",
|
|
568186
|
+
evidenceKind: "delivery",
|
|
568187
|
+
rationale: "Hardware-path or transport evidence that clarifies simulation/hardware status."
|
|
568188
|
+
});
|
|
568189
|
+
}
|
|
568190
|
+
return needs;
|
|
568191
|
+
}
|
|
568192
|
+
function findInventoryMatches(statement, workspaceInventory) {
|
|
568193
|
+
if (!workspaceInventory)
|
|
568194
|
+
return [];
|
|
568195
|
+
const tokens = extractWorkspaceTokens(statement);
|
|
568196
|
+
const candidatePaths = workspaceInventory.files.map((entry) => entry.path);
|
|
568197
|
+
const seen = /* @__PURE__ */ new Set();
|
|
568198
|
+
const matches = [];
|
|
568199
|
+
const literalPathHints = extractPathFragments(statement);
|
|
568200
|
+
for (const hint of literalPathHints) {
|
|
568201
|
+
const normalized = hint.toLowerCase();
|
|
568202
|
+
const exact = candidatePaths.find((path16) => path16.toLowerCase() === normalized);
|
|
568203
|
+
if (exact)
|
|
568204
|
+
seen.add(exact);
|
|
568205
|
+
}
|
|
568206
|
+
for (const path16 of candidatePaths) {
|
|
568207
|
+
if (matches.length >= 5 || seen.size >= 8)
|
|
568208
|
+
break;
|
|
568209
|
+
const lower = path16.toLowerCase();
|
|
568210
|
+
const tokenHits = tokens.filter((token) => lower.includes(token));
|
|
568211
|
+
if (tokenHits.length >= 2 || tokenHits.length >= 1 && literalPathHints.length === 0) {
|
|
568212
|
+
if (!seen.has(path16)) {
|
|
568213
|
+
seen.add(path16);
|
|
568214
|
+
}
|
|
568215
|
+
}
|
|
568216
|
+
}
|
|
568217
|
+
for (const path16 of seen)
|
|
568218
|
+
matches.push(path16);
|
|
568219
|
+
if (literalPathHints.length > 0 && matches.length === 0) {
|
|
568220
|
+
for (const path16 of candidatePaths) {
|
|
568221
|
+
for (const hint of literalPathHints) {
|
|
568222
|
+
if (path16.toLowerCase().includes(hint.toLowerCase())) {
|
|
568223
|
+
matches.push(path16);
|
|
568224
|
+
break;
|
|
568225
|
+
}
|
|
568226
|
+
}
|
|
568227
|
+
if (matches.length >= 6)
|
|
568228
|
+
break;
|
|
568229
|
+
}
|
|
568230
|
+
}
|
|
568231
|
+
return matches.slice(0, 6);
|
|
568232
|
+
}
|
|
568233
|
+
function claimDiscoveryControllerSignals(stage2) {
|
|
568234
|
+
if (!stage2)
|
|
568235
|
+
return [];
|
|
568236
|
+
const openDeltas = (stage2.openDeltas ?? []).slice(0, 10);
|
|
568237
|
+
const evidenceHandles = stage2.evidenceHandles ?? [];
|
|
568238
|
+
const resolvedEvidenceHandles = stage2.resolvedEvidenceHandles ?? [];
|
|
568239
|
+
const survivingBlockers = stage2.survivingBlockers ?? [];
|
|
568240
|
+
const unresolvedQuestions = stage2.unresolvedQuestions ?? [];
|
|
568241
|
+
const boundedInventory = stage2.boundedInventory;
|
|
568242
|
+
const boundedDirs = boundedInventory?.dirs ?? [];
|
|
568243
|
+
const resolvedCount = Math.min(evidenceHandles.length, new Set(resolvedEvidenceHandles).size);
|
|
568244
|
+
const unresolvedEvidenceCount = Math.max(evidenceHandles.length - resolvedCount, 0);
|
|
568245
|
+
return [
|
|
568246
|
+
"[COMPLETION CLAIM DISCOVERY]",
|
|
568247
|
+
`status=${stage2.status ?? "skipped"} generated_at=${stage2.generatedAtIso ?? ""}`,
|
|
568248
|
+
`requires_evidence=${stage2.requiresEvidence ? "true" : "false"}`,
|
|
568249
|
+
`bounded_inventory=${boundedInventory ? `${boundedInventory.root}|files=${boundedInventory.files.length}|dirs=${boundedDirs.length}|truncated=${Boolean(boundedInventory.truncated)}` : "none"}`,
|
|
568250
|
+
`candidate_paths=${(stage2.candidatePaths ?? []).join(",") || "none"}`,
|
|
568251
|
+
`open_deltas=${openDeltas.map((delta) => `${delta.path} :: ${delta.reason}`.replace(/\s+/g, " ")).join(" | ") || "none"}`,
|
|
568252
|
+
`open_delta_count=${openDeltas.length} unresolved_evidence_count=${unresolvedEvidenceCount}`,
|
|
568253
|
+
`surviving_blockers=${survivingBlockers.join(" | ") || "none"}`,
|
|
568254
|
+
`unresolved_questions=${unresolvedQuestions.join(" | ") || "none"}`,
|
|
568255
|
+
`evidence_handles=${evidenceHandles.join(",") || "none"}`,
|
|
568256
|
+
`resolved_evidence_handles=${resolvedEvidenceHandles.join(",") || "none"}`
|
|
568257
|
+
];
|
|
568258
|
+
}
|
|
568005
568259
|
function createCompletionLedger(input) {
|
|
568006
568260
|
const ts = nowIso3(input.now);
|
|
568007
568261
|
return {
|
|
@@ -568018,28 +568272,68 @@ function createCompletionLedger(input) {
|
|
|
568018
568272
|
};
|
|
568019
568273
|
}
|
|
568020
568274
|
function deriveClaimsFromProposedText(input) {
|
|
568021
|
-
|
|
568022
|
-
|
|
568275
|
+
return deriveStructuredClaims({
|
|
568276
|
+
taskText: input.taskText,
|
|
568277
|
+
proposedSummary: input.text,
|
|
568278
|
+
source: input.source,
|
|
568279
|
+
existing: input.existing,
|
|
568280
|
+
workspaceInventory: input.workspaceInventory,
|
|
568281
|
+
maxClaims: 12
|
|
568282
|
+
});
|
|
568283
|
+
}
|
|
568284
|
+
function deriveStructuredClaims(input) {
|
|
568285
|
+
const proposed = String(input.proposedSummary ?? "").trim();
|
|
568286
|
+
const task = String(input.taskText ?? "").trim();
|
|
568287
|
+
const baseText = [proposed, task].filter(Boolean).join("\n");
|
|
568288
|
+
const statements = tokenizeClaims(baseText);
|
|
568289
|
+
if (statements.length === 0)
|
|
568023
568290
|
return [];
|
|
568024
568291
|
const existingIds = new Set((input.existing ?? []).map((claim) => claim.id));
|
|
568025
|
-
const
|
|
568026
|
-
const
|
|
568027
|
-
|
|
568028
|
-
|
|
568029
|
-
|
|
568030
|
-
|
|
568031
|
-
|
|
568032
|
-
|
|
568033
|
-
|
|
568292
|
+
const maxClaims = Math.max(1, Math.min(32, input.maxClaims ?? 12));
|
|
568293
|
+
const seen = /* @__PURE__ */ new Set();
|
|
568294
|
+
const claims = [];
|
|
568295
|
+
for (const statementRaw of statements) {
|
|
568296
|
+
if (claims.length >= maxClaims)
|
|
568297
|
+
break;
|
|
568298
|
+
const text2 = cleanText(statementRaw, 220);
|
|
568299
|
+
if (!text2)
|
|
568300
|
+
continue;
|
|
568301
|
+
const base3 = normalizeCompletionKey(text2, "claim").slice(0, 64) || "claim";
|
|
568302
|
+
let id2 = base3;
|
|
568303
|
+
let suffix = 2;
|
|
568304
|
+
while (existingIds.has(id2) || seen.has(id2)) {
|
|
568305
|
+
id2 = `${base3}_${suffix++}`;
|
|
568306
|
+
}
|
|
568307
|
+
const risk = deriveClaimRisks(text2);
|
|
568308
|
+
const needs = claimEvidenceNeeds(text2);
|
|
568309
|
+
const evidenceHandles = [
|
|
568310
|
+
...needs.map((need) => need.handle),
|
|
568311
|
+
...findInventoryMatches(text2, input.workspaceInventory).map((path16) => `workspace:${path16}`)
|
|
568312
|
+
];
|
|
568313
|
+
const workspaceSignals = findInventoryMatches(text2, input.workspaceInventory);
|
|
568314
|
+
const sourceSignals = [
|
|
568315
|
+
input.taskText ? "task" : "proposed_text",
|
|
568316
|
+
...extractPathFragments(statementRaw).slice(0, 2)
|
|
568317
|
+
].filter(Boolean);
|
|
568318
|
+
claims.push({
|
|
568034
568319
|
id: id2,
|
|
568035
568320
|
text: text2,
|
|
568036
|
-
source: input.source,
|
|
568037
|
-
materiality:
|
|
568038
|
-
evidenceRequirement: "
|
|
568321
|
+
source: input.source ?? "derived",
|
|
568322
|
+
materiality: estimateClaimMateriality(statementRaw),
|
|
568323
|
+
evidenceRequirement: "Attach explicit evidenceIds that match the listed evidence handles and state.",
|
|
568324
|
+
attainedState: classifyClaimAttainedState(text2),
|
|
568325
|
+
riskCategory: risk.riskCategory,
|
|
568326
|
+
requiresIndependentEvidence: risk.requiresIndependentEvidence,
|
|
568327
|
+
requiredCheck: risk.requiredCheck,
|
|
568328
|
+
evidenceNeeds: needs,
|
|
568329
|
+
sourceSignals,
|
|
568330
|
+
workspaceSignals,
|
|
568039
568331
|
evidenceIds: [],
|
|
568040
568332
|
status: "unverified"
|
|
568041
|
-
}
|
|
568042
|
-
|
|
568333
|
+
});
|
|
568334
|
+
seen.add(id2);
|
|
568335
|
+
}
|
|
568336
|
+
return claims;
|
|
568043
568337
|
}
|
|
568044
568338
|
function recordCompletionEvidence(ledger, evidence) {
|
|
568045
568339
|
const targetPaths = cleanTargetPaths(evidence.targetPaths);
|
|
@@ -568138,14 +568432,42 @@ function buildCriticPacketFromLedger(ledger) {
|
|
|
568138
568432
|
lines.push(`Run: ${ledger.runId}`);
|
|
568139
568433
|
lines.push(`Goal: ${ledger.goal || "(not recorded)"}`);
|
|
568140
568434
|
lines.push(`Status: ${ledger.status}`);
|
|
568435
|
+
lines.push(`Claims discovered: ${ledger.proposedClaims.length}`);
|
|
568436
|
+
if (ledger.claimDiscovery) {
|
|
568437
|
+
lines.push("");
|
|
568438
|
+
lines.push("Claim Discovery:");
|
|
568439
|
+
lines.push(` status=${ledger.claimDiscovery.status}`);
|
|
568440
|
+
lines.push(` generated_at=${ledger.claimDiscovery.generatedAtIso}`);
|
|
568441
|
+
lines.push(` candidate_paths=${ledger.claimDiscovery.candidatePaths.join(",") || "none"}`);
|
|
568442
|
+
lines.push(` open_deltas=${ledger.claimDiscovery.openDeltas.map((delta) => `${delta.path} :: ${delta.reason}`).slice(0, 10).join(" | ") || "none"}`);
|
|
568443
|
+
lines.push(` surviving_blockers=${ledger.claimDiscovery.survivingBlockers.join(" | ") || "none"}`);
|
|
568444
|
+
lines.push(` unresolved_questions=${ledger.claimDiscovery.unresolvedQuestions.join(" | ") || "none"}`);
|
|
568445
|
+
lines.push(` evidence_handles=${ledger.claimDiscovery.evidenceHandles.join(",") || "none"}`);
|
|
568446
|
+
lines.push(` resolved_evidence_handles=${ledger.claimDiscovery.resolvedEvidenceHandles.join(",") || "none"}`);
|
|
568447
|
+
}
|
|
568141
568448
|
lines.push("");
|
|
568142
568449
|
lines.push("Claims:");
|
|
568143
568450
|
if (ledger.proposedClaims.length === 0)
|
|
568144
568451
|
lines.push("- none recorded");
|
|
568145
568452
|
for (const claim of ledger.proposedClaims) {
|
|
568146
|
-
|
|
568453
|
+
const handles = claim.evidenceNeeds.length === 0 ? "none" : claim.evidenceNeeds.map((need) => need.handle).join(", ");
|
|
568454
|
+
lines.push(`- [${claim.status}] ${claim.id} (${claim.attainedState}): ${claim.text}`);
|
|
568455
|
+
lines.push(` source: ${claim.source} materiality:${claim.materiality}`);
|
|
568147
568456
|
lines.push(` evidence: ${claim.evidenceIds.length > 0 ? claim.evidenceIds.join(", ") : "none"}`);
|
|
568148
|
-
lines.push(`
|
|
568457
|
+
lines.push(` evidence_handles: ${handles}`);
|
|
568458
|
+
if (claim.workspaceSignals.length > 0) {
|
|
568459
|
+
lines.push(` workspace_signals: ${claim.workspaceSignals.join(", ")}`);
|
|
568460
|
+
}
|
|
568461
|
+
if (claim.sourceSignals.length > 0) {
|
|
568462
|
+
lines.push(` source_signals: ${claim.sourceSignals.join(", ")}`);
|
|
568463
|
+
}
|
|
568464
|
+
lines.push(` requirement: ${claim.evidenceRequirement} ${claim.requiresIndependentEvidence ? "[independent evidence required]" : ""}`);
|
|
568465
|
+
if (claim.riskCategory && claim.riskCategory !== "unknown") {
|
|
568466
|
+
lines.push(` risk: ${claim.riskCategory}`);
|
|
568467
|
+
if (claim.requiredCheck) {
|
|
568468
|
+
lines.push(` required_check: ${claim.requiredCheck}`);
|
|
568469
|
+
}
|
|
568470
|
+
}
|
|
568149
568471
|
}
|
|
568150
568472
|
lines.push("");
|
|
568151
568473
|
lines.push("Evidence:");
|
|
@@ -568232,6 +568554,27 @@ function evidenceTargetPaths(entry) {
|
|
|
568232
568554
|
}
|
|
568233
568555
|
return cleanTargetPaths(paths);
|
|
568234
568556
|
}
|
|
568557
|
+
function claimDiscoveryResolvedHandles(ledger, state) {
|
|
568558
|
+
if (!state)
|
|
568559
|
+
return [];
|
|
568560
|
+
const inspected = /* @__PURE__ */ new Set();
|
|
568561
|
+
const candidatePaths = [...state.candidatePaths].map((value2) => normalizeEvidencePath(value2)).filter(Boolean).map((path16) => path16.replace(/^\/+/, ""));
|
|
568562
|
+
for (const entry of ledger.evidence) {
|
|
568563
|
+
if (entry.success !== true)
|
|
568564
|
+
continue;
|
|
568565
|
+
for (const rawPath of evidenceTargetPaths(entry)) {
|
|
568566
|
+
const path16 = normalizeEvidencePath(rawPath);
|
|
568567
|
+
if (!path16)
|
|
568568
|
+
continue;
|
|
568569
|
+
const normalized = path16.replace(/^\/+/, "");
|
|
568570
|
+
const matched = candidatePaths.find((candidate) => pathsEquivalent(candidate, normalized));
|
|
568571
|
+
if (matched) {
|
|
568572
|
+
inspected.add(`workspace:${matched}`);
|
|
568573
|
+
}
|
|
568574
|
+
}
|
|
568575
|
+
}
|
|
568576
|
+
return [...inspected];
|
|
568577
|
+
}
|
|
568235
568578
|
function pathsEquivalent(a2, b) {
|
|
568236
568579
|
const left = normalizeEvidencePath(a2);
|
|
568237
568580
|
const right = normalizeEvidencePath(b);
|
|
@@ -568803,18 +569146,41 @@ function clean3(value2, max) {
|
|
|
568803
569146
|
return String(value2 ?? "").replace(/\s+/g, " ").trim().slice(0, max);
|
|
568804
569147
|
}
|
|
568805
569148
|
function selectedEvidence(ledger) {
|
|
568806
|
-
if (!ledger)
|
|
568807
|
-
return {
|
|
569149
|
+
if (!ledger) {
|
|
569150
|
+
return {
|
|
569151
|
+
evidenceIds: [],
|
|
569152
|
+
commandReceipts: [],
|
|
569153
|
+
artifactHashes: []
|
|
569154
|
+
};
|
|
569155
|
+
}
|
|
568808
569156
|
const candidates = ledger.evidence.filter((entry) => entry.success === true && (entry.role === "verification" || entry.role === "mutation")).slice(-16);
|
|
568809
569157
|
const artifacts = /* @__PURE__ */ new Map();
|
|
569158
|
+
const commandReceipts = [];
|
|
568810
569159
|
for (const entry of candidates) {
|
|
568811
569160
|
for (const item of entry.receipt?.artifactHashes ?? []) {
|
|
568812
569161
|
if (item.path && item.sha256)
|
|
568813
569162
|
artifacts.set(item.path, item.sha256);
|
|
568814
569163
|
}
|
|
569164
|
+
if (entry.receipt) {
|
|
569165
|
+
const receipt = entry.receipt;
|
|
569166
|
+
commandReceipts.push({
|
|
569167
|
+
evidenceId: entry.id,
|
|
569168
|
+
toolName: entry.toolName ?? "unknown",
|
|
569169
|
+
role: entry.role ?? "unknown",
|
|
569170
|
+
command: receipt.command ?? "",
|
|
569171
|
+
canonicalCommand: receipt.canonicalCommand ?? "",
|
|
569172
|
+
cwd: receipt.cwd ?? "",
|
|
569173
|
+
exitCode: receipt.exitCode ?? null,
|
|
569174
|
+
timedOut: Boolean(receipt.timedOut),
|
|
569175
|
+
startedAtIso: receipt.startedAtIso ?? "",
|
|
569176
|
+
finishedAtIso: receipt.finishedAtIso ?? "",
|
|
569177
|
+
artifactHashes: entry.receipt.artifactHashes?.length ? entry.receipt.artifactHashes : []
|
|
569178
|
+
});
|
|
569179
|
+
}
|
|
568815
569180
|
}
|
|
568816
569181
|
return {
|
|
568817
569182
|
evidenceIds: candidates.map((entry) => entry.id),
|
|
569183
|
+
commandReceipts,
|
|
568818
569184
|
artifactHashes: [...artifacts.entries()].map(([path16, sha2567]) => ({
|
|
568819
569185
|
path: path16,
|
|
568820
569186
|
sha256: sha2567
|
|
@@ -568842,6 +569208,7 @@ function buildCompletionFinalizationRecord(input) {
|
|
|
568842
569208
|
summary: clean3(input.summary, 4e3),
|
|
568843
569209
|
committedAtIso,
|
|
568844
569210
|
evidenceIds: evidence.evidenceIds,
|
|
569211
|
+
commandReceipts: evidence.commandReceipts,
|
|
568845
569212
|
artifactHashes: evidence.artifactHashes,
|
|
568846
569213
|
projections: {
|
|
568847
569214
|
ledger: "pending",
|
|
@@ -577895,16 +578262,90 @@ var init_consolidation_runtime = __esm({
|
|
|
577895
578262
|
});
|
|
577896
578263
|
|
|
577897
578264
|
// packages/orchestrator/dist/completion-evidence-gate.js
|
|
578265
|
+
function normalizedEvidenceText(text2) {
|
|
578266
|
+
return String(text2 ?? "").toLowerCase();
|
|
578267
|
+
}
|
|
577898
578268
|
function classifyCompletionClaim(text2) {
|
|
577899
|
-
|
|
578269
|
+
const normalized = normalizedEvidenceText(text2);
|
|
578270
|
+
if (!normalized) {
|
|
578271
|
+
return {
|
|
578272
|
+
category: null,
|
|
578273
|
+
requiresIndependentEvidence: false,
|
|
578274
|
+
requiredCheck: ""
|
|
578275
|
+
};
|
|
578276
|
+
}
|
|
578277
|
+
const processLiveness = /\b(daemon|service|process|server|port|listener|runtime|pid|socket|endpoint)\b/.test(normalized) && /\b(start(ed|ing)?|run(ning)?|up|ready|alive|online|boot(ed|ing)?|initialized|listening)\b/.test(normalized);
|
|
578278
|
+
if (processLiveness) {
|
|
578279
|
+
return {
|
|
578280
|
+
category: "process_liveness",
|
|
578281
|
+
requiresIndependentEvidence: true,
|
|
578282
|
+
requiredCheck: "Independent runtime verification (process/pid/health/port check) after the claimed state change."
|
|
578283
|
+
};
|
|
578284
|
+
}
|
|
578285
|
+
if (/\b(instal|npm|pnpm|yarn|pip\s+install|go\s+install|cargo\s+install|apt\s+get|brew\s+install|dnf|yum|apk add|make\s+install)\b/.test(normalized)) {
|
|
578286
|
+
return {
|
|
578287
|
+
category: "installation",
|
|
578288
|
+
requiresIndependentEvidence: true,
|
|
578289
|
+
requiredCheck: "Independent command-level availability check for the installed artifact after change."
|
|
578290
|
+
};
|
|
578291
|
+
}
|
|
578292
|
+
const fixHint = /(fix|fixed|resolved|repair|patched|correct|address|addressed)\b/.test(normalized);
|
|
578293
|
+
const fixTarget = /(bug|regression|failure|error|issue|test|build|lint|crash|exception|pass|coverage)\b/.test(normalized);
|
|
578294
|
+
if (fixHint && fixTarget) {
|
|
578295
|
+
return {
|
|
578296
|
+
category: "fix_confirmation",
|
|
578297
|
+
requiresIndependentEvidence: true,
|
|
578298
|
+
requiredCheck: "Rerun the original failing command path and capture a passing result as evidence."
|
|
578299
|
+
};
|
|
578300
|
+
}
|
|
578301
|
+
if (/(simulat|dry.?run|mock|mocked|virtual|paper|emulat)\b/.test(normalized)) {
|
|
578302
|
+
return {
|
|
578303
|
+
category: "reality",
|
|
578304
|
+
requiresIndependentEvidence: false,
|
|
578305
|
+
requiredCheck: "Mark as simulation-only unless paired with a grounded hardware/live execution claim."
|
|
578306
|
+
};
|
|
578307
|
+
}
|
|
577900
578308
|
return {
|
|
577901
578309
|
category: null,
|
|
577902
578310
|
requiresIndependentEvidence: false,
|
|
577903
578311
|
requiredCheck: ""
|
|
577904
578312
|
};
|
|
577905
578313
|
}
|
|
577906
|
-
function detectExitCodeMisread(
|
|
577907
|
-
|
|
578314
|
+
function detectExitCodeMisread(input) {
|
|
578315
|
+
const source = typeof input === "string" ? {
|
|
578316
|
+
statement: input,
|
|
578317
|
+
command: "",
|
|
578318
|
+
output: "",
|
|
578319
|
+
exitCode: null,
|
|
578320
|
+
canonicalCommand: ""
|
|
578321
|
+
} : {
|
|
578322
|
+
statement: input.statement ?? "",
|
|
578323
|
+
command: input.command ?? input.canonicalCommand ?? "",
|
|
578324
|
+
output: input.output ?? "",
|
|
578325
|
+
exitCode: typeof input.exitCode === "number" && Number.isFinite(input.exitCode) ? input.exitCode : null,
|
|
578326
|
+
canonicalCommand: ""
|
|
578327
|
+
};
|
|
578328
|
+
const statement = normalizedEvidenceText(source.statement);
|
|
578329
|
+
const command = normalizedEvidenceText(source.command);
|
|
578330
|
+
const output = normalizedEvidenceText(source.output);
|
|
578331
|
+
const exitCode = source.exitCode;
|
|
578332
|
+
if (exitCode !== null && exitCode !== 0 && /\b(success|pass(?:ed|es)?|succeed(?:ed|s)?|ok|completed|done|finished|verified)\b/.test(statement)) {
|
|
578333
|
+
return true;
|
|
578334
|
+
}
|
|
578335
|
+
if (/\|\|\s*(true|:|exit\s+0)/.test(command))
|
|
578336
|
+
return true;
|
|
578337
|
+
if (/\bset\s*\+e\b/.test(command))
|
|
578338
|
+
return true;
|
|
578339
|
+
if (/;\s*\(\s*/.test(command))
|
|
578340
|
+
return true;
|
|
578341
|
+
if (command.includes("|") && !/\bset\s+-o\s+pipefail\b/.test(statement + " " + command)) {
|
|
578342
|
+
return true;
|
|
578343
|
+
}
|
|
578344
|
+
if (/\b\S+\s&\s*$/.test(command.trim()))
|
|
578345
|
+
return true;
|
|
578346
|
+
if (/\bexit(ed|ion)?\s+code\s*[1-9]\d*/.test(statement + " " + output)) {
|
|
578347
|
+
return true;
|
|
578348
|
+
}
|
|
577908
578349
|
return false;
|
|
577909
578350
|
}
|
|
577910
578351
|
function auditCompletionClaims(claims) {
|
|
@@ -581059,8 +581500,8 @@ var init_evidenceLedger = __esm({
|
|
|
581059
581500
|
}
|
|
581060
581501
|
/**
|
|
581061
581502
|
* Return a bounded, read-only projection for components that need to make a
|
|
581062
|
-
* routing decision from observed workspace state (for example
|
|
581063
|
-
*
|
|
581503
|
+
* routing decision from observed workspace state (for example claim-discovery
|
|
581504
|
+
* grounding). Callers cannot mutate ledger entries through this
|
|
581064
581505
|
* result, preserving the ledger as the single freshness authority.
|
|
581065
581506
|
*/
|
|
581066
581507
|
snapshot(maxEntries = 24) {
|
|
@@ -586977,7 +587418,7 @@ var init_longhaul_integration = __esm({
|
|
|
586977
587418
|
}
|
|
586978
587419
|
/**
|
|
586979
587420
|
* WO-6 (spec §2.5): seed the locked contract from the planner's
|
|
586980
|
-
* `LockedContract` at PLAN time. The
|
|
587421
|
+
* `LockedContract` at PLAN time. The claim-discovery planner path calls this after the
|
|
586981
587422
|
* planner emits its artefact, so the breaker's "regenerate from the locked
|
|
586982
587423
|
* contract" guidance has a real target from the first boundary unit — without
|
|
586983
587424
|
* waiting for coherent code to accumulate one. Idempotent + fault-tolerant.
|
|
@@ -589248,515 +589689,6 @@ var init_git_progress = __esm({
|
|
|
589248
589689
|
}
|
|
589249
589690
|
});
|
|
589250
589691
|
|
|
589251
|
-
// packages/orchestrator/dist/featurePlanner.js
|
|
589252
|
-
import fs7 from "node:fs";
|
|
589253
|
-
import path9 from "node:path";
|
|
589254
|
-
function classifyKind(survey) {
|
|
589255
|
-
const files = survey.files ?? [];
|
|
589256
|
-
const newSym = (survey.newSymbols ?? []).length;
|
|
589257
|
-
const req3 = survey.request.toLowerCase();
|
|
589258
|
-
if (/\b(investigat|why does|how does|trace|understand|root cause|diagnos|explain)\b/.test(req3) && newSym === 0 && files.length <= 2) {
|
|
589259
|
-
return "investigation";
|
|
589260
|
-
}
|
|
589261
|
-
if (/\b(bug|fix|broken|regression|crash|incorrect|fails?|misbehav)/.test(req3) && newSym === 0) {
|
|
589262
|
-
return "bugfix";
|
|
589263
|
-
}
|
|
589264
|
-
if (/\b(refactor|restructure|rename|clean up|simplif|migrate|consolidate)\b/.test(req3) && newSym === 0) {
|
|
589265
|
-
return "refactor";
|
|
589266
|
-
}
|
|
589267
|
-
if (/\b(wir|connect|integrate|hook up|plumb|bridge|glue)\b/.test(req3) && files.length >= 2) {
|
|
589268
|
-
return "wiring";
|
|
589269
|
-
}
|
|
589270
|
-
if (newSym > 0 || /\b(new|create|add|implement|build|introduce|scaffold)\b/.test(req3)) {
|
|
589271
|
-
return "new-module";
|
|
589272
|
-
}
|
|
589273
|
-
return "new-module";
|
|
589274
|
-
}
|
|
589275
|
-
function guessKind(name10) {
|
|
589276
|
-
if (/^(I[A-Z]|.*Interface|.*Contract|.*Spec|.*Event|.*Meta|.*Config|.*State)$/.test(name10)) {
|
|
589277
|
-
return "interface";
|
|
589278
|
-
}
|
|
589279
|
-
if (/^(T|Type|.*Type)$/.test(name10))
|
|
589280
|
-
return "type";
|
|
589281
|
-
if (/^(E|Enum|.*Kind|.*Status|.*Mode)$/.test(name10))
|
|
589282
|
-
return "enum";
|
|
589283
|
-
if (/^[A-Z]/.test(name10))
|
|
589284
|
-
return "class";
|
|
589285
|
-
return "function";
|
|
589286
|
-
}
|
|
589287
|
-
function buildLockedContract(kind, survey) {
|
|
589288
|
-
const symbols = [];
|
|
589289
|
-
if (kind === "refactor") {
|
|
589290
|
-
for (const name10 of survey.existingSymbols ?? []) {
|
|
589291
|
-
symbols.push({ name: name10, kind: guessKind(name10), fields: [] });
|
|
589292
|
-
}
|
|
589293
|
-
} else if (kind === "new-module") {
|
|
589294
|
-
for (const name10 of survey.newSymbols ?? []) {
|
|
589295
|
-
symbols.push({ name: name10, kind: guessKind(name10), fields: [] });
|
|
589296
|
-
}
|
|
589297
|
-
}
|
|
589298
|
-
return { symbols };
|
|
589299
|
-
}
|
|
589300
|
-
function decomposeFeature(survey, kind) {
|
|
589301
|
-
const units = [];
|
|
589302
|
-
const evidenceRefs = featureEvidenceRefs(survey);
|
|
589303
|
-
const unresolvedQuestion = survey.unresolvedQuestions?.[0] ?? (evidenceRefs.length === 0 ? "Which current files, symbols, and tests govern this unit? Inspect them before proposing a mutation." : void 0);
|
|
589304
|
-
const returnContract = "Return the direct result with cited observations, relevant/changed paths, verification or blocker, and the next parent decision.";
|
|
589305
|
-
const withGrounding = (unit) => ({
|
|
589306
|
-
...unit,
|
|
589307
|
-
evidenceRefs,
|
|
589308
|
-
...unresolvedQuestion ? { unresolvedQuestion } : {},
|
|
589309
|
-
returnContract
|
|
589310
|
-
});
|
|
589311
|
-
if (kind === "new-module") {
|
|
589312
|
-
const syms = survey.newSymbols ?? [];
|
|
589313
|
-
if (syms.length === 0) {
|
|
589314
|
-
units.push(withGrounding({
|
|
589315
|
-
label: "Establish the module boundary and implement the evidenced unit",
|
|
589316
|
-
size: "large",
|
|
589317
|
-
detail: "Do not scaffold from the request alone. First identify the owning entry point, adjacent contract, and test surface from current evidence."
|
|
589318
|
-
}));
|
|
589319
|
-
} else {
|
|
589320
|
-
for (const name10 of syms) {
|
|
589321
|
-
units.push({
|
|
589322
|
-
...withGrounding({
|
|
589323
|
-
label: `Implement ${name10} within its evidenced owner`,
|
|
589324
|
-
size: "small",
|
|
589325
|
-
detail: "Confirm the symbol's owning module and contract before editing; do not infer a file path from the feature label."
|
|
589326
|
-
}),
|
|
589327
|
-
expectedSymbols: [name10]
|
|
589328
|
-
});
|
|
589329
|
-
}
|
|
589330
|
-
}
|
|
589331
|
-
} else if (kind === "refactor") {
|
|
589332
|
-
units.push(withGrounding({
|
|
589333
|
-
label: "Refactor only the evidenced public surface",
|
|
589334
|
-
size: survey.files.length > 1 ? "large" : "small"
|
|
589335
|
-
}));
|
|
589336
|
-
} else if (kind === "bugfix") {
|
|
589337
|
-
units.push(withGrounding({
|
|
589338
|
-
label: "Reproduce the evidenced failure, make the smallest justified fix, and verify it",
|
|
589339
|
-
size: "small"
|
|
589340
|
-
}));
|
|
589341
|
-
} else if (kind === "wiring") {
|
|
589342
|
-
units.push(withGrounding({
|
|
589343
|
-
label: "Connect the evidenced module boundaries",
|
|
589344
|
-
size: survey.files.length > 2 ? "large" : "small"
|
|
589345
|
-
}));
|
|
589346
|
-
} else {
|
|
589347
|
-
units.push(withGrounding({
|
|
589348
|
-
label: "Investigate the evidence gap and report the next justified action",
|
|
589349
|
-
size: "small"
|
|
589350
|
-
}));
|
|
589351
|
-
}
|
|
589352
|
-
return units;
|
|
589353
|
-
}
|
|
589354
|
-
function featureEvidenceRefs(survey) {
|
|
589355
|
-
const declared = (survey.evidence ?? []).map((item) => item.ref.trim()).filter(Boolean).slice(0, 6);
|
|
589356
|
-
if (declared.length > 0)
|
|
589357
|
-
return declared;
|
|
589358
|
-
return survey.files.map((file) => `survey:file:${file.path}`).filter(Boolean).slice(0, 6);
|
|
589359
|
-
}
|
|
589360
|
-
function buildFeatureUnitRequest(input) {
|
|
589361
|
-
const evidence = (input.survey.evidence ?? []).filter((item) => !input.unit.evidenceRefs?.length || input.unit.evidenceRefs.includes(item.ref)).slice(0, 6);
|
|
589362
|
-
const fallbackEvidence = evidence.length > 0 ? evidence : input.survey.files.slice(0, 6).map((file) => ({
|
|
589363
|
-
ref: `survey:file:${file.path}`,
|
|
589364
|
-
detail: `${file.path}${file.role ? ` — ${file.role}` : ""}`,
|
|
589365
|
-
freshness: "unknown"
|
|
589366
|
-
}));
|
|
589367
|
-
const lines = [
|
|
589368
|
-
"[FEATURE UNIT EVIDENCE BRIEF]",
|
|
589369
|
-
`Parent request: ${input.parentRequest.slice(0, 900)}`,
|
|
589370
|
-
`Requested unit: ${input.unit.label}`,
|
|
589371
|
-
`Why now: this unit was selected from the current feature survey, not from a task label alone.`,
|
|
589372
|
-
"Evidence:",
|
|
589373
|
-
...fallbackEvidence.length > 0 ? fallbackEvidence.map((item) => `- [${item.freshness ?? "unknown"}] ${item.ref}: ${item.detail.slice(0, 360)}`) : ["- No current code observation is available; discovery is required before mutation."],
|
|
589374
|
-
input.unit.unresolvedQuestion ? `Open question: ${input.unit.unresolvedQuestion}` : null,
|
|
589375
|
-
"Scope: stay within this unit and directly implicated code; do not broaden the feature without returning to the parent.",
|
|
589376
|
-
`Return contract: ${input.unit.returnContract ?? "Return evidence, verification or blocker, and the next parent decision."}`,
|
|
589377
|
-
"",
|
|
589378
|
-
"Work protocol: inspect the cited files/contracts first. Only mutate after a fresh observation identifies the exact target; if the evidence does not support a target, report the gap instead of fabricating one."
|
|
589379
|
-
];
|
|
589380
|
-
return lines.filter((line) => Boolean(line)).join("\n");
|
|
589381
|
-
}
|
|
589382
|
-
function renderSpecMarkdown(input) {
|
|
589383
|
-
const { kind, survey, lockedContract, completionContract, decomposition, prose } = input;
|
|
589384
|
-
const lines = [];
|
|
589385
|
-
lines.push(`# Feature Plan — ${kind}`);
|
|
589386
|
-
lines.push("");
|
|
589387
|
-
lines.push(`**Request:** ${survey.request}`);
|
|
589388
|
-
lines.push("");
|
|
589389
|
-
lines.push(`**Node kind:** \`${kind}\` (selected by CLASSIFY over the survey signals)`);
|
|
589390
|
-
lines.push("");
|
|
589391
|
-
if (prose) {
|
|
589392
|
-
lines.push(`## 1. Intent`);
|
|
589393
|
-
lines.push("");
|
|
589394
|
-
lines.push(prose.trim());
|
|
589395
|
-
lines.push("");
|
|
589396
|
-
}
|
|
589397
|
-
lines.push(`## 2. Survey (codebase as-is)`);
|
|
589398
|
-
lines.push("");
|
|
589399
|
-
if (survey.files.length > 0) {
|
|
589400
|
-
for (const f2 of survey.files) {
|
|
589401
|
-
const refs = f2.lineRefs?.length ? `:${f2.lineRefs.join(",")}` : "";
|
|
589402
|
-
lines.push(`- \`${f2.path}${refs}\`${f2.role ? ` — ${f2.role}` : ""}`);
|
|
589403
|
-
}
|
|
589404
|
-
} else {
|
|
589405
|
-
lines.push("- (no files enumerated in survey)");
|
|
589406
|
-
}
|
|
589407
|
-
if (survey.evidence?.length) {
|
|
589408
|
-
for (const item of survey.evidence.slice(0, 8)) {
|
|
589409
|
-
lines.push(`- evidence [${item.freshness ?? "unknown"}] ${item.ref}: ${item.detail}`);
|
|
589410
|
-
}
|
|
589411
|
-
}
|
|
589412
|
-
if (survey.unresolvedQuestions?.length) {
|
|
589413
|
-
lines.push(`- unresolved: ${survey.unresolvedQuestions.join("; ")}`);
|
|
589414
|
-
}
|
|
589415
|
-
lines.push(`- new symbols: ${(survey.newSymbols ?? []).join(", ") || "none"}`);
|
|
589416
|
-
lines.push(`- public surface changes: ${survey.publicSurfaceChanges ? "yes" : "no"}`);
|
|
589417
|
-
lines.push(`- tests exist: ${survey.testsExist ? "yes" : "no"}`);
|
|
589418
|
-
lines.push("");
|
|
589419
|
-
lines.push(`## 3. Locked contract (executable gate)`);
|
|
589420
|
-
lines.push("");
|
|
589421
|
-
if (lockedContract.symbols.length === 0) {
|
|
589422
|
-
lines.push("- (no locked symbols for this kind — disciplined but permissive)");
|
|
589423
|
-
} else {
|
|
589424
|
-
for (const s2 of lockedContract.symbols) {
|
|
589425
|
-
lines.push(`- \`${s2.kind} ${s2.name}\``);
|
|
589426
|
-
}
|
|
589427
|
-
}
|
|
589428
|
-
lines.push("");
|
|
589429
|
-
lines.push(`## 4. Definition of done (CompletionContract)`);
|
|
589430
|
-
lines.push("");
|
|
589431
|
-
lines.push(`- goal: ${completionContract.goalSummary || "(none)"}`);
|
|
589432
|
-
for (const p2 of completionContract.phases ?? []) {
|
|
589433
|
-
lines.push(`- phase: ${p2.label}`);
|
|
589434
|
-
}
|
|
589435
|
-
lines.push("");
|
|
589436
|
-
lines.push(`## 5. Decomposition (SPLIT seed)`);
|
|
589437
|
-
lines.push("");
|
|
589438
|
-
for (const u of decomposition) {
|
|
589439
|
-
lines.push(`- [${u.size}] ${u.label}${u.expectedSymbols?.length ? ` (symbols: ${u.expectedSymbols.join(", ")})` : ""}${u.evidenceRefs?.length ? ` [evidence: ${u.evidenceRefs.join(", ")}]` : ""}`);
|
|
589440
|
-
}
|
|
589441
|
-
lines.push("");
|
|
589442
|
-
lines.push(`## 6. Verification bar`);
|
|
589443
|
-
lines.push("");
|
|
589444
|
-
lines.push("- planner emits real artefacts (this file + locked contract + completion contract)");
|
|
589445
|
-
lines.push("- approval gate blocks before any source edit");
|
|
589446
|
-
lines.push("- WO-6 executor gate activates on locked symbols");
|
|
589447
|
-
lines.push("- recursion + eviction keep context bounded");
|
|
589448
|
-
lines.push("- scope token re-prompts on out-of-scope work");
|
|
589449
|
-
lines.push("");
|
|
589450
|
-
lines.push(`## 7. Handoff notes`);
|
|
589451
|
-
lines.push("");
|
|
589452
|
-
lines.push("- Compose, do not rebuild: this plan reuses spec-gate + completionContract primitives.");
|
|
589453
|
-
lines.push("- Fail-closed: if planning errors, the run falls back to the general agentic loop.");
|
|
589454
|
-
lines.push("");
|
|
589455
|
-
return lines.join("\n");
|
|
589456
|
-
}
|
|
589457
|
-
async function planFeature(survey, options2 = {}) {
|
|
589458
|
-
const kind = classifyKind(survey);
|
|
589459
|
-
const lockedContract = buildLockedContract(kind, survey);
|
|
589460
|
-
const completionContract = inferCompletionContractFromTexts([survey.request, ...survey.rawTexts ?? [], ...survey.signals ?? []], survey.request);
|
|
589461
|
-
const decomposition = decomposeFeature(survey, kind);
|
|
589462
|
-
let prose = "";
|
|
589463
|
-
try {
|
|
589464
|
-
if (options2.proseGenerator) {
|
|
589465
|
-
prose = await options2.proseGenerator({ request: survey.request, kind, survey });
|
|
589466
|
-
}
|
|
589467
|
-
} catch {
|
|
589468
|
-
prose = "";
|
|
589469
|
-
}
|
|
589470
|
-
const specMarkdown = renderSpecMarkdown({
|
|
589471
|
-
kind,
|
|
589472
|
-
survey,
|
|
589473
|
-
lockedContract,
|
|
589474
|
-
completionContract,
|
|
589475
|
-
decomposition,
|
|
589476
|
-
prose
|
|
589477
|
-
});
|
|
589478
|
-
return { kind, specMarkdown, lockedContract, completionContract, decomposition };
|
|
589479
|
-
}
|
|
589480
|
-
function persistPlannerArtefacts(rootId, artefact, stateDir) {
|
|
589481
|
-
try {
|
|
589482
|
-
const dir = path9.join(stateDir, "feature-tree", rootId);
|
|
589483
|
-
fs7.mkdirSync(dir, { recursive: true });
|
|
589484
|
-
fs7.writeFileSync(path9.join(dir, "spec.md"), artefact.specMarkdown, "utf8");
|
|
589485
|
-
fs7.writeFileSync(path9.join(dir, "locked-contract.json"), JSON.stringify(artefact.lockedContract, null, 2), "utf8");
|
|
589486
|
-
fs7.writeFileSync(path9.join(dir, "completion-contract.json"), JSON.stringify(artefact.completionContract, null, 2), "utf8");
|
|
589487
|
-
} catch {
|
|
589488
|
-
}
|
|
589489
|
-
}
|
|
589490
|
-
var init_featurePlanner = __esm({
|
|
589491
|
-
"packages/orchestrator/dist/featurePlanner.js"() {
|
|
589492
|
-
"use strict";
|
|
589493
|
-
init_completionContract();
|
|
589494
|
-
}
|
|
589495
|
-
});
|
|
589496
|
-
|
|
589497
|
-
// packages/orchestrator/dist/featureApprovalGate.js
|
|
589498
|
-
function mintScopeToken(input) {
|
|
589499
|
-
return {
|
|
589500
|
-
rootId: input.rootId,
|
|
589501
|
-
files: [...input.files ?? []],
|
|
589502
|
-
symbols: input.lockedContract.symbols.map((s2) => s2.name),
|
|
589503
|
-
nodeKinds: input.nodeKinds ?? ["new-module", "refactor", "bugfix", "wiring", "investigation"],
|
|
589504
|
-
depthCap: input.depthCap
|
|
589505
|
-
};
|
|
589506
|
-
}
|
|
589507
|
-
function isWithinScope(input) {
|
|
589508
|
-
const { token } = input;
|
|
589509
|
-
if (typeof input.depth === "number" && input.depth > token.depthCap) {
|
|
589510
|
-
return false;
|
|
589511
|
-
}
|
|
589512
|
-
if (input.nodeKind && !token.nodeKinds.includes(input.nodeKind)) {
|
|
589513
|
-
return false;
|
|
589514
|
-
}
|
|
589515
|
-
if (input.newSymbol && !token.symbols.includes(input.newSymbol)) {
|
|
589516
|
-
return false;
|
|
589517
|
-
}
|
|
589518
|
-
if (input.file) {
|
|
589519
|
-
const file = input.file;
|
|
589520
|
-
const allowed = token.files.some((f2) => {
|
|
589521
|
-
if (f2 === file)
|
|
589522
|
-
return true;
|
|
589523
|
-
if (f2.endsWith("/") && file.startsWith(f2))
|
|
589524
|
-
return true;
|
|
589525
|
-
if (f2.includes("*") && globMatch(f2, file))
|
|
589526
|
-
return true;
|
|
589527
|
-
return false;
|
|
589528
|
-
});
|
|
589529
|
-
if (!allowed)
|
|
589530
|
-
return false;
|
|
589531
|
-
}
|
|
589532
|
-
return true;
|
|
589533
|
-
}
|
|
589534
|
-
function globMatch(pattern, value2) {
|
|
589535
|
-
const re = new RegExp("^" + pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$");
|
|
589536
|
-
return re.test(value2);
|
|
589537
|
-
}
|
|
589538
|
-
async function requestApproval(req3, ask2, options2 = {}) {
|
|
589539
|
-
let decision2;
|
|
589540
|
-
try {
|
|
589541
|
-
const raw = await ask2(req3);
|
|
589542
|
-
decision2 = raw === "approve" || raw === "edit" || raw === "reject" ? raw : "reject";
|
|
589543
|
-
} catch {
|
|
589544
|
-
decision2 = "reject";
|
|
589545
|
-
}
|
|
589546
|
-
if (decision2 === "approve") {
|
|
589547
|
-
const token = mintScopeToken({
|
|
589548
|
-
rootId: req3.rootId,
|
|
589549
|
-
lockedContract: req3.lockedContract,
|
|
589550
|
-
decomposition: req3.decomposition,
|
|
589551
|
-
depthCap: req3.depthCap,
|
|
589552
|
-
files: options2.files,
|
|
589553
|
-
nodeKinds: options2.nodeKinds
|
|
589554
|
-
});
|
|
589555
|
-
return { decision: decision2, token };
|
|
589556
|
-
}
|
|
589557
|
-
return { decision: decision2 };
|
|
589558
|
-
}
|
|
589559
|
-
var init_featureApprovalGate = __esm({
|
|
589560
|
-
"packages/orchestrator/dist/featureApprovalGate.js"() {
|
|
589561
|
-
"use strict";
|
|
589562
|
-
}
|
|
589563
|
-
});
|
|
589564
|
-
|
|
589565
|
-
// packages/orchestrator/dist/featureNode.js
|
|
589566
|
-
import fs8 from "node:fs";
|
|
589567
|
-
import path10 from "node:path";
|
|
589568
|
-
function treePath(stateDir, rootId) {
|
|
589569
|
-
return path10.join(stateDir, "feature-tree", `${rootId}.json`);
|
|
589570
|
-
}
|
|
589571
|
-
function saveFeatureTree(stateDir, rootId, nodes) {
|
|
589572
|
-
try {
|
|
589573
|
-
const file = treePath(stateDir, rootId);
|
|
589574
|
-
fs8.mkdirSync(path10.dirname(file), { recursive: true });
|
|
589575
|
-
fs8.writeFileSync(file, JSON.stringify(nodes, null, 2), "utf8");
|
|
589576
|
-
} catch {
|
|
589577
|
-
}
|
|
589578
|
-
}
|
|
589579
|
-
function loadFeatureTree(stateDir, rootId) {
|
|
589580
|
-
try {
|
|
589581
|
-
const file = treePath(stateDir, rootId);
|
|
589582
|
-
if (!fs8.existsSync(file))
|
|
589583
|
-
return null;
|
|
589584
|
-
const raw = JSON.parse(fs8.readFileSync(file, "utf8"));
|
|
589585
|
-
return raw && typeof raw === "object" ? raw : null;
|
|
589586
|
-
} catch {
|
|
589587
|
-
return null;
|
|
589588
|
-
}
|
|
589589
|
-
}
|
|
589590
|
-
function newNodeId(depth, seed) {
|
|
589591
|
-
const h = String(Math.abs(hashString2(seed)) % 1e9).padStart(9, "0");
|
|
589592
|
-
return `fn-d${depth}-${h}`;
|
|
589593
|
-
}
|
|
589594
|
-
function hashString2(s2) {
|
|
589595
|
-
let h = 0;
|
|
589596
|
-
for (let i2 = 0; i2 < s2.length; i2++)
|
|
589597
|
-
h = h * 31 + s2.charCodeAt(i2) | 0;
|
|
589598
|
-
return h;
|
|
589599
|
-
}
|
|
589600
|
-
async function evictNode(node, ctx3, transcript) {
|
|
589601
|
-
try {
|
|
589602
|
-
await runTodoChunker({
|
|
589603
|
-
inputs: {
|
|
589604
|
-
todoId: node.id,
|
|
589605
|
-
todoContent: node.request,
|
|
589606
|
-
turnRange: [0, 0],
|
|
589607
|
-
transcript: transcript || node.request,
|
|
589608
|
-
toolCalls: [],
|
|
589609
|
-
workingDirectory: ctx3.workingDirectory,
|
|
589610
|
-
sessionId: ctx3.sessionId
|
|
589611
|
-
},
|
|
589612
|
-
callable: ctx3.summarizer ?? (async () => "")
|
|
589613
|
-
});
|
|
589614
|
-
} catch {
|
|
589615
|
-
}
|
|
589616
|
-
}
|
|
589617
|
-
async function execUnit(unit, node, ctx3, contract, maxRegenerate) {
|
|
589618
|
-
let result = await ctx3.executeUnit(unit, node);
|
|
589619
|
-
if (!result.ok)
|
|
589620
|
-
return false;
|
|
589621
|
-
const expected = unit.expectedSymbols ?? [];
|
|
589622
|
-
if (expected.length === 0) {
|
|
589623
|
-
return true;
|
|
589624
|
-
}
|
|
589625
|
-
for (let attempt = 0; attempt <= maxRegenerate; attempt++) {
|
|
589626
|
-
if (!result.path || result.source === void 0)
|
|
589627
|
-
return false;
|
|
589628
|
-
const verdict = evaluateExecutorStep({
|
|
589629
|
-
unit: { path: result.path, source: result.source },
|
|
589630
|
-
contract,
|
|
589631
|
-
expectedSymbols: expected
|
|
589632
|
-
});
|
|
589633
|
-
if (verdict.decision === "accept")
|
|
589634
|
-
return true;
|
|
589635
|
-
if (verdict.decision === "replan")
|
|
589636
|
-
return false;
|
|
589637
|
-
result = await ctx3.executeUnit(unit, node);
|
|
589638
|
-
if (!result.ok)
|
|
589639
|
-
return false;
|
|
589640
|
-
}
|
|
589641
|
-
return false;
|
|
589642
|
-
}
|
|
589643
|
-
async function runFeatureNode(node, ctx3, options2, tree2 = {}) {
|
|
589644
|
-
const maxRegenerate = options2.maxRegenerate ?? 2;
|
|
589645
|
-
tree2[node.id] = node;
|
|
589646
|
-
try {
|
|
589647
|
-
const artefact = await planFeature(options2.survey, {
|
|
589648
|
-
proseGenerator: options2.proseGenerator
|
|
589649
|
-
});
|
|
589650
|
-
node.kind = artefact.kind;
|
|
589651
|
-
if (ctx3.onPlan) {
|
|
589652
|
-
try {
|
|
589653
|
-
await ctx3.onPlan(artefact);
|
|
589654
|
-
} catch {
|
|
589655
|
-
}
|
|
589656
|
-
}
|
|
589657
|
-
persistPlannerArtefacts(ctx3.rootId, artefact, ctx3.stateDir);
|
|
589658
|
-
const mustAsk = node.depth === 0 || !node.scopeToken;
|
|
589659
|
-
if (mustAsk && ctx3.askApproval) {
|
|
589660
|
-
node.status = "awaiting_approval";
|
|
589661
|
-
const outcome = await requestApproval({
|
|
589662
|
-
rootId: ctx3.rootId,
|
|
589663
|
-
request: node.request,
|
|
589664
|
-
specMarkdown: artefact.specMarkdown,
|
|
589665
|
-
lockedContract: artefact.lockedContract,
|
|
589666
|
-
decomposition: artefact.decomposition,
|
|
589667
|
-
depthCap: ctx3.depthCap
|
|
589668
|
-
}, ctx3.askApproval, { files: options2.survey.files.map((f2) => f2.path) });
|
|
589669
|
-
if (outcome.decision !== "approve") {
|
|
589670
|
-
node.status = outcome.decision === "edit" ? "planned" : "rejected";
|
|
589671
|
-
saveFeatureTree(ctx3.stateDir, ctx3.rootId, tree2);
|
|
589672
|
-
return node;
|
|
589673
|
-
}
|
|
589674
|
-
node.scopeToken = outcome.token;
|
|
589675
|
-
}
|
|
589676
|
-
node.status = "approved";
|
|
589677
|
-
node.status = "executing";
|
|
589678
|
-
let allOk = true;
|
|
589679
|
-
for (const unit of artefact.decomposition) {
|
|
589680
|
-
if (unit.size === "large" && node.depth < ctx3.depthCap) {
|
|
589681
|
-
const childId = newNodeId(node.depth + 1, unit.label + node.id);
|
|
589682
|
-
const childRequest = buildFeatureUnitRequest({
|
|
589683
|
-
unit,
|
|
589684
|
-
parentRequest: node.request,
|
|
589685
|
-
survey: options2.survey
|
|
589686
|
-
});
|
|
589687
|
-
const child = {
|
|
589688
|
-
id: childId,
|
|
589689
|
-
parentId: node.id,
|
|
589690
|
-
depth: node.depth + 1,
|
|
589691
|
-
request: childRequest,
|
|
589692
|
-
kind: artefact.kind,
|
|
589693
|
-
status: "planned",
|
|
589694
|
-
scopeToken: node.scopeToken,
|
|
589695
|
-
children: []
|
|
589696
|
-
};
|
|
589697
|
-
node.children.push(childId);
|
|
589698
|
-
const childSurvey = {
|
|
589699
|
-
...options2.survey,
|
|
589700
|
-
request: child.request
|
|
589701
|
-
};
|
|
589702
|
-
const childCtx = {
|
|
589703
|
-
...ctx3,
|
|
589704
|
-
// children inherit the token; re-prompt only if they exceed scope
|
|
589705
|
-
askApproval: (req3) => isWithinScope({
|
|
589706
|
-
token: node.scopeToken,
|
|
589707
|
-
depth: node.depth + 1,
|
|
589708
|
-
nodeKind: artefact.kind
|
|
589709
|
-
}) ? "approve" : ctx3.askApproval(req3)
|
|
589710
|
-
};
|
|
589711
|
-
const res = await runFeatureNode(child, childCtx, { ...options2, survey: childSurvey }, tree2);
|
|
589712
|
-
if (res.status !== "completed")
|
|
589713
|
-
allOk = false;
|
|
589714
|
-
await evictNode(child, ctx3, child.request);
|
|
589715
|
-
} else {
|
|
589716
|
-
const ok3 = await execUnit(unit, node, ctx3, artefact.lockedContract, maxRegenerate);
|
|
589717
|
-
if (!ok3)
|
|
589718
|
-
allOk = false;
|
|
589719
|
-
}
|
|
589720
|
-
}
|
|
589721
|
-
if (allOk) {
|
|
589722
|
-
node.status = "completed";
|
|
589723
|
-
} else {
|
|
589724
|
-
node.status = "failed";
|
|
589725
|
-
}
|
|
589726
|
-
saveFeatureTree(ctx3.stateDir, ctx3.rootId, tree2);
|
|
589727
|
-
return node;
|
|
589728
|
-
} catch {
|
|
589729
|
-
if (ctx3.runGeneralLoop) {
|
|
589730
|
-
await ctx3.runGeneralLoop(node.request);
|
|
589731
|
-
node.status = "completed";
|
|
589732
|
-
} else {
|
|
589733
|
-
node.status = "failed";
|
|
589734
|
-
}
|
|
589735
|
-
saveFeatureTree(ctx3.stateDir, ctx3.rootId, tree2);
|
|
589736
|
-
return node;
|
|
589737
|
-
}
|
|
589738
|
-
}
|
|
589739
|
-
function createRootFeatureNode(request) {
|
|
589740
|
-
return {
|
|
589741
|
-
id: newNodeId(0, request),
|
|
589742
|
-
parentId: null,
|
|
589743
|
-
depth: 0,
|
|
589744
|
-
request,
|
|
589745
|
-
kind: "new-module",
|
|
589746
|
-
status: "planned",
|
|
589747
|
-
children: []
|
|
589748
|
-
};
|
|
589749
|
-
}
|
|
589750
|
-
var init_featureNode = __esm({
|
|
589751
|
-
"packages/orchestrator/dist/featureNode.js"() {
|
|
589752
|
-
"use strict";
|
|
589753
|
-
init_featurePlanner();
|
|
589754
|
-
init_featureApprovalGate();
|
|
589755
|
-
init_spec_gate();
|
|
589756
|
-
init_todo_context_chunker();
|
|
589757
|
-
}
|
|
589758
|
-
});
|
|
589759
|
-
|
|
589760
589692
|
// packages/orchestrator/dist/preflightSnapshot.js
|
|
589761
589693
|
var preflightSnapshot_exports = {};
|
|
589762
589694
|
__export(preflightSnapshot_exports, {
|
|
@@ -590875,6 +590807,142 @@ function stripShellQuotedSegments(command) {
|
|
|
590875
590807
|
}
|
|
590876
590808
|
return out;
|
|
590877
590809
|
}
|
|
590810
|
+
function extractClaimPathFragments(text2) {
|
|
590811
|
+
const out = [];
|
|
590812
|
+
const pathPattern = /\b(?:[\w.-]+\/[\w./-]+(?:\.[A-Za-z0-9]+)?|[\w.-]+\.[A-Za-z0-9]+)\b/g;
|
|
590813
|
+
for (const match of text2.matchAll(pathPattern)) {
|
|
590814
|
+
const value2 = sanitizeDelegationText(String(match[0] ?? ""), 260).trim();
|
|
590815
|
+
if (!value2)
|
|
590816
|
+
continue;
|
|
590817
|
+
out.push(value2);
|
|
590818
|
+
}
|
|
590819
|
+
return [...new Set(out)];
|
|
590820
|
+
}
|
|
590821
|
+
function normalizeClaimPathSignal(raw) {
|
|
590822
|
+
const normalized = raw.replace(/["'`]+/g, "").replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/").trim().toLowerCase();
|
|
590823
|
+
if (!normalized)
|
|
590824
|
+
return "";
|
|
590825
|
+
if (normalized.length < 4)
|
|
590826
|
+
return "";
|
|
590827
|
+
if (normalized.includes(".."))
|
|
590828
|
+
return "";
|
|
590829
|
+
if (/[\\s]/.test(normalized))
|
|
590830
|
+
return "";
|
|
590831
|
+
return normalized;
|
|
590832
|
+
}
|
|
590833
|
+
function isLikelyPathSignal(value2) {
|
|
590834
|
+
if (!value2)
|
|
590835
|
+
return false;
|
|
590836
|
+
return value2.includes("/") || /\.[a-z0-9]+$/i.test(value2);
|
|
590837
|
+
}
|
|
590838
|
+
function collectClaimPathSignals(text2) {
|
|
590839
|
+
const direct = extractClaimPathFragments(text2).map((value2) => normalizeClaimPathSignal(value2)).filter(isLikelyPathSignal);
|
|
590840
|
+
const quoted = [...text2.matchAll(/["'`](.*?)["'`]/g)].map((match) => normalizeClaimPathSignal(String(match[1] ?? ""))).filter((value2) => isLikelyPathSignal(value2));
|
|
590841
|
+
return [.../* @__PURE__ */ new Set([...direct, ...quoted])];
|
|
590842
|
+
}
|
|
590843
|
+
function matchHintToInventoryPath(path16, hint) {
|
|
590844
|
+
const normalizedPath = normalizeClaimPathSignal(path16);
|
|
590845
|
+
const normalizedHint = normalizeClaimPathSignal(hint);
|
|
590846
|
+
if (!normalizedPath || !normalizedHint)
|
|
590847
|
+
return false;
|
|
590848
|
+
if (normalizedPath === normalizedHint)
|
|
590849
|
+
return true;
|
|
590850
|
+
if (normalizedPath.endsWith(`/${normalizedHint}`))
|
|
590851
|
+
return true;
|
|
590852
|
+
if (normalizedPath.endsWith(normalizedHint))
|
|
590853
|
+
return true;
|
|
590854
|
+
if (normalizedHint.includes("/") && normalizedPath.includes(normalizedHint))
|
|
590855
|
+
return true;
|
|
590856
|
+
const base3 = normalizedPath.split("/").at(-1) ?? "";
|
|
590857
|
+
return base3 === normalizedHint;
|
|
590858
|
+
}
|
|
590859
|
+
function claimDiscoveryFallbackCandidates(files, maxCandidates) {
|
|
590860
|
+
const ranked = [];
|
|
590861
|
+
const nowMs = Date.now();
|
|
590862
|
+
const maxAgeMs = 30 * 24 * 60 * 60 * 1e3;
|
|
590863
|
+
for (const raw of files) {
|
|
590864
|
+
const rawPath = String(raw.path ?? "").trim();
|
|
590865
|
+
if (!rawPath || rawPath.startsWith(".omnius/"))
|
|
590866
|
+
continue;
|
|
590867
|
+
const normalized = rawPath.replace(/\s+/g, " ").trim().replace(/\\/g, "/").replace(/^\.\//, "").replace(/\/+/g, "/").toLowerCase();
|
|
590868
|
+
if (normalized.length < 4 || normalized.includes(".."))
|
|
590869
|
+
continue;
|
|
590870
|
+
const chunks = normalized.split("/").filter(Boolean);
|
|
590871
|
+
const depth = chunks.length || 1;
|
|
590872
|
+
const reasons = [];
|
|
590873
|
+
let score = 0;
|
|
590874
|
+
score += Math.max(1, 12 - Math.min(depth, 10));
|
|
590875
|
+
reasons.push("generic workspace proximity");
|
|
590876
|
+
if (raw.bytes !== void 0) {
|
|
590877
|
+
if (raw.bytes > 5e5)
|
|
590878
|
+
score -= 3;
|
|
590879
|
+
else if (raw.bytes > 8e4)
|
|
590880
|
+
score -= 1;
|
|
590881
|
+
if (raw.bytes > 5e5)
|
|
590882
|
+
reasons.push("large artifact");
|
|
590883
|
+
else if (raw.bytes > 8e4)
|
|
590884
|
+
reasons.push("moderate artifact");
|
|
590885
|
+
else
|
|
590886
|
+
reasons.push("light payload");
|
|
590887
|
+
}
|
|
590888
|
+
if (raw.mtimeMs !== void 0 && raw.mtimeMs > 0) {
|
|
590889
|
+
const age = nowMs - raw.mtimeMs;
|
|
590890
|
+
if (age >= 0 && age < maxAgeMs) {
|
|
590891
|
+
score += 2;
|
|
590892
|
+
reasons.push("recently modified");
|
|
590893
|
+
} else if (age < 0) {
|
|
590894
|
+
score += 1;
|
|
590895
|
+
reasons.push("fresh metadata");
|
|
590896
|
+
} else {
|
|
590897
|
+
reasons.push("older artifact");
|
|
590898
|
+
}
|
|
590899
|
+
}
|
|
590900
|
+
const pathSignal = chunks.join("/");
|
|
590901
|
+
if (!pathSignal)
|
|
590902
|
+
continue;
|
|
590903
|
+
ranked.push({
|
|
590904
|
+
path: pathSignal,
|
|
590905
|
+
score,
|
|
590906
|
+
reasons: [...new Set(reasons)].slice(0, 3)
|
|
590907
|
+
});
|
|
590908
|
+
}
|
|
590909
|
+
ranked.sort((left, right) => right.score !== left.score ? right.score - left.score : left.path.localeCompare(right.path));
|
|
590910
|
+
const fallback = [];
|
|
590911
|
+
for (const entry of ranked) {
|
|
590912
|
+
if (fallback.length >= maxCandidates)
|
|
590913
|
+
break;
|
|
590914
|
+
const canonical2 = entry.path.replace(/\\/g, "/").replace(/\/+/g, "/").replace(/^\.\//, "").trim().toLowerCase();
|
|
590915
|
+
if (canonical2.length < 4 || canonical2.includes(".."))
|
|
590916
|
+
continue;
|
|
590917
|
+
if (fallback.some((candidate) => candidate.path === canonical2))
|
|
590918
|
+
continue;
|
|
590919
|
+
fallback.push({
|
|
590920
|
+
path: canonical2,
|
|
590921
|
+
reasons: entry.reasons.length > 0 ? entry.reasons : ["generic workspace candidate"]
|
|
590922
|
+
});
|
|
590923
|
+
}
|
|
590924
|
+
return fallback;
|
|
590925
|
+
}
|
|
590926
|
+
function extractClaimTaskTokens(text2) {
|
|
590927
|
+
return String(text2 ?? "").toLowerCase().replace(/["'`]/g, " ").replace(/[^\w./-]+/g, " ").split(/\s+/).map((value2) => value2.trim()).filter((value2) => value2.length >= 4 && value2.length <= 80 && /[a-z0-9]/i.test(value2)).slice(0, 80);
|
|
590928
|
+
}
|
|
590929
|
+
function isMeaningfulClaimTaskToken(token) {
|
|
590930
|
+
if (!token)
|
|
590931
|
+
return false;
|
|
590932
|
+
const normalized = token.toLowerCase();
|
|
590933
|
+
if (normalized.length < 4 || normalized.length > 80)
|
|
590934
|
+
return false;
|
|
590935
|
+
if (!/[a-z0-9]/i.test(normalized))
|
|
590936
|
+
return false;
|
|
590937
|
+
if (CLAIM_TASK_STOPWORDS.has(normalized))
|
|
590938
|
+
return false;
|
|
590939
|
+
return true;
|
|
590940
|
+
}
|
|
590941
|
+
function chunkHasSymbolMatch(token, text2) {
|
|
590942
|
+
const haystack = text2.toLowerCase().replace(/[^a-z0-9]+/g, " ");
|
|
590943
|
+
const tokens = haystack.split(" ").filter(Boolean);
|
|
590944
|
+
return tokens.includes(token);
|
|
590945
|
+
}
|
|
590878
590946
|
function isCompilerLikeVerifierCommand(command) {
|
|
590879
590947
|
const normalized = command.toLowerCase();
|
|
590880
590948
|
return /\b(?:pio|platformio|tsc|gcc|g\+\+|clang\+\+?|clang|cargo\s+(?:build|check)|go\s+(?:build|test)|javac|gradle|mvn|msbuild|dotnet\s+build|python(?:3)?\s+-m\s+(?:py_compile|compileall)|mypy|pyright)\b/.test(normalized);
|
|
@@ -591617,7 +591685,7 @@ function classifyThinkOutcome(raw) {
|
|
|
591617
591685
|
}
|
|
591618
591686
|
return null;
|
|
591619
591687
|
}
|
|
591620
|
-
var PRESERVE_MODEL_VISIBLE_HISTORY, TOOL_SUBSETS, TOOL_AUTO_DEMOTE_TURNS, LEGACY_ACTION_REASON_KEYS, SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, VISUAL_TOOLS, AUDIO_TOOLS, SOCIAL_TOOLS, SPATIAL_TOOLS, CODE_TOOLS, AgenticRunner, OllamaAgenticBackend;
|
|
591688
|
+
var PRESERVE_MODEL_VISIBLE_HISTORY, TOOL_SUBSETS, TOOL_AUTO_DEMOTE_TURNS, LEGACY_ACTION_REASON_KEYS, CLAIM_TASK_STOPWORDS, SYSTEM_PROMPT, SYSTEM_PROMPT_MEDIUM, SYSTEM_PROMPT_SMALL, VISUAL_TOOLS, AUDIO_TOOLS, SOCIAL_TOOLS, SPATIAL_TOOLS, CODE_TOOLS, AgenticRunner, OllamaAgenticBackend;
|
|
591621
591689
|
var init_agenticRunner = __esm({
|
|
591622
591690
|
"packages/orchestrator/dist/agenticRunner.js"() {
|
|
591623
591691
|
"use strict";
|
|
@@ -591699,8 +591767,6 @@ var init_agenticRunner = __esm({
|
|
|
591699
591767
|
init_prompt_cache();
|
|
591700
591768
|
init_compile_error_fix_loop();
|
|
591701
591769
|
init_git_progress();
|
|
591702
|
-
init_featurePlanner();
|
|
591703
|
-
init_featureNode();
|
|
591704
591770
|
PRESERVE_MODEL_VISIBLE_HISTORY = /* @__PURE__ */ Symbol("omnius.preserveModelVisibleHistory");
|
|
591705
591771
|
TOOL_SUBSETS = {
|
|
591706
591772
|
web: ["web_search", "web_fetch", "web_crawl"],
|
|
@@ -591727,6 +591793,79 @@ var init_agenticRunner = __esm({
|
|
|
591727
591793
|
};
|
|
591728
591794
|
TOOL_AUTO_DEMOTE_TURNS = 10;
|
|
591729
591795
|
LEGACY_ACTION_REASON_KEYS = /* @__PURE__ */ new Set(["action_reason", "actionReason"]);
|
|
591796
|
+
CLAIM_TASK_STOPWORDS = /* @__PURE__ */ new Set([
|
|
591797
|
+
"this",
|
|
591798
|
+
"that",
|
|
591799
|
+
"these",
|
|
591800
|
+
"those",
|
|
591801
|
+
"there",
|
|
591802
|
+
"where",
|
|
591803
|
+
"from",
|
|
591804
|
+
"with",
|
|
591805
|
+
"what",
|
|
591806
|
+
"when",
|
|
591807
|
+
"then",
|
|
591808
|
+
"help",
|
|
591809
|
+
"please",
|
|
591810
|
+
"request",
|
|
591811
|
+
"about",
|
|
591812
|
+
"their",
|
|
591813
|
+
"would",
|
|
591814
|
+
"could",
|
|
591815
|
+
"should",
|
|
591816
|
+
"might",
|
|
591817
|
+
"issue",
|
|
591818
|
+
"issues",
|
|
591819
|
+
"bug",
|
|
591820
|
+
"problem",
|
|
591821
|
+
"problems",
|
|
591822
|
+
"task",
|
|
591823
|
+
"tasks",
|
|
591824
|
+
"run",
|
|
591825
|
+
"build",
|
|
591826
|
+
"make",
|
|
591827
|
+
"need",
|
|
591828
|
+
"needs",
|
|
591829
|
+
"also",
|
|
591830
|
+
"only",
|
|
591831
|
+
"same",
|
|
591832
|
+
"other",
|
|
591833
|
+
"code",
|
|
591834
|
+
"file",
|
|
591835
|
+
"files",
|
|
591836
|
+
"repo",
|
|
591837
|
+
"project",
|
|
591838
|
+
"workspace",
|
|
591839
|
+
"read",
|
|
591840
|
+
"fix",
|
|
591841
|
+
"add",
|
|
591842
|
+
"remove",
|
|
591843
|
+
"create",
|
|
591844
|
+
"review",
|
|
591845
|
+
"check",
|
|
591846
|
+
"report",
|
|
591847
|
+
"inspect",
|
|
591848
|
+
"update",
|
|
591849
|
+
"implement",
|
|
591850
|
+
"setup",
|
|
591851
|
+
"install",
|
|
591852
|
+
"deploy",
|
|
591853
|
+
"run",
|
|
591854
|
+
"get",
|
|
591855
|
+
"set",
|
|
591856
|
+
"open",
|
|
591857
|
+
"close",
|
|
591858
|
+
"start",
|
|
591859
|
+
"stop",
|
|
591860
|
+
"turn",
|
|
591861
|
+
"off",
|
|
591862
|
+
"on",
|
|
591863
|
+
"enable",
|
|
591864
|
+
"disable",
|
|
591865
|
+
"add",
|
|
591866
|
+
"new",
|
|
591867
|
+
"old"
|
|
591868
|
+
]);
|
|
591730
591869
|
SYSTEM_PROMPT = loadPrompt("agentic/system-large.md");
|
|
591731
591870
|
SYSTEM_PROMPT_MEDIUM = loadPrompt("agentic/system-medium.md");
|
|
591732
591871
|
SYSTEM_PROMPT_SMALL = loadPrompt("agentic/system-small.md");
|
|
@@ -592024,8 +592163,6 @@ var init_agenticRunner = __esm({
|
|
|
592024
592163
|
_wideExplorationCooldownUntilTurn = -1;
|
|
592025
592164
|
/** REG-44: how many times the stuck detector has fired (for adaptive cooldown). */
|
|
592026
592165
|
_reg44FireCount = 0;
|
|
592027
|
-
/** Guard against re-entering the feature loop. */
|
|
592028
|
-
_inFeatureLoop = false;
|
|
592029
592166
|
// REG-45: sticky cross-turn escalation. The dispatch-time reflection
|
|
592030
592167
|
// surface (REG-26) only fires when the agent re-emits the exact same
|
|
592031
592168
|
// failed stem. If the agent thrashes on OTHER tools (wide-exploration
|
|
@@ -592145,6 +592282,7 @@ var init_agenticRunner = __esm({
|
|
|
592145
592282
|
*/
|
|
592146
592283
|
_completionCaveat = null;
|
|
592147
592284
|
_completionLedger = null;
|
|
592285
|
+
_claimDiscoveryInitialized = false;
|
|
592148
592286
|
_staleEditFamilies = /* @__PURE__ */ new Map();
|
|
592149
592287
|
/** Semantic retry counter for blocked full-file writes (payload-independent). */
|
|
592150
592288
|
_blockedFullWriteAttempts = /* @__PURE__ */ new Map();
|
|
@@ -593518,7 +593656,9 @@ ${parts.join("\n")}
|
|
|
593518
593656
|
success: input.status === "completed",
|
|
593519
593657
|
output: `terminal_receipt=${record.id}
|
|
593520
593658
|
marker=${markerPath}
|
|
593521
|
-
evidence=${record.evidenceIds.join(",") || "none"}
|
|
593659
|
+
evidence=${record.evidenceIds.join(",") || "none"}
|
|
593660
|
+
command_receipts=${record.commandReceipts.length}
|
|
593661
|
+
` + (record.commandReceipts.length > 0 ? `command_receipts_summary=${record.commandReceipts.map((entry) => `${entry.canonicalCommand || entry.command || "n/a"}:${entry.exitCode}`).join(" | ")}` : "command_receipts_summary=none")
|
|
593522
593662
|
});
|
|
593523
593663
|
commitTerminalTrajectoryProjection(stateDir, record, input.trajectoryPayload);
|
|
593524
593664
|
const committed = {
|
|
@@ -593610,6 +593750,7 @@ evidence=${record.evidenceIds.join(",") || "none"}`
|
|
|
593610
593750
|
disableAdversaryCritic,
|
|
593611
593751
|
disableStepCritic: disableAdversaryCritic,
|
|
593612
593752
|
modelTier: options2?.modelTier ?? "large",
|
|
593753
|
+
claimDiscovery: options2?.claimDiscovery,
|
|
593613
593754
|
referenceContractModules: options2?.referenceContractModules ?? [],
|
|
593614
593755
|
contextWindowSize: options2?.contextWindowSize ?? 0,
|
|
593615
593756
|
recursionDepth: options2?.recursionDepth ?? 0,
|
|
@@ -597037,7 +597178,7 @@ ${extras.join("\n")}`;
|
|
|
597037
597178
|
const paths = args["edits"].map((edit) => edit && typeof edit === "object" ? edit["path"] : null).filter((p3) => typeof p3 === "string" && p3.trim().length > 0);
|
|
597038
597179
|
return [...new Set(paths)];
|
|
597039
597180
|
}
|
|
597040
|
-
const p2 = args?.["path"] ?? args?.["file_path"] ?? args?.["file"] ?? args?.["filename"] ?? args?.["filepath"] ?? args?.["filePath"];
|
|
597181
|
+
const p2 = args?.["path"] ?? args?.["file_path"] ?? args?.["file"] ?? args?.["filename"] ?? args?.["filepath"] ?? args?.["filePath"] ?? args?.["input"] ?? args?.["target"];
|
|
597041
597182
|
return typeof p2 === "string" && p2.trim().length > 0 ? [p2.trim()] : [];
|
|
597042
597183
|
}
|
|
597043
597184
|
_isRealProjectMutation(toolName, result) {
|
|
@@ -597178,6 +597319,9 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
597178
597319
|
metrics: input.result.completionEvidenceMetrics,
|
|
597179
597320
|
receipt
|
|
597180
597321
|
});
|
|
597322
|
+
if (this._completionLedger?.claimDiscovery) {
|
|
597323
|
+
this._refreshClaimDiscoveryStateFromEvidence();
|
|
597324
|
+
}
|
|
597181
597325
|
if (realFileMutation && realMutationPaths.length > 0) {
|
|
597182
597326
|
for (const filePath of realMutationPaths) {
|
|
597183
597327
|
this._completionLedger = recordCompletionEvidence(this._completionLedger, {
|
|
@@ -597194,6 +597338,50 @@ ${modelVisible}` : modelVisible || result.error || displayOutput || "";
|
|
|
597194
597338
|
}
|
|
597195
597339
|
this._saveCompletionLedgerSafe();
|
|
597196
597340
|
}
|
|
597341
|
+
_refreshClaimDiscoveryStateFromEvidence() {
|
|
597342
|
+
if (!this._completionLedger?.claimDiscovery)
|
|
597343
|
+
return;
|
|
597344
|
+
const state = this._completionLedger.claimDiscovery;
|
|
597345
|
+
const evidenceHandles = state.evidenceHandles ?? [];
|
|
597346
|
+
const survivingBlockers = state.survivingBlockers ?? [];
|
|
597347
|
+
const unresolvedQuestions = state.unresolvedQuestions ?? [];
|
|
597348
|
+
const openDeltas = state.openDeltas ?? [];
|
|
597349
|
+
const resolved = claimDiscoveryResolvedHandles(this._completionLedger, state);
|
|
597350
|
+
const unresolvedEvidence = evidenceHandles.filter((handle2) => !resolved.includes(handle2));
|
|
597351
|
+
const unresolvedHandleSet = new Set(unresolvedEvidence);
|
|
597352
|
+
const unresolvedOpenDeltas = openDeltas.filter((delta) => {
|
|
597353
|
+
const normalizedDeltaPath = this._normalizeEvidencePath(delta.path).replace(/^\/+/, "");
|
|
597354
|
+
const handle2 = `workspace:${normalizedDeltaPath}`;
|
|
597355
|
+
return unresolvedHandleSet.has(handle2);
|
|
597356
|
+
});
|
|
597357
|
+
const hasBlockers = survivingBlockers.length > 0;
|
|
597358
|
+
const hasCandidates = state.candidatePaths.length > 0;
|
|
597359
|
+
const hasOpenQuestions = unresolvedQuestions.length > 0;
|
|
597360
|
+
const hasOpenEvidence = unresolvedEvidence.length > 0;
|
|
597361
|
+
let status;
|
|
597362
|
+
if (!hasCandidates) {
|
|
597363
|
+
status = hasBlockers || hasOpenQuestions ? "blocked" : "skipped";
|
|
597364
|
+
} else if (hasOpenEvidence || hasOpenQuestions || hasBlockers) {
|
|
597365
|
+
status = hasOpenQuestions || hasBlockers ? "blocked" : "active";
|
|
597366
|
+
} else {
|
|
597367
|
+
status = "complete";
|
|
597368
|
+
}
|
|
597369
|
+
const updated = {
|
|
597370
|
+
...this._completionLedger,
|
|
597371
|
+
claimDiscovery: {
|
|
597372
|
+
...state,
|
|
597373
|
+
openDeltas: unresolvedOpenDeltas,
|
|
597374
|
+
resolvedEvidenceHandles: resolved,
|
|
597375
|
+
evidenceHandles,
|
|
597376
|
+
survivingBlockers,
|
|
597377
|
+
unresolvedQuestions,
|
|
597378
|
+
status
|
|
597379
|
+
}
|
|
597380
|
+
};
|
|
597381
|
+
this._completionLedger = updated;
|
|
597382
|
+
this._saveCompletionLedgerSafe();
|
|
597383
|
+
return updated.claimDiscovery;
|
|
597384
|
+
}
|
|
597197
597385
|
_completionArtifactHashes(paths) {
|
|
597198
597386
|
const unique3 = [...new Set(paths.map((path16) => this._normalizeEvidencePath(path16)).filter(Boolean))].slice(0, 20);
|
|
597199
597387
|
const out = [];
|
|
@@ -597946,15 +598134,18 @@ ${readOnlyLines.join("\n")}` : "Successful read-only evidence: none"
|
|
|
597946
598134
|
}
|
|
597947
598135
|
const timeoutMs = parseInt(process.env["OMNIUS_COMPLETION_VERIFY_TIMEOUT_MS"] || "180000", 10) || 18e4;
|
|
597948
598136
|
const wd = this._workingDirectory || process.cwd();
|
|
598137
|
+
const hasPipe = cmd.includes("|");
|
|
598138
|
+
const startedAtIso = (/* @__PURE__ */ new Date()).toISOString();
|
|
597949
598139
|
this.emit({
|
|
597950
598140
|
type: "status",
|
|
597951
598141
|
content: `completion verify gate: running '${cmd}' (cwd=${wd})`,
|
|
597952
598142
|
turn,
|
|
597953
598143
|
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
597954
598144
|
});
|
|
597955
|
-
const { exitCode, outTail } = await new Promise((resolve84) => {
|
|
598145
|
+
const { exitCode, outTail, timedOut, finishedAtIso } = await new Promise((resolve84) => {
|
|
597956
598146
|
const chunks = [];
|
|
597957
598147
|
let settled = false;
|
|
598148
|
+
let hitTimeout = false;
|
|
597958
598149
|
const child = _spawn(cmd, {
|
|
597959
598150
|
cwd: wd,
|
|
597960
598151
|
shell: true,
|
|
@@ -597970,6 +598161,7 @@ ${readOnlyLines.join("\n")}` : "Successful read-only evidence: none"
|
|
|
597970
598161
|
child.stderr?.on("data", onData);
|
|
597971
598162
|
const killTimer = setTimeout(() => {
|
|
597972
598163
|
try {
|
|
598164
|
+
hitTimeout = true;
|
|
597973
598165
|
child.kill("SIGKILL");
|
|
597974
598166
|
} catch {
|
|
597975
598167
|
}
|
|
@@ -597980,11 +598172,31 @@ ${readOnlyLines.join("\n")}` : "Successful read-only evidence: none"
|
|
|
597980
598172
|
return;
|
|
597981
598173
|
settled = true;
|
|
597982
598174
|
clearTimeout(killTimer);
|
|
597983
|
-
resolve84({
|
|
598175
|
+
resolve84({
|
|
598176
|
+
exitCode: code8,
|
|
598177
|
+
outTail: chunks.join("").slice(-4e3),
|
|
598178
|
+
timedOut: hitTimeout,
|
|
598179
|
+
finishedAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
598180
|
+
});
|
|
597984
598181
|
};
|
|
597985
598182
|
child.on("error", () => finish(1));
|
|
597986
598183
|
child.on("close", (code8) => finish(code8 ?? 1));
|
|
597987
598184
|
});
|
|
598185
|
+
const commandReceipt = {
|
|
598186
|
+
schema: "omnius.command-evidence-receipt.v1",
|
|
598187
|
+
command: cmd,
|
|
598188
|
+
canonicalCommand: "",
|
|
598189
|
+
cwd: wd,
|
|
598190
|
+
exitCode,
|
|
598191
|
+
pipefail: hasPipe,
|
|
598192
|
+
timedOut,
|
|
598193
|
+
startedAtIso,
|
|
598194
|
+
finishedAtIso,
|
|
598195
|
+
artifactHashes: this._completionArtifactHashes([
|
|
598196
|
+
...this._taskState.modifiedFiles.keys()
|
|
598197
|
+
])
|
|
598198
|
+
};
|
|
598199
|
+
commandReceipt.canonicalCommand = canonicalVerificationIdentity(cmd, commandReceipt) ?? normalizeShellCommand(cmd) ?? cmd;
|
|
597988
598200
|
if (this._completionLedger) {
|
|
597989
598201
|
this._completionLedger = recordCompletionEvidence(this._completionLedger, {
|
|
597990
598202
|
kind: "tool_result",
|
|
@@ -597992,9 +598204,11 @@ ${readOnlyLines.join("\n")}` : "Successful read-only evidence: none"
|
|
|
597992
598204
|
success: exitCode === 0,
|
|
597993
598205
|
summary: `completion verify command exited ${exitCode}: ${cmd}
|
|
597994
598206
|
${outTail || "(no output captured)"}`,
|
|
598207
|
+
receipt: commandReceipt,
|
|
597995
598208
|
role: "verification",
|
|
597996
598209
|
family: "completion_verify"
|
|
597997
598210
|
});
|
|
598211
|
+
this._refreshClaimDiscoveryResolvedHandles();
|
|
597998
598212
|
this._saveCompletionLedgerSafe();
|
|
597999
598213
|
}
|
|
598000
598214
|
const compileGuidance = this._observeCompileVerifierResult({
|
|
@@ -598052,7 +598266,8 @@ ${compileGuidance}` : ""
|
|
|
598052
598266
|
const _newClaims = deriveClaimsFromProposedText({
|
|
598053
598267
|
text: proposedSummary,
|
|
598054
598268
|
source: "task_complete_summary",
|
|
598055
|
-
existing: this._completionLedger.proposedClaims
|
|
598269
|
+
existing: this._completionLedger.proposedClaims,
|
|
598270
|
+
workspaceInventory: this._completionLedger.claimDiscovery?.boundedInventory
|
|
598056
598271
|
});
|
|
598057
598272
|
if (_newClaims.length > 0) {
|
|
598058
598273
|
this._completionLedger = addCompletionClaims(this._completionLedger, _newClaims);
|
|
@@ -598062,7 +598277,10 @@ ${compileGuidance}` : ""
|
|
|
598062
598277
|
try {
|
|
598063
598278
|
const _audit = auditCompletionClaims(this._completionLedger.proposedClaims.map((c9) => ({
|
|
598064
598279
|
text: c9.text,
|
|
598065
|
-
status: c9.status
|
|
598280
|
+
status: c9.status,
|
|
598281
|
+
riskCategory: c9.riskCategory === "unknown" || c9.riskCategory === "coverage" ? null : c9.riskCategory,
|
|
598282
|
+
requiresIndependentEvidence: c9.requiresIndependentEvidence,
|
|
598283
|
+
requiredCheck: c9.requiredCheck
|
|
598066
598284
|
})));
|
|
598067
598285
|
if (!_audit.ok) {
|
|
598068
598286
|
const _checks = _audit.blockers.map((b) => `• [${b.category}] "${b.claim}" → ${b.requiredCheck}`).join("\n");
|
|
@@ -598286,8 +598504,9 @@ ${_checks}`
|
|
|
598286
598504
|
verdict: "approve",
|
|
598287
598505
|
rationale: result.verdict.rationale
|
|
598288
598506
|
});
|
|
598289
|
-
this._saveCompletionLedgerSafe();
|
|
598290
598507
|
}
|
|
598508
|
+
this._saveCompletionLedgerSafe();
|
|
598509
|
+
this._refreshClaimDiscoveryResolvedHandles();
|
|
598291
598510
|
this._lastBackwardPassCritique = null;
|
|
598292
598511
|
return { proceed: true };
|
|
598293
598512
|
}
|
|
@@ -598357,6 +598576,9 @@ ${_checks}`
|
|
|
598357
598576
|
}
|
|
598358
598577
|
return { proceed: false, feedback };
|
|
598359
598578
|
}
|
|
598579
|
+
_refreshClaimDiscoveryResolvedHandles() {
|
|
598580
|
+
this._refreshClaimDiscoveryStateFromEvidence();
|
|
598581
|
+
}
|
|
598360
598582
|
/**
|
|
598361
598583
|
* WO-META-TRACK — Hannover-style turn-counter reminder.
|
|
598362
598584
|
*
|
|
@@ -602241,6 +602463,7 @@ ${notice}`;
|
|
|
602241
602463
|
runId: this.currentArtifactRunId(),
|
|
602242
602464
|
goal: record.content
|
|
602243
602465
|
}) : null;
|
|
602466
|
+
this._claimDiscoveryInitialized = false;
|
|
602244
602467
|
if (this._completionLedger) {
|
|
602245
602468
|
this._completionLedger.taskEpoch = this._taskEpoch;
|
|
602246
602469
|
}
|
|
@@ -603270,111 +603493,210 @@ ${rawTask}`;
|
|
|
603270
603493
|
return next;
|
|
603271
603494
|
}
|
|
603272
603495
|
/**
|
|
603273
|
-
*
|
|
603274
|
-
*
|
|
603275
|
-
*
|
|
603276
|
-
*
|
|
603277
|
-
*
|
|
603278
|
-
* than recreating the old task-label-only Feature Loop.
|
|
603496
|
+
* Claim-discovery uses task + bounded workspace inventory before any mutation.
|
|
603497
|
+
* It remains task-centered and product-agnostic: no protocol-specific
|
|
603498
|
+
* heuristics, no model-inferred domain taxonomy, no filename-category
|
|
603499
|
+
* inference. Candidate grounding is deterministic from task + bounded inventory
|
|
603500
|
+
* signals only.
|
|
603279
603501
|
*/
|
|
603280
|
-
async
|
|
603281
|
-
if (process.env["OMNIUS_FEATURE_SURVEY_GROUNDING"] === "0")
|
|
603282
|
-
return
|
|
603502
|
+
async _resolveClaimDiscoverySurvey(task, turn) {
|
|
603503
|
+
if (process.env["OMNIUS_FEATURE_SURVEY_GROUNDING"] === "0") {
|
|
603504
|
+
return claimDiscoveryStateFromSurvey({
|
|
603505
|
+
request: task,
|
|
603506
|
+
boundedInventory: {
|
|
603507
|
+
root: this.authoritativeWorkingDirectory(),
|
|
603508
|
+
files: [],
|
|
603509
|
+
dirs: [],
|
|
603510
|
+
truncated: true,
|
|
603511
|
+
maxFiles: 0,
|
|
603512
|
+
maxDirs: 0,
|
|
603513
|
+
generatedAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
603514
|
+
},
|
|
603515
|
+
candidatePaths: [],
|
|
603516
|
+
pathReasons: {},
|
|
603517
|
+
unresolvedQuestions: [],
|
|
603518
|
+
survivingBlockers: [
|
|
603519
|
+
"Claim discovery is currently disabled by OMNIUS_FEATURE_SURVEY_GROUNDING=0."
|
|
603520
|
+
],
|
|
603521
|
+
requiresEvidence: false
|
|
603522
|
+
});
|
|
603523
|
+
}
|
|
603283
603524
|
const root = this.authoritativeWorkingDirectory();
|
|
603284
|
-
|
|
603285
|
-
|
|
603286
|
-
|
|
603525
|
+
const maxFiles = Math.max(80, Math.min(420, Number.parseInt(process.env["OMNIUS_CLAIM_DISCOVERY_MAX_FILES"] || "240", 10) || 240));
|
|
603526
|
+
const maxDirs = Math.max(60, Math.min(1200, Number.parseInt(process.env["OMNIUS_CLAIM_DISCOVERY_MAX_DIRS"] || "300", 10) || 300));
|
|
603527
|
+
let boundedInventory = null;
|
|
603528
|
+
try {
|
|
603529
|
+
const workspace = scanWorkspace({ root, maxFiles, maxDirs });
|
|
603530
|
+
const files = workspace.files.slice(0, maxFiles).map((file) => ({
|
|
603531
|
+
path: file.rel,
|
|
603532
|
+
bytes: file.bytes,
|
|
603533
|
+
mtimeMs: file.mtimeMs
|
|
603534
|
+
})).filter((file) => !file.path.startsWith(".omnius/"));
|
|
603535
|
+
boundedInventory = {
|
|
603536
|
+
root,
|
|
603537
|
+
files,
|
|
603538
|
+
dirs: workspace.dirs.slice(0, maxDirs).map((dir) => dir.rel),
|
|
603539
|
+
truncated: workspace.truncated,
|
|
603540
|
+
maxFiles,
|
|
603541
|
+
maxDirs,
|
|
603542
|
+
generatedAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
603543
|
+
};
|
|
603287
603544
|
} catch {
|
|
603288
|
-
return
|
|
603289
|
-
|
|
603290
|
-
|
|
603291
|
-
|
|
603292
|
-
|
|
603293
|
-
|
|
603294
|
-
|
|
603295
|
-
|
|
603296
|
-
|
|
603297
|
-
|
|
603298
|
-
|
|
603299
|
-
|
|
603300
|
-
|
|
603301
|
-
|
|
603302
|
-
|
|
603303
|
-
JSON.stringify({
|
|
603304
|
-
candidate_paths: ["exact allowed relative path, 1-8 items"],
|
|
603305
|
-
path_reasons: { "path": "why this is a candidate, based only on request/inventory" },
|
|
603306
|
-
unresolved_questions: ["specific source fact to inspect before edit"],
|
|
603307
|
-
new_symbols: ["only explicitly requested symbols, if any"],
|
|
603308
|
-
existing_symbols: ["only symbols named in supplied context, if any"],
|
|
603309
|
-
tests_exist: false,
|
|
603310
|
-
public_surface_changes: false
|
|
603311
|
-
}),
|
|
603312
|
-
`Task:
|
|
603313
|
-
${sanitizeDelegationText(task, 1400)}`,
|
|
603314
|
-
context2 ? `Parent context (may be stale; verify):
|
|
603315
|
-
${sanitizeDelegationText(context2, 1200)}` : "",
|
|
603316
|
-
ledgerEvidence.length ? `Fresh/stale reads already observed:
|
|
603317
|
-
${ledgerEvidence.map((item) => `- [${item.freshness}] ${item.ref}: ${item.detail}`).join("\n")}` : "No source files have been read in this run yet.",
|
|
603318
|
-
`Allowed workspace inventory:
|
|
603319
|
-
${inventory}`
|
|
603320
|
-
].filter(Boolean).join("\n\n");
|
|
603321
|
-
try {
|
|
603322
|
-
this._emitModelResolutionTelemetry("feature_survey_grounding", turn);
|
|
603323
|
-
const backend = this._auxInferenceBackend({
|
|
603324
|
-
dumpStage: "feature_survey_grounding"
|
|
603325
|
-
});
|
|
603326
|
-
const response = await backend.chatCompletion({
|
|
603327
|
-
messages: [
|
|
603328
|
-
{
|
|
603329
|
-
role: "system",
|
|
603330
|
-
content: "Return only valid JSON matching the requested schema. Never invent a path or infer file content from its name."
|
|
603331
|
-
},
|
|
603332
|
-
{ role: "user", content: prompt }
|
|
603545
|
+
return claimDiscoveryStateFromSurvey({
|
|
603546
|
+
request: task,
|
|
603547
|
+
boundedInventory: {
|
|
603548
|
+
root,
|
|
603549
|
+
files: [],
|
|
603550
|
+
dirs: [],
|
|
603551
|
+
truncated: true,
|
|
603552
|
+
maxFiles,
|
|
603553
|
+
maxDirs,
|
|
603554
|
+
generatedAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
603555
|
+
},
|
|
603556
|
+
candidatePaths: [],
|
|
603557
|
+
pathReasons: {},
|
|
603558
|
+
unresolvedQuestions: [
|
|
603559
|
+
"Workspace scan failed for bounded inventory grounding; retry with explicit target paths."
|
|
603333
603560
|
],
|
|
603334
|
-
|
|
603335
|
-
|
|
603336
|
-
|
|
603337
|
-
|
|
603338
|
-
think: false
|
|
603561
|
+
survivingBlockers: [
|
|
603562
|
+
"Claim discovery cannot anchor evidence without a successful workspace inventory scan."
|
|
603563
|
+
],
|
|
603564
|
+
requiresEvidence: false
|
|
603339
603565
|
});
|
|
603340
|
-
|
|
603341
|
-
|
|
603342
|
-
|
|
603343
|
-
const requestedPaths = Array.isArray(parsed["candidate_paths"]) ? parsed["candidate_paths"].map((value2) => String(value2).trim()).filter((value2) => allowedPaths.has(value2)).slice(0, 8) : [];
|
|
603344
|
-
if (requestedPaths.length === 0)
|
|
603345
|
-
return null;
|
|
603346
|
-
const reasons = parsed["path_reasons"] && typeof parsed["path_reasons"] === "object" ? parsed["path_reasons"] : {};
|
|
603347
|
-
const stringList3 = (value2, cap, maxChars) => Array.isArray(value2) ? value2.map((item) => sanitizeDelegationText(item, maxChars)).filter(Boolean).slice(0, cap) : [];
|
|
603348
|
-
const selectedEvidence2 = requestedPaths.map((file) => ({
|
|
603349
|
-
ref: `workspace:${file}`,
|
|
603350
|
-
detail: sanitizeDelegationText(reasons[file], 280) || "Selected from the workspace inventory; source contents remain uninspected.",
|
|
603351
|
-
freshness: "unknown"
|
|
603352
|
-
}));
|
|
603353
|
-
const unresolvedQuestions = stringList3(parsed["unresolved_questions"], 6, 260);
|
|
603354
|
-
if (unresolvedQuestions.length === 0) {
|
|
603355
|
-
unresolvedQuestions.push("Read the selected source and its nearest tests/callers to establish the exact implementation contract before editing.");
|
|
603356
|
-
}
|
|
603357
|
-
return {
|
|
603566
|
+
}
|
|
603567
|
+
if (!boundedInventory || boundedInventory.files.length === 0) {
|
|
603568
|
+
return claimDiscoveryStateFromSurvey({
|
|
603358
603569
|
request: task,
|
|
603359
|
-
|
|
603360
|
-
|
|
603361
|
-
|
|
603362
|
-
|
|
603363
|
-
|
|
603364
|
-
|
|
603365
|
-
|
|
603570
|
+
boundedInventory: boundedInventory ?? {
|
|
603571
|
+
root,
|
|
603572
|
+
files: [],
|
|
603573
|
+
dirs: [],
|
|
603574
|
+
truncated: true,
|
|
603575
|
+
maxFiles,
|
|
603576
|
+
maxDirs,
|
|
603577
|
+
generatedAtIso: (/* @__PURE__ */ new Date()).toISOString()
|
|
603578
|
+
},
|
|
603579
|
+
candidatePaths: [],
|
|
603580
|
+
pathReasons: {},
|
|
603581
|
+
unresolvedQuestions: [
|
|
603582
|
+
"Bounded workspace inventory was empty; provide concrete target artifacts before claiming completion."
|
|
603366
603583
|
],
|
|
603367
|
-
|
|
603368
|
-
|
|
603369
|
-
|
|
603370
|
-
|
|
603371
|
-
|
|
603372
|
-
|
|
603373
|
-
|
|
603374
|
-
|
|
603375
|
-
|
|
603376
|
-
|
|
603584
|
+
survivingBlockers: ["No bounded inventory files were discoverable."],
|
|
603585
|
+
requiresEvidence: false
|
|
603586
|
+
});
|
|
603587
|
+
}
|
|
603588
|
+
const boundedInventoryPaths = boundedInventory.files.map((file) => file.path);
|
|
603589
|
+
const allowedPaths = new Set(boundedInventoryPaths);
|
|
603590
|
+
const pathReasons = /* @__PURE__ */ Object.create(null);
|
|
603591
|
+
const normalizedTask = sanitizeDelegationText(task, 1500);
|
|
603592
|
+
const taskTokens = extractClaimTaskTokens(task);
|
|
603593
|
+
const meaningfulTaskTokens = taskTokens.filter(isMeaningfulClaimTaskToken);
|
|
603594
|
+
const explicitPathHints = collectClaimPathSignals(task).map((token) => token.toLowerCase()).slice(0, 80);
|
|
603595
|
+
const unmatchedHints = new Set(explicitPathHints);
|
|
603596
|
+
const scored = [];
|
|
603597
|
+
for (const path16 of boundedInventoryPaths) {
|
|
603598
|
+
const lowerPath = path16.toLowerCase();
|
|
603599
|
+
const lowerBase = (path16.split("/").at(-1) ?? "").toLowerCase();
|
|
603600
|
+
const chunks = lowerPath.split("/").filter(Boolean);
|
|
603601
|
+
let score = 0;
|
|
603602
|
+
const reasons = [];
|
|
603603
|
+
for (const hint of explicitPathHints) {
|
|
603604
|
+
if (!matchHintToInventoryPath(path16, hint))
|
|
603605
|
+
continue;
|
|
603606
|
+
unmatchedHints.delete(hint);
|
|
603607
|
+
score += 120;
|
|
603608
|
+
reasons.push(`explicit path hint "${hint}" matches path`);
|
|
603609
|
+
}
|
|
603610
|
+
for (const token of meaningfulTaskTokens) {
|
|
603611
|
+
const lowerToken = token.toLowerCase();
|
|
603612
|
+
if (lowerToken.length < 4)
|
|
603613
|
+
continue;
|
|
603614
|
+
if (chunks.some((chunk) => chunk === lowerToken)) {
|
|
603615
|
+
score += 40;
|
|
603616
|
+
reasons.push(`segment token match (${lowerToken})`);
|
|
603617
|
+
} else if (lowerPath.includes(lowerToken)) {
|
|
603618
|
+
score += 14;
|
|
603619
|
+
reasons.push(`path includes task token (${lowerToken})`);
|
|
603620
|
+
} else if (chunkHasSymbolMatch(lowerToken, lowerBase)) {
|
|
603621
|
+
score += 6;
|
|
603622
|
+
reasons.push(`base symbol overlap (${lowerToken})`);
|
|
603623
|
+
}
|
|
603624
|
+
}
|
|
603625
|
+
if (score > 0) {
|
|
603626
|
+
scored.push({
|
|
603627
|
+
path: path16,
|
|
603628
|
+
score,
|
|
603629
|
+
reasons: [...new Set(reasons)].slice(0, 3)
|
|
603630
|
+
});
|
|
603631
|
+
}
|
|
603632
|
+
}
|
|
603633
|
+
scored.sort((left, right) => right.score !== left.score ? right.score - left.score : left.path.localeCompare(right.path));
|
|
603634
|
+
const rankedCandidates = scored.filter((entry) => entry.score > 0).map((entry) => entry.path).slice(0, 12);
|
|
603635
|
+
const explicitCandidates = explicitPathHints.flatMap((token) => boundedInventoryPaths.filter((path16) => matchHintToInventoryPath(path16, token))).filter((path16) => allowedPaths.has(path16)).slice(0, 12);
|
|
603636
|
+
const candidateSeeds = explicitCandidates.length > 0 ? explicitCandidates : rankedCandidates;
|
|
603637
|
+
const candidatePaths = [.../* @__PURE__ */ new Set([...candidateSeeds, ...rankedCandidates])].slice(0, 8);
|
|
603638
|
+
const shouldUseFallbackCandidates = explicitPathHints.length === 0 && candidatePaths.length === 0;
|
|
603639
|
+
const fallbackCandidates = shouldUseFallbackCandidates ? claimDiscoveryFallbackCandidates(boundedInventory.files, Math.max(4, Math.min(8, maxFiles ? Math.min(8, maxFiles) : 8))) : [];
|
|
603640
|
+
let finalCandidatePaths = candidatePaths.length > 0 ? candidatePaths : fallbackCandidates.map((entry) => entry.path);
|
|
603641
|
+
if (candidatePaths.length === 0 && fallbackCandidates.length > 0) {
|
|
603642
|
+
for (const candidate of fallbackCandidates) {
|
|
603643
|
+
if (!pathReasons[candidate.path]) {
|
|
603644
|
+
pathReasons[candidate.path] = candidate.reasons.join("; ");
|
|
603645
|
+
}
|
|
603646
|
+
}
|
|
603647
|
+
}
|
|
603648
|
+
if (finalCandidatePaths.length === 0 && boundedInventory.files.length > 0) {
|
|
603649
|
+
const boundedPaths = boundedInventory.files.map((file) => String(file.path ?? "")).map((path16) => path16.trim()).filter((path16) => path16.length >= 4 && path16.length <= 800).filter((path16) => !path16.startsWith(".omnius/"));
|
|
603650
|
+
const candidateWithDir = boundedPaths.filter((path16) => path16.includes("/")).slice(0, 4);
|
|
603651
|
+
finalCandidatePaths = (candidateWithDir.length > 0 ? candidateWithDir : boundedPaths).slice(0, 4);
|
|
603652
|
+
for (const candidate of finalCandidatePaths) {
|
|
603653
|
+
if (!pathReasons[candidate]) {
|
|
603654
|
+
pathReasons[candidate] = "selected from bounded inventory fallback";
|
|
603655
|
+
}
|
|
603656
|
+
}
|
|
603377
603657
|
}
|
|
603658
|
+
if (finalCandidatePaths.length === 0) {
|
|
603659
|
+
const hasUnmatchedHints = unmatchedHints.size > 0;
|
|
603660
|
+
const unresolvedQuestions2 = hasUnmatchedHints ? [
|
|
603661
|
+
normalizedTask.length < 5 ? "Task text is too short to anchor evidence safely." : `No grounded candidate source path was identified for explicit task hints (${[...unmatchedHints].slice(0, 4).join(", ")}).`,
|
|
603662
|
+
"Read from declared artifacts before claiming completion."
|
|
603663
|
+
] : [];
|
|
603664
|
+
const survivingBlockers2 = unmatchedHints.size > 0 ? [
|
|
603665
|
+
`No bounded inventory artifact matched explicit task hints: ${[...unmatchedHints].slice(0, 4).join(", ")}`
|
|
603666
|
+
] : [];
|
|
603667
|
+
return claimDiscoveryStateFromSurvey({
|
|
603668
|
+
request: task,
|
|
603669
|
+
boundedInventory,
|
|
603670
|
+
candidatePaths: [],
|
|
603671
|
+
pathReasons: {},
|
|
603672
|
+
unresolvedQuestions: unresolvedQuestions2,
|
|
603673
|
+
survivingBlockers: survivingBlockers2,
|
|
603674
|
+
requiresEvidence: explicitPathHints.length > 0
|
|
603675
|
+
});
|
|
603676
|
+
}
|
|
603677
|
+
for (const candidate of finalCandidatePaths) {
|
|
603678
|
+
const details = scored.find((entry) => entry.path === candidate);
|
|
603679
|
+
if (!pathReasons[candidate]) {
|
|
603680
|
+
pathReasons[candidate] = details && details.reasons.length > 0 ? details.reasons.join("; ") : unmatchedHints.size > 0 ? "selected from explicit task hints plus inventory" : meaningfulTaskTokens.length === 0 ? "selected from bounded inventory fallback" : "selected from bounded request signals and inventory";
|
|
603681
|
+
}
|
|
603682
|
+
}
|
|
603683
|
+
const unresolvedQuestions = unmatchedHints.size > 0 ? [
|
|
603684
|
+
`Unresolved explicit task hints remain unmatched: ${[...unmatchedHints].slice(0, 3).join(", ")}.`,
|
|
603685
|
+
"If task intent changed, restate target artifacts in the user message."
|
|
603686
|
+
] : [];
|
|
603687
|
+
const survivingBlockers = unmatchedHints.size > 0 ? [
|
|
603688
|
+
`Unmatched explicit task hints: ${[...unmatchedHints].slice(0, 3).join(", ")}`
|
|
603689
|
+
] : [];
|
|
603690
|
+
const shouldRequireEvidence = finalCandidatePaths.length > 0 && (explicitPathHints.length > 0 || rankedCandidates.length > 0);
|
|
603691
|
+
return claimDiscoveryStateFromSurvey({
|
|
603692
|
+
request: task,
|
|
603693
|
+
boundedInventory,
|
|
603694
|
+
candidatePaths: finalCandidatePaths,
|
|
603695
|
+
pathReasons,
|
|
603696
|
+
unresolvedQuestions,
|
|
603697
|
+
survivingBlockers,
|
|
603698
|
+
requiresEvidence: shouldRequireEvidence
|
|
603699
|
+
});
|
|
603378
603700
|
}
|
|
603379
603701
|
/**
|
|
603380
603702
|
* Rebuild the one current checkpoint at the context boundary. This shared
|
|
@@ -603701,6 +604023,7 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
603701
604023
|
this._completionIncompleteVerification = null;
|
|
603702
604024
|
this._completionCaveat = null;
|
|
603703
604025
|
this._completionLedger = null;
|
|
604026
|
+
this._claimDiscoveryInitialized = false;
|
|
603704
604027
|
this._focusTerminalLedgerRecorded = false;
|
|
603705
604028
|
this._resetTaskScopedVerifierState();
|
|
603706
604029
|
this._staleEditFamilies.clear();
|
|
@@ -604001,6 +604324,7 @@ Respond with the assessment and take the selected evidence-backed action.`;
|
|
|
604001
604324
|
runId: this._activeRunId || this._sessionId,
|
|
604002
604325
|
goal: userGoal
|
|
604003
604326
|
});
|
|
604327
|
+
this._claimDiscoveryInitialized = false;
|
|
604004
604328
|
this._completionLedger.taskEpoch = this._taskEpoch;
|
|
604005
604329
|
} else {
|
|
604006
604330
|
this._completionContract = null;
|
|
@@ -604685,6 +605009,44 @@ ${dynamicProjectContext}`
|
|
|
604685
605009
|
});
|
|
604686
605010
|
return true;
|
|
604687
605011
|
};
|
|
605012
|
+
const holdClaimDiscoveryTaskComplete = (turn) => {
|
|
605013
|
+
const ledger = this._completionLedger;
|
|
605014
|
+
if (!ledger?.claimDiscovery)
|
|
605015
|
+
return false;
|
|
605016
|
+
this._refreshClaimDiscoveryStateFromEvidence();
|
|
605017
|
+
const state = this._completionLedger?.claimDiscovery;
|
|
605018
|
+
if (!state)
|
|
605019
|
+
return false;
|
|
605020
|
+
const evidenceHandles = state.evidenceHandles ?? [];
|
|
605021
|
+
const unresolvedQuestions = state.unresolvedQuestions ?? [];
|
|
605022
|
+
const resolved = claimDiscoveryResolvedHandles(ledger, state);
|
|
605023
|
+
const unresolved = evidenceHandles.filter((handle2) => !resolved.includes(handle2));
|
|
605024
|
+
const blockers = state.survivingBlockers ?? [];
|
|
605025
|
+
const openDeltas = state.openDeltas ?? [];
|
|
605026
|
+
const hasOpenDiscoveryWork = unresolved.length > 0 || blockers.length > 0 || unresolvedQuestions.length > 0;
|
|
605027
|
+
const shouldHold = (state.status === "active" || state.status === "blocked") && hasOpenDiscoveryWork && state.requiresEvidence !== false;
|
|
605028
|
+
if (!shouldHold) {
|
|
605029
|
+
return false;
|
|
605030
|
+
}
|
|
605031
|
+
const feedback = [
|
|
605032
|
+
"[COMPLETION BLOCKED — evidence discovery incomplete]",
|
|
605033
|
+
`Open claim-discovery deltas: ${openDeltas.map((item) => `${item.path} :: ${item.reason}`).join(" | ") || "none"}`,
|
|
605034
|
+
`Outstanding evidence handles: ${unresolved.join(" | ") || "none"}`,
|
|
605035
|
+
...blockers.length > 0 ? [`Surviving blockers: ${blockers.join(" | ")}`] : [],
|
|
605036
|
+
state.unresolvedQuestions.length > 0 ? `Outstanding question(s): ${state.unresolvedQuestions.slice(0, 4).join(" | ")}` : ""
|
|
605037
|
+
].filter(Boolean).join("\n");
|
|
605038
|
+
lastCompletionGateReason = unresolved.length > 0 ? `claim discovery evidence pending (${unresolved.length})` : "claim discovery is still waiting on blockers/questions";
|
|
605039
|
+
lastCompletionGateFeedback = feedback;
|
|
605040
|
+
lastCompletionGateCode = "claim_discovery";
|
|
605041
|
+
messages2.push({ role: "system", content: feedback });
|
|
605042
|
+
this.emit({
|
|
605043
|
+
type: "status",
|
|
605044
|
+
content: `task_complete held by claim discovery gate: ${lastCompletionGateReason}`,
|
|
605045
|
+
turn,
|
|
605046
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
605047
|
+
});
|
|
605048
|
+
return true;
|
|
605049
|
+
};
|
|
604688
605050
|
const completionHoldEscapeMax = (() => {
|
|
604689
605051
|
const raw = Number(process.env["OMNIUS_COMPLETION_HOLD_MAX"]);
|
|
604690
605052
|
return Number.isFinite(raw) && raw >= 1 ? Math.floor(raw) : 3;
|
|
@@ -604733,7 +605095,7 @@ ${lastCompletionGateFeedback.trim().slice(0, 4e3)}` : ""
|
|
|
604733
605095
|
lastCompletionGateCode = "";
|
|
604734
605096
|
return true;
|
|
604735
605097
|
}
|
|
604736
|
-
const held = holdDeliveryCoverageTaskComplete(turn) || holdCompileFixLoopTaskComplete(turn) || holdUnresolvedVerificationTaskComplete(turn) || holdNoProgressTaskComplete(args, turn) || holdProvenanceTaskComplete(args, turn);
|
|
605098
|
+
const held = holdDeliveryCoverageTaskComplete(turn) || holdCompileFixLoopTaskComplete(turn) || holdUnresolvedVerificationTaskComplete(turn) || holdNoProgressTaskComplete(args, turn) || holdProvenanceTaskComplete(args, turn) || holdClaimDiscoveryTaskComplete(turn);
|
|
604737
605099
|
if (!held) {
|
|
604738
605100
|
this._completionHoldState.count = 0;
|
|
604739
605101
|
this._completionHoldState.lastKey = "";
|
|
@@ -604828,94 +605190,41 @@ ${lastCompletionGateFeedback.trim().slice(0, 4e3)}` : ""
|
|
|
604828
605190
|
};
|
|
604829
605191
|
let executeSingle = async () => null;
|
|
604830
605192
|
const turnCap = this.options.maxTurns && this.options.maxTurns > 0 ? this.options.maxTurns : Number.MAX_SAFE_INTEGER;
|
|
604831
|
-
const
|
|
604832
|
-
|
|
604833
|
-
|
|
604834
|
-
const _survey = await this._resolveFeatureSurvey(task, context2, 0);
|
|
604835
|
-
if (!_survey) {
|
|
604836
|
-
this.emit({
|
|
604837
|
-
type: "status",
|
|
604838
|
-
content: "[FEATURE LOOP] deferred: no model-grounded workspace survey was available; continuing with the normal discovery loop",
|
|
604839
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604840
|
-
});
|
|
604841
|
-
} else {
|
|
604842
|
-
const _kind = classifyKind(_survey);
|
|
604843
|
-
if (_kind === "investigation") {
|
|
604844
|
-
this.emit({
|
|
604845
|
-
type: "status",
|
|
604846
|
-
content: "[FEATURE LOOP] survey classified this as investigation; continuing with the normal evidence-gathering loop",
|
|
604847
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604848
|
-
});
|
|
604849
|
-
} else {
|
|
604850
|
-
this._inFeatureLoop = true;
|
|
604851
|
-
this.emit({
|
|
604852
|
-
type: "status",
|
|
604853
|
-
content: `[FEATURE LOOP] evidence-grounded survey classified "${_kind}" – entering recursive driver...`,
|
|
604854
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604855
|
-
});
|
|
604856
|
-
const _root = createRootFeatureNode(task);
|
|
604857
|
-
const _startMs = Date.now();
|
|
604858
|
-
const _resultNode = await runFeatureNode(_root, {
|
|
604859
|
-
rootId: _root.id,
|
|
604860
|
-
stateDir: this.omniusStateDir(),
|
|
604861
|
-
workingDirectory: this.authoritativeWorkingDirectory() || process.cwd(),
|
|
604862
|
-
sessionId: this._sessionId,
|
|
604863
|
-
depthCap: 4,
|
|
604864
|
-
askApproval: async () => "approve",
|
|
604865
|
-
executeUnit: async (unit, node) => {
|
|
604866
|
-
const _unitRequest = buildFeatureUnitRequest({
|
|
604867
|
-
unit,
|
|
604868
|
-
parentRequest: node.request,
|
|
604869
|
-
survey: _survey
|
|
604870
|
-
});
|
|
604871
|
-
const _sub = await this.run(_unitRequest, unit.detail || "Feature unit request is grounded in the parent survey; verify the cited source before mutation.", unit.label);
|
|
604872
|
-
return { ok: _sub.status === "completed" };
|
|
604873
|
-
},
|
|
604874
|
-
runGeneralLoop: async (request) => {
|
|
604875
|
-
await this.run(request, void 0, request);
|
|
604876
|
-
},
|
|
604877
|
-
onPlan: async (artefact) => {
|
|
604878
|
-
if (this._longHaul && artefact.lockedContract?.symbols?.length) {
|
|
604879
|
-
this._longHaul.seedLockedContract(artefact.lockedContract);
|
|
604880
|
-
this.emit({
|
|
604881
|
-
type: "status",
|
|
604882
|
-
content: `[FEATURE LOOP] seeded ${artefact.lockedContract.symbols.length} locked symbols into WO-6 contract`,
|
|
604883
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604884
|
-
});
|
|
604885
|
-
}
|
|
604886
|
-
}
|
|
604887
|
-
}, { survey: _survey });
|
|
604888
|
-
this._inFeatureLoop = false;
|
|
604889
|
-
const _completed = _resultNode.status === "completed";
|
|
604890
|
-
const _durMs = Date.now() - _startMs;
|
|
604891
|
-
this.emit({
|
|
604892
|
-
type: _completed ? "complete" : "error",
|
|
604893
|
-
content: `[FEATURE LOOP] ${_completed ? "completed" : "failed"} after ${_durMs}ms — ${_resultNode.children.length} child nodes`,
|
|
604894
|
-
success: _completed,
|
|
604895
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604896
|
-
});
|
|
604897
|
-
return {
|
|
604898
|
-
status: _completed ? "completed" : "incomplete",
|
|
604899
|
-
completed: _completed,
|
|
604900
|
-
turns: 0,
|
|
604901
|
-
toolCalls: 0,
|
|
604902
|
-
totalTokens: 0,
|
|
604903
|
-
promptTokens: 0,
|
|
604904
|
-
completionTokens: 0,
|
|
604905
|
-
estimatedTokens: 0,
|
|
604906
|
-
summary: `[FEATURE LOOP] ${_completed ? "completed" : "failed"}: ${task.slice(0, 200)}`,
|
|
604907
|
-
durationMs: _durMs
|
|
604908
|
-
};
|
|
604909
|
-
}
|
|
604910
|
-
}
|
|
604911
|
-
} catch (e2) {
|
|
604912
|
-
this._inFeatureLoop = false;
|
|
604913
|
-
this.emit({
|
|
604914
|
-
type: "status",
|
|
604915
|
-
content: `[FEATURE LOOP] error, falling back to general loop: ${e2}`,
|
|
604916
|
-
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
604917
|
-
});
|
|
605193
|
+
const _claimDiscoveryEnabled = (() => {
|
|
605194
|
+
if (typeof this.options.claimDiscovery === "boolean") {
|
|
605195
|
+
return this.options.claimDiscovery;
|
|
604918
605196
|
}
|
|
605197
|
+
const parse3 = (raw) => {
|
|
605198
|
+
if (raw === void 0)
|
|
605199
|
+
return void 0;
|
|
605200
|
+
const lowered = raw.toLowerCase();
|
|
605201
|
+
if (raw === "1" || lowered === "true" || lowered === "on")
|
|
605202
|
+
return true;
|
|
605203
|
+
if (raw === "0" || lowered === "false" || lowered === "off")
|
|
605204
|
+
return false;
|
|
605205
|
+
return void 0;
|
|
605206
|
+
};
|
|
605207
|
+
const explicit = parse3(process.env["OMNIUS_CLAIM_DISCOVERY"]);
|
|
605208
|
+
if (explicit !== void 0)
|
|
605209
|
+
return explicit;
|
|
605210
|
+
const legacy = parse3(process.env["OMNIUS_FEATURE_LOOP"]);
|
|
605211
|
+
return legacy ?? true;
|
|
605212
|
+
})();
|
|
605213
|
+
const _claimDiscoveryNeedsInit = _claimDiscoveryEnabled && !this._claimDiscoveryInitialized && !this.options.subAgent && this._completionLedger !== null;
|
|
605214
|
+
if (_claimDiscoveryNeedsInit && this._completionLedger) {
|
|
605215
|
+
this._claimDiscoveryInitialized = true;
|
|
605216
|
+
const _survey = await this._resolveClaimDiscoverySurvey(task, 0);
|
|
605217
|
+
this._completionLedger = setClaimDiscoveryState(this._completionLedger, _survey);
|
|
605218
|
+
messages2.push({
|
|
605219
|
+
role: "system",
|
|
605220
|
+
content: "[CLAIM DISCOVERY] Grounding signals (compact):\n" + claimDiscoveryControllerSignals(this._completionLedger.claimDiscovery).join("\n")
|
|
605221
|
+
});
|
|
605222
|
+
this.emit({
|
|
605223
|
+
type: "status",
|
|
605224
|
+
content: `[CLAIM DISCOVERY] initialized from bounded inventory: ${this._completionLedger.claimDiscovery?.candidatePaths.length ?? 0} candidate path(s), status=${this._completionLedger.claimDiscovery?.status ?? "skipped"}`,
|
|
605225
|
+
timestamp: (/* @__PURE__ */ new Date()).toISOString()
|
|
605226
|
+
});
|
|
605227
|
+
this._saveCompletionLedgerSafe();
|
|
604919
605228
|
}
|
|
604920
605229
|
if (process.env["OMNIUS_DISABLE_TEXT_ECHO_GUARD"] !== "1") {
|
|
604921
605230
|
const restoredCollapsed = this._textEchoGuard.collapseEchoes(messages2);
|
|
@@ -615134,6 +615443,9 @@ ${trimmedNew}`;
|
|
|
615134
615443
|
`next_claim_inspection=${coverage?.nextInspection?.replace(/\s+/g, " ").slice(0, 420) || "none"}`,
|
|
615135
615444
|
`evidence_handles=${evidenceHandles.join(",") || "none"}`
|
|
615136
615445
|
];
|
|
615446
|
+
if (this._completionLedger?.claimDiscovery) {
|
|
615447
|
+
lines.push(...claimDiscoveryControllerSignals(this._completionLedger.claimDiscovery));
|
|
615448
|
+
}
|
|
615137
615449
|
const tier = this.options.modelTier ?? "large";
|
|
615138
615450
|
const directive = this._focusSupervisor?.snapshot().directive;
|
|
615139
615451
|
if (directive && tier === "small") {
|
|
@@ -622530,8 +622842,8 @@ var init_skill_fork = __esm({
|
|
|
622530
622842
|
});
|
|
622531
622843
|
|
|
622532
622844
|
// packages/orchestrator/dist/missionArtifacts.js
|
|
622533
|
-
import * as
|
|
622534
|
-
import * as
|
|
622845
|
+
import * as fs7 from "node:fs";
|
|
622846
|
+
import * as path9 from "node:path";
|
|
622535
622847
|
function createValidationContract(missionId, assertions) {
|
|
622536
622848
|
return {
|
|
622537
622849
|
missionId,
|
|
@@ -622711,33 +623023,33 @@ function checkMilestoneComplete(state, manifest, milestoneId) {
|
|
|
622711
623023
|
return true;
|
|
622712
623024
|
}
|
|
622713
623025
|
function writeFeaturesManifest(missionDir, manifest) {
|
|
622714
|
-
|
|
622715
|
-
const filePath =
|
|
622716
|
-
|
|
623026
|
+
fs7.mkdirSync(missionDir, { recursive: true });
|
|
623027
|
+
const filePath = path9.join(missionDir, "features.json");
|
|
623028
|
+
fs7.writeFileSync(filePath, JSON.stringify(manifest, null, 2), "utf-8");
|
|
622717
623029
|
}
|
|
622718
623030
|
function writeValidationContract(missionDir, contract) {
|
|
622719
|
-
|
|
622720
|
-
const filePath =
|
|
622721
|
-
|
|
623031
|
+
fs7.mkdirSync(missionDir, { recursive: true });
|
|
623032
|
+
const filePath = path9.join(missionDir, "validation-contract.md");
|
|
623033
|
+
fs7.writeFileSync(filePath, renderValidationContract(contract), "utf-8");
|
|
622722
623034
|
}
|
|
622723
623035
|
function writeValidationState(missionDir, state) {
|
|
622724
|
-
|
|
622725
|
-
const filePath =
|
|
622726
|
-
|
|
623036
|
+
fs7.mkdirSync(missionDir, { recursive: true });
|
|
623037
|
+
const filePath = path9.join(missionDir, "validation-state.json");
|
|
623038
|
+
fs7.writeFileSync(filePath, JSON.stringify(state, null, 2), "utf-8");
|
|
622727
623039
|
}
|
|
622728
623040
|
function readFeaturesManifest(missionDir) {
|
|
622729
|
-
const filePath =
|
|
622730
|
-
const content =
|
|
623041
|
+
const filePath = path9.join(missionDir, "features.json");
|
|
623042
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
622731
623043
|
return JSON.parse(content);
|
|
622732
623044
|
}
|
|
622733
623045
|
function readValidationState(missionDir) {
|
|
622734
|
-
const filePath =
|
|
622735
|
-
const content =
|
|
623046
|
+
const filePath = path9.join(missionDir, "validation-state.json");
|
|
623047
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
622736
623048
|
return JSON.parse(content);
|
|
622737
623049
|
}
|
|
622738
623050
|
function readValidationContract(missionDir) {
|
|
622739
|
-
const filePath =
|
|
622740
|
-
const content =
|
|
623051
|
+
const filePath = path9.join(missionDir, "validation-contract.md");
|
|
623052
|
+
const content = fs7.readFileSync(filePath, "utf-8");
|
|
622741
623053
|
const assertions = [];
|
|
622742
623054
|
const lines = content.split("\n");
|
|
622743
623055
|
let inTable = false;
|
|
@@ -623075,8 +623387,8 @@ var init_adversarialHandoffs = __esm({
|
|
|
623075
623387
|
});
|
|
623076
623388
|
|
|
623077
623389
|
// packages/orchestrator/dist/autoValidators.js
|
|
623078
|
-
import * as
|
|
623079
|
-
import * as
|
|
623390
|
+
import * as fs8 from "node:fs";
|
|
623391
|
+
import * as path10 from "node:path";
|
|
623080
623392
|
function generateScrutinyValidatorSkill() {
|
|
623081
623393
|
return `# Scrutiny Validator
|
|
623082
623394
|
|
|
@@ -623193,22 +623505,22 @@ function combineValidatorResults(missionId, milestoneId, scrutiny, userTesting)
|
|
|
623193
623505
|
};
|
|
623194
623506
|
}
|
|
623195
623507
|
function writeValidatorResults(missionDir, results) {
|
|
623196
|
-
|
|
623197
|
-
const filePath =
|
|
623198
|
-
|
|
623508
|
+
fs8.mkdirSync(missionDir, { recursive: true });
|
|
623509
|
+
const filePath = path10.join(missionDir, "validator-results.json");
|
|
623510
|
+
fs8.writeFileSync(filePath, JSON.stringify(results, null, 2), "utf-8");
|
|
623199
623511
|
}
|
|
623200
623512
|
function readValidatorResults(missionDir) {
|
|
623201
|
-
const filePath =
|
|
623202
|
-
const content =
|
|
623513
|
+
const filePath = path10.join(missionDir, "validator-results.json");
|
|
623514
|
+
const content = fs8.readFileSync(filePath, "utf-8");
|
|
623203
623515
|
return JSON.parse(content);
|
|
623204
623516
|
}
|
|
623205
623517
|
function writeValidatorSkill(missionDir, skillName, content) {
|
|
623206
|
-
const dir =
|
|
623207
|
-
if (!
|
|
623208
|
-
|
|
623518
|
+
const dir = path10.join(missionDir, "skills", "auto-injected");
|
|
623519
|
+
if (!fs8.existsSync(dir)) {
|
|
623520
|
+
fs8.mkdirSync(dir, { recursive: true });
|
|
623209
623521
|
}
|
|
623210
|
-
const filePath =
|
|
623211
|
-
|
|
623522
|
+
const filePath = path10.join(dir, `${skillName}.md`);
|
|
623523
|
+
fs8.writeFileSync(filePath, content, "utf-8");
|
|
623212
623524
|
}
|
|
623213
623525
|
var init_autoValidators = __esm({
|
|
623214
623526
|
"packages/orchestrator/dist/autoValidators.js"() {
|
|
@@ -623217,8 +623529,8 @@ var init_autoValidators = __esm({
|
|
|
623217
623529
|
});
|
|
623218
623530
|
|
|
623219
623531
|
// packages/orchestrator/dist/serviceManifest.js
|
|
623220
|
-
import * as
|
|
623221
|
-
import * as
|
|
623532
|
+
import * as fs9 from "node:fs";
|
|
623533
|
+
import * as path11 from "node:path";
|
|
623222
623534
|
function quoteScalar(value2) {
|
|
623223
623535
|
return JSON.stringify(value2);
|
|
623224
623536
|
}
|
|
@@ -623349,8 +623661,8 @@ function getCommand(manifest, name10) {
|
|
|
623349
623661
|
return cmd.command;
|
|
623350
623662
|
}
|
|
623351
623663
|
function writeServicesManifest(missionDir, manifest) {
|
|
623352
|
-
|
|
623353
|
-
const filePath =
|
|
623664
|
+
fs9.mkdirSync(missionDir, { recursive: true });
|
|
623665
|
+
const filePath = path11.join(missionDir, "services.yaml");
|
|
623354
623666
|
const lines = [
|
|
623355
623667
|
`missionId: ${manifest.missionId}`,
|
|
623356
623668
|
`createdAt: ${manifest.createdAt}`,
|
|
@@ -623398,11 +623710,11 @@ function writeServicesManifest(missionDir, manifest) {
|
|
|
623398
623710
|
lines.push(` min: ${manifest.ports.range.min}`);
|
|
623399
623711
|
lines.push(` max: ${manifest.ports.range.max}`);
|
|
623400
623712
|
lines.push(` offLimits: [${manifest.ports.offLimits.join(", ")}]`);
|
|
623401
|
-
|
|
623713
|
+
fs9.writeFileSync(filePath, lines.join("\n"), "utf-8");
|
|
623402
623714
|
}
|
|
623403
623715
|
function readServicesManifest(missionDir) {
|
|
623404
|
-
const filePath =
|
|
623405
|
-
const content =
|
|
623716
|
+
const filePath = path11.join(missionDir, "services.yaml");
|
|
623717
|
+
const content = fs9.readFileSync(filePath, "utf-8");
|
|
623406
623718
|
const services = [];
|
|
623407
623719
|
const commands = [];
|
|
623408
623720
|
let missionId = "";
|
|
@@ -624839,6 +625151,549 @@ var init_conversational_scrutiny = __esm({
|
|
|
624839
625151
|
}
|
|
624840
625152
|
});
|
|
624841
625153
|
|
|
625154
|
+
// packages/orchestrator/dist/featurePlanner.js
|
|
625155
|
+
import fs10 from "node:fs";
|
|
625156
|
+
import path12 from "node:path";
|
|
625157
|
+
function classifyKind(survey) {
|
|
625158
|
+
const files = survey.files ?? [];
|
|
625159
|
+
const newSym = (survey.newSymbols ?? []).length;
|
|
625160
|
+
const req3 = survey.request.toLowerCase();
|
|
625161
|
+
if (/\b(investigat|why does|how does|trace|understand|root cause|diagnos|explain)\b/.test(req3) && newSym === 0 && files.length <= 2) {
|
|
625162
|
+
return "investigation";
|
|
625163
|
+
}
|
|
625164
|
+
if (/\b(bug|fix|broken|regression|crash|incorrect|fails?|misbehav)/.test(req3) && newSym === 0) {
|
|
625165
|
+
return "bugfix";
|
|
625166
|
+
}
|
|
625167
|
+
if (/\b(refactor|restructure|rename|clean up|simplif|migrate|consolidate)\b/.test(req3) && newSym === 0) {
|
|
625168
|
+
return "refactor";
|
|
625169
|
+
}
|
|
625170
|
+
if (/\b(wir|connect|integrate|hook up|plumb|bridge|glue)\b/.test(req3) && files.length >= 2) {
|
|
625171
|
+
return "wiring";
|
|
625172
|
+
}
|
|
625173
|
+
if (newSym > 0 || /\b(new|create|add|implement|build|introduce|scaffold)\b/.test(req3)) {
|
|
625174
|
+
return "new-module";
|
|
625175
|
+
}
|
|
625176
|
+
return "new-module";
|
|
625177
|
+
}
|
|
625178
|
+
function guessKind(name10) {
|
|
625179
|
+
if (/^(I[A-Z]|.*Interface|.*Contract|.*Spec|.*Event|.*Meta|.*Config|.*State)$/.test(name10)) {
|
|
625180
|
+
return "interface";
|
|
625181
|
+
}
|
|
625182
|
+
if (/^(T|Type|.*Type)$/.test(name10))
|
|
625183
|
+
return "type";
|
|
625184
|
+
if (/^(E|Enum|.*Kind|.*Status|.*Mode)$/.test(name10))
|
|
625185
|
+
return "enum";
|
|
625186
|
+
if (/^[A-Z]/.test(name10))
|
|
625187
|
+
return "class";
|
|
625188
|
+
return "function";
|
|
625189
|
+
}
|
|
625190
|
+
function buildLockedContract(kind, survey) {
|
|
625191
|
+
const symbols = [];
|
|
625192
|
+
if (kind === "refactor") {
|
|
625193
|
+
for (const name10 of survey.existingSymbols ?? []) {
|
|
625194
|
+
symbols.push({ name: name10, kind: guessKind(name10), fields: [] });
|
|
625195
|
+
}
|
|
625196
|
+
} else if (kind === "new-module") {
|
|
625197
|
+
for (const name10 of survey.newSymbols ?? []) {
|
|
625198
|
+
symbols.push({ name: name10, kind: guessKind(name10), fields: [] });
|
|
625199
|
+
}
|
|
625200
|
+
}
|
|
625201
|
+
return { symbols };
|
|
625202
|
+
}
|
|
625203
|
+
function decomposeFeature(survey, kind) {
|
|
625204
|
+
const units = [];
|
|
625205
|
+
const evidenceRefs = claimEvidenceRefs(survey);
|
|
625206
|
+
const unresolvedQuestion = survey.unresolvedQuestions?.[0] ?? (evidenceRefs.length === 0 ? "Which current files, symbols, and tests govern this unit? Inspect them before proposing a mutation." : void 0);
|
|
625207
|
+
const returnContract = "Return the direct result with cited observations, relevant/changed paths, verification or blocker, and the next parent decision.";
|
|
625208
|
+
const withGrounding = (unit) => ({
|
|
625209
|
+
...unit,
|
|
625210
|
+
evidenceRefs,
|
|
625211
|
+
...unresolvedQuestion ? { unresolvedQuestion } : {},
|
|
625212
|
+
returnContract
|
|
625213
|
+
});
|
|
625214
|
+
if (kind === "new-module") {
|
|
625215
|
+
const syms = survey.newSymbols ?? [];
|
|
625216
|
+
if (syms.length === 0) {
|
|
625217
|
+
units.push(withGrounding({
|
|
625218
|
+
label: "Establish the module boundary and implement the evidenced unit",
|
|
625219
|
+
size: "large",
|
|
625220
|
+
detail: "Do not scaffold from the request alone. First identify the owning entry point, adjacent contract, and test surface from current evidence."
|
|
625221
|
+
}));
|
|
625222
|
+
} else {
|
|
625223
|
+
for (const name10 of syms) {
|
|
625224
|
+
units.push({
|
|
625225
|
+
...withGrounding({
|
|
625226
|
+
label: `Implement ${name10} within its evidenced owner`,
|
|
625227
|
+
size: "small",
|
|
625228
|
+
detail: "Confirm the symbol's owning module and contract before editing; do not infer a file path from the request label."
|
|
625229
|
+
}),
|
|
625230
|
+
expectedSymbols: [name10]
|
|
625231
|
+
});
|
|
625232
|
+
}
|
|
625233
|
+
}
|
|
625234
|
+
} else if (kind === "refactor") {
|
|
625235
|
+
units.push(withGrounding({
|
|
625236
|
+
label: "Refactor only the evidenced public surface",
|
|
625237
|
+
size: survey.files.length > 1 ? "large" : "small"
|
|
625238
|
+
}));
|
|
625239
|
+
} else if (kind === "bugfix") {
|
|
625240
|
+
units.push(withGrounding({
|
|
625241
|
+
label: "Reproduce the evidenced failure, make the smallest justified fix, and verify it",
|
|
625242
|
+
size: "small"
|
|
625243
|
+
}));
|
|
625244
|
+
} else if (kind === "wiring") {
|
|
625245
|
+
units.push(withGrounding({
|
|
625246
|
+
label: "Connect the evidenced module boundaries",
|
|
625247
|
+
size: survey.files.length > 2 ? "large" : "small"
|
|
625248
|
+
}));
|
|
625249
|
+
} else {
|
|
625250
|
+
units.push(withGrounding({
|
|
625251
|
+
label: "Investigate the evidence gap and report the next justified action",
|
|
625252
|
+
size: "small"
|
|
625253
|
+
}));
|
|
625254
|
+
}
|
|
625255
|
+
return units;
|
|
625256
|
+
}
|
|
625257
|
+
function claimEvidenceRefs(survey) {
|
|
625258
|
+
const declared = (survey.evidence ?? []).map((item) => item.ref.trim()).filter(Boolean).slice(0, 6);
|
|
625259
|
+
if (declared.length > 0)
|
|
625260
|
+
return declared;
|
|
625261
|
+
return survey.files.map((file) => `survey:file:${file.path}`).filter(Boolean).slice(0, 6);
|
|
625262
|
+
}
|
|
625263
|
+
function buildFeatureUnitRequest(input) {
|
|
625264
|
+
const evidence = (input.survey.evidence ?? []).filter((item) => !input.unit.evidenceRefs?.length || input.unit.evidenceRefs.includes(item.ref)).slice(0, 6);
|
|
625265
|
+
const fallbackEvidence = evidence.length > 0 ? evidence : input.survey.files.slice(0, 6).map((file) => ({
|
|
625266
|
+
ref: `survey:file:${file.path}`,
|
|
625267
|
+
detail: `${file.path}${file.role ? ` — ${file.role}` : ""}`,
|
|
625268
|
+
freshness: "unknown"
|
|
625269
|
+
}));
|
|
625270
|
+
const explicitOpenDeltas = [
|
|
625271
|
+
...input.unit.unresolvedQuestion ? [input.unit.unresolvedQuestion] : [],
|
|
625272
|
+
...input.survey.unresolvedQuestions ?? []
|
|
625273
|
+
].slice(0, 6);
|
|
625274
|
+
const lines = [
|
|
625275
|
+
"[CLAIM UNIT EVIDENCE BRIEF]",
|
|
625276
|
+
`Parent request: ${input.parentRequest.slice(0, 900)}`,
|
|
625277
|
+
`Requested unit: ${input.unit.label}`,
|
|
625278
|
+
`Why now: this unit was selected from the current claim discovery survey, not from a task label alone.`,
|
|
625279
|
+
`Open deltas: ${explicitOpenDeltas.length > 0 ? explicitOpenDeltas.join(" | ") : "none"}`,
|
|
625280
|
+
`Surviving blockers: ${input.unit.unresolvedQuestion ? "blocker carried from planner: open question" : "none"}`,
|
|
625281
|
+
`Evidence handles: ${fallbackEvidence.map((item) => item.ref).join(", ")}`,
|
|
625282
|
+
"Evidence:",
|
|
625283
|
+
...fallbackEvidence.length > 0 ? fallbackEvidence.map((item) => `- [${item.freshness ?? "unknown"}] ${item.ref}: ${item.detail.slice(0, 360)}`) : ["- No current code observation is available; discovery is required before mutation."],
|
|
625284
|
+
`Open question: ${input.unit.unresolvedQuestion ?? "none"}`,
|
|
625285
|
+
"Scope: stay within this unit and directly implicated code; do not broaden the claim without returning to the parent.",
|
|
625286
|
+
`Return contract: ${input.unit.returnContract ?? "Return evidence, verification or blocker, and the next parent decision."}`,
|
|
625287
|
+
"",
|
|
625288
|
+
"Work protocol: inspect the cited files/contracts first. Only mutate after a fresh observation identifies the exact target; if the evidence does not support a target, report the gap instead of fabricating one."
|
|
625289
|
+
];
|
|
625290
|
+
return lines.filter((line) => Boolean(line)).join("\n");
|
|
625291
|
+
}
|
|
625292
|
+
function renderSpecMarkdown(input) {
|
|
625293
|
+
const { kind, survey, lockedContract, completionContract, decomposition, prose } = input;
|
|
625294
|
+
const lines = [];
|
|
625295
|
+
lines.push(`# Claim Discovery Plan — ${kind}`);
|
|
625296
|
+
lines.push("");
|
|
625297
|
+
lines.push(`**Request:** ${survey.request}`);
|
|
625298
|
+
lines.push("");
|
|
625299
|
+
lines.push(`**Node kind:** \`${kind}\` (selected by CLASSIFY over the survey signals)`);
|
|
625300
|
+
lines.push("");
|
|
625301
|
+
if (prose) {
|
|
625302
|
+
lines.push(`## 1. Intent`);
|
|
625303
|
+
lines.push("");
|
|
625304
|
+
lines.push(prose.trim());
|
|
625305
|
+
lines.push("");
|
|
625306
|
+
}
|
|
625307
|
+
lines.push(`## 2. Survey (codebase as-is)`);
|
|
625308
|
+
lines.push("");
|
|
625309
|
+
if (survey.files.length > 0) {
|
|
625310
|
+
for (const f2 of survey.files) {
|
|
625311
|
+
const refs = f2.lineRefs?.length ? `:${f2.lineRefs.join(",")}` : "";
|
|
625312
|
+
lines.push(`- \`${f2.path}${refs}\`${f2.role ? ` — ${f2.role}` : ""}`);
|
|
625313
|
+
}
|
|
625314
|
+
} else {
|
|
625315
|
+
lines.push("- (no files enumerated in survey)");
|
|
625316
|
+
}
|
|
625317
|
+
if (survey.evidence?.length) {
|
|
625318
|
+
for (const item of survey.evidence.slice(0, 8)) {
|
|
625319
|
+
lines.push(`- evidence [${item.freshness ?? "unknown"}] ${item.ref}: ${item.detail}`);
|
|
625320
|
+
}
|
|
625321
|
+
}
|
|
625322
|
+
if (survey.unresolvedQuestions?.length) {
|
|
625323
|
+
lines.push(`- unresolved: ${survey.unresolvedQuestions.join("; ")}`);
|
|
625324
|
+
}
|
|
625325
|
+
lines.push(`- new symbols: ${(survey.newSymbols ?? []).join(", ") || "none"}`);
|
|
625326
|
+
lines.push(`- public surface changes: ${survey.publicSurfaceChanges ? "yes" : "no"}`);
|
|
625327
|
+
lines.push(`- tests exist: ${survey.testsExist ? "yes" : "no"}`);
|
|
625328
|
+
lines.push("");
|
|
625329
|
+
lines.push(`## 3. Locked contract (executable gate)`);
|
|
625330
|
+
lines.push("");
|
|
625331
|
+
if (lockedContract.symbols.length === 0) {
|
|
625332
|
+
lines.push("- (no locked symbols for this kind — disciplined but permissive)");
|
|
625333
|
+
} else {
|
|
625334
|
+
for (const s2 of lockedContract.symbols) {
|
|
625335
|
+
lines.push(`- \`${s2.kind} ${s2.name}\``);
|
|
625336
|
+
}
|
|
625337
|
+
}
|
|
625338
|
+
lines.push("");
|
|
625339
|
+
lines.push(`## 4. Definition of done (CompletionContract)`);
|
|
625340
|
+
lines.push("");
|
|
625341
|
+
lines.push(`- goal: ${completionContract.goalSummary || "(none)"}`);
|
|
625342
|
+
for (const p2 of completionContract.phases ?? []) {
|
|
625343
|
+
lines.push(`- phase: ${p2.label}`);
|
|
625344
|
+
}
|
|
625345
|
+
lines.push("");
|
|
625346
|
+
lines.push(`## 5. Decomposition (SPLIT seed)`);
|
|
625347
|
+
lines.push("");
|
|
625348
|
+
for (const u of decomposition) {
|
|
625349
|
+
lines.push(`- [${u.size}] ${u.label}${u.expectedSymbols?.length ? ` (symbols: ${u.expectedSymbols.join(", ")})` : ""}${u.evidenceRefs?.length ? ` [evidence: ${u.evidenceRefs.join(", ")}]` : ""}`);
|
|
625350
|
+
}
|
|
625351
|
+
lines.push("");
|
|
625352
|
+
lines.push(`## 6. Verification bar`);
|
|
625353
|
+
lines.push("");
|
|
625354
|
+
lines.push("- planner emits real artefacts (this file + locked contract + completion contract)");
|
|
625355
|
+
lines.push("- approval gate blocks before any source edit");
|
|
625356
|
+
lines.push("- WO-6 executor gate activates on locked symbols");
|
|
625357
|
+
lines.push("- recursion + eviction keep context bounded");
|
|
625358
|
+
lines.push("- scope token re-prompts on out-of-scope work");
|
|
625359
|
+
lines.push("");
|
|
625360
|
+
lines.push(`## 7. Handoff notes`);
|
|
625361
|
+
lines.push("");
|
|
625362
|
+
lines.push("- Compose, do not rebuild: this plan reuses spec-gate + completionContract primitives.");
|
|
625363
|
+
lines.push("- Fail-closed: if planning errors, the run falls back to the general agentic loop.");
|
|
625364
|
+
lines.push("");
|
|
625365
|
+
return lines.join("\n");
|
|
625366
|
+
}
|
|
625367
|
+
async function planFeature(survey, options2 = {}) {
|
|
625368
|
+
const kind = classifyKind(survey);
|
|
625369
|
+
const lockedContract = buildLockedContract(kind, survey);
|
|
625370
|
+
const completionContract = inferCompletionContractFromTexts([survey.request, ...survey.rawTexts ?? [], ...survey.signals ?? []], survey.request);
|
|
625371
|
+
const decomposition = decomposeFeature(survey, kind);
|
|
625372
|
+
let prose = "";
|
|
625373
|
+
try {
|
|
625374
|
+
if (options2.proseGenerator) {
|
|
625375
|
+
prose = await options2.proseGenerator({ request: survey.request, kind, survey });
|
|
625376
|
+
}
|
|
625377
|
+
} catch {
|
|
625378
|
+
prose = "";
|
|
625379
|
+
}
|
|
625380
|
+
const specMarkdown = renderSpecMarkdown({
|
|
625381
|
+
kind,
|
|
625382
|
+
survey,
|
|
625383
|
+
lockedContract,
|
|
625384
|
+
completionContract,
|
|
625385
|
+
decomposition,
|
|
625386
|
+
prose
|
|
625387
|
+
});
|
|
625388
|
+
return { kind, specMarkdown, lockedContract, completionContract, decomposition };
|
|
625389
|
+
}
|
|
625390
|
+
function persistPlannerArtefacts(rootId, artefact, stateDir, survey) {
|
|
625391
|
+
try {
|
|
625392
|
+
const dir = path12.join(stateDir, "feature-tree", rootId);
|
|
625393
|
+
fs10.mkdirSync(dir, { recursive: true });
|
|
625394
|
+
fs10.writeFileSync(path12.join(dir, "spec.md"), artefact.specMarkdown, "utf8");
|
|
625395
|
+
fs10.writeFileSync(path12.join(dir, "locked-contract.json"), JSON.stringify(artefact.lockedContract, null, 2), "utf8");
|
|
625396
|
+
fs10.writeFileSync(path12.join(dir, "completion-contract.json"), JSON.stringify(artefact.completionContract, null, 2), "utf8");
|
|
625397
|
+
if (survey) {
|
|
625398
|
+
fs10.writeFileSync(path12.join(dir, "claim-discovery-survey.json"), JSON.stringify({
|
|
625399
|
+
request: survey.request,
|
|
625400
|
+
requestSource: "bound_workspace_inventory",
|
|
625401
|
+
files: survey.files,
|
|
625402
|
+
unresolvedQuestions: survey.unresolvedQuestions ?? [],
|
|
625403
|
+
evidenceRefs: survey.evidence?.map((item) => item.ref) ?? [],
|
|
625404
|
+
signals: survey.signals ?? [],
|
|
625405
|
+
requiredVerificationCommands: survey.requiredVerificationCommands ?? [],
|
|
625406
|
+
testsExist: survey.testsExist ?? false,
|
|
625407
|
+
publicSurfaceChanges: survey.publicSurfaceChanges ?? false,
|
|
625408
|
+
newSymbols: survey.newSymbols ?? [],
|
|
625409
|
+
existingSymbols: survey.existingSymbols ?? []
|
|
625410
|
+
}, null, 2), "utf8");
|
|
625411
|
+
}
|
|
625412
|
+
} catch {
|
|
625413
|
+
}
|
|
625414
|
+
}
|
|
625415
|
+
var classifyClaimKind, buildClaimPlan, buildClaimUnitRequest, buildClaimLockedContract;
|
|
625416
|
+
var init_featurePlanner = __esm({
|
|
625417
|
+
"packages/orchestrator/dist/featurePlanner.js"() {
|
|
625418
|
+
"use strict";
|
|
625419
|
+
init_completionContract();
|
|
625420
|
+
classifyClaimKind = classifyKind;
|
|
625421
|
+
buildClaimPlan = planFeature;
|
|
625422
|
+
buildClaimUnitRequest = buildFeatureUnitRequest;
|
|
625423
|
+
buildClaimLockedContract = buildLockedContract;
|
|
625424
|
+
}
|
|
625425
|
+
});
|
|
625426
|
+
|
|
625427
|
+
// packages/orchestrator/dist/featureApprovalGate.js
|
|
625428
|
+
function mintScopeToken(input) {
|
|
625429
|
+
return {
|
|
625430
|
+
rootId: input.rootId,
|
|
625431
|
+
files: [...input.files ?? []],
|
|
625432
|
+
symbols: input.lockedContract.symbols.map((s2) => s2.name),
|
|
625433
|
+
nodeKinds: input.nodeKinds ?? ["new-module", "refactor", "bugfix", "wiring", "investigation"],
|
|
625434
|
+
depthCap: input.depthCap
|
|
625435
|
+
};
|
|
625436
|
+
}
|
|
625437
|
+
function isWithinScope(input) {
|
|
625438
|
+
const { token } = input;
|
|
625439
|
+
if (typeof input.depth === "number" && input.depth > token.depthCap) {
|
|
625440
|
+
return false;
|
|
625441
|
+
}
|
|
625442
|
+
if (input.nodeKind && !token.nodeKinds.includes(input.nodeKind)) {
|
|
625443
|
+
return false;
|
|
625444
|
+
}
|
|
625445
|
+
if (input.newSymbol && !token.symbols.includes(input.newSymbol)) {
|
|
625446
|
+
return false;
|
|
625447
|
+
}
|
|
625448
|
+
if (input.file) {
|
|
625449
|
+
const file = input.file;
|
|
625450
|
+
const allowed = token.files.some((f2) => {
|
|
625451
|
+
if (f2 === file)
|
|
625452
|
+
return true;
|
|
625453
|
+
if (f2.endsWith("/") && file.startsWith(f2))
|
|
625454
|
+
return true;
|
|
625455
|
+
if (f2.includes("*") && globMatch(f2, file))
|
|
625456
|
+
return true;
|
|
625457
|
+
return false;
|
|
625458
|
+
});
|
|
625459
|
+
if (!allowed)
|
|
625460
|
+
return false;
|
|
625461
|
+
}
|
|
625462
|
+
return true;
|
|
625463
|
+
}
|
|
625464
|
+
function globMatch(pattern, value2) {
|
|
625465
|
+
const re = new RegExp("^" + pattern.replace(/[.+?^${}()|[\]\\]/g, "\\$&").replace(/\*/g, ".*") + "$");
|
|
625466
|
+
return re.test(value2);
|
|
625467
|
+
}
|
|
625468
|
+
async function requestApproval(req3, ask2, options2 = {}) {
|
|
625469
|
+
let decision2;
|
|
625470
|
+
try {
|
|
625471
|
+
const raw = await ask2(req3);
|
|
625472
|
+
decision2 = raw === "approve" || raw === "edit" || raw === "reject" ? raw : "reject";
|
|
625473
|
+
} catch {
|
|
625474
|
+
decision2 = "reject";
|
|
625475
|
+
}
|
|
625476
|
+
if (decision2 === "approve") {
|
|
625477
|
+
const token = mintScopeToken({
|
|
625478
|
+
rootId: req3.rootId,
|
|
625479
|
+
lockedContract: req3.lockedContract,
|
|
625480
|
+
decomposition: req3.decomposition,
|
|
625481
|
+
depthCap: req3.depthCap,
|
|
625482
|
+
files: options2.files,
|
|
625483
|
+
nodeKinds: options2.nodeKinds
|
|
625484
|
+
});
|
|
625485
|
+
return { decision: decision2, token };
|
|
625486
|
+
}
|
|
625487
|
+
return { decision: decision2 };
|
|
625488
|
+
}
|
|
625489
|
+
var mintClaimScopeToken, isWithinClaimScope, requestClaimApproval;
|
|
625490
|
+
var init_featureApprovalGate = __esm({
|
|
625491
|
+
"packages/orchestrator/dist/featureApprovalGate.js"() {
|
|
625492
|
+
"use strict";
|
|
625493
|
+
mintClaimScopeToken = mintScopeToken;
|
|
625494
|
+
isWithinClaimScope = isWithinScope;
|
|
625495
|
+
requestClaimApproval = requestApproval;
|
|
625496
|
+
}
|
|
625497
|
+
});
|
|
625498
|
+
|
|
625499
|
+
// packages/orchestrator/dist/featureNode.js
|
|
625500
|
+
import fs11 from "node:fs";
|
|
625501
|
+
import path13 from "node:path";
|
|
625502
|
+
function treePath(stateDir, rootId) {
|
|
625503
|
+
return path13.join(stateDir, "feature-tree", `${rootId}.json`);
|
|
625504
|
+
}
|
|
625505
|
+
function saveFeatureTree(stateDir, rootId, nodes) {
|
|
625506
|
+
try {
|
|
625507
|
+
const file = treePath(stateDir, rootId);
|
|
625508
|
+
fs11.mkdirSync(path13.dirname(file), { recursive: true });
|
|
625509
|
+
fs11.writeFileSync(file, JSON.stringify(nodes, null, 2), "utf8");
|
|
625510
|
+
} catch {
|
|
625511
|
+
}
|
|
625512
|
+
}
|
|
625513
|
+
function loadFeatureTree(stateDir, rootId) {
|
|
625514
|
+
try {
|
|
625515
|
+
const file = treePath(stateDir, rootId);
|
|
625516
|
+
if (!fs11.existsSync(file))
|
|
625517
|
+
return null;
|
|
625518
|
+
const raw = JSON.parse(fs11.readFileSync(file, "utf8"));
|
|
625519
|
+
return raw && typeof raw === "object" ? raw : null;
|
|
625520
|
+
} catch {
|
|
625521
|
+
return null;
|
|
625522
|
+
}
|
|
625523
|
+
}
|
|
625524
|
+
function newNodeId(depth, seed) {
|
|
625525
|
+
const h = String(Math.abs(hashString2(seed)) % 1e9).padStart(9, "0");
|
|
625526
|
+
return `fn-d${depth}-${h}`;
|
|
625527
|
+
}
|
|
625528
|
+
function hashString2(s2) {
|
|
625529
|
+
let h = 0;
|
|
625530
|
+
for (let i2 = 0; i2 < s2.length; i2++)
|
|
625531
|
+
h = h * 31 + s2.charCodeAt(i2) | 0;
|
|
625532
|
+
return h;
|
|
625533
|
+
}
|
|
625534
|
+
async function evictNode(node, ctx3, transcript) {
|
|
625535
|
+
try {
|
|
625536
|
+
await runTodoChunker({
|
|
625537
|
+
inputs: {
|
|
625538
|
+
todoId: node.id,
|
|
625539
|
+
todoContent: node.request,
|
|
625540
|
+
turnRange: [0, 0],
|
|
625541
|
+
transcript: transcript || node.request,
|
|
625542
|
+
toolCalls: [],
|
|
625543
|
+
workingDirectory: ctx3.workingDirectory,
|
|
625544
|
+
sessionId: ctx3.sessionId
|
|
625545
|
+
},
|
|
625546
|
+
callable: ctx3.summarizer ?? (async () => "")
|
|
625547
|
+
});
|
|
625548
|
+
} catch {
|
|
625549
|
+
}
|
|
625550
|
+
}
|
|
625551
|
+
async function execUnit(unit, node, ctx3, contract, maxRegenerate) {
|
|
625552
|
+
let result = await ctx3.executeUnit(unit, node);
|
|
625553
|
+
if (!result.ok)
|
|
625554
|
+
return false;
|
|
625555
|
+
const expected = unit.expectedSymbols ?? [];
|
|
625556
|
+
if (expected.length === 0) {
|
|
625557
|
+
return true;
|
|
625558
|
+
}
|
|
625559
|
+
for (let attempt = 0; attempt <= maxRegenerate; attempt++) {
|
|
625560
|
+
if (!result.path || result.source === void 0)
|
|
625561
|
+
return false;
|
|
625562
|
+
const verdict = evaluateExecutorStep({
|
|
625563
|
+
unit: { path: result.path, source: result.source },
|
|
625564
|
+
contract,
|
|
625565
|
+
expectedSymbols: expected
|
|
625566
|
+
});
|
|
625567
|
+
if (verdict.decision === "accept")
|
|
625568
|
+
return true;
|
|
625569
|
+
if (verdict.decision === "replan")
|
|
625570
|
+
return false;
|
|
625571
|
+
result = await ctx3.executeUnit(unit, node);
|
|
625572
|
+
if (!result.ok)
|
|
625573
|
+
return false;
|
|
625574
|
+
}
|
|
625575
|
+
return false;
|
|
625576
|
+
}
|
|
625577
|
+
async function runFeatureNode(node, ctx3, options2, tree2 = {}) {
|
|
625578
|
+
const maxRegenerate = options2.maxRegenerate ?? 2;
|
|
625579
|
+
tree2[node.id] = node;
|
|
625580
|
+
try {
|
|
625581
|
+
const artefact = await planFeature(options2.survey, {
|
|
625582
|
+
proseGenerator: options2.proseGenerator
|
|
625583
|
+
});
|
|
625584
|
+
node.kind = artefact.kind;
|
|
625585
|
+
if (ctx3.onPlan) {
|
|
625586
|
+
try {
|
|
625587
|
+
await ctx3.onPlan(artefact);
|
|
625588
|
+
} catch {
|
|
625589
|
+
}
|
|
625590
|
+
}
|
|
625591
|
+
persistPlannerArtefacts(ctx3.rootId, artefact, ctx3.stateDir, options2.survey);
|
|
625592
|
+
const mustAsk = node.depth === 0 || !node.scopeToken;
|
|
625593
|
+
if (mustAsk && ctx3.askApproval) {
|
|
625594
|
+
node.status = "awaiting_approval";
|
|
625595
|
+
const outcome = await requestApproval({
|
|
625596
|
+
rootId: ctx3.rootId,
|
|
625597
|
+
request: node.request,
|
|
625598
|
+
specMarkdown: artefact.specMarkdown,
|
|
625599
|
+
lockedContract: artefact.lockedContract,
|
|
625600
|
+
decomposition: artefact.decomposition,
|
|
625601
|
+
depthCap: ctx3.depthCap
|
|
625602
|
+
}, ctx3.askApproval, { files: options2.survey.files.map((f2) => f2.path) });
|
|
625603
|
+
if (outcome.decision !== "approve") {
|
|
625604
|
+
node.status = outcome.decision === "edit" ? "planned" : "rejected";
|
|
625605
|
+
saveFeatureTree(ctx3.stateDir, ctx3.rootId, tree2);
|
|
625606
|
+
return node;
|
|
625607
|
+
}
|
|
625608
|
+
node.scopeToken = outcome.token;
|
|
625609
|
+
}
|
|
625610
|
+
node.status = "approved";
|
|
625611
|
+
node.status = "executing";
|
|
625612
|
+
let allOk = true;
|
|
625613
|
+
for (const unit of artefact.decomposition) {
|
|
625614
|
+
if (unit.size === "large" && node.depth < ctx3.depthCap) {
|
|
625615
|
+
const childId = newNodeId(node.depth + 1, unit.label + node.id);
|
|
625616
|
+
const childRequest = buildFeatureUnitRequest({
|
|
625617
|
+
unit,
|
|
625618
|
+
parentRequest: node.request,
|
|
625619
|
+
survey: options2.survey
|
|
625620
|
+
});
|
|
625621
|
+
const child = {
|
|
625622
|
+
id: childId,
|
|
625623
|
+
parentId: node.id,
|
|
625624
|
+
depth: node.depth + 1,
|
|
625625
|
+
request: childRequest,
|
|
625626
|
+
kind: artefact.kind,
|
|
625627
|
+
status: "planned",
|
|
625628
|
+
scopeToken: node.scopeToken,
|
|
625629
|
+
children: []
|
|
625630
|
+
};
|
|
625631
|
+
node.children.push(childId);
|
|
625632
|
+
const childSurvey = {
|
|
625633
|
+
...options2.survey,
|
|
625634
|
+
request: child.request
|
|
625635
|
+
};
|
|
625636
|
+
const childCtx = {
|
|
625637
|
+
...ctx3,
|
|
625638
|
+
// children inherit the token; re-prompt only if they exceed scope
|
|
625639
|
+
askApproval: (req3) => isWithinScope({
|
|
625640
|
+
token: node.scopeToken,
|
|
625641
|
+
depth: node.depth + 1,
|
|
625642
|
+
nodeKind: artefact.kind
|
|
625643
|
+
}) ? "approve" : ctx3.askApproval(req3)
|
|
625644
|
+
};
|
|
625645
|
+
const res = await runFeatureNode(child, childCtx, { ...options2, survey: childSurvey }, tree2);
|
|
625646
|
+
if (res.status !== "completed")
|
|
625647
|
+
allOk = false;
|
|
625648
|
+
await evictNode(child, ctx3, child.request);
|
|
625649
|
+
} else {
|
|
625650
|
+
const ok3 = await execUnit(unit, node, ctx3, artefact.lockedContract, maxRegenerate);
|
|
625651
|
+
if (!ok3)
|
|
625652
|
+
allOk = false;
|
|
625653
|
+
}
|
|
625654
|
+
}
|
|
625655
|
+
if (allOk) {
|
|
625656
|
+
node.status = "completed";
|
|
625657
|
+
} else {
|
|
625658
|
+
node.status = "failed";
|
|
625659
|
+
}
|
|
625660
|
+
saveFeatureTree(ctx3.stateDir, ctx3.rootId, tree2);
|
|
625661
|
+
return node;
|
|
625662
|
+
} catch {
|
|
625663
|
+
if (ctx3.runGeneralLoop) {
|
|
625664
|
+
await ctx3.runGeneralLoop(node.request);
|
|
625665
|
+
node.status = "completed";
|
|
625666
|
+
} else {
|
|
625667
|
+
node.status = "failed";
|
|
625668
|
+
}
|
|
625669
|
+
saveFeatureTree(ctx3.stateDir, ctx3.rootId, tree2);
|
|
625670
|
+
return node;
|
|
625671
|
+
}
|
|
625672
|
+
}
|
|
625673
|
+
function createRootFeatureNode(request) {
|
|
625674
|
+
return {
|
|
625675
|
+
id: newNodeId(0, request),
|
|
625676
|
+
parentId: null,
|
|
625677
|
+
depth: 0,
|
|
625678
|
+
request,
|
|
625679
|
+
kind: "new-module",
|
|
625680
|
+
status: "planned",
|
|
625681
|
+
children: []
|
|
625682
|
+
};
|
|
625683
|
+
}
|
|
625684
|
+
var runClaimNode, createClaimRootNode;
|
|
625685
|
+
var init_featureNode = __esm({
|
|
625686
|
+
"packages/orchestrator/dist/featureNode.js"() {
|
|
625687
|
+
"use strict";
|
|
625688
|
+
init_featurePlanner();
|
|
625689
|
+
init_featureApprovalGate();
|
|
625690
|
+
init_spec_gate();
|
|
625691
|
+
init_todo_context_chunker();
|
|
625692
|
+
runClaimNode = runFeatureNode;
|
|
625693
|
+
createClaimRootNode = createRootFeatureNode;
|
|
625694
|
+
}
|
|
625695
|
+
});
|
|
625696
|
+
|
|
624842
625697
|
// packages/orchestrator/dist/causalAblation.js
|
|
624843
625698
|
function _identifyAblationTargets(messages2, dimension) {
|
|
624844
625699
|
const targets = [];
|
|
@@ -625364,6 +626219,9 @@ __export(dist_exports3, {
|
|
|
625364
626219
|
buildAgentDeploymentPatternSummary: () => buildAgentDeploymentPatternSummary,
|
|
625365
626220
|
buildAgentNotification: () => buildAgentNotification,
|
|
625366
626221
|
buildAgentTypeSummary: () => buildAgentTypeSummary,
|
|
626222
|
+
buildClaimLockedContract: () => buildClaimLockedContract,
|
|
626223
|
+
buildClaimPlan: () => buildClaimPlan,
|
|
626224
|
+
buildClaimUnitRequest: () => buildClaimUnitRequest,
|
|
625367
626225
|
buildCompletionFinalizationRecord: () => buildCompletionFinalizationRecord,
|
|
625368
626226
|
buildCompletionScenarioDecomposition: () => buildCompletionScenarioDecomposition,
|
|
625369
626227
|
buildCoordinatorPrompt: () => buildCoordinatorPrompt,
|
|
@@ -625390,6 +626248,7 @@ __export(dist_exports3, {
|
|
|
625390
626248
|
chooseCheapModelRoute: () => chooseCheapModelRoute,
|
|
625391
626249
|
claimAssertion: () => claimAssertion,
|
|
625392
626250
|
classifyBreadth: () => classifyBreadth,
|
|
626251
|
+
classifyClaimKind: () => classifyClaimKind,
|
|
625393
626252
|
classifyCompletionClaim: () => classifyCompletionClaim,
|
|
625394
626253
|
classifyHandoff: () => classifyHandoff,
|
|
625395
626254
|
classifyKind: () => classifyKind,
|
|
@@ -625424,6 +626283,7 @@ __export(dist_exports3, {
|
|
|
625424
626283
|
countDefinitions: () => countDefinitions,
|
|
625425
626284
|
createAppState: () => createAppState,
|
|
625426
626285
|
createChildAbortController: () => createChildAbortController,
|
|
626286
|
+
createClaimRootNode: () => createClaimRootNode,
|
|
625427
626287
|
createCompletionLedger: () => createCompletionLedger,
|
|
625428
626288
|
createDefaultContextEngine: () => createDefaultContextEngine,
|
|
625429
626289
|
createFeaturesManifest: () => createFeaturesManifest,
|
|
@@ -625517,6 +626377,7 @@ __export(dist_exports3, {
|
|
|
625517
626377
|
isSuccessfulRunFinished: () => isSuccessfulRunFinished,
|
|
625518
626378
|
isTerminalRunEvent: () => isTerminalRunEvent,
|
|
625519
626379
|
isTerminalTaskStatus: () => isTerminalTaskStatus,
|
|
626380
|
+
isWithinClaimScope: () => isWithinClaimScope,
|
|
625520
626381
|
isWithinScope: () => isWithinScope,
|
|
625521
626382
|
legacyAgenticEventToRunEvent: () => legacyAgenticEventToRunEvent,
|
|
625522
626383
|
listContextWindowDumps: () => listContextWindowDumps,
|
|
@@ -625533,6 +626394,7 @@ __export(dist_exports3, {
|
|
|
625533
626394
|
measureContextSNR: () => measureContextSNR,
|
|
625534
626395
|
memoryCosine: () => cosine4,
|
|
625535
626396
|
mergeDigests: () => mergeDigests,
|
|
626397
|
+
mintClaimScopeToken: () => mintClaimScopeToken,
|
|
625536
626398
|
mintScopeToken: () => mintScopeToken,
|
|
625537
626399
|
normalizeCompletionKey: () => normalizeCompletionKey,
|
|
625538
626400
|
normalizeMemoryCompilationPlanAudit: () => normalizeMemoryCompilationPlanAudit,
|
|
@@ -625551,6 +626413,7 @@ __export(dist_exports3, {
|
|
|
625551
626413
|
persistAgentTaskSidecar: () => persistAgentTaskSidecar,
|
|
625552
626414
|
persistPlannerArtefacts: () => persistPlannerArtefacts,
|
|
625553
626415
|
planAgentDeploymentPattern: () => planAgentDeploymentPattern,
|
|
626416
|
+
planClaim: () => buildClaimPlan,
|
|
625554
626417
|
planConsolidation: () => planConsolidation,
|
|
625555
626418
|
planFeature: () => planFeature,
|
|
625556
626419
|
prepareCompletionFinalization: () => prepareCompletionFinalization,
|
|
@@ -625598,6 +626461,7 @@ __export(dist_exports3, {
|
|
|
625598
626461
|
renderValidationContract: () => renderValidationContract,
|
|
625599
626462
|
renderWorkerSkill: () => renderWorkerSkill,
|
|
625600
626463
|
requestApproval: () => requestApproval,
|
|
626464
|
+
requestClaimApproval: () => requestClaimApproval,
|
|
625601
626465
|
resetPluginRegistry: () => resetPluginRegistry,
|
|
625602
626466
|
resolveAgentTools: () => resolveAgentTools,
|
|
625603
626467
|
resolveDefaultPoolConfig: () => resolveDefaultPoolConfig,
|
|
@@ -625605,6 +626469,7 @@ __export(dist_exports3, {
|
|
|
625605
626469
|
resolveModelProfile: () => resolveModelProfile,
|
|
625606
626470
|
restoreAgentTasks: () => restoreAgentTasks,
|
|
625607
626471
|
retentionStrength: () => retentionStrength,
|
|
626472
|
+
runClaimNode: () => runClaimNode,
|
|
625608
626473
|
runFeatureNode: () => runFeatureNode,
|
|
625609
626474
|
runMemoryCompilerReplay: () => runMemoryCompilerReplay,
|
|
625610
626475
|
runMemoryCompilerReplaySuite: () => runMemoryCompilerReplaySuite,
|
|
@@ -772018,6 +772883,8 @@ async function runCommand2(opts, config) {
|
|
|
772018
772883
|
await runBackground(opts.task, mergedConfig, opts);
|
|
772019
772884
|
} else if (opts.json) {
|
|
772020
772885
|
await runJson(opts.task, mergedConfig, opts.repoPath);
|
|
772886
|
+
} else if (opts.verbose) {
|
|
772887
|
+
await runConsole(opts.task, mergedConfig, opts.repoPath);
|
|
772021
772888
|
} else {
|
|
772022
772889
|
await runWithTUI(opts.task, mergedConfig, opts.repoPath);
|
|
772023
772890
|
if (shouldForceSingleRunExit()) process.exit(0);
|
|
@@ -772117,6 +772984,95 @@ async function runJson(task, config, repoPath2) {
|
|
|
772117
772984
|
if (result.exitCode !== 0) process.exit(result.exitCode);
|
|
772118
772985
|
if (shouldForceJsonExit()) process.exit(0);
|
|
772119
772986
|
}
|
|
772987
|
+
async function runConsole(task, config, repoPath2) {
|
|
772988
|
+
const startTime = Date.now();
|
|
772989
|
+
const origWrite = process.stdout.write.bind(process.stdout);
|
|
772990
|
+
const origStderr = process.stderr.write.bind(process.stderr);
|
|
772991
|
+
process.stdout.write = (() => true);
|
|
772992
|
+
process.stderr.write = (() => true);
|
|
772993
|
+
let runnerResult = null;
|
|
772994
|
+
let toolCount = 0;
|
|
772995
|
+
const fmtArgs = (args) => {
|
|
772996
|
+
if (args === void 0 || args === null) return "";
|
|
772997
|
+
if (typeof args !== "object") return ` (${String(args)})`;
|
|
772998
|
+
const entries = Object.entries(args);
|
|
772999
|
+
if (entries.length === 0) return "";
|
|
773000
|
+
const parts = entries.map(([k, v]) => {
|
|
773001
|
+
let s2;
|
|
773002
|
+
if (typeof v === "string") {
|
|
773003
|
+
s2 = v.length > 200 ? `${v.slice(0, 197)}…` : v;
|
|
773004
|
+
} else if (v === void 0 || v === null) {
|
|
773005
|
+
s2 = String(v);
|
|
773006
|
+
} else {
|
|
773007
|
+
try {
|
|
773008
|
+
s2 = JSON.stringify(v);
|
|
773009
|
+
} catch {
|
|
773010
|
+
s2 = String(v);
|
|
773011
|
+
}
|
|
773012
|
+
if (s2.length > 200) s2 = `${s2.slice(0, 197)}…`;
|
|
773013
|
+
}
|
|
773014
|
+
return `${k}=${s2}`;
|
|
773015
|
+
});
|
|
773016
|
+
return ` (${parts.join(", ")})`;
|
|
773017
|
+
};
|
|
773018
|
+
const emit2 = (line) => {
|
|
773019
|
+
origWrite(line + "\n");
|
|
773020
|
+
};
|
|
773021
|
+
try {
|
|
773022
|
+
emit2(`▶ Task: ${task}`);
|
|
773023
|
+
await runWithTUI(task, config, repoPath2, {
|
|
773024
|
+
onToolCall: (tool, args) => {
|
|
773025
|
+
toolCount += 1;
|
|
773026
|
+
emit2(`[${toolCount}] 🔧 ${tool}${fmtArgs(args)}`);
|
|
773027
|
+
},
|
|
773028
|
+
onToolResult: (tool, output, success) => {
|
|
773029
|
+
const redacted = getSecretRedactor().redactText(output || "");
|
|
773030
|
+
const capped = redacted && redacted.length > 400 ? redacted.slice(0, 380) + `… [+${redacted.length - 380} chars]` : redacted;
|
|
773031
|
+
const mark = success ? "✓" : "✗";
|
|
773032
|
+
emit2(` ${mark} ${tool} → ${capped || "(no output)"}`);
|
|
773033
|
+
},
|
|
773034
|
+
onStatus: (content) => {
|
|
773035
|
+
if (content && content.trim()) {
|
|
773036
|
+
emit2(`ℹ ${content.trim()}`);
|
|
773037
|
+
}
|
|
773038
|
+
},
|
|
773039
|
+
onAssistantText: (text2) => {
|
|
773040
|
+
const clean6 = sanitizeAgentOutputForUser(text2).trim();
|
|
773041
|
+
if (clean6) emit2(`💬 ${clean6.replace(/\n/g, "\n ")}`);
|
|
773042
|
+
},
|
|
773043
|
+
onRunResult: (result) => {
|
|
773044
|
+
runnerResult = {
|
|
773045
|
+
status: result.status,
|
|
773046
|
+
completed: result.completed,
|
|
773047
|
+
summary: result.summary,
|
|
773048
|
+
turns: result.turns,
|
|
773049
|
+
toolCalls: result.toolCalls
|
|
773050
|
+
};
|
|
773051
|
+
}
|
|
773052
|
+
});
|
|
773053
|
+
} catch (err) {
|
|
773054
|
+
process.stdout.write = origWrite;
|
|
773055
|
+
process.stderr.write = origStderr;
|
|
773056
|
+
emit2(`✗ Error: ${err instanceof Error ? err.message : String(err)}`);
|
|
773057
|
+
if (config.verbose && err instanceof Error && err.stack) {
|
|
773058
|
+
emit2(err.stack);
|
|
773059
|
+
}
|
|
773060
|
+
process.exit(1);
|
|
773061
|
+
}
|
|
773062
|
+
process.stdout.write = origWrite;
|
|
773063
|
+
process.stderr.write = origStderr;
|
|
773064
|
+
const durationMs = Date.now() - startTime;
|
|
773065
|
+
const rr = runnerResult;
|
|
773066
|
+
const status = rr?.completed ? "completed" : rr?.status ?? "completed";
|
|
773067
|
+
emit2("");
|
|
773068
|
+
emit2(
|
|
773069
|
+
`✓ Done — status: ${status} | ${rr?.turns ?? "?"} turns | ${toolCount} tool calls | ${(durationMs / 1e3).toFixed(1)}s`
|
|
773070
|
+
);
|
|
773071
|
+
if (rr?.summary) {
|
|
773072
|
+
emit2(`Summary: ${rr.summary.slice(0, 400)}`);
|
|
773073
|
+
}
|
|
773074
|
+
if (shouldForceSingleRunExit()) process.exit(0);
|
|
773075
|
+
}
|
|
772120
773076
|
function shouldForceJsonExit() {
|
|
772121
773077
|
if (process.env["OMNIUS_JSON_NO_FORCE_EXIT"] === "1") return false;
|
|
772122
773078
|
if (process.env["VITEST"] === "true" || process.env["NODE_ENV"] === "test")
|
|
@@ -773408,7 +774364,7 @@ Flags:
|
|
|
773408
774364
|
--dry-run Validate patches, don't write to disk
|
|
773409
774365
|
--offline Use FakeBackend, no backend connection needed
|
|
773410
774366
|
-l, --local Save settings to .omnius/settings.json (project-local)
|
|
773411
|
-
-v, --verbose
|
|
774367
|
+
-v, --verbose Lightweight console mode: print each tool call, result, and reasoning step as plain text (no TUI)
|
|
773412
774368
|
--max-retries <n> Max retries per model request
|
|
773413
774369
|
--timeout-ms <ms> Overall task timeout
|
|
773414
774370
|
--suite <name> Eval suite: basic (default) or full
|