Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
79 changes: 79 additions & 0 deletions .githooks/validate-workflow-yaml.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,79 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: MPL-2.0
# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk>
#
# validate-workflow-yaml.sh — every .github/workflows/*.yml must PARSE.
#
# WHY THIS EXISTS
# ---------------
# A malformed workflow is not a red check. GitHub Actions rejects it at PARSE
# time, which produces zero jobs and NO CHECK RUN AT ALL — the gate silently
# ceases to exist while the board still reads green. `gh pr checks` shows
# nothing wrong. The only visible tell is that `gh run list` starts printing the
# workflow's PATH instead of its NAME.
#
# This repo has hit that twice in one day, from the same cause both times: a
# sweep that appends `actions: read` after every `permissions:` line. Four
# workflows declare permissions in the SCALAR form —
#
# permissions: read-all
#
# — and hanging a mapping key under a scalar is invalid YAML:
#
# permissions: read-all
# actions: read # "mapping values are not allowed here"
#
# It was fixed in PR #64 and reintroduced by PR #68, because the sweep matched
# `permissions:` as TEXT rather than as a YAML node. The insertion is redundant
# regardless: `read-all` already grants every read scope, `actions: read`
# included.
#
# So this check is deliberately dumb and total: parse every workflow, fail on
# any that does not. It cannot be satisfied by a sweep that only looks at text.

set -euo pipefail

cd "$(git rev-parse --show-toplevel 2>/dev/null || echo .)"

if ! command -v python3 >/dev/null 2>&1; then
echo "validate-workflow-yaml: python3 not found — cannot verify workflows" >&2
exit 1
fi

python3 - "$@" <<'PY'
import glob, sys

try:
import yaml
except ImportError:
print("validate-workflow-yaml: PyYAML not installed — cannot verify workflows",
file=sys.stderr)
sys.exit(1)

files = sorted(glob.glob(".github/workflows/*.yml") + glob.glob(".github/workflows/*.yaml"))
if not files:
print("validate-workflow-yaml: no workflow files found", file=sys.stderr)
sys.exit(1)

bad = []
for f in files:
try:
doc = yaml.safe_load(open(f))
except Exception as e:
bad.append((f, str(e).splitlines()[0]))
continue
# A workflow that parses but has no jobs is equally inert.
if not isinstance(doc, dict) or not doc.get("jobs"):
bad.append((f, "parses but declares no jobs — would run nothing"))

if bad:
print("ERROR: unparseable or inert workflow(s) — these produce NO check run,")
print(" not a red X, so CI would look green while the gate is dead:\n")
for f, err in bad:
print(f" {f}\n {err}")
print("\nIf this is `actions: read` under `permissions: read-all`, delete the")
print("added line: `read-all` already grants every read scope.")
sys.exit(1)

print(f"validate-workflow-yaml: all {len(files)} workflows parse and declare jobs")
PY
1 change: 0 additions & 1 deletion .github/workflows/container-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@
- '.github/workflows/container-build.yml'
workflow_dispatch:

permissions: read-all

Check warning on line 32 in .github/workflows/container-build.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "read-all" with specific permissions (e.g., "contents: read").

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_statistikles&issues=AZ-qDpciEgyOKRdKxKnG&open=AZ-qDpciEgyOKRdKxKnG&pullRequest=69
actions: read

concurrency:
group: container-build-${{ github.ref }}
Expand Down
18 changes: 18 additions & 0 deletions .github/workflows/dogfood-gate.yml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,24 @@ permissions:
contents: read

jobs:
# ---------------------------------------------------------------------------
# Job 0: every workflow must PARSE
#
# A malformed workflow is not a red check — Actions rejects it at parse time,
# yielding zero jobs and NO check run, so the board reads green while the gate
# is dead. This repo hit that twice in one day from the same sweep (fixed in
# #64, reintroduced by #68). This job is the backstop.
# ---------------------------------------------------------------------------
workflow-yaml:
name: Workflows parse (no silent-dead gates)
runs-on: ubuntu-latest
timeout-minutes: 5
steps:
- name: Checkout repository
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
- name: Validate every workflow parses and declares jobs
run: ./.githooks/validate-workflow-yaml.sh

# ---------------------------------------------------------------------------
# Job 1: A2ML manifest validation
# ---------------------------------------------------------------------------
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/e2e.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
branches: [main, master]
workflow_dispatch:

permissions: read-all

Check warning on line 28 in .github/workflows/e2e.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "read-all" with specific permissions (e.g., "contents: read").

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_statistikles&issues=AZ-qDpY2EgyOKRdKxKnE&open=AZ-qDpY2EgyOKRdKxKnE&pullRequest=69
actions: read

concurrency:
group: e2e-${{ github.ref }}
Expand Down
1 change: 0 additions & 1 deletion .github/workflows/install-smoke.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,8 +22,7 @@
branches: [main]
workflow_dispatch:

permissions: read-all

Check warning on line 25 in .github/workflows/install-smoke.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "read-all" with specific permissions (e.g., "contents: read").

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_statistikles&issues=AZ-qDpc0EgyOKRdKxKnH&open=AZ-qDpc0EgyOKRdKxKnH&pullRequest=69
actions: read

concurrency:
group: install-smoke-${{ github.ref }}
Expand Down
34 changes: 0 additions & 34 deletions .github/workflows/push-email-notify.yml

This file was deleted.

1 change: 0 additions & 1 deletion .github/workflows/zig.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,7 @@
- '.github/workflows/zig.yml'
workflow_dispatch:

permissions: read-all

Check warning on line 26 in .github/workflows/zig.yml

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Replace "read-all" with specific permissions (e.g., "contents: read").

See more on https://sonarcloud.io/project/issues?id=hyperpolymath_statistikles&issues=AZ-qDpcOEgyOKRdKxKnF&open=AZ-qDpcOEgyOKRdKxKnF&pullRequest=69
actions: read

concurrency:
group: zig-${{ github.ref }}
Expand Down
4 changes: 2 additions & 2 deletions .machine_readable/contractiles/Mustfile.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ hooks fail if any check fails.
- severity: critical

### governance-docs
- description: GOVERNANCE.adoc, MAINTAINERS.adoc, CODEOWNERS must exist
- run: test -f GOVERNANCE.adoc && test -f MAINTAINERS.adoc && test -f .github/CODEOWNERS
- description: GOVERNANCE.md, MAINTAINERS.adoc, CODEOWNERS must exist
- run: test -f GOVERNANCE.md && test -f MAINTAINERS.adoc && test -f .github/CODEOWNERS
- severity: critical

### machine-readable-dir
Expand Down
2 changes: 1 addition & 1 deletion .machine_readable/contractiles/Trustfile.a2ml
Original file line number Diff line number Diff line change
Expand Up @@ -71,7 +71,7 @@ Current trust level: maximal
- severity: advisory
- areas:
- .machine_readable/
- GOVERNANCE.adoc
- GOVERNANCE.md
- MAINTAINERS.adoc
- .github/CODEOWNERS

Expand Down
65 changes: 65 additions & 0 deletions GOVERNANCE.md
Original file line number Diff line number Diff line change
Expand Up @@ -157,4 +157,69 @@ with the community before adoption, even though the BDFL retains final authority

---

## Contribution Lifecycle

| Stage | Process |
|---|---|
| **Ideation** | Open issue, discuss feasibility |
| **Development** | Fork, implement, test thoroughly |
| **Review** | Submit PR, maintainer reviews within 7 days |
| **Merge** | Maintainer merges or requests changes |
| **Release** | Maintainer publishes according to project conventions |

## Conflict Resolution

In case of disagreements:

1. Discuss in the relevant GitHub issue or PR.
2. Provide technical justification for positions.
3. Maintainer mediates and makes the final decision.
4. The decision is documented and can be revisited later.

## Project Policies

This repository adheres to hyperpolymath estate-wide policies:

- **Licence** — MPL-2.0 for code, CC-BY-SA-4.0 for prose (per `standards/LICENCE-POLICY.adoc`)
- **Code of Conduct** — follows hyperpolymath `CODE_OF_CONDUCT.md`
- **Security** — follows hyperpolymath `SECURITY.md`
- **Contributing** — follows hyperpolymath `CONTRIBUTING.adoc` conventions

## Repository-Specific Conventions

| Convention | Description |
|---|---|
| **Signing** | All commits must be signed (SSH or GPG) |
| **SPDX headers** | All source files must carry SPDX licence identifiers |
| **Contractiles** | `Mustfile`, `Trustfile`, `Intendfile`, `Adjustfile` in root |
| **Machine readable** | `META.a2ml` in `.machine_readable/6a2/` |
| **CI/CD** | GitHub Actions workflows in `.github/workflows/` |

## Governance Evolution

As the project grows, this governance model may evolve:

- **Adding co-maintainers** — when contribution volume warrants it
- **Forming a team** — for complex multi-maintainer projects
- **Adopting TPCF** — for large, multi-repository projects (see `rhodium-standard-repositories`)

Changes to this document require the same process as Significant Changes above.

## See Also

- [Maintainers](MAINTAINERS.md)
- [Code of Conduct](CODE_OF_CONDUCT.md)
- [Contributing Guide](CONTRIBUTING.md)
- [Estate Licence Policy](https://github.com/hyperpolymath/standards/blob/main/LICENCE-POLICY.adoc)
- [rhodium-standard-repositories (TPCF)](https://github.com/hyperpolymath/standards)

## Changelog

| Date | Change | By |
|---|---|---|
| 2026-06-07 | Initial governance model established | @hyperpolymath |
| 2026-07-27 | Merged in the sections that had lived only in `GOVERNANCE.adoc`, which was deleted in #68; this file is now the single source. | @hyperpolymath |

---

<sub>Copyright (c) 2026 hyperpolymath. Licensed under MPL-2.0.</sub>
Loading