@tangle-network/traces 0.11.0 → 0.11.3

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 CHANGED
@@ -15,6 +15,7 @@ import {
15
15
  CopilotAdapter,
16
16
  DEFAULT_HARNESS,
17
17
  EMPTY_SPAN_RUN_SNAPSHOT,
18
+ EXPORT_RULE,
18
19
  EmptySessionError,
19
20
  FactoryAdapter,
20
21
  ForgeAdapter,
@@ -31,6 +32,8 @@ import {
31
32
  RULE,
32
33
  SPAWN_JOURNAL_FILE,
33
34
  STATUS_MARK,
35
+ SUBMIT_ACTION_SIGNATURE,
36
+ SandboxCounterfactualRunner,
34
37
  SessionWorkflowError,
35
38
  TRACES_REDACTION_RULES,
36
39
  ZERO_ROLL,
@@ -38,9 +41,12 @@ import {
38
41
  alreadyUploaded,
39
42
  analyzeAdoption,
40
43
  analyzeLiveBatch,
44
+ analyzeLoopConvergence,
41
45
  analyzeReactions,
42
46
  analyzeSpans,
47
+ analyzeSteeringChain,
43
48
  applyRedactor,
49
+ buildFixPrompt,
44
50
  buildPolicyEvidenceRecord,
45
51
  buildSessionIndex,
46
52
  buildSessionIndexFromRows,
@@ -51,6 +57,8 @@ import {
51
57
  classifyLiveActions,
52
58
  classifyReaction,
53
59
  claudeActor,
60
+ cmdReplayVerify,
61
+ cmdReplayVerifyBatch,
54
62
  codexActor,
55
63
  collectPolicyEvidence,
56
64
  collectSessionIndex,
@@ -58,29 +66,41 @@ import {
58
66
  collectSessionWorkflow,
59
67
  commandAnalyzer,
60
68
  commandRedactor,
69
+ conformanceOfSpans,
61
70
  connectors,
62
71
  countSkillRunsJsonl,
63
72
  cwdMatchesSelection,
64
73
  defaultTraceLiveAnalysts,
74
+ deriveFailureSignature,
75
+ derivedImageTag,
65
76
  describeSessionRelationship,
77
+ dockerImagePreparer,
78
+ enumerateReplayableCases,
66
79
  equivalentGitCwds,
67
80
  executeUpload,
68
81
  exportTraceEvidenceFile,
69
82
  exportTraceEvidenceRows,
70
83
  exportTraceEvidenceText,
84
+ extractFixCommand,
71
85
  fileRunContextSupervisorRunReader,
72
86
  findSpanSourceFiles,
73
87
  forEachTreeNode,
88
+ generateFixCommand,
89
+ goldIncorrectSteps,
74
90
  haloAnalyzer,
75
91
  hodoscopeAnalyzer,
76
92
  importCodeTraceBench,
93
+ incompleteInputsNote,
77
94
  indexSessionIdsByTrace,
78
95
  inferRole,
96
+ inferSpanKind,
97
+ ingestCodeTraceBenchSteps,
79
98
  inspectSessionIndex,
80
99
  int,
81
100
  isChatTrajectory,
82
101
  isChatTrajectoryMessage,
83
102
  isFileRunContextDir,
103
+ isSubmitAction,
84
104
  knownHarnesses,
85
105
  listAdapters,
86
106
  loadState,
@@ -91,8 +111,14 @@ import {
91
111
  mergeTracesConfig,
92
112
  ms,
93
113
  normalizeRemote,
114
+ otlpRowToSpan,
94
115
  outboundHash,
116
+ parseCorpusFlag,
95
117
  parseIsoToEpochMs,
118
+ parseObservationOutput,
119
+ parseRecordedReturncode,
120
+ parseReplayBatchArgs,
121
+ parseReplayVerifyArgs,
96
122
  parseSession,
97
123
  parseSince,
98
124
  planTraceAgenticRoute,
@@ -101,6 +127,8 @@ import {
101
127
  readFileRunContext,
102
128
  readJsonFile,
103
129
  readJsonl,
130
+ readLabelEntries,
131
+ readOtlpInput,
104
132
  readRunContextJournal,
105
133
  readRunContextSnapshot,
106
134
  readRunWatchSnapshot,
@@ -108,11 +136,19 @@ import {
108
136
  readSpanRunSnapshot,
109
137
  recordSessionCorruption,
110
138
  redactSpans,
139
+ renderBatchReport,
140
+ renderConformance,
111
141
  renderInspectionReport,
112
142
  renderRunContextSnapshot,
113
143
  renderRunWatchSnapshot,
114
144
  renderSpanRunSnapshot,
145
+ renderValidation,
146
+ replayBatchUsage,
147
+ replayVerify,
148
+ replayVerifyUsage,
115
149
  resolveAdapter,
150
+ resolveCaseResources,
151
+ resolveOtlpInputFiles,
116
152
  resolveRepoAttrs,
117
153
  resolveRunContextDir,
118
154
  resolveRunWatchTarget,
@@ -120,13 +156,16 @@ import {
120
156
  runCommand,
121
157
  runExternalAnalyzers,
122
158
  runPipelines,
159
+ runReplayBatch,
123
160
  runTotals,
124
161
  runTraceImprovement,
125
162
  runTraceInvestigation,
126
163
  runTraceStoreInvestigation,
164
+ sandboxReplayBackend,
127
165
  saveReport,
128
166
  saveState,
129
167
  scanSessions,
168
+ seededSample,
130
169
  selectAdapters,
131
170
  serializeInspectionReport,
132
171
  serializePolicyEvidence,
@@ -136,6 +175,7 @@ import {
136
175
  sessionHash,
137
176
  sessionIdFromAttributes,
138
177
  sessionIntegrityAttributes,
178
+ skippedAnalyses,
139
179
  span,
140
180
  spanRunTotals,
141
181
  stampRepoAttrs,
@@ -145,6 +185,7 @@ import {
145
185
  streamSessions,
146
186
  summarizeOtlpExecution,
147
187
  summarizeSpanExecution,
188
+ summarizeSpanStructure,
148
189
  takeJsonl,
149
190
  textIsSynthetic,
150
191
  toOpenInferenceSpan,
@@ -154,13 +195,16 @@ import {
154
195
  totalAgenticFailureMessage,
155
196
  traceAgenticKinds,
156
197
  traceStreamEventsFromSpans,
198
+ unavailableCapabilities,
157
199
  uploadKey,
158
200
  usd,
159
201
  userPromptSpan,
160
202
  validateOtlpSpans,
203
+ validationExitCode,
161
204
  watchRunTarget,
162
205
  watchSessions,
163
206
  wrap,
207
+ wrapActionForExec,
164
208
  writeHodoscopeInput,
165
209
  writeInspectionReportFile,
166
210
  writeOtlpFile,
@@ -168,8 +212,9 @@ import {
168
212
  writeSessionIndexFile,
169
213
  writeTraceEvidenceExportFile,
170
214
  writeTraceImprovementArtifacts,
215
+ zaiChatCaller,
171
216
  zeroPricedCost
172
- } from "./chunk-JCI5YXNT.js";
217
+ } from "./chunk-CK5F5TWO.js";
173
218
 
174
219
  // src/collect.ts
175
220
  async function collectSessions(opts = {}) {
@@ -185,6 +230,79 @@ async function collectSessions(opts = {}) {
185
230
  return out;
186
231
  }
187
232
 
233
+ // src/replay-wire.ts
234
+ var SUBJECT_PATTERN = /^incorrect-steps-(\d+)-(\d+)-(escaped|unescaped)-consequence-(\d+)$/;
235
+ function parseIncorrectStepsSubject(subject) {
236
+ const match = SUBJECT_PATTERN.exec(subject);
237
+ if (!match) return null;
238
+ return {
239
+ firstStep: Number(match[1]),
240
+ lastStep: Number(match[2]),
241
+ escapeStatus: match[3],
242
+ consequenceStep: Number(match[4])
243
+ };
244
+ }
245
+ function resolveFindingInvocation(finding, corpora) {
246
+ const subject = parseIncorrectStepsSubject(finding.subject);
247
+ if (!subject) {
248
+ throw new Error(
249
+ `replay-wire: subject '${finding.subject}' is not incorrect-steps-<first>-<last>-<escaped|unescaped>-consequence-<step>`
250
+ );
251
+ }
252
+ const failures = [];
253
+ for (const corpus of corpora) {
254
+ const resolution = resolveCaseResources(corpus, finding.trajId);
255
+ if (resolution.resolved) {
256
+ const at = subject.firstStep;
257
+ const step = resolution.resources.steps.find((s) => s.step_id === at);
258
+ if (!step) {
259
+ throw new Error(
260
+ `replay-wire: finding step ${at} is outside ${finding.trajId} (${resolution.resources.steps.length} steps)`
261
+ );
262
+ }
263
+ return { resources: resolution.resources, subject, at };
264
+ }
265
+ failures.push(`${corpus.name}: ${resolution.reason}`);
266
+ }
267
+ throw new Error(
268
+ `replay-wire: trajectory ${finding.trajId} is not replayable in any corpus \u2014 ${failures.join("; ")}`
269
+ );
270
+ }
271
+ async function replayVerifyFinding(finding, options) {
272
+ if (options.fixCaller && options.fixCommand !== void 0) {
273
+ throw new Error("replay-wire: pass fixCaller or fixCommand, not both");
274
+ }
275
+ const invocation = resolveFindingInvocation(finding, options.corpora);
276
+ let fixCommand = options.fixCommand ?? null;
277
+ if (options.fixCaller) {
278
+ const generated = await generateFixCommand(options.fixCaller, {
279
+ taskStatement: invocation.resources.taskStatement,
280
+ steps: invocation.resources.steps,
281
+ k: invocation.at
282
+ });
283
+ if (!generated.succeeded) {
284
+ throw new Error(`replay-wire: fix generation failed \u2014 ${generated.error}`);
285
+ }
286
+ fixCommand = generated.value.command;
287
+ }
288
+ const verdict = await replayVerify({
289
+ stepsPath: invocation.resources.stepsPath,
290
+ image: invocation.resources.image,
291
+ at: invocation.at,
292
+ fixCommand: fixCommand ?? void 0,
293
+ cwd: invocation.resources.cwd,
294
+ out: options.out,
295
+ caseId: invocation.resources.trajId,
296
+ stepTimeoutMs: options.stepTimeoutMs ?? invocation.resources.recordedStepTimeoutMs ?? void 0,
297
+ prefixLimit: options.prefixLimit,
298
+ backend: options.backend,
299
+ apiKey: options.apiKey,
300
+ baseUrl: options.baseUrl,
301
+ onProgress: options.onProgress
302
+ });
303
+ return { invocation, fixCommand, verdict };
304
+ }
305
+
188
306
  // src/index.ts
189
307
  import {
190
308
  AnalystRegistry,
@@ -212,6 +330,7 @@ export {
212
330
  DEFAULT_HARNESS,
213
331
  DEFAULT_REDACTION_RULES,
214
332
  EMPTY_SPAN_RUN_SNAPSHOT,
333
+ EXPORT_RULE,
215
334
  EmptySessionError,
216
335
  FactoryAdapter,
217
336
  ForgeAdapter,
@@ -228,6 +347,8 @@ export {
228
347
  RULE,
229
348
  SPAWN_JOURNAL_FILE,
230
349
  STATUS_MARK,
350
+ SUBMIT_ACTION_SIGNATURE,
351
+ SandboxCounterfactualRunner,
231
352
  SessionWorkflowError,
232
353
  TRACES_REDACTION_RULES,
233
354
  ZERO_ROLL,
@@ -235,10 +356,13 @@ export {
235
356
  alreadyUploaded,
236
357
  analyzeAdoption,
237
358
  analyzeLiveBatch,
359
+ analyzeLoopConvergence,
238
360
  analyzeReactions,
239
361
  analyzeSpans,
362
+ analyzeSteeringChain,
240
363
  applyRedactor,
241
364
  buildDefaultAnalystRegistry,
365
+ buildFixPrompt,
242
366
  buildPolicyEvidenceRecord,
243
367
  buildSessionIndex,
244
368
  buildSessionIndexFromRows,
@@ -249,6 +373,8 @@ export {
249
373
  classifyLiveActions,
250
374
  classifyReaction,
251
375
  claudeActor,
376
+ cmdReplayVerify,
377
+ cmdReplayVerifyBatch,
252
378
  codexActor,
253
379
  collectPolicyEvidence,
254
380
  collectSessionIndex,
@@ -257,31 +383,43 @@ export {
257
383
  collectSessions,
258
384
  commandAnalyzer,
259
385
  commandRedactor,
386
+ conformanceOfSpans,
260
387
  connectors,
261
388
  countSkillRunsJsonl,
262
389
  createHostedClient,
263
390
  cwdMatchesSelection,
264
391
  defaultTraceLiveAnalysts,
392
+ deriveFailureSignature,
393
+ derivedImageTag,
265
394
  describeSessionRelationship,
395
+ dockerImagePreparer,
396
+ enumerateReplayableCases,
266
397
  equivalentGitCwds,
267
398
  executeUpload,
268
399
  exportTraceEvidenceFile,
269
400
  exportTraceEvidenceRows,
270
401
  exportTraceEvidenceText,
402
+ extractFixCommand,
271
403
  fileRunContextSupervisorRunReader,
272
404
  findSpanSourceFiles,
273
405
  forEachTreeNode,
406
+ generateFixCommand,
407
+ goldIncorrectSteps,
274
408
  haloAnalyzer,
275
409
  hodoscopeAnalyzer,
276
410
  hostedClientFromEnv,
277
411
  importCodeTraceBench,
412
+ incompleteInputsNote,
278
413
  indexSessionIdsByTrace,
279
414
  inferRole,
415
+ inferSpanKind,
416
+ ingestCodeTraceBenchSteps,
280
417
  inspectSessionIndex,
281
418
  int,
282
419
  isChatTrajectory,
283
420
  isChatTrajectoryMessage,
284
421
  isFileRunContextDir,
422
+ isSubmitAction,
285
423
  knownHarnesses,
286
424
  listAdapters,
287
425
  loadState,
@@ -293,8 +431,15 @@ export {
293
431
  mergeTracesConfig,
294
432
  ms,
295
433
  normalizeRemote,
434
+ otlpRowToSpan,
296
435
  outboundHash,
436
+ parseCorpusFlag,
437
+ parseIncorrectStepsSubject,
297
438
  parseIsoToEpochMs,
439
+ parseObservationOutput,
440
+ parseRecordedReturncode,
441
+ parseReplayBatchArgs,
442
+ parseReplayVerifyArgs,
298
443
  parseSession,
299
444
  parseSince,
300
445
  planTraceAgenticRoute,
@@ -303,6 +448,8 @@ export {
303
448
  readFileRunContext,
304
449
  readJsonFile,
305
450
  readJsonl,
451
+ readLabelEntries,
452
+ readOtlpInput,
306
453
  readRunContextJournal,
307
454
  readRunContextSnapshot,
308
455
  readRunWatchSnapshot,
@@ -312,11 +459,21 @@ export {
312
459
  redactSpans,
313
460
  redactString,
314
461
  redactValue,
462
+ renderBatchReport,
463
+ renderConformance,
315
464
  renderInspectionReport,
316
465
  renderRunContextSnapshot,
317
466
  renderRunWatchSnapshot,
318
467
  renderSpanRunSnapshot,
468
+ renderValidation,
469
+ replayBatchUsage,
470
+ replayVerify,
471
+ replayVerifyFinding,
472
+ replayVerifyUsage,
319
473
  resolveAdapter,
474
+ resolveCaseResources,
475
+ resolveFindingInvocation,
476
+ resolveOtlpInputFiles,
320
477
  resolveRepoAttrs,
321
478
  resolveRunContextDir,
322
479
  resolveRunWatchTarget,
@@ -324,13 +481,16 @@ export {
324
481
  runCommand,
325
482
  runExternalAnalyzers,
326
483
  runPipelines,
484
+ runReplayBatch,
327
485
  runTotals,
328
486
  runTraceImprovement,
329
487
  runTraceInvestigation,
330
488
  runTraceStoreInvestigation,
489
+ sandboxReplayBackend,
331
490
  saveReport,
332
491
  saveState,
333
492
  scanSessions,
493
+ seededSample,
334
494
  selectAdapters,
335
495
  serializeInspectionReport,
336
496
  serializePolicyEvidence,
@@ -340,6 +500,7 @@ export {
340
500
  sessionHash,
341
501
  sessionIdFromAttributes,
342
502
  sessionIntegrityAttributes,
503
+ skippedAnalyses,
343
504
  span,
344
505
  spanRunTotals,
345
506
  stampRepoAttrs,
@@ -349,6 +510,7 @@ export {
349
510
  streamSessions,
350
511
  summarizeOtlpExecution,
351
512
  summarizeSpanExecution,
513
+ summarizeSpanStructure,
352
514
  takeJsonl,
353
515
  textIsSynthetic,
354
516
  toOpenInferenceSpan,
@@ -358,13 +520,16 @@ export {
358
520
  totalAgenticFailureMessage,
359
521
  traceAgenticKinds,
360
522
  traceStreamEventsFromSpans,
523
+ unavailableCapabilities,
361
524
  uploadKey,
362
525
  usd,
363
526
  userPromptSpan,
364
527
  validateOtlpSpans,
528
+ validationExitCode,
365
529
  watchRunTarget,
366
530
  watchSessions,
367
531
  wrap,
532
+ wrapActionForExec,
368
533
  writeHodoscopeInput,
369
534
  writeInspectionReportFile,
370
535
  writeOtlpFile,
@@ -372,5 +537,6 @@ export {
372
537
  writeSessionIndexFile,
373
538
  writeTraceEvidenceExportFile,
374
539
  writeTraceImprovementArtifacts,
540
+ zaiChatCaller,
375
541
  zeroPricedCost
376
542
  };
@@ -0,0 +1,76 @@
1
+ # Replay-verify batch — first measured replayability and fix-flip rates (2026-08-02)
2
+
3
+ Provenance: labels shas in `~/bench-cache/ctb-20260801/replay-batch/label-shas.txt`; docker 29.6.1; node v24.16.0; orchestrator :4095 + SDK adapter :4097; seed 17; fix model glm-5.2 via z.ai direct (16k cap, one doubled retry on length-empty); command recorded in `run2-20260802.log` header.
4
+ Corpora: dev-32, holdout-1, holdout-2, split3 (all spent mini-SWE splits; submit-only golds excluded per the split3 positional-degeneracy finding).
5
+
6
+ ## Headline (n=22 replayable of 133 label entries)
7
+
8
+ | Rate | Value |
9
+ | --- | --- |
10
+ | Replayability (prefix ≤10% divergence AND arm A reproduces recorded returncode at the gold step) | 16/22 = 72.7% |
11
+ | Strict signature match (returncode + output substring) | 13/22 = 59.1% |
12
+ | Fix-flip (one-shot glm-5.2 corrected command makes the failure vanish) | 9/11 = 81.8% |
13
+ | Fix-flip, nonzero-returncode subset | 7/9 = 77.8% |
14
+
15
+ Exclusions (101 of 133, all named): 65 no-swe-raw-trajectory, 21 no-docker-image, 21 gold-only-submit-step, 4 no-gold-incorrect-step.
16
+ LLM: 16 calls, 5 residual failures (long-reasoning cases exceeding the doubled cap), 41,878 prompt + 51,312 completion tokens (~$0.14).
17
+
18
+
19
+ Generated 2026-08-02T00:55:37.309Z.
20
+
21
+ ## Headline
22
+
23
+ - **Replayability rate: 72.7%** (16/22 replayable cases where the prefix replayed with ≤10% returncode divergence AND arm A reproduced the recorded returncode at the gold step k).
24
+ - Signature-strict rate: 59.1% (13/22; additionally requires the recorded error substring in arm A output).
25
+ - **Fix-flip rate: 81.8%** (9/11 arm-B-executed cases where the generated fix made the failure vanish).
26
+ - Fix-flip rate on recorded-rc≠0 cases: 77.8% (7/9; real recorded failures — a gold step recorded with rc 0 flips vacuously).
27
+
28
+ ## Enumeration
29
+
30
+ 133 label entries across 4 corpora → 22 replayable (SWE-style docker image + ≥1 gold incorrect step), 22 executed.
31
+
32
+ | exclusion reason | count |
33
+ | --- | --- |
34
+ | no-swe-raw-trajectory | 65 |
35
+ | no-docker-image | 21 |
36
+ | gold-only-submit-step | 21 |
37
+ | no-gold-incorrect-step | 4 |
38
+
39
+ Submit-command golds are never counterfactual targets (a gold on the submit step marks a bad submit decision, not a failed command):
40
+
41
+ | corpus | cases excluded (all golds = submit) | golds skipped within replayable cases |
42
+ | --- | --- | --- |
43
+ | dev-32 | 1 | 0 |
44
+ | holdout-1 | 2 | 0 |
45
+ | split3 | 18 | 0 |
46
+
47
+ ## Per-case results
48
+
49
+ | corpus | trajectory | k | rc@k | prefix | div | div% | armA exit | rc match | sig match | replayed | fix | armB exit | vanished | wall s |
50
+ | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- | --- |
51
+ holdout-1 | miniswe-OpenAI__GPT-5-clap-rs__clap-3179-107b… | 33 | 0 | 32 | 4 | 12.5 | 0 | yes | yes | no | — | — | — | 10.6
52
+ holdout-1 | miniswe-OpenAI__GPT-5-clap-rs__clap-3421-8c92… | 23 | 2 | 22 | 1 | 4.5 | 2 | yes | no | **yes** | llm-failed | — | — | 7.2
53
+ holdout-1 | miniswe-OpenAI__GPT-5-clap-rs__clap-3975-5f1a… | 33 | 101 | 32 | 1 | 3.1 | 127 | no | no | no | — | — | — | 13.0
54
+ holdout-1 | miniswe-OpenAI__GPT-5-clap-rs__clap-4248-85bd… | 23 | 2 | 22 | 0 | 0 | 2 | yes | no | **yes** | generated | 0 | **yes** | 35.3
55
+ holdout-2 | miniswe-OpenAI__GPT-5-instance_ansible__ansib… | 7 | 127 | 6 | 0 | 0 | 127 | yes | yes | **yes** | generated | 0 | **yes** | 20.0
56
+ holdout-2 | miniswe-OpenAI__GPT-5-instance_ansible__ansib… | 13 | 0 | 12 | 0 | 0 | 0 | yes | yes | **yes** | llm-failed | — | — | 13.5
57
+ holdout-2 | miniswe-OpenAI__GPT-5-instance_element-hq__el… | 17 | 2 | 16 | 0 | 0 | 2 | yes | no | **yes** | llm-failed | — | — | 25.9
58
+ holdout-2 | miniswe-OpenAI__GPT-5-instance_internetarchiv… | 10 | 0 | 9 | 0 | 0 | 0 | yes | yes | **yes** | generated | 0 | **yes** | 4.8
59
+ holdout-2 | miniswe-OpenAI__GPT-5-instance_qutebrowser__q… | 15 | 127 | 14 | 0 | 0 | 127 | yes | yes | **yes** | generated | 0 | **yes** | 4.1
60
+ holdout-2 | miniswe-OpenAI__GPT-5-instance_qutebrowser__q… | 18 | 127 | 17 | 0 | 0 | 127 | yes | yes | **yes** | generated | 0 | **yes** | 4.1
61
+ holdout-2 | miniswe-OpenAI__GPT-5-ponylang__ponyc-1057-56… | 35 | 127 | 34 | 0 | 0 | 127 | yes | yes | **yes** | generated | 0 | **yes** | 4.4
62
+ holdout-2 | miniswe-OpenAI__GPT-5-ponylang__ponyc-2532-98… | 12 | 1 | 11 | 0 | 0 | 1 | yes | yes | **yes** | generated | 0 | **yes** | 4.4
63
+ holdout-2 | miniswe-OpenAI__GPT-5-sveltejs__svelte-10608-… | 23 | 127 | 22 | 0 | 0 | 127 | yes | yes | **yes** | generated | 0 | **yes** | 4.7
64
+ split3 | miniswe-OpenAI__GPT-5-fasterxml__jackson-data… | 18 | 127 | 17 | 0 | 0 | 127 | yes | yes | **yes** | generated | 127 | no | 5.7
65
+ split3 | miniswe-OpenAI__GPT-5-instance_ansible__ansib… | 21 | 0 | 20 | 1 | 5 | 2 | no | no | no | — | — | — | 4.8
66
+ split3 | miniswe-OpenAI__GPT-5-instance_element-hq__el… | 21 | 0 | 20 | 0 | 0 | 2 | no | no | no | — | — | — | 6.3
67
+ split3 | miniswe-OpenAI__GPT-5-nushell__nushell-13357-… | 28 | 127 | 27 | 0 | 0 | 127 | yes | yes | **yes** | generated | 127 | no | 5.9
68
+ split3 | miniswe-OpenAI__GPT-5-ponylang__ponyc-2205-2a… | 27 | 127 | 26 | 0 | 0 | 0 | no | no | no | — | — | — | 5.4
69
+ split3 | miniswe-OpenAI__GPT-5-ponylang__ponyc-3973-60… | 20 | 0 | 19 | 0 | 0 | 127 | no | no | no | — | — | — | 5.8
70
+ split3 | miniswe-OpenAI__GPT-5-simdjson__simdjson-2016… | 24 | 0 | 23 | 0 | 0 | 0 | yes | yes | **yes** | llm-failed | — | — | 5.2
71
+ split3 | miniswe-OpenAI__GPT-5-sveltejs__svelte-11913-… | 19 | 0 | 18 | 0 | 0 | 0 | yes | yes | **yes** | generated | 0 | **yes** | 41.2
72
+ split3 | miniswe-OpenAI__GPT-5-sveltejs__svelte-9962-5… | 21 | 127 | 20 | 0 | 0 | 127 | yes | yes | **yes** | llm-failed | — | — | 4.3
73
+
74
+ ## LLM fix generation
75
+
76
+ Model glm-5.2: 16 calls (5 failed), 41878 prompt + 51312 completion tokens.
@@ -0,0 +1,105 @@
1
+ # replay-verify — executed proofs for trajectory findings
2
+
3
+ An analyst finding today is a cited claim: "step 37 is where the run went wrong."
4
+ `traces replay-verify` upgrades that claim to an executed proof: it replays the trajectory prefix inside a real sandbox on the trajectory's own docker image, then runs two counterfactual arms at the error-critical step k:
5
+
6
+ - **Arm A** re-executes the recorded step k and checks the recorded failure reproduces — same returncode plus a stable output substring (the failure signature).
7
+ - **Arm B** executes a corrected step k and checks the failure vanishes (exit 0 and the signature absent).
8
+
9
+ Each arm gets a fresh sandbox with its own prefix replay, so arm B is never contaminated by arm A's side effects.
10
+ Under the hood each arm is an agent-eval `runCounterfactual` meta-run (`layer='meta'`, `parentRunId` = the ingested trajectory run), with the sandbox-backed `CounterfactualRunner` from `src/replay-verify.ts` supplying the `executeFrom` callback that scaffold leaves to consumers.
11
+
12
+ ## Usage
13
+
14
+ ```sh
15
+ traces replay-verify \
16
+ --steps normalized/<traj_id>/steps.json \
17
+ --image <docker_config.base_image> \
18
+ --at 37 \
19
+ --cwd /home \
20
+ --fix-command "sed -i '145d' /home/zstd/programs/zstdcli.c && make -C /home/zstd zstd -j2 V=1" \
21
+ --signature 'undeclared (first use in this function)' \
22
+ --out ./replay-out \
23
+ --base-url http://127.0.0.1:4097 --api-key-env SANDBOX_API_KEY
24
+ ```
25
+
26
+ Outputs `replay-verdict.json` (machine-readable: prefix divergences, both arms, timings, run ids) and `report.md` (human-readable with real stdout/stderr excerpts).
27
+ `traces replay-verify --help` lists every flag.
28
+
29
+ ## Execution semantics
30
+
31
+ Every step runs the way mini-SWE ran it: a fresh `/bin/sh` subshell from a fixed workdir.
32
+ The action is base64-piped into `sh` after `cd`-ing to `--cwd`, so arbitrary quoting in recorded actions survives, and the reported exit code is the action's own.
33
+
34
+ Prefix divergences (recorded returncode ≠ replayed exit) are recorded per step, never abort the replay, and are surfaced in the verdict.
35
+ A high divergence rate is a finding about replayability, not a failure of the tool.
36
+
37
+ ## Honest limits
38
+
39
+ - **Only SWE-style trajectories are replayable.** The docker image comes from the raw trajectory's `info.docker_config.base_image`; terminal-bench-style tasks that need external compose peers (databases, services) cannot be replayed with a single image.
40
+ - **Commands never run as root.** The sandbox platform pins every customer command to the configured non-root subprocess identity (uid 1000 by default) — a deliberate security invariant with no override. Trajectories recorded as root (mini-SWE's default) will hit permission errors on root-owned trees. Fix by deriving a replay image that chowns the working tree to the sandbox uid:
41
+
42
+ ```dockerfile
43
+ FROM mswebench/facebook_m_zstd:pr-1733
44
+ RUN chown -R 1000:1000 /home
45
+ ```
46
+
47
+ This preserves the recorded failure semantics for build/edit workflows (they depend on writability, not on uid 0). The verdict records the image actually used.
48
+ - **Copy-on-write forks are firecracker-only.** `box.branch()` could replay the prefix once and fork at k; on the docker driver each arm replays the prefix in its own fresh sandbox instead. Wall-time cost is one extra prefix replay per arm.
49
+ - **Environment drift shows up as divergence.** The sandbox mounts a workspace at `/home/agent` and injects platform env; recorded observations that depend on exact `ls` output or env contents can differ while returncodes still match. Only returncodes drive the divergence count.
50
+ - **The failure signature is derived, not assumed.** Default: the first recorded-output line containing "error". Compiler quote glyphs vary with locale, so prefer an explicit `--signature` with an ASCII-stable substring.
51
+
52
+ ## Batch mode — replayability and fix-flip rates
53
+
54
+ `traces replay-verify-batch` runs the proof at corpus scale over gold-labeled CodeTraceBench corpora and measures two headline numbers nobody had before:
55
+
56
+ - **Replayability rate** — fraction of replayable cases where the prefix replays with ≤10% returncode divergence AND arm A reproduces the recorded returncode at the gold step k (k = the first gold incorrect step from `incorrect_stages[].incorrect_step_ids` that is a real mid-trajectory action; see the submit-step rule below).
57
+ - **Fix-flip rate** — fraction of arm-B-executed cases where a generated corrected command made the failure vanish.
58
+
59
+ ```sh
60
+ traces replay-verify-batch \
61
+ --corpus dev-32=<labels.json>::<prepared-dir> \
62
+ --corpus holdout-1=<labels.json>::<prepared-dir> \
63
+ --out ./replay-batch-out \
64
+ --fix generate --max-fix-cases 30 --seed 17 \
65
+ --base-url http://127.0.0.1:4097 --api-key-env SANDBOX_API_KEY \
66
+ --fix-api-key-env ZAI_GLM_API_KEY
67
+ ```
68
+
69
+ A corpus is a gold label file plus a prepared directory (`normalized/<traj_id>/steps.json` + `extracted/<traj_id>/swe_raw/**`). Replayable = the raw trajectory carries `info.docker_config.base_image` AND the labels mark ≥1 gold incorrect step that is a real mid-trajectory action. The batch:
70
+
71
+ - reports the true replayable count and a per-reason exclusion table (`--enumerate-only` prints both without touching a sandbox);
72
+ - **skips submit-command golds when choosing k.** A gold step whose action is the agent's end-of-run submit (`COMPLETE_TASK_AND_SUBMIT_FINAL_OUTPUT`) marks a bad submit *decision*, not a failed command — there is no executable failure to reproduce, so it is never a counterfactual target. k advances to the first non-submit gold; a case whose golds are all submit steps is excluded as `gold-only-submit-step`. The report carries a per-corpus table of both counts (this matters most for split3, whose gold labels concentrate on the submit decision);
73
+ - derives the working directory from the recorded run config (`info.config.environment.cwd`), falling back to `docker_config.cwd`, then to the first `pwd` observation;
74
+ - builds and caches a uid-1000 derived image per (base image, cwd) pair — `ctb-replay:<hash>-uid1000` — because the sandbox platform pins commands to a non-root identity;
75
+ - runs every case serially (image pulls contend on disk and registry bandwidth) and records pull/build failures as report rows, never silent skips;
76
+ - uses the recorded per-step timeout (`info.config.environment.timeout`) unless `--step-timeout` overrides it.
77
+
78
+ Fix generation (`--fix generate`) runs ONE chat completion per arm-A-reproduced case against an OpenAI-compatible endpoint (default: glm-5.2 on z.ai). The prompt carries the gold step's action and observation, ±3 surrounding steps, and the task statement; the reply must be a single corrected shell command. Cases beyond `--max-fix-cases` are excluded by a seeded random sample and marked `sampled-out` in the report. Arm B replays the prefix in its own fresh sandbox and executes the corrected command; `failureVanished` = exit 0 with the failure signature absent.
79
+
80
+ Honest-reporting notes baked into the report:
81
+
82
+ - A gold step whose recorded observation carries **no returncode** can never satisfy "arm A reproduces the recorded returncode": it counts against the replayability rate and the per-case table says why.
83
+ - A gold step recorded with **returncode 0** (the labeled mistake succeeded — a wrong-direction action, not a crash) reproduces trivially; for such cases `failureVanished` is vacuous, so read the headline's separate fix-flip rate on the recorded-rc≠0 subset.
84
+
85
+ Outputs: `batch-report.json`, `batch-report.md` (headline + exclusion + pull-failure + per-case tables), `cases.jsonl` (incremental, crash-safe), and one directory per case with the full `replay-verify` artifacts plus `armB-result.json`.
86
+
87
+ ## Analyst wire — finding in, executed proof out
88
+
89
+ `replayVerifyFinding` (exported from the package root, `src/replay-wire.ts`) is the entry point the analyst product calls:
90
+
91
+ ```ts
92
+ import { replayVerifyFinding } from '@tangle-network/traces'
93
+
94
+ const { invocation, fixCommand, verdict } = await replayVerifyFinding(
95
+ { trajId: 'miniswe-…-zstd-1733-786102c1', subject: 'incorrect-steps-37-37-unescaped-consequence-39' },
96
+ { corpora, out: './proof', fixCaller, baseUrl, apiKey },
97
+ )
98
+ ```
99
+
100
+ The subject grammar is the analyst benchmark's `incorrect-steps-<first>-<last>-<escaped|unescaped>-consequence-<step>`; `--at` is the finding's **first** incorrect step (the finding's claim, which may differ from the gold label). The wire resolves the trajectory across the given corpora, generates the arm-B fix through the same one-call generator (or accepts a pre-supplied `fixCommand`), and returns the full `ReplayVerdict`. It throws with a precise reason when the finding cannot be replayed (malformed subject, unknown trajectory, non-SWE case, step out of range) — the product surfaces that reason instead of a proof.
101
+
102
+ ## Orchestrator prerequisites
103
+
104
+ replay-verify talks to a sandbox API (`--base-url`); in local development that is the sandbox SDK adapter in front of an orchestrator running the docker driver.
105
+ Arbitrary docker images need the platform control runtime (node injected from a mounted Nix profile) because sidecar-less images rarely ship node: the orchestrator needs `NIX_PROFILE_PATH` set, and this CLI passes the `SIDECAR_PLATFORM_CONTROL_RUNTIME` container-env marker on create (the production sandbox API derives the same marker from `agent: false`).
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@tangle-network/traces",
3
- "version": "0.11.0",
3
+ "version": "0.11.3",
4
4
  "description": "Point it at your coding-agent session traces (Claude Code, Codex, OpenCode, Gemini, Pi, …) and get failure-mode + efficiency findings. CLI + SDK over the @tangle-network/agent-eval analyst suite — observe live sessions, run your own analysts, redact, and upload to the Tangle Intelligence Platform.",
5
5
  "type": "module",
6
6
  "license": "MIT",
@@ -47,9 +47,10 @@
47
47
  "node": ">=22"
48
48
  },
49
49
  "dependencies": {
50
- "@tangle-network/agent-eval": "0.140.0",
51
- "@tangle-network/agent-runtime": "0.116.0",
52
- "@tangle-network/sandbox": "0.15.2"
50
+ "@tangle-network/agent-eval": "0.140.1",
51
+ "@tangle-network/agent-runtime": "0.121.0",
52
+ "@tangle-network/agent-trace-contract": "^1.0.2",
53
+ "@tangle-network/sandbox": "0.16.0"
53
54
  },
54
55
  "devDependencies": {
55
56
  "@types/node": "^22.0.0",
@@ -64,6 +65,7 @@
64
65
  "dev": "tsx src/cli.ts",
65
66
  "build": "tsup src/index.ts src/cli.ts --format esm --target node22 --clean --dts",
66
67
  "check:package": "node scripts/check-package-bin.mjs",
68
+ "check:source": "node scripts/check-source-text.mjs",
67
69
  "test": "vitest run",
68
70
  "test:watch": "vitest",
69
71
  "typecheck": "tsc --noEmit"