Files
uupl-smart-contract/docs/superpowers/plans/2026-08-25-superpowers-artifact-ignore-policy.md

10 KiB

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:

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:

**/.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:

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
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:

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

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
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:

# 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
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
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:

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
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
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.