# Worktrees
.worktrees/
.superset/

# omx state
.omx/

# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
.venv/
venv/
ENV/
.eggs/
*.egg-info/
dist/
!apps/buildai-openai-ingest/frontend/
!apps/buildai-openai-ingest/frontend/dist/
!apps/buildai-openai-ingest/frontend/dist/index.html
!apps/buildai-openai-ingest/frontend/dist/mac-mini.png
# Vendored BuildSpec engine — commit its built dist; node_modules stays ignored.
!tools/buildspec/dist/
build/
!.claude/commands/build/
!.claude/commands/build/*.md
.pytest_cache/
.mypy_cache/
.ruff_cache/
tmp/
test-results/
.certificates/

# Node
node_modules/
.next/
.expect/
out/
*.tsbuildinfo

# IDE
.idea/
.vscode/
*.swp
*.swo

# OS
.DS_Store
Thumbs.db

# Environment
.env
.env.*
!.env.example
!.env.local.example
.env.local
.env*.local
.env-archive/
.buildai/
.vercel

# Local tool state
.superpowers/
.grid-builder-work/
.factory/
.gemini/
.opencode/
.superset/

# EgoExo sync trial script spill (default output is under experiments/egoexo-pipeline/out/)
/*.sync_trial.json
/run_config.json
.codex/config.toml
.codex-bin/
.mcp.json
.playwright-mcp/
.hypothesis/
.dmux/
.ralph-status
buildai-workspace/
apps/buildai-sd-card-reader-android/

# Local DDS verification refresh artifacts. The reviewed dry-run manifest is
# tracked separately so tests and handoffs use one stable repair plan.
.codex/dds-gcs-inventory*.txt
.codex/dds-gcs-repair-dry-run.current.json
.codex/dds-gcs-repair-verify*.json
.codex/dds-*-smoke-current.png

# Generated artifacts
outputs/
logs/
# ...but the /kiwi/logs dashboard route is real source, not artifacts
!apps/buildai-dashboard/src/app/kiwi/logs/
reports/
scratchpad/
scratch-demian-labels/
local-archive/
reference/
recording-cache/
/datasets/1m-hour-dataset/*
!/datasets/1m-hour-dataset/README.md
!/datasets/1m-hour-dataset/anonymized-remap-summary.json
!/datasets/1m-hour-dataset/clip_mapping.parquet
!/datasets/1m-hour-dataset/object_rename_mapping.parquet
/datasets/250k-hour-dataset/*
!/datasets/250k-hour-dataset/README.md
!/datasets/250k-hour-dataset/build/
!/datasets/250k-hour-dataset/build/**
/datasets/250k-hour-dataset/build/**/out/
!/datasets/buildai-100k-hour-monocular-sample/build/
!/datasets/buildai-100k-hour-monocular-sample/build/**
/datasets/buildai-100k-hour-monocular-sample/build/**/out/
!/datasets/buildai-research-100k/build/
!/datasets/buildai-research-100k/build/**
/datasets/buildai-research-100k/out/
/datasets/imu-on-head-frames-2026-04-25/*
!/datasets/imu-on-head-frames-2026-04-25/README.md
!/datasets/golden-ego-exo/build/
!/datasets/golden-ego-exo/build/**
/datasets/golden-ego-exo/build/**/out/
!/datasets/embedding-atlas/build/
!/datasets/embedding-atlas/build/**
!/datasets/buildai-1k-hour-figure-sample/build/
/datasets/buildai-1k-hour-figure-sample/build/*
!/datasets/buildai-1k-hour-figure-sample/build/validate_blocked_policies.py
!/datasets/buildai-1k-hour-figure-sample/build/test_validate_blocked_policies.py
!/datasets/buildai-1k-hour-figure-sample/build/test_figure_requirements_contract.py
!/datasets/buildai-1k-hour-figure-sample/build/test_showcase_policy.py
!/datasets/buildai-1k-hour-figure-sample/build/package/
/datasets/buildai-1k-hour-figure-sample/build/package/*
!/datasets/buildai-1k-hour-figure-sample/build/package/summarize_preupload_readiness_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/package/test_summarize_preupload_readiness_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/media/
/datasets/buildai-1k-hour-figure-sample/build/media/*
!/datasets/buildai-1k-hour-figure-sample/build/media/figure_h264_worker.requirements.lock
!/datasets/buildai-1k-hour-figure-sample/build/media/summarize_exact10_quality.py
!/datasets/buildai-1k-hour-figure-sample/build/media/test_summarize_exact10_quality.py
!/datasets/buildai-1k-hour-figure-sample/build/media/summarize_gigcamera_h264_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/media/test_summarize_gigcamera_h264_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/media/figure_h264_batch_v13.py
!/datasets/buildai-1k-hour-figure-sample/build/media/test_figure_h264_batch_v13.py
!/datasets/buildai-1k-hour-figure-sample/build/media/compile_neutral_h264_v19_receipts.py
!/datasets/buildai-1k-hour-figure-sample/build/media/test_figure_h264_batch_v19.py
!/datasets/buildai-1k-hour-figure-sample/build/media/collect_neutral_h264_v19_launch_receipts.py
!/datasets/buildai-1k-hour-figure-sample/build/media/test_collect_neutral_h264_v19_launch_receipts.py
!/datasets/buildai-1k-hour-figure-sample/build/media/run_neutral_h264_v19_worker_iam_probe.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/
/datasets/buildai-1k-hour-figure-sample/build/qc/*
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_buildai_exact_sheets_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_buildai_exact_sheets_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_buildai_exact_launch_packet_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_buildai_exact_launch_packet_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/export_buildai_existing_qc_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_export_buildai_existing_qc_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/figure_semantic_qc_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_figure_semantic_qc_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/run_figure_semantic_batch_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_run_figure_semantic_batch_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/figure_v12_source_manifest.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_figure_v12_source_manifest.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/figure_v18_source_manifest.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_figure_v18_source_manifest.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_v18_existing_qc_census.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_v18_existing_qc_census.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_gigcamera_qc_coverage_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_gigcamera_qc_coverage_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_gigcamera_qc_coverage_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_gigcamera_qc_coverage_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/bind_gigcamera_contact_sheet_sources_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_bind_gigcamera_contact_sheet_sources_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/run_gigcamera_exact_qc_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_run_gigcamera_exact_qc_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/contract/
/datasets/buildai-1k-hour-figure-sample/build/qc/contract/*
!/datasets/buildai-1k-hour-figure-sample/build/qc/contract/figure_semantic_batch_contract_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/contract/compile_figure_semantic_batch_contract_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/contract/figure-semantic-batch-contract-v1.schema.json
!/datasets/buildai-1k-hour-figure-sample/build/qc/contract/figure-semantic-batch-gigcamera-v13.json
!/datasets/buildai-1k-hour-figure-sample/build/selection/
/datasets/buildai-1k-hour-figure-sample/build/selection/*
!/datasets/buildai-1k-hour-figure-sample/build/selection/finalize_neutral_1k_roster_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_finalize_neutral_1k_roster_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/README_final_neutral_1k_roster_v1.md
!/datasets/buildai-1k-hour-figure-sample/build/selection/export_provisional_review_dino.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_export_provisional_review_dino.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/collect_v8_dino_generation_inventory.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_collect_v8_dino_generation_inventory.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/audit_gigcamera_imu_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_audit_gigcamera_imu_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/bind_gigcamera_imu_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_bind_gigcamera_imu_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/audit_buildai_v9_imu_environment_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_audit_buildai_v9_imu_environment_canary.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_gigcamera_home_candidates_v10.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_gigcamera_home_candidates_v10.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_gigcamera_commercial_candidates_v11.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_gigcamera_commercial_candidates_v11.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_figure_showcase_roster_v12.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_figure_showcase_roster_v12.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/bind_gigcamera_candidate_sources_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_bind_gigcamera_candidate_sources_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_gigcamera_home_candidates_v13.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_gigcamera_home_candidates_v13.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_figure_showcase_roster_v13.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_figure_showcase_roster_v13.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/export_gigcamera_dino_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_export_gigcamera_dino_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/finalize_figure_roster_v14.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_finalize_figure_roster_v14.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/figure_text_exclusion_policy_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_figure_text_exclusion_policy_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/export_gigcamera_gemini_text_snapshot_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_export_gigcamera_gemini_text_snapshot_v1.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_figure_showcase_roster_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_figure_showcase_roster_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_figure_showcase_roster_v16_gig_qc.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_figure_showcase_roster_v16_gig_qc.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_gigcamera_home_candidates_v14_from_snapshot.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_gigcamera_home_candidates_v14_from_snapshot.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/bind_gigcamera_home_snapshot_sources_v2.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_bind_gigcamera_home_snapshot_sources_v2.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/export_gigcamera_dino_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_export_gigcamera_dino_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_gigcamera_qc_coverage_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_gigcamera_qc_coverage_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/bind_gigcamera_contact_sheet_sources_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_bind_gigcamera_contact_sheet_sources_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/run_gigcamera_exact_qc_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_run_gigcamera_exact_qc_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/project_buildai_existing_qc_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_project_buildai_existing_qc_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_buildai_qc_coverage_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_buildai_qc_coverage_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/bind_buildai_imu_sources_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_bind_buildai_imu_sources_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/run_buildai_imu_exact_qc_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_run_buildai_imu_exact_qc_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_buildai_exact_sheets_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_buildai_exact_sheets_v15.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_gigcamera_expanded_qc_pool_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_gigcamera_expanded_qc_pool_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_buildai_strict_qc_pool_v16.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_buildai_strict_qc_pool_v16.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/prepare_gigcamera_expanded_qc_coverage_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_prepare_gigcamera_expanded_qc_coverage_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/bind_gigcamera_expanded_contact_sheet_sources_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_bind_gigcamera_expanded_contact_sheet_sources_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/run_gigcamera_expanded_exact_qc_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/qc/test_run_gigcamera_expanded_exact_qc_v17.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/prepare_figure_strict_roster_v18.py
!/datasets/buildai-1k-hour-figure-sample/build/selection/test_prepare_figure_strict_roster_v18.py
/datasets/dataset-*.json
/datasets/**/__pycache__/
/datasets/**/frames/
/datasets/**/*.jpg
/datasets/**/*.jpeg
/datasets/**/*.png
/datasets/**/*.mp4
/datasets/**/*.mov
/datasets/**/*.parquet
!/datasets/1m-hour-dataset/clip_mapping.parquet
!/datasets/1m-hour-dataset/object_rename_mapping.parquet
/datasets/**/manifest.csv
/datasets/**/scored_device_on_head_candidates.jsonl
/datasets/label-viz-clips/candidates/*.decisions.jsonl
.atlas-bootstrap/
scripts/output/
scripts/atlas/
scripts/dead_assets.json
scripts/dead_assets.ids.txt
scripts/figure_h264_1000h/
/apps/gigcamera/public/prototypes/
/apps/gigcamera/.local-prototypes/

# Terraform/Terragrunt local artifacts
**/.terragrunt-cache/
**/.terraform/
**/.terraform.lock.hcl
infra/**/plan*.txt
infra/**/apply*.txt

# Service account keys
*-sa-key.json
*-sa-key-*.json

# Large binaries
*.npy
*.apk
.tmp-*.yml

# TLS certs
*.ts.net.crt
*.ts.net.key
test-buildai-data/
.claude/worktrees/

# Generated multi-service app factory (local dev only)
_combined_factory.py
