Skip to content

Commit 1f517dc

Browse files
committed
feat: add Claude Code config with hooks, skills, and rules
Signed-off-by: Joana Maia <jmaia@contractor.linuxfoundation.org>
1 parent e088a2e commit 1f517dc

18 files changed

Lines changed: 1460 additions & 0 deletions
Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
---
2+
name: code-standards-enforcer
3+
description: "Audits recently written or modified code against CLAUDE.md rules, patterns-in-transition, and checklist files. Covers CDP-specific patterns: pg-promise over Sequelize, functional services over classes, single-tenant via DEFAULT_TENANT_ID, Auth0 auth, Zod + validateOrThrow for public endpoints, query performance, and Temporal workflow rules. Invoked in background by review-pr."
4+
model: inherit
5+
color: red
6+
memory: none
7+
---
8+
9+
# Code Standards Enforcer
10+
11+
You are an elite code standards enforcement specialist. Your singular mission is to audit recently written or modified code against the project's CLAUDE.md guidelines, rule files, and checklist files, catching violations before they enter the codebase.
12+
13+
## Your Primary Directive
14+
15+
Read and internalize every rule, convention, pattern, and guideline described in CLAUDE.md. These are law. When CLAUDE.md references other documents (rule files in `.claude/rules/`, checklist files under `.claude/skills/review-pr/references/`), read and enforce those too.
16+
17+
## Enforcement Process
18+
19+
### Step 1: Load All Reference Documents
20+
21+
- Read the project's `CLAUDE.md` thoroughly
22+
- Read the user's global CLAUDE.md at `~/.claude/CLAUDE.md` if it exists
23+
- Glob `.claude/rules/*.md` and read every rule file
24+
- Read all checklists under `.claude/skills/review-pr/references/`
25+
- Build a mental checklist of every enforceable rule
26+
27+
### Step 2: Identify Recently Changed Code
28+
29+
- Use `git status` or `git diff` to identify changed files
30+
- Categorize changes: backend (`backend/`), frontend (`frontend/`), services (`services/apps/*`, `services/libs/*`), migrations, SQL
31+
32+
### Step 3: Systematic Audit
33+
34+
For each changed file, check against ALL applicable rules. The patterns-in-transition from CLAUDE.md are the highest priority:
35+
36+
#### Patterns in Transition (enforce on ALL new code)
37+
38+
- [ ] **No new Sequelize usage** — all new DB code uses `queryExecutor` from `@crowd/data-access-layer`. Legacy Sequelize in `backend/src/database/repositories/` and `backend/src/services/` is exempt.
39+
- [ ] **No new class-based services or repositories** — plain functions only
40+
- [ ] **No new multi-tenant logic** — use `DEFAULT_TENANT_ID` from `@crowd/common`
41+
- [ ] **New public endpoints use Zod + `validateOrThrow`** from `@crowd/common`
42+
- [ ] **Auth0 patterns** — no new legacy JWT patterns
43+
- [ ] **No `any` types** in new code
44+
45+
#### Backend Rules
46+
47+
- [ ] New DAL functions checked against existing equivalents (blast-radius risk)
48+
- [ ] Parameterized queries only — no string interpolation with user input
49+
- [ ] `$N` placeholder count matches bind values array length
50+
- [ ] No secrets hardcoded — env vars only
51+
- [ ] Query performance: indexes considered for WHERE clauses on large tables
52+
53+
#### Services Rules (Temporal/Kafka/Redis workers)
54+
55+
- [ ] Temporal workflows are deterministic — no I/O, no `Math.random()`, no `Date.now()` inside workflow code
56+
- [ ] Kafka/Redis calls are in Activities only, not Workflows
57+
- [ ] Activities are idempotent where possible
58+
- [ ] Logger from `@crowd/logging` — no `console.log`
59+
60+
#### Frontend Rules
61+
62+
- [ ] `<script setup>` Composition API — no Options API
63+
- [ ] TanStack Vue Query for server state — no raw `axios` in `onMounted`
64+
- [ ] Pinia for shared client state
65+
- [ ] `ref()` / `computed()` for reactive state
66+
67+
#### Migration Rules
68+
69+
- [ ] Migrations are append-only — never modify an applied migration
70+
- [ ] Filename format: `V{epoch}__{description}.sql`
71+
- [ ] Production-safe: no dangerous `DROP TABLE`, no adding NOT NULL without default/backfill
72+
73+
#### Protected Files Check
74+
75+
Flag if any of these protected infrastructure files were modified — they require code owner approval:
76+
77+
- `services/libs/data-access-layer/**`
78+
- `services/libs/common/**`
79+
- `backend/src/database/migrations/**`
80+
- `scripts/cli`, `scripts/scaffold.yaml`
81+
- `.husky/*`, `commitlint.config.js`
82+
- `.github/workflows/**`, `.github/actions/**`
83+
- `tsconfig*.json`, `.eslintrc*`, `.prettierrc*`
84+
- `pnpm-lock.yaml`, `package.json`, `*/package.json`
85+
- `CLAUDE.md`, `.claude/settings.json`
86+
87+
### Step 4: Report Findings
88+
89+
For each violation found, report:
90+
91+
1. **File and line number** (or approximate location)
92+
2. **Rule violated** — cite the specific CLAUDE.md section, rule file, or checklist
93+
3. **What's wrong** — explain the violation clearly
94+
4. **How to fix** — provide the corrected code snippet
95+
5. **Severity** — CRITICAL / SHOULD FIX / NIT
96+
97+
### Step 5: Summary
98+
99+
After auditing all files, provide:
100+
101+
- Total violations found grouped by severity
102+
- A PASS / FAIL verdict
103+
- Top 3 most important fixes to prioritize
104+
- Confirmation of which rules and documents were checked
105+
106+
## Behavior Rules
107+
108+
1. **Be thorough** — check every applicable rule
109+
2. **Be specific** — always cite the exact rule source
110+
3. **Be actionable** — always provide corrected code, not just descriptions
111+
4. **Be fair** — acknowledge when code correctly follows guidelines
112+
5. **Do not flag legacy code in already-legacy files** — only flag new violations in new or modified files
113+
6. **If you cannot quote the rule from a loaded document, drop the finding** — hallucinated rules are worse than missed ones
114+
115+
## Output Format
116+
117+
```text
118+
## Code Standards Audit Report
119+
120+
### Documents Referenced
121+
- [List all CLAUDE.md files, rule files, and checklists consulted]
122+
123+
### Files Audited
124+
- [List of files checked]
125+
126+
### Protected Files
127+
- [List any protected files that were modified, or "None modified"]
128+
129+
### Violations Found
130+
131+
#### CRITICAL
132+
[Violations that break core patterns or introduce security/data issues]
133+
134+
#### SHOULD FIX
135+
[Deviations from documented conventions]
136+
137+
#### NIT
138+
[Minor style issues, protected-file awareness]
139+
140+
### Correctly Followed
141+
[Notable rules that were correctly followed]
142+
143+
### Verdict: PASS / FAIL
144+
[Summary and priority fixes]
145+
```
Lines changed: 111 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,111 @@
1+
#!/usr/bin/env bash
2+
# Copyright The Linux Foundation and each contributor to CDP.
3+
# SPDX-License-Identifier: MIT
4+
#
5+
# Guard hook: warns when editing protected infrastructure files.
6+
# Used by Claude Code PreToolUse hook on Edit and Write operations.
7+
# Exit code 0 = allow (with warning message printed to stderr).
8+
9+
set -euo pipefail
10+
11+
# Read tool input from stdin (JSON with file_path field)
12+
INPUT=$(cat)
13+
14+
# Extract file_path from the JSON input
15+
FILE_PATH=$(echo "$INPUT" | grep -o '"file_path"[[:space:]]*:[[:space:]]*"[^"]*"' | head -1 | sed 's/.*"file_path"[[:space:]]*:[[:space:]]*"//;s/"$//' || true)
16+
17+
# If no file_path found, allow the operation
18+
if [ -z "$FILE_PATH" ]; then
19+
exit 0
20+
fi
21+
22+
# Normalize: strip leading ./ if present
23+
FILE_PATH="${FILE_PATH#./}"
24+
25+
# Also handle absolute paths by stripping the repo root
26+
REPO_ROOT=$(git rev-parse --show-toplevel 2>/dev/null || echo "")
27+
if [ -n "$REPO_ROOT" ] && [[ "$FILE_PATH" == "$REPO_ROOT"/* ]]; then
28+
FILE_PATH="${FILE_PATH#$REPO_ROOT/}"
29+
fi
30+
31+
# Helper: warn about a protected file (allows the edit to proceed)
32+
warn() {
33+
local reason="$1"
34+
echo "" >&2
35+
echo "⚠ WARNING: This file is part of the project's core infrastructure." >&2
36+
echo "File: $FILE_PATH" >&2
37+
echo "Reason: $reason" >&2
38+
echo "Ensure this change is intentional and reviewed by a code owner." >&2
39+
echo "" >&2
40+
exit 0
41+
}
42+
43+
# ── Data Access Layer ──────────────────────────────────────────────
44+
if [[ "$FILE_PATH" == services/libs/data-access-layer/* ]]; then
45+
warn "Shared DAL — high blast radius. Check for existing functions before adding new ones (CLAUDE.md: 'duplicates are already a problem')."
46+
fi
47+
48+
# ── Common / Shared Utilities ──────────────────────────────────────
49+
if [[ "$FILE_PATH" == services/libs/common/* ]]; then
50+
warn "Shared utility library — changes affect all services and the backend."
51+
fi
52+
53+
# ── Database Migrations ────────────────────────────────────────────
54+
if [[ "$FILE_PATH" == backend/src/database/migrations/* ]]; then
55+
warn "Flyway migration — append-only. Never modify an existing migration that has been applied."
56+
fi
57+
58+
# ── Dev CLI & Scaffold ─────────────────────────────────────────────
59+
case "$FILE_PATH" in
60+
scripts/cli)
61+
warn "Dev CLI entrypoint — changes affect all contributors' local setup." ;;
62+
scripts/scaffold.yaml|scripts/scaffold.insights.yaml)
63+
warn "Docker scaffold config — changes affect how local services are started." ;;
64+
esac
65+
66+
# ── Git Hooks & Commit Standards ──────────────────────────────────
67+
if [[ "$FILE_PATH" == .husky/* ]]; then
68+
warn "Git hooks — changes affect pre-commit validation for all contributors."
69+
fi
70+
71+
case "$FILE_PATH" in
72+
commitlint.config.js|commitlint.config.*)
73+
warn "Commitlint config — changes affect commit message validation for all contributors." ;;
74+
esac
75+
76+
# ── CI / GitHub Actions ────────────────────────────────────────────
77+
if [[ "$FILE_PATH" == .github/workflows/* ]] || [[ "$FILE_PATH" == .github/actions/* ]]; then
78+
warn "CI/CD pipeline — changes affect automated checks run on every PR."
79+
fi
80+
81+
# ── Lint / Format / TypeScript Config ─────────────────────────────
82+
case "$FILE_PATH" in
83+
tsconfig*.json|*/tsconfig*.json)
84+
warn "TypeScript configuration — changes affect compilation across the monorepo." ;;
85+
.eslintrc*|*/eslintrc*|eslint.config*|*/eslint.config*)
86+
warn "ESLint configuration — changes affect code quality rules for the project." ;;
87+
.prettierrc*|*/.prettierrc*)
88+
warn "Prettier configuration — changes affect code formatting standards." ;;
89+
esac
90+
91+
# ── Package Files ──────────────────────────────────────────────────
92+
if [[ "$FILE_PATH" == pnpm-lock.yaml ]]; then
93+
warn "Lock file — changes affect resolved dependency versions for all contributors."
94+
fi
95+
if [[ "$FILE_PATH" == package.json ]] || [[ "$FILE_PATH" == */package.json ]]; then
96+
warn "Package manifest — changes affect dependencies and scripts for this workspace."
97+
fi
98+
99+
# ── Claude Config ─────────────────────────────────────────────────
100+
case "$FILE_PATH" in
101+
CLAUDE.md)
102+
warn "Project instructions — changes affect AI assistant behavior for all users." ;;
103+
.claude/settings.json)
104+
warn "Claude Code settings — changes affect hooks, permissions, and plugins for all users." ;;
105+
esac
106+
if [[ "$FILE_PATH" == .claude/hooks/* ]]; then
107+
warn "Claude Code hook — changes affect automated pre-tool validations."
108+
fi
109+
110+
# If none of the protected patterns matched, allow the operation
111+
exit 0

.claude/rules/adr-format.md

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
---
2+
description: Enforce Nygard ADR template structure on files written under docs/adr/
3+
paths:
4+
- 'docs/adr/**/*.md'
5+
---
6+
7+
# ADR Format Enforcement
8+
9+
When writing or editing any `.md` file under `docs/adr/`, enforce these rules:
10+
11+
## Exempt files
12+
13+
`README.md` and `template.md` are index/template files — they are **not** ADRs
14+
and are exempt from the section requirements below.
15+
16+
## Mandatory sections for ADR files
17+
18+
Every file matching `docs/adr/[0-9]*.md` **must** contain all of the following,
19+
in this order:
20+
21+
1. `# ADR-NNNN: [Title]` — H1 heading with 4-digit sequential ID
22+
2. `**Date**:` — ISO date (YYYY-MM-DD)
23+
3. `**Status**:` — one of: `proposed`, `accepted`, `deprecated`, `superseded by ADR-NNNN`
24+
4. `**Deciders**:` — who was involved in the decision
25+
5. `## Context` — 2–5 sentences on the situation and forces
26+
6. `## Decision` — 1–3 sentences stating the change
27+
7. `## Alternatives Considered` — at least one alternative with Pros, Cons, Why not
28+
8. `## Consequences` — with sub-sections `### Positive`, `### Negative`, `### Risks`
29+
30+
If any mandatory section is missing, **stop and ask the user** to provide the
31+
missing information before writing the file. Do not write a partial ADR.
32+
33+
## Numbering
34+
35+
- IDs are zero-padded to 4 digits: `0001`, `0002`, `0003`, …
36+
- Assign the next sequential number by scanning existing files with `Glob docs/adr/[0-9]*.md`.
37+
- Never reuse a number, even if a previous ADR is deprecated.
38+
39+
## File naming
40+
41+
`docs/adr/NNNN-kebab-case-title.md` — all lowercase, words separated by hyphens.
42+
43+
## Index maintenance
44+
45+
After writing or changing the status of an ADR, update the index table in
46+
`docs/adr/README.md`:
47+
48+
```markdown
49+
| [ADR-NNNN](./NNNN-kebab-title.md) | Title | accepted | YYYY-MM-DD |
50+
```
51+
52+
Remove the `_none yet_` placeholder row once the first real ADR is added.

.claude/rules/commit-workflow.md

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
---
2+
description: Commit conventions, branch naming, PR format, PR size guidelines, sign-off + GPG signing, and JIRA tracking workflow
3+
paths:
4+
- '*'
5+
---
6+
7+
# Commit & PR Workflow
8+
9+
## Commit Conventions
10+
11+
- Follow the [Conventional Commits](https://www.conventionalcommits.org/) format: `type: description`
12+
- A scope is **optional** — most commits in this repo do not use one
13+
- Valid types: `feat`, `fix`, `docs`, `style`, `refactor`, `perf`, `test`, `build`, `ci`, `chore`, `revert`
14+
- Use present tense, imperative mood: "add feature" not "added feature"
15+
- Include the JIRA ticket **inline at the end** of the description, in parentheses
16+
- Examples:
17+
- `feat: add github discussions integration (CM-1164)`
18+
- `fix: improve member merge suggestions (CM-1137)`
19+
- `chore: update stale dependency versions`
20+
21+
## Commit Signing
22+
23+
All commits must be both DCO-signed and GPG-signed:
24+
25+
- **DCO sign-off (`--signoff`)** — required by LF governance; validated by the Probot DCO check in CI. The `Signed-off-by: Name <email>` trailer is appended automatically when you pass `--signoff` (or `-s`).
26+
- **GPG signature (`-S`)** — required by repo policy. Configure a signing key once:
27+
28+
```bash
29+
git config --global user.signingkey <KEY_ID>
30+
git config --global commit.gpgsign true
31+
```
32+
33+
Standard commit command:
34+
35+
```bash
36+
git commit --signoff -S -m "type: description (CM-XXX)"
37+
```
38+
39+
If signing fails, fix the underlying issue — do not push unsigned commits. To verify signature status on a branch's commits:
40+
41+
```bash
42+
git log --format='%G? %h %s' origin/main..HEAD
43+
```
44+
45+
Acceptable `%G?` codes: `G` (good signature) or `U` (good signature, key not in local trust db). Codes `N`, `B`, or `E` need investigation.
46+
47+
## Branch Naming
48+
49+
- Format: `type/CM-<number>-short-description` (e.g. `feat/CM-1164-github-discussions`)
50+
- The JIRA key in the branch name lets `/commit` include it automatically in the message
51+
52+
## PR Titles
53+
54+
- PR titles must contain a JIRA key — validated by CI (`.github/workflows/pr-title-jira-key-lint.yml`)
55+
- Format: `type: description (CM-XXX)` — Conventional Commits format with the JIRA key in parens at the end
56+
- Example: `feat: add github discussions source (CM-1164)`
57+
58+
## PR Size & Focus
59+
60+
- **Target under 1000 lines of diff** — one feature, one bug fix, or one refactor per PR
61+
- **Don't bundle unrelated changes** — keeps reviews focused and rollbacks clean
62+
63+
## JIRA Tracking
64+
65+
Before starting any work:
66+
67+
1. Check if there is a JIRA ticket in the `CM` project
68+
2. Create one if untracked work
69+
3. Include `CM-XXX` in commit messages and PR title

0 commit comments

Comments
 (0)