shoc-backend/REVIEW_AND_PR_FRAMEWORK.md
Adam Moussa b7b22a8893
chore(repo): add PR template and README, retire stale root files
The org PR template pre-filled Summary / Validation / Tests / Notes here while
REVIEW_AND_PR_FRAMEWORK.md section 8 prescribes Summary / Changes and value /
Ticket. A repo template now overrides the org one, and the framework notes the
divergence from the org pr-policy workflow, which is not wired in.

README.md orients a reader: environments, architecture in one line, project
map, local commands, the governance gate, deployment, and a documentation map.

Cleanup: TODO.md is removed because Jira owns work status and its items are
stale or done. BACKEND_ARCHITECTURE.md is removed as superseded; the two
references now point at git history. .env.example loses its BOM and mojibake
dashes. .gitattributes keeps its one active rule.
2026-09-18 19:05:30 -04:00

144 lines
6.9 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# Review and PR Framework (canonical)
> **Status: canonical.** This document owns *who* reviews, in what order, with
> what evidence, and how exceptions are recorded. The rules under review live in
> `ARCHITECTURE_AND_CODE_QUALITY.md`; the gates live in `QUALITY_GATES.md`.
## 1. Exact-head review
Reviews are performed against the **exact HEAD** the PR will merge, not a stale
snapshot:
- Fetch and review the precise merge commit / head SHA. If new commits land
after review, the review covers only the previously seen diff until re-run.
- Comments cite `file:line` against current HEAD so they are navigable and
reproducible.
- A "looks good from what I remember" approval is invalid; re-diff before
approving.
Review order is **business-rule-first, high-signal, low-false-positive**:
1. Correctness of the changed business behavior vs. the acceptance criteria.
2. Regression risk against board-backed protected behavior (§2).
3. Security / data / authorization (§3).
4. Architecture / dependency direction (the `ArchitectureTests` gate already
covers mechanical direction; review covers *semantic* layering).
5. Performance / complexity evidence (§4).
6. Tests: do they assert behavior through public contracts?
7. Nitpicks / style last, and only if not already caught by `dotnet format`.
## 2. Board-backed regression inventory
A task is incomplete if it implements the current change while regressing
behavior that was already working. Before claiming review/merge readiness:
- Pull the **Seahaven Jira SH board inventory** — all
visible tickets, not only the current one: key, title, type, status,
component, acceptance criteria, linked PR/release, and QA evidence.
- Check the change against that inventory. A plausible regression against
protected (Done / released / QA-approved) behavior is a **Blocker** until
disproven with repo evidence and targeted validation.
- **Missing board access, incomplete inventory, or missing PR-to-ticket
traceability is Blocked / NOT READY** — never a pass. Say so explicitly.
If Jira cannot be reached, report the gate as **not-run / blocked**, not green.
The current workflow has no `Ready for QA` transition; merged-but-unverified
work remains in the documented pre-QA status and must not be mislabeled Done.
## 3. Security, data, and authorization evidence
For changes touching auth, data, crypto, external input, or configuration,
review requires evidence (not assertion) for:
- **No exception disclosure** — changed endpoints do not leak exception
messages, stack traces, or SQL/provider/path/credential/crypto detail to the
client. `SanitizedErrorsTests` covers the shared boundary; changed handlers
must route through it.
- **Secret handling** — no secret-bearing field is logged or serialized into a
response. Structured log templates must not interpolate secrets.
- **Tenant scope** — scope is server-derived and authorization is enforced at
service entry (§2 of the architecture doc).
- **Authorization** — the service entry trust boundary is intact; controllers
express HTTP policy and delegate.
Cite the test, log redaction, or code path for each. "We don't think it leaks"
without evidence is a fail.
## 4. Performance and Big-O evidence
For each changed hot path, the PR provides:
- **Complexity** — CPU and memory Big-O for any in-memory step (e.g., dictionary
reconstruction is `O(n)`; repeated `First`/`Single` scans are `O(n²)`).
- **SQL-backed evidence** — claims that filtering/ordering/paging execute in
SQL, or that there is a single round trip, are backed by provider query logs,
`ToQueryString()`, store SQL, or a measured count/plan — **not** inferred from
LINQ shape.
- **Round trips / loops** — no query-in-loop / save-in-loop where a set-based
operation preserves semantics; document when a loop is intentional and why.
- **Partial-failure / transaction behavior** — preserved or explicitly changed
by business decision (see architecture §4/§8).
## 5. Tests
- Tests assert **behavior through public interfaces**, not linter/analyzer
self-proofs.
- Cover: the happy path, authorization, data contracts, ordering, duplicates,
missing records, and relevant failure boundaries.
- New I/O paths include cancellation-forwarding evidence (architecture §6).
- A test that only proves "the rule exists" is not a behavior test; rewrite it
to exercise the product behavior the rule protects.
## 6. Size and "no godfile theater"
- Do not request splits based on line/file counts. A number is not feedback.
- If a unit is too large, name the **concrete second responsibility** or the
**untestable coupling** and propose the seam. Otherwise size is not a blocker.
- Do not introduce file/line thresholds into gates (architecture §9).
## 7. Exceptions (ADR)
A deviation from a hard rule requires an **Architecture Decision Record** under
`docs/adr/NNNN-title.md` (create the path if absent), referenced from the PR:
- context, decision, consequences;
- the specific rule being excepted;
- expiry/review date.
Suppressions are single-diagnostic and cite the ADR — **no wildcard
suppressions** (no global `[SuppressMessage]`, no `.editorconfig` severity
sweeps, no `#pragma` swaths). See architecture §10.
Infra and application **PRs** stay separate. GitHub Actions owns Elastic
Beanstalk application versions. HCP Terraform owns infrastructure and ignores
`version_label`. A change set that includes both `terraform/` and deployable
application files (`.cs`, `.csproj`, `.razor`, `.ebextensions/`, or the
Elastic Beanstalk package/smoke scripts) fails the isolation check. Workflow,
docs, and gate-script changes may travel with either side.
## 8. PR description contract (minimal)
- **Summary** — what changed and why, in plain language.
- **Changes and value** — grouped by area, each with the value it delivers.
- **Ticket** — the board key(s) when one applies. A missing ticket link is not
itself a blocker; missing board regression access or contradictory acceptance
criteria is.
- Link G6 migration evidence if the PR adds/changes a migration.
- Link any ADR relied upon.
Avoid boilerplate: no deployment notes, no validation transcripts, no
"residual-risk" theatre, no AI signatures. The validation story lives in the
check run results and the close-out, not in the PR body.
`.github/PULL_REQUEST_TEMPLATE.md` pre-fills this layout and overrides the org
template, whose Summary / Validation / Tests / Notes headings this repository
does not use. The org `callable-pr-policy` workflow hard-codes those four
headings; it is not wired into this repository, and this layout is the reason.
## 9. Merge readiness
Merge requires: exact-head review done; board-backed regression check pass (or
documented blocked); security/perf evidence present where applicable; CI green
(G1–G5); migration evidence (G6) if touched; no open hard-rule exceptions
without an ADR. Report each as pass / fail / skipped / not-run — never infer a
pass.