turnlog 0.1.0

Lightweight local provenance recorder for agent sessions and turns
# turnlog Design

## Purpose

`turnlog` is a lightweight CLI for recording agent work provenance and linking it to task and VCS state.

It connects:

```text
ticket → agent session → agent turn → jj change or git commit
```

`turnlog` is not a version control system. It does not commit, rebase, merge, push, move bookmarks, or replace Git/Jujutsu.

## Product shape

- Rust CLI first.
- Passive recorder: explicit commands write trace records.
- Git-compatible metadata directory in the repository.
- Jujutsu-aware when `jj` is installed and the current repo is a jj repo.
- Git fallback when jj is unavailable.
- Pi extension can be added later as a thin wrapper around the CLI/core library.
- No daemon in v1.

## Storage

Canonical storage is append-only JSONL plus small JSON documents and Markdown reports.

```text
.turnlog/
  index.jsonl
  sessions/
    <session-id>.json
    <session-id>.md
  turns/
    <turn-id>.json
    <turn-id>.md
  attachments/
    <turn-id>.diff
```

`index.jsonl` is the source of truth for event history. Per-session/turn JSON files are convenient snapshots. Markdown files are human-readable reports. SQLite may be added later as a derived cache, not canonical storage.

## Core commands

```bash
turnlog init
turnlog start --ticket AUTH-123 --goal "Fix auth token validation"
turnlog record --model claude-sonnet-4-5 --verification "cargo test auth"
turnlog status
turnlog log
turnlog show <session-or-turn>
```

## VCS detection

Detection order:

1. If `jj` exists and `jj root` succeeds: record jj metadata and Git metadata where available.
2. Else if `git rev-parse --show-toplevel` succeeds: record Git metadata.
3. Else: record trace metadata with `vcs.kind = "none"`.

## VCS metadata

With jj:

```json
{
  "kind": "jj",
  "jj_change": "kmqzvrlp",
  "jj_commit": "def789",
  "jj_operation": "abcxyz",
  "git_head": "abc123",
  "git_branch": "main",
  "dirty": true,
  "changed_files": ["src/auth.rs"]
}
```

Without jj:

```json
{
  "kind": "git",
  "git_head": "abc123",
  "git_branch": "main",
  "dirty": true,
  "changed_files": ["src/auth.rs"]
}
```

Outside VCS:

```json
{
  "kind": "none"
}
```

## Record model

Session:

```json
{
  "id": "sess_01HX...",
  "ticket": "AUTH-123",
  "goal": "Fix auth token validation",
  "created_at": "2026-05-22T12:00:00Z",
  "repo_root": "/repo",
  "vcs_start": {}
}
```

Turn:

```json
{
  "id": "turn_01HX...",
  "session": "sess_01HX...",
  "created_at": "2026-05-22T12:05:00Z",
  "model": "claude-sonnet-4-5",
  "summary": "Updated token validation and added tests",
  "verification": ["cargo test auth"],
  "vcs": {}
}
```

## Invariants

- `turnlog init` is idempotent.
- Recording never mutates VCS history.
- Every event has an ID, timestamp, schema version, and event type.
- A turn references exactly one session.
- JSONL appends should be safe to review and easy to recover manually.
- The CLI must work in Git-only repos and non-VCS directories.

## Non-goals for v1

- Replacing Git or jj.
- Automatic filesystem watching.
- Daemon/background process.
- Token-level diff or merge.
- Remote sync protocol.
- Cryptographic identity/delegation.
- Knowledge graph or project memory vault.

## Implementation plan

Rust modules:

```text
src/
  main.rs       CLI entrypoint
  cli.rs        clap command definitions
  model.rs      typed records and VCS enums
  store.rs      .turnlog read/write and markdown rendering
  vcs.rs        jj/git detection and metadata capture
  ids.rs        ID generation
```

Suggested dependencies:

- `clap` for CLI parsing
- `serde`, `serde_json` for records
- `time` for timestamps
- `ulid` for sortable IDs
- `anyhow` for CLI errors
- `camino` optional for UTF-8 paths