From 2fa1bc9183fa67af3df0758d2a3c19810b970fbf Mon Sep 17 00:00:00 2001 From: Dzarlax Date: Sat, 6 Jun 2026 14:13:18 +0200 Subject: [PATCH 1/3] Add manual race detector CI policy --- .github/workflows/ci.yml | 26 ++- CONTRIBUTING.md | 14 ++ ...ace-detector-branch-protection-policy.html | 161 ++++++++++++++++++ 3 files changed, 197 insertions(+), 4 deletions(-) create mode 100644 docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 4a716e1..00e6fc9 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -15,6 +15,10 @@ on: description: "Build ARM64 image" type: boolean default: false + run_race: + description: "Run Go race detector tests" + type: boolean + default: false env: REGISTRY: ghcr.io @@ -45,13 +49,27 @@ jobs: # services into this job; the build job's purpose is catching # logic regressions in seconds, not standing up a stack. # - # CGO_ENABLED stays at 0 (matches the build above). `-race` - # would catch goroutine data-race regressions but requires - # CGO=1, so we skip it; the test set today is mostly - # math-kernel pure functions where -race adds little. + # CGO_ENABLED stays at 0 (matches the build above). Use the + # manual Race Detector job when reviewing concurrency-sensitive + # changes; it runs with CGO=1 because Go's -race requires CGO. - name: Test run: CGO_ENABLED=0 go test ./... + race: + name: Race Detector + runs-on: ubuntu-latest + if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_race }} + steps: + - uses: actions/checkout@v5 + + - uses: actions/setup-go@v6 + with: + go-version-file: go.mod + cache: true + + - name: Test with race detector + run: CGO_ENABLED=1 go test -race ./... + docker-amd64: name: Docker Build & Push (amd64) needs: build diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 4028c6e..2fcc9ab 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -25,6 +25,20 @@ Dependencies are managed through normal Go module resolution. Review dependency DB-backed integration tests skip when no Postgres connection is configured. To run them, provide libpq environment variables or `READINESS_TEST_DSN`. Tests create throwaway schemas and drop them during cleanup. +### CI and race detector policy + +The default required-looking CI job is `Build, Vet & Test`. Keep that job name stable unless repository branch protection is updated at the same time. + +Default PR and push CI uses `CGO_ENABLED=0` for build, vet, and tests, matching the production binary. Race detector tests are available as a manual GitHub Actions run: start the `CI` workflow with `run_race=true`. Use this before merging changes that touch tenant management, scheduler goroutines, async AI generation, recompute coordination, Telegram webhook dispatch, or notification loops. + +For local checks on a machine with a CGO toolchain: + +```bash +CGO_ENABLED=1 go test -race ./... +``` + +Branch protection is managed in GitHub repository settings, not in this tree. As of 2026-06-06, the GitHub API reports `main` as not protected. Enabling required checks is a separate admin decision; if enabled, require the `Build, Vet & Test` check first and only require `Race Detector` after deciding that every PR should pay the CGO/race runtime cost. + ## Pull Request Guidelines - Keep behavioral changes focused and explain the data contract they affect. diff --git a/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html b/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html new file mode 100644 index 0000000..fa449ad --- /dev/null +++ b/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html @@ -0,0 +1,161 @@ + + + + + Implementation Plan: Issue #152 CI Race Detector and Branch Protection Policy + + + + +
+

Implementation Plan: Issue #152 CI Race Detector and Branch Protection Policy

+

Approved and implemented

+ +
+

Task Summary

+

Record a clear policy for race-detector CI and branch protection, then implement only the parts that are justified now.

+
+ +
+

Current Behavior

+
    +
  • .github/workflows/ci.yml has one required-looking build job named Build, Vet & Test.
  • +
  • The job runs CGO_ENABLED=0 go build, go vet, and go test.
  • +
  • The workflow comment explicitly says -race is skipped because it requires CGO=1 and the current test set is mostly pure math-kernel code.
  • +
  • The repo contains concurrency-sensitive code and tests, for example internal/storage/recompute.go and internal/tenants/manager.go.
  • +
  • Branch protection state is a GitHub repository setting, not represented in the working tree.
  • +
+
+ +
+

Desired Behavior

+
    +
  • A documented policy says when go test -race is required, optional, or deferred.
  • +
  • If race CI is added, it is a separate job with clear CGO expectations and does not slow the default pure test loop unnecessarily.
  • +
  • Branch protection decision is explicit: either require the existing CI check, or document why it remains manual for now.
  • +
  • This issue stays separate from product guardrail tests and no-vendor migration.
  • +
+
+ +
+

Assumptions And Unknowns

+
    +
  • Assumption: the default fast CI job should remain pure and easy to understand.
  • +
  • Assumption: race detector is most valuable for PRs touching scheduler, tenant manager, async AI generation, recompute, webhook dispatch, or notification goroutines.
  • +
  • Unknown: whether GitHub branch protection is already configured outside the repository.
  • +
  • Unknown: whether the user wants enforcement now or just a recorded revisit policy.
  • +
+
+ +
+

Files Likely To Change

+
    +
  • .github/workflows/ci.yml - add an optional/manual or path-scoped race job only if approved.
  • +
  • CONTRIBUTING.md - document local go test -race ./... guidance and CI policy.
  • +
  • README.md or docs/ARCHITECTURE.md - only if branch protection policy belongs in operator docs.
  • +
  • GitHub repository settings - if branch protection is approved, apply through gh api after confirming exact required check names.
  • +
+
+ +
+

Implementation Steps

+
    +
  1. Inspect current branch protection via GitHub API before changing settings.
  2. +
  3. Choose one of three race-detector policies: defer with revisit criteria, manual workflow-only job, or PR job for all branches.
  4. +
  5. If implementing race CI, add a separate Race Detector job using CGO_ENABLED=1 go test -race ./....
  6. +
  7. Keep the existing Build, Vet & Test job name stable unless branch protection is updated at the same time.
  8. +
  9. Document local developer guidance and revisit criteria.
  10. +
  11. If branch protection is approved, update GitHub settings and verify required status checks match actual workflow job names.
  12. +
+
+ +
+

Impact

+
    +
  • CI: possible extra job duration if race detector is enabled.
  • +
  • Repository process: branch protection could block direct merges/pushes when CI fails.
  • +
  • Runtime: no production code changes expected.
  • +
  • Permissions: branch protection changes require GitHub admin capability and explicit user approval.
  • +
+
+ +
+

Test Plan

+
    +
  • go test ./...
  • +
  • go vet ./...
  • +
  • If race job is added: CGO_ENABLED=1 go test -race ./... locally or in CI.
  • +
  • If branch protection is changed: verify via gh api repos/Dzarlax-AI/health_dashboard/branches/main/protection.
  • +
  • After PR: confirm workflow job names match any required status checks.
  • +
+
+ +
+

Risks And Edge Cases

+
    +
  • Race detector can be slow and may need CGO toolchain behavior that differs from the production CGO_ENABLED=0 build.
  • +
  • Branch protection misconfiguration can block urgent fixes or require admin intervention.
  • +
  • Changing CI policy at the same time as no-vendor migration can make failures harder to attribute; coordinate with issue #170.
  • +
+
+ +
+

Rollback Plan

+

Remove the race job or switch it back to manual-only. For branch protection, restore the previous protection JSON or remove the newly required check after confirming with the user.

+
+ +
+

Open Questions

+
    +
  • Should race detector be required on every PR, manual-only, or deferred with explicit triggers?
  • +
  • Do we want branch protection on main now?
  • +
  • If issue #170 is approved, should this policy be implemented after no-vendor CI settles?
  • +
+
+ +
+

Approval Gate

+

Approved by the user on 2026-06-06. Branch protection settings were inspected but not changed, because settings mutation requires additional explicit approval.

+
+ +
+

Implementation Result

+
    +
  • Kept the default Build, Vet & Test job name stable.
  • +
  • Added a manual-only Race Detector job behind workflow_dispatch input run_race=true.
  • +
  • Race detector job runs CGO_ENABLED=1 go test -race ./... and is not required on normal PR or push runs.
  • +
  • Documented local and CI race-detector guidance in CONTRIBUTING.md.
  • +
  • Recorded current branch protection state: GitHub API returned Branch not protected for main on 2026-06-06.
  • +
+
+ +
+

Verification Run

+
    +
  • go test ./...
  • +
  • go vet ./...
  • +
  • CGO_ENABLED=1 go test -race ./... on Windows was blocked before tests by missing gcc in PATH; the manual GitHub Actions job is the Ubuntu validation path.
  • +
  • gh api repos/Dzarlax-AI/health_dashboard/branches/main/protection returned 404 Branch not protected.
  • +
+
+ +
+

Known Limitations

+
    +
  • Race detector is intentionally manual-only; it will not block PRs unless branch protection and workflow policy are changed later.
  • +
  • Local race-detector runs require a working CGO C compiler. This Windows workspace did not have gcc available.
  • +
  • Branch protection remains unchanged to avoid silently imposing repository-admin policy from a code PR.
  • +
+
+
+ + From 6d761d58b80fa77ae5c86fd9f6d1d3e52e136f3e Mon Sep 17 00:00:00 2001 From: Dzarlax Date: Sat, 6 Jun 2026 14:21:13 +0200 Subject: [PATCH 2/3] Prevent race dispatch image publishing --- .github/workflows/ci.yml | 4 ++-- CONTRIBUTING.md | 2 +- ...6-issue-152-ci-race-detector-branch-protection-policy.html | 2 ++ 3 files changed, 5 insertions(+), 3 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 00e6fc9..6d093da 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -74,7 +74,7 @@ jobs: name: Docker Build & Push (amd64) needs: build runs-on: ubuntu-latest - if: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.build_amd64)) }} + if: ${{ github.ref == 'refs/heads/main' && (github.event_name == 'push' || (github.event_name == 'workflow_dispatch' && inputs.build_amd64 && !inputs.run_race)) }} permissions: contents: read packages: write @@ -115,7 +115,7 @@ jobs: name: Docker Build & Push (arm64) needs: build runs-on: ubuntu-latest - if: ${{ github.event_name == 'workflow_dispatch' && inputs.build_arm64 }} + if: ${{ github.event_name == 'workflow_dispatch' && inputs.build_arm64 && !inputs.run_race }} permissions: contents: read packages: write diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2fcc9ab..a81df28 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -29,7 +29,7 @@ DB-backed integration tests skip when no Postgres connection is configured. To r The default required-looking CI job is `Build, Vet & Test`. Keep that job name stable unless repository branch protection is updated at the same time. -Default PR and push CI uses `CGO_ENABLED=0` for build, vet, and tests, matching the production binary. Race detector tests are available as a manual GitHub Actions run: start the `CI` workflow with `run_race=true`. Use this before merging changes that touch tenant management, scheduler goroutines, async AI generation, recompute coordination, Telegram webhook dispatch, or notification loops. +Default PR and push CI uses `CGO_ENABLED=0` for build, vet, and tests, matching the production binary. Race detector tests are available as a manual GitHub Actions run: start the `CI` workflow with `run_race=true`. Race-only dispatches do not publish Docker images, even when the image build inputs are left at their defaults. Use this before merging changes that touch tenant management, scheduler goroutines, async AI generation, recompute coordination, Telegram webhook dispatch, or notification loops. For local checks on a machine with a CGO toolchain: diff --git a/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html b/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html index fa449ad..b2902e4 100644 --- a/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html +++ b/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html @@ -133,6 +133,7 @@

Implementation Result

  • Kept the default Build, Vet & Test job name stable.
  • Added a manual-only Race Detector job behind workflow_dispatch input run_race=true.
  • Race detector job runs CGO_ENABLED=1 go test -race ./... and is not required on normal PR or push runs.
  • +
  • Guarded Docker publish jobs so race-only dispatches do not push images when run_race=true.
  • Documented local and CI race-detector guidance in CONTRIBUTING.md.
  • Recorded current branch protection state: GitHub API returned Branch not protected for main on 2026-06-06.
  • @@ -144,6 +145,7 @@

    Verification Run

  • go test ./...
  • go vet ./...
  • CGO_ENABLED=1 go test -race ./... on Windows was blocked before tests by missing gcc in PATH; the manual GitHub Actions job is the Ubuntu validation path.
  • +
  • Manual GitHub Actions run 27062004434 passed with run_race=true, including the Race Detector job on Ubuntu.
  • gh api repos/Dzarlax-AI/health_dashboard/branches/main/protection returned 404 Branch not protected.
  • From 963a367711b8af7edd28ea73f5dc093e3293b589 Mon Sep 17 00:00:00 2001 From: Dzarlax Date: Sat, 6 Jun 2026 14:27:00 +0200 Subject: [PATCH 3/3] Harden manual race workflow --- .github/workflows/ci.yml | 10 +++++++--- ...-152-ci-race-detector-branch-protection-policy.html | 4 +++- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 6d093da..e02d842 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -59,10 +59,14 @@ jobs: name: Race Detector runs-on: ubuntu-latest if: ${{ github.event_name == 'workflow_dispatch' && inputs.run_race }} + permissions: + contents: read steps: - - uses: actions/checkout@v5 + - uses: actions/checkout@93cb6efe18208431cddfb8368fd83d5badbf9bfd # v5 + with: + persist-credentials: false - - uses: actions/setup-go@v6 + - uses: actions/setup-go@4a3601121dd01d1626a1e23e37211e3254c1c06c # v6 with: go-version-file: go.mod cache: true @@ -115,7 +119,7 @@ jobs: name: Docker Build & Push (arm64) needs: build runs-on: ubuntu-latest - if: ${{ github.event_name == 'workflow_dispatch' && inputs.build_arm64 && !inputs.run_race }} + if: ${{ github.ref == 'refs/heads/main' && github.event_name == 'workflow_dispatch' && inputs.build_arm64 && !inputs.run_race }} permissions: contents: read packages: write diff --git a/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html b/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html index b2902e4..d55daac 100644 --- a/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html +++ b/docs/ai-plans/2026-06-06-issue-152-ci-race-detector-branch-protection-policy.html @@ -133,7 +133,8 @@

    Implementation Result

  • Kept the default Build, Vet & Test job name stable.
  • Added a manual-only Race Detector job behind workflow_dispatch input run_race=true.
  • Race detector job runs CGO_ENABLED=1 go test -race ./... and is not required on normal PR or push runs.
  • -
  • Guarded Docker publish jobs so race-only dispatches do not push images when run_race=true.
  • +
  • Guarded Docker publish jobs so race-only dispatches do not push images when run_race=true, and so arm64 image publishing is limited to main.
  • +
  • Hardened the manual race job with permissions: contents: read, persist-credentials: false, and SHA-pinned checkout/setup-go actions.
  • Documented local and CI race-detector guidance in CONTRIBUTING.md.
  • Recorded current branch protection state: GitHub API returned Branch not protected for main on 2026-06-06.
  • @@ -146,6 +147,7 @@

    Verification Run

  • go vet ./...
  • CGO_ENABLED=1 go test -race ./... on Windows was blocked before tests by missing gcc in PATH; the manual GitHub Actions job is the Ubuntu validation path.
  • Manual GitHub Actions run 27062004434 passed with run_race=true, including the Race Detector job on Ubuntu.
  • +
  • Manual GitHub Actions run 27062164558 passed with build_amd64=true, build_arm64=true, and run_race=true; race detector passed and both Docker publish jobs were skipped.
  • gh api repos/Dzarlax-AI/health_dashboard/branches/main/protection returned 404 Branch not protected.