Repository navigation
feat: generate searchable Mathesis atlas directly from census #26
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # This workflow is managed by gh actions-lock. | |
| # SPDX-License-Identifier: MPL-2.0 | |
| # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) <j.d.a.jewell@open.ac.uk> | |
| # | |
| # Estate Rules — enforces hyperpolymath estate-wide conventions: | |
| # * root shape (allowlist of permitted root entries) | |
| # * AsciiDoc-by-default (no .md files under docs/) | |
| # * AsciiDoc that renders (every tracked .adoc parses with no diagnostics) | |
| # * V-lang is banned (no V-lang scaffolding or references; Zig is the FFI default) | |
| # | |
| # 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 | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| concurrency: | |
| group: ${{ github.workflow }}-${{ github.ref }} | |
| cancel-in-progress: true | |
| permissions: | |
| contents: read | |
| jobs: | |
| estate-rules: | |
| runs-on: ubuntu-24.04 | |
| timeout-minutes: 15 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 | |
| with: | |
| persist-credentials: false | |
| # Prove the instrument works before trusting its reading. This gate was | |
| # one-directional for months, which is indistinguishable from a working | |
| # gate until you try to make it fail. | |
| - name: Root-shape gate self-test (must fail on drift) | |
| run: bash tests/shape/check_root_shape_test.sh | |
| - name: Root shape allowlist | |
| run: bash scripts/check-root-shape.sh . | |
| # The map is generated. Five hand-written predecessors all rotted because | |
| # nothing diffed them. | |
| # The freshness check below is only meaningful if the generator is | |
| # environment-independent. It wasn't: sort is locale-dependent, so the | |
| # map generated differently in CI than locally. Vary the locale first. | |
| - name: Repository map generates identically across locales | |
| run: bash tests/shape/repo_map_determinism_test.sh | |
| - name: Repository map is not stale | |
| run: | | |
| cp docs/architecture/REPOSITORY-MAP.adoc /tmp/map.before | |
| bash scripts/gen-repo-map.sh . | |
| diff -u /tmp/map.before docs/architecture/REPOSITORY-MAP.adoc \ | |
| || { echo "::error::REPOSITORY-MAP.adoc is stale - run 'just repo-map'"; exit 1; } | |
| - name: AsciiDoc by default (no .md under docs/) | |
| run: bash scripts/check-no-md-in-docs.sh . | |
| # The rule above checks the file EXTENSION only, so a Markdown body | |
| # renamed to .adoc passes it. This one checks the file actually parses. | |
| # asciidoctor's --failure-level defaults to FATAL, so a document emitting | |
| # WARNING or ERROR still exits 0; the version is pinned because the | |
| # verdict rests on a stderr comparison. | |
| - name: Install asciidoctor | |
| run: sudo gem install asciidoctor -v 2.0.26 --no-document | |
| - name: AsciiDoc render gate self-test (must catch what bare asciidoctor misses) | |
| run: bash tests/workflows/check_adoc_renders_test.sh | |
| - name: Every tracked .adoc renders clean | |
| run: bash scripts/check-adoc-renders.sh . | |
| - name: No V-language references | |
| run: bash scripts/check-no-vlang.sh . | |
| # Was written but wired to nothing, so it had never run in CI. | |
| - name: V-language gate self-test | |
| run: bash tests/workflows/check_no_vlang_test.sh | |
| # .a2ml is retired estate-wide: facts are deed clauses, contracts are .k9. | |
| - name: No .a2ml files | |
| run: bash scripts/check-no-a2ml.sh . | |
| - name: No-a2ml gate self-test (planted positives must fail) | |
| run: bash tests/workflows/check_no_a2ml_test.sh | |
| - name: Deed clause writer controls | |
| run: bash tests/workflows/deed_clause_test.sh | |
| - name: Install verified Nickel 1.17.0 | |
| run: | | |
| mkdir -p "$RUNNER_TEMP/nickel-bin" | |
| curl --proto '=https' --proto-redir '=https' --fail --silent --show-error --location \ | |
| https://github.com/nickel-lang/nickel/releases/download/1.17.0/nickel-x86_64-linux \ | |
| --output "$RUNNER_TEMP/nickel-bin/nickel" | |
| echo "afcdfa6e0fff31760cf229e85997456c02c00b8b3b84ff38f897ac7b3f39ae34 $RUNNER_TEMP/nickel-bin/nickel" | sha256sum --check --strict | |
| chmod +x "$RUNNER_TEMP/nickel-bin/nickel" | |
| echo "$RUNNER_TEMP/nickel-bin" >> "$GITHUB_PATH" | |
| - name: Evaluate session contracts | |
| run: bash scripts/validate-session-contracts.sh | |
| - name: Check Nickel typecheck controls | |
| run: bash tests/workflows/k9_typecheck_test.sh | |
| - name: Verify session envelope controls | |
| run: bash tests/workflows/session_contracts_test.sh | |
| - name: Verify mint cleanup controls | |
| run: bash tests/workflows/mint_cleanup_test.sh | |
| - name: Self-name pass keeps issue references, provenance and detectors | |
| run: bash tests/workflows/self_name_pass_test.sh | |
| # The automated mint path (RSR_NON_INTERACTIVE) never completed, and no | |
| # workflow exercised repo-init at all: tests/e2e runs nowhere in CI. | |
| - name: Install verified just 1.43.0 | |
| run: | | |
| mkdir -p "$RUNNER_TEMP/just-bin" | |
| curl --proto '=https' --proto-redir '=https' --fail --silent --show-error --location \ | |
| https://github.com/casey/just/releases/download/1.43.0/just-1.43.0-x86_64-unknown-linux-musl.tar.gz \ | |
| --output "$RUNNER_TEMP/just.tgz" | |
| echo "a1bc93654f31669fd964ea3011a5e5e9676b9b6f8adcd762606e5140632ea72d $RUNNER_TEMP/just.tgz" | sha256sum --check --strict | |
| tar -xzf "$RUNNER_TEMP/just.tgz" -C "$RUNNER_TEMP/just-bin" just | |
| echo "$RUNNER_TEMP/just-bin" >> "$GITHUB_PATH" | |
| - name: Non-interactive mint resolves every prompt from the environment | |
| run: bash tests/workflows/non_interactive_mint_test.sh | |
| # repo-init recorded the CHILD's own HEAD as the template commit whenever | |
| # a repo was created with "Use this template" (metadatastician/lintel). | |
| - name: Template pin resolves by tree equality (controls) | |
| run: bash tests/workflows/resolve_template_pin_test.sh | |
| # The first CI job to run a FULL mint: a Use-this-template child, checked | |
| # for provenance, untouched fixtures and ignored files, the map and the | |
| # closing advice. A fresh mint of main aborted on 2026-10-20 and nothing | |
| # here noticed. uuidgen is util-linux; installed only if the image lacks it. | |
| - name: Use-this-template mint end to end | |
| # This tests the generator as a template, not an already-minted child. | |
| if: github.event.repository.name == 'rsr-template-repo' | |
| run: | | |
| command -v uuidgen >/dev/null || { sudo apt-get update -q && sudo apt-get install -y -q uuid-runtime; } | |
| bash tests/e2e/use_template_mint_test.sh | |
| # An archetype overlay once shipped its own actions.lock, which replaced | |
| # the spine's at mint and left every Julia mint with Lock Sync red. | |
| - name: Archetype lock fragments merge into a valid lock | |
| run: bash tests/workflows/archetype_lock_merge_test.sh | |
| # The CHECK half of the template contract. repo-init has always written an | |
| # answer-file (now the child deed's (provenance) clause); nothing ever read it. | |
| # This is the missing reader, and it covers the #200/#201/#203 class: | |
| # self-parenting identity, unresolved pins, and leaked template branches. | |
| # | |
| # The template itself self-skips (archetypes/ present), so the real check | |
| # runs in minted children. What THIS proves is that the instrument can | |
| # fail — the only property that matters for a gate, and the one that was | |
| # missing in #49, #64 and the conformance gate that "reported them | |
| # conforming" upstream. | |
| - name: Template conformance gate self-test (must fail on drift) | |
| run: bash tests/workflows/template_conformance_test.sh | |
| # runtime-policy.yml folded into governance (#244). Both validators must | |
| # require governance.yml, and a retired gate's name must not stand in. | |
| - name: Validators require governance in place of the runtime gate | |
| run: bash tests/workflows/runtime_policy_fold_test.sh | |
| # Bun is the estate's first-choice runtime; the governance test below | |
| # parses the workflow and its lock with Bun.YAML. Pinned and verified, | |
| # as the other tools here are. | |
| - name: Install verified Bun 1.4.2 | |
| run: | | |
| curl --proto '=https' --proto-redir '=https' --fail --silent --show-error --location \ | |
| https://github.com/oven-sh/bun/releases/download/bun-v1.4.2/bun-linux-x64.zip \ | |
| --output "$RUNNER_TEMP/bun.zip" | |
| echo "36368faef7527875d5ffa52e53cd48021741f2a83eb6208a8dd64068d422a913 $RUNNER_TEMP/bun.zip" | sha256sum --check --strict | |
| unzip -q "$RUNNER_TEMP/bun.zip" -d "$RUNNER_TEMP" | |
| echo "$RUNNER_TEMP/bun-linux-x64" >> "$GITHUB_PATH" | |
| # The runtime gate stays retired, governance runs for pull requests to | |
| # any branch, and it calls the standards reusable at the commit its lock | |
| # records. | |
| - name: Governance replaces the runtime gate for every pull request | |
| run: bash tests/workflows/governance_policy_test.sh | |
| # KYAML ratchet (standards YAML-POLICY §3.4, §5 step 5, standards#1024): | |
| # every file listed here has been converted and must stay KYAML. A file | |
| # joins the list in the PR that converts it and never leaves it. The | |
| # formatter is standards' own kyaml-format.sh at a pinned commit, the one | |
| # rewriter the step-2 comment-preservation proof covers, so this repo | |
| # carries no copy that can drift. yq is pinned too: kyaml-format.sh exits | |
| # 2 (red) on a yq that cannot write KYAML, never green. Workflows wait for | |
| # step 6 (standards#1025); files a third-party bot or tool rewrites or | |
| # finds by schema (Dependabot, FUNDING, issue forms, settings, CodeRabbit, | |
| # Copilot, GitLab CI, pre-commit) are not listed, as in standards. | |
| - name: Install verified yq 4.53.3 and kyaml-format.sh (standards 8e48b1c) | |
| run: | | |
| mkdir -p "$RUNNER_TEMP/yq-bin" | |
| curl --proto '=https' --proto-redir '=https' --fail --silent --show-error --location \ | |
| https://github.com/mikefarah/yq/releases/download/v4.53.3/yq_linux_amd64 \ | |
| --output "$RUNNER_TEMP/yq-bin/yq" | |
| echo "fa52a4e758c63d38299163fbdd1edfb4c4963247918bf9c1c5d31d84789eded4 $RUNNER_TEMP/yq-bin/yq" | sha256sum --check --strict | |
| chmod +x "$RUNNER_TEMP/yq-bin/yq" | |
| echo "$RUNNER_TEMP/yq-bin" >> "$GITHUB_PATH" | |
| curl --proto '=https' --proto-redir '=https' --fail --silent --show-error --location \ | |
| https://raw.githubusercontent.com/metadatastician/standards/8e48b1caade08a552646adeab66558ac43b4360d/scripts/kyaml-format.sh \ | |
| --output "$RUNNER_TEMP/kyaml-format.sh" | |
| echo "5fddd58fc8cbd2b68766ef5b4b5ba39f299da3f27252ae6cdcff0a641bbaef18 $RUNNER_TEMP/kyaml-format.sh" | sha256sum --check --strict | |
| # Container narrowing at mint (build/just/container.just) can delete any | |
| # of these files. The template (archetypes/ present) must keep all of | |
| # them; a minted repository checks the ones it kept and names the rest. | |
| - name: Converted YAML stays KYAML | |
| run: | | |
| set -euo pipefail | |
| converted=( | |
| build/container/compose.yaml | |
| build/container/compose.example.yaml | |
| build/container/stapeln/.gatekeeper.yaml | |
| ) | |
| present=() | |
| for file in "${converted[@]}"; do | |
| if [ -f "$file" ]; then | |
| present+=("$file") | |
| elif [ -d archetypes ]; then | |
| echo "::error::$file is missing from the template" | |
| exit 1 | |
| else | |
| echo "::notice::$file was removed at mint by container narrowing; not checked" | |
| fi | |
| done | |
| if [ "${#present[@]}" -eq 0 ]; then | |
| echo "No converted YAML is left in this repository; nothing to check." | |
| exit 0 | |
| fi | |
| bash "$RUNNER_TEMP/kyaml-format.sh" --check "${present[@]}" | |
| - name: Estate composite actions stay KYAML | |
| run: | | |
| set -euo pipefail | |
| if [ -f .github/actions/squabble/action.yml ]; then | |
| bash "$RUNNER_TEMP/kyaml-format.sh" --check .github/actions/squabble/action.yml | |
| if [ -f scripts/kyaml-format.sh ]; then | |
| bash scripts/kyaml-format.sh --check .github/actions/squabble/action.yml | |
| fi | |
| fi | |
| - name: Converted container configs keep their data (template only) | |
| run: bash tests/workflows/container_kyaml_test.sh | |
| - name: KYAML ratchet self-test (installs verify, gate propagates, narrowing) | |
| run: bash tests/workflows/kyaml_ratchet_test.sh | |
| - name: I-JSON (RFC 7493) + JCS (RFC 8785) canonical gate & self-test | |
| run: | | |
| set -euo pipefail | |
| bash tests/workflows/check_ijson_jcs_test.sh | |
| bash scripts/check-ijson-jcs.sh --enforce . | |
| - name: Required status contexts & squabble anti-bypass gate | |
| run: | | |
| set -euo pipefail | |
| bash tests/workflows/squabble_gate_test.sh | |
| bash scripts/check-required-contexts.sh . |