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
16 changes: 8 additions & 8 deletions .claude/rules/security.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,17 +11,17 @@ This file states requirements. It does not, by itself, enforce them. Enforcement
3. **Hooks** (`.claude/hooks/*`) — deterministic guardrails, not a security boundary. This repo's hooks are **fail-open by design**: if `jq` is missing or input can't be parsed, the check is skipped and the tool call proceeds. See `docs/hooks.md` for the full security model.
4. **`permissions.deny` + CI** — boundaries. `permissions.deny` in `settings.json` cannot be overridden by any allow rule at any scope. CI checks (`.github/workflows/`) run outside the agent's control and block merges on failure.

Only the mechanically checkable items on this page have enforcement below step 1. The checklist states what must be true; it is the hooks, `permissions.deny` entries, and CI jobs cited in each line's parenthetical that actually verify it.
Only the mechanically checkable items on this page have enforcement below rung 1. The checklist below tags every line with its actual rung (1–4, matching the ladder above) and names the hook, `permissions.deny` entry, or CI job that verifies it; a rung-1 tag means prose only — nothing here mechanically checks it.

## Security Checklist

- [ ] No hardcoded secrets or credentials (enforced via `pre-tool-use-validator.sh` hook secret detection + CI secret-scan job, Trivy `fs --scanners secret`, blocking)
- [ ] All user input is validated and sanitized (enforce via input validation middleware)
- [ ] SQL queries use parameterized statements
- [ ] Authentication and authorization are properly implemented
- [ ] Sensitive data is encrypted at rest and in transit
- [ ] Error messages don't expose internal details
- [ ] Dependencies are up to date and vulnerability-free (enforce via automated dependency scanning)
- [ ] No hardcoded secrets or credentials (rung 3+4 — enforced via `pre-tool-use-validator.sh` hook secret detection across Write/Edit content and Bash redirects/heredocs, plus CI secret-scan job, Trivy `fs --scanners secret,vuln`, blocking)
- [ ] All user input is validated and sanitized (rung 1 — adopter-level: enforce in your application/CI; this framework cannot check it)
- [ ] SQL queries use parameterized statements (rung 1 — adopter-level: enforce in your application/CI; this framework cannot check it)
- [ ] Authentication and authorization are properly implemented (rung 1 — adopter-level: enforce in your application/CI; this framework cannot check it)
- [ ] Sensitive data is encrypted at rest and in transit (rung 1 — adopter-level: enforce in your application/CI; this framework cannot check it)
- [ ] Error messages don't expose internal details (rung 1 — adopter-level: enforce in your application/CI; this framework cannot check it)
- [ ] Dependencies are up to date and vulnerability-free (rung 4 — enforced via this repo's own Trivy `fs --scanners secret,vuln` CI job, blocking (trivially green today: no dependency manifests exist in this repo); every stack pack ships a matching native audit gate — `pnpm audit --audit-level high` / `uvx pip-audit` / `govulncheck ./...` / `cargo audit` in `.claude/templates/stack-packs/*/ci-gates.yml` — reaching the same CI rung in an adopter's own repo once merged)

## Data Routing

Expand Down
3 changes: 3 additions & 0 deletions .claude/templates/stack-packs/go/ci-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ gates:
- uses: golangci/golangci-lint-action@v9.3.0
with:
version: v2.12
# dependency scan — .claude/rules/security.md Dependency Safety
- run: go install golang.org/x/vuln/cmd/govulncheck@latest
- run: govulncheck ./...
- run: go test ./...
- run: go vet ./...
- run: go build ./...
2 changes: 1 addition & 1 deletion .claude/templates/stack-packs/go/golden-path.skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Regenerate `go.sum` with `go mod tidy` after every dependency change — never h

## Gates Wiring

`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `go.mod` and reminds you to run these commands before a commit lands. CI runs the identical gates — see this pack's `ci-gates.yml`.
`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `go.mod` and reminds you to run these commands before a commit lands. CI runs the same gates plus a dependency-audit step (`govulncheck ./...`) that has no local pre-commit equivalent — see this pack's `ci-gates.yml`.

## Related Skills

Expand Down
2 changes: 2 additions & 0 deletions .claude/templates/stack-packs/python/ci-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ gates:
with:
enable-cache: true
- run: uv sync --locked
# dependency scan — .claude/rules/security.md Dependency Safety
- run: uvx pip-audit
- run: uv run pytest
- run: uv run ruff check .
- run: uv run ruff format --check .
Expand Down
2 changes: 1 addition & 1 deletion .claude/templates/stack-packs/python/golden-path.skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ Regenerate `uv.lock` with `uv lock` (`uv sync` regenerates it implicitly too)

## Gates Wiring

`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `pyproject.toml` and reminds you to run these commands before a commit lands. CI runs the identical four gates — see this pack's `ci-gates.yml`.
`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `pyproject.toml` and reminds you to run these commands before a commit lands. CI runs the same four gates plus a dependency-audit step (`uvx pip-audit`) that has no local pre-commit equivalent — see this pack's `ci-gates.yml`.

## Related Skills

Expand Down
2 changes: 2 additions & 0 deletions .claude/templates/stack-packs/rust/ci-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,8 @@ gates:
- uses: actions-rust-lang/setup-rust-toolchain@v1.17.0
with:
components: clippy, rustfmt
- run: cargo install cargo-audit --locked # dependency scan — .claude/rules/security.md Dependency Safety
- run: cargo audit # vulnerability audit
- run: cargo test # test suite
- run: cargo clippy # lint
- run: cargo fmt --check # format check
Expand Down
2 changes: 1 addition & 1 deletion .claude/templates/stack-packs/rust/golden-path.skill.md
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Cargo regenerates `Cargo.lock` automatically on any command that resolves depend

## Gates Wiring

`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `Cargo.toml` and reminds you to run these commands before a commit lands. CI runs the identical gates — see this pack's `ci-gates.yml`.
`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `Cargo.toml` and reminds you to run these commands before a commit lands. CI runs the same gates plus a dependency-audit step (`cargo audit`) that has no local pre-commit equivalent — see this pack's `ci-gates.yml`.

## Related Skills

Expand Down
1 change: 1 addition & 0 deletions .claude/templates/stack-packs/typescript/ci-gates.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ gates:
node-version: lts/*
cache: pnpm
- run: pnpm install --frozen-lockfile
- run: pnpm audit --audit-level high # dependency scan — .claude/rules/security.md Dependency Safety
- run: pnpm test # vitest run
- run: pnpm lint # biome check .
- run: pnpm typecheck # tsc --noEmit
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ Regenerate `pnpm-lock.yaml` with `pnpm install` — never hand-edit it. Commit i

## Gates Wiring

`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `package.json` and reminds you to run these commands before a commit lands. CI runs the identical four gates — see this pack's `ci-gates.yml`.
`.claude/hooks/pre-commit-verification.sh` auto-detects this stack from `package.json` and reminds you to run these commands before a commit lands. CI runs the same four gates plus a dependency-audit step (`pnpm audit --audit-level high`) that has no local pre-commit equivalent — see this pack's `ci-gates.yml`.

## Related Skills

Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/framework-invariants.yml
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ jobs:
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0 (SHA-pins its own setup-trivy dependency; older releases referenced since-deleted setup-trivy tags)
with:
scan-type: fs
scanners: secret
# No manifests exist in this repo today, so vuln findings are trivially green here — the scanner is real for forks/adopters that add them.
scanners: secret,vuln
exit-code: 1

diff-size:
Expand Down
2 changes: 2 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- `pre-commit-verification.sh` rewritten from advisory-only to enforcing (jq present): on `git commit`, runs every gate `gate-lib.sh` detects, each under `timeout "${CLAUDE_GATE_TIMEOUT_SECS:-120}"` from the project dir, logging to `.claude/hooks/.state/gate-<label>.log`. All green writes a hook-authored evidence stamp (`.claude/hooks/.state/commit-verified`, `{epoch, tree-hash}`) trusted on a later commit only when BOTH ≤5 minutes old AND its tree-hash matches the current `git write-tree` output — content-bound, not time-only (review F8), so an edit staged seconds ago forces a re-run despite an otherwise-fresh stamp. A red gate denies the commit, naming the gate, its log, and the existing anti-test-deletion sentence; a gate that exceeds its budget asks instead of silently killing or hanging, and writes no stamp. No gates detected → falls back to the original advisory text, unchanged. `CLAUDE_SKIP_GATE_HOOK=1` escape hatch allows unconditionally with the skip always disclosed in context; the jq-absent path is unchanged (silent fail-open). `settings.json`'s registration for this hook is raised from 5s to 300s to fit real gate runs (per-gate defaults sum safely under it). New `scripts/hook-tests.d/30-gates-lane.sh` covers the red/green/timeout/escape-hatch/cache-invalidation matrix against three fixtures — `scripts/fixtures/failing-project/` and `.../slow-gate/` each gain an (empty) `package-lock.json` so `gate-lib.sh` picks npm over pnpm (GitHub-hosted ubuntu-latest ships the former, not the latter, keeping the fixtures CI-executable); new sibling fixture `scripts/fixtures/passing-project/` covers the green/stamp path. `docs/hooks.md` gains a "Quality Gates" subsection documenting the stamp, `CLAUDE_GATE_TIMEOUT_SECS`, and the escape hatch (unit U5b)
- `.claude/hooks/gate-lib.sh` gains `gate_lib_timeout_bin`: the portable timeout-binary resolution (`timeout`/`gtimeout`/unbounded) `pre-commit-verification.sh` (U5b) used inline, now shared verbatim with the new `task-quality-gate.sh` — DRY, the same justified pattern `gate_lib_detect` itself set in U5a. `pre-commit-verification.sh` calls the new helper instead of resolving the binary inline; behavior is unchanged (verified: the full `30-gates-lane.sh` matrix passes unmodified against the refactored hook)
- New `.claude/hooks/task-quality-gate.sh`, registered by **default** under `hooks.TaskCompleted` in `.claude/settings.json` (timeout 120s) — the framework's only true completion-time quality gate no longer ships disabled (unit U5c; decision record: `artifacts/adr_default_quality_gate.md`, Decision D1). Runs the same `gate-lib.sh`-detected gates `pre-commit-verification.sh` runs at commit time, but at task-completion time — a second, independent checkpoint. A red gate blocks via exit code 2 (the platform's documented `TaskCompleted` mechanism), naming the gate, its log (`.claude/hooks/.state/taskgate-<label>.log`, a separate namespace from the commit gate's), and the same anti-test-deletion reminder. A gate exceeding its `${CLAUDE_GATE_TIMEOUT_SECS:-90}`-second budget is treated as non-blocking (allows, with an honest stderr note) rather than the commit gate's `ask`, since a task completion should not hard-fail on slowness alone. `CLAUDE_SKIP_GATE_HOOK=1` — the same variable the commit gate honors — disables it, disclosed on stderr, never silent. No detectable stack or `jq` absent → silent allow. New `scripts/hook-tests.d/60-taskgate.sh` covers the red/green/no-stack/escape-hatch/jq-absent matrix against the existing `failing-project`/`passing-project` fixtures; `scripts/test-hooks.sh`'s `run_case` gains `exit2-stderr-contains:`/`exit0-stderr-contains:` expectation forms for TaskCompleted's exit-code-plus-stderr contract (documented in the runner's own header). `docs/hooks.md` gains a "Quality Gates (task-quality-gate.sh)" subsection beside the commit gate's, a Built-in Hooks table row, and its opt-in-recipes preamble is rewritten so "ships disabled by default" accurately scopes to the recipes that remain opt-in (the forced-eval skill-activation hook, `docs/examples/worker-budget-hook.sh`) instead of contradicting the newly-shipped default; `artifacts/adr_default_quality_gate.md` records the context, the decision, the rejected keep-opt-in-but-prominent alternative, the reversal path, and consequences (MIGRATION.md entry, below)
- Real dependency scanning (O7/unit U20): `framework-invariants.yml`'s Trivy job now scans `fs --scanners secret,vuln` instead of `secret` alone, same blocking exit-code style — trivially green today since this repo carries no dependency manifests, but real for any fork/adopter that adds one. Every stack-pack `ci-gates.yml` (TypeScript/JavaScript, Python, Go, Rust) gains one native audit step — `pnpm audit --audit-level high` / `uvx pip-audit` / `govulncheck ./...` (via `go install golang.org/x/vuln/cmd/govulncheck@latest`) / `cargo install cargo-audit --locked` + `cargo audit` — each citing `.claude/rules/security.md`'s Dependency Safety section rather than restating it. Each pack's `golden-path.skill.md` "Gates Wiring" sentence is corrected from "CI runs the identical gates" to name the new CI-only audit step, since it has no local pre-commit equivalent. Closes the gap `research_ai_coding_frustrations.md`'s audit flagged: `security.md`'s checklist claimed "automated dependency scanning" that existed nowhere in repo CI or stack packs
- Security checklist truth-in-labeling (O7/unit U20): every `.claude/rules/security.md` Security Checklist line now names its real Enforcement Ladder rung instead of mixing enforced and aspirational claims in one visual register. The secrets line's citation is updated to name `pre-tool-use-validator.sh`'s Bash redirect/heredoc coverage and Trivy's `secret,vuln` scanners (both landed in the prior entry); the dependency line's parenthetical is now genuinely true, citing that same Trivy vuln scan plus the four stack-pack audit gates; the five adopter-only lines (input validation, SQL parameterization, auth/authz, encryption, error messages) are marked "rung 1 — adopter-level: enforce in your application/CI; this framework cannot check it" instead of implying framework-level enforcement that never existed. The Enforcement Ladder preamble is reworded to name the per-line rung tags; file grows 0 lines (annotations extend existing lines, not new ones) — rules-lines total unchanged
- Verification-first implementation loop (U17/O10): `testing/SKILL.md`'s Verification Loop First section gains red-green-observe discipline — a bug fix's regression test must be run and its failure observed (not assumed) before the fix, a feature states a falsifiable "done when" before implementation, and a completion claim cites evidence (test output, pushed SHA) rather than narrating it; extends the skill's existing regression-test-per-bug content instead of duplicating it. `builder/SKILL.md` gains a 2-line cross-reference from its Implementation Workflow into this loop, keeping `testing` the single policy home. `docs/hooks.md`'s opt-in recipes gain a short paragraph on mechanical TDD enforcement — teams wanting a hard `PreToolUse` block can adopt an external TDD-Guard-style hook (`nizos/tdd-guard` cited as the worked example, not vendored); it composes with the shipped commit/task quality gates rather than replacing them
- Implementation-time hallucination defense (U18/O15): `builder/SKILL.md` gains a Hallucination Defense section, concretizing CLAUDE.md Core Principle 1 with two named workflow steps — (a) before calling an API not already used elsewhere in this repo (checked via Grep first), verify it against Context7 or official docs; (b) before adding a dependency not already in the manifest, confirm the package exists in its official registry (`npm view <pkg>`, `pip index versions <pkg>`/PyPI, crates.io, pkg.go.dev) before installing, since hallucinated package names are deterministic enough across models to be pre-registered by attackers (slopsquatting) — registry existence is not a vulnerability scan, which is tracked separately as the unselected O7. `core-engineering/dependency-upgrade/SKILL.md` gains a one-line cross-reference beside its "a version string is a claim" rule pointing at builder's new-dependency existence check rather than restating it
- Scope-adherence review lens (U19/O17): `swarm-review/SKILL.md`'s Parallel Review Perspectives gain a Scope adherence review — does this diff exceed its stated task? Flags unrequested refactors, drive-by edits outside the task/plan's acceptance criteria, and dead code left behind; compares the diff against the task/plan's AC and the PR template's stated scope and Risk Tier field; cites the `diff-size` CI job's >400-LOC advisory (`framework-invariants.yml`) as the size signal. Adversarial Questions' Challenge Assumptions gains one matching question ("What in this diff did nobody ask for?"). `code-check/SKILL.md`'s Audit Dimensions gains a matching Scope Adherence entry cross-referencing swarm-review's lens rather than restating it
Expand Down
8 changes: 8 additions & 0 deletions MIGRATION.md
Original file line number Diff line number Diff line change
Expand Up @@ -324,4 +324,12 @@ This is a deliberate doctrine change, not an oversight — see `artifacts/adr_de
- To skip gate enforcement for one task completion, set `CLAUDE_SKIP_GATE_HOOK=1` — the same escape hatch the commit gate honors (one variable disables both).
- If you don't want this hook running at all, remove the `TaskCompleted` entry from `.claude/settings.json`'s `hooks` block — see `docs/hooks.md`'s "How to disable a hook."

### Dependency-audit step added to CI (repo Trivy scan + stack-pack `ci-gates.yml`)

**Who is affected:** anyone whose repo's CI workflow was built by pasting a stack-pack `ci-gates.yml` snippet (TypeScript/JavaScript, Python, Go, or Rust); at the framework-repo level, anyone who forks this repo and later adds a dependency manifest.

**What breaks:** nothing — purely additive. This repo's own `framework-invariants.yml` Trivy job now scans `secret,vuln` instead of `secret` only (trivially green today: this repo carries no dependency manifests, real for any fork that adds one). Each stack pack's `ci-gates.yml` gains one blocking audit step using that stack's native tool (`pnpm audit --audit-level high`, `uvx pip-audit`, `govulncheck ./...`, `cargo audit`) — see `.claude/rules/security.md`'s Dependency Safety section. Each pack's `golden-path.skill.md` "Gates Wiring" sentence is corrected to name this CI-only step, since it has no local pre-commit equivalent.

**Action required:** if you previously pasted a pack's `ci-gates.yml` block into your own workflow, re-paste it (or add the one new audit step by hand) to pick up the gate — these are exemplars, not live includes, so nothing updates automatically in an already-copied file.

<!-- Future migration notes appended here. -->
Loading