Traject is a local-first developer CLI tool for inspecting coding-agent sessions and diagnosing where an agent stopped making productive progress.
- Local-First & Offline: 100% local log parsing (
.jsonl,.sqlite). No API keys, no network calls, no cloud telemetry. - Deterministic Analysis: Diagnosis based on strict, verifiable heuristic detectors without relying on LLM calls or embeddings.
- Workspace Correlation: Correlates raw transcript actions with local Git workspace diffs and test execution evidence.
- Extensible Architecture: Adapter-based design supports multiple agent transcript formats (Claude Code, OpenAI Codex, etc.).
In 2026, software development is shifting from synchronous inline code generation to asynchronous agent supervision. Developers delegate tasks to terminal agents operating in multi-turn loops.
When an agent succeeds, postmortem analysis is unnecessary. When an agent stalls, burns excessive tokens, or fails, the developer faces a visibility boundary:
Raw JSON Transcript ──► High Noise, Low Signal (Needs Mental Parsing)
Git Diff Only ──► Shows Final State, Misses Intermediate Loops
Test Output Only ──► Shows Failure Symptom, Misses Root Cause Edit
Traject unifies these three signals into a single normalized event stream:
Transcript Events + Git State Diffs + Test Signatures ➜ Deterministic Postmortem
By analyzing the delta between agent tool calls and actual workspace state changes, Traject pinpoints the exact turn where the agent began wasting effort or repeating unproductive edits.
# Using uv (recommended)
uv pip install traject
# Or install from source
git clone https://github.com/Sumeet-basfore/traject.git
cd traject
uv sync# Diagnose a coding-agent session
uv run traject diagnose <path-to-session.jsonl>
# Output as JSON for programmatic use
uv run traject diagnose <path-to-session.jsonl> --json- Claude Code JSONL —
~/.claude/sessions/*.jsonlor any exported session file - More adapters coming — OpenAI Codex, Aider, Cursor (contributions welcome)
┌─ POSTMORTEM REPORT ──────────────────────────────────────────────┐
│ Session: repeated-failure-123 │
│ Agent: Claude Code │
│ Duration: 3m 42s | Turns: 23 | Total Tokens: 42,847 │
├──────────────────────────────────────────────────────────────────┤
│ FINDINGS (3) │
├──────────────────────────────────────────────────────────────────┤
│ 🔴 HIGH | Repeated Command Failure │
│ Command `pytest tests/test_parser.py` failed 3 times │
│ with identical signature 'AssertionError: expected 200 │
│ got 500' despite 2 intervening file edit(s). │
│ → Investigate why error signature persisted across 3 │
│ attempts in `pytest tests/test_parser.py`. │
│ │
│ 🟡 WARN | Stagnant Retry Loop Detected │
│ Command `pytest tests/test_parser.py` failed 3 │
│ consecutive times with identical signature despite │
│ 2 intervening file edit(s) across target file(s): │
│ `src/parser.py` (IRRELEVANT). │
│ → Investigate why corrective edits failed to resolve │
│ error signature in `pytest tests/test_parser.py`. │
│ │
│ 🟡 WARN | Unproductive Context Thrashing Detected │
│ File `src/parser.py` was re-read 4 times without │
│ intervening edits or execution state modifications. │
│ → Ensure file context is retained or included in │
│ initial prompt to avoid repeated context re-fetching. │
└──────────────────────────────────────────────────────────────────┘
| Detector | ID | Description |
|---|---|---|
| Repeated Failure | repeated_failure |
Commands failing ≥2 times with identical error signatures |
| Retry Loop | retry_loop |
Execution cycles where edits fail to alter failure signatures |
| Context Thrashing | context_thrash |
Un-interleaved file reads without state changes (≥3 reads) |
| No-Op Edit | noop_edit |
Edits that change no semantic content (whitespace/comments only) |
| Regression | regression |
Previously passing tests that start failing after edits |
Traject follows a strict unidirectional pipeline architecture:
Raw Agent Transcript (Claude JSONL, etc.)
│
▼
┌────────────────────────┐
│ Adapter Layer │ ← SessionAdapter protocol (vendor-specific)
│ (traject.adapters) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Normalized Session │ ← Immutable Pydantic models (vendor-agnostic)
│ Event Model │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Git & Workspace │ ← Local git diffs, workspace state, test logs
│ Correlation Engine │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Detector Framework │ ← Deterministic rules, each implements Detector protocol
│ (traject.detectors) │
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Finding Model │ ← Evidence-anchored findings with severity/confidence
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ Report Model │ ← Aggregated, coalesced postmortem
└───────────┬────────────┘
│
▼
┌────────────────────────┐
│ CLI Renderer │ ← Rich terminal output / JSON
│ (traject.cli) │
└────────────────────────┘
Core Principles (from AGENTS.md)
- Local-First & Offline — Zero network calls, zero telemetry, zero cloud backends
- Deterministic Analysis — No LLMs, embeddings, or vector databases for core diagnosis
- No Database Engine — Parses transcript files directly on demand
- Evidence vs. Interpretation — Findings grounded in observable facts, never speculation
- Strict Scope Boundaries — No Web UI, no server, no auth, no automatic prompt mutation
- Python 3.12+
uvpackage manager
# Clone and install
git clone https://github.com/Sumeet-basfore/traject.git
cd traject
uv sync
# Run tests
uv run pytest
# Type checking
uv run pyright
# Linting & formatting
uv run ruff check .
uv run ruff format --check .# All tests with coverage
uv run pytest -v
# Specific detector tests
uv run pytest tests/test_m1_detectors.py -v
uv run pytest tests/test_m2_pass2.py -v
# Git correlation tests
uv run pytest tests/test_git.py -vtraject/
├── src/traject/
│ ├── __init__.py
│ ├── cli/
│ │ └── main.py # Typer CLI entrypoint
│ ├── adapters/
│ │ ├── __init__.py
│ │ └── claude.py # Claude Code JSONL adapter
│ ├── core/
│ │ ├── __init__.py
│ │ ├── models.py # Normalized domain models (Pydantic)
│ │ ├── finding.py # Finding, EvidenceItem, Severity, Confidence
│ │ ├── protocols.py # SessionAdapter, Detector protocols
│ │ ├── utils.py # Helper functions (failure signatures, etc.)
│ │ ├── state.py # Workspace/context state machines
│ │ ├── timeline.py # Event timeline utilities
│ │ ├── episodes.py # Episode segmentation
│ │ ├── aggregation.py # Finding coalescing/deduplication
│ │ └── progress.py # Progress tracking
│ ├── detectors/
│ │ ├── __init__.py
│ │ ├── repeated_failure.py
│ │ ├── retry_loop.py
│ │ ├── context_thrash.py
│ │ ├── noop_edit.py
│ │ └── regression.py
│ ├── git/
│ │ ├── __init__.py
│ │ └── context.py # Git workspace correlation
│ └── reporting/
│ ├── __init__.py
│ ├── model.py
│ ├── model_v2.py # Postmortem report model v2
│ ├── renderer.py # Rich terminal renderer
│ └── json_renderer.py # JSON output renderer
├── tests/
│ ├── fixtures/ # Behavioral test fixtures (.jsonl)
│ ├── test_cli.py
│ ├── test_adapter.py
│ ├── test_detector.py
│ ├── test_git.py
│ ├── test_behavioral_matrix.py
│ ├── test_m1_detectors.py
│ ├── test_m2_pass2.py
│ └── test_progress.py
├── docs/
│ ├── 00-project-brief.md
│ ├── product/
│ │ ├── 01-product-thesis.md
│ │ ├── 02-use-cases.md
│ │ ├── 03-mvp-scope.md
│ │ ├── 04-non-goals.md
│ │ ├── 05-m1-goals.md
│ │ └── 06-m2-goals.md
│ ├── technical/
│ │ ├── 01-architecture.md
│ │ ├── 02-event-model.md
│ │ ├── 03-adapter-interface.md
│ │ ├── 04-detection-framework.md
│ │ ├── 05-git-correlation.md
│ │ └── 06-report-model.md
│ └── validation/
│ ├── 01-m1-validation.md
│ └── 02-m2-validation.md
├── AGENTS.md # Engineering constitution & agent guidelines
├── pyproject.toml
├── uv.lock
└── LICENSE
- Create
src/traject/detectors/your_detector.pyimplementing theDetectorprotocol - Add tests in
tests/test_your_detector.pyusing behavioral fixtures - Register the detector in
src/traject/cli/main.py - Ensure all quality gates pass:
ruff,pyright,pytest
- Create
src/traject/adapters/your_adapter.pyimplementingSessionAdapter - Add
can_adapt()to identify your log format - Map vendor events to normalized
SessionEventmodels - Add tests with fixture files in
tests/fixtures/
- 100% type annotation coverage enforced by Pyright (strict mode)
- Immutable data structures —
frozen=TruePydantic models - TDD/Red-Green-Refactor — Tests before implementation
- Behavioral fixtures — Real or minimal synthetic transcript files
- AGENTS.md — Engineering Constitution & Agent Guidelines
- Product Thesis — Core product vision
- Technical Architecture — System design
- Adapter Interface — Building new adapters
- Detection Framework — Building new detectors
MIT License — see LICENSE for details.
Traject is built for developers who need to understand what their coding agents actually did — without leaving their terminal.