Skip to content
ƒtsforgev0.52.0
19

Trace a run

3 min read

When you run with --log, tsforge writes the whole run to ~/.tsforge/logs/<timestamp>.jsonl as a typed ledger. tsforge trace reads that ledger back and prints a one-screen summary of what actually happened (deterministically, with no model call).

Terminal window
tsforge trace # summarize the newest log
tsforge trace run.jsonl # a specific log file

Inside an interactive session, /trace does the same and prefers the current session’s own log:

› /trace
trace of ~/.tsforge/logs/2026-06-19-…​.jsonl
model deepseek-v4-flash
final status done
failure class none
turns 1
turns to green 1
model calls 1
tokens out 380
peak context 4200 (13% of 32000)
edits/creates 1 (0 created)
accept rate 100% (0 reverted)
cost/accepted 380 tok
gate runs 1
policy denials 1 (1 high)
policy asks 0
wall clock 0s
FieldMeaning
final status / failure classhow the run ended (if it didn’t reach green, one structured reason why, e.g. type-error (TS18048))
turns / turns to greenrepair iterations, and how many it took to first pass the gate (lower is better)
model calls / tokens out / peak contextcall count, completion tokens, and the context high-water mark
edits/creates / gate runsfile mutations and how many times the gate ran
accept rate / cost/acceptedshare of edits that stuck (vs were reverted), and completion tokens per durable change (tokens mean little if most edits get reverted)
policy denials / policy asksaction-policy verdicts that blocked or paused an action, denials bucketed by risk

Each line is one typed event (valid JSON), so a run is fully reconstructable. Events are wrapped in a payload:

{ "type": "policy_decision", "runId": "", "timestamp": "",
"payload": { "kind": "policy", "decision": "deny", "risk": "high",
"message": "blocked rm -rf /", "rules": ["no-destructive-shell"] } }

Policy decisions (allow / ask / deny, with their risk and the rules that matched) are recorded alongside model calls, tool calls, and gate verdicts. tsforge trace surfaces the denials and asks so you can see where the harness stepped in.

The same distillation is available from the eval module of @agjs/tsforge:

import { parseEventLog, analyzeEvents, formatTrace } from "@agjs/tsforge";
const events = parseEventLog(await Bun.file("run.jsonl").text());
const metrics = analyzeEvents(events); // { turns, tokensOut, policyDenies, denialsByRisk, … }
console.log(formatTrace(events));

parseEventLog tolerates both the ledger shape and the older flat shape, and analyzeEvents feeds the A/B sweep report.

Token metrics · Permissions & policy · tsforge.config.json · A/B testing