Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions CLAUDE_CODE_SDLC_WIZARD.md
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,16 @@ When Anthropic provides official plugins or tools that handle something:
| **Claude Code v2.1.69+** | Required for InstructionsLoaded hook, skill directory variable, and Tasks system |
| **Git repository** | Files should be committed for team sharing |

**Installing Claude Code itself.** Use the native installer — it is what [the official setup docs](https://code.claude.com/docs/en/setup) label *Recommended*, and it auto-updates in the background with no `claude update` step to remember:

```bash
curl -fsSL https://claude.ai/install.sh | bash
```

**Never** install it with `sudo npm install -g @anthropic-ai/claude-code` — the official docs warn against that in those words, because sudo can leave the global module directory root-owned. When it does, the damage compounds, as observed on a real machine (#476): `claude update` refused with "Insufficient permissions to install update"; `npm uninstall -g` then failed with `EACCES`, because a normal user cannot rename a root-owned directory; and switching to the native install left *two* `claude` binaries on `PATH` at once, resolved by `PATH` order — so a reordering downgrades you to the stale pinned version. An npm install *without* sudo is not dangerous, just worse: if the global npm directory is not writable it stops auto-updating, with only a one-time notice at startup.

Run `which -a claude` to check for conflicting installations — that is the official docs' own procedure, and it is the one that catches a stale binary shadowing a newer one by `PATH` order. Use `claude doctor` for install health, but do not rely on it for this: when run with a decoy binary placed earlier on `PATH`, it reported no conflict.

**Blank repos (no CLAUDE.md, no code):** The wizard works on empty repos. Run `npx -y agentic-sdlc-wizard@latest init` — it installs hooks, skills, and the wizard doc. (The `@latest` pin guards against stale npx caches per #358.) On first session, the hooks detect missing SDLC files and redirect to `/claude-setup-wizard`, which generates CLAUDE.md, SDLC.md, TESTING.md, and ARCHITECTURE.md interactively. You do NOT need to run Claude's built-in `/init` first — the setup wizard handles everything.

---
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ A **self-evolving Software Development Life Cycle (SDLC) enforcement system for

## Install

**Requires [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview)** (Anthropic's CLI for Claude).
**Requires [Claude Code](https://docs.anthropic.com/en/docs/claude-code/overview)** (Anthropic's CLI for Claude). Install it with the native installer — `curl -fsSL https://claude.ai/install.sh | bash` — which the [official setup docs](https://code.claude.com/docs/en/setup) label *Recommended* and which keeps it auto-updating in the background. **Never** use `sudo npm install -g @anthropic-ai/claude-code`: sudo can leave the global module directory root-owned, which then breaks `claude update` *and* `npm uninstall -g`. Check for conflicting installs with `which -a claude`.

Run from your terminal or from inside Claude Code (`!` prefix):
```bash
Expand Down
60 changes: 60 additions & 0 deletions tests/test-doc-consistency.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3668,6 +3668,66 @@ $out"
}
test_guard_selftests_actually_run

# #476: the wizard documented how to install ITSELF and never how to install
# Claude Code, the thing it runs on. A real machine hit the footgun the official
# setup docs warn about in those words: `sudo npm install -g` left the global
# module dir root-owned, which killed `claude update` ("Insufficient
# permissions"), then killed `npm uninstall -g` (EACCES on a root-owned rename),
# and finally left two `claude` binaries on PATH at once — resolved by PATH
# order, so a reordering would have downgraded the user with no warning.
#
# Scoped to the Prerequisites SECTION on purpose. "the installer is named
# somewhere in a 4,900-line file" is the #493 failure mode — it passes on a doc
# that mentions the installer in an unrelated aside about version pinning, which
# this doc already contains at the version-test benchmark procedure. The claim
# under test is narrower and is the one that matters: a reader standing at the
# install moment is told which installer to use.
#
# The recommendation half exists because round 1 asserted only that the URL
# appeared. Rewriting the prose to "Do not use the native installer" while
# keeping the URL still passed — the guard proved a string, not a stance.
test_wizard_prereqs_recommend_native_claude_install() {
local DOC="$REPO_ROOT/CLAUDE_CODE_SDLC_WIZARD.md"
if [ ! -f "$DOC" ]; then fail "CLAUDE_CODE_SDLC_WIZARD.md not found"; return; fi
local section tmp negated
section=$(awk '/^## Prerequisites$/ { f = 1; next } /^## / { f = 0 } f' "$DOC")
if [ -z "$section" ]; then
fail "#476: no '## Prerequisites' section in the wizard doc to carry install guidance"
return
fi
tmp=$(mktemp "${TMPDIR:-/tmp}/prereq-XXXXXX")
printf '%s\n' "$section" > "$tmp"

if ! grep -qE 'claude\.ai/install\.sh' "$tmp"; then
fail "#476: wizard Prerequisites gives no Claude Code install command, so a reader at the install moment is never steered off sudo-npm"
rm -f "$tmp"; return
fi
if ! grep -qiE 'recommend' "$tmp"; then
fail "#476: wizard Prerequisites shows an install command but never says it is the recommended one — a bare command is not a recommendation"
rm -f "$tmp"; return
fi
# A negation reaching the installer without crossing a clause boundary.
# This is the whole inversion attack that was made against this test: keep
# the URL, flip the sentence to "Do not use the native installer". One grep
# closes it, because the negation has to sit right on the phrase.
#
# Deliberately NOT a general negation-scope engine. A companion guard that
# tried to be one cost four review rounds chasing sentence forms and one
# more chasing spellings of `sudo`, and was dropped for it — see #551. The
# docs are what #476 asked for; this test guards the stance the docs take,
# and cross-model review covers what a regex cannot.
negated=$(grep -inE "(do not|don't|never|avoid)[^.;,]*native install" "$tmp" || true)
rm -f "$tmp"
if [ -n "$negated" ]; then
fail "#476: wizard Prerequisites negates the native installer it is supposed to recommend:
$negated"
return
fi
pass "#476: wizard Prerequisites recommends the native Claude Code installer, unnegated"
}
test_wizard_prereqs_recommend_native_claude_install


echo "=== Results: $PASSED passed, $FAILED failed ==="

if [ "$FAILED" -gt 0 ]; then
Expand Down