Clean Project Export
You are a strict file gatekeeper. This skill MUST be loaded automatically before ANY git operation or zip/export -- no matter how small. Do NOT wait for the user to ask.
Auto-triggers: git add, git commit, git push, zip, archive, export, package, "push this", "commit this", "add to git", "zip the project".
When triggered: scan files, enforce rules, block non-project files, strip AI attribution. Every time. No exceptions.
Core Principle
If a file does not run, compile, render, migrate, seed, test, configure the application, or serve as a required project asset -- it does NOT belong in the export.
ABSOLUTE RULE #0: NO AI ATTRIBUTION IN GIT
NEVER add Claude, Copilot, Cursor, or ANY AI as a co-author, contributor, or collaborator in git commits, PR descriptions, or merge commits. The human developer is the sole author. Always. Zero exceptions. Check every commit message before pushing.
Rules (Non-Negotiable)
- ONLY project source files are added to git or zip. No exceptions.
- NEVER add files without scanning first. If uncertain, read the file before deciding.
- NEVER assume a file is safe to include. Verify it is an actual project file.
- NEVER assume a new file is excluded. Rescan when new files appear.
- ALWAYS maintain a
.excludefile at the project root listing all non-project files. - ALWAYS preserve folder structure in zip exports. Files keep their exact relative paths.
- README.md is the ONLY markdown file allowed. All other
.mdfiles are excluded. - When in doubt, read the file contents. A file's name can be misleading -- contents tell the truth.
- Framework-shipped does NOT mean project-allowed. If a starter template (
create-next-app,create-vue,create-react-app, etc.) ships an AI/agent file (AGENTS.md, CLAUDE.md, .cursor/, .windsurf/, .codex/, etc.), it is STILL excluded. Convention authority does not override this skill. The dev is the sole author and the repo is the sole product. - AI patterns live in
.exclude, NOT.gitignore..gitignorecontains only standard dev junk (node_modules, build artifacts, .env, OS files) plus the single line.exclude. AI/agent/plan/skill/scratch patterns belong in.excludeonly. Do not pollute.gitignorewith AI categories. - Run a template scan immediately after
create-*-appor any scaffolder. Before the first commit, list every file the template created and verify each one against the inclusion list. Untracked AI files from a template are the most common leak path. - Comments in
.gitignoreshould be minimal. No prose explanations. Standard dev tools recognise the patterns. The only allowed annotation is the leading.excludeline, uncommented. - Verify clean tree before AND after every push. Run
git ls-tree -r HEAD --name-only | grep -iE "AGENTS|CLAUDE|\.claude|\.cursor|\.exclude|\.env". Output must be empty. Run again after push to confirm what shipped. - If an AI/agent file ships by accident, do not patch forward. Wipe local
.git, re-init, single clean root commit, force push. Three-commit history with "removed AGENTS.md" cleanup is worse than one clean commit.
What Gets INCLUDED (Project Files)
These are actual project files that ship with the application:
SOURCE CODE:
- .php, .py, .js, .ts, .jsx, .tsx, .vue, .svelte, .rb, .go, .rs, .java, .kt, .swift, .c, .cpp, .h
- .blade.php, .edge, .ejs, .pug, .twig, .hbs
CONFIGURATION (Application):
- .env.example (never .env itself)
- composer.json, composer.lock
- package.json, package-lock.json, yarn.lock, pnpm-lock.yaml, bun.lockb
- tsconfig.json, jsconfig.json
- vite.config.*, webpack.config.*, next.config.*, nuxt.config.*
- tailwind.config.*, postcss.config.*
- phpunit.xml, pest.php, vitest.config.*, jest.config.*
- .eslintrc.*, .prettierrc.*, .stylelintrc.*
- .editorconfig
- docker-compose.yml, Dockerfile, .dockerignore
- nginx.conf, apache.conf, Procfile
- Makefile, Rakefile, Gemfile, Gemfile.lock
- .github/workflows/*.yml (CI/CD pipelines)
- phpstan.neon, psalm.xml, pint.json
ASSETS:
- .css, .scss, .sass, .less, .styl, .pcss
- .svg, .png, .jpg, .jpeg, .gif, .webp, .ico, .avif
- .woff, .woff2, .ttf, .eot, .otf
- .mp4, .webm, .mp3, .wav, .ogg
- .pdf (if project asset, not documentation)
DATA & DATABASE:
- migrations/, seeders/, factories/
- .sql files (schema, seeds)
- .json, .xml, .yaml, .yml (data/config files within the project)
- .csv (if fixture/seed data)
LANGUAGE & LOCALIZATION:
- lang/, locales/, i18n/, translations/
- .po, .pot, .mo files
VIEWS & TEMPLATES:
- resources/views/, templates/, layouts/
- public/ directory contents
TESTS:
- tests/ directory
- .test.*, .spec.*, *Test.php, *_test.*
PROJECT ROOT FILES:
- README.md (the ONLY allowed .md file)
- LICENSE, LICENSE.md, LICENSE.txt
- .gitignore
- .gitattributes
- artisan (Laravel)
- server.php (Laravel)
- bootstrap/, public/index.php
What Gets EXCLUDED (Non-Project Files)
These are NEVER added to git or zip:
AGENT & AI FILES:
- .claude/ directory (all contents)
- .cursor/ directory
- .agents/ directory
- .continue/ directory
- .codebuddy/ directory
- .windsurf/ directory
- .augment/ directory
- .codex/ directory
- CLAUDE.md, .claude-plugin/
- .cursorrules, .cursorignore
- .copilot/
- Any file containing agent instructions or AI system prompts
PLAN & DOCUMENTATION FILES (except README.md):
- PLAN.md, PLANS.md, plan.md, plan.txt
- ARCHITECTURE.md, DESIGN.md, SPEC.md, SPECIFICATION.md
- NOTES.md, NOTES.txt, notes/
- TODO.md, TODO.txt, TASKS.md
- CHANGELOG.md (unless explicitly part of a published package)
- CONTRIBUTING.md (unless explicitly part of a published package)
- ROADMAP.md, DECISIONS.md, ADR/
- docs/ directory (unless user confirms it ships with the project)
- *.md (ALL markdown except README.md -- this is strict)
SKILLS & RULES FILES:
- SKILL.md, skills/
- rules.json, rules.yaml, rules/
- .rules, .cursorrules
- .eslint-rules (custom, not .eslintrc)
- REFERENCE.md (skill reference files)
- Any file with "skill", "rule", or "agent" in the path
ENVIRONMENT & SECRETS:
- .env (NEVER -- only .env.example is allowed)
- .env.local, .env.production, .env.staging, .env.testing
- *.pem, *.key, *.cert, *.p12, *.jks
- credentials.json, service-account.json
- Any file containing API keys, tokens, or secrets
BUILD ARTIFACTS & DEPENDENCIES:
- node_modules/, vendor/ (unless deploying without install)
- .next/, .nuxt/, .output/
- dist/, build/, out/ (unless deploying static build)
- storage/framework/cache/, storage/framework/sessions/, storage/framework/views/
- bootstrap/cache/*.php (Laravel compiled)
- .phpunit.result.cache, .php-cs-fixer.cache
- *.log, storage/logs/
OS & IDE FILES:
- .DS_Store, Thumbs.db, desktop.ini
- .idea/, .vscode/ (unless shared team settings)
- *.swp, *.swo, *~, *.bak, *.tmp
- .project, .classpath, .settings/
MEMORY & SESSION FILES:
- MEMORY.md, memory/
- .local.md files
- *.session, *.pid
TEMPORARY & GENERATED:
- tmp/, temp/, .tmp/
- coverage/, .nyc_output/
- .parcel-cache/, .turbo/, .vercel/, .netlify/
Two-File System: .gitignore vs .exclude
Project uses BOTH files. Different purpose. No overlap.
.gitignore (standard junk — commit to git)
Holds universally-known ignore patterns every dev expects. Shared with team. Pushed to GitHub.
NEVER list AI/agent/plan/skill patterns here. Those go in .exclude only.
The only project-specific line allowed is the .exclude reference itself,
on its own with no comment block.
.exclude
# dependencies
.env
.env.local
.env.*.local
node_modules/
vendor/
# framework build
.next/
.nuxt/
dist/
build/
out/
# laravel storage
storage/logs/
storage/framework/cache/
storage/framework/sessions/
storage/framework/views/
bootstrap/cache/*.php
# logs
*.log
# os
.DS_Store
Thumbs.db
# editors (only if not shared)
.idea/
.vscode/
# coverage
coverage/
.phpunit.result.cache
.php-cs-fixer.cache
# secrets
*.pem
*.key
DO NOT add: AGENTS.md, CLAUDE.md, .claude/, .cursor/, .windsurf/,
.codex/, .cursorrules, PLAN.md, SKILL.md, or any AI/plan pattern to
.gitignore. Those belong in .exclude and the workflow keeps them off the
staging area through explicit git add <path> calls.
.exclude (custom/AI/plan junk — NEVER commit, NEVER zip)
Holds project-specific non-project files: agent configs, plan files, skill rules, AI instructions, personal notes. Local-only. Never pushed to GitHub. Never included in zip exports.
# .exclude - Non-project files identified by clean export scan
# LOCAL ONLY. Never commit. Never zip. Never push.
# Auto-generated. Rescan to discover new files.
# Last scanned: [date]
# Agent & AI
.claude/
.cursor/
.agents/
.continue/
.windsurf/
.codex/
CLAUDE.md
CLAUDE.original.md
.cursorrules
# Plans & Docs (except README.md)
PLAN.md
PLANS.md
ARCHITECTURE.md
DESIGN.md
SPEC.md
NOTES.md
TODO.md
CHANGELOG.md
ROADMAP.md
docs/
# Skills & Rules
SKILL.md
skills/
rules.json
rules.yaml
.rules
REFERENCE.md
# Memory & Session
MEMORY.md
memory/
*.local.md
# Temporary
tmp/
temp/
.tmp/
scratch.*
Split Rule
- If ignore pattern is standard dev knowledge (every dev knows to skip) →
.gitignore - If ignore pattern is AI/plan/skill/custom (project-specific, not universal) →
.exclude - No duplication. A file belongs in one place only.
Rules for .exclude
- Create on first scan. After scanning the project for the first time, write
.exclude. - Update on rescan. When new files appear, add them to
.excludeafter verification. - Never assume new files are excluded. New file must be scanned and classified before adding.
.excludeis LOCAL ONLY. Never commit. Never push. Never include in zip.- Auto-add
.excludeto.gitignore. First line of.gitignoremust contain.exclude. - Zip exports must exclude
.excludeitself. Verify before zipping. - Comment sections for clarity. Group exclusions by category.
Enforcement checklist
Before ANY git add / commit / push / zip:
-
.gitignoreexists and contains.excludeentry -
.excludeis NOT in staged files (git diff --cached --name-only | grep -v '^\.exclude$') -
.excludeis NOT in zip file list - Files in
.excludeare NOT staged or zipped
If .exclude appears staged → git reset HEAD .exclude immediately.
If .exclude appears in zip → rebuild zip without it.
Scanning Process
Full Scan (First time or when requested)
STEP 1: List ALL files in the project (recursive, excluding .git/)
STEP 2: Classify each file:
- KNOWN PROJECT FILE -> include (matches the inclusion list above)
- KNOWN NON-PROJECT FILE -> exclude (matches the exclusion list above)
- UNKNOWN FILE -> inspect
STEP 3: For UNKNOWN files:
a. Read the file contents (first 50-100 lines)
b. Determine purpose:
- Contains code that runs/compiles? -> PROJECT FILE
- Contains agent instructions or AI prompts? -> EXCLUDE
- Contains a plan, spec, or documentation? -> EXCLUDE (unless README.md)
- Contains project configuration? -> PROJECT FILE
- Contains data the app uses at runtime? -> PROJECT FILE
- Still unclear? -> ASK THE USER before deciding
c. Add classification to .exclude if excluded
STEP 4: Report findings:
"Scan complete:
- [X] project files identified
- [Y] non-project files excluded
- [Z] files need your review: [list them]"
STEP 5: Write/update .exclude file
Incremental Scan (New files detected)
STEP 1: List all files NOT in .exclude and NOT already tracked
STEP 2: Classify new files using the same process
STEP 3: Update .exclude with new exclusions
STEP 4: Report what was found
Template Scan (after a scaffolder runs)
Run this immediately after create-next-app, create-vue, create-react-app,
degit, nest new, rails new, django-admin startproject, or any other
project bootstrapper. Templates ship AI/agent files as a "feature." Catch
them before the first commit lands.
STEP 1: List EVERY file the template created at the project root:
ls -la
STEP 2: Flag for inspection any of:
AGENTS.md, CLAUDE.md, COPILOT.md, CURSOR.md
.claude/, .cursor/, .windsurf/, .codex/, .continue/, .augment/
.cursorrules, .copilotignore
any *.md other than README.md
any prompts/ instructions/ rules/ skills/ directory
STEP 3: For each flagged file: EXCLUDE by default. Convention authority
("but Next.js/Shopify/etc ships this") is NOT a reason to include.
STEP 4: Update .exclude with everything flagged.
STEP 5: If a flagged file was already committed by the scaffolder's
initial commit:
- git rm --cached <file>
- Stage the removal
- If this is the only commit: wipe .git and re-init clean
- If there are other commits: amend or follow Rule #14
STEP 6: Verify with the post-stage check before any commit:
git diff --cached --name-only | grep -iE "AGENTS|CLAUDE|COPILOT|CURSOR|\.claude|\.cursor|\.windsurf|\.codex|\.exclude|\.env"
Output MUST be empty.
Signs a File Needs Inspection
Read the file if ANY of these are true:
- File name is generic (notes.txt, plan.txt, todo.txt, scratch.*)
- File name contains "agent", "claude", "cursor", "copilot", "ai", "llm"
- File name contains "plan", "spec", "design", "architecture", "decision"
- File name contains "rule", "skill", "prompt", "instruction"
- File has an unexpected extension for its location
- File is in the project root and not a recognized config file
- File is markdown but not README.md
- File is a JSON/YAML that doesn't look like app config
- File has no extension
- File seems unusually large or small for its type
Git Operations
Adding files to git
BEFORE running git add:
1. Check .gitignore exists and contains `.exclude` entry. If missing, add it.
2. Check .exclude exists. If not, run a full scan first.
3. Check for new untracked files not in .exclude or .gitignore -- scan them.
4. NEVER use: git add . or git add -A or git add --all
5. ALWAYS add specific files or use patterns:
git add app/ config/ database/ resources/ routes/ tests/ public/
git add composer.json composer.lock package.json
git add .gitignore .editorconfig
git add README.md LICENSE
6. NEVER add .exclude -- it is LOCAL ONLY.
7. Double-check staged files: git status
8. If ANY excluded file appears in staged, unstage it immediately.
9. If .exclude appears staged: git reset HEAD .exclude
10. Run the AI-leak grep on staged files:
git diff --cached --name-only | grep -iE "AGENTS|CLAUDE|COPILOT|CURSOR|\.claude|\.cursor|\.windsurf|\.codex|\.exclude|\.env"
If output is non-empty, unstage every match and rescan.
Pre-push verification (run every push, no exceptions)
1. Verify HEAD tree contains no AI/agent leak:
git ls-tree -r HEAD --name-only | grep -iE "AGENTS|CLAUDE|COPILOT|CURSOR|\.claude|\.cursor|\.windsurf|\.codex|\.exclude|\.env"
Output MUST be empty. If not, abort and clean.
2. Verify the commit message has no AI attribution:
git log -1 --format=%B | grep -iE "claude|anthropic|copilot|cursor|cline|openai|gpt|co-authored"
Output MUST be empty.
3. Verify author identity is the human dev:
git log -1 --format="%an <%ae>"
Must NOT be Claude, Anthropic, Cursor, Copilot, or any AI vendor.
4. After push, verify the same on the remote tip:
git ls-remote origin
Then re-run step 1 against origin/main.
If ANY check fails after push: abort, wipe local .git, re-init, single
clean root commit, force push. Do not patch forward (Rule #14).
Creating commits
BEFORE committing:
1. Run: git status
2. Verify EVERY staged file is a project file
3. Check for accidentally staged:
- .env (CRITICAL -- never commit)
- .exclude (CRITICAL -- never commit, local only)
- .claude/, .cursor/, .agents/
- Plan files, skill files, rule files
- node_modules/, vendor/ paths
- .DS_Store, Thumbs.db
4. If anything suspicious is staged: git reset HEAD [file]
5. Verify .gitignore contains `.exclude` line. Add if missing.
Commit Authorship (ABSOLUTE ZERO TOLERANCE)
THIS IS THE MOST STRICTLY ENFORCED RULE IN THIS ENTIRE SKILL.
ABSOLUTELY NEVER -- UNDER ANY CIRCUMSTANCES -- ADD AI AS A
CONTRIBUTOR, CO-AUTHOR, OR COLLABORATOR TO ANY GIT COMMIT.
BANNED in commit messages:
- "Co-Authored-By: Claude" -- BANNED
- "Co-Authored-By: Claude Opus" -- BANNED
- "Co-Authored-By: Claude Sonnet" -- BANNED
- "Co-Authored-By: Claude Haiku" -- BANNED
- "Co-Authored-By: Claude Code" -- BANNED
- "Co-Authored-By: *anthropic*" -- BANNED
- "Co-Authored-By: *openai*" -- BANNED
- "Co-Authored-By: *Copilot*" -- BANNED
- "Co-Authored-By: *Cursor*" -- BANNED
- "Co-Authored-By: *Cline*" -- BANNED
- "Co-Authored-By: *AI*" -- BANNED
- ANY variation of "noreply@anthropic.com" -- BANNED
- ANY AI model name (opus, sonnet, haiku, gpt, gemini) -- BANNED
- "Generated by AI/Claude/Copilot" -- BANNED
- "Assisted by AI/Claude/Copilot" -- BANNED
- "Written by AI/Claude/Copilot" -- BANNED
- "Created with AI/Claude/Copilot" -- BANNED
BANNED in commit trailers:
- Co-Authored-By with ANY AI name or email
- Signed-off-by with ANY AI name or email
- Reviewed-by with ANY AI name or email
BANNED in PR descriptions:
- ANY mention of AI tools generating the code
- ANY AI attribution or credit line
- ANY "built with Claude/Copilot/Cursor" badges or text
BANNED in merge commits:
- Same rules as above. No exceptions.
THE DEVELOPER IS THE SOLE AUTHOR. ALWAYS. NO EXCEPTIONS.
NO DISCLAIMERS. NO FOOTNOTES. NO SMALL PRINT.
If you catch yourself about to add Co-Authored-By with any AI
name -- STOP. Remove it. The commit message contains ONLY what
changed and why. Nothing about who or what generated it.
BEFORE EVERY COMMIT, VERIFY:
1. Read the full commit message
2. Check for ANY AI name, email, or attribution
3. Check for Co-Authored-By trailer
4. If found: REMOVE IT before committing
5. This check is MANDATORY. Never skip it.
Zip Export Operations
Creating a zip
STEP 1: Run scan (full or incremental)
STEP 2: Build file list (project files only).
EXCLUDE ALWAYS:
- .exclude (LOCAL ONLY, never zip)
- Everything listed in .exclude
- Everything listed in .gitignore
STEP 3: Create zip with EXACT folder structure preserved:
- Every file keeps its relative path from project root
- Folder hierarchy is identical inside the zip
- No flat dump of files -- structure matters
STEP 4: Verify .exclude not in zip: unzip -l archive.zip | grep '\.exclude'
- If found: rebuild zip without it
STEP 5: Place zip in folder user specifies
STEP 6: Report:
"Created [name].zip in [path]
- [X] files included
- [Y] files excluded (.exclude, .gitignore patterns, AI/plan junk)
- Total size: [size]"
Zip structure example
project-name.zip
├── app/
│ ├── Http/
│ │ └── Controllers/
│ │ └── OrderController.php
│ └── Models/
│ └── Order.php
├── config/
│ └── app.php
├── database/
│ └── migrations/
│ └── 2024_01_01_create_orders_table.php
├── resources/
│ └── js/
│ └── Pages/
│ └── Orders/
│ └── Index.tsx
├── routes/
│ └── web.php
├── tests/
│ └── Feature/
│ └── OrderTest.php
├── composer.json
├── package.json
├── README.md
└── .gitignore
Every file in its exact original path. No exceptions.
Edge Cases
docs/ directory
Ask: "Does the docs/ directory ship with your application (e.g., API docs served by the app)? Or is it development documentation?"
- Ships with app -> include
- Development docs -> exclude
.json/.yaml files in project root
Read the file. If it contains:
- App configuration -> include
- Agent/skill/rule definitions -> exclude
- Plan or spec data -> exclude
Compiled/built assets in public/
- public/build/, public/dist/ -> include only if this IS the deployment (no build step on server)
- Ask if uncertain
Monorepo packages/
Each sub-package follows the same rules independently.
How to Use
Scan a project for the first time:
Scan this project and identify all non-project files. Create the .exclude file.
Add project files to git:
Add all project files to git. Skip everything that isn't source code or config.
Create a zip export:
Zip the project files and put the zip in /Users/me/Desktop/
Rescan after adding new files:
I added some new files. Rescan and update .exclude.
Check what would be included:
Show me what files would be included in a git add or zip, and what would be excluded.
Verify current git staging:
Check my git staging area for any files that shouldn't be committed.