Skip to content

feat(eval): emit ATIF trajectory.json from the clawcodex harbor adapter#736

Merged
ericleepi314 merged 2 commits into
mainfrom
feat/clawcodex-trajectory-logs
Jul 21, 2026
Merged

feat(eval): emit ATIF trajectory.json from the clawcodex harbor adapter#736
ericleepi314 merged 2 commits into
mainfrom
feat/clawcodex-trajectory-logs

Conversation

@ericleepi314

Copy link
Copy Markdown
Collaborator

Summary

Harbor's built-in claude-code agent writes a rich step-by-step trajectory.json (ATIF) that its viewer/leaderboard render; the clawcodex adapter emitted none. This adds it, at parity.

  • eval/harbor/clawcodex_agent.py: SUPPORTS_ATIF=True; populate_context_post_run builds an ATIF-v1.7 Trajectory (Agent header from the system:init event; Steps with per-turn message/reasoning/tool_calls + observations; FinalMetrics from token usage; total_cost_usd/context.cost_usd from the session cost block). Two sources:
    • rich — the persisted session conversation (per-turn narration, reasoning, tool calls AND results), synced under <logs>/sessions/;
    • fallback — the stream-json log (always present): every tool call+result, the final answer, authoritative token usage; carries a notes marker noting narration is unavailable.
      Best-effort throughout — a build failure never fails the trial. Token backfill unchanged.
  • src/entrypoints/headless.py: persist the session (session.save()) at the end of a --print run (best-effort). The print path left no session on disk, so -p runs were un-resumable and carried no transcript; this enables --resume for headless and gives the adapter its rich source. Verified no secret is serialized (session json holds provider/model names, conversation, timestamps, cost — no keys/tokens).
  • eval/harbor/backfill_trajectories.py: reproduce trajectory.json for a past job from its stream-json logs, no re-run.

Test plan

  • Live container trial (terminal-bench fix-git, deepseek-v4-flash): trajectory.json appears; rich path — 43 steps, 43/43 narrated, multi-tool turns bundled; 62 observations, 0 cross-step mismatches, sequential step_ids; trial reward 1.0, token backfill intact
  • Fallback path validated against a real stream-json (53 tool steps + metrics + notes); cost-from-session-block sets FinalMetrics.total_cost_usd + context.cost_usd
  • Backfill reproduced 86/89 trajectories for the 2026-07-19 opus job offline (3 misses = watchdog-crash trials with no events)
  • 669 headless/session tests pass with the session.save() change
  • Critic review → APPROVE

🤖 Generated with Claude Code

ericleepi314 and others added 2 commits July 21, 2026 10:52
Harbor's built-in claude-code agent writes a rich step-by-step
trajectory.json (ATIF) that its viewer/leaderboard render; the clawcodex
adapter emitted none. Add it:

- eval/harbor/clawcodex_agent.py: SUPPORTS_ATIF=True; populate_context_
  post_run now builds an ATIF-v1.7 Trajectory (Agent header from the
  system:init event; Steps with per-turn message/reasoning/tool_calls and
  observations; FinalMetrics from the stream-json result usage) and writes
  trajectory.json. Two sources, preferred order:
    * the persisted session conversation (RICH — per-turn narration,
      reasoning, tool calls AND results), synced under <logs>/sessions/;
    * the stream-json log (always present) — every tool call+result plus
      the final answer, and the authoritative token usage.
  Best-effort throughout: a build failure never fails the trial. Token
  backfill behavior is unchanged.

- src/entrypoints/headless.py: persist the session (session.save()) at the
  end of a headless run. The print path previously left no session on
  disk, so `-p` runs were un-resumable and carried no structured
  transcript; this both enables --resume for headless and gives the
  adapter its rich trajectory source. Best-effort (never changes exit
  code/output).

Verified: rich path yields user→agent(tool+result)→agent steps with
narration; fallback path yields 53 tool steps + metrics from a real
stream-json log; a live headless run persists the conversation; 669
headless/session tests pass.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ill script (critic follow-ups)

- Read total_cost_usd from the persisted session's cost block (the
  --print result event has no cost field) and set both
  FinalMetrics.total_cost_usd AND context.cost_usd — leaderboard cost
  parity with the claude-code agent (critic's substantive finding).
- Fallback (stream-json-only) trajectories carry a Trajectory.notes
  marker explaining per-step narration is unavailable.
- Dedup _load_session_data's rglob (was scanning the sessions/ subtree
  twice via nested roots).
- Add eval/harbor/backfill_trajectories.py: reproduce trajectory.json for
  a PAST job from its stream-json logs, no re-run. Idempotent (skips
  existing unless --force); reports trials that crashed before any event.
  Backfilled 86/89 of the 2026-07-19 opus job (3 misses = watchdog-crash
  trials whose 5-line logs have no events to reconstruct).

Critic verdict on the branch: APPROVE.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@ericleepi314
ericleepi314 merged commit 000a18e into main Jul 21, 2026
2 checks passed
@ericleepi314
ericleepi314 deleted the feat/clawcodex-trajectory-logs branch July 21, 2026 18:16
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant