diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 7efddcb6..ba1667cd 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -32,4 +32,3 @@ permissions: jobs: governance: uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@412a7031577112b31ee287cc6060179d638d6500 # main 2026-06-27 - timeout-minutes: 30 diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index 769e4195..6ee8a1b4 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -29,8 +29,4 @@ jobs: hypatia: uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@e9c8888769a703924cc3c0d717900960d78aea00 secrets: inherit - # Total caller-side wall-clock cap for the reusable. Matches - # Hypatia's `missing_timeout_minutes` rule expectation. The scan is - # typically ~3 min; the cap leaves headroom for slow estate builds. - timeout-minutes: 30 diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 00f335ca..fe6f7afd 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -13,4 +13,3 @@ jobs: mirror: uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@e9c8888769a703924cc3c0d717900960d78aea00 secrets: inherit - timeout-minutes: 60 diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 8c49673c..59ab07c9 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -15,10 +15,5 @@ permissions: jobs: scan: - permissions: - contents: read - pull-requests: write - actions: read uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@e9c8888769a703924cc3c0d717900960d78aea00 - secrets: inherit - timeout-minutes: 20 \ No newline at end of file + secrets: inherit \ No newline at end of file diff --git a/bots/echidnabot/guix.scm b/bots/echidnabot/guix.scm index 3ace6106..c6dd7be8 100644 --- a/bots/echidnabot/guix.scm +++ b/bots/echidnabot/guix.scm @@ -1,75 +1,18 @@ -;; echidnabot - Guix Package Definition -;; Development: guix shell -D -f guix.scm -;; Build: guix build -f guix.scm +; SPDX-License-Identifier: MPL-2.0 +;; guix.scm — GNU Guix package definition for squisher-corpus +;; Usage: guix shell -f guix.scm (use-modules (guix packages) - (guix gexp) - (guix git-download) - (guix build-system cargo) - ((guix licenses) #:prefix license:) - (gnu packages base) - (gnu packages crates-io) - (gnu packages rust) - (gnu packages rust-apps) - (gnu packages sqlite) - (gnu packages tls) - (gnu packages pkg-config)) + (guix build-system gnu) + (guix licenses)) -(define-public echidnabot - (package - (name "echidnabot") - (version "0.1.0") - (source (local-file "." "echidnabot-checkout" - #:recursive? #t - #:select? (git-predicate "."))) - (build-system cargo-build-system) - (arguments - `(#:cargo-inputs - (;; Core async runtime - ("rust-tokio" ,rust-tokio-1) - ;; HTTP framework - ("rust-axum" ,rust-axum-0.7) - ("rust-tower" ,rust-tower-0.4) - ("rust-tower-http" ,rust-tower-http-0.5) - ;; Serialization - ("rust-serde" ,rust-serde-1) - ("rust-serde-json" ,rust-serde-json-1) - ("rust-toml" ,rust-toml-0.8) - ;; Database - ("rust-sqlx" ,rust-sqlx-0.8) - ;; HTTP client - ("rust-reqwest" ,rust-reqwest-0.11) - ;; Utilities - ("rust-uuid" ,rust-uuid-1) - ("rust-chrono" ,rust-chrono-0.4) - ("rust-thiserror" ,rust-thiserror-1) - ("rust-anyhow" ,rust-anyhow-1) - ("rust-tracing" ,rust-tracing-0.1) - ("rust-tracing-subscriber" ,rust-tracing-subscriber-0.3) - ;; Crypto - ("rust-hmac" ,rust-hmac-0.12) - ("rust-sha2" ,rust-sha2-0.10) - ("rust-hex" ,rust-hex-0.4) - ;; CLI - ("rust-clap" ,rust-clap-4) - ("rust-config" ,rust-config-0.14)) - #:cargo-development-inputs - (("rust-tokio-test" ,rust-tokio-test-0.4) - ("rust-tempfile" ,rust-tempfile-3)))) - (native-inputs - (list pkg-config - rust - rust-cargo)) - (inputs - (list sqlite - openssl)) - (synopsis "Proof-aware CI bot for theorem prover repositories") - (description - "echidnabot monitors code repositories containing formal proofs and -delegates verification to ECHIDNA Core. It integrates with GitHub, GitLab, -and Bitbucket to provide automated proof checking via webhooks.") - (home-page "https://github.com/hyperpolymath/echidnabot") - (license license:agpl3+))) - -;; For development shell -echidnabot +(package + (name "squisher-corpus") + (version "0.1.0") + (source #f) + (build-system gnu-build-system) + (synopsis "squisher-corpus") + (description "squisher-corpus — part of the hyperpolymath ecosystem.") + (home-page "https://github.com/hyperpolymath/squisher-corpus") + (license ((@@ (guix licenses) license) "PMPL-1.0-or-later" + "https://github.com/hyperpolymath/palimpsest-license"))) diff --git a/guix.scm b/guix.scm index e1a566da..c6dd7be8 100644 --- a/guix.scm +++ b/guix.scm @@ -1,5 +1,5 @@ ; SPDX-License-Identifier: MPL-2.0 -;; guix.scm — GNU Guix package definition for gitbot-fleet +;; guix.scm — GNU Guix package definition for squisher-corpus ;; Usage: guix shell -f guix.scm (use-modules (guix packages) @@ -7,12 +7,12 @@ (guix licenses)) (package - (name "gitbot-fleet") + (name "squisher-corpus") (version "0.1.0") (source #f) (build-system gnu-build-system) - (synopsis "gitbot-fleet") - (description "gitbot-fleet — part of the hyperpolymath ecosystem.") - (home-page "https://github.com/hyperpolymath/gitbot-fleet") - (license ((@@ (guix licenses) license) "MPL-2.0" + (synopsis "squisher-corpus") + (description "squisher-corpus — part of the hyperpolymath ecosystem.") + (home-page "https://github.com/hyperpolymath/squisher-corpus") + (license ((@@ (guix licenses) license) "PMPL-1.0-or-later" "https://github.com/hyperpolymath/palimpsest-license"))) diff --git a/scripts/fix-actions-policy.sh b/scripts/fix-actions-policy.sh new file mode 100755 index 00000000..b788f06f --- /dev/null +++ b/scripts/fix-actions-policy.sh @@ -0,0 +1,258 @@ +#!/bin/bash +# SPDX-License-Identifier: MPL-2.0 +# +# fix-actions-policy.sh — repair the estate-wide "Actions-policy CI outage" +# +# Driven by gitbot-fleet#362. An onboarding stamp set +# `allowed_actions=selected` + `sha_pinning_required=true` but never +# populated `patterns_allowed`, leaving it `[]`. An empty selected-list +# rejects every non-github-owned `uses:` at workflow-parse time, so the run +# dies as `startup_failure` with ZERO jobs — indistinguishable from "CI is +# broken" but actually a settings fault. +# +# MEASURED 2026-07-21: 80 of 306 scanned hyperpolymath repos are in this +# state (BROKEN-M1). `hyperpolymath` is a USER account, so there is no org +# lever and each repo needs its own settings PUT. `metadatastician` IS an +# Organization, where a single org-level PUT fixes every repo by +# inheritance (requires the `admin:org` token scope). +# +# ── Why this fixer is shaped differently to every other fix-*.sh ────────── +# Every other script in this directory takes a REPO_PATH and edits files, so +# its blast radius is a diff that a human reviews in a PR. This one writes +# repository *settings* through the API: there is no diff, no branch and no +# PR. Per #362 that means it must be report-by-default and gated. Hence: +# +# * default mode is --list (READ ONLY — never writes) +# * --apply is required to write, and is refused without an explicit mode +# * the HYPATIA_AUTOMATION kill switch halts writes instantly +# * the estate exclusion registry is consulted, FAIL-CLOSED, before writes +# * every PUT is GET-verified, and the sweep ABORTS if sha_pinning was +# silently reset (never trade pinning away for permissiveness) +# +# ── Target posture ─────────────────────────────────────────────────────── +# #362's decision of record was `allowed_actions=all` + sha_pinning. A +# parallel remediation (llm-coding-configs/claude-code/notification-storm- +# remediation/FINDINGS.md, 2026-07-21) established a STRICTLY SAFER route +# that fixes the same 98 repos WITHOUT widening anything: +# +# keep allowed_actions=selected, keep sha_pinning_required=true, +# and simply POPULATE the empty patterns_allowed list. +# +# Its evidence is a natural experiment over 426 repos: +# allowed_actions=all 286 repos -> wrappers run +# selected + `hyperpolymath/*` present 42 repos -> wrappers run +# selected + patterns_allowed=[] 98 repos -> ALL startup_failure +# i.e. the breakage is caused by the list being EMPTY, not by it existing. +# Populating it therefore restores CI while KEEPING the owner allowlist as a +# real control — so `selected` is the default here, and `--mode all` is the +# opt-in fallback rather than the target. +# +# NEVER disable sha_pinning_required. +# +# Idempotent: healthy repos are reported `ok` and skipped. +# +# Usage: +# fix-actions-policy.sh [--list|--apply] [--mode all|selected] +# [--limit N] [--jsonl FILE] [--repo NAME] +# +# Exit codes: 0 ok · 2 usage · 3 sha_pinning reset (ABORT) · 4 kill switch +# 5 exclusion registry unavailable while applying + +set -euo pipefail + +OWNER="" +ACTION="list" # list | apply (report-by-default) +MODE="selected" # selected (default, non-widening) | all (opt-in fallback) +ALLOWLIST="" # curated patterns_allowed JSON; defaults to standards' +LIMIT=500 +JSONL="" +ONE_REPO="" +FINDING_FILE="" # dispatch-runner contract: $2 is the finding JSON +STD_REPO="hyperpolymath/standards" + +die() { echo "fix-actions-policy: $*" >&2; exit "${2:-2}"; } + +while [ $# -gt 0 ]; do + case "$1" in + --list) ACTION="list" ;; + --apply) ACTION="apply" ;; + --mode) MODE="${2:-}"; shift ;; + --allowlist) ALLOWLIST="${2:-}"; shift ;; + --limit) LIMIT="${2:-}"; shift ;; + --jsonl) JSONL="${2:-}"; shift ;; + --repo) ONE_REPO="${2:-}"; shift ;; + -h|--help) sed -n '2,50p' "$0"; exit 0 ;; + -*) die "unknown flag: $1" ;; + *) if [ -z "$OWNER" ]; then OWNER="$1" + elif [ -z "$FINDING_FILE" ]; then FINDING_FILE="$1" # dispatch-runner passes finding JSON as $2 + else die "unexpected arg: $1"; fi ;; + esac + shift +done + +# ── Dual invocation contract ───────────────────────────────────────────── +# scripts/dispatch-runner.sh calls every fixer as `