﻿# CONTRIBUTING — the workflow for every change

This is the procedure. `CODING-CONVENTIONS.md` says how code looks, `SECURITY.md` what it must
never do, `API-PARITY.md` what it must always also do. This file says in which order.

---

## 1. Before you start (once)

1. Read `RULEFOLDER/README.md` and follow its reading order.
2. Register your developer code in `RULEFOLDER/TEAM.md` (a `chore` change).
3. Install the hooks: `git config core.hooksPath .githooks`
4. Set up: `cp .env.example .env`, fill secrets, choose the database engine (`DB_ENGINE=sqlite`
   for a personal instance; `DB_ENGINE=postgres` plus `COMPOSE_PROFILES=postgres` and the
   `POSTGRES_*` values for a shared or large instance, see ADR-004), then
   `docker compose up --build -d`.
   For tests: `python -m venv .venv && .venv/Scripts/pip install -r requirements.txt -r requirements-dev.txt`.

---

## 2. One change, start to finish

### 2.1 Branch
`chg/<short-slug>` from `main` (e.g. `chg/reels-support`). One change per branch. Small changes:
a day of work at most. A bigger feature is several changes on the same branch, each with its own
fragment and commit.

### 2.2 Create the fragment **first**
```bash
python RULEFOLDER/tools/new_change.py "Reels support" --type feature --scope api web-ui
```
You get `RULEFOLDER/changes/CHG-YYYYMMDD-RG-01-reels-support.md`. Write `## What` and `## Why`
now, before code. If you cannot write them, you do not yet know what you are building.

### 2.3 Design before code
- Where does the logic go? A service function (ADR-002). Which facade calls does it need?
- Which pattern, if any, and why (write it in `## How`; name it in `patterns:` only if applied).
- Which API endpoint(s) and which GUI route(s)? Fill `gui_routes` / `api_endpoints`.
- Which security rules apply? Skim `SECURITY.md` §2 for the areas you touch.
- Which tests prove it? List them in `tests:` before writing them.

### 2.4 Code
Follow `CODING-CONVENTIONS.md`. Service → API adapter → GUI adapter → template. Keep the diff
focused on the change; unrelated clean-ups are their own change.

### 2.5 Tests
`pytest` green. New service function ⇒ unit test with a fake facade. New endpoint ⇒ test through
the Flask test client (auth guard, happy path, one validation error, explicit-account case for
mutations). New GUI mutation ⇒ CSRF test. A change that touches `models.py`, `migrations/` or a
query runs the suite on **both** engines (`DB_ENGINE=sqlite` locally, `DB_ENGINE=postgres`
against the compose `db` container) and records both results in `## Verification`.

### 2.6 Keep the records in sync (same commit)
- `FEATURE-REGISTRY.md`: add or update the feature row.
- `DOC/API.md`: endpoint section + quick-reference table row.
- `.env.example`: any new variable, with a comment.
- `ARCHITECTURE.md`: only if a module, flow or pattern was added or removed.
- Fragment: `files:`, `## API impact`, `## Security review` (the checklist, answered),
  `## Verification` (commands and results), `status: done`, `api_doc_updated: yes`.

### 2.7 Check and build
```bash
python RULEFOLDER/tools/build_changelog.py
python RULEFOLDER/tools/check_rules.py
docker compose build --no-cache && docker compose up -d
```

### 2.8 Commit
```
CHG-YYYYMMDD-RG-01: reels support
```
The first line must start with the fragment ID (hook-enforced). Body optional. The hooks refuse a
commit that stages code without a fragment, has an invalid fragment, or has a stale `CHANGELOG.md`.

### 2.9 Review (pull request or peer review)
The reviewer reads the **fragment first**, then the diff, and checks:
- the diff does what `## What` says and nothing else;
- `## Security review` is answered truthfully (spot-check two answers against the code);
- parity: registry row present, API and GUI semantics match (`API-PARITY.md` §1 table);
- tests exist and test the behaviour, not the mocks;
- conventions (layering, naming, envelope, no logic in routes).
Approval comment includes "parity: verified" and "security: reviewed".

### 2.10 Merge
Squash or merge, keep the `CHG-…` line as the first line of the merge commit. If `CHANGELOG.md`
conflicts, do not resolve by hand: take either side, run `build_changelog.py`, commit.

---

## 3. Definition of done

- [ ] Fragment complete, `status: done`, all sections filled
- [ ] Service function + tests; adapters thin
- [ ] GUI route ⇒ API endpoint (or reasoned exception) ⇒ `DOC/API.md` ⇒ registry row
- [ ] Security checklist answered; no new finding introduced; any closed finding marked in `SECURITY.md` §4
- [ ] `check_rules.py` passes; `pytest` passes; Docker builds and starts
- [ ] `.env.example` updated if config changed
- [ ] Commit message starts with the change ID

---

## 4. Types and scopes

| `type` | Use for |
|--------|---------|
| `feature` | New capability visible to a user or API client |
| `bugfix` | Wrong behaviour corrected (fragment has Problem/Fix) |
| `refactor` | Structure changed, behaviour identical (say how you proved it) |
| `security` | Closes a `SECURITY.md` finding or hardens something |
| `docs` | Documentation only |
| `infra` | Docker, dependencies, CI, hooks, tooling |
| `test` | Tests only |
| `chore` | Housekeeping (team table, renames) |

`scope` is a list from: `backend`, `api`, `web-ui`, `infra`, `docs`, `project-wide`.

---

## 5. Questions people ask

**Two of us created a fragment on the same day. Do the IDs clash?** No: the ID contains your
developer code. `CHG-20261013-RG-01` and `CHG-20261013-AH-01` are different files.

**I created two fragments today.** `-01`, `-02`. The tool counts your existing files for the day.

**I want to merge two changes into one.** Keep one fragment, delete the other file, mention the
deleted ID in `## What` so the history stays traceable.

**I fixed a typo in a template. Fragment?** Yes. `type: docs` or `chore`, three lines. The point is
that *nothing* changes without a record; small records are cheap.

**A colleague's fragment says `status: in-progress` on main.** Not allowed; the checker only
enforces the full field set for `done`, so in-progress fragments must not be merged. Reviewer's job.

**Can I edit `CHANGELOG.md` to fix wording?** No. Edit the fragment, rebuild.

**Where do I record a decision that is not a code change?** `decisions/ADR-NNN-<slug>.md`, and a
`docs` fragment that points to it.

---

## 6. Releases

- Semantic versioning, tag `vMAJOR.MINOR.PATCH`. `breaking: true` in any fragment since the last
  tag ⇒ MAJOR (or a `v2` API prefix, see `API-PARITY.md` §3).
- Release steps: `build_changelog.py`, `check_rules.py`, `pip-audit`, tag, deploy, record the
  deployment in `DEPLOY-HISTORY.md`.


