From c91ed4c17111e01396d391c3b932045c31f30f1c Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 27 Jul 2026 14:37:00 +0100 Subject: [PATCH] fix(ci): resolve the four standing CI/CD failures at their roots MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Each of these had been red on main on every push. Fixed at source rather than suppressed. 1. 🟡 Estate rules — "Root shape allowlist" rejected flake.nix flake.nix is debris from the 07-21 sweep and contradicts the 2026-05-18 ruling that the estate is Guix-primary with the Nix fallback retired. The file even documents itself as "the Nix fallback tier". Removed; guix.scm remains under build/, so the Guix-only policy gate is unaffected. scripts/check-root-shape.sh now reports PASS (45 entries, 46 permitted). 2. 🟡 OpenSSF best-practices — unfilled {{PLACEHOLDER}} tokens .github/SECURITY.md still carried its "delete this block before publishing" template header and advertised a PGP key that does not exist ({{PGP_KEY_URL}}, {{PGP_FINGERPRINT}}). Removed the instruction block and the PGP table/import snippet; reporting by email is stated plainly rather than pointing at a key nobody can fetch. STATE.a2ml and ECOSYSTEM.a2ml were verbatim copies of rsr-template-repo's own manifests: they declared `project = "rsr-template-repo"`, the template's purpose, and phase/maturity of maintenance/production. They now describe Haec (design/experimental, 0.1.0) and its actual pipeline position. This is the template self-name leak, which also misdirects tooling that keys off these files. 3. 🟡 RSR self-use (dogfooding) — two actions that do not exist hyperpolymath/a2ml-validate-action and hyperpolymath/k9-validate-action both 404, so those steps failed at "Set up job" on every push and could never have validated anything. An unresolvable action also breaks Dependabot's github_actions updater, which is why that job failed too. Replaced with inline checks of the envelope contract that genuinely exists: non-empty, valid UTF-8, an SPDX header, and for K9 the magic first line ('K9!' for .k9, '# K9!' for .k9.ncl so `nickel typecheck` still parses). Scope is stated in the workflow: these do NOT parse the A2ML grammar or typecheck Nickel. That still needs the real validators. 4. Six .a2ml manifests had no SPDX header Added, both for REUSE compliance and so the new check in (3) is meaningful rather than vacuous. Verified locally: root-shape PASS, placeholder check PASS, A2ML and K9 envelope checks PASS, and every workflow parses with at least one live job. Not changed: CLADE.a2ml still declares canonical-name "rsr-template-repo" with the template's registry UUID and clade prefix. Those are assigned by gv-clade-index; inventing replacements would corrupt that registry, so it needs a real assignment. Co-Authored-By: Claude Opus 5 --- .github/0.1-AI-MANIFEST.a2ml | 2 + .github/SECURITY.md | 35 +--------- .github/workflows/dogfood-gate.yml | 66 +++++++++++++++---- .machine_readable/6a2/0-AI-MANIFEST.a2ml | 2 + .machine_readable/6a2/ECOSYSTEM.a2ml | 20 +++--- .machine_readable/6a2/STATE.a2ml | 28 ++++---- .../6a2/anchors/0-AI-MANIFEST.a2ml | 2 + .machine_readable/ai/AI.a2ml | 3 +- examples/0.1-AI-MANIFEST.a2ml | 2 + flake.nix | 34 ---------- verification/tests/0.2-AI-MANIFEST.a2ml | 2 + 11 files changed, 92 insertions(+), 104 deletions(-) delete mode 100644 flake.nix diff --git a/.github/0.1-AI-MANIFEST.a2ml b/.github/0.1-AI-MANIFEST.a2ml index 85b2f0f..c64c294 100644 --- a/.github/0.1-AI-MANIFEST.a2ml +++ b/.github/0.1-AI-MANIFEST.a2ml @@ -1 +1,3 @@ +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) # AI Manifest - Level 1: .github diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 9df233a..46769b7 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -4,24 +4,6 @@ Copyright (c) Jonathan D.A. Jewell --> # Security Policy - - We take security seriously. We appreciate your efforts to responsibly disclose vulnerabilities and will make every effort to acknowledge your contributions. ## Table of Contents @@ -56,26 +38,16 @@ This method ensures: - Coordinated disclosure tooling - Automatic credit when the advisory is published -### Alternative: Encrypted Email +### Alternative: Email If you cannot use GitHub Security Advisories, you may email us directly: | | | |---|---| | **Email** | j.d.a.jewell@open.ac.uk | -| **PGP Key** | [Download Public Key]({{PGP_KEY_URL}}) | -| **Fingerprint** | `{{PGP_FINGERPRINT}}` | - -```bash -# Import our PGP key -curl -sSL {{PGP_KEY_URL}} | gpg --import -# Verify fingerprint -gpg --fingerprint j.d.a.jewell@open.ac.uk - -# Encrypt your report -gpg --armor --encrypt --recipient j.d.a.jewell@open.ac.uk report.txt -``` +No PGP key is published for this project. If you need to send an encrypted +report, say so in a first plaintext message and a key will be exchanged. > **⚠️ Important:** Do not report security vulnerabilities through public GitHub issues, pull requests, discussions, or social media. @@ -374,7 +346,6 @@ When using Haec, we recommend: ## Additional Resources -- [Our PGP Public Key]({{PGP_KEY_URL}}) - [Security Advisories](https://github.com/hyperpolymath/haec/security/advisories) - [Changelog](CHANGELOG.md) - [Contributing Guidelines](CONTRIBUTING.md) diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index c2a6753..0020820 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -48,23 +48,65 @@ jobs: echo "::warning::Found $config_count config files but no K9 contracts" fi - - name: Validate A2ML manifests + # hyperpolymath/a2ml-validate-action and hyperpolymath/k9-validate-action + # do not exist — both 404. The steps therefore failed at "Set up job" on + # every push, and an unresolvable action also breaks Dependabot's + # github_actions updater. Validated inline until those are published. + # + # Scope is deliberately limited and stated honestly: these assert the + # file-level envelope contract (encoding, non-emptiness, SPDX header, and + # the K9 magic first line). They do NOT parse the A2ML grammar or + # typecheck Nickel — that still needs the real validators. + - name: Validate A2ML manifest envelopes id: a2ml if: steps.inventory.outputs.a2ml_count != '0' - continue-on-error: true - uses: hyperpolymath/a2ml-validate-action@05bcb78917c09702e90ed18004298a6728753914 # main - with: - path: '.' - strict: 'false' + shell: bash + run: | + set -euo pipefail + fail=0 + while IFS= read -r -d '' f; do + if [ ! -s "$f" ]; then + echo "::error file=$f::empty A2ML manifest"; fail=1; continue + fi + if ! iconv -f UTF-8 -t UTF-8 "$f" >/dev/null 2>&1; then + echo "::error file=$f::not valid UTF-8"; fail=1; continue + fi + if ! grep -qE 'SPDX-License-Identifier:' "$f"; then + echo "::error file=$f::missing SPDX-License-Identifier header"; fail=1 + fi + done < <(find . -name '*.a2ml' -not -path './.git/*' -print0) + [ "$fail" -eq 0 ] || { echo "::error::A2ML envelope check failed"; exit 1; } + echo "A2ML envelope check: OK" - - name: Validate K9 contracts + - name: Validate K9 contract envelopes id: k9 if: steps.inventory.outputs.k9_count != '0' - continue-on-error: true - uses: hyperpolymath/k9-validate-action@bddcd9109ee96f9ea3fdb4bf51084fe9cd0909ce # main - with: - path: '.' - strict: 'false' + shell: bash + run: | + set -euo pipefail + fail=0 + while IFS= read -r -d '' f; do + if [ ! -s "$f" ]; then + echo "::error file=$f::empty K9 contract"; fail=1; continue + fi + if ! iconv -f UTF-8 -t UTF-8 "$f" >/dev/null 2>&1; then + echo "::error file=$f::not valid UTF-8"; fail=1; continue + fi + first=$(head -1 "$f") + case "$f" in + # .k9.ncl must comment the magic so `nickel typecheck` still parses. + *.k9.ncl) want='# K9!' ;; + *) want='K9!' ;; + esac + if [ "$first" != "$want" ]; then + echo "::error file=$f::first line must be '$want' (found: '$first')"; fail=1 + fi + if ! grep -qE 'SPDX-License-Identifier:' "$f"; then + echo "::error file=$f::missing SPDX-License-Identifier header"; fail=1 + fi + done < <(find . \( -name '*.k9' -o -name '*.k9.ncl' \) -not -path './.git/*' -print0) + [ "$fail" -eq 0 ] || { echo "::error::K9 envelope check failed"; exit 1; } + echo "K9 envelope check: OK" - name: Scan for invisible characters id: empty_lint diff --git a/.machine_readable/6a2/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/0-AI-MANIFEST.a2ml index a542ab6..27fa878 100644 --- a/.machine_readable/6a2/0-AI-MANIFEST.a2ml +++ b/.machine_readable/6a2/0-AI-MANIFEST.a2ml @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) # AI Manifest for 6a2 Directory ## Purpose diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/6a2/ECOSYSTEM.a2ml index cec008d..f0c7f1e 100644 --- a/.machine_readable/6a2/ECOSYSTEM.a2ml +++ b/.machine_readable/6a2/ECOSYSTEM.a2ml @@ -1,23 +1,21 @@ # SPDX-License-Identifier: MPL-2.0 -# ECOSYSTEM.a2ml — Ecosystem position (META-TEMPLATE) +# ECOSYSTEM.a2ml — Ecosystem position for Haec. # -# This is the ECOSYSTEM file for rsr-template-repo itself. It records the -# TEMPLATE's own position in the estate. When consumed by a new project, -# replace these fields with the target project's ecosystem position and -# related projects (see the NOTE FOR CONSUMERS at the bottom). +# Instantiated from the rsr-template-repo meta-template; the fields below +# describe Haec's own position in the estate. [metadata] -project = "rsr-template-repo" +project = "haec" ecosystem = "hyperpolymath" [position] -type = "repository-template" -purpose = "Canonical RSR-compliant repository template: scaffolding (CI/CD, AI manifests, ABI/FFI standards, container ecosystem, governance) that new hyperpolymath projects are instantiated from." +type = "language" +purpose = "Writes and type-checks Haec programs and emits Trope IR. Haec is deliberately not the tropechecker (trope-checker) and not the vocabulary (trope-particularity-workbench)." [pipeline] -position = "foundation" -chain = "standards → rsr-template-repo → (every estate repo)" -notes = "rsr-template-repo turns the RSR standard into runnable scaffolding. New repos are created from it via `just init`, which substitutes the {{PLACEHOLDER}} tokens." +position = "producer" +chain = "trope-particularity-workbench (vocabulary) → haec (emits Trope IR) → trope-checker (verdict)" +notes = "Haec produces a record of graded effects; the checker consumes that IR and returns a verdict against each consumer's declared use-model. The checker never executes a Haec program, so Rice's theorem is no obstacle: an unbounded lossy loop simply gets an honest top grade." coordination = "standards" [related-projects] diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index a76d8dd..9958d3f 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -1,26 +1,26 @@ # SPDX-License-Identifier: MPL-2.0 # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # -# STATE.a2ml — Project state checkpoint (META-TEMPLATE) +# STATE.a2ml — Project state checkpoint for Haec. # -# This is the STATE file for rsr-template-repo itself. -# When consumed by a new project, replace {{PLACEHOLDER}} tokens -# and customize sections below for the target project. +# Instantiated from the rsr-template-repo meta-template. Identity and +# project-context below describe Haec; sections further down are still +# inherited from the template and need review (see NOTE, bottom). [metadata] -project = "rsr-template-repo" -version = "0.2.0" +project = "haec" +version = "0.1.0" last-updated = "2026-02-28" status = "active" # active | paused | archived [project-context] -name = "rsr-template-repo" -purpose = "Canonical RSR-compliant repository template providing scaffolding for all hyperpolymath projects — including CI/CD, AI manifests, ABI/FFI standards, container ecosystem, and governance infrastructure." -completion-percentage = 95 +name = "Haec" +purpose = "A Turing-complete language whose type discipline is trope-particularity: every operation over a property-instance carries a loss-shape grade, emitted as Trope IR for a separate, language-independent tropechecker to verdict." +completion-percentage = 10 # rough: design stage, see README status '0.1 (design)' [position] -phase = "maintenance" # design | implementation | testing | maintenance | archived -maturity = "production" # experimental | alpha | beta | production | lts +phase = "design" # design | implementation | testing | maintenance | archived +maturity = "experimental" # experimental | alpha | beta | production | lts [route-to-mvp] milestones = [ @@ -58,7 +58,7 @@ part-of = ["RSR Framework", "stapeln ecosystem"] depends-on = ["stapeln", "selur-compose", "cerro-torre", "svalinn", "vordr", "k9-svc"] # --------------------------------------------------------------------------- -# NOTE FOR CONSUMERS: When using this template to create a new repo, reset -# the fields above to your project's values and replace all {{PLACEHOLDER}} -# tokens. The milestones above describe the TEMPLATE's evolution, not yours. +# NOTE: the milestones and depends-on above are still the meta-template's, +# not Haec's, and are pending a rewrite. Identity, purpose, phase and +# maturity have been corrected to describe this project. # --------------------------------------------------------------------------- diff --git a/.machine_readable/6a2/anchors/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/anchors/0-AI-MANIFEST.a2ml index 0dd6825..f8136b6 100644 --- a/.machine_readable/6a2/anchors/0-AI-MANIFEST.a2ml +++ b/.machine_readable/6a2/anchors/0-AI-MANIFEST.a2ml @@ -1,3 +1,5 @@ +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) # AI Manifest for Anchor Directory ## Purpose diff --git a/.machine_readable/ai/AI.a2ml b/.machine_readable/ai/AI.a2ml index 3754aca..e15b962 100644 --- a/.machine_readable/ai/AI.a2ml +++ b/.machine_readable/ai/AI.a2ml @@ -1,4 +1,5 @@ - +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) # AI Assistant Instructions ## Repository Focus diff --git a/examples/0.1-AI-MANIFEST.a2ml b/examples/0.1-AI-MANIFEST.a2ml index 0d69c90..062c228 100644 --- a/examples/0.1-AI-MANIFEST.a2ml +++ b/examples/0.1-AI-MANIFEST.a2ml @@ -1 +1,3 @@ +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) # AI Manifest - Level 1: examples diff --git a/flake.nix b/flake.nix deleted file mode 100644 index b0b3901..0000000 --- a/flake.nix +++ /dev/null @@ -1,34 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell -# -# Development environment for haec. -# -# Estate policy is Guix primary / Nix fallback (hyperpolymath/standards). -# This is the Nix fallback tier. It is a dev shell, not a package build: -# it declares the toolchain needed to work on this repo, pinned to an -# exact nixpkgs revision per the estate SHA-pinning rule. -# -# Packages mirror the build tooling actually present in this repo -# (just) — not a generic estate default. -# -# nix develop # enter the shell -# nix flake check # verify this file evaluates (run before committing) -{ - description = "haec development environment"; - - inputs.nixpkgs.url = "github:NixOS/nixpkgs/b134951a4c9f3c995fd7be05f3243f8ecd65d798"; - - outputs = { self, nixpkgs }: - let - systems = [ "x86_64-linux" "aarch64-linux" "x86_64-darwin" "aarch64-darwin" ]; - forAllSystems = f: - nixpkgs.lib.genAttrs systems (system: f nixpkgs.legacyPackages.${system}); - in - { - devShells = forAllSystems (pkgs: { - default = pkgs.mkShell { - packages = with pkgs; [ just ]; - }; - }); - }; -} diff --git a/verification/tests/0.2-AI-MANIFEST.a2ml b/verification/tests/0.2-AI-MANIFEST.a2ml index 0008fcf..2ae8a23 100644 --- a/verification/tests/0.2-AI-MANIFEST.a2ml +++ b/verification/tests/0.2-AI-MANIFEST.a2ml @@ -1 +1,3 @@ +# SPDX-License-Identifier: MPL-2.0 +# SPDX-FileCopyrightText: © 2026 Jonathan D.A. Jewell (hyperpolymath) # AI Manifest - Level 1: tests