# =============================================================
# .NET
# =============================================================
bin/
obj/
out/
*.user
*.suo
*.ide/
*.VisualState.xml
*.pidb
*.booproj
*.svd
*.pdb
*.mdb
.vs/
project.lock.json
project.fragment.lock.json
artifacts/

# EF Core migrations scratch
src/**/Migrations/*.Designer.cs.bak

# =============================================================
# Node / React / Vite
# =============================================================
node_modules/
dist/
dist-ssr/
.vite/
*.local
coverage/
.eslintcache

# =============================================================
# Logs
# =============================================================
logs/
*.log
npm-debug.log*
yarn-debug.log*
yarn-error.log*
lerna-debug.log*

# =============================================================
# Editor / OS
# =============================================================
.idea/
.vscode/*
!.vscode/settings.json
!.vscode/tasks.json
!.vscode/launch.json
!.vscode/extensions.json
Thumbs.db
desktop.ini
.DS_Store

# =============================================================
# Secrets / env
# =============================================================
appsettings.*.Local.json
appsettings.Production.json
*.env
.env.local
.env.*.local
src/Backend/SolutionErp.Api/.env

# Local MCP config — rag-unified stdio, machine-specific absolute paths
# (python + AI_INFRA claude-rag), no secrets, reconstructable → not shared
.mcp.json

# =============================================================
# Build artifacts / uploads
# =============================================================
src/Backend/SolutionErp.Api/wwwroot/uploads/
src/Backend/SolutionErp.Api/wwwroot/exports/

# =============================================================
# Claude / skills (keep tracked — these ARE source of truth)
# =============================================================
# .claude/  ← DO NOT ignore, skills are committed
!.claude/
!.claude/**

# HMW-mode marker — session-local toggle (T2: MUST gitignore — commit → clone stuck-ON / ungoverned on-ramp).
# Pattern AFTER !.claude/** so last-match wins (.claude/ itself not excluded → re-include valid).
.claude/hmw-mode.on

# Fable-real-mode marker — 🧊 retired H21 S110 (2026-07-11): mode-marker BỎ, engine-đắt = per-invocation
# (/fable-real|/fable-clone <vai> <đề-bài>, owner gõ kèm vai). Pattern GIỮ phòng-hờ: file cũ Dropbox-sync
# tái xuất vẫn ignored, KHÔNG bao giờ commit (semantics-ma). Pattern AFTER !.claude/** so last-match wins.
.claude/fable-real-mode.on

# HMW run-trace folders — Harness-10 (2026-06-18): `.claude/workflows/runs/<run-id>/` is git-TRACKED
# (run.md + sub-md/ + harvest/ + _ledger.md) for auditability. Stays tracked via the !.claude/** negation
# above — do NOT add an ignore rule for runs/. Containment model shifts from Harness-2 B6 ("wave-*/ gitignored
# → any tracked-change post-workflow = stray-write") to Harness-10 ("tracked-change OUTSIDE runs/<run-id>/ +
# assigned code-disjoint = violation"). Run-trace now VISIBLE in git-diff = direct audit (stronger).
#
# Legacy Harness-2 wave-folder + agent-team — kept ignored (superseded by runs/; no wave-*/ remain; harmless).
# Pattern AFTER !.claude/** so last-match wins (giống hmw-mode.on).
# ⚠️ check-ignore verify (exit-code nuance): plain `git check-ignore X` exits 1 for a negation/re-included path
#   (NOT 0); only `git check-ignore -v --no-index` shows exit 0 for BOTH. Use the idiom for a correct verdict:
#   `git check-ignore X && echo IGNORED || echo NOT-IGNORED` → runs/ = NOT-IGNORED (tracked); wave-x/ = IGNORED.
.claude/workflows/wave-*/
.claude/agent-teams/

# Claude harness orphan dumps
*.zip

# Sub-agent output dumps (JSON/HTML scratch)
tmp/

# [S76] Guard cwd-misland (feedback_agent_cwd_relative_memory_misland): sub-agent `cd`
# vào fe-user/fe-admin chạy npm build rồi ghi MEMORY.md relative-path → stray
# `fe-*/.claude/agent-memory/...`. Canonical agent-memory ở ROOT `.claude/` vẫn tracked
# (negation `!.claude/**` trên). Pattern AFTER negation → last-match-wins cho path FE-app.
fe-*/.claude/
backups/
*.bak

# [S93 Harness-16] Runtime strikes-state (machine-local, regenerated each run) -- NOT source.
# Pattern AFTER the !.claude/** negation -> last-match-wins ignores these state files.
.claude/agent-memory/.mfe-state.json
.claude/agent-memory/.archive-strikes.json

# [S146] Scheduled-tasks LOCK file — runtime mutex, machine-local, NOT source.
# Bat @S146: no KHONG duoc ignore nen bat ky `git add -A` nao cung nuot no vao commit
# (lock file trong git = nhieu + de xung dot giua may). Hook wal-flush.ps1 khong cham
# (ngoai 4 path co dinh) nhung closeout `add -A` thi co. Pattern AFTER !.claude/** -> last-match-wins.
.claude/scheduled_tasks.lock

# [S152] Cygwin/MSYS crash dumps (grep.exe.stackdump xuat hien khi grep MSYS crash
# tren mega-line UTF-8 — E-2 @S152). May-local debris, khong bao gio la source.
*.stackdump

# Python bytecode (scripts/session_ctx.py � S153)
__pycache__/
*.pyc
