# CLAUDE.md

This file provides guidance to the active coding agent when working with code in this repository.

> **Always adhere strictly to this file and silver-bullet.md — they override all defaults.**

<!-- BEGIN context-mode hint (do not edit) -->
## Context Mode usage

When reading large files, MCP results, or web fetches:

- For files > 5 KB: use Context Mode index + search tools (`ctx_index` / `ctx_search` or host-qualified MCP names) instead of reading the whole file.
- For Playwright snapshots, web fetches, and other MCP tool results: use `ctx_execute` to run a sandboxed script that processes the result and only returns relevant `console.log` lines.
- For batch reads (5+ files): use `ctx_batch_execute` instead of N separate reads.

If a call returns "tool not found", run Context Mode doctor in a live session to confirm the exact tool prefix for your host, or use slash commands where available (`/ctx-index`, `/ctx-search` on Claude Code).

For everything else, use your normal tools. RTK handles shell command output automatically when RTK is opted in and wired.
<!-- END context-mode hint (do not edit) -->

---

## Project Overview

Silver Bullet is a host-aware plugin — an agentic process orchestrator that enforces structured AI-native workflows via hooks, skills, and a state machine. It ships as a plugin (installed via `/plugin install`) and activates inside any downstream project.

- **Stack**: Bash (hooks, lib, scripts, tests), Markdown (skills, templates), JSON (config, hooks manifest)
- **Git repo**: https://github.com/alo-exp/silver-bullet.git
- **Runtime prerequisite**: `jq` (all hooks fail-open with a visible warning when absent)

> **Development rule**: All code edits go to **source files in this repo** (`hooks/`, `scripts/`, `skills/`, `templates/`, `tests/`, `.github/`, etc.). Never modify the installed plugin cache at the host's plugin cache path (for example `${SB_RUNTIME_HOME_ROOT}/plugins/cache/alo-labs/silver-bullet/*/` or the equivalent Codex cache path) — that is a read-only build artifact. Source changes here are what gets released and installed.

---

## Commands

### Running Tests

```bash
# Full test suite (hook unit tests + integration scenarios + coverage matrix)
bash tests/run-all-tests.sh

# Single hook unit test
bash tests/hooks/test-completion-audit.sh

# Single integration test
bash tests/integration/test-e2e-enforcement-gates.sh

# Single script test
bash tests/scripts/test-semantic-compress.sh
```

### Linting and Validation

```bash
# Syntax-check all hook scripts
for f in hooks/*.sh hooks/lib/*.sh; do bash -n "$f" && echo "OK: $f"; done

# ShellCheck (if installed)
shellcheck hooks/*.sh hooks/lib/*.sh scripts/*.sh

# Validate hooks.json
jq . hooks/hooks.json > /dev/null && echo "hooks.json valid"

# Validate .silver-bullet.json
jq . .silver-bullet.json > /dev/null && echo ".silver-bullet.json valid"

# Validate templates/silver-bullet.config.json.default
jq . templates/silver-bullet.config.json.default > /dev/null
```

### Development Setup (for contributors)

```bash
# Prerequisites
brew install jq
# In the host coding agent: /sb:init — activates enforcement in this repo
```

---

## Architecture

### Core Concepts

Silver Bullet has **two personas**:
1. **As a plugin** — installs into end-user projects. Users never see the source; they interact with `silver-bullet.md` + `CLAUDE.md` generated by `/sb:init`.
2. **As a repo** — this codebase, where enforcement is active on itself (dogfooding).

The three pillars:

| Pillar | Location | Role |
|--------|----------|------|
| **Skills** | `skills/<name>/SKILL.md` | Orchestrator instructions loaded by the Skill tool |
| **Hooks** | `hooks/*.sh` + `hooks/hooks.json` | Runtime enforcement injected into every host coding session |
| **Config** | `.silver-bullet.json` (per-project) + `templates/silver-bullet.config.json.default` | Required-skill lists, state file paths, src patterns |

### Hook Architecture

`hooks/hooks.json` maps host hook events to shell scripts:

- **SessionStart** → `session-start` (branch-scoped state reset, context injection), `spec-session-record.sh`
- **PreToolUse/Bash** → `phase-archive.sh`, `completion-audit.sh`, `roadmap-freshness.sh`, `dev-cycle-check.sh`, `ci-status-check.sh`, `spec-floor-check.sh`
- **PreToolUse/Edit|Write|MultiEdit** → `planning-file-guard.sh` (blocks direct edits to SB-managed planning artifacts)
- **PreToolUse/Skill** → `forbidden-skill-check.sh`, `uat-gate.sh`
- **PostToolUse/Skill** → `semantic-compress.sh`, `record-skill.sh` (writes to state file)
- **PostToolUse/Write|Edit|MultiEdit** → trivial-file removal (marks session as non-trivial)
- **PostToolUse/Bash** → `completion-audit.sh`, `pr-traceability.sh`, `session-log-init.sh`, `ci-status-check.sh`, `timeout-check.sh`
- **PostToolUse/\*** → `compliance-status.sh` (async, informational)
- **Stop / SubagentStop** → `stop-check.sh` (blocks task-complete if required skills missing)
- **UserPromptSubmit** → `record-requested-skill.sh`, `prompt-reminder.sh` (records requested routes, re-injects missing skill list)

### Two-Tier Enforcement Model

`completion-audit.sh` and `stop-check.sh` enforce two separate gates:

1. **Intermediate commits** (`git commit`, `git push`, and git plumbing that creates commits: `write-tree`, `commit-tree`, `hash-object -w`, `update-ref refs/heads/*`) — requires only `required_planning` skills (default: `silver-quality-gates`). Allows execution subagents to make atomic commits mid-execution.
2. **Final delivery** (`gh pr create`, `gh release create`, `deploy`) — requires the full `required_deploy` list from `.silver-bullet.json`.

The required-skill list has a **single source of truth**: `templates/silver-bullet.config.json.default`. Hooks source `hooks/lib/required-skills.sh`, which reads from that file via `jq` at runtime — there are no hardcoded skill literals in hook scripts.

### State Machine

Skill invocations are recorded to `${SB_RUNTIME_HOME_ROOT}/.silver-bullet/state` by `record-skill.sh` after each `PostToolUse/Skill` event. The state is:
- **Branch-scoped**: wiped when `git branch` or git worktree toplevel changes between sessions (tracked via `${SB_RUNTIME_HOME_ROOT}/.silver-bullet/branch`)
- **Trivial bypass**: if `${SB_RUNTIME_HOME_ROOT}/.silver-bullet/trivial` file exists (real file, not symlink), all enforcement gates exit 0 — used for typo/config-only sessions; auto-created at SessionStart, removed on first Write/Edit

### SB OVERRIDE (audited escape hatch)

When a blocking orchestrator directive or PreToolUse gate cannot be satisfied, include in your next user message:

`SB OVERRIDE: <reason>`

The hook logs the override to `.planning/orchestrator-override-log.jsonl` and clears the pending directive. Documented in `silver-bullet.md` §2h and `docs/ORCHESTRATOR.md`.

**Test env-var overrides** (mirrors the `SILVER_BULLET_STATE_FILE` pattern):
- `SILVER_BULLET_STATE_FILE` — overrides the default state file path (`${SB_RUNTIME_HOME_ROOT}/.silver-bullet/state`); must remain under `${SB_RUNTIME_HOME_ROOT}/`
- `SILVER_BULLET_BRANCH_FILE` — overrides the branch-tracking file path (`${SB_RUNTIME_HOME_ROOT}/.silver-bullet/branch`); must remain under `${SB_RUNTIME_HOME_ROOT}/`. Used by integration tests (`tests/integration/helpers/common.sh`) to supply a per-test mock branch file so `session-start` does not read or mutate the live branch file during test runs.

### Shared Libraries (`hooks/lib/`)

| File | Purpose |
|------|---------|
| `required-skills.sh` | Discovers and populates `DEFAULT_REQUIRED` / `DEVOPS_DEFAULT_REQUIRED` from `templates/silver-bullet.config.json.default` |
| `workflow-utils.sh` | Single source of truth for Flow Log regex (`count_flow_log_rows`, `count_complete_flow_rows`) used by multiple hooks |
| `trivial-bypass.sh` | `sb_trivial_bypass()` — shared exit-0 guard for trivial sessions |
| `nofollow-guard.sh` | `sb_guard_nofollow()` / `sb_safe_write()` — refuse to write through symlinks (SEC-02) |

### Skills

Every skill is a single `SKILL.md` file with YAML frontmatter (`name`, `description`, optional `argument-hint`). The **composable flow skills** are orchestrators that sequence other skills:

- `silver-feature` — 20-step app development workflow
- `silver-ui` — UI variant of silver-feature, adds UI phase and review steps
- `silver-bugfix` — diagnosis-first bug fix workflow
- `silver-release` — cross-artifact review → deploy-checklist → ship ordering
- `silver-devops` — infrastructure / DevOps variant

Composable flow skills sequence SB-owned lifecycle skills. Legacy `gsd-*` marker names remain as compatibility aliases in hooks and config.

### Templates

`templates/` contains the files that `/sb:init` stamps into downstream projects:
- `silver-bullet.md.base` → becomes `silver-bullet.md` in the target project
- `CLAUDE.md.base` → becomes `CLAUDE.md` in the target project
- `silver-bullet.config.json.default` → default values for `.silver-bullet.json`
- `workflow.md.base` → becomes `.planning/workflows/<id>.md`

**Critical invariant**: changes to enforcement logic (required skill lists, hook behavior) must be reflected in **both** `silver-bullet.md` (this repo's live copy) **and** `templates/silver-bullet.md.base` (the template stamped into new projects). Same for `CLAUDE.md` / `CLAUDE.md.base`.

### Tests

Tests use a consistent pattern:
- Each test creates a temp directory with a real `git init`, writes a `.silver-bullet.json` config, and sets `SILVER_BULLET_STATE_FILE` to a path under `${SB_RUNTIME_HOME_ROOT}/` (path validation in hooks rejects anything outside `${SB_RUNTIME_HOME_ROOT}/`)
- Hook scripts are invoked by piping JSON via stdin (matching the host hook protocol)
- Results are parsed from `Results: N passed, M failed` lines

---

## Key Invariants

- **`jq` is required** — all hooks fail-open (warn + exit 0) if `jq` is absent; never fail silently
- **ERR trap pattern** — every hook has `trap 'exit 0' ERR` so unexpected failures don't block the active runtime
- **No hardcoded skill literals in hooks** — only `hooks/lib/required-skills.sh` reads the canonical list from `templates/silver-bullet.config.json.default`
- **Config is authoritative** — when `.silver-bullet.json` has `required_deploy`, it overrides the default; hooks never append extra mandatory skills on top
- **Plugin boundary** — `dev-cycle-check.sh` hard-blocks any Edit/Write targeting `${SB_RUNTIME_HOME_ROOT}/plugins/cache/**` (§8 enforcement)
- **State files must be under `${SB_RUNTIME_HOME_ROOT}/`** — `session-start` and `completion-audit.sh` reject `SILVER_BULLET_STATE_FILE` paths outside this prefix

## graphify

This project has a knowledge graph at graphify-out/ with god nodes, community structure, and cross-file relationships.

Rules:
- For codebase questions, first run `graphify query "<question>"` when graphify-out/graph.json exists. Use `graphify path "<A>" "<B>"` for relationships and `graphify explain "<concept>"` for focused concepts. These return a scoped subgraph, usually much smaller than GRAPH_REPORT.md or raw grep output.
- If graphify-out/wiki/index.md exists, use it for broad navigation instead of raw source browsing.
- Read graphify-out/GRAPH_REPORT.md only for broad architecture review or when query/path/explain do not surface enough context.
- After modifying code, run `graphify update .` to keep the graph current (AST-only, no API cost).
