# Python
__pycache__/
*.py[cod]
*.egg-info/
*.egg
.eggs/
dist/
build/
.venv/
venv/
env/

# Type checking / linting
.mypy_cache/
.ruff_cache/
.pyright/
.pytype/

# Testing
.pytest_cache/
.coverage
coverage.xml
htmlcov/
*.cover

# Jupyter
.ipynb_checkpoints/
*.ipynb_checkpoints

# uv
.python-version
# NOTE: uv.lock is deliberately COMMITTED (not ignored). See AGENTS.md — the
# cadquery-ocp / cadquery-ocp-novtk conflict is silent, so the resolution must
# be pinned and reviewable.

# Environment
.env
.env.local

# OS
.DS_Store
Thumbs.db

# Personal scratch (never committed)
working/

# Generated by `partspec check` next to a contract
outputs/

# The build scratch, when a run dies to a signal it cannot catch. All four
# writers — `cli._build_to_file`, `openscad.render`, and since #224
# `openscad.render_section_stl` and `openscad.render_views` — remove it on
# every ordinary exit including SIGINT; SIGTERM/SIGKILL leaves one (measured:
# exit 143). This said "both writers" until #224 made it four. The pattern is
# unanchored and so matches at any depth, which it needs to: `render_views`
# puts its scratch under `<out dir>/renders/`, a level down from the other
# three. `outputs/` above already covers the default destination, so this is
# for an explicit `--out` into a tracked directory — the same "a tmp file any
# `git add -A` would see" hazard that moved the METHOD scratch out of the
# source tree (#39).
.partspec-build-*/

# Eval scratch: run output and the artifacts partspec writes next to a case.
# The cited baseline lives in evals/baseline-*/ and IS tracked.
evals/results/
evals/cases/*/outputs/

# notes/ is TRACKED (analysis the tracker cites — see notes/README.md; #51).
# These entries within it are not. Comments on their own lines: gitignore has
# no trailing-comment syntax, and a pattern with a trailing "# ..." matches
# nothing — silently, which is this project's least favourite adverb.
# Vendored reference clones, each carrying its own .git:
notes/upstream/
# Raw audit transcript and output; the tracked synthesis is the artifact:
notes/audit-journal.jsonl
notes/audit-run1-raw.json
# Tracker snapshots, regenerable with `gh issue list`:
notes/issues-snapshot-*
notes/issues-final-*

# Claude Code's per-checkout runtime state. This lived only in
# .git/info/exclude, which is local to one clone and which hatchling does not
# read — so a locally built sdist shipped .claude/scheduled_tasks.lock while a
# CI-built one did not, and a dev-built tarball is only worth building if it is
# the same tarball (#218). The published artifact was never affected:
# release.yml builds from a clean checkout.
#
# The whole directory, and `**/` rather than the root. This started as the ten
# named entries `.git/info/exclude` happens to carry, and the review of #231
# broke both halves of that: root-anchored, `examples/.claude/
# scheduled_tasks.lock` still shipped (measured, with both sdist tests green);
# and an enumeration only covers what the tool wrote on the day it was written,
# so a `history.jsonl` or a `todos/` turns up as a leak or a red local suite
# for the next person. Nothing under `.claude/` is tracked here — `git ls-files`
# says zero — and this repo's own agent material lives in the top-level
# `skills/`, which ships.
#
# The directory is CLOSED, not filtered. Git cannot re-include a file whose
# parent directory is excluded, so a bare `!.claude/settings.json` below would
# do nothing — measured, and this comment claimed the opposite until the review
# of #234. To track something under here, exclude the CONTENTS rather than the
# directory, then re-include the one path:
#     **/.claude/*
#     !**/.claude/
#     !.claude/settings.json
# The `**/` on both is load-bearing. The v0.7.6 pre-tag audit followed an
# earlier version of this recipe — `!.claude/`, `.claude/*`, `!…` — and it
# re-opened the leak the review that wrote it had just closed: a pattern with
# no internal separator matches at ANY depth, so `!.claude/` re-included
# `examples/.claude/scheduled_tasks.lock`, the exact file measured shipping in
# the sdist. Measured again on the form above: the nested file stays ignored.
# Note the sdist allowlist test asserts the only dot-directory shipped is
# `.github`, so tracking anything here needs that test's list changed too.
**/.claude/
