CI/CD Generator
Lifecycle skill that scaffolds a complete GitHub Actions pipeline for a Go, Rust, TypeScript, or Python project. The workflow encodes opinionated defaults documented in the project owner's notes — coverage gates, N+1 query detection, race condition property-based testing (including Python 3.14t free-threaded), memory leak detection, and load testing — plus standard security gates (SAST, SCA, container scan, SBOM, secret scan).
When to Use
The skill has two operating modes — generation (the default, walks Phase 0 → 6 below) and audit (read-only review of an existing pipeline, walks Phase A0 → A5 in references/AUDIT.md).
Generation mode
- A new repository (Go, Rust, TypeScript, or Python) has no
.github/workflows/ directory and the user wants CI/CD wired up
- An existing repository has an ad-hoc workflow that the user wants replaced with a complete, opinionated baseline
- The user explicitly asks for "criar CI", "gerar pipeline", "scaffold workflow", or invokes
/valarmindskills:ci-cd-generator
- A polyglot monorepo needs per-language pipelines (run the skill once per project root)
Audit mode
- The repository already has workflows authored before this skill existed and the user wants them reviewed
- A security incident exposed a CI weakness (compromised secret, malicious action) and the user wants the full surface checked
- Pre-release gate: confirm the workflows match the security level the team thinks they are running at
- The user explicitly asks for "auditar pipeline", "audit CI pipeline", "review existing workflow"
This skill is language-aware and lifecycle-driven: it detects → asks the minimum needed → applies heuristics → emits YAML or report → validates. For multi-stack API security review (design + active testing + Go, Next.js, and Python stack-specific lifecycles) run from a CI pipeline, complement with @code-security-review (Go branch — references/golang/; Next branch — references/nextjs/; Python branch — references/python/). For Next.js performance audits, see @code-review references/NEXTJS.md; for Python performance/style sweeps, see @code-review references/PYTHON.md.
Do not use when
- The user wants to fix or refactor a single line in an existing workflow — open the YAML directly or use
@github-pr-review. For a full pipeline audit, switch to audit mode instead.
- The CI platform is GitLab CI, CircleCI, Buildkite, or Jenkins — this skill is GitHub Actions only
- The project language is not Go, Rust, TypeScript (Node.js / Bun / Deno), or Python (3.13+/3.14+, FastAPI / Django / Flask)
- The user wants to deploy infrastructure (Terraform, Pulumi, Kubernetes manifests) — pipeline ≠ infra
Prerequisites
| Tool |
Purpose |
Install |
gh (GitHub CLI) |
Branch protection, secrets management, dispatch |
brew install gh then gh auth login |
actionlint |
Static lint of generated YAML |
brew install actionlint |
yamllint |
Style and structural lint |
brew install yamllint |
| Language toolchain on host |
Local sanity check before commit |
go, cargo, bun/pnpm/npm, python 3.13+/3.14+ with uv/poetry/pip per project |
Required access:
Phase 0 — Project Detection
Detect language, package manager, and runtime before generating anything. Run the steps in order; stop at the first conclusive match per axis.
# Step 1 — language
test -f go.mod && echo "language: go"
test -f Cargo.toml && echo "language: rust"
test -f package.json && echo "language: typescript"
test -f tsconfig.json && echo " ts-config: present"
{ test -f pyproject.toml || test -f requirements.txt || test -f setup.py; } && echo "language: python"
# Step 2 — TypeScript runtime (only if language=typescript)
test -f bun.lockb && echo "runtime: bun, pm: bun"
test -f pnpm-lock.yaml && echo "runtime: node, pm: pnpm"
test -f yarn.lock && echo "runtime: node, pm: yarn"
test -f package-lock.json && echo "runtime: node, pm: npm"
# Step 3 — Rust workspace shape
grep -q '\[workspace\]' Cargo.toml 2>/dev/null && echo "rust: workspace"
# Step 4 — Go module shape
grep -E '^go [0-9]+\.[0-9]+' go.mod | head -1 # toolchain version
grep -q '^// +build' . -r 2>/dev/null && echo "go: legacy build tags present"
# Step 5 — Python PM + framework (only if language=python)
test -f uv.lock && echo "pm: uv"
test -f poetry.lock && echo "pm: poetry"
test -f Pipfile.lock && echo "pm: pipenv" # legacy
{ test -f requirements.txt && ! test -f uv.lock && ! test -f poetry.lock; } && echo "pm: pip"
grep -qE '(^|[[:space:]"])fastapi[>=<~!"[:space:]]' pyproject.toml requirements.txt 2>/dev/null && echo "framework: fastapi"
grep -qE '(^|[[:space:]"])django[>=<~!"[:space:]]' pyproject.toml requirements.txt 2>/dev/null && echo "framework: django"
grep -qE '(^|[[:space:]"])flask[>=<~!"[:space:]]' pyproject.toml requirements.txt 2>/dev/null && echo "framework: flask"
# Python version source of truth
test -f .python-version && cat .python-version
grep -E '^requires-python' pyproject.toml 2>/dev/null
Persist as $LANG ∈ {go, rust, typescript, python}, plus per-language sub-fields ($RUNTIME, $PM, $WORKSPACE, $FRAMEWORK). The next phases branch on these values.
$LANG |
Reference to load |
Default file emitted |
go |
references/GO.md |
.github/workflows/ci.yml |
rust |
references/RUST.md |
.github/workflows/ci.yml |
typescript |
references/TYPESCRIPT.md |
.github/workflows/ci.yml |
python |
references/PYTHON.md |
.github/workflows/ci.yml |
polyglot (multiple matches) |
Run Phase 0 per subdirectory |
One workflow per language detected |
If no match is found, abort with a one-line notice. The skill does not invent a language.
Phase 1 — Collect Preferences
Ask the user only for inputs that cannot be inferred. Use one consolidated AskUserQuestion block, never one question per phase.
| Input |
Required |
Default |
Inferable from |
| Coverage threshold |
No |
60 (per user heuristic) |
None — must default |
| Security level |
No |
standard (SAST + SCA + secret scan) |
None — must default |
| Container scan |
No |
true if Dockerfile exists, else false |
test -f Dockerfile |
| SBOM emission |
No |
true if security level = strict |
None |
| Release workflow (tag-driven) |
No |
true if goreleaser.yml exists or user has github-release-note history |
test -f .goreleaser.yml |
| Dependabot config |
No |
true (always) |
None |
| Load testing job |
No |
false (heavy; opt-in) |
Never default on |
| Branch protection rules |
No |
Suggest in report; do not apply automatically |
None |
Three security levels:
minimal — lint + test + build. No security gates. Use only for prototypes.
standard (default) — adds CodeQL/Semgrep, dependency audit, secret scan
strict — adds container scan (trivy), SBOM (syft), license check, signing
The full preferences-elicitation script lives in references/USER_HEURISTICS.md. It also documents the rationale for each default, citing the project owner's vault notes.
Phase 2 — Apply User Heuristics
The pipeline emits five opinionated checks regardless of language. Each is sourced from the project owner's notes and is mandatory unless the user opts out explicitly.
| # |
Heuristic |
Default behavior |
Override flag |
| 1 |
Coverage gate ≥ 60% (warn ≥ 80%) |
Pipeline fails below threshold |
--coverage=N or "ignore coverage" |
| 2 |
N+1 detection |
Integration tests assert max query count per request |
--no-n1 |
| 3 |
Race condition PBT |
Concurrent property-based test job; -race flag in Go |
--no-race |
| 4 |
Memory leak detection |
Jest/Vitest --detectOpenHandles --detectLeaks (TS); -race (Go); miri optional (Rust); tracemalloc snapshot + pytest-asyncio --strict-mode + pytest-memray (Python) |
--no-leak-detect |
| 5 |
Load testing |
Nightly workflow_dispatch job using k6 or artillery (opt-in) |
Default off |
For each heuristic, references/USER_HEURISTICS.md contains:
- The exact rationale from the source notes
- The detection technique per language
- A copy-pasteable workflow snippet
- The expected failure mode if the heuristic catches something
Phase 3 — Wire Security Gates
Branch on the security level chosen in Phase 1. Each gate is a separate job that runs in parallel with the test job whenever possible.
| Gate |
minimal |
standard |
strict |
actionlint self-check |
✓ |
✓ |
✓ |
| Lint + format |
✓ |
✓ |
✓ |
| Unit + integration tests |
✓ |
✓ |
✓ |
| Coverage gate |
✓ |
✓ |
✓ |
| CodeQL / Semgrep (SAST) |
— |
✓ |
✓ |
| Dependency audit (SCA) |
— |
✓ |
✓ |
| Secret scan (gitleaks) |
— |
✓ |
✓ |
| Container scan (trivy) |
— |
conditional |
✓ |
| SBOM (syft / cyclonedx) |
— |
— |
✓ |
| License check |
— |
— |
✓ |
| Provenance / signing (cosign + SLSA) |
— |
— |
optional |
Per-language tool selection (CodeQL languages, audit commands, container base scan strategy) is captured in references/SECURITY_GATES.md.
Anti-patterns the generator must refuse to emit:
pull_request_target with checkout of the PR head (RCE vector)
permissions: defaulting to write-all at the workflow level
- Third-party actions without a pinned commit SHA when
security level = strict
- Secrets passed via
env: at the workflow level (must be job- or step-scoped)
actions/checkout@v4 followed by running untrusted scripts before any allowlist check
Phase 4 — Generate Workflow YAML
Emit the YAML in this skeleton, populated from the language-specific reference:
name: ci
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
concurrency:
group: ci-${{ github.ref }}
cancel-in-progress: true
jobs:
meta:
name: actionlint
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: rhysd/actionlint@v1 # pinned via SHA in `strict`
lint:
needs: meta
# populated from <language>.md
test:
needs: meta
# populated from <language>.md
# includes: race flag, coverage gate, N+1 assertion, leak detection
security:
needs: meta
# populated from SECURITY_GATES.md per security-level
build:
needs: [lint, test, security]
# populated from <language>.md
Per-language fully populated workflows (with matrix, cache, environment variables, and the canonical job graph) live in:
- references/GO.md —
actions/setup-go@v5, go test -race -cover -covermode=atomic, staticcheck, golangci-lint, govulncheck, optional goreleaser
- references/RUST.md —
actions-rust-lang/setup-rust-toolchain@v1, Swatinem/rust-cache@v2, cargo fmt --check, cargo clippy -D warnings, cargo nextest, cargo-llvm-cov, cargo-audit, cargo-deny
- references/TYPESCRIPT.md —
setup-bun / setup-node + pnpm/action-setup, tsc --noEmit, eslint, vitest/jest with --detectOpenHandles --detectLeaks, N+1 query test template, size-limit
- references/PYTHON.md —
actions/setup-python@v5 / astral-sh/setup-uv@v3 / snok/install-poetry, ruff check+ruff format --check, mypy --strict/pyright, pytest --cov-fail-under, bandit+pip-audit+safety, N+1 templates (Django assertNumQueries / SQLAlchemy event listener), free-threaded race (python3.14t + hypothesis), optional PyPI trusted publishing
Always pin third-party actions:
standard level: @vN major-version pin
strict level: full commit SHA pin (@<40-char-sha>) with a comment naming the version
Phase 5 — Validation & Dry-Run
Before reporting success, run the local checks:
# 1. Lint the YAML
actionlint .github/workflows/*.yml
yamllint -d relaxed .github/workflows/*.yml
# 2. Confirm secrets referenced in the YAML
grep -hoE '\$\{\{ secrets\.[A-Z_]+ \}\}' .github/workflows/*.yml | sort -u
# 3. Verify all third-party actions are pinned
grep -hE 'uses: ' .github/workflows/*.yml | grep -v 'actions/' | grep -v '@[a-f0-9]\{40\}\|@v[0-9]'
# 4. List required workflows for branch protection
grep -E '^ [a-z_-]+:$' .github/workflows/ci.yml | sed 's/[: ]//g'
Each finding is added to the post-generation report. If actionlint reports errors, abort and emit the diff for the user instead of writing the file.
The full validation matrix and the optional gh workflow run --ref <branch> ci.yml smoke test are in references/CHECKLIST.md.
Phase 6 — Deliver
- Write the workflow file(s) to
.github/workflows/. Default filename: ci.yml. Optional: release.yml, nightly-load.yml.
- Write
.github/dependabot.yml if Phase 1 enabled it.
- Emit the generation report (see Output format).
- Surface the suggested branch protection rules — do not apply them automatically. Provide the
gh command the user can run.
- Hand off to
@github-commit to commit the new files; do not commit unless the user explicitly approves.
A worked end-to-end run of Phase 0 → Phase 6 for a Go API project is in EXAMPLE.md.
Audit mode (alternate entry)
When the user asks to audit an existing pipeline rather than generate one, branch at the very top of Phase 0 into the audit procedure documented in references/AUDIT.md. The audit walks Phase A0 → A5 (inventory → heuristic compliance → security gate compliance → anti-pattern sweep → action freshness → caching/concurrency hygiene) and emits a severity-ranked findings table with fix proposals.
The audit is read-only by default. The user can opt in per finding ID for the skill to apply unified-diff fixes; each fix is tagged SAFE / REVIEW / BREAKING and re-validated with actionlint before report-ok. The skill never commits.
Pick the entry point by user intent:
| Intent signal |
Entry |
"criar CI", "gerar pipeline", "scaffold workflow", /ci-cd-generator on a repo with no .github/workflows/ |
Phase 0 (generation) |
"auditar pipeline", "audit CI", "review existing workflow", /ci-cd-generator on a repo with workflows present |
Phase A0 (audit) |
Ambiguous and .github/workflows/ exists |
Ask once: "audit existing workflows or generate a new baseline alongside?" — do not assume |
Constraints
- Never commit the generated YAML without explicit user approval — emit the diff first
- Never apply branch protection rules without an explicit
gh api call confirmed by the user
- Never emit
pull_request_target with PR-head checkout
- Never default
permissions: to write-all at workflow level — start at contents: read and elevate per job
- Never pass secrets via the workflow-level
env:; scope them to the job or step
- Never use third-party actions without a version pin (major tag minimum, SHA in
strict)
- Never generate a pipeline for a language outside
{go, rust, typescript, python} — abort with a one-line notice
- Never silently downgrade the security level when a tool is missing — surface the gap to the user
- Must load the matching language reference before emitting any YAML
- Must run
actionlint on the generated file before reporting success
- Must include a header comment listing required secrets, the trigger graph, and the source skill
- Must keep the workflow under 500 lines per file; split into
ci.yml + release.yml + nightly-load.yml when needed
- Must not invent secrets or repository variables — every
${{ secrets.X }} reference must be listed in the report
Output format
Generation report (printed verbatim after every successful run):
ci-cd-generator: <action>
language: <go | rust | typescript | python>
runtime/pm: <node+pnpm | bun | rust+nextest | go+toolchain x.y | python+uv | python+poetry | python+pip>
framework: <fastapi | django | flask | n/a> # python only
security: <minimal | standard | strict>
workflows: <files written, paths under .github/>
jobs: <ordered list of job ids in ci.yml>
required-secrets: <SECRET_A, SECRET_B, … or "none">
Suggested branch protection (run after committing):
gh api -X PUT repos/<owner>/<repo>/branches/main/protection \
-F required_status_checks.strict=true \
-F 'required_status_checks.contexts[]=lint' \
-F 'required_status_checks.contexts[]=test' \
-F 'required_status_checks.contexts[]=security' \
-F enforce_admins=true \
-F required_pull_request_reviews.required_approving_review_count=1
Next: review the diff, then `/valarmindskills:github-commit`.
Related Skills
@github-commit — commit the generated workflow files following Conventional Commits
@github-release-note — generate release notes when the release workflow tags a version
@github-pr-review — review the diff that introduces the workflow
@clean-code — apply principles to the YAML (consistent naming, no duplication across jobs)
@code-security-review — multi-stack security review job covering generic flows + Go (Gin/Fiber, references/golang/) + Next.js 16 App Router (references/nextjs/); active testing via references/TESTING_PHASES.md, run nightly via the load testing slot; 100-vuln class catalog via references/WEB_VULNERABILITIES.md when the pipeline must spell out which classes each gate addresses
@code-debugger — diagnosing a failing generated workflow before reporting it as broken
References
- GO — Go pipeline template, tooling matrix, canonical workflow
- RUST — Rust pipeline template, tooling matrix, canonical workflow
- TYPESCRIPT — TypeScript pipeline template (Node + Bun), N+1 and leak templates
- PYTHON — Python 3.13/3.14 pipeline template (FastAPI / Django / Flask), uv/poetry/pip PM detection, N+1 templates, free-threaded race testing, PyPI trusted publishing
- USER_HEURISTICS — coverage gate, N+1, race PBT, leak detection, load testing — rationale and snippets
- SECURITY_GATES — SAST, SCA, container, SBOM, secret scan, license — per-language tool matrix
- CHECKLIST — post-generation validation, branch protection, smoke test
- AUDIT — audit mode procedure, detection rules, severity matrix, report format, opt-in fix application
- EXAMPLE — end-to-end worked example for a Go API project
1---2name: ci-cd-generator3description: Scaffold/audit GitHub Actions CI/CD — Go/Rust/TS/Python (FastAPI/Django/Flask). Generation: workflows + coverage gates (60–80%), security scans (CodeQL/Semgrep/bandit, SCA, SBOM, gitleaks), N+1/race/leak/load tests + free-threaded 3.14t. Audit: severity-ranked findings + diff fixes. Triggers: 'criar CI', 'gerar pipeline', 'auditar pipeline', '/ci-cd-generator'.4---56# CI/CD Generator78Lifecycle skill that scaffolds a complete GitHub Actions pipeline for a Go, Rust, TypeScript, or Python project. The workflow encodes opinionated defaults documented in the project owner's notes — coverage gates, N+1 query detection, race condition property-based testing (including Python 3.14t free-threaded), memory leak detection, and load testing — plus standard security gates (SAST, SCA, container scan, SBOM, secret scan).910## When to Use1112The skill has two operating modes — **generation** (the default, walks Phase 0 → 6 below) and **audit** (read-only review of an existing pipeline, walks Phase A0 → A5 in [references/AUDIT.md](references/AUDIT.md)).1314### Generation mode1516- A new repository (Go, Rust, TypeScript, or Python) has no `.github/workflows/` directory and the user wants CI/CD wired up17- An existing repository has an ad-hoc workflow that the user wants replaced with a complete, opinionated baseline18- The user explicitly asks for "criar CI", "gerar pipeline", "scaffold workflow", or invokes `/valarmindskills:ci-cd-generator`19- A polyglot monorepo needs per-language pipelines (run the skill once per project root)2021### Audit mode2223- The repository already has workflows authored before this skill existed and the user wants them reviewed24- A security incident exposed a CI weakness (compromised secret, malicious action) and the user wants the full surface checked25- Pre-release gate: confirm the workflows match the security level the team thinks they are running at26- The user explicitly asks for "auditar pipeline", "audit CI pipeline", "review existing workflow"2728This skill is **language-aware and lifecycle-driven**: it detects → asks the minimum needed → applies heuristics → emits YAML or report → validates. For multi-stack API security review (design + active testing + Go, Next.js, and Python stack-specific lifecycles) run from a CI pipeline, complement with `@code-security-review` (Go branch — `references/golang/`; Next branch — `references/nextjs/`; Python branch — `references/python/`). For Next.js performance audits, see `@code-review` `references/NEXTJS.md`; for Python performance/style sweeps, see `@code-review` `references/PYTHON.md`.2930## Do not use when3132- The user wants to fix or refactor a single line in an existing workflow — open the YAML directly or use `@github-pr-review`. For a full pipeline audit, switch to **audit mode** instead.33- The CI platform is GitLab CI, CircleCI, Buildkite, or Jenkins — this skill is GitHub Actions only34- The project language is not Go, Rust, TypeScript (Node.js / Bun / Deno), or Python (3.13+/3.14+, FastAPI / Django / Flask)35- The user wants to deploy infrastructure (Terraform, Pulumi, Kubernetes manifests) — pipeline ≠ infra3637## Prerequisites3839| Tool | Purpose | Install |40| --- | --- | --- |41| `gh` (GitHub CLI) | Branch protection, secrets management, dispatch | `brew install gh` then `gh auth login` |42| `actionlint` | Static lint of generated YAML | `brew install actionlint` |43| `yamllint` | Style and structural lint | `brew install yamllint` |44| Language toolchain on host | Local sanity check before commit | `go`, `cargo`, `bun`/`pnpm`/`npm`, `python` 3.13+/3.14+ with `uv`/`poetry`/`pip` per project |4546Required access:4748- [ ] Read access to the repository root (for detection)49- [ ] Write access to `.github/` and `.github/workflows/`50- [ ] Permission to commit on a branch (skill never commits without explicit user approval)51- [ ] If branch protection is part of the request: admin role on the repository5253## Phase 0 — Project Detection5455Detect language, package manager, and runtime before generating anything. Run the steps in order; stop at the first conclusive match per axis.5657```bash58# Step 1 — language59test -f go.mod && echo "language: go"60test -f Cargo.toml && echo "language: rust"61test -f package.json && echo "language: typescript"62test -f tsconfig.json && echo " ts-config: present"63{ test -f pyproject.toml || test -f requirements.txt || test -f setup.py; } && echo "language: python"6465# Step 2 — TypeScript runtime (only if language=typescript)66test -f bun.lockb && echo "runtime: bun, pm: bun"67test -f pnpm-lock.yaml && echo "runtime: node, pm: pnpm"68test -f yarn.lock && echo "runtime: node, pm: yarn"69test -f package-lock.json && echo "runtime: node, pm: npm"7071# Step 3 — Rust workspace shape72grep -q '\[workspace\]' Cargo.toml 2>/dev/null && echo "rust: workspace"7374# Step 4 — Go module shape75grep -E '^go [0-9]+\.[0-9]+' go.mod | head -1 # toolchain version76grep -q '^// +build' . -r 2>/dev/null && echo "go: legacy build tags present"7778# Step 5 — Python PM + framework (only if language=python)79test -f uv.lock && echo "pm: uv"80test -f poetry.lock && echo "pm: poetry"81test -f Pipfile.lock && echo "pm: pipenv" # legacy82{ test -f requirements.txt && ! test -f uv.lock && ! test -f poetry.lock; } && echo "pm: pip"83grep -qE '(^|[[:space:]"])fastapi[>=<~!"[:space:]]' pyproject.toml requirements.txt 2>/dev/null && echo "framework: fastapi"84grep -qE '(^|[[:space:]"])django[>=<~!"[:space:]]' pyproject.toml requirements.txt 2>/dev/null && echo "framework: django"85grep -qE '(^|[[:space:]"])flask[>=<~!"[:space:]]' pyproject.toml requirements.txt 2>/dev/null && echo "framework: flask"86# Python version source of truth87test -f .python-version && cat .python-version88grep -E '^requires-python' pyproject.toml 2>/dev/null89```9091Persist as `$LANG ∈ {go, rust, typescript, python}`, plus per-language sub-fields (`$RUNTIME`, `$PM`, `$WORKSPACE`, `$FRAMEWORK`). The next phases branch on these values.9293| `$LANG` | Reference to load | Default file emitted |94| --- | --- | --- |95| `go` | [references/GO.md](references/GO.md) | `.github/workflows/ci.yml` |96| `rust` | [references/RUST.md](references/RUST.md) | `.github/workflows/ci.yml` |97| `typescript` | [references/TYPESCRIPT.md](references/TYPESCRIPT.md) | `.github/workflows/ci.yml` |98| `python` | [references/PYTHON.md](references/PYTHON.md) | `.github/workflows/ci.yml` |99| `polyglot` (multiple matches) | Run Phase 0 per subdirectory | One workflow per language detected |100101If no match is found, abort with a one-line notice. The skill does not invent a language.102103## Phase 1 — Collect Preferences104105Ask the user **only** for inputs that cannot be inferred. Use one consolidated `AskUserQuestion` block, never one question per phase.106107| Input | Required | Default | Inferable from |108| --- | --- | --- | --- |109| Coverage threshold | No | `60` (per user heuristic) | None — must default |110| Security level | No | `standard` (SAST + SCA + secret scan) | None — must default |111| Container scan | No | `true` if `Dockerfile` exists, else `false` | `test -f Dockerfile` |112| SBOM emission | No | `true` if `security level = strict` | None |113| Release workflow (tag-driven) | No | `true` if `goreleaser.yml` exists or user has `github-release-note` history | `test -f .goreleaser.yml` |114| Dependabot config | No | `true` (always) | None |115| Load testing job | No | `false` (heavy; opt-in) | Never default on |116| Branch protection rules | No | Suggest in report; do not apply automatically | None |117118Three security levels:119120- **`minimal`** — lint + test + build. No security gates. Use only for prototypes.121- **`standard`** (default) — adds CodeQL/Semgrep, dependency audit, secret scan122- **`strict`** — adds container scan (trivy), SBOM (syft), license check, signing123124The full preferences-elicitation script lives in [references/USER_HEURISTICS.md](references/USER_HEURISTICS.md). It also documents the rationale for each default, citing the project owner's vault notes.125126## Phase 2 — Apply User Heuristics127128The pipeline emits five opinionated checks regardless of language. Each is sourced from the project owner's notes and is mandatory unless the user opts out explicitly.129130| # | Heuristic | Default behavior | Override flag |131| --- | --- | --- | --- |132| 1 | **Coverage gate** ≥ 60% (warn ≥ 80%) | Pipeline fails below threshold | `--coverage=N` or "ignore coverage" |133| 2 | **N+1 detection** | Integration tests assert max query count per request | `--no-n1` |134| 3 | **Race condition PBT** | Concurrent property-based test job; `-race` flag in Go | `--no-race` |135| 4 | **Memory leak detection** | Jest/Vitest `--detectOpenHandles --detectLeaks` (TS); `-race` (Go); miri optional (Rust); `tracemalloc` snapshot + `pytest-asyncio --strict-mode` + `pytest-memray` (Python) | `--no-leak-detect` |136| 5 | **Load testing** | Nightly `workflow_dispatch` job using k6 or artillery (opt-in) | Default off |137138For each heuristic, [references/USER_HEURISTICS.md](references/USER_HEURISTICS.md) contains:139140- The exact rationale from the source notes141- The detection technique per language142- A copy-pasteable workflow snippet143- The expected failure mode if the heuristic catches something144145## Phase 3 — Wire Security Gates146147Branch on the security level chosen in Phase 1. Each gate is a separate job that runs in parallel with the test job whenever possible.148149| Gate | `minimal` | `standard` | `strict` |150| --- | :---: | :---: | :---: |151| `actionlint` self-check | ✓ | ✓ | ✓ |152| Lint + format | ✓ | ✓ | ✓ |153| Unit + integration tests | ✓ | ✓ | ✓ |154| Coverage gate | ✓ | ✓ | ✓ |155| **CodeQL / Semgrep (SAST)** | — | ✓ | ✓ |156| **Dependency audit (SCA)** | — | ✓ | ✓ |157| **Secret scan (gitleaks)** | — | ✓ | ✓ |158| **Container scan (trivy)** | — | conditional | ✓ |159| **SBOM (syft / cyclonedx)** | — | — | ✓ |160| License check | — | — | ✓ |161| Provenance / signing (cosign + SLSA) | — | — | optional |162163Per-language tool selection (CodeQL languages, audit commands, container base scan strategy) is captured in [references/SECURITY_GATES.md](references/SECURITY_GATES.md).164165Anti-patterns the generator must refuse to emit:166167- `pull_request_target` with checkout of the PR head (RCE vector)168- `permissions:` defaulting to `write-all` at the workflow level169- Third-party actions without a pinned commit SHA when `security level = strict`170- Secrets passed via `env:` at the workflow level (must be job- or step-scoped)171- `actions/checkout@v4` followed by running untrusted scripts before any allowlist check172173## Phase 4 — Generate Workflow YAML174175Emit the YAML in this skeleton, populated from the language-specific reference:176177```yaml178name: ci179on:180 push:181 branches: [main]182 pull_request:183 branches: [main]184185permissions:186 contents: read187188concurrency:189 group: ci-${{ github.ref }}190 cancel-in-progress: true191192jobs:193 meta:194 name: actionlint195 runs-on: ubuntu-latest196 steps:197 - uses: actions/checkout@v4198 - uses: rhysd/actionlint@v1 # pinned via SHA in `strict`199200 lint:201 needs: meta202 # populated from <language>.md203204 test:205 needs: meta206 # populated from <language>.md207 # includes: race flag, coverage gate, N+1 assertion, leak detection208209 security:210 needs: meta211 # populated from SECURITY_GATES.md per security-level212213 build:214 needs: [lint, test, security]215 # populated from <language>.md216```217218Per-language fully populated workflows (with matrix, cache, environment variables, and the canonical job graph) live in:219220- [references/GO.md](references/GO.md) — `actions/setup-go@v5`, `go test -race -cover -covermode=atomic`, `staticcheck`, `golangci-lint`, `govulncheck`, optional `goreleaser`221- [references/RUST.md](references/RUST.md) — `actions-rust-lang/setup-rust-toolchain@v1`, `Swatinem/rust-cache@v2`, `cargo fmt --check`, `cargo clippy -D warnings`, `cargo nextest`, `cargo-llvm-cov`, `cargo-audit`, `cargo-deny`222- [references/TYPESCRIPT.md](references/TYPESCRIPT.md) — `setup-bun` / `setup-node` + `pnpm/action-setup`, `tsc --noEmit`, `eslint`, `vitest`/`jest` with `--detectOpenHandles --detectLeaks`, N+1 query test template, `size-limit`223- [references/PYTHON.md](references/PYTHON.md) — `actions/setup-python@v5` / `astral-sh/setup-uv@v3` / `snok/install-poetry`, `ruff check`+`ruff format --check`, `mypy --strict`/`pyright`, `pytest --cov-fail-under`, `bandit`+`pip-audit`+`safety`, N+1 templates (Django `assertNumQueries` / SQLAlchemy event listener), free-threaded race (`python3.14t` + hypothesis), optional PyPI trusted publishing224225Always pin third-party actions:226227- `standard` level: `@vN` major-version pin228- `strict` level: full commit SHA pin (`@<40-char-sha>`) with a comment naming the version229230## Phase 5 — Validation & Dry-Run231232Before reporting success, run the local checks:233234```bash235# 1. Lint the YAML236actionlint .github/workflows/*.yml237yamllint -d relaxed .github/workflows/*.yml238239# 2. Confirm secrets referenced in the YAML240grep -hoE '\$\{\{ secrets\.[A-Z_]+ \}\}' .github/workflows/*.yml | sort -u241242# 3. Verify all third-party actions are pinned243grep -hE 'uses: ' .github/workflows/*.yml | grep -v 'actions/' | grep -v '@[a-f0-9]\{40\}\|@v[0-9]'244245# 4. List required workflows for branch protection246grep -E '^ [a-z_-]+:$' .github/workflows/ci.yml | sed 's/[: ]//g'247```248249Each finding is added to the post-generation report. If `actionlint` reports errors, abort and emit the diff for the user instead of writing the file.250251The full validation matrix and the optional `gh workflow run --ref <branch> ci.yml` smoke test are in [references/CHECKLIST.md](references/CHECKLIST.md).252253## Phase 6 — Deliver2542551. Write the workflow file(s) to `.github/workflows/`. Default filename: `ci.yml`. Optional: `release.yml`, `nightly-load.yml`.2562. Write `.github/dependabot.yml` if Phase 1 enabled it.2573. Emit the generation report (see Output format).2584. Surface the suggested branch protection rules — do not apply them automatically. Provide the `gh` command the user can run.2595. Hand off to `@github-commit` to commit the new files; do not commit unless the user explicitly approves.260261A worked end-to-end run of Phase 0 → Phase 6 for a Go API project is in [EXAMPLE.md](EXAMPLE.md).262263## Audit mode (alternate entry)264265When the user asks to **audit** an existing pipeline rather than generate one, branch at the very top of Phase 0 into the audit procedure documented in [references/AUDIT.md](references/AUDIT.md). The audit walks Phase A0 → A5 (inventory → heuristic compliance → security gate compliance → anti-pattern sweep → action freshness → caching/concurrency hygiene) and emits a severity-ranked findings table with fix proposals.266267The audit is **read-only by default**. The user can opt in per finding ID for the skill to apply unified-diff fixes; each fix is tagged **SAFE** / **REVIEW** / **BREAKING** and re-validated with `actionlint` before report-ok. The skill never commits.268269Pick the entry point by user intent:270271| Intent signal | Entry |272| --- | --- |273| "criar CI", "gerar pipeline", "scaffold workflow", `/ci-cd-generator` on a repo with no `.github/workflows/` | Phase 0 (generation) |274| "auditar pipeline", "audit CI", "review existing workflow", `/ci-cd-generator` on a repo with workflows present | Phase A0 (audit) |275| Ambiguous and `.github/workflows/` exists | Ask once: "audit existing workflows or generate a new baseline alongside?" — do not assume |276277## Constraints278279- **Never** commit the generated YAML without explicit user approval — emit the diff first280- **Never** apply branch protection rules without an explicit `gh api` call confirmed by the user281- **Never** emit `pull_request_target` with PR-head checkout282- **Never** default `permissions:` to `write-all` at workflow level — start at `contents: read` and elevate per job283- **Never** pass secrets via the workflow-level `env:`; scope them to the job or step284- **Never** use third-party actions without a version pin (major tag minimum, SHA in `strict`)285- **Never** generate a pipeline for a language outside `{go, rust, typescript, python}` — abort with a one-line notice286- **Never** silently downgrade the security level when a tool is missing — surface the gap to the user287- **Must** load the matching language reference before emitting any YAML288- **Must** run `actionlint` on the generated file before reporting success289- **Must** include a header comment listing required secrets, the trigger graph, and the source skill290- **Must** keep the workflow under 500 lines per file; split into `ci.yml` + `release.yml` + `nightly-load.yml` when needed291- **Must not** invent secrets or repository variables — every `${{ secrets.X }}` reference must be listed in the report292293## Output format294295Generation report (printed verbatim after every successful run):296297```text298ci-cd-generator: <action>299 language: <go | rust | typescript | python>300 runtime/pm: <node+pnpm | bun | rust+nextest | go+toolchain x.y | python+uv | python+poetry | python+pip>301 framework: <fastapi | django | flask | n/a> # python only302 security: <minimal | standard | strict>303 workflows: <files written, paths under .github/>304 jobs: <ordered list of job ids in ci.yml>305 required-secrets: <SECRET_A, SECRET_B, … or "none">306307Suggested branch protection (run after committing):308 gh api -X PUT repos/<owner>/<repo>/branches/main/protection \309 -F required_status_checks.strict=true \310 -F 'required_status_checks.contexts[]=lint' \311 -F 'required_status_checks.contexts[]=test' \312 -F 'required_status_checks.contexts[]=security' \313 -F enforce_admins=true \314 -F required_pull_request_reviews.required_approving_review_count=1315316Next: review the diff, then `/valarmindskills:github-commit`.317```318319## Related Skills320321- `@github-commit` — commit the generated workflow files following Conventional Commits322- `@github-release-note` — generate release notes when the release workflow tags a version323- `@github-pr-review` — review the diff that introduces the workflow324- `@clean-code` — apply principles to the YAML (consistent naming, no duplication across jobs)325- `@code-security-review` — multi-stack security review job covering generic flows + Go (Gin/Fiber, `references/golang/`) + Next.js 16 App Router (`references/nextjs/`); active testing via `references/TESTING_PHASES.md`, run nightly via the load testing slot; 100-vuln class catalog via `references/WEB_VULNERABILITIES.md` when the pipeline must spell out which classes each gate addresses326- `@code-debugger` — diagnosing a failing generated workflow before reporting it as broken327328## References329330- [GO](references/GO.md) — Go pipeline template, tooling matrix, canonical workflow331- [RUST](references/RUST.md) — Rust pipeline template, tooling matrix, canonical workflow332- [TYPESCRIPT](references/TYPESCRIPT.md) — TypeScript pipeline template (Node + Bun), N+1 and leak templates333- [PYTHON](references/PYTHON.md) — Python 3.13/3.14 pipeline template (FastAPI / Django / Flask), uv/poetry/pip PM detection, N+1 templates, free-threaded race testing, PyPI trusted publishing334- [USER_HEURISTICS](references/USER_HEURISTICS.md) — coverage gate, N+1, race PBT, leak detection, load testing — rationale and snippets335- [SECURITY_GATES](references/SECURITY_GATES.md) — SAST, SCA, container, SBOM, secret scan, license — per-language tool matrix336- [CHECKLIST](references/CHECKLIST.md) — post-generation validation, branch protection, smoke test337- [AUDIT](references/AUDIT.md) — audit mode procedure, detection rules, severity matrix, report format, opt-in fix application338- [EXAMPLE](EXAMPLE.md) — end-to-end worked example for a Go API project