Dictum: Workflow generation and validation enforce security, performance, and supply chain integrity.
Generate and validate production-ready GitHub Actions workflows and custom actions.
Tasks:
- Gather requirements — triggers, runners, dependencies, environments, security posture.
- Read best-practices.md — security hardening, supply chain, performance, anti-patterns.
- Read version-discovery.md — SHA resolution protocol, action index, permissions.
- Read expressions-and-contexts.md — contexts, functions, injection prevention.
- (advanced triggers) Read advanced-triggers.md — workflow_run, dispatch, ChatOps, merge queue.
- (custom actions) Read custom-actions.md — composite, Docker, JavaScript action authoring.
- Resolve action versions —
git ls-remote, Context7 MCP, or WebSearch for latest SHA. - Generate — SHA-pinned actions, minimal permissions, concurrency, caching, timeouts, harden-runner.
- Validate — Read validation references, run actionlint, apply 11 best practice checks.
- Fix and re-validate until passing (max 3 iterations).
Scope:
- Workflow files (
.github/workflows/*.yml). - Custom actions — composite, Docker, JavaScript (
.github/actions/*/action.yml). - Reusable workflows (
workflow_call). - Supply chain — SLSA attestation, SBOM, Cosign signing.
- Monorepo CI — Nx affected detection, sparse checkout, pnpm workspace caching.
References:
| Domain | File |
|---|---|
| Best Practices | best-practices.md |
| Version Discovery | version-discovery.md |
| Expressions | expressions-and-contexts.md |
| Advanced Triggers | advanced-triggers.md |
| Custom Actions | custom-actions.md |
| Common Errors | common_errors.md |
| Supply Chain | supply_chain.md |
| Modern Features | modern_features.md |
| Runners | runners.md |
| Actionlint + Act | act_usage.md |
| Template | basic-workflow.template.yml |
| Template | reusable-workflow.template.yml |
| Template | composite-action.template.yml |
| Template | docker-action.template.yml |
| Template | javascript-action.template.yml |
| Example | nodejs-ci.yml |
| Example | docker-build-push.yml |
| Example | monorepo-ci.yml |
| Example | dependency-review.yml |
| Example | sbom-attestation.yml |
| Example | setup-node-cached-action.yml |
| Example | chatops-dispatch.yml |
| Example | oidc-cloud-auth-action.yml |
| Example | release-deploy.yml |
| Example | docker-lint-scan-action.yml |
| Example | pr-change-router-action.yml |
[1][STANDARDS]
Dictum: Mandatory standards enforce baseline quality across all generated workflows.
Every generated workflow enforces defense-in-depth: supply chain integrity prevents compromised actions from executing, minimal permissions limit blast radius if a job is compromised, and harden-runner detects anomalous behavior at runtime. These layers are independent — failure of one leaves others intact.
[CRITICAL]:
- [ALWAYS] SHA-pin every
uses:reference — mutable tags (@v1,@main) enable supply chain attacks. The tj-actions incident (CVE-2025-30066) compromised 23,000+ repos via tag retargeting. - [ALWAYS]
step-security/harden-runneras first step in every job — detected the tj-actions breach before any other tool. - [ALWAYS] Top-level
permissions: {}(deny-all default); grant minimal per-job permissions. - [ALWAYS]
timeout-minutes:on every job — prevents runaway billing on stuck workflows.
[IMPORTANT]:
- [ALWAYS] OIDC federation (
id-token: write) for cloud auth — eliminates static credentials entirely. - [ALWAYS]
actions/create-github-app-tokenfor cross-repo ops — scoped, 1-hour expiry, survives offboarding. - [ALWAYS]
>> $GITHUB_OUTPUTfor step outputs;>> $GITHUB_STEP_SUMMARYfor job summaries. - [NEVER] Direct
${{ }}interpolation of untrusted input inrun:blocks — route throughenv:indirection.
[REFERENCE] best-practices.md — Security checklist, supply chain controls, anti-patterns.
[2][TEMPLATES]
Dictum: Templates scaffold canonical workflow and action structure.
Templates use [PLACEHOLDER] syntax for generation-time substitution. SHA resolution happens at generation time via the discovery protocol — templates contain placeholder SHAs, not static pins.
[2.1][PLACEHOLDER_CONVENTION]
All templates use a unified [UPPER_SNAKE_CASE] placeholder convention:
| [CATEGORY] | [PLACEHOLDERS] |
|---|---|
| Identity | [ACTION_NAME], [WORKFLOW_NAME], [DESCRIPTION], [AUTHOR_NAME] |
| Runtime | [RUNTIME_VERSION], [RUNTIME_ENV_KEY], [ENABLE_CMD] |
| Package Mgr | [PACKAGE_MANAGER], [INSTALL_CMD] |
| Build/Test | [BUILD_CMD], [LINT_CMD], [TEST_CMD], [BUILD_PATH], [RESULTS_PATH] |
| Deploy | [ENV_NAME], [ENV_URL], [DEPLOY_CMD], [VERIFY_CMD] |
| Secrets | [SECRET_KEY], [SECRET_NAME], [REGISTRY_TOKEN] |
| Docker | [BASE_IMAGE], [BUILDER_IMAGE], [ENTRYPOINT] |
[2.2][HARDEN_RUNNER_SCOPE]
harden-runner is included as the first step in every workflow job template (basic, reusable). Action templates (composite, Docker, JavaScript) do NOT include harden-runner — the calling workflow is responsible for adding it as the first step in the job that invokes the action. Actions are steps, not jobs.
[2.3][TEMPLATE_INDEX]
| [INDEX] | [TEMPLATE] | [PATH] | [SCAFFOLDS] |
|---|---|---|---|
| [1] | Basic Workflow | templates/basic-workflow.template.yml |
CI pipeline: lint, test, build, deploy with parameterized runtime. |
| [2] | Reusable Workflow | templates/reusable-workflow.template.yml |
workflow_call with typed inputs, secrets, version extraction. |
| [3] | Composite Action | templates/composite-action.template.yml |
Multi-step action with parameterized runtime and error handling. |
| [4] | Docker Action | templates/docker-action.template.yml |
Container action with distroless multi-stage Dockerfile pattern. |
| [5] | JavaScript Action | templates/javascript-action.template.yml |
Node 24 action with pre/post lifecycle, typed error handling. |
[REFERENCE] custom-actions.md — Action type selection, metadata, runtime deprecation.
[3][EXAMPLES]
Dictum: Examples demonstrate production patterns for common scenarios.
Each example demonstrates distinct patterns with minimal overlap. Load relevant examples before generation to match the target scenario.
| [INDEX] | [EXAMPLE] | [PATH] | [DEMONSTRATES] |
|---|---|---|---|
| [1] | Node.js CI | examples/nodejs-ci.yml |
Matrix testing, caching, artifact upload, coverage, summaries. |
| [2] | Docker Build + Push | examples/docker-build-push.yml |
Multi-platform builds, GHCR, BuildKit caching, SLSA provenance. |
| [3] | Monorepo CI | examples/monorepo-ci.yml |
Nx affected detection, pnpm workspace, sparse checkout. |
| [4] | PR Security Gate | examples/dependency-review.yml |
Multi-job security: dep review, CodeQL, Gitleaks, triage. |
| [5] | Container Supply Chain | examples/sbom-attestation.yml |
SBOM, Trivy severity gating, Cosign, gh attestation verify. |
| [6] | Composite Action (setup-node-cached) | examples/setup-node-cached-action.yml |
Smart caching, corepack detection, cache-dir resolution. |
| [7] | ChatOps Dispatch | examples/chatops-dispatch.yml |
Slash commands, injection prevention, App token, env indirection. |
| [8] | Multi-Cloud OIDC Auth | examples/oidc-cloud-auth-action.yml |
Composite action: AWS/GCP/Azure OIDC, output normalization. |
| [9] | Release + Deploy | examples/release-deploy.yml |
Environment promotion, reusable workflow, concurrency groups. |
| [10] | Docker Lint + Scan | examples/docker-lint-scan-action.yml |
Composite action: Trivy scan, hadolint, SARIF output. |
| [11] | PR Change Router | examples/pr-change-router-action.yml |
Composite action: paths-filter, dynamic matrix, label sync. |
[4][ACTION_DISCOVERY]
Dictum: Runtime version resolution prevents stale SHA pins and supply chain drift.
Static SHA catalogs decay — actions release frequently and stale pins miss security patches. Resolve versions at generation time. Never embed hardcoded SHAs in reference docs or templates.
Resolution protocol:
git ls-remote --tags https://github.com/{owner}/{repo}— verify tag exists.gh api repos/{owner}/{repo}/git/ref/tags/{tag} --jq '.object.sha'— resolve tag to full SHA.- Format:
owner/repo@<40-char-SHA> # vX.Y.Z.
Fallback methods:
- Context7 MCP:
resolve-library-idthenget-library-docsfor action documentation. - WebSearch:
"[owner/repo] [version] github action"for release notes.
[IMPORTANT]:
- [ALWAYS] Verify the tag exists before pinning — deleted tags return empty results.
- [ALWAYS] Include version comment suffix (
# vX.Y.Z) — Dependabot/Renovate parse these for automated updates. - [NEVER] Embed static SHAs in reference files — they decay within weeks.
[REFERENCE] version-discovery.md — Discovery protocol, SHA pinning format, common actions index, automated maintenance.
[5][VALIDATION]
Dictum: Three-stage pipeline and 11 best practice checks gate workflow quality.
Validation pipeline:
| [INDEX] | [STAGE] | [TOOL] | [VALIDATES] |
|---|---|---|---|
| [1] | Static Analysis | actionlint 1.7.10 | YAML syntax, expressions, runner labels, action inputs, CRON, globs. |
| [2] | Best Practices | 11 custom checks | SHA pinning, permissions, injection, timeouts, harden-runner. |
| [3] | Local Execution | act v0.2.84 | Dry-run validation against Docker images (requires Docker). |
Best practice checks (11):
| [INDEX] | [CHECK] | [TAG] | [DETECTS] |
|---|---|---|---|
| [1] | Deprecated commands | [DEPRECATED-CMD] |
::set-output, ::save-state, ::set-env, ::add-path. |
| [2] | Missing permissions | [PERMISSIONS] |
No top-level permissions: {} deny-all default. |
| [3] | Unpinned actions | [UNPINNED] |
Mutable tags (@v1, @main), abbreviated SHAs. |
| [4] | SHA without comment | [SHA-NO-COMMENT] |
SHA-pinned but missing # vX.Y.Z version comment. |
| [5] | Missing timeout | [TIMEOUT] |
Jobs without timeout-minutes: (default is 6 hours). |
| [6] | Deprecated runners | [RUNNER] |
ubuntu-20.04, macos-12, macos-13, windows-2019. |
| [7] | Missing concurrency | [CONCURRENCY] |
No concurrency: group or missing cancel-in-progress. |
| [8] | PAT usage | [APP-TOKEN] |
PATs for cross-repo ops (use create-github-app-token). |
| [9] | No harden-runner | [HARDEN] |
Missing or not first step in job (CVE-2025-30066 detection). |
| [10] | Expression injection | [INJECTION] |
Direct ${{ github.event.* }} in run: blocks. |
| [11] | Immutable actions | [IMMUTABLE] |
Action publishing without immutable OCI (informational). |
Error routing: Match error patterns to reference files — common_errors.md (syntax, expressions, deprecated), runners.md (labels, deprecations), supply_chain.md (SHA, OIDC, SBOM, harden-runner), modern_features.md (reusable workflows, concurrency, matrix, node runtime), act_usage.md (actionlint rules, act limitations).
Troubleshooting:
| [INDEX] | [ISSUE] | [SOLUTION] |
|---|---|---|
| [1] | Tools not found | Install actionlint + act (see act_usage.md). |
| [2] | Docker not running | Start Docker or validate with actionlint only. |
| [3] | act fails, GitHub works | See act_usage.md — Limitations. |
| [4] | ARM Mac arch mismatch | Add --container-architecture linux/amd64. |
| [5] | Custom runner labels | Declare in .github/actionlint.yaml. |
[VERIFY] Completion:
- Supply chain: Every
uses:reference SHA-pinned with# vX.Y.Zcomment suffix. - Security: Top-level
permissions: {}, per-job minimal grants,harden-runnerfirst step. - Injection: No direct
${{ github.event.* }}inrun:blocks — all throughenv:indirection. - Performance: Caching enabled,
concurrencygroups set,timeout-minutes:on every job. - Structure: Descriptive
name:on workflow/jobs/steps, lowercase-hyphen filenames. - Outputs:
>> $GITHUB_OUTPUTfor data,>> $GITHUB_STEP_SUMMARYfor summaries. - Harden-runner: Workflow jobs include it; action templates note caller responsibility.
- All errors resolved with reference-backed fixes; warnings documented.
[REFERENCE] best-practices.md — Anti-patterns with specific remediations.