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
40 changes: 40 additions & 0 deletions .github/workflows/gate.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
name: gate

on:
push:
branches: [main]
pull_request:

# Nothing here writes to the repo; keep the token read-only even for same-repo branches.
permissions:
contents: read

jobs:
gate:
name: Local quality gate (CLAUDE.md §19.3)
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@fbc6f3992d24b796d5a048ff273f7fcc4a7b6c09 # v5.1.0

- name: Install shellcheck and jq
run: sudo apt-get update -q && sudo apt-get install -y -q shellcheck jq

- name: Bash hooks and tests lint clean
run: shellcheck hooks/*.sh tests/hooks/*.sh

- name: Settings parse as valid JSON
run: jq empty settings.json settings2.json

- name: Every agent declares a name
run: test -z "$(grep -L '^name:' agents*/*.md)"

- name: Scaffolder templates match the canonical project template
run: |
diff -q templates/CLAUDE.project.md skills/new-repo/templates/web/CLAUDE.md.tmpl
diff -q templates/CLAUDE.project.md skills/new-repo/templates/android/CLAUDE.md.tmpl

- name: Commit-guard hook behavior
run: bash tests/hooks/test-guard-commit.sh

- name: Format hook behavior
run: bash tests/hooks/test-format.sh
21 changes: 12 additions & 9 deletions CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ Every non-trivial change goes through four phases, in order — wear all four ha

1. **Architect** (read-only): minimal change? existing patterns to match? failure modes (auth, network, concurrency, data loss, partial failure, retry storms)? scope boundaries? → a 3–8 line plan, user-approved. Run this in **plan mode** so the read-only constraint is enforced by the harness, not just intended.
2. **Engineer:** implement the plan, nothing more. One _purpose_ per commit. Run the code; if it doesn't start, fix it before moving on.
3. **Code Reviewer** (read-only, adversarial): walk the review checklist against the diff as if you didn't write it. Zero-open-comments rule — every issue fixed or explicitly justified before proceeding.
3. **Code Reviewer** (read-only, adversarial): walk the review checklist against the diff, and the diff against the Phase 1 plan, as if you didn't write it. Zero-open-comments rule — every issue fixed or explicitly justified before proceeding.
4. **QA:** run the local quality gate (platform rule §7), the happy path, at least one realistic error case, and a regression check. If a test fails, diagnose the failure class (§4.7) before reacting. Don't push broken code.

**§4.5 Skip rules.** Typo / config-only: skip Phase 1 & 4. `type:chore|docs|qa` that's text-/config-/test-config-only: skip Phases 1, 3, 4 (use judgement — keep all four if there's real surface area). Everything else: all four, every time.
Expand All @@ -74,7 +74,7 @@ The layer that wraps the four hats. `technical-program-manager` owns what / why

## 9. Stacked PR Workflow

Shipping multiple related PRs in a session: local feature branch per ticket; **don't push the version-bump + CHANGELOG combo until the prior PR merges** (else both touch the same version lines and the second hits a rebase conflict); when it merges, `git checkout <protected> && git pull --ff-only`, then `git rebase <protected>` the next branch **locally** rather than relying on platform conflict-resolution (squash-merge SHAs don't match local commits). Full rebase discipline + the stash-and-checkout pitfall: `~/.claude/docs/git-workflows.md`.
Shipping multiple related PRs in a session: local feature branch per ticket; **don't push the version-bump + CHANGELOG combo until the prior PR merges** (else both touch the same version lines and the second hits a rebase conflict); when it merges, `git checkout <protected> && git pull --ff-only`, then `git rebase <protected>` the next branch **locally** rather than relying on platform conflict-resolution (squash-merge SHAs don't match local commits). Full rebase discipline, the stash-and-checkout pitfall, and what to do between PR-open and merge (CI, review-thread replies with a pushed SHA, re-check after every push): `~/.claude/docs/git-workflows.md`.

---

Expand Down Expand Up @@ -166,23 +166,27 @@ Four no-code extensions cover almost everything before you'd fork the binary: **
- **Framework(s):** None (only Claude Code extension points — §18).
- **Storage:** None.
- **Build / package:** None — files are copied verbatim into `~/.claude/`; `package.json` is intentionally absent.
- **Test runner:** None; verification is static (§19.3).
- **CI:** None currently (no `.github/workflows`); the gate runs locally before tagging.
- **Test runner:** Plain bash. `tests/hooks/*.sh` feed each hook a PreToolUse / PostToolUse JSON payload on stdin and assert the exit code (bash 3.2 + jq + git, no framework).
- **CI:** `.github/workflows/gate.yml` runs §19.3 on every PR and on push to `main`. The same commands run locally before tagging.
- **Distribution channel:** Public GitHub `roadhero/claude-code-setup`, MIT, released as annotated `vX.Y.Z` tags + a matching GitHub Release. No package registry.

### 19.3 Local quality gate

Concrete commands a fresh clone can run (verified green: shellcheck exit 0, jq exit 0).
Concrete commands a fresh clone can run; `.github/workflows/gate.yml` runs the same list.

```bash
shellcheck hooks/*.sh # bash hooks lint clean (bash 3.2 target)
shellcheck hooks/*.sh tests/hooks/*.sh # bash hooks + tests lint clean (bash 3.2 target)
jq empty settings.json settings2.json # settings parse as valid JSON
grep -L '^name:' agents*/*.md # every agent declares a name; prints nothing when clean
diff -q templates/CLAUDE.project.md skills/new-repo/templates/web/CLAUDE.md.tmpl # scaffolder copies
diff -q templates/CLAUDE.project.md skills/new-repo/templates/android/CLAUDE.md.tmpl # stay byte-identical
bash tests/hooks/test-guard-commit.sh # commit guard: stdin payload → exit code, one case per rule/regression
bash tests/hooks/test-format.sh # format hook: exit 0, touches only the tool's own target
# Optional, advisory (not installed by default; repo ships no markdownlint config):
# npx --yes markdownlint-cli2 "**/*.md" "!skills/**/templates/**"
```

Requires `shellcheck` and `jq` (the hooks need `jq` at runtime too) — `brew install shellcheck jq`. No build step; files ship verbatim. Markdown prose is reviewed by eye, not hard-gated.
Requires `shellcheck`, `jq`, and `git` (the hooks need `jq` at runtime too) — `brew install shellcheck jq`. No build step; files ship verbatim. Markdown prose is reviewed by eye, not hard-gated. A hook bug fix starts with a failing case in `tests/hooks/` (§3.4).

### 19.4 Current release pointers

Expand All @@ -201,10 +205,9 @@ Requires `shellcheck` and `jq` (the hooks need `jq` at runtime too) — `brew in

> Each override erodes the predictability §1–18 provides; treat them as debt with a documented reason. Review quarterly: can any be removed?

- §19.3 replaces the build/unit/integration gate with static analysis (shellcheck + jq + a name-invariant grep) — reason: this repo ships configuration, not code; nothing to compile or unit-test.
- §19.3 replaces the build/unit/integration gate with static analysis (shellcheck + jq + a name-invariant grep + a copies-in-sync diff) plus behavioral tests for the two hooks — reason: this repo ships configuration; the hooks are its only executable code, so they are the only thing unit-tested.
- Release notes come from the GitHub Release body instead of a `CHANGELOG.md` — reason: no CHANGELOG is maintained here.
- Platform rule-pack path-triggering (`rules/{web,android,ios,compute}.md`) never fires in this repo — it has no matching source files. Expected.
- No CI yet — candidate follow-up: a GitHub Action running §19.3 on PR.

---

Expand Down
27 changes: 14 additions & 13 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,19 +6,20 @@ Most people publish a single `CLAUDE.md` and call it a setup. The thing that act

## What's inside

| Path | What it is |
| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLAUDE.md` | The universal spine — a lean (~215-line) always-loaded core: workflow, git rules, coding guidelines, secrets, anti-patterns. Stack-agnostic. Longer reference material lives in `docs/` and loads on demand. |
| `rules/{web,android,ios,compute}.md` | Platform rule packs. Each carries a `paths:` frontmatter glob; Claude Code loads a pack when it reads a file matching that glob (`*.kt` → android, `*.swift` → ios, `*.ts`/`*.py` → web, `*.cpp`/`*.cu` → compute). Path-triggered, so packs whose files you never touch stay out of context. |
| `agents/` (15) | The default subagent roster: the four-hat chain (architect → senior-swe → code-reviewer → qa), plus specialists (security, performance, db-migration, debugger, devops, docs, design), release-engineer + tech-writer, and a delivery layer (TPM, scrum-master). |
| `agents-android/` (7), `agents-ios/` (7), `agents-compute/` (13) | Per-stack overrides. Drop them into a repo's `.claude/agents/` and they override the generic ones of the same name with platform-brained versions. |
| `hooks/guard-commit.sh` | A Claude Code Bash hook (PreToolUse) that blocks the _agent_ from force-pushing, committing as a non-human, writing AI attribution into a commit message, or staging obvious secrets. It guards Claude's git commands — not a human typing `git` directly in their own terminal. |
| `hooks/format.sh` | Auto-formats edited files by extension across every stack. Missing formatter is a silent no-op, never an error. |
| `skills/new-repo/` | A scaffolder skill: spins up a new repo with the right `CLAUDE.md`, `.gitignore`, quality gate, and release workflow. Scaffolds **web + Android**; iOS and compute ship as rule + agent packs (no scaffolder for them yet). |
| `docs/` | On-demand reference the spine points to (full roster tables, the Phase-3 review checklist, the error-recovery table, PR template, scaling notes). Installed to `~/.claude/docs/`; loaded only when a stub references it. |
| `templates/` | Blank project `CLAUDE.md` templates (generic + compute) to copy into a new repo and fill in. |
| `examples/CLAUDE.example-web.md` | A filled-in example so you can see what "done" looks like before you write your own. |
| `STRUCTURE.md` | The full layout, install steps, and how the two-settings-file swap works. **Read this first.** |
| Path | What it is |
| ---------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `CLAUDE.md` | The universal spine — a lean (~220-line) always-loaded core: workflow, git rules, coding guidelines, secrets, anti-patterns. Stack-agnostic. Longer reference material lives in `docs/` and loads on demand. |
| `rules/{web,android,ios,compute}.md` | Platform rule packs. Each carries a `paths:` frontmatter glob; Claude Code loads a pack when it reads a file matching that glob (`*.kt` → android, `*.swift` → ios, `*.ts`/`*.py` → web, `*.cpp`/`*.cu` → compute). Path-triggered, so packs whose files you never touch stay out of context. |
| `agents/` (15) | The default subagent roster: the four-hat chain (architect → senior-swe → code-reviewer → qa), plus specialists (security, performance, db-migration, debugger, devops, docs, design), release-engineer + tech-writer, and a delivery layer (TPM, scrum-master). |
| `agents-android/` (7), `agents-ios/` (7), `agents-compute/` (13) | Per-stack overrides. Drop them into a repo's `.claude/agents/` and they override the generic ones of the same name with platform-brained versions. |
| `hooks/guard-commit.sh` | A Claude Code Bash hook (PreToolUse) that blocks the _agent_ from force-pushing, skipping git hooks with `--no-verify`, committing as a non-human, writing AI attribution into a commit message, or staging obvious secrets. Every segment of a chained command is checked on its own. It guards Claude's git commands — not a human typing `git` directly in their own terminal. |
| `hooks/format.sh` | Auto-formats edited files by extension across every stack. Missing formatter is a silent no-op, never an error. |
| `tests/hooks/` | Behavioral tests for both hooks: a JSON payload on stdin, an exit code out, one case per rule and per past regression. Plain bash 3.2 + `jq`. CI (`.github/workflows/gate.yml`) runs them with the rest of the quality gate on every PR. |
| `skills/new-repo/` | A scaffolder skill: spins up a new repo with the right `CLAUDE.md`, `.gitignore`, quality gate, and release workflow. Scaffolds **web + Android**; iOS and compute ship as rule + agent packs (no scaffolder for them yet). |
| `docs/` | On-demand reference the spine points to (full roster tables, the Phase-3 review checklist, the error-recovery table, PR template, scaling notes). Installed to `~/.claude/docs/`; loaded only when a stub references it. |
| `templates/` | Blank project `CLAUDE.md` templates (generic + compute) to copy into a new repo and fill in. |
| `examples/CLAUDE.example-web.md` | A filled-in example so you can see what "done" looks like before you write your own. |
| `STRUCTURE.md` | The full layout, install steps, and how the two-settings-file swap works. **Read this first.** |

## The idea in one paragraph

Expand Down
Loading