zelari-code 2.0.1 → 2.1.0
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/README.md +2 -2
- package/dist/cli/hooks/useChatTurn.js +2 -1
- package/dist/cli/hooks/useChatTurn.js.map +1 -1
- package/dist/cli/kraken/candidateRegistry.js +15 -1
- package/dist/cli/kraken/candidateRegistry.js.map +1 -1
- package/dist/cli/kraken/evidenceProvenance.test.js +113 -0
- package/dist/cli/kraken/evidenceProvenance.test.js.map +1 -0
- package/dist/cli/kraken/strictGatePackIndependence.test.js +112 -0
- package/dist/cli/kraken/strictGatePackIndependence.test.js.map +1 -0
- package/dist/cli/kraken/verificationBridge.js +125 -14
- package/dist/cli/kraken/verificationBridge.js.map +1 -1
- package/dist/cli/kraken/verifierLifecycle.js +88 -0
- package/dist/cli/kraken/verifierLifecycle.js.map +1 -0
- package/dist/cli/kraken/verifierLifecycle.test.js +181 -0
- package/dist/cli/kraken/verifierLifecycle.test.js.map +1 -0
- package/dist/cli/kraken/verifyReport.js.map +1 -1
- package/dist/cli/main.bundled.js +272 -89
- package/dist/cli/main.bundled.js.map +4 -4
- package/dist/cli/runHeadless.js +44 -93
- package/dist/cli/runHeadless.js.map +1 -1
- package/dist/cli/tools/taskTool.js +49 -3
- package/dist/cli/tools/taskTool.js.map +1 -1
- package/package.json +3 -3
package/dist/cli/main.bundled.js
CHANGED
|
@@ -33708,6 +33708,7 @@ function resetKrakenCandidates() {
|
|
|
33708
33708
|
g.__zelariKrakenCandidates = [];
|
|
33709
33709
|
g.__zelariKrakenSelection = null;
|
|
33710
33710
|
g.__zelariKrakenCheckResults = null;
|
|
33711
|
+
g.__zelariVerifyToolTrace = null;
|
|
33711
33712
|
}
|
|
33712
33713
|
function setKrakenSelection(verdict) {
|
|
33713
33714
|
const g = globalThis;
|
|
@@ -33722,15 +33723,21 @@ function krakenRequiredChecks() {
|
|
|
33722
33723
|
if (!verdict || verdict.status !== "selected") return [];
|
|
33723
33724
|
return verdict.requiredChecks;
|
|
33724
33725
|
}
|
|
33725
|
-
function setKrakenCheckResults(results) {
|
|
33726
|
+
function setKrakenCheckResults(results, toolTrace) {
|
|
33726
33727
|
const g = globalThis;
|
|
33727
33728
|
g.__zelariKrakenCheckResults = results;
|
|
33729
|
+
g.__zelariVerifyToolTrace = toolTrace ? [...toolTrace] : null;
|
|
33728
33730
|
}
|
|
33729
33731
|
function getKrakenCheckResults() {
|
|
33730
33732
|
const g = globalThis;
|
|
33731
33733
|
const results = g.__zelariKrakenCheckResults;
|
|
33732
33734
|
return results ? [...results] : null;
|
|
33733
33735
|
}
|
|
33736
|
+
function getLastVerifyToolTrace() {
|
|
33737
|
+
const g = globalThis;
|
|
33738
|
+
const trace = g.__zelariVerifyToolTrace;
|
|
33739
|
+
return trace ? [...trace] : null;
|
|
33740
|
+
}
|
|
33734
33741
|
function krakenChecksPassed() {
|
|
33735
33742
|
const results = getKrakenCheckResults();
|
|
33736
33743
|
if (!results) return void 0;
|
|
@@ -34114,20 +34121,49 @@ function maxToolCallsForThoroughness(thoroughness, agent) {
|
|
|
34114
34121
|
if (thoroughness === "deep") return 12;
|
|
34115
34122
|
return 6;
|
|
34116
34123
|
}
|
|
34124
|
+
function toolCommandHint(args) {
|
|
34125
|
+
if (!args) return void 0;
|
|
34126
|
+
for (const key of ["command", "cmd", "script", "pattern", "path", "query", "url"]) {
|
|
34127
|
+
const v = args[key];
|
|
34128
|
+
if (typeof v === "string" && v.trim()) return v.trim().slice(0, 160);
|
|
34129
|
+
}
|
|
34130
|
+
return void 0;
|
|
34131
|
+
}
|
|
34117
34132
|
async function runSubAgent(harness, opts = {}) {
|
|
34118
34133
|
const { signal } = opts;
|
|
34119
34134
|
let current = "";
|
|
34120
34135
|
let lastCompleted = "";
|
|
34121
34136
|
let error51;
|
|
34122
34137
|
let usage;
|
|
34138
|
+
const pendingTools = /* @__PURE__ */ new Map();
|
|
34139
|
+
const toolTrace = [];
|
|
34123
34140
|
if (signal?.aborted) return { result: "", aborted: true };
|
|
34124
34141
|
for await (const ev of harness.run()) {
|
|
34125
34142
|
if (signal?.aborted) {
|
|
34126
34143
|
return {
|
|
34127
34144
|
result: (lastCompleted || current).trim(),
|
|
34128
34145
|
...error51 ? { error: error51 } : {},
|
|
34129
|
-
aborted: true
|
|
34130
|
-
|
|
34146
|
+
aborted: true,
|
|
34147
|
+
...toolTrace.length > 0 ? { toolTrace } : {}
|
|
34148
|
+
};
|
|
34149
|
+
}
|
|
34150
|
+
if (ev.type === "tool_execution_start") {
|
|
34151
|
+
pendingTools.set(ev.toolCallId, { tool: ev.toolName, command: toolCommandHint(ev.args) });
|
|
34152
|
+
} else if (ev.type === "tool_execution_end") {
|
|
34153
|
+
const started = pendingTools.get(ev.toolCallId);
|
|
34154
|
+
pendingTools.delete(ev.toolCallId);
|
|
34155
|
+
toolTrace.push({
|
|
34156
|
+
tool: started?.tool ?? "unknown",
|
|
34157
|
+
callId: ev.toolCallId,
|
|
34158
|
+
ok: !ev.isError,
|
|
34159
|
+
...started?.command ? { command: started.command } : {},
|
|
34160
|
+
output: String(ev.result ?? "").slice(0, TOOL_TRACE_OUTPUT_MAX),
|
|
34161
|
+
durationMs: ev.durationMs,
|
|
34162
|
+
endedAt: Date.now()
|
|
34163
|
+
});
|
|
34164
|
+
if (toolTrace.length > TOOL_TRACE_RING) {
|
|
34165
|
+
toolTrace.splice(0, toolTrace.length - TOOL_TRACE_RING);
|
|
34166
|
+
}
|
|
34131
34167
|
}
|
|
34132
34168
|
switch (ev.type) {
|
|
34133
34169
|
case "message_start":
|
|
@@ -34158,7 +34194,12 @@ async function runSubAgent(harness, opts = {}) {
|
|
|
34158
34194
|
}
|
|
34159
34195
|
}
|
|
34160
34196
|
const result = (lastCompleted || current).trim();
|
|
34161
|
-
return {
|
|
34197
|
+
return {
|
|
34198
|
+
result,
|
|
34199
|
+
...error51 ? { error: error51 } : {},
|
|
34200
|
+
...usage ? { usage } : {},
|
|
34201
|
+
...toolTrace.length > 0 ? { toolTrace } : {}
|
|
34202
|
+
};
|
|
34162
34203
|
}
|
|
34163
34204
|
async function runTentacle(opts) {
|
|
34164
34205
|
const { deps, args, agent, thoroughness, parentCwd, sessionId: sessionId2 } = opts;
|
|
@@ -34268,7 +34309,7 @@ async function runTentacle(opts) {
|
|
|
34268
34309
|
error: `task: failed to start sub-agent \u2014 ${err instanceof Error ? err.message : String(err)}`
|
|
34269
34310
|
};
|
|
34270
34311
|
}
|
|
34271
|
-
const { result, error: error51, aborted: aborted2, usage } = await runSubAgent(harness, {
|
|
34312
|
+
const { result, error: error51, aborted: aborted2, usage, toolTrace } = await runSubAgent(harness, {
|
|
34272
34313
|
...opts.signal ? { signal: opts.signal } : {}
|
|
34273
34314
|
});
|
|
34274
34315
|
const durationMs = Date.now() - started;
|
|
@@ -34370,6 +34411,7 @@ ${verifyHintForGeneral(args.acceptance)}`;
|
|
|
34370
34411
|
result,
|
|
34371
34412
|
footer,
|
|
34372
34413
|
...usage ? { usage } : {},
|
|
34414
|
+
...toolTrace && toolTrace.length > 0 ? { toolTrace } : {},
|
|
34373
34415
|
worktreePath: worktree?.path ?? null,
|
|
34374
34416
|
worktreeHandle: worktree
|
|
34375
34417
|
};
|
|
@@ -34476,7 +34518,8 @@ RESTRICTED in this mode: only agent=${allowedAgents.join("|")} is allowed.` : ""
|
|
|
34476
34518
|
const required2 = krakenRequiredChecks();
|
|
34477
34519
|
if (required2.length > 0) {
|
|
34478
34520
|
setKrakenCheckResults(
|
|
34479
|
-
res.ok ? parseVerifyReport(res.result, required2) : allUnknownCheckResults(required2, `verify tentacle failed: ${res.error}`)
|
|
34521
|
+
res.ok ? parseVerifyReport(res.result, required2) : allUnknownCheckResults(required2, `verify tentacle failed: ${res.error}`),
|
|
34522
|
+
res.ok ? res.toolTrace : void 0
|
|
34480
34523
|
);
|
|
34481
34524
|
}
|
|
34482
34525
|
}
|
|
@@ -34489,7 +34532,7 @@ ${res.result}${res.footer}`,
|
|
|
34489
34532
|
}
|
|
34490
34533
|
};
|
|
34491
34534
|
}
|
|
34492
|
-
var EXPLORE_PROMPT, GENERAL_PROMPT, VERIFY_PROMPT, TaskArgsSchema, TaskPurposeSchema, TaskArgsWithPurposeSchema;
|
|
34535
|
+
var EXPLORE_PROMPT, GENERAL_PROMPT, VERIFY_PROMPT, TaskArgsSchema, TaskPurposeSchema, TaskArgsWithPurposeSchema, TOOL_TRACE_RING, TOOL_TRACE_OUTPUT_MAX;
|
|
34493
34536
|
var init_taskTool = __esm({
|
|
34494
34537
|
"src/cli/tools/taskTool.ts"() {
|
|
34495
34538
|
"use strict";
|
|
@@ -34559,6 +34602,8 @@ var init_taskTool = __esm({
|
|
|
34559
34602
|
TaskArgsWithPurposeSchema = TaskArgsSchema.extend({
|
|
34560
34603
|
purpose: TaskPurposeSchema
|
|
34561
34604
|
});
|
|
34605
|
+
TOOL_TRACE_RING = 24;
|
|
34606
|
+
TOOL_TRACE_OUTPUT_MAX = 600;
|
|
34562
34607
|
}
|
|
34563
34608
|
});
|
|
34564
34609
|
|
|
@@ -40496,7 +40541,7 @@ var init_headlessSpine = __esm({
|
|
|
40496
40541
|
});
|
|
40497
40542
|
|
|
40498
40543
|
// src/cli/state/fileStateStore.ts
|
|
40499
|
-
import { createHash as
|
|
40544
|
+
import { createHash as createHash11, randomUUID as randomUUID2 } from "node:crypto";
|
|
40500
40545
|
import { promises as fs21 } from "node:fs";
|
|
40501
40546
|
import * as path41 from "node:path";
|
|
40502
40547
|
function shortId() {
|
|
@@ -40548,7 +40593,7 @@ async function getStateStore(projectRoot, env = process.env) {
|
|
|
40548
40593
|
}
|
|
40549
40594
|
}
|
|
40550
40595
|
function hashStablePrompt(stable) {
|
|
40551
|
-
return
|
|
40596
|
+
return createHash11("sha256").update(stable, "utf8").digest("hex").slice(0, 16);
|
|
40552
40597
|
}
|
|
40553
40598
|
var DEFAULT_MATERIALIZE_CHARS, FileDurableStateStore, NoopDurableStateStore;
|
|
40554
40599
|
var init_fileStateStore = __esm({
|
|
@@ -43926,7 +43971,7 @@ __export(agentsMd_exports, {
|
|
|
43926
43971
|
updateAgentsMd: () => updateAgentsMd
|
|
43927
43972
|
});
|
|
43928
43973
|
import { existsSync as existsSync35, readFileSync as readFileSync30, writeFileSync as writeFileSync19 } from "node:fs";
|
|
43929
|
-
import { createHash as
|
|
43974
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
43930
43975
|
import { join as join28 } from "node:path";
|
|
43931
43976
|
import { readFile as readFile4 } from "node:fs/promises";
|
|
43932
43977
|
async function readPackageJson2(projectRoot) {
|
|
@@ -44141,7 +44186,7 @@ async function updateAgentsMd(ctx, projectRoot) {
|
|
|
44141
44186
|
return { changed: true, sections: changedSections };
|
|
44142
44187
|
}
|
|
44143
44188
|
function hash2(s) {
|
|
44144
|
-
return
|
|
44189
|
+
return createHash12("sha256").update(s).digest("hex").slice(0, 16);
|
|
44145
44190
|
}
|
|
44146
44191
|
var AUTO_SECTIONS, MARKER_OPEN, MARKER_CLOSE, GENERATORS;
|
|
44147
44192
|
var init_agentsMd = __esm({
|
|
@@ -50747,7 +50792,7 @@ import {
|
|
|
50747
50792
|
} from "node:fs";
|
|
50748
50793
|
import { join as join38 } from "node:path";
|
|
50749
50794
|
import { homedir as homedir13 } from "node:os";
|
|
50750
|
-
import { createHash as
|
|
50795
|
+
import { createHash as createHash13, randomBytes as randomBytes5, timingSafeEqual } from "node:crypto";
|
|
50751
50796
|
function getZelariHome() {
|
|
50752
50797
|
return join38(homedir13(), ".zelari-code");
|
|
50753
50798
|
}
|
|
@@ -50823,8 +50868,8 @@ function loadOrCreateToken(explicit) {
|
|
|
50823
50868
|
}
|
|
50824
50869
|
function tokenMatches(expected, provided) {
|
|
50825
50870
|
if (!provided) return false;
|
|
50826
|
-
const a =
|
|
50827
|
-
const b =
|
|
50871
|
+
const a = createHash13("sha256").update(expected).digest();
|
|
50872
|
+
const b = createHash13("sha256").update(provided).digest();
|
|
50828
50873
|
try {
|
|
50829
50874
|
return timingSafeEqual(a, b);
|
|
50830
50875
|
} catch {
|
|
@@ -55420,6 +55465,7 @@ init_completionGate();
|
|
|
55420
55465
|
// src/cli/kraken/verificationBridge.ts
|
|
55421
55466
|
init_candidateRegistry();
|
|
55422
55467
|
init_completionGate();
|
|
55468
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
55423
55469
|
|
|
55424
55470
|
// src/cli/kraken/nativeVerification.ts
|
|
55425
55471
|
init_runtime2();
|
|
@@ -55545,33 +55591,94 @@ function krakenResultsToContract(requiredChecks, results, now = Date.now()) {
|
|
|
55545
55591
|
});
|
|
55546
55592
|
return { criteria, results: verifications };
|
|
55547
55593
|
}
|
|
55548
|
-
|
|
55549
|
-
|
|
55594
|
+
function sha256Hex2(input) {
|
|
55595
|
+
return createHash10("sha256").update(input).digest("hex");
|
|
55596
|
+
}
|
|
55597
|
+
function matchNoteToToolTrace(note, trace) {
|
|
55598
|
+
const n = normalize4(note);
|
|
55599
|
+
if (!n) return null;
|
|
55600
|
+
for (let i = trace.length - 1; i >= 0; i--) {
|
|
55601
|
+
const t = trace[i];
|
|
55602
|
+
const cmd = t.command ? normalize4(t.command) : "";
|
|
55603
|
+
if (cmd.length >= 4 && (n.includes(cmd) || cmd.includes(n))) return t;
|
|
55604
|
+
}
|
|
55605
|
+
for (let i = trace.length - 1; i >= 0; i--) {
|
|
55606
|
+
const t = trace[i];
|
|
55607
|
+
const out = normalize4(t.output);
|
|
55608
|
+
if (!out) continue;
|
|
55609
|
+
if (n.length >= 8 && out.includes(n)) return t;
|
|
55610
|
+
const fragments = n.match(/\S*\d[\d.,/%]*\S*/g) ?? [];
|
|
55611
|
+
for (const raw of fragments) {
|
|
55612
|
+
const frag = raw.replace(/[.,;:]+$/, "");
|
|
55613
|
+
if (frag.length >= 3 && out.includes(frag)) return t;
|
|
55614
|
+
}
|
|
55615
|
+
}
|
|
55616
|
+
return null;
|
|
55617
|
+
}
|
|
55618
|
+
async function anchorSelectionEvidence(results, emit, toolTrace) {
|
|
55619
|
+
const counts = { toolResultAnchored: 0, noteFallback: 0 };
|
|
55620
|
+
if (!emit) return counts;
|
|
55550
55621
|
for (const r of results) {
|
|
55551
55622
|
for (const ev of r.evidence) {
|
|
55552
55623
|
if (ev.seq !== void 0) continue;
|
|
55553
55624
|
if (ev.tier === "verifier-llm" || ev.tier === "human") continue;
|
|
55554
55625
|
try {
|
|
55626
|
+
const match = toolTrace && toolTrace.length > 0 ? matchNoteToToolTrace(ev.ref, toolTrace) : null;
|
|
55627
|
+
if (match) {
|
|
55628
|
+
const digest = sha256Hex2(match.output);
|
|
55629
|
+
const appended2 = await emit({
|
|
55630
|
+
kind: "verification.evidence",
|
|
55631
|
+
actor: { type: "system", role: "verification" },
|
|
55632
|
+
data: {
|
|
55633
|
+
observation: "tool-result",
|
|
55634
|
+
provenance: "tentacle-tool-capture",
|
|
55635
|
+
criterionId: r.criterionId,
|
|
55636
|
+
tool: match.tool,
|
|
55637
|
+
callId: match.callId,
|
|
55638
|
+
ok: match.ok,
|
|
55639
|
+
digest,
|
|
55640
|
+
outputTail: match.output.slice(0, 240),
|
|
55641
|
+
note: ev.ref,
|
|
55642
|
+
...match.command ? { command: match.command } : {}
|
|
55643
|
+
}
|
|
55644
|
+
});
|
|
55645
|
+
const toolSeq = appended2 && typeof appended2 === "object" && "seq" in appended2 ? Number(appended2.seq) : NaN;
|
|
55646
|
+
if (Number.isFinite(toolSeq) && toolSeq > 0) {
|
|
55647
|
+
ev.seq = toolSeq;
|
|
55648
|
+
ev.digest = digest;
|
|
55649
|
+
ev.ref = `${match.tool}${match.command ? ` ${match.command}` : ""} \u2192 ${match.ok ? "ok" : "error"} @seq`;
|
|
55650
|
+
counts.toolResultAnchored += 1;
|
|
55651
|
+
}
|
|
55652
|
+
continue;
|
|
55653
|
+
}
|
|
55555
55654
|
const appended = await emit({
|
|
55556
55655
|
kind: "verification.evidence",
|
|
55557
55656
|
actor: { type: "system", role: "verification" },
|
|
55558
55657
|
data: {
|
|
55559
55658
|
observation: "verify-report-note",
|
|
55659
|
+
provenance: "note-fallback",
|
|
55560
55660
|
criterionId: r.criterionId,
|
|
55561
55661
|
ref: ev.ref,
|
|
55562
55662
|
tier: ev.tier
|
|
55563
55663
|
}
|
|
55564
55664
|
});
|
|
55565
55665
|
const seq = appended && typeof appended === "object" && "seq" in appended ? Number(appended.seq) : NaN;
|
|
55566
|
-
if (Number.isFinite(seq) && seq > 0)
|
|
55666
|
+
if (Number.isFinite(seq) && seq > 0) {
|
|
55667
|
+
ev.seq = seq;
|
|
55668
|
+
counts.noteFallback += 1;
|
|
55669
|
+
}
|
|
55567
55670
|
} catch {
|
|
55568
55671
|
}
|
|
55569
55672
|
}
|
|
55570
55673
|
}
|
|
55674
|
+
return counts;
|
|
55571
55675
|
}
|
|
55572
55676
|
async function evaluateStrictBuildGate(mode, options = {}) {
|
|
55573
55677
|
const gate = evaluateKrakenCompletionGate(mode);
|
|
55574
|
-
|
|
55678
|
+
const strictOn = strictDoneEnabled(options.surface ?? "kraken");
|
|
55679
|
+
const nativeOn = nativePackEnabled(options.env ?? process.env);
|
|
55680
|
+
const selectionAvailable = gate.selectionUsed && gate.total > 0;
|
|
55681
|
+
if (!selectionAvailable && !nativeOn || !strictOn && !nativeOn) {
|
|
55575
55682
|
return {
|
|
55576
55683
|
gate,
|
|
55577
55684
|
strict: false,
|
|
@@ -55581,9 +55688,13 @@ async function evaluateStrictBuildGate(mode, options = {}) {
|
|
|
55581
55688
|
summary: gate.blocked ? `blocked: ${gate.failedChecks.length} failed, ${gate.unknownChecks.length} unknown` : "open"
|
|
55582
55689
|
};
|
|
55583
55690
|
}
|
|
55584
|
-
const checks = krakenRequiredChecks();
|
|
55585
|
-
const contract = krakenResultsToContract(checks, getKrakenCheckResults());
|
|
55586
|
-
await anchorSelectionEvidence(
|
|
55691
|
+
const checks = selectionAvailable ? krakenRequiredChecks() : [];
|
|
55692
|
+
const contract = selectionAvailable ? krakenResultsToContract(checks, getKrakenCheckResults()) : { criteria: [], results: [] };
|
|
55693
|
+
const anchoring = await anchorSelectionEvidence(
|
|
55694
|
+
contract.results,
|
|
55695
|
+
options.emit,
|
|
55696
|
+
getLastVerifyToolTrace() ?? void 0
|
|
55697
|
+
);
|
|
55587
55698
|
const native = await evaluateNativePack({
|
|
55588
55699
|
cwd: options.cwd,
|
|
55589
55700
|
env: options.env,
|
|
@@ -55592,15 +55703,29 @@ async function evaluateStrictBuildGate(mode, options = {}) {
|
|
|
55592
55703
|
}).catch(() => null);
|
|
55593
55704
|
const allCriteria = [...contract.criteria, ...native?.criteria ?? []];
|
|
55594
55705
|
const allResults = [...contract.results, ...native?.results ?? []];
|
|
55706
|
+
if (allCriteria.length === 0) {
|
|
55707
|
+
return {
|
|
55708
|
+
gate,
|
|
55709
|
+
strict: false,
|
|
55710
|
+
evaluation: null,
|
|
55711
|
+
native,
|
|
55712
|
+
results: allResults,
|
|
55713
|
+
blocked: gate.blocked,
|
|
55714
|
+
summary: gate.blocked ? `blocked: ${gate.failedChecks.length} failed, ${gate.unknownChecks.length} unknown` : "open (native pack bound no command)"
|
|
55715
|
+
};
|
|
55716
|
+
}
|
|
55595
55717
|
const evaluation = evaluateCompletion(allCriteria, allResults, STRICT_BUILD_POLICY);
|
|
55596
55718
|
const blocked = gate.blocked || evaluation.verdict !== "PASS";
|
|
55719
|
+
const legacyPart = selectionAvailable ? `${gate.passed}/${gate.total} legacy-pass, ` : "no selection contract, ";
|
|
55597
55720
|
return {
|
|
55598
55721
|
gate,
|
|
55599
55722
|
strict: true,
|
|
55723
|
+
results: allResults,
|
|
55724
|
+
anchoring,
|
|
55600
55725
|
evaluation,
|
|
55601
55726
|
native,
|
|
55602
55727
|
blocked,
|
|
55603
|
-
summary: blocked ? `blocked (strict ${evaluation?.verdict ?? "n/a"}): ${
|
|
55728
|
+
summary: blocked ? `blocked (strict ${evaluation?.verdict ?? "n/a"}): ${legacyPart}evidence ${evaluation?.evidenceComplete ? "complete" : "incomplete"}` : `open (strict PASS): ${evaluation?.satisfied.length ?? 0}/${allCriteria.length} criteria pass with evidence`
|
|
55604
55729
|
};
|
|
55605
55730
|
}
|
|
55606
55731
|
var STRICT_DONE_EXIT_CODE = 4;
|
|
@@ -55621,7 +55746,8 @@ function strictGateEventPayload(evaluation) {
|
|
|
55621
55746
|
evidence: evaluation.evaluation ? {
|
|
55622
55747
|
satisfied: evaluation.evaluation.satisfied,
|
|
55623
55748
|
unsatisfied: evaluation.evaluation.unsatisfied,
|
|
55624
|
-
complete: evaluation.evaluation.evidenceComplete
|
|
55749
|
+
complete: evaluation.evaluation.evidenceComplete,
|
|
55750
|
+
provenance: evaluation.anchoring ?? null
|
|
55625
55751
|
} : null,
|
|
55626
55752
|
// F2: deterministic pack results — real command evidence, replayable.
|
|
55627
55753
|
native: evaluation.native ? {
|
|
@@ -55634,6 +55760,16 @@ function strictGateEventPayload(evaluation) {
|
|
|
55634
55760
|
detail: r.detail
|
|
55635
55761
|
}))
|
|
55636
55762
|
} : null,
|
|
55763
|
+
// 2.1 T4: advisory verifier review (opt-in) — informational, never
|
|
55764
|
+
// authoritative: verdict/blocked above come from the deterministic policy.
|
|
55765
|
+
verifier: evaluation.review ? {
|
|
55766
|
+
verdict: evaluation.review.verdict,
|
|
55767
|
+
score: evaluation.review.score ?? null,
|
|
55768
|
+
rationale: evaluation.review.rationale ?? null,
|
|
55769
|
+
fallback: evaluation.review.fallback ?? null,
|
|
55770
|
+
effectiveModel: evaluation.review.effectiveModel,
|
|
55771
|
+
advisory: true
|
|
55772
|
+
} : null,
|
|
55637
55773
|
summary: evaluation.summary
|
|
55638
55774
|
};
|
|
55639
55775
|
}
|
|
@@ -56389,7 +56525,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
|
|
|
56389
56525
|
if (event.type === "agent_end") {
|
|
56390
56526
|
let krakenSuppressFinish = false;
|
|
56391
56527
|
const krakenSpineEmit = (input) => writerRef.current?.spine?.appendEvent(input) ?? Promise.resolve(null);
|
|
56392
|
-
if (event.reason === "completed" && !krakenRepairEnqueued && isKrakenSelectionEnabled() && workPhase === "build") {
|
|
56528
|
+
if (event.reason === "completed" && !krakenRepairEnqueued && (isKrakenSelectionEnabled() || nativePackEnabled()) && workPhase === "build") {
|
|
56393
56529
|
const strictGate = await evaluateStrictBuildGate("build", { emit: krakenSpineEmit });
|
|
56394
56530
|
const krakenGate = strictGate.gate;
|
|
56395
56531
|
writerRef.current?.spine?.verificationRun(strictGateEventPayload(strictGate));
|
|
@@ -61763,6 +61899,93 @@ init_sessionTodos();
|
|
|
61763
61899
|
import { promises as fs36 } from "node:fs";
|
|
61764
61900
|
import path61 from "node:path";
|
|
61765
61901
|
import { randomUUID as randomUUID6 } from "node:crypto";
|
|
61902
|
+
|
|
61903
|
+
// src/cli/kraken/verifierLifecycle.ts
|
|
61904
|
+
init_verification2();
|
|
61905
|
+
init_krakenSelectTool();
|
|
61906
|
+
|
|
61907
|
+
// src/cli/kraken/verifierResolution.ts
|
|
61908
|
+
init_providerConfig();
|
|
61909
|
+
function verifierOverrideToModelSelection(override) {
|
|
61910
|
+
if (override && typeof override.provider === "string" && typeof override.model === "string" && override.provider.trim().length > 0 && override.model.trim().length > 0) {
|
|
61911
|
+
return {
|
|
61912
|
+
mode: "fixed",
|
|
61913
|
+
provider: override.provider.trim(),
|
|
61914
|
+
model: override.model.trim()
|
|
61915
|
+
};
|
|
61916
|
+
}
|
|
61917
|
+
return { mode: "inherit" };
|
|
61918
|
+
}
|
|
61919
|
+
function loadVerifierModelSelection() {
|
|
61920
|
+
return verifierOverrideToModelSelection(getKrakenVerifierOverride());
|
|
61921
|
+
}
|
|
61922
|
+
|
|
61923
|
+
// src/cli/kraken/verifierLifecycle.ts
|
|
61924
|
+
function verifierReviewEnabled(selection = loadVerifierModelSelection(), env = process.env) {
|
|
61925
|
+
const v = env.ZELARI_VERIFIER_REVIEW?.toLowerCase();
|
|
61926
|
+
if (v === "0" || v === "false" || v === "off") return false;
|
|
61927
|
+
if (v === "1" || v === "true" || v === "on") return true;
|
|
61928
|
+
return selection.mode === "fixed";
|
|
61929
|
+
}
|
|
61930
|
+
function makeVerifierCallModel(loadStream, identity, timeoutMs = 12e4) {
|
|
61931
|
+
return async ({ system, user }) => {
|
|
61932
|
+
const stream = await loadStream(identity.provider, identity.model);
|
|
61933
|
+
if (!stream) {
|
|
61934
|
+
throw new Error(`no provider config for verifier "${identity.provider}"`);
|
|
61935
|
+
}
|
|
61936
|
+
const { text } = await collectProviderText(stream, {
|
|
61937
|
+
messages: [
|
|
61938
|
+
{ role: "system", content: system },
|
|
61939
|
+
{ role: "user", content: user }
|
|
61940
|
+
],
|
|
61941
|
+
model: identity.model,
|
|
61942
|
+
provider: identity.provider,
|
|
61943
|
+
tools: [],
|
|
61944
|
+
signal: AbortSignal.timeout(timeoutMs)
|
|
61945
|
+
});
|
|
61946
|
+
return { text, provider: identity.provider, model: identity.model };
|
|
61947
|
+
};
|
|
61948
|
+
}
|
|
61949
|
+
function resolveIdentity(selection, session) {
|
|
61950
|
+
if (selection.mode === "fixed") {
|
|
61951
|
+
return { provider: selection.provider, model: selection.model };
|
|
61952
|
+
}
|
|
61953
|
+
return session && session.provider && session.model ? session : null;
|
|
61954
|
+
}
|
|
61955
|
+
async function runAdvisoryVerifierReview(evaluation, deps = {}) {
|
|
61956
|
+
if (!evaluation.evaluation || !evaluation.results) return null;
|
|
61957
|
+
const env = deps.env ?? process.env;
|
|
61958
|
+
const selection = deps.selection ?? loadVerifierModelSelection();
|
|
61959
|
+
if (!verifierReviewEnabled(selection, env)) return null;
|
|
61960
|
+
const identity = resolveIdentity(selection, deps.session);
|
|
61961
|
+
let callModel = deps.callModel;
|
|
61962
|
+
if (!callModel) {
|
|
61963
|
+
if (!identity || !deps.loadStream) return null;
|
|
61964
|
+
callModel = makeVerifierCallModel(deps.loadStream, identity, deps.timeoutMs);
|
|
61965
|
+
}
|
|
61966
|
+
const service = new VerifierService({
|
|
61967
|
+
callModel,
|
|
61968
|
+
config: {
|
|
61969
|
+
enabled: true,
|
|
61970
|
+
model: selection,
|
|
61971
|
+
progressScoring: false,
|
|
61972
|
+
bon: { enabled: false, n: 3 }
|
|
61973
|
+
},
|
|
61974
|
+
emit: deps.emit,
|
|
61975
|
+
env
|
|
61976
|
+
});
|
|
61977
|
+
const passed = evaluation.results.filter((r) => r.status === "pass").length;
|
|
61978
|
+
const summary = `Kraken BUILD turn \u2014 deterministic evidence: ${passed}/${evaluation.results.length} criteria pass, completion verdict ${evaluation.evaluation.verdict}.`;
|
|
61979
|
+
const review = await service.reviewCompletion({
|
|
61980
|
+
summary,
|
|
61981
|
+
results: evaluation.results,
|
|
61982
|
+
session: deps.session
|
|
61983
|
+
});
|
|
61984
|
+
evaluation.review = review;
|
|
61985
|
+
return review;
|
|
61986
|
+
}
|
|
61987
|
+
|
|
61988
|
+
// src/cli/runHeadless.ts
|
|
61766
61989
|
init_headlessSpine();
|
|
61767
61990
|
async function runHeadless(opts) {
|
|
61768
61991
|
resetTaskSpawnCount();
|
|
@@ -62017,13 +62240,6 @@ ${formatKrakenGraphDigest2(
|
|
|
62017
62240
|
emitEvent({ type: "message_delta", delta: finalAscii });
|
|
62018
62241
|
emitEvent({ type: "message_end" });
|
|
62019
62242
|
emitEvent({ type: "agent_end", reason: summary.converged ? "completed" : "error" });
|
|
62020
|
-
emitEvent({
|
|
62021
|
-
type: "history_snapshot",
|
|
62022
|
-
messages: [
|
|
62023
|
-
{ role: "user", content: prompt },
|
|
62024
|
-
{ role: "assistant", content: finalAscii }
|
|
62025
|
-
]
|
|
62026
|
-
});
|
|
62027
62243
|
} else {
|
|
62028
62244
|
process.stdout.write(`${finalAscii}
|
|
62029
62245
|
`);
|
|
@@ -62406,8 +62622,29 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
62406
62622
|
};
|
|
62407
62623
|
}
|
|
62408
62624
|
let strictExit = 0;
|
|
62409
|
-
|
|
62625
|
+
const verifierReviewDeps = {
|
|
62626
|
+
session: { provider, model },
|
|
62627
|
+
loadStream: async (providerId, modelId) => {
|
|
62628
|
+
if (providerId === provider) return providerStream;
|
|
62629
|
+
try {
|
|
62630
|
+
const key = await resolveHeadlessKey(providerId);
|
|
62631
|
+
if ("error" in key) return null;
|
|
62632
|
+
const { buildProviderStream: buildProviderStream2 } = await Promise.resolve().then(() => (init_resolveStream(), resolveStream_exports));
|
|
62633
|
+
return buildProviderStream2({
|
|
62634
|
+
providerId,
|
|
62635
|
+
apiKey: key.apiKey,
|
|
62636
|
+
baseUrl: key.baseUrl,
|
|
62637
|
+
model: modelId
|
|
62638
|
+
});
|
|
62639
|
+
} catch {
|
|
62640
|
+
return null;
|
|
62641
|
+
}
|
|
62642
|
+
},
|
|
62643
|
+
emit: (input) => spine.appendEvent(input)
|
|
62644
|
+
};
|
|
62645
|
+
if (pass.finalReason === "completed" && pass.exitCode === 0 && opts.mode === "kraken" && (isKrakenSelectionEnabled() || nativePackEnabled()) && !planModeFromOpts(opts)) {
|
|
62410
62646
|
const strictGate = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input) });
|
|
62647
|
+
await runAdvisoryVerifierReview(strictGate, verifierReviewDeps).catch(() => void 0);
|
|
62411
62648
|
const gate = strictGate.gate;
|
|
62412
62649
|
const verificationPayload = strictGateEventPayload(strictGate);
|
|
62413
62650
|
spine.verificationRun(verificationPayload);
|
|
@@ -62441,6 +62678,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
62441
62678
|
emittedWrites: pass.emittedWrites + repair.emittedWrites
|
|
62442
62679
|
};
|
|
62443
62680
|
const after = await evaluateStrictBuildGate("build", { emit: (input) => spine.appendEvent(input) });
|
|
62681
|
+
await runAdvisoryVerifierReview(after, verifierReviewDeps).catch(() => void 0);
|
|
62444
62682
|
const afterPayload = strictGateEventPayload(after);
|
|
62445
62683
|
spine.verificationRun(afterPayload);
|
|
62446
62684
|
if (opts.output === "json") {
|
|
@@ -62465,41 +62703,8 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
|
|
|
62465
62703
|
process.stdout.write(pass.textBuffer.join(""));
|
|
62466
62704
|
}
|
|
62467
62705
|
process.stdout.write("");
|
|
62468
|
-
if (pass.finalReason !== "error" && opts.output === "json") {
|
|
62469
|
-
|
|
62470
|
-
const all = pass.messages;
|
|
62471
|
-
let lastAsst = "";
|
|
62472
|
-
for (let i = all.length - 1; i >= 0; i--) {
|
|
62473
|
-
const m = all[i];
|
|
62474
|
-
if (m?.role === "assistant" && (m.content ?? "").trim()) {
|
|
62475
|
-
lastAsst = cleanAgentContent(m.content, {
|
|
62476
|
-
stripQuestion: false,
|
|
62477
|
-
stripThink: false
|
|
62478
|
-
});
|
|
62479
|
-
break;
|
|
62480
|
-
}
|
|
62481
|
-
}
|
|
62482
|
-
if (!lastAsst.trim() && pass.textBuffer.length > 0) {
|
|
62483
|
-
lastAsst = pass.textBuffer.join("").trim();
|
|
62484
|
-
}
|
|
62485
|
-
if (wantWrites && pass.successfulWrites === 0) {
|
|
62486
|
-
lastAsst = (lastAsst ? `${lastAsst}
|
|
62487
|
-
|
|
62488
|
-
` : "") + "[zelari] WARNING: BUILD turn ended with zero successful file writes. The planned changes may still need to be applied on disk.";
|
|
62489
|
-
emitEvent({
|
|
62490
|
-
type: "log",
|
|
62491
|
-
message: "[headless] BUILD warning: still zero successful writes after retry"
|
|
62492
|
-
});
|
|
62493
|
-
}
|
|
62494
|
-
const snapshot = [
|
|
62495
|
-
{ role: "user", content: opts.task },
|
|
62496
|
-
...lastAsst ? [{ role: "assistant", content: lastAsst }] : []
|
|
62497
|
-
];
|
|
62498
|
-
if (snapshot.length > 0) {
|
|
62499
|
-
emitEvent({ type: "history_snapshot", messages: snapshot });
|
|
62500
|
-
}
|
|
62501
|
-
} catch {
|
|
62502
|
-
}
|
|
62706
|
+
if (pass.finalReason !== "error" && opts.output === "json" && wantWrites && pass.successfulWrites === 0) {
|
|
62707
|
+
emitEvent({ type: "log", message: "[headless] BUILD warning: still zero successful writes after retry" });
|
|
62503
62708
|
}
|
|
62504
62709
|
try {
|
|
62505
62710
|
const closeStatus = pass.finalReason === "error" ? "error" : strictExit !== 0 ? "stopped" : "completed";
|
|
@@ -62659,16 +62864,6 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
|
|
|
62659
62864
|
);
|
|
62660
62865
|
return 2;
|
|
62661
62866
|
}
|
|
62662
|
-
if (opts.output === "json") {
|
|
62663
|
-
try {
|
|
62664
|
-
const snapshot = [
|
|
62665
|
-
{ role: "user", content: opts.task },
|
|
62666
|
-
...lastAssistantText ? [{ role: "assistant", content: lastAssistantText }] : []
|
|
62667
|
-
];
|
|
62668
|
-
emitEvent({ type: "history_snapshot", messages: snapshot });
|
|
62669
|
-
} catch {
|
|
62670
|
-
}
|
|
62671
|
-
}
|
|
62672
62867
|
try {
|
|
62673
62868
|
await spine.close(exitCode === 0 ? "completed" : "error");
|
|
62674
62869
|
} catch {
|
|
@@ -63027,18 +63222,6 @@ ${ragContext}` : slicePrompt;
|
|
|
63027
63222
|
}
|
|
63028
63223
|
}
|
|
63029
63224
|
}
|
|
63030
|
-
if (opts.output === "json") {
|
|
63031
|
-
try {
|
|
63032
|
-
emitEvent({
|
|
63033
|
-
type: "history_snapshot",
|
|
63034
|
-
messages: [
|
|
63035
|
-
{ role: "user", content: opts.task },
|
|
63036
|
-
...lastMissionAssistant ? [{ role: "assistant", content: lastMissionAssistant }] : []
|
|
63037
|
-
]
|
|
63038
|
-
});
|
|
63039
|
-
} catch {
|
|
63040
|
-
}
|
|
63041
|
-
}
|
|
63042
63225
|
return exitCode;
|
|
63043
63226
|
}
|
|
63044
63227
|
|