diff --git a/.github/workflows/architecture-quality.yml b/.github/workflows/architecture-quality.yml index 482f244..10f77bd 100644 --- a/.github/workflows/architecture-quality.yml +++ b/.github/workflows/architecture-quality.yml @@ -21,9 +21,8 @@ jobs: with: dotnet-version: "8.0.x" - # CI and local run the SAME governance check (scripts/governance-check.sh). - # See QUALITY_GATES.md. A green run here is equivalent to a local run. - - name: Governance check (restore + architecture tests + changed-file format) + # CI and local run the same complete repository gate. + - name: Repository quality gate shell: bash env: BASE_REF: ${{ github.event.pull_request.base.sha }} diff --git a/AGENTS.md b/AGENTS.md index a96d9bc..03e95fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,9 +1,8 @@ # AGENTS.md — SeaHaven backend (repo-specific delta) This file is the **repo-specific delta** for the Seahaven backend. It layers on -top of the operator/workspace agent baseline (the global `AGENTS.md` and the -agent-config-kit framework) and does not repeat it. Where this file and the -baseline conflict on repo details, **this file wins for this repository**. +top of the operator/workspace agent baseline and does not repeat it. This file +may add stricter backend rules but may never weaken the workspace baseline. ## Canonical governance documents (precedence) @@ -40,16 +39,15 @@ Controller -> I{Feature}Service -> I{Feature}DataService -> ApplicationDbContext Full detail: `ARCHITECTURE_AND_CODE_QUALITY.md`. -## Running the gates (local == CI) +## Running the complete gate (local == CI) ```bash -bash scripts/governance-check.sh # restore + ArchitectureTests + changed-file format -dotnet build SeaHavenIndustries.sln -c Release -dotnet test SeaHavenIndustries.sln -c Release --no-build +bash scripts/governance-check.sh ``` -CI (`architecture-quality` workflow) calls the same `scripts/governance-check.sh` -so a local green run means the same thing as CI. See `QUALITY_GATES.md`. +The command restores, verifies architecture and changed-file formatting, builds +Release, and runs the full test suite. CI (`architecture-quality` workflow) +calls the same script. See `QUALITY_GATES.md`. ## Hard rules (deviation needs an ADR; no wildcard suppressions) diff --git a/QUALITY_GATES.md b/QUALITY_GATES.md index f507c41..e7b5c84 100644 --- a/QUALITY_GATES.md +++ b/QUALITY_GATES.md @@ -18,8 +18,8 @@ | G1 | Restore | build integrity | `dotnet restore SeaHavenIndustries.sln` | `architecture-quality` → `governance-check.sh` | | G2 | Architecture boundary tests | §1, §3 (dependency direction) | `dotnet test Api.SeaHavenIndustries.Tests ... --filter FullyQualifiedName~ArchitectureTests --no-restore` | same script | | G3 | Changed-file formatting | §1 (conventions) | `dotnet format SeaHavenIndustries.sln --no-restore --verify-no-changes --include ` | same script | -| G4 | Release build | compile correctness | `dotnet build SeaHavenIndustries.sln -c Release --no-restore` | `ci` (reusable dotnet CI) | -| G5 | Full test suite | behavior | `dotnet test SeaHavenIndustries.sln -c Release --no-build` | `ci` (reusable dotnet CI) | +| G4 | Release build | compile correctness | `dotnet build SeaHavenIndustries.sln -c Release --no-restore` | `architecture-quality` and `ci` | +| G5 | Full test suite | behavior | `dotnet test SeaHavenIndustries.sln -c Release --no-build` | `architecture-quality` and `ci` | | G6 | Migration gates | §7 | see §"Migration gates" below | on-demand / release | | G7 | Cancellation forwarding | §6 | behavior tests on changed I/O paths + analyzer | review-enforced on changed paths | | G8 | Error disclosure | §5 | `SanitizedErrorsTests` (part of G5) | `ci` | @@ -28,7 +28,7 @@ ## How to run locally ```bash -# Full local governance gate (mirrors the architecture-quality workflow): +# Complete local repository gate (mirrors the architecture-quality workflow): bash scripts/governance-check.sh # By default it compares against the default branch for changed-file formatting. @@ -43,15 +43,8 @@ The script: 3. computes changed `.cs` files vs `BASE_REF` (default `origin/dev`) and runs `dotnet format --verify-no-changes --include ...` (G3). When there are no changed C# files it skips G3 with an explicit "skipped: no changed C#" line. - -It is **fast-path only**: restore + boundary tests + changed-file format. It is -not a substitute for G4/G5, which the full CI run performs. Run G4/G5 locally -with: - -```bash -dotnet build SeaHavenIndustries.sln -c Release -dotnet test SeaHavenIndustries.sln -c Release --no-build -``` +4. builds the complete solution in Release with no restore (G4). +5. runs the complete solution test suite in Release with no rebuild (G5). ## Migration gates (G6) @@ -104,8 +97,8 @@ non-empty. A future namespace move that makes reflection return zero types will Runtime/semantic properties (cancellation actually cancelling, a query executing in SQL, a transaction actually committing atomically) are proven by behavior tests or provider evidence, never by reflection. -- The per-PR fast path (G1–G3) does **not** assert the full suite is green; - that is G4/G5 in CI. Report them separately. +- A passing script proves G1–G5 ran in sequence. It does not prove the + provider-backed or review-owned gates G6–G9. ## Pass / fail / skip / not-run reporting diff --git a/REVIEW_AND_PR_FRAMEWORK.md b/REVIEW_AND_PR_FRAMEWORK.md index b00dc8e..04b70dc 100644 --- a/REVIEW_AND_PR_FRAMEWORK.md +++ b/REVIEW_AND_PR_FRAMEWORK.md @@ -32,7 +32,7 @@ Review order is **business-rule-first, high-signal, low-false-positive**: A task is incomplete if it implements the current change while regressing behavior that was already working. Before claiming review/merge readiness: -- Pull the **authoritative ticket board inventory** for this component — all +- 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 @@ -41,9 +41,9 @@ behavior that was already working. Before claiming review/merge readiness: - **Missing board access, incomplete inventory, or missing PR-to-ticket traceability is Blocked / NOT READY** — never a pass. Say so explicitly. -> The specific tracker for this component must be confirmed at review time -> (Jira, Linear, or the project's authoritative board). Do not assume; if the -> board cannot be reached, report the gate as **not-run / blocked**, not green. +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 @@ -113,7 +113,9 @@ sweeps, no `#pragma` swaths). See architecture §10. - **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), with traceability. +- **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. diff --git a/scripts/governance-check.sh b/scripts/governance-check.sh index 2ea10cb..4175287 100755 --- a/scripts/governance-check.sh +++ b/scripts/governance-check.sh @@ -2,13 +2,9 @@ # # governance-check.sh — local/CI parity governance gate for the Seahaven backend. # -# Runs the fast-path gates (G1 restore, G2 ArchitectureTests, G3 changed-file -# formatting) exactly as the `architecture-quality` workflow does. A green run -# here means the same thing locally and in CI. See QUALITY_GATES.md. -# -# Full build + test (G4/G5) are NOT run here; run them separately: -# dotnet build SeaHavenIndustries.sln -c Release -# dotnet test SeaHavenIndustries.sln -c Release --no-build +# Runs G1 restore, G2 ArchitectureTests, G3 changed-file formatting, G4 Release +# build, and G5 full tests exactly as the `architecture-quality` workflow does. +# A green run here means the same thing locally and in that CI workflow. # # Usage: # bash scripts/governance-check.sh @@ -19,15 +15,26 @@ set -euo pipefail SOLUTION="SeaHavenIndustries.sln" ARCH_TEST_PROJECT="Api.SeaHavenIndustries.Tests/Api.SeaHavenIndustries.Tests.csproj" +log() { printf '\n\033[1m== %s ==\033[0m\n' "$1"; } +ok() { printf '\033[32mPASS\033[0m %s\n' "$1"; } +bad() { printf '\033[31mFAIL\033[0m %s\n' "$1"; } + +if [[ -n "${DOTNET_BIN:-}" ]]; then + DOTNET="$DOTNET_BIN" +elif command -v dotnet >/dev/null 2>&1; then + DOTNET="$(command -v dotnet)" +elif [[ -x "$HOME/.dotnet/dotnet" ]]; then + DOTNET="$HOME/.dotnet/dotnet" +else + bad "dotnet is unavailable; set DOTNET_BIN or install the repository SDK." + exit 1 +fi + # Comparison point for changed-file formatting. Default to the dev integration # branch locally; CI overrides BASE_REF/HEAD_REF with the PR base/head SHAs. BASE_REF="${BASE_REF:-origin/dev}" HEAD_REF="${HEAD_REF:-HEAD}" -log() { printf '\n\033[1m== %s ==\033[0m\n' "$1"; } -ok() { printf '\033[32mPASS\033[0m %s\n' "$1"; } -bad() { printf '\033[31mFAIL\033[0m %s\n' "$1"; } - # Resolve the base ref before using it for a diff. if ! git rev-parse --verify --quiet "${BASE_REF}^{commit}" >/dev/null; then bad "G3: BASE_REF '${BASE_REF}' does not resolve to a commit (run: git fetch origin)." @@ -35,11 +42,11 @@ if ! git rev-parse --verify --quiet "${BASE_REF}^{commit}" >/dev/null; then fi log "G1: restore" -dotnet restore "$SOLUTION" +"$DOTNET" restore "$SOLUTION" ok "G1: restore" log "G2: architecture boundary tests (dependency direction)" -dotnet test "$ARCH_TEST_PROJECT" \ +"$DOTNET" test "$ARCH_TEST_PROJECT" \ --no-restore \ --filter "FullyQualifiedName~ArchitectureTests" \ --nologo @@ -57,11 +64,19 @@ if (( ${#changed_cs[@]} == 0 )); then printf '\033[33mSKIP\033[0m G3: no changed C# files between %s..%s\n' "${BASE_REF}" "${HEAD_REF}" else printf ' checking %d changed C# file(s)\n' "${#changed_cs[@]}" - dotnet format "$SOLUTION" \ + "$DOTNET" format "$SOLUTION" \ --no-restore \ --verify-no-changes \ --include "${changed_cs[@]}" ok "G3: changed-file formatting" fi -log "governance-check: all fast-path gates passed" +log "G4: Release build" +"$DOTNET" build "$SOLUTION" -c Release --no-restore --nologo +ok "G4: Release build" + +log "G5: full test suite" +"$DOTNET" test "$SOLUTION" -c Release --no-build --nologo +ok "G5: full test suite" + +log "governance-check: all required repository gates passed"