# Contributing to breakpilot-compliance

---

## 1. Getting Started

```bash
git clone ssh://git@gitea.meghsakha.com:22222/Benjamin_Boenisch/breakpilot-compliance.git
cd breakpilot-compliance
```

**Branch conventions** (branch from `main`):

| Prefix | Use for |
|--------|---------|
| `feature/` | New functionality |
| `fix/` | Bug fixes |
| `chore/` | Tooling, deps, CI, docs |

Example: `git checkout -b feature/ai-sdk-risk-scoring`

---

## 2. Dev Environment

Each service runs independently. Start only what you need.

**Go — ai-compliance-sdk**
```bash
cd ai-compliance-sdk
go run ./cmd/server
```

**Python — backend-compliance**
```bash
cd backend-compliance
pip install -r requirements.txt
uvicorn main:app --reload
```

**Python — dsms-gateway / document-crawler / compliance-tts-service**
```bash
cd <service>
pip install -r requirements.txt
uvicorn main:app --reload --port <port>
```

**Node.js — admin-compliance**
```bash
cd admin-compliance
npm install
npm run dev        # http://localhost:3007
```

**Node.js — developer-portal**
```bash
cd developer-portal
npm install
npm run dev        # http://localhost:3006
```

**All services together (local Docker)**
```bash
docker compose up -d
```

Config lives in `.env` (not committed). Copy `.env.example` and fill in `COMPLIANCE_DATABASE_URL`, `QDRANT_URL`, `QDRANT_API_KEY`, and Vault tokens.

---

## 3. Before Your First Commit

Run all of these locally. CI will run the same checks and fail if they don't pass.

**LOC budget (mandatory)**
```bash
bash scripts/check-loc.sh          # must exit 0
```

**Go lint**
```bash
cd ai-compliance-sdk
golangci-lint run --timeout 5m ./...
```

**Python lint**
```bash
cd backend-compliance
ruff check .
mypy compliance/                   # only if mypy.ini exists
```

**TypeScript type-check**
```bash
cd admin-compliance
npx tsc --noEmit
```

**Tests**
```bash
# Go
cd ai-compliance-sdk && go test ./...

# Python backend
cd backend-compliance && pytest

# DSMS gateway
cd dsms-gateway && pytest test_main.py
```

If any step fails, fix it before committing. The git pre-commit hook re-runs `check-loc.sh` automatically.

---

## 4. Commit Message Rules

Use [Conventional Commits](https://www.conventionalcommits.org/) style:

```
<type>(<scope>): <short summary>

[optional body]
[optional footer]
```

Types: `feat`, `fix`, `chore`, `refactor`, `test`, `docs`, `ci`.

### `[guardrail-change]` marker — REQUIRED

Add `[guardrail-change]` anywhere in the commit message body (or footer) when your changeset touches **any** of these files:

| File / path | Reason protected |
|-------------|-----------------|
| `.claude/settings.json` | PreToolUse/PostToolUse hooks |
| `scripts/check-loc.sh` | LOC enforcement script |
| `scripts/githooks/pre-commit` | Git hook |
| `.claude/rules/loc-exceptions.txt` | Exception registry |
| `AGENTS.*.md` (any) | Per-language architecture rules |

The `guardrail-integrity` CI job checks for this marker and **fails the build** if it is missing.

**Valid guardrail commit example:**
```
chore(guardrail): add exception for generated protobuf file

proto/generated/compliance.pb.go exceeds 500 LOC because it is
machine-generated and cannot be split. Added to loc-exceptions.txt
with rationale.

[guardrail-change]
```

---

## 5. Architecture Rules (Non-Negotiable)

### File budget
- **500 LOC hard cap** on every non-test, non-generated source file.
- The `PreToolUse` hook in `.claude/settings.json` blocks Claude Code from creating or editing files that would breach this limit.
- Exceptions require a written rationale in `.claude/rules/loc-exceptions.txt` plus `[guardrail-change]` in the commit.

### Clean architecture per service
- Python (FastAPI): `api → services → repositories → db.models`. Handlers ≤ 30 LOC. See `AGENTS.python.md`.
- Go (Gin): Standard Go Project Layout + hexagonal. `cmd/` is thin wiring. See `AGENTS.go.md`.
- TypeScript (Next.js 15): server-first, push client boundary deep, colocate `_components/` + `_hooks/` per route. See `AGENTS.typescript.md`.

### Database is frozen
- No new Alembic migrations, no `ALTER TABLE`, no `__tablename__` or column renames.
- The pre-commit hook blocks any change under `migrations/` or `alembic/versions/` unless the commit message contains `[migration-approved]`.

### Public endpoints are a contract
- Any change to a route path, HTTP method, status code, request schema, or response schema in `backend-compliance/`, `ai-compliance-sdk/`, `dsms-gateway/`, `document-crawler/`, or `compliance-tts-service/` **must** be accompanied by a matching update in every consumer (`admin-compliance/`, `developer-portal/`, `breakpilot-compliance-sdk/`, `consent-sdk/`) in the **same changeset**.
- OpenAPI baseline snapshots live in `tests/contracts/`. Contract tests fail on any drift.

---

## 6. Pull Requests

- **Target branch: `main`** — squash merge your feature branch into `main`.
- Keep PRs focused; one logical change per PR.

**PR checklist before requesting review:**

- [ ] `bash scripts/check-loc.sh` exits 0
- [ ] All lint checks pass (go, python, tsc)
- [ ] All tests pass locally
- [ ] No endpoint drift without consumer updates in the same PR
- [ ] `[guardrail-change]` present in commit message if guardrail files were touched
- [ ] Docs updated if new endpoints, config vars, or architecture changed

---

## 7. Claude Code Users

This section is for AI-assisted development sessions using Claude Code.

- **Always work on a feature branch** (`feat/*`, `feature/*`, `hotfix/*`), never directly on `main`.
- The `.claude/settings.json` `PreToolUse` hooks will automatically block Write/Edit operations on files that would exceed 500 lines. This is intentional — split the file instead.
- If the `guardrail-integrity` CI job fails, check that your commit message body includes `[guardrail-change]`. Add it and amend or create a fixup commit.
- **Never use `git add -A` or `git add .`** — always stage specific files by path to avoid accidentally committing `.env`, `node_modules/`, `.next/`, or compiled binaries.
- After every session: `bash scripts/check-loc.sh` must exit 0 before pushing.
- Read `CLAUDE.md` and the relevant `AGENTS.<lang>.md` before starting work on a service.
