__pycache__/
*.py[cod]
.venv/
.env
.mypy_cache/
.ruff_cache/
.pytest_cache/
dist/
build/
*.egg-info/
.coverage

# `.lockstep/` is the one directory the framework owns, and it holds two kinds of thing.
#
# COMMITTED: `lockstep.py` is the lifecycle definition and belongs in review like any other code.
# So this ignores the scratch subdirectories by name rather than ignoring the directory and
# negating — a negation is one `!` away from silently un-tracking the configuration, and the
# failure mode there is a repository that runs on detected defaults without anybody noticing.
#
# SCRATCH: everything below belongs to one machine's attempt at one run. The replay fixture that
# ships is tracked where it ships from, in src/in_lockstep/cassettes/ — tracking a working copy
# here as well would be two versions of one artifact, drifting apart.
#
# The ledger is not here at all: run records go to an orphan branch, so they survive a machine.
.lockstep/runs/
.lockstep/cassettes/
# Candidate cases, which `lockstep.yml` harvests into after every review. Ignored because a
# candidate is a proposal: it holds a whole prompt and a whole diff, and it becomes durable
# only when somebody promotes it into `evidence/cases/` in a pull request. That directory is
# deliberately NOT here. The distinction is the whole point of the pair -- one expires with an
# artifact and nobody has to act; the other is published and cannot be unpublished.
.lockstep/cases/
.lockstep/ledger/
# Transcripts hold the full message history of a run, including tool results. `transcript.py`'s
# docstring already claimed they were ignored "like the rest of a run's working state" and they
# were not — the entries above are named individually, and this one was missing. A transcript is
# the file most likely to be pasted whole into an issue; it is also the one most likely to be
# committed by a `git add .` after a failed run.
.lockstep/transcripts/
# The loader imports `.lockstep/lockstep.py`, and Python writes bytecode beside what it imports.
.lockstep/__pycache__/
# The previous layout, still ignored for a checkout that predates the move.
.in-lockstep/

# `.claude/` gets the same split as `.lockstep/`: `launch.json` is committed tooling config
# (the browser preview server definition), so the machine-local session state is ignored by
# name rather than by ignoring the directory and negating.
.claude/worktrees/
.claude/scheduled_tasks.lock
.claude/.cc-writes
.claude/settings.local.json
.claude/skills/

.agents/

skills-lock.json
