From 702073cb6287ef07a4ac9ce38945670b1e885fd4 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Fri, 17 Jul 2026 23:06:49 +0200 Subject: [PATCH 1/4] docs(agents): correct the Validation topology in go-template AGENTS.md AGENTS.md claimed a repository ruleset "Require workflows to pass before merging for Go" injects the archived devantler-tech/reusable-workflows validate-go-project workflow (go build/test/lint/dead-code/MegaLinter/coverage) on every PR and the merge queue. Verified live against a real .go-touching PR's check set (#163) and the repo's rulesets: no such ruleset exists, and no validate-go-project workflow runs on this template's CI at all. The real gates are CI - Required Checks (a trivial aggregator), Validate Scaffold, and the org CodeQL / zizmor / Dependency Review rulesets; the full Go gate runs in generated projects, not the template. Rewrite the Validation section and the two dependent references (toolchain-floor note and the Maintenance validate-before-PR line) to match, dropping the stale reusable-workflows reference. Fixes #181 Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENTS.md | 32 +++++++++++++++++++------------- 1 file changed, 19 insertions(+), 13 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 3e67650..be46ffe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -43,18 +43,24 @@ golangci-lint run # run the configured linters Workflow YAML changes should pass `actionlint`. -These local checks are for fast feedback — **CI does verify the scaffold.** A -**repository ruleset** ("Require workflows to pass before merging for Go") -injects the shared `devantler-tech/reusable-workflows` **`validate-go-project`** -workflow on every PR and the merge queue; it runs `go build`, `go test`, -`golangci-lint`, dead-code analysis, MegaLinter, and Code-Quality coverage -(change-detection skips the Go jobs on non-Go PRs). The repo's own `ci.yaml` is -a separate, trivially-passing `CI - Required Checks` aggregator — **not** the Go -gate — so do **not** wire `validate-go-project` into `ci.yaml`; that would -double-run every job (see go-template#76, closed as invalid). - -The scaffold's **non-Go integrity checks** sit outside that Go gate, so they -have their own template-repo-only workflow, `validate-scaffold.yaml`. It runs +These local checks are for **fast feedback** and are the primary Go +verification for the template repository itself: CI here does **not** run `go +build` / `go test` / `golangci-lint` on the template's own scaffold. What CI +gates on every PR and the merge queue is `CI - Required Checks` (a trivial +aggregator defined in the repo's own `ci.yaml`), `Validate Scaffold` (the +scaffold-integrity checks below), and the org-wide security/automation +rulesets — CodeQL (`Analyze (go)` / `Analyze (actions)`), Scan for Workflow +Vulnerabilities (`zizmor`), and Dependency Review. Required status checks come +from the org "Require status checks to pass" ruleset (context: `CI - Required +Checks`); there is **no** "…for Go" workflow ruleset and **no** +`validate-go-project` / `reusable-workflows` injection (that repo was archived +into `devantler-tech/actions`). Keep `ci.yaml` the trivial aggregator it is — do +**not** add heavy Go build/test/lint jobs to it (see go-template#76, closed as +invalid); the full Go gate runs in **generated** projects via their own +scaffolded CI, not in this template. + +The scaffold's **non-Go integrity checks** are the template-repo-specific gate, +run by their own template-repo-only workflow, `validate-scaffold.yaml`. It runs `sh scripts/validate-agent-shims.test.sh`, `sh scripts/rename-placeholders.test.sh`, and `sh .github/scripts/run-mockery.test.sh`. Run the matching check locally when @@ -114,7 +120,7 @@ plus an `--experimental` opt-in (or a config gate), and only add the SDK where richer evaluation is genuinely needed. Same default-off, remove-after-rollout lifecycle either way. -**Validate before any PR (locally):** `golangci-lint fmt` (if configured), `go build ./... && go test ./...`, `golangci-lint run` — local checks for fast feedback (the ruleset-injected `validate-go-project` workflow re-runs build/test/lint/coverage on the PR — see *Validation* above; don't duplicate it into `ci.yaml`). Workflows → `actionlint`. +**Validate before any PR (locally):** `golangci-lint fmt` (if configured), `go build ./... && go test ./...`, `golangci-lint run` — local checks for fast feedback and the primary Go verification for the template itself; CI here does **not** re-run build/test/lint on the scaffold (see *Validation* above), so don't add heavy Go jobs to `ci.yaml`. Workflows → `actionlint`. **Task menu** (light; ≤1 high-value item per run): From f3b83f063ca6d0ce7e7f545dc22f8307861025cf Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Fri, 17 Jul 2026 23:26:41 +0200 Subject: [PATCH 2/4] docs(agents): sharpen the Validation topology per review MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Correct three over-broad claims from the first pass: the template's CI is not free of Go build/test (the Validate Scaffold job builds and tests a renamed scaffold copy — there is just no dedicated lint/coverage gate); Validate Scaffold is pull_request-only, so the merge queue is gated by ci.yaml's CI - Required Checks, not Validate Scaffold; and generated projects gate Go via org-injected ruleset workflows (devantler-tech) or a manually-replaced ci.yaml (outside the org), not via the scaffolded ci.yaml aggregator. Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENTS.md | 40 +++++++++++++++++++++++++--------------- 1 file changed, 25 insertions(+), 15 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index be46ffe..63de0fe 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -44,20 +44,30 @@ golangci-lint run # run the configured linters Workflow YAML changes should pass `actionlint`. These local checks are for **fast feedback** and are the primary Go -verification for the template repository itself: CI here does **not** run `go -build` / `go test` / `golangci-lint` on the template's own scaffold. What CI -gates on every PR and the merge queue is `CI - Required Checks` (a trivial -aggregator defined in the repo's own `ci.yaml`), `Validate Scaffold` (the -scaffold-integrity checks below), and the org-wide security/automation -rulesets — CodeQL (`Analyze (go)` / `Analyze (actions)`), Scan for Workflow -Vulnerabilities (`zizmor`), and Dependency Review. Required status checks come -from the org "Require status checks to pass" ruleset (context: `CI - Required -Checks`); there is **no** "…for Go" workflow ruleset and **no** -`validate-go-project` / `reusable-workflows` injection (that repo was archived -into `devantler-tech/actions`). Keep `ci.yaml` the trivial aggregator it is — do -**not** add heavy Go build/test/lint jobs to it (see go-template#76, closed as -invalid); the full Go gate runs in **generated** projects via their own -scaffolded CI, not in this template. +verification for the template repository itself: CI here has **no dedicated Go +build/test/lint gate**. It is not absent, though — the `Validate Scaffold` job +(below) renames the scaffold into a throwaway copy and runs `go build ./...` and +`go test ./...` against it (`scripts/rename-placeholders.test.sh`), so a scaffold +that stops building or testing fails a PR; there is just no dedicated +`golangci-lint` / dead-code / MegaLinter / coverage gate on this repo. A **PR** +is gated by `Validate Scaffold`, `CI - Required Checks` (a trivial aggregator in +the repo's own `ci.yaml`), and the org-wide rulesets — CodeQL (`Analyze (go)` / +`Analyze (actions)`), Scan for Workflow Vulnerabilities (`zizmor`), and +Dependency Review. The **merge queue** runs only `ci.yaml` (it declares +`merge_group`; `validate-scaffold.yaml` is `pull_request`-only), so `CI - +Required Checks` is the merge-group gate and `Validate Scaffold` does not run +there. Required status checks come from the org "Require status checks to pass" +ruleset (context: `CI - Required Checks`); there is **no** "…for Go" workflow +ruleset and **no** `validate-go-project` / `reusable-workflows` injection on this +repo (that repo was archived into `devantler-tech/actions`). Keep `ci.yaml` the +trivial aggregator it is — do **not** add heavy Go build/test/lint jobs to it +(see go-template#76, closed as invalid). + +**Generated** projects gate Go build/test differently — **not** via the +scaffolded `ci.yaml`, which is the same empty aggregator. **devantler-tech** +instances get build/test from org-injected ruleset workflows; instances +**outside** devantler-tech inherit no real build/test workflow and must replace +`ci.yaml` with their own (see the README and `.templatesyncignore`). The scaffold's **non-Go integrity checks** are the template-repo-specific gate, run by their own template-repo-only workflow, `validate-scaffold.yaml`. It runs @@ -120,7 +130,7 @@ plus an `--experimental` opt-in (or a config gate), and only add the SDK where richer evaluation is genuinely needed. Same default-off, remove-after-rollout lifecycle either way. -**Validate before any PR (locally):** `golangci-lint fmt` (if configured), `go build ./... && go test ./...`, `golangci-lint run` — local checks for fast feedback and the primary Go verification for the template itself; CI here does **not** re-run build/test/lint on the scaffold (see *Validation* above), so don't add heavy Go jobs to `ci.yaml`. Workflows → `actionlint`. +**Validate before any PR (locally):** `golangci-lint fmt` (if configured), `go build ./... && go test ./...`, `golangci-lint run` — local checks for fast feedback; the template has no dedicated Go lint gate in CI (its only CI build/test is the `Validate Scaffold` job's smoke of a renamed scaffold copy — see *Validation* above), so don't add heavy Go jobs to `ci.yaml`. Workflows → `actionlint`. **Task menu** (light; ≤1 high-value item per run): From e2242ac026a6d201acca280148f356532e59f2ff Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Sat, 18 Jul 2026 08:38:09 +0200 Subject: [PATCH 3/4] docs(agents): complete the required-workflow set in the CI topology Two review corrections: the PR gate list omitted the org-required Enable Auto-Merge workflow (its eligibility run is in every live check set), and the merge queue was described as ci.yaml alone. All four org-required workflows (CodeQL, zizmor, Dependency Review, Enable Auto-Merge) declare merge_group and appear in the merge-group check set; only validate-scaffold.yaml is pull_request-only. Co-Authored-By: Claude Opus 4.8 (1M context) --- AGENTS.md | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index 63de0fe..d23cc34 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -51,12 +51,14 @@ build/test/lint gate**. It is not absent, though — the `Validate Scaffold` job that stops building or testing fails a PR; there is just no dedicated `golangci-lint` / dead-code / MegaLinter / coverage gate on this repo. A **PR** is gated by `Validate Scaffold`, `CI - Required Checks` (a trivial aggregator in -the repo's own `ci.yaml`), and the org-wide rulesets — CodeQL (`Analyze (go)` / -`Analyze (actions)`), Scan for Workflow Vulnerabilities (`zizmor`), and -Dependency Review. The **merge queue** runs only `ci.yaml` (it declares -`merge_group`; `validate-scaffold.yaml` is `pull_request`-only), so `CI - -Required Checks` is the merge-group gate and `Validate Scaffold` does not run -there. Required status checks come from the org "Require status checks to pass" +the repo's own `ci.yaml`), and the org-required workflows — CodeQL (`Analyze +(go)` / `Analyze (actions)`), Scan for Workflow Vulnerabilities (`zizmor`), +Dependency Review, and Enable Auto-Merge (`eligibility`). The **merge queue** +runs `ci.yaml` **plus** those org-required workflows — they all declare +`merge_group` and complete via no-op eligibility paths, so they appear in the +merge-group check set too. Only `validate-scaffold.yaml` is +`pull_request`-only, so `Validate Scaffold` does **not** run on a merge-group +SHA. Required status checks come from the org "Require status checks to pass" ruleset (context: `CI - Required Checks`); there is **no** "…for Go" workflow ruleset and **no** `validate-go-project` / `reusable-workflows` injection on this repo (that repo was archived into `devantler-tech/actions`). Keep `ci.yaml` the From b3810b03ea6695d6b229b66c672c69bb8b30fa45 Mon Sep 17 00:00:00 2001 From: Nikolai Emil Damm Date: Sat, 18 Jul 2026 09:46:54 +0200 Subject: [PATCH 4/4] docs: align README and validate-scaffold with the corrected topology MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Codex P3 on #183: the AGENTS.md correction states this repo has no validate-go-project / reusable-workflows injection and no dedicated golangci-lint / MegaLinter / coverage gate, but two other surfaces still published the old story. Verified against the repo at e2242ac: no workflow (cd, ci, release, template-sync, todos, validate-scaffold) runs golangci-lint, MegaLinter, or coverage. The configs (.golangci.yml, .mega-linter.yml, .pre-commit-config.yaml) do ship, so the fix is to state where they actually run, not to drop them. - README: the lint/format and coverage bullets no longer claim "in CI" for this repo; they describe shipped, ready-to-use configs that run locally via pre-commit and in whatever Go workflow the consuming organisation injects, linking AGENTS.md#validation. - validate-scaffold.yaml: drop the "shared Go gate" framing and the reference to the retired injected validate-go-project workflow. Comment/prose only — the workflow parsed to JSON is byte-identical to the previous head; actionlint clean; both scaffold self-tests pass. --- .github/workflows/validate-scaffold.yaml | 8 ++++---- README.md | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/.github/workflows/validate-scaffold.yaml b/.github/workflows/validate-scaffold.yaml index 78550e5..c221930 100644 --- a/.github/workflows/validate-scaffold.yaml +++ b/.github/workflows/validate-scaffold.yaml @@ -6,8 +6,7 @@ on: permissions: {} -# Template-repo-only scaffold-integrity gate for three non-Go surfaces that -# the shared Go gate does not cover: +# Template-repo-only scaffold-integrity gate for three non-Go surfaces: # * scripts/rename-placeholders.sh — the first thing a newcomer runs after # `Use this template`; a silent regression ships broken to every generated # project. @@ -17,8 +16,9 @@ permissions: {} # copied guidance would create a second source that silently drifts. # This job runs ONLY in the template repo; it no-ops in projects created from it # (the guard below is false there), mirroring how cd.yaml/release.yaml run only -# downstream. Generated projects delete the onboarding script and validate their -# own code via the injected validate-go-project workflow. +# downstream. Generated projects delete the onboarding script and gate their own +# code through whatever Go workflow their organisation injects (see AGENTS.md +# *Validation*) — this repo has no such injection. jobs: validate-scaffold: name: Validate Scaffold diff --git a/README.md b/README.md index ec53bed..374735a 100644 --- a/README.md +++ b/README.md @@ -10,9 +10,9 @@ A minimal, batteries-included Go template for new projects. Skip the boilerplate - **Idiomatic scaffold** — a no-op `main.go` plus the conventional `cmd/`, `internal/`, and `pkg/` layout, ready for your first package. A minimal [`pkg/example`](pkg/example) package with a table-driven test shows the house testing pattern — replace it with your own. - **Feature-flag-first** — [`pkg/featureflag`](pkg/featureflag) wires the portable [OpenFeature](https://openfeature.dev/) Go SDK so a **service** can land every new feature behind a flag, default-off, and flip it on only after validation (swap the in-memory provider for [flagd](https://flagd.dev/) or a managed backend). A **CLI** can stay dependency-free instead — gate experimental commands behind cobra `Hidden` + an `--experimental` opt-in, reaching for the SDK only when you need richer evaluation. Delete it when you add your own. -- **Linting & formatting** — [`golangci-lint`](https://golangci-lint.run/) v2 (formatters + `default: all` linters) in CI, with [MegaLinter](https://megalinter.io/) covering everything else. A [pre-commit](https://pre-commit.com/) hook runs `golangci-lint` formatting (and `mockery` mock generation) locally on commit. +- **Linting & formatting** — ready-to-use [`golangci-lint`](https://golangci-lint.run/) v2 (formatters + `default: all` linters) and [MegaLinter](https://megalinter.io/) configs. A [pre-commit](https://pre-commit.com/) hook runs `golangci-lint` formatting (and `mockery` mock generation) locally on commit; in CI they run wherever your organisation injects a Go workflow (see [*Validation*](AGENTS.md#validation)). - **CI/CD** — a required-checks workflow on pull requests and the merge queue, plus a [GoReleaser](https://goreleaser.com/) release pipeline (`cd.yaml`) triggered on `v*` tags. -- **Coverage** — `go test` coverage reported via [GitHub Code Quality](https://docs.github.com/code-security/code-quality). +- **Coverage** — a `go test` coverage config ready to report via [GitHub Code Quality](https://docs.github.com/code-security/code-quality) once your CI runs it. - **Dependency management** — [Dependabot](https://docs.github.com/code-security/dependabot) keeps Go modules and pinned GitHub Actions current (daily). - **Agent-ready** — [`AGENTS.md`](AGENTS.md) conventions and a `.claude/skills/maintain` card so the autonomous Daily AI Assistant (and any agentic tool) can maintain the repo.