# Generated by `osprey build` alongside the reference Dockerfile. This is the
# canonical list of what must never enter a container image — secrets and
# host-specific state.
#
# It is not the file docker reads. An image is built from the container repo at
# `build/.image/<project>/`, and a `.dockerignore` is read only at a context's
# ROOT, so the build derives that file from this one and re-spells every pattern
# `**/`-anchored (see build_cmd._write_image_context_dockerignore) — everything
# named here now lives one level down, under `build/`, where a root-anchored
# pattern matches nothing. Edit the list here; the spelling for that depth is
# derived, never maintained twice.
#
# There is deliberately NO `build/` entry. The project image's context is a
# deployment repo whose render — the deployment itself — lives under `build/`,
# so excluding it would ship an image with no config, no .mcp.json and no
# Claude Code artifacts at all.

# Secrets — must never enter the image (pass at runtime: --env-file .env).
# Every variant is excluded, the deploy-generated .env.users included;
# .env.example carries no secrets and is useful in the image, so it stays.
#
# .env.shared is deliberately NOT re-included. Git tracks it because it holds
# no secrets, but it is still a host file the runtime reads at start, alongside
# the .env beside it — an image carrying a stale copy of one site's defaults is
# exactly the confusion runtime env exists to avoid. The `.env*` glob above
# covers it; leave it covered.
.env*
!.env.example

# Host-specific / regenerable
.venv
.git
# The STATE zone — the host's agent memory, sessions and audit log. It is
# durable and host-local, and the container mounts its own volume over the
# same path, so copying the host's copy in would only bloat the image with
# data the running container never reads. Must track `agent_data.base_dir`
# in config.yml.
var/
__pycache__/
*.py[cod]
.pytest_cache/
*.log
*.pid
.DS_Store

# Personal (non-shared) Claude Code settings
.claude/settings.local.json
CLAUDE.local.md

# Host-side working state under the deployment repo's .claude/ tree: open
# planning artifacts, epic state, nested git worktrees, and agent log/receipt
# history. None of it is deployment source an image's runtime reads — it is
# how the repo got built, not what runs.
.claude/plans/
.claude/epics/
.claude/worktrees/
.claude/.logs/

# The compose document a deploy merges at the repo root when the container
# runtime needs a single file. Machine-written on the host, rewritten by every
# `osprey up`, and meaningless inside an image — the build already keeps it out
# of the context, and this is the second guard that says so where the rest of
# the exclusions live.
.osprey-compose.yml

# The image doesn't need its own build recipe. Note: .dockerignore itself is
# NOT excluded — the wheel layer's `COPY .dockerignore *.wh[l]` relies on it as a
# guaranteed-present sibling so the COPY never fails when no wheel is staged.
Dockerfile

# Model files an operator stages by hand where the model host is unreachable.
# They belong to the qmd sidecar, which loads them over a read-only mount and
# never from an image — gigabytes of GGUF that this image would carry for no
# reader.
#
# The one `**/`-anchored entry in this file, deliberately: `services.qmd.models_dir`
# is an absolute host path, so the staging directory can sit anywhere — this tree
# included — and a root-anchored pattern would miss it. The files reach the sidecar
# over that read-only mount, never through a build context. The derivation
# described above prefixes another `**/`, which is redundant but harmless.
**/prefetched-models/
