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

241 lines
10 KiB
Markdown

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