v0.18.0
[0.18.0] - 2026-04-17
Added
-
CLI↔library feature parity — Phase 1 (NDJSON) + Phase 2 (#76, PR #101). Four CLI commands (
diagnose,audit,doctor,simulate) and the NDJSON event writer are now public library APIs. Library consumers can reuse the CLI's behavior without shelling to a binary and parsing printed output.tracker.NewNDJSONWriter(io.Writer)— public NDJSON event writer producing the same wire format astracker --json. Factory methodsPipelineHandler,AgentHandler,TraceObserverreturn handlers that plug intoConfig.EventHandler,Config.AgentEvents, and the LLM trace hook. Closes Phase 1.tracker.Diagnose(runDir)/tracker.DiagnoseMostRecent(workDir)— structured*DiagnoseReportwith node failures, budget halt, and typed suggestions (Kind: "retry_pattern" | "escalate_limit" | "no_output" | "shell_command" | "go_test" | "suspicious_timing" | "budget").tracker.Audit(runDir)— structured*AuditReportwith timeline, retries, errors, and recommendations.tracker.ListRuns(workDir)— sorted[]RunSummaryfor enumerating past runs (newest first).tracker.Doctor(cfg)— structured*DoctorReportfor preflight health checks.ProbeProvidersdefaults to false; set true to make real API calls for auth verification.CheckDetail.Statushas four values:"ok","warn","error", and"hint"(informational sub-items such as optional providers not configured).tracker.Simulate(source)— structured*SimulateReportwith nodes, edges, execution plan, graph attributes, and unreachable-node list.tracker.ResolveRunDir(workDir, runID)/tracker.MostRecentRunID(workDir)— exposed run-directory resolution helpers.tracker.ActivityEntry/tracker.LoadActivityLog(runDir)/tracker.ParseActivityLine(line)/tracker.SortActivityByTime(entries)— shared activity.jsonl parsing used by CLI and library.
-
SWE-bench harness (
cmd/tracker-swebench): a new orchestrator binary that evaluates tracker's agent against the SWE-bench dataset. Includes a Dockerfile and build script for the base image, container lifecycle management with SIGTERM handling and orphan cleanup, dataset JSONL parsing, results writer with resumability, container resource limits (CPU/memory) and--platformpinning, secure--env-filefor API keys (replacing-eflags), instance-ID validation + scoped container names, integration test for the dataset-to-results pipeline, and an in-containeragent-runnerbinary that captures all changes viagit diff(including new files). -
WithExtraHeadersoption for Anthropic and OpenAI adapters: injects custom HTTP headers (e.g.,cf-aig-token) for gateway auth. Used by the swebench harness to forwardCF_AIG_TOKENfrom the host through the container to the agent-runner.
Fixed
classifyStatusnow correctly returns"fail"for budget-halted runs (runs with abudget_exceededactivity event were previously mis-classified as"success").NDJSONWriter.AgentHandlernow preserves the originalagent.Event.Timestampinstead of re-stamping withtime.Now(), preventing event reordering in the NDJSON stream.simBFSNodeOrdernow sorts orphan nodes by ID before appending, makingSimulateReport.Nodesordering deterministic.ResolveRunDirnow always returns an absolute path viafilepath.Abs, matching its documented contract.MostRecentRunIDno longer writes toos.Stderrfrom a library function; invalid checkpoint directories are silently skipped.checkWorkdirLibnow correctly propagateswarndetails to the section-levelStatusfield.checkProvidersLibnow propagates individual providererrordetails to the section-levelStatus(was always"ok"when any provider was configured).getDippinVersionnow usesexec.CommandContextwith a 5-second timeout to prevent hangs on unresponsive dippin binaries.PinnedDippinVersionconstant updated tov0.20.0to match thego.modrequirement.checkPipelineFileLibno longer warns when the pipeline file has a.dotextension (both.dipand.dotare valid input formats).- Fixed ineffectual assignment to
suffixincmd/tracker/doctor.gomaybeFixGitignore. checkDiskSpaceLibmoved to platform-specific files (tracker_doctor_unix.go/tracker_doctor_windows.go) to avoid a Windows build failure fromsyscall.Statfs.enrichFromEntryNFandupdateFailureTimingNFnow guard against zero timestamps to prevent incorrect duration calculations inDiagnoseReport.claude-sonnet-4-6added to the LLM model catalog — the model was inpricing.gobut missing fromcatalog.go, causingGetModelInfoto return nil and cost reporting to show$0.00for the swebench harness default model.- ACP backend:
validatePathInWorkDirnow resolves symlinks on bothpathandworkDir. On macOS/varis a symlink to/private/var, which was causing path validation to reject files insidet.TempDir().
Changed
-
cmd/tracker/diagnose.go,audit.go,doctor.go,simulate.goare now thin printers over the new library APIs. CLI stdout and--jsonwire format are byte-identical. Closes Phase 2 of #76. -
dippin-langdependency bumped fromv0.19.1→v0.20.0. CI installs the matching CLI version (was stale atv0.10.0).examples/human_gate_test_suite.diprenameddefault_choice:→default:to match the IR field. The file is temporarily skipped frommake lintbecause v0.20.0's stricter parser rejectstimeout:/timeout_action:on human nodes — tracker supports those attrs at the node level but dippin-lang'sHumanConfigIR doesn't expose them yet. Tracked upstream at dippin-lang#18. -
Structured reflection prompt on tool failure (issue #93): when a tool call returns an error, the agent session now automatically injects a user-role reflection message before the next LLM turn. The prompt asks the model to identify what went wrong, what assumption was incorrect, and what minimal change will fix it — matching the pattern used by top SWE-bench agents (~10-15% recovery improvement). The feature is enabled by default (
ReflectOnError: trueinDefaultConfig()) and capped at three consecutive reflection turns to prevent infinite loops; the counter resets after any clean (no-error) turn. Pipeline authors can opt individual nodes out viareflect_on_error: falsein their.dipfile. -
Verify-after-edit loop with auto-test (closes #94): agent sessions can now automatically run tests after any turn that includes file-edit tool calls (
write,edit,apply_patch,notebook_edit). Modelled on top SWE-bench agent behaviour (~15-20% improvement on benchmark), this transparent inner loop catches regressions before the LLM moves on.SessionConfig.VerifyAfterEdit bool— opt-in flag (default: false).SessionConfig.VerifyCommand string— explicit command; if empty, auto-detection runs:go.mod→go test ./...,Cargo.toml→cargo test,package.json→npm test,Makefilewithtest:target →make test,pytest.ini/pyproject.toml[tool.pytest]→pytest.SessionConfig.MaxVerifyRetries int— max verify→repair cycles per edit turn (default: 2). After exhaustion the session proceeds without blocking.- Repair turns do NOT count toward
MaxTurns— they are a transparent sub-loop. - Verification output is capped at 4 KB (tail kept — most relevant errors appear at the end).
- Pipeline nodes wire the feature via
verify_after_edit,verify_command, andmax_verify_retriesnode attributes.verify_commandcan also be set at graph level as a default for all nodes. - New file
agent/verify.go; 8 new tests inagent/verify_test.goandagent/session_test.go.