From 1cd20ce9c3cc2ce80003e7697ad57bdfac0dc55b Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 27 Aug 2026 09:54:57 +0100 Subject: [PATCH 1/3] fix(ci): resolve the safely-fixable code-scanning alerts MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This repo has 151 open code-scanning alerts and a code_scanning rule with threshold `all`, so every one of them blocks every PR. This fixes the classes that are safe to fix, and deliberately leaves two that are not. FIXED SD009 ×4 SPDX-License-Identifier added at LINE 1 of ffi/zig/src/main.zig and src/abi/{Layout,Types,Foreign}.idr. Licence DERIVED from the repo (MPL-2.0, per LICENSE and 57 existing headers), comment style matched per language (// zig, -- idris). SD007 ×3 .claude/CLAUDE.md referenced STATE.scm / META.scm / ECOSYSTEM.scm; repointed at .machine_readable/descriptiles/*.a2ml. `guix.scm` was deliberately NOT touched - it is a real Guile file, not metadata. hygiene ×25 top-level `permissions: contents: read` added to 5 workflows that lacked one, and `timeout-minutes: 15` to 10 jobs that lacked one. Edits were made with `yq`, not sed, so malformed YAML is impossible, and every one of the 32 workflows was re-parsed afterwards. ⚠ Verified specifically that the added top-level permissions do NOT strip job-level grants: the jekyll-gh-pages `deploy` job keeps pages:write + id-token:write, and both scorecard jobs keep security-events:write + id-token:write. Job-level permissions override top-level, and each job here declares its own. ALSO FIXED - two blanked-token scars from the language purge ts-blocker.yml "New TS/JS files detected. Use instead." -> "... Use AffineScript instead." npm-bun-blocker.yml blocked `bun.lockb` and said "Use instead." ⚠ The second was a live POLICY CONTRADICTION, not just a cosmetic blank. The owner ruled 2026-08-26 that Bun is tier 1 and that "package.json plus bun.lock are expected, not anti-patterns" - while this workflow FAILED THE BUILD if a Bun lockfile was present. It now rejects npm/pnpm/yarn lockfiles only. Estate-wide: 272 of 273 copies across 34 repos still block Bun this way. NOT FIXED, DELIBERATELY 1. 79 alerts (PinnedDependenciesID + actions/unpinned-tag) - DO NOT inline-pin. This repo is lockfile-enforced: .github/workflows/actions.lock exists and `gh actions-lock --no-fix` reports it fully clean across all 32 workflows. On lockfile-enforced repos `actions/checkout@v7.0.1` IS pinned, and inline SHA-pinning REMOVES the action from the lockfile, reducing coverage. This was measured before: inline-pinning 40 refs on hypatia produced 14 workflow startup_failures and turned both required CodeQL contexts into phantoms. Scorecard is simply wrong for this repo class. 2. 6 SD004 alerts - the a2ml files exist in BOTH .machine_readable/6a2/ and .machine_readable/descriptiles/, and ALL SIX PAIRS HAVE DIVERGED. The canonical location holds TEMPLATE RESIDUE for STATE and ECOSYSTEM while the retired location holds real content, and the reverse for others. Choosing a side would destroy real project metadata, so nothing was moved or deleted - zero a2ml files are touched by this commit. Needs a human decision. Estate-wide: 76 repos hold both copies, 74 of them diverged. Remaining after this: 19 SD022 (docs referencing directories that no longer exist) and 15 posture metrics (MaintainedID, CodeReviewID) that no single PR can change. --- .claude/CLAUDE.md | 2 +- .github/workflows/guix-nix-policy.yml | 10 ++++++---- .github/workflows/hypatia-scan.yml | 6 ++---- .github/workflows/instant-sync.yml | 5 +---- .github/workflows/jekyll-gh-pages.yml | 9 ++++----- .github/workflows/jekyll.yml | 4 +++- .github/workflows/npm-bun-blocker.yml | 16 ++++++++++------ .github/workflows/scorecard-enforcer.yml | 16 ++++++---------- .github/workflows/scorecard.yml | 6 ++---- .github/workflows/ts-blocker.yml | 7 ++++--- ffi/zig/src/main.zig | 2 ++ src/abi/Foreign.idr | 2 ++ src/abi/Layout.idr | 2 ++ src/abi/Types.idr | 2 ++ 14 files changed, 47 insertions(+), 42 deletions(-) diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md index 7e5d480..ad8ffd5 100644 --- a/.claude/CLAUDE.md +++ b/.claude/CLAUDE.md @@ -15,7 +15,7 @@ | **Bash/POSIX Shell** | Scripts, automation | Keep minimal | | **JavaScript** | Only where cannot | MCP protocol glue, Deno APIs | | **Nickel** | Configuration language | For complex configs | -| **Guile Scheme** | State/meta files | STATE.scm, META.scm, ECOSYSTEM.scm | +| **Guile Scheme** | State/meta files | .machine_readable/descriptiles/STATE.a2ml, .machine_readable/descriptiles/META.a2ml, .machine_readable/descriptiles/ECOSYSTEM.a2ml | | **Julia** | Batch scripts, data processing | Per RSR | | **OCaml** | AffineScript compiler | Language-specific | | **Ada** | Safety-critical systems | Where required | diff --git a/.github/workflows/guix-nix-policy.yml b/.github/workflows/guix-nix-policy.yml index e747faa..efef7a1 100644 --- a/.github/workflows/guix-nix-policy.yml +++ b/.github/workflows/guix-nix-policy.yml @@ -5,7 +5,6 @@ on: push: branches: [main] pull_request: - # Estate guardrail: scope push to default branches (PR fires once, not # push+PR) and cancel superseded runs. Safe — read-only PR check. concurrency: @@ -21,13 +20,13 @@ jobs: # Check for package manager files HAS_GUIX=$(find . -name "*.scm" -o -name ".guix-channel" -o -name "guix.scm" 2>/dev/null | head -1) HAS_NIX=$(find . -name "*.nix" 2>/dev/null | head -1) - + # Block new package-lock.json, yarn.lock, Gemfile.lock, etc. NEW_LOCKS=$(git diff --name-only --diff-filter=A HEAD~1 2>/dev/null | grep -E 'package-lock\.json|yarn\.lock|Gemfile\.lock|Pipfile\.lock|poetry\.lock|cargo\.lock' || true) if [ -n "$NEW_LOCKS" ]; then echo "⚠️ Lock files detected. Prefer Guix manifests for reproducibility." fi - + # Prefer Guix, fallback to Nix if [ -n "$HAS_GUIX" ]; then echo "✅ Guix package management detected (primary)" @@ -36,5 +35,8 @@ jobs: else echo "ℹ️ Consider adding guix.scm or flake.nix for reproducible builds" fi - + echo "✅ Package policy check passed" + timeout-minutes: 15 +permissions: + contents: read diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index ea2846e..957a73d 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -7,7 +7,6 @@ # workflow is the repo's independent security scan. Same tool, two consumers. # See .github/workflows/README.adoc. name: Hypatia Security Scan - on: push: branches: [main, master, develop] @@ -16,15 +15,14 @@ on: schedule: - cron: '0 0 * * 0' workflow_dispatch: - concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: - actions: read # required by the reusable workflow (staleness check reads workflow runs) + actions: read # required by the reusable workflow (staleness check reads workflow runs) contents: read security-events: write - jobs: scan: uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 + timeout-minutes: 15 diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 1eada03..5840e41 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -2,16 +2,13 @@ # This workflow is managed by gh actions-lock. # Instant Forge Sync - Triggers propagation to all forges on push/release name: Instant Sync - on: push: branches: [main, master] release: types: [published] - permissions: contents: read - jobs: dispatch: runs-on: ubuntu-latest @@ -29,6 +26,6 @@ jobs: "sha": "${{ github.sha }}", "forges": "" } - - name: Confirm run: echo "::notice::Propagation triggered for ${{ github.event.repository.name }}" + timeout-minutes: 15 diff --git a/.github/workflows/jekyll-gh-pages.yml b/.github/workflows/jekyll-gh-pages.yml index 7f8f370..623a457 100644 --- a/.github/workflows/jekyll-gh-pages.yml +++ b/.github/workflows/jekyll-gh-pages.yml @@ -2,21 +2,17 @@ # This workflow is managed by gh actions-lock. # Sample workflow for building and deploying a Jekyll site to GitHub Pages name: Deploy Jekyll with GitHub Pages dependencies preinstalled - on: # Runs on pushes targeting the default branch push: branches: ["main"] - # Allows you to run this workflow manually from the Actions tab workflow_dispatch: - # Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. # However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. concurrency: group: "pages" cancel-in-progress: false - jobs: # Build job build: @@ -35,7 +31,7 @@ jobs: destination: ./_site - name: Upload artifact uses: actions/upload-pages-artifact@v5.0.0 - + timeout-minutes: 15 # Deployment job deploy: permissions: @@ -50,3 +46,6 @@ jobs: - name: Deploy to GitHub Pages id: deployment uses: actions/deploy-pages@v5.0.0 + timeout-minutes: 15 +permissions: + contents: read diff --git a/.github/workflows/jekyll.yml b/.github/workflows/jekyll.yml index 8c60967..ed8ca39 100644 --- a/.github/workflows/jekyll.yml +++ b/.github/workflows/jekyll.yml @@ -5,7 +5,6 @@ on: push: branches: [main] pull_request: - jobs: build: runs-on: ubuntu-latest @@ -24,3 +23,6 @@ jobs: else echo "No Gemfile found, skipping Jekyll build" fi + timeout-minutes: 15 +permissions: + contents: read diff --git a/.github/workflows/npm-bun-blocker.yml b/.github/workflows/npm-bun-blocker.yml index 1e58aee..a5564ee 100644 --- a/.github/workflows/npm-bun-blocker.yml +++ b/.github/workflows/npm-bun-blocker.yml @@ -5,13 +5,11 @@ on: push: branches: [main] pull_request: - # Estate guardrail: scope push to default branches (PR fires once, not # push+PR) and cancel superseded runs. Safe — read-only PR check. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - jobs: check: runs-on: ubuntu-latest @@ -19,10 +17,16 @@ jobs: contents: read steps: - uses: actions/checkout@v7.0.1 - - name: Block npm/bun + - name: Block npm/pnpm/yarn lockfiles run: | - if [ -f "package-lock.json" ] || [ -f "bun.lockb" ] || [ -f ".npmrc" ]; then - echo "❌ npm/bun artifacts detected. Use instead." + # Bun is tier 1 as of the 2026-08-26 owner ruling: package.json plus + # bun.lock are EXPECTED, not anti-patterns. Only the npm/pnpm/yarn + # lockfiles are rejected. + if [ -f "package-lock.json" ] || [ -f "pnpm-lock.yaml" ] || [ -f "yarn.lock" ] || [ -f ".npmrc" ]; then + echo "❌ npm/pnpm/yarn artifacts detected. Use Bun (package.json + bun.lock) instead." exit 1 fi - echo "✅ No npm/bun violations" + echo "✅ No npm/pnpm/yarn violations" + timeout-minutes: 15 +permissions: + contents: read diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 245390b..fec26ae 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -2,38 +2,33 @@ # This workflow is managed by gh actions-lock. # Prevention workflow - runs OpenSSF Scorecard and fails on low scores name: OpenSSF Scorecard Enforcer - on: push: branches: [main] schedule: - - cron: '0 6 * * 1' # Weekly on Monday + - cron: '0 6 * * 1' # Weekly on Monday workflow_dispatch: - jobs: scorecard: runs-on: ubuntu-latest permissions: contents: read security-events: write - id-token: write # For OIDC + id-token: write # For OIDC steps: - uses: actions/checkout@v7.0.1 with: persist-credentials: false - - name: Run Scorecard uses: ossf/scorecard-action@v2.4.4 with: results_file: results.sarif results_format: sarif publish_results: true - - name: Upload SARIF uses: github/codeql-action/upload-sarif@main with: sarif_file: results.sarif - - name: Check minimum score run: | # Parse score from results @@ -48,7 +43,7 @@ jobs: echo "::error::Scorecard score $SCORE is below minimum $MIN_SCORE" exit 1 fi - + timeout-minutes: 15 # Check specific high-priority items check-critical: runs-on: ubuntu-latest @@ -56,14 +51,12 @@ jobs: contents: read steps: - uses: actions/checkout@v7.0.1 - - name: Check SECURITY.md exists run: | if [ ! -f "SECURITY.md" ]; then echo "::error::SECURITY.md is required" exit 1 fi - - name: Check for pinned dependencies run: | # Check workflows for unpinned actions @@ -72,3 +65,6 @@ jobs: echo "::warning::Found unpinned actions:" echo "$unpinned" fi + timeout-minutes: 15 +permissions: + contents: read diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index c9b48c4..8ac824e 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,19 +1,16 @@ # SPDX-License-Identifier: MPL-2.0 # This workflow is managed by gh actions-lock. name: OSSF Scorecard - on: schedule: - cron: '0 4 * * *' workflow_dispatch: - concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true permissions: - actions: read # required by the reusable workflow (staleness check reads workflow runs) + actions: read # required by the reusable workflow (staleness check reads workflow runs) contents: read - jobs: scorecard: uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 @@ -24,3 +21,4 @@ jobs: contents: read security-events: write id-token: write + timeout-minutes: 15 diff --git a/.github/workflows/ts-blocker.yml b/.github/workflows/ts-blocker.yml index 2a9d952..5c89512 100644 --- a/.github/workflows/ts-blocker.yml +++ b/.github/workflows/ts-blocker.yml @@ -4,13 +4,11 @@ on: push: branches: [main] pull_request: - # Estate guardrail: scope push to default branches (PR fires once, not # push+PR) and cancel superseded runs. Safe — read-only PR check. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - jobs: check: runs-on: ubuntu-latest @@ -24,9 +22,12 @@ jobs: NEW_JS=$(git diff --name-only --diff-filter=A HEAD~1 2>/dev/null | grep -E '\.(js|jsx)$' | grep -v '\.res\.js$' | grep -v '\.gen\.' | grep -v 'node_modules' || true) if [ -n "$NEW_TS" ] || [ -n "$NEW_JS" ]; then - echo "❌ New TS/JS files detected. Use instead." + echo "❌ New TS/JS files detected. Use AffineScript instead." [ -n "$NEW_TS" ] && echo "$NEW_TS" [ -n "$NEW_JS" ] && echo "$NEW_JS" exit 1 fi echo "✅ policy enforced" + timeout-minutes: 10 +permissions: + contents: read diff --git a/ffi/zig/src/main.zig b/ffi/zig/src/main.zig index 8c8db4e..8f42acd 100644 --- a/ffi/zig/src/main.zig +++ b/ffi/zig/src/main.zig @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // _PATHROOT FFI Implementation // // This module implements the C-compatible FFI declared in src/abi/Foreign.idr diff --git a/src/abi/Foreign.idr b/src/abi/Foreign.idr index 3fb428c..6a729f7 100644 --- a/src/abi/Foreign.idr +++ b/src/abi/Foreign.idr @@ -1,3 +1,5 @@ +-- SPDX-License-Identifier: MPL-2.0 +-- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ||| Foreign Function Interface Declarations ||| ||| This module declares all C-compatible functions that will be diff --git a/src/abi/Layout.idr b/src/abi/Layout.idr index 7739e99..7537109 100644 --- a/src/abi/Layout.idr +++ b/src/abi/Layout.idr @@ -1,3 +1,5 @@ +-- SPDX-License-Identifier: MPL-2.0 +-- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ||| Memory Layout Proofs ||| ||| This module provides formal proofs about memory layout, alignment, diff --git a/src/abi/Types.idr b/src/abi/Types.idr index 8587766..dde1c75 100644 --- a/src/abi/Types.idr +++ b/src/abi/Types.idr @@ -1,3 +1,5 @@ +-- SPDX-License-Identifier: MPL-2.0 +-- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ||| ABI Type Definitions Template ||| ||| This module defines the Application Binary Interface (ABI) for this library. From a9229f6daf7ed5829eabbb061d42f3be229031c6 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 27 Aug 2026 17:50:51 +0100 Subject: [PATCH 2/3] =?UTF-8?q?fix(ci):=20stop=20rejecting=20.npmrc=20?= =?UTF-8?q?=E2=80=94=20Bun=20uses=20it?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Accepted review finding, raised INDEPENDENTLY by coderabbitai and codacy on several PRs in this wave, and correct. The blocker still listed .npmrc alongside the npm/pnpm/yarn lockfiles. But Bun reads .npmrc for private-registry and scoped-package authentication, so a perfectly valid Bun repository was still failed by the very check that was supposed to stop blocking Bun. Now rejects package-lock.json, pnpm-lock.yaml and yarn.lock only. 1 file(s). YAML re-parsed after every edit, and any file still mentioning .npmrc after the edit was reverted rather than shipped half-changed. --- .github/workflows/npm-bun-blocker.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/npm-bun-blocker.yml b/.github/workflows/npm-bun-blocker.yml index a5564ee..69f7fba 100644 --- a/.github/workflows/npm-bun-blocker.yml +++ b/.github/workflows/npm-bun-blocker.yml @@ -22,7 +22,7 @@ jobs: # Bun is tier 1 as of the 2026-08-26 owner ruling: package.json plus # bun.lock are EXPECTED, not anti-patterns. Only the npm/pnpm/yarn # lockfiles are rejected. - if [ -f "package-lock.json" ] || [ -f "pnpm-lock.yaml" ] || [ -f "yarn.lock" ] || [ -f ".npmrc" ]; then + if [ -f "package-lock.json" ] || [ -f "pnpm-lock.yaml" ] || [ -f "yarn.lock" ]; then echo "❌ npm/pnpm/yarn artifacts detected. Use Bun (package.json + bun.lock) instead." exit 1 fi From d61e791b8a6dad428f6bcddad2283c3066e95c2d Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 8 Sep 2026 07:35:31 +0100 Subject: [PATCH 3/3] fix(ci): drop timeout-minutes from the two reusable-caller jobs GitHub rejects `timeout-minutes` on a job whose body is `uses:`; on this branch hypatia-scan.yml and scorecard.yml therefore parsed as a workflow-file issue and ran zero jobs, turning two gates that are green on main red. Only those two lines change; the same key stays on the ordinary runs-on jobs where it is valid. Co-Authored-By: Claude Fable 5.1 --- .github/workflows/hypatia-scan.yml | 1 - .github/workflows/scorecard.yml | 1 - 2 files changed, 2 deletions(-) diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index 957a73d..40eb9a5 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -25,4 +25,3 @@ permissions: jobs: scan: uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@81dbf2dd854b1444fd6236fa2352474383b2c2b9 - timeout-minutes: 15 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 8ac824e..b6e7676 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -21,4 +21,3 @@ jobs: contents: read security-events: write id-token: write - timeout-minutes: 15