Skip to content

chore: consolidate 37 workflows → 23 (behaviour-preserving)#258

Merged
hyperpolymath merged 1 commit into
mainfrom
chore/consolidate-workflows
May 16, 2026
Merged

chore: consolidate 37 workflows → 23 (behaviour-preserving)#258
hyperpolymath merged 1 commit into
mainfrom
chore/consolidate-workflows

Conversation

@hyperpolymath

Copy link
Copy Markdown
Owner

Summary

Consolidates the GitHub Actions workflow set from 37 → 23 files,
behaviour-preserving: every job is retained, every job's name: is
kept stable, every on: trigger is preserved (unioned, never narrowed),
and every required estate gate stays an independent, identically-named
status check. Nothing is deleted in the sense of "a check stops running" —
jobs are moved into fewer files, not removed.

Do not merge — the parent session controls merges.

OLD → NEW mapping

OLD file(s) NEW file Notes
rust.yml + rust-ci.yml rust.yml rust-ci's check/test job keys → rustci_check/rustci_test (names "Cargo check + clippy + fmt" / "Cargo test" unchanged); needs: rewired
security.yml + security-audit.yml security.yml duplicate job keys from security-audit prefixed audit_* (names "Security Audit Summary" etc. unchanged); needs: + ${{ needs.* }} rewired
scorecard.yml + scorecard-enforcer.yml scorecard.yml jobs analysis + scorecard + check-critical all retained
npm-bun-blocker.yml + ts-blocker.yml language-blockers.yml ts-blocker checkts_check
verify-idris.yml + verify-lean.yml + verify-tlaplus.yml verify-proofs.yml jobs type-check / lake-build / tlc retained; path filters unioned
e2e.yml + integration.yml + stress-test.yml + bench.yml tests.yml all 11 jobs retained
mirror.yml + instant-sync.yml + boj-build.yml mirror-sync.yml all 9 jobs retained
docs.yml + quality.yml docs-quality.yml all 6 jobs retained
cflite_pr.yml + cflite_batch.yml clusterfuzzlite.yml jobs pr-fuzzing + batch-fuzzing
release.yml + container.yml release.yml container's build-and-push job retained

Untouched / kept standalone (13): ci.yml, codeql.yml, dogfood-gate.yml,
hypatia-scan.yml, secret-scanner.yml, rsr-antipattern.yml,
guix-nix-policy.yml, security-policy.yml, workflow-linter.yml,
wellknown-enforcement.yml, hypatia-remediation-sweep.yml,
dependabot-automerge.yml, build-gossamer-gui.yml.

Required gates preserved (independent, stable check names)

Each remains its own workflow file with an unchanged name::

  • codeql.yml :: CodeQL Security Analysis
  • hypatia-scan.yml :: Hypatia Security Scan
  • dogfood-gate.yml :: Dogfood Gate
  • secret-scanner.yml :: Secret Scanner
  • rsr-antipattern.yml :: RSR Anti-Pattern Check
  • guix-nix-policy.yml :: Guix/Nix Package Policy
  • security-policy.yml :: Security Policy
  • workflow-linter.yml :: Workflow Security Linter
  • wellknown-enforcement.yml :: Well-Known Standards (RFC 9116 + RSR)

(CodeQL/secret/SBOM SAST jobs that also live inside security.yml are kept
as additional jobs there — the dedicated codeql.yml / secret-scanner.yml
gate workflows are NOT folded in.)

Job-name preservation was verified mechanically: 91 distinct original job
names → 92 current → 0 missing
(the +1 is two previously-anonymous check
keys surfacing distinct names after key-prefixing; no behaviour change).

Concurrency additions

concurrency: { group: ${{ github.workflow }}-${{ github.ref }}, cancel-in-progress: true } added to push/PR check workflows:
rust.yml, security.yml, language-blockers.yml, verify-proofs.yml,
tests.yml, docs-quality.yml.

Deliberately omitted (per estate template — no cancel-in-progress on
release/publish/scheduled/security-upload): scorecard.yml,
clusterfuzzlite.yml, release.yml, mirror-sync.yml.

Validation

$ python3 -c "import yaml,glob; [yaml.safe_load(open(f)) for f in glob.glob('.github/workflows/*.y*ml')]; print(len(glob.glob('.github/workflows/*.y*ml')),'workflows, yaml ok')"
23 workflows, yaml ok

All 23 resulting files yaml.safe_load cleanly. No pre-existing PyYAML
quirks needed working around.

Deliberately NOT merged (and why)

  • The required estate gate workflows (codeql, hypatia-scan, dogfood-gate,
    secret-scanner, rsr-antipattern, guix-nix-policy, security-policy,
    workflow-linter, wellknown-enforcement) were left as their own files so
    their status-check names stay stable and independently required.
  • ci.yml (multi-language umbrella CI), hypatia-remediation-sweep.yml
    (scheduled fleet sweep), dependabot-automerge.yml (PR automation),
    build-gossamer-gui.yml (distinct toolchain build) kept standalone —
    no meaningful overlap with other files.
  • No V-lang / ban-enforcement assets were touched.

Behaviour note

For grouped workflows, on: triggers are the union of the sources, so a
consolidated workflow may now trigger on a superset of events (e.g.
verify-proofs.yml runs all three proof jobs when any proof tree changes,
where previously each had its own path-filtered workflow). This only ever
causes a gate to run more often, never less — no check or trigger is lost.
Path/branch filters are unioned, not dropped, so unrelated pushes still do
not trigger.

🤖 Generated with Claude Code

Merge overlapping/duplicate GitHub Actions workflows into fewer multi-job
files without losing any check or gate. Every job's `name:` is preserved;
colliding job KEYS are namespaced (and their `needs:` / `${{ needs.* }}`
references rewritten) so no status check is renamed or hidden. All required
estate gate workflows remain independent, identically-named status checks.

- rust.yml      ← rust.yml + rust-ci.yml
- security.yml  ← security.yml + security-audit.yml
- scorecard.yml ← scorecard.yml + scorecard-enforcer.yml
- language-blockers.yml ← npm-bun-blocker.yml + ts-blocker.yml
- verify-proofs.yml ← verify-idris.yml + verify-lean.yml + verify-tlaplus.yml
- tests.yml     ← e2e.yml + integration.yml + stress-test.yml + bench.yml
- mirror-sync.yml ← mirror.yml + instant-sync.yml + boj-build.yml
- docs-quality.yml ← docs.yml + quality.yml
- clusterfuzzlite.yml ← cflite_pr.yml + cflite_batch.yml
- release.yml   ← release.yml + container.yml

`on:` triggers are unioned (superset — no trigger lost). A concurrency
block is added to push/PR check workflows; release/publish/scheduled and
security-upload workflows are deliberately left without cancel-in-progress.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
@hyperpolymath
hyperpolymath merged commit c2c0ae2 into main May 16, 2026
33 of 38 checks passed
@hyperpolymath
hyperpolymath deleted the chore/consolidate-workflows branch May 16, 2026 15:25
hyperpolymath added a commit that referenced this pull request Jun 25, 2026
)

**Root cause of the undefined `env.REGISTRY`/`env.IMAGE_NAME`:** the
v1.0 commit `0d310fa` had the top-level `env:` block, but the
workflow-consolidation PR #258 (*'consolidate 37 workflows → 23,
behaviour-preserving'*) moved the container jobs from `container.yml`
into `release.yml` **without carrying the `env:` block** — and `env:` is
file-scoped, so it didn't travel with the moved jobs. The vars went
undefined, breaking ghcr login, metadata/push tags, and the attest
subject-name. So it *was* fixed before; the consolidation regressed it.
Restores the original `REGISTRY: ghcr.io` / `IMAGE_NAME: ${{
github.repository }}`. 🤖 Generated with [Claude
Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
hyperpolymath added a commit that referenced this pull request Jul 17, 2026
)

## Problem

`release.yml` still built a **four-image** container matrix
(`cli`/`adapter`/`registry`/`engine`) plus a Haskell build+publish
pipeline — but three of those were retired:
- `deploy/Containerfile.{adapter,registry,engine}` were deleted
(`1103e4d`)
- the Haskell `registry/` and Logtalk `engine/` sources were removed
(`f2fe2df`)

So `build-and-push` and `build-docker` fail on `open
Containerfile.engine: no such file or directory`, and `build-haskell` /
`publish-hackage` run `cabal` against a `registry/` that no longer
exists.

**Logtalk** (the SWI-Prolog rule engine) and the **Haskell rule
registry** were early designs, since **superseded by the native Elixir
ruleset** (confirmed by the owner).

## Change

- Drop the `build-haskell` and `publish-hackage` jobs.
- Scope both container matrices (`build-docker`, `build-and-push`) to
**`cli`**.
- Drop `build-haskell` from the `build-docker` / `github-release`
`needs`.
- Fix the GitHub-release notes: drop the Registry/Engine components +
their `docker pull` lines; keep **Adapters** (`forge-adapter` still
ships as a binary in the release archives via `build-rust`).

**The adapter's Rust code is not dead** — only its *service image* was
retired; it's still built and shipped as a binary. Recover its image
anytime with `git show f2fe2df^:deploy/Containerfile.adapter`.

Net **−113/+18** lines.

## Scope notes

- Pre-existing dangling `inputs.dry_run` / `inputs.version` references
(from the #258 "consolidate 37 → 23 workflows" merge — no
`workflow_dispatch.inputs` block defines them) are **left untouched**
here; they're a separate correctness fix (the dry-run guard currently
never engages).
- `build-docker` and `build-and-push` are near-duplicate container jobs
(release semver vs per-push dev); consolidating them is also left for a
follow-up.
- Broader expunge of stale **Logtalk/SWI-Prolog** references elsewhere
in the repo (docs, substrate, paper) is being triaged separately — not
bundled here.

## Validation (run, not asserted)

- `actionlint`: my edits introduce **zero** new findings and remove two
(the deleted `build-haskell` job's SC2046/SC2035). Remaining findings
are all pre-existing on `main`.
- No `needs:` references a removed job; final jobs: `prepare`,
`build-rust`, `build-docker`, `github-release`, `build-and-push`.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-authored-by: Claude Opus 4.8 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant