# Superpowers Artifact Ignore Policy Implementation Plan > **For agentic workers:** REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (`- [ ]`) syntax for tracking. **Goal:** Remove operational Superpowers artifacts from the current repository tip, prevent them from being committed in future projects, and resolve PR #2's `.gitignore` merge conflict without rewriting history. **Architecture:** Apply defense in depth: the user-level Git excludes file protects every local repository, while this repository's `.gitignore` protects collaborators and other machines. Merge current `origin/main` into `feature/uups-bank-demo`, retain local `.superpowers/` copies as ignored files, remove those artifacts from Git's index, and keep intentional documents under `docs/superpowers/` tracked. **Tech Stack:** Git, Bash, Make, the repository's existing Foundry/Node verification gate, and Gitea CLI `tea`. **Spec:** `docs/superpowers/specs/2026-08-25-superpowers-artifact-ignore-policy-design.md` ## Global Constraints - Operational Superpowers and worktree directories are private local state and must not be committed: `**/.superpowers/`, `**/.claude/superpowers/`, and `**/.worktrees/`. - Intentional design and implementation documents remain tracked under `docs/superpowers/specs/` and `docs/superpowers/plans/`. - Enforce the policy in both the machine-wide Git excludes file and this repository's `.gitignore`. - Remove `.superpowers/` from the current repository index without deleting local copies. - Do not rewrite published history or force-push. - Do not move or recreate `demo-start` or `demo-complete`. - Preserve existing global ignore entries byte-for-byte apart from appending the approved rules once. - Never print or inspect operational artifact contents during cleanup. - If any merge conflict other than `.gitignore` appears, stop and report it rather than applying a broad resolution. - Run the complete `make verify` gate before publishing the resolved branch. ## File and Interface Map | Area | Files | Responsibility | | --- | --- | --- | | Machine policy | `/home/golem/.config/git/ignore` | Ignore operational Superpowers and worktree directories in all local repositories | | Repository policy | `.gitignore` | Carry the same protection for collaborators while retaining application-specific generated/build exclusions | | Repository cleanup | `.superpowers/**` index entries introduced by current `origin/main` | Remove generated operational artifacts from the resulting repository tree while retaining local ignored copies | | Intentional docs | `docs/superpowers/specs/**`, `docs/superpowers/plans/**` | Remain tracked as authored project source | --- ### Task 1: Add the machine-wide Git ignore safeguard **Files:** - Modify: `/home/golem/.config/git/ignore` **Interfaces:** - Consumes: Git's default XDG user excludes file at `/home/golem/.config/git/ignore`. - Produces: machine-wide ignored-directory behavior for `.superpowers/`, `.claude/superpowers/`, and `.worktrees/` in repositories that have no local `.gitignore` rule. - [ ] **Step 1: Verify the current global policy does not yet ignore the three directories** Create an isolated repository with no local ignore file: ```bash probe_dir=$(mktemp -d /tmp/superpowers-ignore-policy.XXXXXX) git -C "$probe_dir" init -q mkdir -p "$probe_dir/.superpowers/sdd" "$probe_dir/.claude/superpowers" "$probe_dir/.worktrees/feature" touch "$probe_dir/.superpowers/sdd/report.md" "$probe_dir/.claude/superpowers/state.json" "$probe_dir/.worktrees/feature/marker" git -C "$probe_dir" check-ignore -v .superpowers/sdd/report.md .claude/superpowers/state.json .worktrees/feature/marker ``` Expected RED: `git check-ignore` exits `1` and prints no matching ignore rule. If all three paths are already ignored by the user-level file, do not duplicate them; record the existing matching rules and continue to Step 3. - [ ] **Step 2: Append the exact global exclusions once** Preserve the existing `**/.claude/settings.local.json` line and append exactly: ```gitignore **/.superpowers/ **/.claude/superpowers/ **/.worktrees/ ``` Use `apply_patch` directly when permitted. If the sandbox blocks editing `/home/golem/.config/git/ignore`, copy the file to a uniquely named `/tmp` path, use `apply_patch` on that copy, verify its diff against the original, then request narrowly scoped approval to install that exact prepared file back at `/home/golem/.config/git/ignore`. Do not use an in-place shell append that can duplicate entries. - [ ] **Step 3: Verify the global policy in an isolated repository** Run against the same `probe_dir`: ```bash git -C "$probe_dir" check-ignore -v .superpowers/sdd/report.md .claude/superpowers/state.json .worktrees/feature/marker ``` Expected GREEN: exit `0`; all three paths print a matching rule sourced from `/home/golem/.config/git/ignore`. - [ ] **Step 4: Verify uniqueness and preserve the existing rule** ```bash test "$(rg -n -x -F '**/.superpowers/' /home/golem/.config/git/ignore | wc -l)" -eq 1 test "$(rg -n -x -F '**/.claude/superpowers/' /home/golem/.config/git/ignore | wc -l)" -eq 1 test "$(rg -n -x -F '**/.worktrees/' /home/golem/.config/git/ignore | wc -l)" -eq 1 rg -n -x -F '**/.claude/settings.local.json' /home/golem/.config/git/ignore ``` Expected: each new rule occurs exactly once and the pre-existing settings rule remains present. - [ ] **Step 5: Remove only the isolated probe** Validate the prefix before deleting: ```bash case "$probe_dir" in /tmp/superpowers-ignore-policy.*) rm -rf "$probe_dir" ;; *) echo "refusing unexpected probe path: $probe_dir" >&2; exit 1 ;; esac ``` No repository commit is created for this user-level configuration task. --- ### Task 2: Merge main, resolve the policy conflict, and untrack runtime artifacts **Files:** - Modify: `.gitignore` - Remove from index only: `.superpowers/**` - Preserve tracked: `docs/superpowers/specs/**` - Preserve tracked: `docs/superpowers/plans/**` **Interfaces:** - Consumes: `origin/main` at the latest fetched commit, `feature/uups-bank-demo`, and the global exclusions produced by Task 1. - Produces: a normal merge commit whose tree contains no `.superpowers/**` paths, keeps intentional `docs/superpowers/**` documents, and is conflict-free against the fetched `origin/main`. - [ ] **Step 1: Confirm the exact pre-merge state** ```bash git fetch origin main feature/uups-bank-demo git status --short --branch git rev-parse HEAD git rev-parse origin/main git rev-parse origin/feature/uups-bank-demo git merge-tree --write-tree --messages origin/main HEAD ``` Expected RED: the branch is clean and named `feature/uups-bank-demo`; `git merge-tree` reports exactly one content conflict, `.gitignore`. If another path conflicts, stop and report it. - [ ] **Step 2: Start a non-fast-forward merge without committing** ```bash git merge --no-ff --no-commit origin/main ``` Expected: Git stops with one unresolved path, `.gitignore`; files newly tracked by `origin/main` may appear under `.superpowers/`. - [ ] **Step 3: Resolve `.gitignore` to the exact repository policy** Replace the conflicted file with: ```gitignore # Local agent/session state .claude/superpowers/ .superpowers/ .worktrees/ .env .env.local .demo/ cache/ out/ broadcast/ deployments/*.json deployments/**/*.json !deployments/*.example.json node_modules/ web/node_modules/ web/dist/ web/coverage/ web/public/deployment.json web/src/generated/*.ts !.gitkeep ``` Do not retain `main`'s granular `.superpowers/brainstorm/...` rules; the broad `.superpowers/` rule is the approved policy. - [ ] **Step 4: Keep operational artifacts locally while removing them from Git's index** ```bash git add .gitignore git rm -r --cached .superpowers ``` Expected: `.superpowers/**` paths are staged as deletions from the merge result but remain present locally and ignored. - [ ] **Step 5: Verify the resolved merge before committing** ```bash test -z "$(git diff --name-only --diff-filter=U)" test -z "$(git ls-files '.superpowers/**')" git check-ignore -v --no-index .superpowers/sdd/example.md .claude/superpowers/state.json .worktrees/example/marker git ls-files 'docs/superpowers/specs/**' 'docs/superpowers/plans/**' git diff --cached --check git status --short ``` Expected: no unresolved paths; no `.superpowers/**` index entries; all three operational paths ignored by `.gitignore`; the approved design and implementation plan remain tracked; no whitespace errors. - [ ] **Step 6: Commit the merge cleanup** Inspect the staged path set without opening operational artifact contents, then commit: ```bash git diff --cached --name-status git commit -m "chore: keep superpowers artifacts local" ``` Expected: a merge commit with `origin/main` and the former feature HEAD as parents; no history rewrite and no tag movement. - [ ] **Step 7: Run focused policy verification** ```bash git merge-base --is-ancestor origin/main HEAD test -z "$(git ls-tree -r --name-only HEAD -- .superpowers)" git check-ignore -v --no-index .superpowers/sdd/example.md .claude/superpowers/state.json .worktrees/example/marker git ls-tree -r --name-only HEAD -- docs/superpowers/specs docs/superpowers/plans git diff --check origin/feature/uups-bank-demo..HEAD git status --short --branch ``` Expected: `origin/main` is an ancestor; the committed tree has no `.superpowers` paths; intentional docs remain; the branch is ahead of `origin/feature/uups-bank-demo` only by the policy/design and merge-cleanup commits; the worktree has no tracked changes. - [ ] **Step 8: Run the complete repository gate** ```bash export PATH=/tmp/node-v24.18.0-linux-x64/bin:$PATH export npm_config_cache=/tmp/uups-demo-npm-cache export npm_config_offline=true make verify git diff --check ``` Expected GREEN: all Solidity, finalizer, process-safety, Base configuration, scanner, web lint/typecheck/test/build checks exit `0`; `git diff --check` exits `0`. --- ## Final Review and Publication After both tasks pass their independent SDD review gates: 1. Run the whole-plan review over the design commit and merge-cleanup range. 2. Run a fresh controller `make verify` and `git diff --check` at the reviewed HEAD. 3. Confirm `demo-start` and `demo-complete` still peel to their pre-cleanup targets. 4. Push `feature/uups-bank-demo` normally with no force option. 5. Query Gitea PR #2 and require `state: open`, `base: main`, `head: feature/uups-bank-demo`, and `mergeable: true`. 6. Preserve the existing linked worktree for PR feedback.