@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/README.md +161 -13
- package/dist/{chunk-JCI5YXNT.js → chunk-CK5F5TWO.js} +3566 -913
- package/dist/cli.js +208 -21
- package/dist/index.d.ts +1137 -9
- package/dist/index.js +167 -1
- package/docs/replay-batch-20260802.md +76 -0
- package/docs/replay-verify.md +105 -0
- package/package.json +6 -4
- package/skills/inspect-agent-traces/SKILL.md +31 -2
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-
|
|
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.
|
|
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.
|
|
51
|
-
"@tangle-network/agent-runtime": "0.
|
|
52
|
-
"@tangle-network/
|
|
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"
|