@tangle-network/agent-eval 0.186.2 → 0.187.1

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.
Files changed (55) hide show
  1. package/CHANGELOG.md +31 -0
  2. package/dist/analyst/index.d.ts +2 -2
  3. package/dist/analyst/index.js +2 -2
  4. package/dist/{benchmark-command-NATyhXB4.js → benchmark-command-CERRH0E6.js} +2 -2
  5. package/dist/{benchmark-command-NATyhXB4.js.map → benchmark-command-CERRH0E6.js.map} +1 -1
  6. package/dist/benchmarks/index.d.ts +72 -2
  7. package/dist/benchmarks/index.d.ts.map +1 -1
  8. package/dist/benchmarks/index.js +106 -2
  9. package/dist/benchmarks/index.js.map +1 -1
  10. package/dist/cli.js +2 -2
  11. package/dist/contract/index.js +1 -1
  12. package/dist/{default-registry-xiHrldW8.js → default-registry-Ca2IWH1X.js} +2 -2
  13. package/dist/{default-registry-xiHrldW8.js.map → default-registry-Ca2IWH1X.js.map} +1 -1
  14. package/dist/{exec-D9WpA2p-.js → exec-ChJ6d5if.js} +10 -6
  15. package/dist/exec-ChJ6d5if.js.map +1 -0
  16. package/dist/experiment/index.d.ts +155 -1
  17. package/dist/experiment/index.d.ts.map +1 -1
  18. package/dist/experiment/index.js +268 -2
  19. package/dist/experiment/index.js.map +1 -1
  20. package/dist/{index-C8jCAOTT.d.ts → index-vYNHCV2G.d.ts} +2 -2
  21. package/dist/{index-C8jCAOTT.d.ts.map → index-vYNHCV2G.d.ts.map} +1 -1
  22. package/dist/index.d.ts +47 -3
  23. package/dist/index.d.ts.map +1 -1
  24. package/dist/index.js +54 -2
  25. package/dist/index.js.map +1 -1
  26. package/dist/{integrity-CgQce0FV.js → integrity-BvHANvnp.js} +81 -11
  27. package/dist/integrity-BvHANvnp.js.map +1 -0
  28. package/dist/openapi.json +1 -1
  29. package/dist/{report-command-BvqaxlVG.js → report-command-CSTjzFGY.js} +104 -11
  30. package/dist/report-command-CSTjzFGY.js.map +1 -0
  31. package/dist/{steps-CiNVJry_.d.ts → steps-Bg5-KVx1.d.ts} +4 -4
  32. package/dist/{steps-CiNVJry_.d.ts.map → steps-Bg5-KVx1.d.ts.map} +1 -1
  33. package/dist/supervisor-run/index.d.ts +3 -3
  34. package/dist/supervisor-run/index.d.ts.map +1 -1
  35. package/dist/supervisor-run/index.js +2 -2
  36. package/dist/terminal-record-BHocwFw1.js.map +1 -1
  37. package/dist/trace-repair/index.d.ts +1 -1
  38. package/dist/trace-repair/index.js +1 -1
  39. package/dist/trajectory-replay/index.d.ts +11 -11
  40. package/dist/trajectory-replay/index.d.ts.map +1 -1
  41. package/dist/trajectory-replay/index.js +35 -16
  42. package/dist/trajectory-replay/index.js.map +1 -1
  43. package/dist/{types-c3ZRTbw9.d.ts → types--18oHwVF.d.ts} +10 -1
  44. package/dist/types--18oHwVF.d.ts.map +1 -0
  45. package/dist/{types-BlIJ5URG.d.ts → types-Tp5WhYL9.d.ts} +27 -2
  46. package/dist/types-Tp5WhYL9.d.ts.map +1 -0
  47. package/docs/adapters-observability.md +26 -0
  48. package/docs/experiment.md +94 -0
  49. package/docs/trajectory-replay.md +9 -4
  50. package/package.json +2 -1
  51. package/dist/exec-D9WpA2p-.js.map +0 -1
  52. package/dist/integrity-CgQce0FV.js.map +0 -1
  53. package/dist/report-command-BvqaxlVG.js.map +0 -1
  54. package/dist/types-BlIJ5URG.d.ts.map +0 -1
  55. package/dist/types-c3ZRTbw9.d.ts.map +0 -1
@@ -4,7 +4,7 @@ import { t as TraceEmitter } from "../emitter-DeQHiDMm.js";
4
4
  import { t as runCounterfactual } from "../counterfactual-Bjq1mlUu.js";
5
5
  import { n as InMemoryTraceStore } from "../store-DNe_Uv1Q.js";
6
6
  import { t as packageVersion } from "../package-version-D7lQHt_-.js";
7
- import { a as assertReplayableTrajectory, c as deriveFailureSignature, d as isRecordedTimeout, f as isSubmitAction, g as unreadableExitCount, h as parseRecordedReturncode, i as TIMEOUT_OBSERVATION_MARKER, l as finalRecordedOutcome, m as parseObservationOutput, n as FORMAT_ERROR_OBSERVATION_PREFIX, o as classifyObservation, p as isSubmitOnlyAction, r as SUBMIT_ACTION_SIGNATURE, s as decodeRecordedTurns, t as wrapActionForExec, u as isElidedField } from "../exec-D9WpA2p-.js";
7
+ import { a as assertReplayableTrajectory, c as deriveFailureSignature, d as isRecordedTimeout, f as isSubmitAction, g as unreadableExitCount, h as parseRecordedReturncode, i as TIMEOUT_OBSERVATION_MARKER, l as finalRecordedOutcome, m as parseObservationOutput, n as FORMAT_ERROR_OBSERVATION_PREFIX, o as classifyObservation, p as isSubmitOnlyAction, r as SUBMIT_ACTION_SIGNATURE, s as decodeRecordedTurns, t as wrapActionForExec, u as isElidedField } from "../exec-ChJ6d5if.js";
8
8
  import { createHash } from "node:crypto";
9
9
  import { appendFileSync, existsSync, mkdirSync, mkdtempSync, readFileSync, readdirSync, writeFileSync } from "node:fs";
10
10
  import { join } from "node:path";
@@ -198,7 +198,7 @@ function enumerateReplayableCases(corpora) {
198
198
  missingGoldId = goldId;
199
199
  break;
200
200
  }
201
- if (isSubmitAction(step.action)) {
201
+ if (step.action.trim() === "submit" || isSubmitOnlyAction(step.action)) {
202
202
  submitGoldsSkipped += 1;
203
203
  continue;
204
204
  }
@@ -223,12 +223,22 @@ function enumerateReplayableCases(corpora) {
223
223
  });
224
224
  continue;
225
225
  }
226
+ const recordedReturncodeAtK = parseRecordedReturncode(target.observation);
227
+ if (recordedReturncodeAtK === null) {
228
+ excluded.push({
229
+ corpus: corpus.name,
230
+ trajId,
231
+ reason: "no-recorded-returncode-at-k",
232
+ detail: `k=${target.step_id}; arm A cannot confirm execution without a recorded returncode`
233
+ });
234
+ continue;
235
+ }
226
236
  replayable.push({
227
237
  ...resources,
228
238
  goldIncorrectSteps: gold,
229
239
  k: target.step_id,
230
240
  submitGoldsSkipped,
231
- recordedReturncodeAtK: parseRecordedReturncode(target.observation)
241
+ recordedReturncodeAtK
232
242
  });
233
243
  }
234
244
  return {
@@ -831,7 +841,7 @@ async function replayVerify(options) {
831
841
  if (target.step_id !== options.at) throw new Error(`trajectory-replay: steps[${index}].step_id=${target.step_id} != at ${options.at}; steps.json must be ordered with 1-based contiguous step_ids`);
832
842
  const caseId = options.caseId ?? options.stepsPath;
833
843
  const recordedReturncode = parseRecordedReturncode(target.observation);
834
- const signature = options.signature ?? deriveFailureSignature(target.observation);
844
+ const signature = options.signature === void 0 ? deriveFailureSignature(target.observation) : options.signature.trim() || null;
835
845
  const signatureBasis = signature ? "returncode+output-substring" : "returncode-only";
836
846
  const runnerOptions = {
837
847
  cwd: options.cwd,
@@ -853,7 +863,9 @@ async function replayVerify(options) {
853
863
  const armAMs = Date.now() - armAStart;
854
864
  const armAExec = requireExec(armARunner, "arm A");
855
865
  const armAOutput = `${armAExec.stdout}\n${armAExec.stderr}`;
856
- const failureSignatureMatch = recordedReturncode !== null && armAExec.exitCode === recordedReturncode && (signature ? armAOutput.includes(signature) : true);
866
+ const returncodeMatch = recordedReturncode !== null && armAExec.exitCode === recordedReturncode;
867
+ const failureSignatureMatch = returncodeMatch && signature !== null && armAOutput.includes(signature);
868
+ const failureReproduced = recordedReturncode !== 0 && returncodeMatch && (signature === null || failureSignatureMatch);
857
869
  let armBRunner = null;
858
870
  let armBExec = null;
859
871
  let armBRunId = null;
@@ -909,7 +921,7 @@ async function replayVerify(options) {
909
921
  exitCode: armBExec.exitCode,
910
922
  wallMs: armBExec.wallMs,
911
923
  prefix: requirePrefix(armBRunner, "arm B"),
912
- failureVanished: armBExec.exitCode === 0 && (signature && armBOutput ? !armBOutput.includes(signature) : true)
924
+ failureVanished: requirePrefix(armBRunner, "arm B").prefixWithinTolerance && armBExec.exitCode === 0 && (signature && armBOutput ? !armBOutput.includes(signature) : true)
913
925
  } : null,
914
926
  timings: {
915
927
  armAMs,
@@ -926,14 +938,15 @@ async function replayVerify(options) {
926
938
  if (armAPrefix.prefixUnknownExpectations > 0) assumptions.push(`${armAPrefix.prefixUnknownExpectations} prefix step(s) carry no recorded returncode — agreement with the recording is unestablished there`);
927
939
  if (options.prefixLimit !== void 0 && options.prefixLimit < index) assumptions.push(`prefix truncated at ${options.prefixLimit} of ${index} recorded steps — state fidelity at k is weakened`);
928
940
  if (signatureBasis === "returncode-only") assumptions.push("no output substring derived from the recording — reproduction rests on the returncode alone");
929
- const valid = core.prefixWithinTolerance && failureSignatureMatch && (core.armB === null || core.armB.failureVanished);
941
+ if (core.armB !== null && !core.armB.prefix.prefixWithinTolerance) assumptions.push("arm B prefix diverged beyond tolerance — the corrected step ran from a different state");
942
+ const valid = core.prefixWithinTolerance && failureReproduced && (core.armB === null || core.armB.failureVanished);
930
943
  const verdict = {
931
944
  ...core,
932
945
  valid,
933
946
  score: valid ? 1 : 0,
934
947
  scores: {
935
948
  prefixFidelity: 1 - core.prefixDivergencePct / 100,
936
- armAReproduced: failureSignatureMatch ? 1 : 0,
949
+ armAReproduced: failureReproduced ? 1 : 0,
937
950
  ...core.armB === null ? {} : { armBFailureVanished: core.armB.failureVanished ? 1 : 0 }
938
951
  },
939
952
  certification: {
@@ -1037,8 +1050,9 @@ function renderReport(verdict, target, armA, armB) {
1037
1050
  *
1038
1051
  * Headline metrics:
1039
1052
  * replayability rate — fraction of replayable cases where the prefix
1040
- * replays within the divergence tolerance AND arm A reproduces the
1041
- * recorded returncode at k;
1053
+ * replays within the divergence tolerance AND arm A reproduces a
1054
+ * recorded failure at k; a zero exit without an error signature is not
1055
+ * evidence of failure;
1042
1056
  * prefix fidelity — executed prefix steps and the share of them that did
1043
1057
  * not confirm the recording, split by kind. A corpus whose recordings
1044
1058
  * carry no returncodes shows up here as unknown-expectation steps, never
@@ -1097,7 +1111,7 @@ async function executeArmB(replayCase, fixCommand, backend, signature, stepTimeo
1097
1111
  prefixExecuted: prefix.prefixExecuted,
1098
1112
  prefixDivergences: prefix.prefixDivergences.length,
1099
1113
  prefixDivergencePct: prefix.prefixDivergencePct,
1100
- failureVanished: exec.exitCode === 0 && (signature ? !output.includes(signature) : true),
1114
+ failureVanished: prefix.prefixWithinTolerance && exec.exitCode === 0 && (signature ? !output.includes(signature) : true),
1101
1115
  stdout: exec.stdout,
1102
1116
  stderr: exec.stderr
1103
1117
  };
@@ -1205,7 +1219,7 @@ async function runReplayBatch(options) {
1205
1219
  armAExit: verdict.armA.exitCode,
1206
1220
  armAReturncodeMatch: returncodeMatch,
1207
1221
  armASignatureMatch: verdict.armA.failureSignatureMatch,
1208
- replayed: verdict.prefixWithinTolerance && returncodeMatch,
1222
+ replayed: verdict.valid,
1209
1223
  fix: null,
1210
1224
  wallMs: Date.now() - caseStart
1211
1225
  };
@@ -1557,7 +1571,7 @@ function renderBatchReport(report) {
1557
1571
  lines.push("## Headline");
1558
1572
  lines.push("");
1559
1573
  const fidelity = headline.prefixFidelity;
1560
- lines.push(`- **Replayability rate: ${pct(headline.replayabilityRate.value)}** (${headline.replayabilityRate.numerator}/${headline.replayabilityRate.denominator} replayable cases where the prefix replayed within ${fidelity.tolerancePct}% divergence AND arm A reproduced the recorded returncode at the gold step k).`);
1574
+ lines.push(`- **Replayability rate: ${pct(headline.replayabilityRate.value)}** (${headline.replayabilityRate.numerator}/${headline.replayabilityRate.denominator} replayable cases where the prefix replayed within ${fidelity.tolerancePct}% divergence AND arm A reproduced an observed failure at the gold step k).`);
1561
1575
  lines.push(`- Signature-strict rate: ${pct(headline.signatureStrictRate.value)} (${headline.signatureStrictRate.numerator}/${headline.signatureStrictRate.denominator}; additionally requires the recorded error substring in arm A output).`);
1562
1576
  lines.push(`- **Prefix divergence: ${fidelity.divergencePct === null ? "—" : `${fidelity.divergencePct}%`}** (${fidelity.divergentSteps}/${fidelity.executedSteps} executed prefix steps did not confirm the recording: ${fidelity.returncodeMismatches} returncode mismatches, ${fidelity.unknownExpectations} with no recorded returncode to check). ${fidelity.casesWithinTolerance}/${fidelity.casesExecuted} executed cases are within the ${fidelity.tolerancePct}% tolerance.`);
1563
1577
  if (headline.fixFlipRate) lines.push(`- **Fix-flip rate: ${pct(headline.fixFlipRate.value)}** (${headline.fixFlipRate.numerator}/${headline.fixFlipRate.denominator} arm-B-executed cases where the generated fix made the failure vanish).`);
@@ -1671,7 +1685,11 @@ function resolveFindingInvocation(finding, corpora) {
1671
1685
  const resolution = resolveCaseResources(corpus, finding.trajId);
1672
1686
  if (resolution.resolved) {
1673
1687
  const at = subject.firstStep;
1674
- if (!resolution.resources.steps.find((s) => s.step_id === at)) throw new Error(`trajectory-replay: finding step ${at} is outside ${finding.trajId} (${resolution.resources.steps.length} steps)`);
1688
+ const step = resolution.resources.steps.find((s) => s.step_id === at);
1689
+ if (!step) throw new Error(`trajectory-replay: finding step ${at} is outside ${finding.trajId} (${resolution.resources.steps.length} steps)`);
1690
+ const recordedReturncode = parseRecordedReturncode(step.observation);
1691
+ if (recordedReturncode === null) throw new Error(`trajectory-replay: finding step ${at} in ${finding.trajId} has no recorded returncode`);
1692
+ if (recordedReturncode === 0) throw new Error(`trajectory-replay: finding step ${at} in ${finding.trajId} exited 0; shell replay cannot verify its semantic error`);
1675
1693
  return {
1676
1694
  resources: resolution.resources,
1677
1695
  subject,
@@ -1876,14 +1894,14 @@ function resolveFindingReplayability(finding, source) {
1876
1894
  };
1877
1895
  }
1878
1896
  /**
1879
- * Arm A reproduced on a prefix the recording confirmed → the fix flipping it
1897
+ * Arm A reproduced an observed failure on a confirmed prefix → a fix flipping it
1880
1898
  * beats plain reproduction; anything else diverged. A proof standing on a
1881
1899
  * prefix outside the divergence tolerance is divergent no matter what arm A
1882
1900
  * did: the state it ran against is not the recorded state.
1883
1901
  */
1884
1902
  function classifyVerdict(verdict) {
1885
1903
  if (!verdict.prefixWithinTolerance) return "divergent";
1886
- if (!verdict.armA.failureSignatureMatch) return "divergent";
1904
+ if (verdict.scores?.armAReproduced !== 1) return "divergent";
1887
1905
  if (verdict.armB?.failureVanished) return "fix-flipped";
1888
1906
  return "reproduced";
1889
1907
  }
@@ -1898,6 +1916,7 @@ function receiptExecution(verdict) {
1898
1916
  command: verdict.armA.command,
1899
1917
  exitCode: verdict.armA.exitCode,
1900
1918
  wallMs: verdict.armA.wallMs,
1919
+ reproduced: verdict.scores?.armAReproduced === 1,
1901
1920
  failureSignatureMatch: verdict.armA.failureSignatureMatch
1902
1921
  },
1903
1922
  armB: verdict.armB ? {