diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index b203334..7c04b4e 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -5,7 +5,7 @@ # It is a no-op if BOJ_SERVER_URL is not set or the server is unreachable. # To enable: set BOJ_SERVER_URL as a repository secret or variable. # To disable: delete this file or leave BOJ_SERVER_URL unset. -name: BoJ Server Build Trigger +name: "⚙ Auto: BoJ server build trigger" on: push: branches: [main, master] diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 349b19f..894cafb 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: CodeQL Security Analysis +name: "🟡 Check: CodeQL security analysis" on: push: branches: [main, master] diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index bce3810..4a79b0d 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -34,7 +34,7 @@ # Dependabot config via the github-actions ecosystem block, so SHA # bumps for dependabot/fetch-metadata flow through the same path. -name: Dependabot Auto-Merge +name: "⚙ Auto: Dependabot auto-merge" on: pull_request: types: [opened, reopened, synchronize] diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index 523b590..a902e8a 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -4,7 +4,7 @@ # dogfood-gate.yml — Hyperpolymath Dogfooding Quality Gate # Validates that the repo uses hyperpolymath's own formats and tools. # Companion to static-analysis-gate.yml (security) — this is for format compliance. -name: Dogfood Gate +name: "🟡 Check: RSR self-use (dogfooding)" on: pull_request: @@ -261,31 +261,16 @@ jobs: echo "has_manifest=true" >> "$GITHUB_OUTPUT" - # Validate TOML structure using Python 3.11+ tomllib - python3 -c " -import tomllib, sys -with open('eclexiaiser.toml', 'rb') as f: - data = tomllib.load(f) -project = data.get('project', {}) -if not project.get('name', '').strip(): - print('ERROR: project.name is required', file=sys.stderr) - sys.exit(1) -functions = data.get('functions', []) -if not functions: - print('ERROR: at least one [[functions]] entry is required', file=sys.stderr) - sys.exit(1) -for fn in functions: - if not fn.get('name', '').strip(): - print('ERROR: function name cannot be empty', file=sys.stderr) - sys.exit(1) - if not fn.get('source', '').strip(): - print(f'ERROR: function {fn[\"name\"]} has no source path', file=sys.stderr) - sys.exit(1) -print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') -" || { - echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml — see step output for details" - exit 1 - } + # Validate eclexiaiser.toml structure (bash + grep; no Python — estate no-Python rule). + ok=1 + grep -qE '^[[:space:]]*name[[:space:]]*=[[:space:]]*"[^"]+"' eclexiaiser.toml || { echo "::error::project.name is required"; ok=0; } + nfun=$(grep -cE '^[[:space:]]*\[\[functions\]\]' eclexiaiser.toml || true) + [ "${nfun:-0}" -ge 1 ] || { echo "::error::at least one [[functions]] entry is required"; ok=0; } + nname=$(grep -cE '^[[:space:]]*name[[:space:]]*=[[:space:]]*"[^"]+"' eclexiaiser.toml || true) + nsrc=$(grep -cE '^[[:space:]]*source[[:space:]]*=[[:space:]]*"[^"]+"' eclexiaiser.toml || true) + [ "${nname:-0}" -ge "$(( ${nfun:-0} + 1 ))" ] || { echo "::error::a function has an empty or missing name"; ok=0; } + [ "${nsrc:-0}" -ge "${nfun:-0}" ] || { echo "::error::a function has an empty or missing source"; ok=0; } + if [ "$ok" = 1 ]; then echo "Valid: eclexiaiser.toml (${nfun:-0} function(s))"; else echo "::error file=eclexiaiser.toml::Invalid eclexiaiser.toml"; exit 1; fi - name: Write summary run: | diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 5cac223..0b1cd64 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -12,7 +12,7 @@ # INSTRUCTIONS: Uncomment and customise the section matching your stack. # Delete sections that don't apply. See examples in each job. -name: E2E + Aspect + Bench +name: "🟡 Check: E2E + aspect + bench" on: push: branches: [main, master, develop] diff --git a/.github/workflows/estate-rules.yml b/.github/workflows/estate-rules.yml index d85b7ab..1da5c31 100644 --- a/.github/workflows/estate-rules.yml +++ b/.github/workflows/estate-rules.yml @@ -9,7 +9,7 @@ # Each rule is enforced by an executable check script under scripts/. Failures # are surfaced as workflow errors so the rule can't silently regress. -name: Estate Rules +name: "🟡 Check: Estate rules" on: push: branches: [main] diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 8161ec2..b572da4 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: PMPL-1.0-or-later -name: Governance +name: "🟡 Check: Governance metadata" on: push: diff --git a/.github/workflows/guix-nix-policy.yml b/.github/workflows/guix-nix-policy.yml index 3d78b73..ac5e0f8 100644 --- a/.github/workflows/guix-nix-policy.yml +++ b/.github/workflows/guix-nix-policy.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: Guix/Nix Package Policy +name: "🔴 Gate: Guix-only package policy" on: push: branches: [main, master] diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index e715848..1109e36 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: PMPL-1.0-or-later -name: Hypatia Security Scan +name: "🟡 Check: Hypatia baseline security scan" on: push: diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 0994325..9dbd3f4 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MPL-2.0 # Instant Forge Sync - Triggers propagation to all forges on push/release -name: Instant Sync +name: "⚙ Auto: Instant sync" on: push: branches: [main, master] diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index fcff1f2..fd3f7a0 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: Mirror to Git Forges +name: "⚙ Auto: Mirror to forges" on: push: branches: [main] diff --git a/.github/workflows/npm-bun-blocker.yml b/.github/workflows/npm-bun-blocker.yml index 153b39d..6e1ba52 100644 --- a/.github/workflows/npm-bun-blocker.yml +++ b/.github/workflows/npm-bun-blocker.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: NPM/Bun Blocker +name: "🔴 Gate: No-npm/bun policy" on: push: branches: [main, master] diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index d688426..b8e58d6 100644 --- a/.github/workflows/openssf-compliance.yml +++ b/.github/workflows/openssf-compliance.yml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MPL-2.0 # OpenSSF Best Practices compliance gate — blocks PRs and pushes that lack # required files or still contain unfilled placeholder tokens. -name: OpenSSF Compliance +name: "🟡 Check: OpenSSF best-practices" on: push: branches: [main] diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 3537517..516d512 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: Code Quality +name: "🔴 Gate: Code quality (fmt/lint/test)" on: push: branches: [main, master] diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0b50929..9ad2b8d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -4,7 +4,7 @@ # Release workflow — triggered by version tags (v*). # Builds artifacts, generates changelog via git-cliff, creates a GitHub Release, # and produces SLSA provenance attestations. -name: Release +name: "⚙ Auto: Release" on: push: tags: diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index d020405..0f679dc 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -10,7 +10,7 @@ # # Runs weekly and on Hypatia scan completion. -name: "\U0001F916 Rhodibot — RSR Auto-Fix" +name: "⚙ Auto: Rhodibot RSR auto-fix" on: schedule: - cron: '0 6 * * 1' # Every Monday at 06:00 UTC diff --git a/.github/workflows/rsr-antipattern.yml b/.github/workflows/rsr-antipattern.yml index 2df4715..bae04c6 100644 --- a/.github/workflows/rsr-antipattern.yml +++ b/.github/workflows/rsr-antipattern.yml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MPL-2.0 # RSR Anti-Pattern Check - Uses reusable workflow from standards -name: RSR Anti-Pattern Check +name: "🔴 Gate: RSR anti-pattern scan" on: push: branches: [main, master, develop] diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 875d30a..c210ce2 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -2,7 +2,7 @@ # Rust CI — thin wrapper calling the shared estate reusable in # hyperpolymath/standards. Configure once, propagate everywhere. # See: docs/CI-REUSABLE-WORKFLOWS.adoc in standards. -name: Rust CI +name: "🟡 Check: Rust CI (build/test)" on: push: branches: [main, master] diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 47acbb5..6cd3aa8 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: PMPL-1.0-or-later -name: OSSF Scorecard +name: "⚪ Advisory: OpenSSF Scorecard (score)" on: push: diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 10729d0..c61fb2d 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: Secret Scanner +name: "🔴 Gate: Secret scan" on: pull_request: push: diff --git a/.github/workflows/security-policy.yml b/.github/workflows/security-policy.yml index deafd84..c244ff2 100644 --- a/.github/workflows/security-policy.yml +++ b/.github/workflows/security-policy.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: Security Policy +name: "🔴 Gate: Security policy present" on: push: branches: [main, master] diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index 8bd1606..1ecc46b 100644 --- a/.github/workflows/static-analysis-gate.yml +++ b/.github/workflows/static-analysis-gate.yml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MPL-2.0 # Static Analysis Gate — Required by branch protection rules. # Runs panic-attack and hypatia, deposits findings for gitbot-fleet learning. -name: Static Analysis Gate +name: "🔴 Gate: Static analysis" on: pull_request: branches: ['**'] diff --git a/.github/workflows/trope-check.yml b/.github/workflows/trope-check.yml index 3c9a1ae..528481a 100644 --- a/.github/workflows/trope-check.yml +++ b/.github/workflows/trope-check.yml @@ -2,7 +2,7 @@ # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # Haec: every example lowers to a well-formed Trope IR document (bash + jq, no Python). -name: trope-check +name: "🔴 Gate: Trope conformance" on: push: paths: ['design/**', 'examples/**', 'tests/**', '.github/workflows/trope-check.yml'] diff --git a/.github/workflows/ts-blocker.yml b/.github/workflows/ts-blocker.yml index 9c6e204..4c298c2 100644 --- a/.github/workflows/ts-blocker.yml +++ b/.github/workflows/ts-blocker.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: TypeScript/JavaScript Blocker +name: "🔴 Gate: No-TypeScript policy" on: push: branches: [main, master] diff --git a/.github/workflows/wellknown-enforcement.yml b/.github/workflows/wellknown-enforcement.yml index 088e617..67eb4f4 100644 --- a/.github/workflows/wellknown-enforcement.yml +++ b/.github/workflows/wellknown-enforcement.yml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -name: Well-Known Standards (RFC 9116 + RSR) +name: "🔴 Gate: .well-known / RFC 9116" on: push: branches: [main, master] diff --git a/.github/workflows/workflow-linter.yml b/.github/workflows/workflow-linter.yml index f260470..c9848fa 100644 --- a/.github/workflows/workflow-linter.yml +++ b/.github/workflows/workflow-linter.yml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MPL-2.0 # workflow-linter.yml - Validates GitHub workflows against RSR security standards # This workflow can be copied to other repos for consistent enforcement -name: Workflow Security Linter +name: "🟡 Check: Workflow security lint" on: push: diff --git a/ci/CI-CRITICALITY.toml b/ci/CI-CRITICALITY.toml new file mode 100644 index 0000000..2d336d0 --- /dev/null +++ b/ci/CI-CRITICALITY.toml @@ -0,0 +1,52 @@ +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) +# SPDX-License-Identifier: MPL-2.0 +# +# CI criticality tiers — the source of truth for what blocks a merge (pilot). +# Workflow name: fields carry the same glyph so the GitHub checks list is self-sorting. +# 🔴 Gate (must) — pass-or-die; merge-blocking; SET THESE AS BRANCH-PROTECTION REQUIRED CHECKS. +# 🟡 Check (should) — important; reviewed; waivable on purpose. +# ⚪ Advisory (could)— a score / deep / experimental pass; skippable in a rush. +# ⚙ Auto — not a gate; a side-effecting job. + +[meta] +scheme = "Gate / Check / Advisory / Auto (must / should / could / automation)" +pilot = true +note = "Pilot in the three trope repos; promote to standards + rsr-template once proven." + +# 🔴 Gate — must pass (branch-protection required checks) +[gate] +"guix-nix-policy" = "Guix-only package policy — Nix banned; Guix only" +"npm-bun-blocker" = "No-npm/bun policy — banned toolchain = do not ship" +"quality" = "Code quality (fmt/lint/test) — formatting/lint/tests must pass" +"rsr-antipattern" = "RSR anti-pattern scan — structural anti-patterns block merge" +"secret-scanner" = "Secret scan — leaked secret = do not ship" +"security-policy" = "Security policy present — SECURITY.md must exist" +"static-analysis-gate" = "Static analysis — static-analysis gate must pass" +"trope-check" = "Trope conformance — IR schema + verified core + conformance" +"ts-blocker" = "No-TypeScript policy — banned language = do not ship" +"wellknown-enforcement" = ".well-known / RFC 9116 — security.txt + RSR well-known" + +# 🟡 Check — should pass +[check] +"codeql" = "CodeQL security analysis — findings reviewed, not auto-blocking" +"dogfood-gate" = "RSR self-use (dogfooding) — repo uses its own RSR tooling" +"e2e" = "E2E + aspect + bench — integration; may be skipped in a rush" +"estate-rules" = "Estate rules — estate conventions" +"governance" = "Governance metadata — governance docs present" +"hypatia-scan" = "Hypatia baseline security scan — baseline scan (deep neurosymbolic = advisory, in standards)" +"openssf-compliance" = "OpenSSF best-practices — should pass; waivable on review" +"rust-ci" = "Rust CI (build/test) — Rust build + test" +"workflow-linter" = "Workflow security lint — workflow hygiene" + +# ⚪ Advisory — could skip in a rush +[advisory] +"scorecard" = "OpenSSF Scorecard (score) — a score, not a gate" + +# ⚙ Auto — not a gate +[automation] +"boj-build" = "BoJ server build trigger — side-effect: triggers a build" +"dependabot-automerge" = "Dependabot auto-merge — side-effect: merges dep PRs" +"instant-sync" = "Instant sync — side-effect: sync" +"mirror" = "Mirror to forges — side-effect: pushes mirrors" +"release" = "Release — side-effect: cuts releases" +"rhodibot" = "Rhodibot RSR auto-fix — side-effect: auto-fix bot"