zelari-code 2.0.0-alpha.5 → 2.0.0-alpha.6

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.
@@ -29645,6 +29645,16 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
29645
29645
  });
29646
29646
  continue;
29647
29647
  }
29648
+ const admissible = policy.admissibleTiers;
29649
+ if (admissible && !result.evidence.some((e) => admissible.includes(e.tier))) {
29650
+ const tiers = [...new Set(result.evidence.map((e) => e.tier))].join(", ");
29651
+ unsatisfied.push({
29652
+ id,
29653
+ status: "unknown",
29654
+ reason: `pass with inadmissible evidence tiers only (${tiers}) \u2014 not acceptable for completion`
29655
+ });
29656
+ continue;
29657
+ }
29648
29658
  satisfied.push(id);
29649
29659
  }
29650
29660
  const verdict = unsatisfied.length === 0 ? "PASS" : unsatisfied.some((u) => u.status === "fail") ? "REPAIR_REQUIRED" : "BLOCKED";
@@ -29656,15 +29666,113 @@ function evaluateCompletion(criteria, results, policy = STRICT_ALL_POLICY) {
29656
29666
  summary: verdict === "PASS" ? `complete: ${satisfied.length}/${ids.length} required criteria pass with evidence` : `incomplete (${verdict}): ${unsatisfied.map((u) => `${u.id}=${u.status}`).join(", ")}`
29657
29667
  };
29658
29668
  }
29659
- var STRICT_ALL_POLICY, strictBuildGate;
29669
+ var STRICT_ALL_POLICY, DETERMINISTIC_EVIDENCE_TIERS, STRICT_BUILD_POLICY, strictBuildGate;
29660
29670
  var init_completionPolicy = __esm({
29661
29671
  "packages/core/dist/verification/completionPolicy.js"() {
29662
29672
  "use strict";
29663
29673
  STRICT_ALL_POLICY = { mode: "strict", required: "*" };
29674
+ DETERMINISTIC_EVIDENCE_TIERS = [
29675
+ "tool-output",
29676
+ "command-output",
29677
+ "fs-observation",
29678
+ "human"
29679
+ ];
29680
+ STRICT_BUILD_POLICY = {
29681
+ mode: "strict",
29682
+ required: "*",
29683
+ admissibleTiers: DETERMINISTIC_EVIDENCE_TIERS
29684
+ };
29664
29685
  strictBuildGate = evaluateCompletion;
29665
29686
  }
29666
29687
  });
29667
29688
 
29689
+ // packages/core/dist/verification/sessionEvidence.js
29690
+ function asString2(v) {
29691
+ return typeof v === "string" ? v : null;
29692
+ }
29693
+ function asStringArray(v) {
29694
+ if (!Array.isArray(v))
29695
+ return [];
29696
+ return v.filter((x) => typeof x === "string");
29697
+ }
29698
+ function asUnsatisfied(v) {
29699
+ if (!Array.isArray(v))
29700
+ return [];
29701
+ const out = [];
29702
+ for (const item of v) {
29703
+ if (!item || typeof item !== "object")
29704
+ continue;
29705
+ const rec = item;
29706
+ const id = asString2(rec.id);
29707
+ if (id === null)
29708
+ continue;
29709
+ out.push({
29710
+ id,
29711
+ status: asString2(rec.status) ?? "unknown",
29712
+ reason: asString2(rec.reason) ?? ""
29713
+ });
29714
+ }
29715
+ return out;
29716
+ }
29717
+ function parseVerificationRunPayload(ev) {
29718
+ const data = ev.data;
29719
+ if (!data || typeof data !== "object")
29720
+ return null;
29721
+ const rec = data;
29722
+ const verdictRaw = asString2(rec.verdict);
29723
+ const verdict = verdictRaw !== null && VERDICTS.has(verdictRaw) ? verdictRaw : "unknown";
29724
+ const evidence = rec.evidence && typeof rec.evidence === "object" ? rec.evidence : null;
29725
+ const satisfied = asStringArray(evidence?.satisfied);
29726
+ const unsatisfied = asUnsatisfied(evidence?.unsatisfied);
29727
+ const completeRaw = evidence?.complete;
29728
+ return {
29729
+ seq: ev.seq,
29730
+ ts: ev.ts,
29731
+ engine: asString2(rec.engine),
29732
+ strict: rec.strict === true,
29733
+ verdict,
29734
+ satisfied,
29735
+ unsatisfied,
29736
+ evidenceComplete: typeof completeRaw === "boolean" ? completeRaw : verdict === "PASS" && satisfied.length > 0 && unsatisfied.length === 0,
29737
+ summary: asString2(rec.summary) ?? ""
29738
+ };
29739
+ }
29740
+ function lastVerificationRun(events) {
29741
+ for (let i = events.length - 1; i >= 0; i--) {
29742
+ const ev = events[i];
29743
+ if (ev.kind !== "verification.run")
29744
+ continue;
29745
+ const snap = parseVerificationRunPayload(ev);
29746
+ if (snap)
29747
+ return snap;
29748
+ }
29749
+ return null;
29750
+ }
29751
+ function snapshotToCompletionEvaluation(snap) {
29752
+ if (!snap.strict)
29753
+ return null;
29754
+ const unsatisfied = snap.unsatisfied.map((u) => ({
29755
+ id: u.id,
29756
+ status: u.status === "fail" || u.status === "missing" ? u.status : "unknown",
29757
+ reason: u.reason
29758
+ }));
29759
+ const verdict = snap.verdict === "PASS" || snap.verdict === "REPAIR_REQUIRED" || snap.verdict === "BLOCKED" ? snap.verdict : "BLOCKED";
29760
+ return {
29761
+ verdict,
29762
+ satisfied: [...snap.satisfied],
29763
+ unsatisfied,
29764
+ evidenceComplete: snap.evidenceComplete && unsatisfied.length === 0 && verdict === "PASS",
29765
+ summary: snap.summary
29766
+ };
29767
+ }
29768
+ var VERDICTS;
29769
+ var init_sessionEvidence = __esm({
29770
+ "packages/core/dist/verification/sessionEvidence.js"() {
29771
+ "use strict";
29772
+ VERDICTS = /* @__PURE__ */ new Set(["PASS", "REPAIR_REQUIRED", "BLOCKED"]);
29773
+ }
29774
+ });
29775
+
29668
29776
  // packages/core/dist/verification/criteriaPack.v1.js
29669
29777
  function codingCriteriaPack(options = {}) {
29670
29778
  const timeoutMs = options.commandTimeoutMs ?? 6e5;
@@ -29954,6 +30062,7 @@ var init_verification2 = __esm({
29954
30062
  init_types9();
29955
30063
  init_engine();
29956
30064
  init_completionPolicy();
30065
+ init_sessionEvidence();
29957
30066
  init_criteriaPack_v1();
29958
30067
  init_metrics();
29959
30068
  init_verifier();
@@ -30045,6 +30154,7 @@ __export(dist_exports, {
30045
30154
  DESIGN_PHASE_MODE_BANNER: () => DESIGN_PHASE_MODE_BANNER,
30046
30155
  DESIGN_PHASE_REQUIREMENTS: () => DESIGN_PHASE_REQUIREMENTS,
30047
30156
  DESIGN_PHASE_REQUIREMENT_SETS: () => DESIGN_PHASE_REQUIREMENT_SETS,
30157
+ DETERMINISTIC_EVIDENCE_TIERS: () => DETERMINISTIC_EVIDENCE_TIERS,
30048
30158
  DOOM_LOOP_THRESHOLD: () => DOOM_LOOP_THRESHOLD,
30049
30159
  DeterministicCheckSchema: () => DeterministicCheckSchema,
30050
30160
  EXPERIMENTAL_FLAGS: () => EXPERIMENTAL_FLAGS,
@@ -30100,6 +30210,7 @@ __export(dist_exports, {
30100
30210
  SINGLE_AGENT_IDENTITY_MODULE: () => SINGLE_AGENT_IDENTITY_MODULE,
30101
30211
  SKILL_CATALOG: () => SKILL_CATALOG,
30102
30212
  STRICT_ALL_POLICY: () => STRICT_ALL_POLICY,
30213
+ STRICT_BUILD_POLICY: () => STRICT_BUILD_POLICY,
30103
30214
  STRUCTURED_REASONING_DIRECTIVE: () => STRUCTURED_REASONING_DIRECTIVE,
30104
30215
  ScriptRunner: () => ScriptRunner,
30105
30216
  SessionActorSchema: () => SessionActorSchema,
@@ -30255,6 +30366,7 @@ __export(dist_exports, {
30255
30366
  isVerifyToolCheckSkipped: () => isVerifyToolCheckSkipped,
30256
30367
  jaccardSimilarity: () => jaccardSimilarity,
30257
30368
  jsonBytes: () => jsonBytes,
30369
+ lastVerificationRun: () => lastVerificationRun,
30258
30370
  lineageOf: () => lineageOf,
30259
30371
  lintSynthesisHonesty: () => lintSynthesisHonesty,
30260
30372
  listCodingSkills: () => listCodingSkills,
@@ -30276,6 +30388,7 @@ __export(dist_exports, {
30276
30388
  parseProjectRootFromWorkspaceContext: () => parseProjectRootFromWorkspaceContext,
30277
30389
  parseTextToolCalls: () => parseTextToolCalls,
30278
30390
  parseThinking: () => parseThinking,
30391
+ parseVerificationRunPayload: () => parseVerificationRunPayload,
30279
30392
  parseVerificationTable: () => parseVerificationTable,
30280
30393
  parseVerifyVerdict: () => parseVerifyVerdict,
30281
30394
  pathsOverlap: () => pathsOverlap,
@@ -30325,6 +30438,7 @@ __export(dist_exports, {
30325
30438
  sha256Hex: () => sha256Hex,
30326
30439
  shouldRetryMember: () => shouldRetryMember,
30327
30440
  slugify: () => slugify2,
30441
+ snapshotToCompletionEvaluation: () => snapshotToCompletionEvaluation,
30328
30442
  specificityFromAssumptions: () => specificityFromAssumptions,
30329
30443
  stableStringify: () => stableStringify,
30330
30444
  strictBuildGate: () => strictBuildGate,
@@ -30694,6 +30808,7 @@ var init_sessionSpine = __esm({
30694
30808
  "use strict";
30695
30809
  init_session();
30696
30810
  init_session();
30811
+ init_verification2();
30697
30812
  MAX_STREAM_BUFFERS = 32;
30698
30813
  SessionSpineMirror = class _SessionSpineMirror {
30699
30814
  constructor(sessionId2, options) {
@@ -30781,6 +30896,19 @@ var init_sessionSpine = __esm({
30781
30896
  if (!report || report.events.length === 0) return null;
30782
30897
  return deriveMessages(report.events);
30783
30898
  }
30899
+ /**
30900
+ * E2.1 (ADR-0023 × ADR-0021): last recognizable strict verification record
30901
+ * in this session's log — the completion verdict is reconstructible from
30902
+ * the spine alone (null when degraded/disabled or no record).
30903
+ */
30904
+ async lastVerificationRun() {
30905
+ if (this.status !== "active" && this.status !== "closed") return null;
30906
+ const report = await readSessionLog(
30907
+ path21.join(this.sessionsDir, this.sessionId, "events.jsonl")
30908
+ ).catch(() => null);
30909
+ if (!report) return null;
30910
+ return lastVerificationRun(report.events);
30911
+ }
30784
30912
  /** Mirror one BrainEvent (coalescing message deltas until message_end). */
30785
30913
  mirrorBrainEvent(ev) {
30786
30914
  if (this.status !== "active" || !this.writer) return;
@@ -39959,8 +40087,16 @@ __export(headlessSpine_exports, {
39959
40087
  missionStateFromSpine: () => missionStateFromSpine,
39960
40088
  openHeadlessSpine: () => openHeadlessSpine,
39961
40089
  resolveHeadlessProfileId: () => resolveHeadlessProfileId,
39962
- seedHeadlessModelHistory: () => seedHeadlessModelHistory
40090
+ seedHeadlessModelHistory: () => seedHeadlessModelHistory,
40091
+ sessionStartedEvent: () => sessionStartedEvent
39963
40092
  });
40093
+ function sessionStartedEvent(handle) {
40094
+ return {
40095
+ type: "session_started",
40096
+ sessionId: handle.sessionId,
40097
+ spine: handle.spine.status
40098
+ };
40099
+ }
39964
40100
  function resolveHeadlessProfileId(mode, explicit) {
39965
40101
  if (explicit) return resolveProfile(explicit).id;
39966
40102
  return defaultProfileForMode(mode ?? "kraken");
@@ -40002,6 +40138,9 @@ async function openHeadlessSpine(opts) {
40002
40138
  verificationRun(payload) {
40003
40139
  spine.verificationRun(payload);
40004
40140
  },
40141
+ lastVerificationRun() {
40142
+ return spine.lastVerificationRun();
40143
+ },
40005
40144
  missionPhase(phase2, note) {
40006
40145
  spine.missionPhase(phase2, note);
40007
40146
  },
@@ -55094,7 +55233,7 @@ function evaluateStrictBuildGate(mode) {
55094
55233
  }
55095
55234
  const checks = krakenRequiredChecks();
55096
55235
  const contract = krakenResultsToContract(checks, getKrakenCheckResults());
55097
- const evaluation = evaluateCompletion(contract.criteria, contract.results, STRICT_ALL_POLICY);
55236
+ const evaluation = evaluateCompletion(contract.criteria, contract.results, STRICT_BUILD_POLICY);
55098
55237
  const blocked = gate.blocked || evaluation.verdict !== "PASS";
55099
55238
  return {
55100
55239
  gate,
@@ -55104,6 +55243,10 @@ function evaluateStrictBuildGate(mode) {
55104
55243
  summary: blocked ? `blocked (strict ${evaluation?.verdict ?? "n/a"}): ${gate.passed}/${gate.total} legacy-pass, evidence ${evaluation?.evidenceComplete ? "complete" : "incomplete"}` : `open (strict PASS): ${evaluation?.satisfied.length ?? 0}/${gate.total} criteria pass with evidence`
55105
55244
  };
55106
55245
  }
55246
+ var STRICT_DONE_EXIT_CODE = 4;
55247
+ function strictGateExitCode(evaluation) {
55248
+ return evaluation.strict && evaluation.blocked ? STRICT_DONE_EXIT_CODE : 0;
55249
+ }
55107
55250
  function strictGateEventPayload(evaluation) {
55108
55251
  return {
55109
55252
  engine: "kraken-legacy+completion-policy",
@@ -55631,7 +55774,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
55631
55774
  });
55632
55775
  }
55633
55776
  const cwd = process.cwd();
55634
- const budget = await applyBudgetPolicyAsync(getHistory(), getPhase(), {
55777
+ const budget = await applyBudgetPolicyAsync(historyForModel, getPhase(), {
55635
55778
  model: getActiveModel(),
55636
55779
  sessionId: sessionId2,
55637
55780
  // v1.36.0: envelope for full-request metering + cache-aware
@@ -55657,6 +55800,7 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
55657
55800
  });
55658
55801
  void writerRef.current?.append(compactionEvent);
55659
55802
  }
55803
+ historyForModel = budget.history;
55660
55804
  historySeedLen = historyForModel.length;
55661
55805
  let composedWorkspace = "";
55662
55806
  let composedInstructions = "";
@@ -55892,6 +56036,15 @@ _(${req.context})_` : "") + "\n\u2192 scegli dalla lista (il turno continua dopo
55892
56036
  }
55893
56037
  if (event.reason === "completed" && krakenRepairEnqueued && !evaluateStrictBuildGate("build").blocked) {
55894
56038
  markRepairSucceeded();
56039
+ } else if (event.reason === "completed" && krakenRepairEnqueued) {
56040
+ const still = evaluateStrictBuildGate("build");
56041
+ if (still.blocked) {
56042
+ appendSystem(
56043
+ setMessages,
56044
+ `[kraken] strict done: evidence still incomplete after repair (${still.evaluation?.unsatisfied.length ?? "?"} unresolved) \u2014 turn is NOT verified-complete`,
56045
+ Date.now()
56046
+ );
56047
+ }
55895
56048
  }
55896
56049
  if (!krakenSuppressFinish) progressRuntime.finish(event.reason);
55897
56050
  }
@@ -56285,14 +56438,31 @@ async function dispatchCouncilPromptImpl(text, deps, overrides = {}) {
56285
56438
  return { completionOk: false, ran: false };
56286
56439
  }
56287
56440
  setBusy(true);
56288
- compactInPlace();
56289
- const councilBudget = await applyBudgetPolicyAsync(getHistory(), getPhase(), {
56441
+ let councilHistory = getHistory();
56442
+ {
56443
+ const mirror = writerRef.current?.spine ?? null;
56444
+ if (mirror && mirror.status === "active") {
56445
+ const derived = await mirror.derivedPriorTurns();
56446
+ if (derived && derived.length > 0) {
56447
+ councilHistory = derivedModelSeed(derived);
56448
+ }
56449
+ }
56450
+ }
56451
+ const councilBudget = await applyBudgetPolicyAsync(councilHistory, getPhase(), {
56290
56452
  model: envConfig.model
56291
56453
  });
56292
56454
  setHistory(councilBudget.history);
56293
56455
  for (const w of councilBudget.warnings) {
56294
56456
  appendSystem(setMessages, w, Date.now());
56295
56457
  }
56458
+ if ((councilBudget.messagesRemoved ?? 0) > 0) {
56459
+ void writerRef.current?.append(
56460
+ createBrainEvent("session_compacted", sessionId2, {
56461
+ summary: councilBudget.compactSummary ?? "",
56462
+ messagesRemoved: councilBudget.messagesRemoved ?? 0
56463
+ })
56464
+ );
56465
+ }
56296
56466
  const anchored = maybeAnchorShortAnswer(text);
56297
56467
  const effectiveText = anchored ?? text;
56298
56468
  appendSystem(
@@ -61550,6 +61720,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
61550
61720
  workspace: process.cwd()
61551
61721
  });
61552
61722
  const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
61723
+ emitEvent(sessionStartedEvent(spine));
61553
61724
  if (opts.task) spine.userMessage(opts.task);
61554
61725
  resetKrakenCandidates();
61555
61726
  resetKrakenTurnMetrics();
@@ -61862,6 +62033,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
61862
62033
  emittedWrites: pass.emittedWrites + retry.emittedWrites
61863
62034
  };
61864
62035
  }
62036
+ let strictExit = 0;
61865
62037
  if (pass.finalReason === "completed" && pass.exitCode === 0 && opts.mode === "kraken" && isKrakenSelectionEnabled() && !planModeFromOpts(opts)) {
61866
62038
  const strictGate = evaluateStrictBuildGate("build");
61867
62039
  const gate = strictGate.gate;
@@ -61903,6 +62075,13 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
61903
62075
  emitEvent({ type: "verification_run", ...afterPayload });
61904
62076
  }
61905
62077
  if (!after.blocked) markRepairSucceeded();
62078
+ else {
62079
+ strictExit = strictGateExitCode(after);
62080
+ const gateMsg = `[headless] Kraken BUILD: strict completion gate still blocked after repair pass \u2014 closing non-success (exit ${strictExit}): ${after.summary}`;
62081
+ if (opts.output === "json") emitEvent({ type: "log", message: gateMsg });
62082
+ else process.stderr.write(`[zelari-code --headless] ${gateMsg}
62083
+ `);
62084
+ }
61906
62085
  }
61907
62086
  }
61908
62087
  progressRuntime.finish(pass.finalReason);
@@ -61951,7 +62130,8 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
61951
62130
  }
61952
62131
  }
61953
62132
  try {
61954
- await spine.close(pass.finalReason === "error" ? "error" : "completed");
62133
+ const closeStatus = pass.finalReason === "error" ? "error" : strictExit !== 0 ? "stopped" : "completed";
62134
+ await spine.close(closeStatus);
61955
62135
  } catch {
61956
62136
  }
61957
62137
  if (opts.exportSessionPath) {
@@ -61968,6 +62148,7 @@ async function runHeadlessSingle(opts, provider, model, providerStream) {
61968
62148
  }
61969
62149
  }
61970
62150
  if (pass.finalReason === "error") return 3;
62151
+ if (strictExit !== 0) return strictExit;
61971
62152
  return pass.exitCode;
61972
62153
  }
61973
62154
  async function buildCouncilToolRegistry(planMode, opts) {
@@ -62007,6 +62188,7 @@ async function runHeadlessCouncil(opts, provider, model, providerStream) {
62007
62188
  workspace: process.cwd()
62008
62189
  });
62009
62190
  const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
62191
+ emitEvent(sessionStartedEvent(spine));
62010
62192
  if (opts.task) spine.userMessage(opts.task);
62011
62193
  const { shouldAllowCouncilBuild: shouldAllowCouncilBuild2 } = await Promise.resolve().then(() => (init_buildPolicy(), buildPolicy_exports));
62012
62194
  let councilRunMode = planModeFromOpts(opts) ? "design-phase" : "implementation";
@@ -62144,6 +62326,7 @@ async function runHeadlessZelari(opts, provider, model, providerStream) {
62144
62326
  workspace: projectRoot
62145
62327
  });
62146
62328
  const seededHistory = await seedHeadlessModelHistory(spine, opts.history);
62329
+ emitEvent(sessionStartedEvent(spine));
62147
62330
  if (opts.task) spine.userMessage(opts.task);
62148
62331
  spine.missionPhase("design", "mission-start");
62149
62332
  const { buildMissionBrief: buildMissionBrief2 } = await Promise.resolve().then(() => (init_council(), council_exports));