From 35af8871bdc8708c33efb1ceef23c60eb9670c81 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 21 Jul 2026 07:06:14 +0100 Subject: [PATCH] chore: remove Guix/build scaffolding and complete the interrupted sweep The build/ directory (contractile.just, guix.scm, .guix-channel, setup.sh, just/*.just section imports) was RSR template scaffolding, not systemet content. Its deletion was already staged uncommitted in two estate repos (systemet + anytype) as an interrupted sweep; this commit completes it here so nothing dangles: - Justfile: drop the 7 dead `import?` lines, their section headers, and the guix-shell/guix-build recipes; `automate update` now calls recipes that exist (validate-claude-md, validate-coapt) - .envrc: drop the guix-shell block - .gitignore: keep the !/build/ exemption (build/just/proofs.just returns with the proof-gate PR) but correct the comment - root-allow.txt: remove the build/ entry; fix the Justfile justification - PLAYBOOK.a2ml / CONTRIBUTING.md / container docs / install-tools.sh: update prose that described the retired layout `just proofs`/`just validate` gates return for real (prover-absent = FAIL) in the forthcoming proof-gate PR. Co-Authored-By: Claude Fable 5 --- .envrc | 5 - .github/CONTRIBUTING.md | 5 +- .gitignore | 9 +- .machine_readable/6a2/PLAYBOOK.a2ml | 29 +- .machine_readable/root-allow.txt | 3 +- .../scripts/lifecycle/install-tools.sh | 9 +- EXPLAINME.adoc | 6 +- Justfile | 53 +--- build/.guix-channel | 22 -- build/contractile.just | 75 ----- build/guix.scm | 71 ----- build/just/assess.just | 225 -------------- build/just/container.just | 284 ----------------- build/just/groove.just | 98 ------ build/just/init.just | 214 ------------- build/just/proofs.just | 154 --------- build/just/validate.just | 130 -------- build/setup.sh | 294 ------------------ container/0.1-AI-MANIFEST.a2ml | 2 +- container/README.adoc | 30 +- 20 files changed, 36 insertions(+), 1682 deletions(-) delete mode 100644 build/.guix-channel delete mode 100644 build/contractile.just delete mode 100644 build/guix.scm delete mode 100644 build/just/assess.just delete mode 100644 build/just/container.just delete mode 100644 build/just/groove.just delete mode 100644 build/just/init.just delete mode 100644 build/just/proofs.just delete mode 100644 build/just/validate.just delete mode 100755 build/setup.sh diff --git a/.envrc b/.envrc index 0e3a43a..aef1a86 100644 --- a/.envrc +++ b/.envrc @@ -7,11 +7,6 @@ if has asdf; then use asdf fi -# Load Guix shell if guix.scm exists -if has guix && [ -f guix.scm ]; then - use guix -fi - # Project environment variables export PROJECT_NAME="systemet" export RSR_TIER="infrastructure" diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index dba0f50..77560d3 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -6,8 +6,8 @@ Copyright (c) Jonathan D.A. Jewell git clone https://github.com/hyperpolymath/systemet.git cd systemet -# Using Guix (recommended for reproducibility) -guix shell -D -f guix.scm +# Using asdf/mise (.tool-versions is the pin source) +mise install # or: asdf install # Or using toolbox/distrobox toolbox create systemet-dev @@ -49,7 +49,6 @@ systemet/ ├── MAINTAINERS.md ├── README.adoc ├── SECURITY.md -├── guix.scm # Guix package — primary (Perimeter 1) └── Justfile # Task runner (Perimeter 1) ``` diff --git a/.gitignore b/.gitignore index ccf874b..71efb37 100644 --- a/.gitignore +++ b/.gitignore @@ -109,11 +109,10 @@ deps/ build/ dist/ -# /build/ is a tracked config directory (build orchestration: contractile.just, -# guix.scm, just/*.just, etc.) introduced in chore/root-cleanup. Whitelist -# root-level /build/ so its contents are tracked. The blanket `build/` rule -# above still ignores any nested `build/` directories (e.g. Rust crate -# target/build/) — only the root-level path is exempt. +# Root-level /build/ is exempt from the blanket `build/` ignore above so that +# tracked task-runner modules (e.g. build/just/proofs.just) stay tracked. The +# Guix/contractile scaffolding that used to live here was removed; nested +# build/ directories (e.g. Rust crate target/build/) remain ignored. !/build/ !/build/** diff --git a/.machine_readable/6a2/PLAYBOOK.a2ml b/.machine_readable/6a2/PLAYBOOK.a2ml index 8bb8b22..db2ab12 100644 --- a/.machine_readable/6a2/PLAYBOOK.a2ml +++ b/.machine_readable/6a2/PLAYBOOK.a2ml @@ -56,15 +56,14 @@ enforcement-workflow = ".github/workflows/estate-rules.yml" # 0-AI-MANIFEST.a2ml AI agent work-allocation policy # LICENSE Repo license (root-bound by convention) # CHANGELOG.md One of the recognised .md exceptions (see below) -# Justfile Task runner — thin, imports per-section files from build/just/ +# Justfile Task runner — self-contained (build/ scaffolding retired; +# build/just/proofs.just returns with the proof gate) # coordination.k9 Repo-local session binding # === Required directories === # .github/ CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, workflows/ # .machine_readable/ AI manifests (0.1-AI-MANIFEST.a2ml), 6a2/ checkpoints, # contractiles/, configs/, anchors/, policies/, scripts/, self-validating/ -# build/ contractile.just, guix.scm, Containerfile, -# just/*.just (Justfile section imports) # docs/ onboarding/, status/, architecture/, governance/ (all .adoc) # session/ dispatch.sh, custom-checks.k9, local-hooks.sh # src/ Project source (Idris2 ABI under abi/, Zig FFI under ffi/) @@ -89,22 +88,14 @@ enforcement-workflow = ".github/workflows/estate-rules.yml" # # Enforcement: `scripts/check-no-vlang.sh`. -# === Justfile structure (post-split) === -# The root Justfile is thin — it holds `set` directives, project metadata -# variables, and the `default`/`help`/`info` recipes. Each major section -# lives in its own file under build/just/ and is brought in via `import?`. -# -# Imported sections (in the canonical split): -# build/just/init.just INIT recipe (template bootstrap) -# build/just/assess.just self-assess + verify (OpenSSF compliance) -# build/just/validate.just validate-rsr/state/ai-install + aggregate -# build/just/proofs.just proof-check-{all,idris2,lean4,agda,coq}, -# proof-scan-dangerous, proof-status -# build/just/groove.just Groove protocol setup (after zig removed) -# -# Daily-use recipes (BUILD, TEST, LINT, RUN, DEPS, DOCS, CONTAINER, CI, -# SECURITY, STATE, GUIX, MATRIX, VERSION CONTROL, UTILITIES, SESSION) -# stay in the root Justfile where users expect to find them. +# === Justfile structure === +# The root Justfile is self-contained. The template's build/just/ section +# split (init/assess/validate/groove) and the Guix scaffolding were retired +# in chore/remove-guix-build-scaffolding — those recipes served the RSR +# template lifecycle, not this repo. The one section that returns is +# FORMAL VERIFICATION: build/just/proofs.just (proof-check-{all,lean4,…}, +# proof-scan-dangerous, proof-status) is reintroduced by the proof-gate PR +# and imported via `import?`. # === 5-PR cleanup pattern === # Apply these branches (in order) to bring a non-conforming downstream repo diff --git a/.machine_readable/root-allow.txt b/.machine_readable/root-allow.txt index 07e7a77..de32260 100644 --- a/.machine_readable/root-allow.txt +++ b/.machine_readable/root-allow.txt @@ -27,7 +27,7 @@ CHANGELOG.md CITATION.cff # citation metadata (surfaced at root by #96) # ─── Build entry points (must live at root for their tooling) ──────────────── -Justfile # delegates phases to build/just/*.just +Justfile # task runner entry point (self-contained since build/ scaffolding removal) coordination.k9 # repo-local session binding (template-mandated) abi.ipkg # Idris2 package for the ABI seam; sourcedir=src/interface (estate canon: root-level *-abi.ipkg). Single case-consistent src/interface/Abi/ dir. Typecheck: `idris2 --typecheck abi.ipkg`. @@ -47,7 +47,6 @@ sonar-project.properties # SonarCloud analysis config; the SonarQube scan acti .github/ # CONTRIBUTING.md, CODE_OF_CONDUCT.md, SECURITY.md, workflows/ .machine_readable/ # AI manifests, contractiles, custom-format configs .well-known/ -build/ # contractile.just, setup.sh, guix.scm, .guix-channel, Containerfile ci/ # .gitlab-ci.yml, .pre-commit-config.yaml (root shims if tools require) docs/ # onboarding/, status/, governance/, ... docs-template/ # template-only: scaffolding docs copied into new repos diff --git a/.machine_readable/scripts/lifecycle/install-tools.sh b/.machine_readable/scripts/lifecycle/install-tools.sh index 6d2fa71..a27bd2a 100755 --- a/.machine_readable/scripts/lifecycle/install-tools.sh +++ b/.machine_readable/scripts/lifecycle/install-tools.sh @@ -3,16 +3,13 @@ # # install-tools.sh — Developer toolchain installer # -# Detects and installs the required project toolchain (Guix or asdf). +# Detects and installs the required project toolchain (asdf). set -euo pipefail echo "=== RSR Toolchain Installer ===" -if [ -f "guix.scm" ] && command -v guix &>/dev/null; then - echo "Guix detected. Verifying development shell..." - guix shell -f guix.scm -- true && echo "Guix shell verified." -elif [ -f ".tool-versions" ] && command -v asdf &>/dev/null; then +if [ -f ".tool-versions" ] && command -v asdf &>/dev/null; then echo "asdf detected. Installing plugins and tools..." while read -r line; do plugin=$(echo "$line" | awk '{print $1}') @@ -20,7 +17,7 @@ elif [ -f ".tool-versions" ] && command -v asdf &>/dev/null; then done < .tool-versions asdf install else - echo "No standard toolchain (Guix/asdf) detected or installed." + echo "No standard toolchain (asdf) detected or installed." echo "Please refer to README.adoc for manual setup instructions." fi diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index d22e440..a6047a3 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -165,9 +165,9 @@ infrastructure being part of the theory. How this is implemented: * `0-AI-MANIFEST.a2ml` is the AI-agent entry point; `.machine_readable/` holds - metadata, policy, contractiles, anchors, and agent-readable state; `just validate` - checks repository shape; `AFFIRMATION.adoc` is the dated honesty snapshot; - `AUDIT.adoc` is the release gate. + metadata, policy, contractiles, anchors, and agent-readable state; CI estate + workflows check repository shape; `AFFIRMATION.adoc` is the dated honesty + snapshot; `AUDIT.adoc` is the release gate. Caveat: diff --git a/Justfile b/Justfile index c6c157e..a010893 100644 --- a/Justfile +++ b/Justfile @@ -14,10 +14,6 @@ set shell := ["bash", "-uc"] set dotenv-load := true set positional-arguments := true -# Import auto-generated contractile recipes (must-check, trust-verify, etc.) -# Re-generate with: contractile gen-just -import? "build/contractile.just" - # Project metadata — customize these project := "rsr-template-repo" OWNER := "hyperpolymath" @@ -58,29 +54,6 @@ info: invariant-path *ARGS: ./scripts/invariant-path.sh {{ARGS}} -# ═══════════════════════════════════════════════════════════════════════════════ -# INIT — see build/just/init.just -# ═══════════════════════════════════════════════════════════════════════════════ - -import? "build/just/init.just" - -# >>> container-module (three-tier: OCI · portable engine · stapeln) >>> -# Self-contained. Remove the entire block — this and the import — with `just no-container`. -import? "build/just/container.just" -# <<< container-module <<< - -# ═══════════════════════════════════════════════════════════════════════════════ -# GROOVE PROTOCOL — see build/just/groove.just -# ═══════════════════════════════════════════════════════════════════════════════ - -import? "build/just/groove.just" - -# ═══════════════════════════════════════════════════════════════════════════════ -# PROJECT SELF-ASSESSMENT + OPENSSF COMPLIANCE — see build/just/assess.just -# ═══════════════════════════════════════════════════════════════════════════════ - -import? "build/just/assess.just" - # ═══════════════════════════════════════════════════════════════════════════════ # BUILD & COMPILE # ═══════════════════════════════════════════════════════════════════════════════ @@ -419,12 +392,6 @@ sbom: @mkdir -p docs/security @command -v syft >/dev/null && syft . -o spdx-json > docs/security/sbom.spdx.json || echo "syft not found" -# ═══════════════════════════════════════════════════════════════════════════════ -# VALIDATION & COMPLIANCE — see build/just/validate.just -# ═══════════════════════════════════════════════════════════════════════════════ - -import? "build/just/validate.just" - # ═══════════════════════════════════════════════════════════════════════════════ # STATE MANAGEMENT # ═══════════════════════════════════════════════════════════════════════════════ @@ -440,18 +407,6 @@ state-touch: state-phase: @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/6a2/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" -# ═══════════════════════════════════════════════════════════════════════════════ -# GUIX -# ═══════════════════════════════════════════════════════════════════════════════ - -# Enter Guix development shell (primary) -guix-shell: - guix shell -D -f guix.scm - -# Build with Guix -guix-build: - guix build -f guix.scm - # ═══════════════════════════════════════════════════════════════════════════════ # HYBRID AUTOMATION # ═══════════════════════════════════════════════════════════════════════════════ @@ -462,7 +417,7 @@ automate task="all": case "{{task}}" in all) just fmt && just lint && just test && just docs && just state-touch ;; cleanup) just clean && find . -name "*.orig" -delete && find . -name "*~" -delete ;; - update) just deps && just validate ;; + update) just deps && just validate-claude-md && just validate-coapt ;; *) echo "Unknown: {{task}}. Use: all, cleanup, update" && exit 1 ;; esac @@ -589,12 +544,6 @@ help-me: @echo "" @echo "Include the output of 'just doctor' in your report." -# ═══════════════════════════════════════════════════════════════════════════════ -# FORMAL VERIFICATION (PROOFS) — see build/just/proofs.just -# ═══════════════════════════════════════════════════════════════════════════════ - -import? "build/just/proofs.just" - # ═══════════════════════════════════════════════════════════════════════════════ # SESSION MANAGEMENT (THIN BINDINGS TO CENTRAL STANDARDS) # ═══════════════════════════════════════════════════════════════════════════════ diff --git a/build/.guix-channel b/build/.guix-channel deleted file mode 100644 index 7b28a7a..0000000 --- a/build/.guix-channel +++ /dev/null @@ -1,22 +0,0 @@ -;; SPDX-License-Identifier: MPL-2.0 -;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -;; -;; Guix channel definition for systemet -;; -;; To use this channel, add to ~/.config/guix/channels.scm: -;; -;; (channel -;; (name 'systemet) -;; (url "https://github.com/hyperpolymath/systemet") -;; (branch "main")) -;; -;; Then: guix pull - -(channel - (version 0) - (url "https://github.com/hyperpolymath/systemet") - (dependencies - (channel - (name 'guix) - (url "https://git.savannah.gnu.org/git/guix.git") - (branch "master")))) diff --git a/build/contractile.just b/build/contractile.just deleted file mode 100644 index 9a5827b..0000000 --- a/build/contractile.just +++ /dev/null @@ -1,75 +0,0 @@ -# Auto-generated by: contractile gen-just -# Source directory: contractiles -# Re-generate with: contractile gen-just --dir contractiles -# -# SPDX-License-Identifier: MPL-2.0 - -# === DUST (Recovery & Rollback) === -# Source: Dustfile.a2ml - -# List available dust recovery actions -dust-status: - @echo ' dust-source-rollback: Revert all source changes to last commit [rollback]' - -# Revert all source changes to last commit -dust-source-rollback: - @echo 'Executing rollback for source-rollback' - git checkout HEAD -- . - - -# === INTEND (Declared Future Intent) === -# Source: Intentfile.a2ml - -# Display declared future intents -intend-list: - @echo '=== Declared Intent ===' - @echo '' - @echo 'Features:' - @echo '' - @echo 'Quality:' - - -# === MUST (Physical State Checks) === -# Source: Mustfile.a2ml - -# Run all must checks -must-check: must-license-present must-readme-present must-spdx-headers must-no-banned-files - @echo 'All must checks passed' - -# LICENSE file must exist -must-license-present: - test -f LICENSE - -# README must exist -must-readme-present: - test -f README.adoc || test -f README.md - -# Source files should have SPDX license headers -must-spdx-headers: - find . -name '*.rs' -o -name '*.res' -o -name '*.gleam' | head -20 | xargs -r grep -L 'SPDX-License-Identifier' | wc -l | grep -q '^0$' - -# No Dockerfiles or Makefiles -must-no-banned-files: - test ! -f Dockerfile && test ! -f Makefile - - -# === TRUST (Integrity & Provenance Verification) === -# Source: Trustfile.a2ml - -# Run all trust verifications -trust-verify: trust-license-content trust-no-secrets-committed trust-container-images-pinned - @echo 'All trust verifications passed' - -# LICENSE contains expected SPDX identifier -trust-license-content: - grep -q 'SPDX\|License\|MIT\|Apache\|PMPL\|MPL' LICENSE - -# No .env or credential files in repo -trust-no-secrets-committed: - test ! -f .env && test ! -f credentials.json && test ! -f .env.local - -# Containerfile base images use pinned digests -trust-container-images-pinned: - test ! -f Containerfile || grep -q '@sha256:' Containerfile - - diff --git a/build/guix.scm b/build/guix.scm deleted file mode 100644 index 9f56d6b..0000000 --- a/build/guix.scm +++ /dev/null @@ -1,71 +0,0 @@ -;; SPDX-License-Identifier: MPL-2.0 -;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -;; -;; Guix package definition for systemet -;; -;; Usage: -;; guix shell -D -f guix.scm # Enter development shell -;; guix build -f guix.scm # Build package -;; -;; TODO: Replace systemet and customize inputs for your language/stack. -;; See: https://guix.gnu.org/manual/en/html_node/Defining-Packages.html - -(use-modules (guix packages) - (guix gexp) - (guix git-download) - (guix build-system gnu) - (guix licenses) - (gnu packages base)) - -(package - (name "systemet") - (version "0.1.0") - (source (local-file "." "source" - #:recursive? #t - #:select? (lambda (file stat) - (not (string-contains file ".git"))))) - (build-system gnu-build-system) - (arguments - '(#:phases - (modify-phases %standard-phases - ;; TODO: Customize build phases for your project - ;; Examples for common stacks: - ;; - ;; Rust: - ;; (replace 'build (lambda _ (invoke "cargo" "build" "--release"))) - ;; (replace 'check (lambda _ (invoke "cargo" "test"))) - ;; - ;; Elixir: - ;; (replace 'build (lambda _ (invoke "mix" "compile"))) - ;; (replace 'check (lambda _ (invoke "mix" "test"))) - ;; - ;; Zig: - ;; (replace 'build (lambda _ (invoke "zig" "build"))) - ;; (replace 'check (lambda _ (invoke "zig" "build" "test"))) - (delete 'configure) - (delete 'build) - (delete 'check) - (replace 'install - (lambda* (#:key outputs #:allow-other-keys) - (let ((out (assoc-ref outputs "out"))) - (mkdir-p (string-append out "/share/doc")) - (copy-file "README.adoc" - (string-append out "/share/doc/README.adoc")))))))) - (native-inputs - (list - ;; TODO: Add build-time dependencies - ;; Examples: - ;; rust (gnu packages rust) - ;; elixir (gnu packages elixir) - ;; zig (gnu packages zig) - )) - (inputs - (list - ;; TODO: Add runtime dependencies - )) - (home-page "https://github.com/hyperpolymath/systemet") - (synopsis "The Equality Theory specification and proof obligations that the anytype kernel implements.") - (description "RSR-compliant project. See README.adoc for details.") - (license (list - ;; MPL-2.0 extends MPL-2.0 - mpl2.0))) diff --git a/build/just/assess.just b/build/just/assess.just deleted file mode 100644 index 6e2a128..0000000 --- a/build/just/assess.just +++ /dev/null @@ -1,225 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# PROJECT SELF-ASSESSMENT + OPENSSF COMPLIANCE VERIFICATION -# -# Imported by ../../Justfile via `import? "build/just/assess.just"`. -# Recipes here advise on what to keep/remove (`self-assess`, read-only) and -# verify that OpenSSF Best Practices prerequisites are present (`verify`, -# called by `init` and CI). - -# Analyse this project and advise what to keep, remove, or leave for later. -# Does NOT modify any files — only prints recommendations. -self-assess: - #!/usr/bin/env bash - set -euo pipefail - - echo "═══════════════════════════════════════════════════" - echo " RSR Project Self-Assessment" - echo "═══════════════════════════════════════════════════" - echo "" - echo "Scanning project structure to identify what's" - echo "relevant, removable, or worth keeping for later..." - echo "" - - # Detect project characteristics - HAS_RUST=false; [ -f "Cargo.toml" ] && HAS_RUST=true - HAS_ELIXIR=false; [ -f "mix.exs" ] && HAS_ELIXIR=true - HAS_RESCRIPT=false; [ -f "rescript.json" ] || [ -f "bsconfig.json" ] && HAS_RESCRIPT=true - HAS_IDRIS=false; ls *.ipkg >/dev/null 2>&1 && HAS_IDRIS=true - HAS_ZIG=false; [ -f "build.zig" ] || [ -d "ffi/zig" ] && HAS_ZIG=true - HAS_GLEAM=false; [ -f "gleam.toml" ] && HAS_GLEAM=true - HAS_CONTAINER=false; [ -f "Containerfile" ] || [ -f "container/Containerfile" ] && HAS_CONTAINER=true - HAS_TESTS=false; [ -d "test" ] || [ -d "tests" ] || [ -d "__tests__" ] && HAS_TESTS=true - HAS_API=false; grep -rq 'port\|listen\|endpoint' --include="*.exs" --include="*.rs" --include="*.toml" . 2>/dev/null && HAS_API=true - IS_LIBRARY=false; [ -f "Cargo.toml" ] && grep -q '\[lib\]' Cargo.toml 2>/dev/null && IS_LIBRARY=true - - echo "Detected: Rust=$HAS_RUST Elixir=$HAS_ELIXIR ReScript=$HAS_RESCRIPT" - echo " Idris=$HAS_IDRIS Zig=$HAS_ZIG Gleam=$HAS_GLEAM" - echo " Container=$HAS_CONTAINER Tests=$HAS_TESTS API=$HAS_API" - echo "" - - # ── ESSENTIAL (removing these breaks RSR compliance) ────────── - echo "── ESSENTIAL (removing breaks Rhodium Standard) ──────────" - echo "" - - for f in LICENSE SECURITY.md CODE_OF_CONDUCT.md CONTRIBUTING.md .editorconfig .gitignore; do - if [ -f "$f" ]; then - echo " ✓ $f — KEEP (RSR required)" - else - echo " ✗ $f — MISSING (RSR violation!)" - fi - done - - if [ -d ".machine_readable/6a2" ]; then - echo " ✓ .machine_readable/6a2/ — KEEP (SCM checkpoint files)" - else - echo " ✗ .machine_readable/6a2/ — MISSING (RSR violation!)" - fi - - if [ -d ".github/workflows" ]; then - WF_COUNT=$(ls .github/workflows/*.yml 2>/dev/null | wc -l) - echo " ✓ .github/workflows/ — KEEP ($WF_COUNT workflows, RSR CI/CD)" - fi - echo "" - - # ── RELEVANT (useful for your project type) ─────────────────── - echo "── RELEVANT (matches your project) ───────────────────────" - echo "" - - if $HAS_IDRIS && { [ -d "src/interface/abi" ] || [ -d "src/interface/Abi" ]; }; then - echo " ✓ src/interface/abi/ — KEEP (Idris2 ABI definitions)" - elif ! $HAS_IDRIS && { [ -d "src/interface/abi" ] || [ -d "src/interface/Abi" ]; }; then - echo " ? src/interface/abi/ — No Idris2 detected." - echo " → KEEP if you plan to add formal verification later." - echo " → SAFE TO REMOVE if this project will never use Idris2." - echo " ⚠ Consequence: no formally verified interface definitions." - fi - - if $HAS_ZIG && [ -d "src/interface/ffi" ]; then - echo " ✓ src/interface/ffi/ — KEEP (Zig FFI bridge)" - elif ! $HAS_ZIG && [ -d "src/interface/ffi" ]; then - echo " ? src/interface/ffi/ — No Zig detected." - echo " → KEEP if you plan C ABI interop later." - echo " → SAFE TO REMOVE if this is a pure web/scripting project." - echo " ⚠ Consequence: no C-compatible FFI bridge." - fi - - if $HAS_API && [ -f ".machine_readable/integrations/groove.a2ml" ]; then - PORT=$(grep '(port ' .machine_readable/integrations/groove.a2ml 2>/dev/null | sed 's/.*(port \([0-9]*\)).*/\1/') - if [ "$PORT" = "0" ]; then - echo " ⚠ groove.a2ml — Port not assigned. Run 'just groove-setup'." - else - echo " ✓ groove.a2ml — KEEP (Groove discovery on port $PORT)" - fi - elif $HAS_API; then - echo " ✗ groove.a2ml — MISSING. Your project has an API but no Groove manifest." - echo " → Run 'just groove-setup' to enable snap-on/snap-off discovery." - fi - - if $HAS_CONTAINER && [ -d "container" ]; then - echo " ✓ container/ — KEEP (Containerfile + compose)" - elif ! $HAS_CONTAINER && [ -d "container" ]; then - echo " ? container/ — No Containerfile detected in use." - echo " → KEEP if you plan to containerise later." - echo " → SAFE TO REMOVE for libraries and CLI tools (run: just no-container)." - fi - - echo "" - - # ── SAFE TO REMOVE (not relevant, no consequences) ──────────── - echo "── SAFE TO REMOVE (no RSR consequences) ──────────────────" - echo "" - - if ! $HAS_RESCRIPT && [ -d "examples" ] && ls examples/*.res >/dev/null 2>&1; then - echo " ○ examples/*.res — Template ReScript examples. Not your code." - fi - - if [ -f ".machine_readable/ai/PLACEHOLDERS.adoc" ]; then - echo " ○ .machine_readable/ai/PLACEHOLDERS.adoc — Template doc. Remove after init." - fi - - if { [ -f "build/flake.nix" ] || [ -f "flake.nix" ]; } && ! command -v nix >/dev/null 2>&1; then - echo " ○ flake.nix — Nix flake. Safe to remove if you don't use Nix." - echo " → KEEP if others might build with Nix." - fi - - if { [ -f "build/guix.scm" ] || [ -f "guix.scm" ]; } && ! command -v guix >/dev/null 2>&1; then - echo " ○ guix.scm — Guix package. Safe to remove if you don't use Guix." - echo " → KEEP if others might build with Guix." - fi - - echo "" - - # ── FUTURE VALUE (not needed now, worth keeping) ────────────── - echo "── KEEP FOR FUTURE (not active, but valuable later) ──────" - echo "" - - if [ -d ".machine_readable/contractiles" ]; then - echo " ◆ contractiles/ — Must/Trust/Dust/Lust contracts." - echo " Not enforced until you configure them, but ready when you need" - echo " automated compliance checking. Zero cost to keep." - fi - - if [ -d ".machine_readable/bot_directives" ]; then - echo " ◆ bot_directives/ — Gitbot fleet configuration." - echo " Not active until gitbot-fleet is connected. Keeps your repo" - echo " ready for automated maintenance when the fleet arrives." - fi - - if [ -d ".machine_readable/bot_directives" ]; then - echo " ◆ bot_directives/ — AI agent methodology config." - echo " Guides Claude/Gemini/etc on how to work in this repo." - echo " No cost to keep. Improves AI assistance quality." - fi - - if [ -d "docs/governance" ]; then - echo " ◆ docs/governance/ — TSDM, CRG, maintenance checklists." - echo " Not needed for solo projects. Essential when you add contributors." - fi - - if [ -d "verification" ]; then - echo " ◆ verification/ — Proofs, benchmarks, fuzzing, safety case." - echo " Empty scaffolds until you add formal verification." - echo " Worth keeping for any project that claims safety properties." - fi - - echo "" - echo "═══════════════════════════════════════════════════" - echo " Assessment complete. No files were modified." - echo "═══════════════════════════════════════════════════" - -# Verify OpenSSF Best Practices prerequisites — fails if any required file is missing -verify: - #!/usr/bin/env bash - set -euo pipefail - - echo "=== OpenSSF Best Practices Verification ===" - ERRORS=0 - - check_file() { - if [ ! -f "$1" ]; then - echo " FAIL: $1 missing" - ERRORS=$((ERRORS + 1)) - else - echo " OK: $1" - fi - } - - # Accept either .md or .adoc for documentation files - check_either() { - if [ ! -f "$1" ] && [ ! -f "$2" ]; then - echo " FAIL: $1 (or $2) missing" - ERRORS=$((ERRORS + 1)) - else - local found="$1" - [ -f "$2" ] && found="$2" - [ -f "$1" ] && found="$1" - echo " OK: $found" - fi - } - - check_either "SECURITY.md" "SECURITY.adoc" - check_file "LICENSE" - check_either "CONTRIBUTING.md" "CONTRIBUTING.adoc" - check_either "README.adoc" "README.md" - check_file ".machine_readable/6a2/STATE.a2ml" - check_file ".machine_readable/6a2/META.a2ml" - check_file ".machine_readable/6a2/ECOSYSTEM.a2ml" - check_either "CHANGELOG.md" "CHANGELOG.adoc" - - # Check at least 1 workflow exists - WORKFLOW_COUNT=$(find .github/workflows -name '*.yml' -o -name '*.yaml' 2>/dev/null | wc -l) - if [ "$WORKFLOW_COUNT" -eq 0 ]; then - echo " FAIL: No workflows in .github/workflows/" - ERRORS=$((ERRORS + 1)) - else - echo " OK: .github/workflows/ ($WORKFLOW_COUNT workflows)" - fi - - echo "" - if [ "$ERRORS" -gt 0 ]; then - echo "FAIL: $ERRORS OpenSSF prerequisites missing — repo cannot ship." - exit 1 - fi - echo "PASS: All OpenSSF Best Practices prerequisites satisfied." diff --git a/build/just/container.just b/build/just/container.just deleted file mode 100644 index c5728a9..0000000 --- a/build/just/container.just +++ /dev/null @@ -1,284 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# CONTAINERS — three-tier containerisation -# -# Imported by ../../Justfile via `import? "build/just/container.just"`. -# Variables (project, OWNER, ...) and `set shell` are inherited from the root. -# -# Tier A — OCI standard: container/Containerfile, container/.containerignore -# Tier B — portable engine: container/compose.yaml (podman | nerdctl | docker) -# Tier C — stapeln sovereign: container/stapeln/ (cerro-torre, svalinn, -# vordr, selur, rokur, k9) -# -# Engine is auto-selected: $CONTAINER_ENGINE, else the first of podman / -# nerdctl / docker found on PATH. Override with: CONTAINER_ENGINE=docker just … -# -# Narrow the template to the tiers you want (see the Narrowing section below): -# just container-keep oci portable # keep image + portable compose, drop the rest -# just no-stapeln | no-devcontainer | no-container # convenience aliases - -# ── Engine detection (shared snippet) ────────────────────────────────────── -# Resolves the OCI engine into $ENGINE. Sourced at the top of each recipe. -_engine := ''' - ENGINE="${CONTAINER_ENGINE:-}" - if [ -z "$ENGINE" ]; then - for e in podman nerdctl docker; do - if command -v "$e" >/dev/null 2>&1; then ENGINE="$e"; break; fi - done - fi - if [ -z "$ENGINE" ]; then - echo "No container engine found (looked for podman, nerdctl, docker)." >&2 - echo "Install one or set CONTAINER_ENGINE." >&2 - exit 1 - fi -''' - -# Initialise container templates — substitute placeholders with project values -container-init: - #!/usr/bin/env bash - set -euo pipefail - - if [ ! -d "container" ]; then - echo "Error: container/ directory not found." - echo "This repo may not have been created from rsr-template-repo," - echo "or containerisation was removed with 'just no-container'." - exit 1 - fi - - echo "=== Container Template Initialisation ===" - echo "" - - # Load RSR defaults if available - DEFAULTS="${XDG_CONFIG_HOME:-$HOME/.config}/rsr/defaults" - if [ -f "$DEFAULTS" ]; then - echo "Loading defaults from $DEFAULTS" - # shellcheck source=/dev/null - source "$DEFAULTS" - echo "" - fi - - # Prompt for container-specific values - read -rp "Service name (e.g. my-api) [{{project}}]: " _SERVICE_NAME - SERVICE_NAME="${_SERVICE_NAME:-{{project}}}" - - read -rp "Primary port [8080]: " _PORT - PORT="${_PORT:-8080}" - - read -rp "Container registry [ghcr.io/${OWNER:-{{OWNER}}}]: " _REGISTRY - REGISTRY="${_REGISTRY:-ghcr.io/${OWNER:-{{OWNER}}}}" - - echo "" - echo " Service: $SERVICE_NAME" - echo " Port: $PORT" - echo " Registry: $REGISTRY" - echo "" - read -rp "Proceed? [Y/n] " CONFIRM - [[ "${CONFIRM:-Y}" =~ ^[Nn] ]] && echo "Aborted." && exit 0 - - echo "" - echo "Replacing container placeholders..." - - # Brace tokens as variables (hex escapes avoid just interpolation) - LB=$(printf '\x7b\x7b') - RB=$(printf '\x7d\x7d') - - SED_ARGS=( - -e "s|${LB}SERVICE_NAME${RB}|${SERVICE_NAME}|g" - -e "s|${LB}PORT${RB}|${PORT}|g" - -e "s|${LB}REGISTRY${RB}|${REGISTRY}|g" - ) - - # Recurses into container/stapeln/ as well. - find container/ -type f | while read -r file; do - if file --brief "$file" | grep -qi 'text\|ascii\|utf'; then - sed -i "${SED_ARGS[@]}" "$file" - fi - done - - echo "Container templates initialised." - echo "" - echo "Next steps:" - echo " 1. Edit container/Containerfile — add your build commands (Tier A)" - echo " 2. Edit container/entrypoint.sh — set your application binary" - echo " 3. Review container/compose.yaml — portable stack (Tier B)" - echo " 4. Review container/stapeln/ — sovereign stack (Tier C)" - echo " 5. Build: just container-build" - -# Build container image (cerro-torre pipeline if present, else plain OCI build) -container-build *args: - #!/usr/bin/env bash - set -euo pipefail - {{_engine}} - if [ -f "container/stapeln/ct-build.sh" ]; then - cd container/stapeln && CONTAINER_ENGINE="$ENGINE" ./ct-build.sh {{args}} - elif [ -f "container/Containerfile" ]; then - "$ENGINE" build -t {{project}}:latest -f container/Containerfile . - elif [ -f "Containerfile" ]; then - "$ENGINE" build -t {{project}}:latest -f Containerfile . - else - echo "No Containerfile found in container/ or project root" - exit 1 - fi - -# Pick the compose path: selur-compose (sovereign) if installed, else portable -_compose action *args: - #!/usr/bin/env bash - set -euo pipefail - {{_engine}} - if command -v selur-compose >/dev/null 2>&1 && [ -f "container/stapeln/compose.toml" ]; then - ( cd container/stapeln && selur-compose {{action}} {{args}} ) - elif [ -f "container/compose.yaml" ]; then - "$ENGINE" compose -f container/compose.yaml {{action}} {{args}} - else - echo "No compose file found (container/stapeln/compose.toml or container/compose.yaml)" - exit 1 - fi - -# Verify compose configuration (selur-compose verify, else compose config) -container-verify: - #!/usr/bin/env bash - set -euo pipefail - {{_engine}} - if command -v selur-compose >/dev/null 2>&1 && [ -f "container/stapeln/compose.toml" ]; then - ( cd container/stapeln && selur-compose verify ) - elif [ -f "container/compose.yaml" ]; then - "$ENGINE" compose -f container/compose.yaml config - else - echo "No compose file found (container/stapeln/compose.toml or container/compose.yaml)" - exit 1 - fi - -# Start the container stack (selur-compose if available, else $ENGINE compose) -container-up *args: - @just _compose up {{args}} - -# Stop the container stack -container-down *args: - @just _compose down {{args}} - -# Sign and verify the container bundle (cerro-torre: build + pack + sign + verify) -container-sign: - #!/usr/bin/env bash - set -euo pipefail - if [ -f "container/stapeln/ct-build.sh" ]; then - cd container/stapeln && ./ct-build.sh - else - echo "No container/stapeln/ct-build.sh found" - exit 1 - fi - -# Push the signed bundle (or plain image) to the registry -container-push: - #!/usr/bin/env bash - set -euo pipefail - {{_engine}} - if [ -f "container/stapeln/ct-build.sh" ]; then - cd container/stapeln && CONTAINER_ENGINE="$ENGINE" ./ct-build.sh --push - else - echo "No container/stapeln/ct-build.sh found — falling back to $ENGINE push" - "$ENGINE" push {{project}}:latest - fi - -# Run the container interactively (for debugging) -container-run *args: - #!/usr/bin/env bash - set -euo pipefail - {{_engine}} - "$ENGINE" run --rm -it {{project}}:latest {{args}} - -# Container matrix: [build|run|push|shell|scan] x [registry] x [tag] -container-matrix action="build" registry="ghcr.io/{{OWNER}}" tag="latest": - @echo "Container matrix: action={{action}} registry={{registry}} tag={{tag}}" - -# ── Narrowing / opt-out ────────────────────────────────────────────────────── -# -# `container-keep` is the workhorse: declare exactly which tiers to KEEP; the -# rest are removed. Tiers: oci (A) · portable (B) · stapeln (C) · devcontainer. -# Idempotent — safe to re-run. The aliases below are thin wrappers. -# -# just container-keep oci # bare OCI image only -# just container-keep oci portable # image + portable compose -# just container-keep oci portable stapeln # full prod stack, no dev container -# just container-keep all # no-op (keep everything) -# just container-keep none # remove everything (= no-container) -# DRY_RUN=1 just container-keep oci # show what would change, do nothing -# FORCE=1 just container-keep oci # skip the confirm prompt -# -# Accepts space- or comma-separated tokens, and aliases: a/A, b/B/compose, -# c/C/sovereign, dev. 'portable'/'stapeln' require 'oci' (they build the image). -container-keep +tiers: - #!/usr/bin/env bash - set -euo pipefail - - sel="$(echo "$@" | tr ',' ' ')" - keep_oci=false keep_port=false keep_stap=false keep_dev=false - for t in $sel; do - case "$t" in - all) keep_oci=true; keep_port=true; keep_stap=true; keep_dev=true ;; - none) : ;; - oci|a|A) keep_oci=true ;; - portable|compose|b|B) keep_port=true ;; - stapeln|sovereign|c|C) keep_stap=true ;; - devcontainer|dev) keep_dev=true ;; - *) echo "Unknown tier '$t'. Valid: oci portable stapeln devcontainer | all | none" >&2; exit 1 ;; - esac - done - - # Coherence: tiers B and C build the OCI image, so they need tier A. - if { $keep_port || $keep_stap; } && ! $keep_oci; then - echo "Incoherent selection: 'portable'/'stapeln' build the OCI image — add 'oci'." >&2 - exit 1 - fi - - # Build the removal plan. - plan=() - $keep_dev || plan+=(".devcontainer/ (dev container)") - if $keep_oci; then - $keep_stap || plan+=("container/stapeln/ (cerro-torre, svalinn, vordr, selur, rokur, k9)") - $keep_port || plan+=("container/compose.yaml + compose.example.yaml (portable stack)") - else - plan+=("container/ (entire image + compose + stapeln)") - plan+=("build/just/container.just (this module) + its Justfile import") - [ -f .github/workflows/container-build.yml ] && plan+=(".github/workflows/container-build.yml") - fi - - echo "Keeping: oci=$keep_oci portable=$keep_port stapeln=$keep_stap devcontainer=$keep_dev" - if [ ${#plan[@]} -eq 0 ]; then echo "Nothing to remove — selection already matches."; exit 0; fi - echo "Will remove:"; printf ' - %s\n' "${plan[@]}" - - if [ "${DRY_RUN:-}" = "1" ]; then echo "(DRY_RUN — no changes made)"; exit 0; fi - if [ "${FORCE:-}" != "1" ]; then - read -rp "Proceed? [y/N] " c; [[ "${c:-N}" =~ ^[Yy] ]] || { echo "Aborted."; exit 0; } - fi - - # Apply. - $keep_dev || rm -rf .devcontainer - if $keep_oci; then - $keep_stap || rm -rf container/stapeln - $keep_port || rm -f container/compose.yaml container/compose.example.yaml - else - rm -rf container - rm -f .machine_readable/configs/selur-compose.toml - rm -f .github/workflows/container-build.yml - rm -f build/just/container.just - [ -f Justfile ] && sed -i '/# >>> container-module/,/# <<< container-module/d' Justfile - for jf in Justfile .machine_readable/contractiles/Justfile; do - [ -f "$jf" ] && sed -i '\|import? "build/just/container.just"|d' "$jf" - done - fi - - echo "" - echo "Done. Review .github/workflows/ for image build/publish jobs you no longer need." - -# Remove ALL containerisation (image, compose, stapeln, dev container) -no-container: - @just container-keep none - -# Drop only the stapeln sovereign tier (keep OCI image + portable compose + dev container) -no-stapeln: - @just container-keep oci portable devcontainer - -# Drop only the dev container (keep the full image/compose/stapeln stack) -no-devcontainer: - @just container-keep oci portable stapeln diff --git a/build/just/groove.just b/build/just/groove.just deleted file mode 100644 index 029a9bd..0000000 --- a/build/just/groove.just +++ /dev/null @@ -1,98 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# GROOVE PROTOCOL -# -# Imported by ../../Justfile via `import? "build/just/groove.just"`. -# Recipes here configure and validate the Groove protocol manifest at -# .machine_readable/integrations/groove.a2ml — port assignment, API surface -# flags (REST/gRPC/GraphQL/WebSocket/SSE), and template-placeholder hygiene. -# The manifest itself is consumed by the Groove bridge / zig-unified-api-adapter. - -# Configure Groove protocol manifest (port assignment, API surfaces) -groove-setup: - #!/usr/bin/env bash - set -euo pipefail - MANIFEST=".machine_readable/integrations/groove.a2ml" - if [ ! -f "$MANIFEST" ]; then - echo "Error: $MANIFEST not found. Run 'just init' first." - exit 1 - fi - - echo "═══════════════════════════════════════════════════" - echo " Groove Protocol Setup" - echo "═══════════════════════════════════════════════════" - echo "" - echo "Check PORT-REGISTRY.md before assigning a port:" - echo " https://github.com/hyperpolymath/standards/blob/main/PORT-REGISTRY.md" - echo "" - - read -rp "Primary port for this service: " PORT - [ -z "$PORT" ] && echo "Error: port required" && exit 1 - - echo "" - echo "Which API surfaces does this project expose?" - read -rp " REST API? [Y/n]: " REST - read -rp " gRPC? [y/N]: " GRPC - read -rp " GraphQL? [y/N]: " GRAPHQL - read -rp " WebSocket? [y/N]: " WS - read -rp " SSE (Server-Sent Events)? [y/N]: " SSE - - # Update port in manifest - sed -i "s/(port 0)/(port ${PORT})/" "$MANIFEST" - - # Update API surface flags - [[ "${GRPC,,}" == "y" ]] && sed -i 's/(grpc.*enabled false)/(grpc (enabled true)/' "$MANIFEST" - [[ "${GRAPHQL,,}" == "y" ]] && sed -i 's/(graphql.*enabled false)/(graphql (enabled true)/' "$MANIFEST" - [[ "${WS,,}" == "y" ]] && sed -i 's/(websocket.*enabled false)/(websocket (enabled true)/' "$MANIFEST" - [[ "${SSE,,}" == "y" ]] && sed -i 's/(sse.*enabled false)/(sse (enabled true)/' "$MANIFEST" - - echo "" - echo "Groove manifest updated: $MANIFEST" - echo "Port ${PORT} assigned. Add to PORT-REGISTRY.md if not already there." - -# Check for template placeholders that haven't been replaced -verify-template: - #!/usr/bin/env bash - set -euo pipefail - echo "Checking for unreplaced template placeholders..." - FOUND=0 - - # Check for double-brace placeholder patterns - HITS=$(grep -rn '{{'{{'}}[A-Z_]*{{'}}'}}' --include="*.adoc" --include="*.md" --include="*.a2ml" \ - --include="*.scm" --include="*.toml" --include="*.yml" --include="*.yaml" \ - . 2>/dev/null | grep -v 'node_modules\|\.git/' | grep -v 'PLACEHOLDERS.adoc' || true) - if [ -n "$HITS" ]; then - echo "" - echo "⚠ Unreplaced placeholders found:" - echo "$HITS" | head -20 - FOUND=1 - fi - - # Check for template defaults still present - if grep -q 'rsr-template-repo' Justfile 2>/dev/null; then - echo "⚠ Justfile still references 'rsr-template-repo' — update project name" - FOUND=1 - fi - - # Check for port 0 in Groove manifest - if grep -q '(port 0)' .machine_readable/integrations/groove.a2ml 2>/dev/null; then - echo "⚠ Groove manifest has port 0 — run 'just groove-setup' to assign a port" - FOUND=1 - fi - - # Check for empty SCM files - for f in .machine_readable/6a2/STATE.a2ml .machine_readable/6a2/META.a2ml .machine_readable/6a2/ECOSYSTEM.a2ml; do - if [ -f "$f" ] && grep -q '{{'{{'}}' "$f" 2>/dev/null; then - echo "⚠ $f still has template placeholders" - FOUND=1 - fi - done - - if [ $FOUND -eq 0 ]; then - echo "✓ No template placeholders found — project is properly customised." - else - echo "" - echo "Run 'just init' to replace placeholders, or edit files manually." - exit 1 - fi diff --git a/build/just/init.just b/build/just/init.just deleted file mode 100644 index 746b4f6..0000000 --- a/build/just/init.just +++ /dev/null @@ -1,214 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# INIT — Bootstrap a new project from this template -# -# Imported by ../../Justfile via `import? "build/just/init.just"`. -# Variables (project, OWNER, REPO, version, tier) and the `set shell` directive -# are inherited from the root Justfile. - -# Interactive project bootstrap — replaces all {{PLACEHOLDER}} tokens -init: - #!/usr/bin/env bash - set -euo pipefail - - echo "═══════════════════════════════════════════════════" - echo " RSR Project Bootstrap" - echo "═══════════════════════════════════════════════════" - echo "" - - # --- Load defaults from config (if exists) --- - # Create yours: ~/.config/rsr/defaults - # Format: OWNER=myorg AUTHOR="My Name" AUTHOR_EMAIL=me@example.org ... - DEFAULTS="${XDG_CONFIG_HOME:-$HOME/.config}/rsr/defaults" - if [ -f "$DEFAULTS" ]; then - echo "Loading defaults from $DEFAULTS" - # shellcheck source=/dev/null - source "$DEFAULTS" - echo "" - fi - - # --- Required values (pre-filled from defaults if available) --- - read -rp "Project name (human-readable, e.g. My Project): " PROJECT_NAME - [ -z "$PROJECT_NAME" ] && echo "Error: project name required" && exit 1 - - read -rp "Repository slug (e.g. my-project): " REPO - [ -z "$REPO" ] && echo "Error: repo slug required" && exit 1 - - read -rp "Owner [${OWNER:-}]: " _OWNER - OWNER="${_OWNER:-${OWNER:-}}" - [ -z "$OWNER" ] && echo "Error: owner required" && exit 1 - - read -rp "Author full name [${AUTHOR:-}]: " _AUTHOR - AUTHOR="${_AUTHOR:-${AUTHOR:-}}" - [ -z "$AUTHOR" ] && echo "Error: author name required" && exit 1 - - read -rp "Author email [${AUTHOR_EMAIL:-}]: " _AUTHOR_EMAIL - AUTHOR_EMAIL="${_AUTHOR_EMAIL:-${AUTHOR_EMAIL:-}}" - [ -z "$AUTHOR_EMAIL" ] && echo "Error: email required" && exit 1 - - # --- Optional values (pre-filled from defaults if available) --- - read -rp "Author organization [${AUTHOR_ORG:-none}]: " _AUTHOR_ORG - AUTHOR_ORG="${_AUTHOR_ORG:-${AUTHOR_ORG:-}}" - - read -rp "Previous/alt email [${AUTHOR_EMAIL_ALT:-none}]: " _AUTHOR_EMAIL_ALT - AUTHOR_EMAIL_ALT="${_AUTHOR_EMAIL_ALT:-${AUTHOR_EMAIL_ALT:-}}" - - read -rp "Project description []: " PROJECT_DESCRIPTION - - read -rp "Forge domain [${FORGE:-github.com}]: " _FORGE - FORGE="${_FORGE:-${FORGE:-github.com}}" - - read -rp "Security contact email [${SECURITY_EMAIL:-$AUTHOR_EMAIL}]: " _SECURITY_EMAIL - SECURITY_EMAIL="${_SECURITY_EMAIL:-${SECURITY_EMAIL:-$AUTHOR_EMAIL}}" - - read -rp "Conduct contact email [${CONDUCT_EMAIL:-$AUTHOR_EMAIL}]: " _CONDUCT_EMAIL - CONDUCT_EMAIL="${_CONDUCT_EMAIL:-${CONDUCT_EMAIL:-$AUTHOR_EMAIL}}" - - read -rp "Project type (library|binary|monorepo|service|website) [library]: " PROJECT_TYPE - PROJECT_TYPE="${PROJECT_TYPE:-library}" - - read -rp "Website URL [https://${FORGE}/${OWNER}/${REPO}]: " WEBSITE - WEBSITE="${WEBSITE:-https://${FORGE}/${OWNER}/${REPO}}" - - # --- Container values (optional — only relevant if container/ exists) --- - if [ -d "container" ]; then - echo "" - echo "── Container configuration (optional) ─────────" - read -rp "Service name [${REPO}]: " _SERVICE_NAME - SERVICE_NAME="${_SERVICE_NAME:-${REPO}}" - read -rp "Primary port [8080]: " _PORT - PORT="${_PORT:-8080}" - read -rp "Container registry [ghcr.io/${OWNER}]: " _REGISTRY - REGISTRY="${_REGISTRY:-ghcr.io/${OWNER}}" - else - SERVICE_NAME="${REPO}" - PORT="8080" - REGISTRY="ghcr.io/${OWNER}" - fi - - # --- Derived values --- - PROJECT_UPPER=$(echo "$REPO" | tr '[:lower:]-' '[:upper:]_') - PROJECT_LOWER=$(echo "$REPO" | tr '[:upper:]-' '[:lower:]_') - CURRENT_YEAR=$(date +%Y) - CURRENT_DATE=$(date +%Y-%m-%d) - VERSION="0.1.0" - - # Derive citation name parts (best-effort split on last space) - AUTHOR_LAST="${AUTHOR##* }" - AUTHOR_FIRST="${AUTHOR% *}" - FIRST_INITIAL="${AUTHOR_FIRST:0:1}." - if [ "$AUTHOR_LAST" = "$AUTHOR_FIRST" ]; then - AUTHOR_FIRST="$AUTHOR" - AUTHOR_LAST="" - FIRST_INITIAL="" - fi - - echo "" - echo "── Summary ──────────────────────────────────────" - echo " Project: $PROJECT_NAME" - echo " Repo: $REPO" - echo " Owner: $OWNER" - echo " Author: $AUTHOR <$AUTHOR_EMAIL>" - [ -n "$AUTHOR_ORG" ] && echo " Organization: $AUTHOR_ORG" - echo " Forge: $FORGE" - echo " Year: $CURRENT_YEAR" - echo "────────────────────────────────────────────────" - echo "" - read -rp "Proceed? [Y/n] " CONFIRM - [[ "${CONFIRM:-Y}" =~ ^[Nn] ]] && echo "Aborted." && exit 0 - - echo "" - echo "Replacing placeholders..." - - # Brace tokens as variables (hex avoids just interpolation) - LB=$(printf '\x7b\x7b') - RB=$(printf '\x7d\x7d') - - # Build the sed expression list - # Note: using | as delimiter since URLs contain / - SED_ARGS=( - -e "s|${LB}PROJECT_NAME${RB}|${PROJECT_NAME}|g" - -e "s|${LB}PROJECT_DESCRIPTION${RB}|${PROJECT_DESCRIPTION}|g" - -e "s|${LB}PROJECT${RB}|${PROJECT_UPPER}|g" - -e "s|${LB}project${RB}|${PROJECT_LOWER}|g" - -e "s|${LB}REPO${RB}|${REPO}|g" - -e "s|${LB}OWNER${RB}|${OWNER}|g" - -e "s|${LB}AUTHOR${RB}|${AUTHOR}|g" - -e "s|${LB}AUTHOR_EMAIL${RB}|${AUTHOR_EMAIL}|g" - -e "s|${LB}AUTHOR_ORG${RB}|${AUTHOR_ORG}|g" - -e "s|${LB}AUTHOR_LAST${RB}|${AUTHOR_LAST}|g" - -e "s|${LB}AUTHOR_FIRST${RB}|${AUTHOR_FIRST}|g" - -e "s|${LB}AUTHOR_INITIALS${RB}|${FIRST_INITIAL}|g" - -e "s|${LB}FORGE${RB}|${FORGE}|g" - -e "s|${LB}CURRENT_YEAR${RB}|${CURRENT_YEAR}|g" - -e "s|${LB}CURRENT_DATE${RB}|${CURRENT_DATE}|g" - -e "s|${LB}DATE${RB}|${CURRENT_DATE}|g" - -e "s|${LB}SECURITY_EMAIL${RB}|${SECURITY_EMAIL}|g" - -e "s|${LB}CONDUCT_EMAIL${RB}|${CONDUCT_EMAIL}|g" - -e "s|${LB}LICENSE${RB}|MPL-2.0|g" - -e "s|${LB}CONDUCT_TEAM${RB}|Code of Conduct Committee|g" - -e "s|${LB}RESPONSE_TIME${RB}|48 hours|g" - -e "s|${LB}MAIN_BRANCH${RB}|main|g" - -e "s|${LB}PROJECT_PURPOSE${RB}|${PROJECT_DESCRIPTION}|g" - -e "s|${LB}PROJECT_ROLE${RB}|${PROJECT_TYPE}|g" - -e "s|${LB}PROJECT_TYPE${RB}|${PROJECT_TYPE}|g" - -e "s|${LB}WEBSITE${RB}|${WEBSITE}|g" - -e "s|${LB}SERVICE_NAME${RB}|${SERVICE_NAME}|g" - -e "s|${LB}PORT${RB}|${PORT}|g" - -e "s|${LB}REGISTRY${RB}|${REGISTRY}|g" - -e "s|${LB}IMAGE${RB}|${REGISTRY}/${SERVICE_NAME}|g" - -e "s|${LB}VERSION${RB}|${VERSION}|g" - -e "s|${LB}EMAIL${RB}|${AUTHOR_EMAIL}|g" - ) - [ -n "$AUTHOR_EMAIL_ALT" ] && SED_ARGS+=(-e "s|${LB}AUTHOR_EMAIL_ALT${RB}|${AUTHOR_EMAIL_ALT}|g") - - # Replace in all text files (skip .git, LICENSE text, and binaries) - find . -type f \ - -not -path './.git/*' \ - -not -name 'MPL-2.0.txt' \ - -not -name '*.png' -not -name '*.jpg' -not -name '*.gif' \ - -not -name '*.woff' -not -name '*.woff2' \ - | while read -r file; do - if file --brief "$file" | grep -qi 'text\|ascii\|utf'; then - sed -i "${SED_ARGS[@]}" "$file" - fi - done - - # Also replace [YOUR-REPO-NAME] and [YOUR-NAME/ORG] in AI manifest - sed -i "s|\[YOUR-REPO-NAME\]|${PROJECT_NAME}|g" 0-AI-MANIFEST.a2ml 2>/dev/null || true - sed -i "s|\[YOUR-NAME/ORG\]|${OWNER}|g" 0-AI-MANIFEST.a2ml 2>/dev/null || true - - echo "" - echo "── Validation ───────────────────────────────────" - - # Check for remaining placeholders - PATTERN="${LB}[A-Z_]*${RB}" - REMAINING=$(grep -rl "$PATTERN" . --include='*.md' --include='*.adoc' --include='*.yml' --include='*.yaml' --include='*.a2ml' --include='*.toml' --include='*.scm' --include='*.ncl' --include='*.nix' --include='*.json' --include='*.sh' 2>/dev/null | grep -v '.git/' | grep -v '.machine_readable/ai/PLACEHOLDERS.adoc' || true) - if [ -n "$REMAINING" ]; then - echo "WARNING: Remaining placeholders in:" - echo "$REMAINING" | sed 's/^/ /' - echo "" - echo "Run: grep -rn '$LB' . --include='*.md' to inspect" - else - echo "All placeholders replaced successfully!" - fi - - # K9-SVC validation (if available) - if command -v k9-svc >/dev/null 2>&1; then - echo "" - echo "Running k9-svc validation..." - k9-svc validate . 2>/dev/null || true - fi - - echo "" - echo "Running OpenSSF compliance verification..." - just verify - - echo "" - echo "Done! Next steps:" - echo " 1. Review changes: git diff" - echo " 2. Remove template cruft: rm .machine_readable/ai/PLACEHOLDERS.adoc" - echo " 3. Customize README.adoc for your project" - echo " 4. Commit: git add -A && git commit -m 'feat: initialize from RSR template'" - echo " 5. Push: git remote add origin git@${FORGE}:${OWNER}/${REPO}.git && git push -u origin main" diff --git a/build/just/proofs.just b/build/just/proofs.just deleted file mode 100644 index b124d7a..0000000 --- a/build/just/proofs.just +++ /dev/null @@ -1,154 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# FORMAL VERIFICATION (PROOFS) -# -# Imported by ../../Justfile via `import? "build/just/proofs.just"`. -# Recipes here check formal proofs across Idris2, Lean4, Agda, and Coq, plus -# scan for dangerous/unsafe constructs and report status. Run via -# `just proof-check-all` for the full sweep. - -# Check all formal proofs (Idris2 + Lean4 + Agda + Coq) -proof-check-all: proof-check-idris2 proof-check-lean4 proof-check-agda proof-check-coq proof-scan-dangerous - @echo "=== All proof checks complete ===" - -# Check Idris2 proofs (ABI, types, dependent type proofs) -proof-check-idris2: - #!/usr/bin/env bash - set -euo pipefail - echo "=== Checking Idris2 proofs ===" - if ! command -v idris2 &>/dev/null; then - echo "SKIP: idris2 not installed" - exit 0 - fi - ERRORS=0 - for f in $(find verification/proofs/idris2 -name '*.idr' 2>/dev/null); do - echo -n " Checking $f ... " - if idris2 --check "$f" 2>/dev/null; then - echo "OK" - else - echo "FAIL" - ERRORS=$((ERRORS + 1)) - fi - done - if [ "$ERRORS" -gt 0 ]; then - echo "FAIL: $ERRORS Idris2 proof(s) failed" - exit 1 - fi - echo "PASS: All Idris2 proofs verified" - -# Check Lean4 proofs -proof-check-lean4: - #!/usr/bin/env bash - set -euo pipefail - echo "=== Checking Lean4 proofs ===" - if ! command -v lean &>/dev/null; then - echo "SKIP: lean not installed" - exit 0 - fi - ERRORS=0 - for f in $(find verification/proofs/lean4 -name '*.lean' 2>/dev/null); do - echo -n " Checking $f ... " - if lean "$f" 2>/dev/null; then - echo "OK" - else - echo "FAIL" - ERRORS=$((ERRORS + 1)) - fi - done - if [ "$ERRORS" -gt 0 ]; then - echo "FAIL: $ERRORS Lean4 proof(s) failed" - exit 1 - fi - echo "PASS: All Lean4 proofs verified" - -# Check Agda proofs -proof-check-agda: - #!/usr/bin/env bash - set -euo pipefail - echo "=== Checking Agda proofs ===" - if ! command -v agda &>/dev/null; then - echo "SKIP: agda not installed" - exit 0 - fi - ERRORS=0 - for f in $(find verification/proofs/agda -name '*.agda' 2>/dev/null); do - echo -n " Checking $f ... " - if agda --safe "$f" 2>/dev/null; then - echo "OK" - else - echo "FAIL" - ERRORS=$((ERRORS + 1)) - fi - done - if [ "$ERRORS" -gt 0 ]; then - echo "FAIL: $ERRORS Agda proof(s) failed" - exit 1 - fi - echo "PASS: All Agda proofs verified" - -# Check Coq proofs -proof-check-coq: - #!/usr/bin/env bash - set -euo pipefail - echo "=== Checking Coq proofs ===" - if ! command -v coqc &>/dev/null; then - echo "SKIP: coqc not installed" - exit 0 - fi - ERRORS=0 - for f in $(find verification/proofs/coq -name '*.v' 2>/dev/null); do - echo -n " Checking $f ... " - if coqc "$f" 2>/dev/null; then - echo "OK" - else - echo "FAIL" - ERRORS=$((ERRORS + 1)) - fi - done - if [ "$ERRORS" -gt 0 ]; then - echo "FAIL: $ERRORS Coq proof(s) failed" - exit 1 - fi - echo "PASS: All Coq proofs verified" - -# Scan for dangerous patterns in proof files (believe_me, sorry, Admitted, etc.) -proof-scan-dangerous: - #!/usr/bin/env bash - set -euo pipefail - echo "=== Scanning for dangerous patterns in proofs ===" - DANGEROUS=0 - PATTERNS="believe_me|assert_total|postulate|sorry|Admitted|unsafeCoerce|Obj\.magic" - for f in $(find verification/proofs -name '*.idr' -o -name '*.lean' -o -name '*.agda' -o -name '*.v' 2>/dev/null); do - MATCHES=$(grep -nE "$PATTERNS" "$f" 2>/dev/null || true) - if [ -n "$MATCHES" ]; then - echo " DANGEROUS: $f" - echo "$MATCHES" | sed 's/^/ /' - DANGEROUS=$((DANGEROUS + 1)) - fi - done - if [ "$DANGEROUS" -gt 0 ]; then - echo "FAIL: $DANGEROUS file(s) contain dangerous patterns" - exit 1 - fi - echo "PASS: No dangerous patterns found in proofs" - -# Show proof status summary -proof-status: - #!/usr/bin/env bash - echo "=== Proof Status ===" - echo "" - echo "Idris2: $(find verification/proofs/idris2 -name '*.idr' 2>/dev/null | wc -l) files" - echo "Lean4: $(find verification/proofs/lean4 -name '*.lean' 2>/dev/null | wc -l) files" - echo "Agda: $(find verification/proofs/agda -name '*.agda' 2>/dev/null | wc -l) files" - echo "Coq: $(find verification/proofs/coq -name '*.v' 2>/dev/null | wc -l) files" - echo "TLA+: $(find verification/proofs/tlaplus -name '*.tla' 2>/dev/null | wc -l) files" - echo "" - # PROOF-STATUS may live at root, docs/status/ (post-#20), .md or .adoc (post-#23) - for candidate in docs/status/PROOF-STATUS.adoc docs/status/PROOF-STATUS.md PROOF-STATUS.adoc PROOF-STATUS.md; do - if [ -f "$candidate" ]; then - grep -E "^\| \*\*Total\*\*|^\| \*Total\*" "$candidate" 2>/dev/null || echo "(No summary row in $candidate)" - exit 0 - fi - done - echo "(No PROOF-STATUS file found at root or docs/status/)" diff --git a/build/just/validate.just b/build/just/validate.just deleted file mode 100644 index 5ef9208..0000000 --- a/build/just/validate.just +++ /dev/null @@ -1,130 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# VALIDATION & COMPLIANCE -# -# Imported by ../../Justfile via `import? "build/just/validate.just"`. -# Recipes here check that this repo conforms to the RSR (Rhodium Standard -# Repository) skeleton: required files, METAdata, AI install guide -# completeness, etc. Run via `just validate`. - -# Validate RSR compliance -validate-rsr: - #!/usr/bin/env bash - echo "=== RSR Compliance Check ===" - MISSING="" - for f in .editorconfig .gitignore Justfile README.adoc LICENSE 0-AI-MANIFEST.a2ml; do - [ -f "$f" ] || MISSING="$MISSING $f" - done - for f in .machine_readable/6a2/STATE.a2ml .machine_readable/6a2/META.a2ml .machine_readable/6a2/ECOSYSTEM.a2ml .machine_readable/6a2/anchors/ANCHOR.a2ml .machine_readable/policies/MAINTENANCE-AXES.a2ml .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml .machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml; do - [ -f "$f" ] || MISSING="$MISSING $f" - done - for f in licensing/exhibits/EXHIBIT-A-ETHICAL-USE.txt licensing/exhibits/EXHIBIT-B-QUANTUM-SAFE.txt licensing/texts/MPL-2.0.txt; do - [ -f "$f" ] || MISSING="$MISSING $f" - done - if [ ! -d "src/interface/abi" ] && [ ! -d "src/interface/Abi" ]; then - MISSING="$MISSING src/interface/abi" - fi - for f in src/interface/ffi src/interface/generated; do - [ -d "$f" ] || MISSING="$MISSING $f" - done - for f in docs/governance/MAINTENANCE-CHECKLIST.adoc docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc; do - [ -f "$f" ] || MISSING="$MISSING $f" - done - if [ -f ".machine_readable/6a2/META.a2ml" ]; then - grep -q 'axis-1 = "must > intend > like"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:axis-1" - grep -q 'axis-2 = "corrective > adaptive > perfective"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:axis-2" - grep -q 'axis-3 = "systems > compliance > effects"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:axis-3" - grep -q 'scoping-first = true' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:scoping-first" - grep -q 'idris-unsound-scan = "believe_me/assert_total"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:idris-unsound-scan" - grep -q 'audit-focus = "systems in place, documentation explains actual state, safety/security accounted for, observed effects reviewed"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:audit-focus" - grep -q 'compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:compliance-focus" - grep -q 'effects-evidence = "benchmark execution/results and maintainer status dialogue/review"' .machine_readable/6a2/META.a2ml || MISSING="$MISSING META.a2ml:effects-evidence" - grep -q 'compliance-tooling = "panic-attack"' .machine_readable/policies/MAINTENANCE-AXES.a2ml || MISSING="$MISSING MAINTENANCE-AXES.a2ml:compliance-tooling" - grep -q 'effects-tooling = "ecological checking with sustainabot guidance"' .machine_readable/policies/MAINTENANCE-AXES.a2ml || MISSING="$MISSING MAINTENANCE-AXES.a2ml:effects-tooling" - grep -q 'source-human = "docs/governance/MAINTENANCE-CHECKLIST.adoc"' .machine_readable/policies/MAINTENANCE-CHECKLIST.a2ml || MISSING="$MISSING MAINTENANCE-CHECKLIST.a2ml:source-human" - grep -q 'source-human = "docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc"' .machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml || MISSING="$MISSING SOFTWARE-DEVELOPMENT-APPROACH.a2ml:source-human" - fi - if [ -n "$MISSING" ]; then - echo "MISSING:$MISSING" - exit 1 - fi - echo "RSR compliance: PASS" - -# Validate STATE.a2ml syntax -validate-state: - @if [ -f ".machine_readable/6a2/STATE.a2ml" ]; then \ - grep -q '^\[metadata\]' .machine_readable/6a2/STATE.a2ml && \ - grep -q 'project\s*=' .machine_readable/6a2/STATE.a2ml && \ - echo "STATE.a2ml: valid" || echo "STATE.a2ml: INVALID (missing required sections)"; \ - else \ - echo "No .machine_readable/6a2/STATE.a2ml found"; \ - fi - -# Validate AI installation guide completeness (finishbot pre-release check) -validate-ai-install: - #!/usr/bin/env bash - echo "=== AI Installation Guide Check ===" - GUIDE="docs/AI_INSTALLATION_GUIDE.adoc" - README="README.adoc" - ERRORS=0 - - # Check guide exists - if [ ! -f "$GUIDE" ]; then - echo "MISSING: $GUIDE (create from template: docs/AI_INSTALLATION_GUIDE.adoc)" - ERRORS=$((ERRORS + 1)) - else - # Check for unfilled TODO markers - TODOS=$(grep -c '\[TODO-AI-INSTALL' "$GUIDE" 2>/dev/null || true) - if [ "$TODOS" -gt 0 ]; then - echo "INCOMPLETE: $GUIDE has $TODOS unfilled [TODO-AI-INSTALL] markers:" - grep -n '\[TODO-AI-INSTALL' "$GUIDE" | head -10 - ERRORS=$((ERRORS + 1)) - else - echo "$GUIDE: complete (no TODO markers)" - fi - - # Check AI implementation section exists - if ! grep -q 'ai-implementation' "$GUIDE" 2>/dev/null; then - echo "MISSING: [[ai-implementation]] anchor in $GUIDE" - ERRORS=$((ERRORS + 1)) - fi - - # Check privacy notice exists - if ! grep -qi 'privacy' "$GUIDE" 2>/dev/null; then - echo "MISSING: Privacy notice in $GUIDE" - ERRORS=$((ERRORS + 1)) - fi - - # Check install commands exist (not just placeholders) - if ! grep -q 'git clone' "$GUIDE" 2>/dev/null; then - echo "WARNING: No git clone command found in $GUIDE -- install commands may be incomplete" - fi - fi - - # Check README has AI install section - if [ -f "$README" ]; then - if ! grep -qi 'AI-Assisted Installation' "$README" 2>/dev/null; then - echo "MISSING: AI-Assisted Installation section in $README" - echo " Copy from docs/AI-INSTALL-README-SECTION.adoc" - ERRORS=$((ERRORS + 1)) - fi - - # Check README for unfilled TODO markers - README_TODOS=$(grep -c '\[TODO-AI-INSTALL' "$README" 2>/dev/null || true) - if [ "$README_TODOS" -gt 0 ]; then - echo "INCOMPLETE: $README has $README_TODOS unfilled [TODO-AI-INSTALL] markers" - ERRORS=$((ERRORS + 1)) - fi - fi - - if [ "$ERRORS" -gt 0 ]; then - echo "" - echo "AI install guide: FAIL ($ERRORS issues)" - exit 1 - fi - echo "AI install guide: PASS" - -# Full validation suite -validate: validate-rsr validate-state validate-ai-install - @echo "All validations passed!" diff --git a/build/setup.sh b/build/setup.sh deleted file mode 100755 index f652bf4..0000000 --- a/build/setup.sh +++ /dev/null @@ -1,294 +0,0 @@ -#!/bin/sh -# SPDX-License-Identifier: MPL-2.0 -# setup.sh — Universal setup script for rsr-template-repo -# -# Detects your shell, platform, and installs prerequisites. -# Then hands off to `just setup` for project-specific configuration. -# -# hypatia: allow code_safety/shell_download_then_run -- the only remote fetch -# (install_just_upstream) deliberately downloads to a temp file and runs that -# file rather than piping `curl | sh`, so the script can be inspected; the -# upstream just installer is a rolling script that cannot be checksum-pinned. -# -# Usage: -# curl -fsSL https://raw.githubusercontent.com/hyperpolymath/rsr-template-repo/main/setup.sh -o setup.sh && sh setup.sh -# # or after cloning: -# ./setup.sh -# -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) - -set -eu - -# ── Colours (safe — uses symbols too per ADJUST contractile) ── -if [ -t 1 ] && command -v tput >/dev/null 2>&1; then - RED=$(tput setaf 1 2>/dev/null || true) - GREEN=$(tput setaf 2 2>/dev/null || true) - YELLOW=$(tput setaf 3 2>/dev/null || true) - CYAN=$(tput setaf 6 2>/dev/null || true) - BOLD=$(tput bold 2>/dev/null || true) - RESET=$(tput sgr0 2>/dev/null || true) -else - RED="" GREEN="" YELLOW="" CYAN="" BOLD="" RESET="" -fi - -ok() { printf " %s[OK]%s %s\n" "$GREEN" "$RESET" "$1"; } -fail() { printf " %s[FAIL]%s %s\n" "$RED" "$RESET" "$1"; } -warn() { printf " %s[WARN]%s %s\n" "$YELLOW" "$RESET" "$1"; } -info() { printf " %s[INFO]%s %s\n" "$CYAN" "$RESET" "$1"; } - -# ── Shell Detection ── -detect_shell() { - # Check the actual running shell, not just $SHELL - CURRENT_SHELL="unknown" - - if [ -n "${BASH_VERSION:-}" ]; then CURRENT_SHELL="bash" - elif [ -n "${ZSH_VERSION:-}" ]; then CURRENT_SHELL="zsh" - elif [ -n "${FISH_VERSION:-}" ]; then CURRENT_SHELL="fish" - elif [ -n "${KSH_VERSION:-}" ]; then CURRENT_SHELL="ksh" - # Check by process name for shells that don't set version vars - elif command -v ps >/dev/null 2>&1; then - SHELL_PROC=$(ps -p $$ -o comm= 2>/dev/null || echo "unknown") - case "$SHELL_PROC" in - *dash*) CURRENT_SHELL="dash" ;; - *tcsh*) CURRENT_SHELL="tcsh" ;; - *csh*) CURRENT_SHELL="csh" ;; - *elvish*) CURRENT_SHELL="elvish" ;; - *nu*) CURRENT_SHELL="nushell" ;; - *oil*|*osh*) CURRENT_SHELL="oil" ;; - *xonsh*) CURRENT_SHELL="xonsh" ;; - *murex*) CURRENT_SHELL="murex" ;; - *ion*) CURRENT_SHELL="ion" ;; - *hilbish*) CURRENT_SHELL="hilbish" ;; - *oh*) CURRENT_SHELL="oh" ;; - *vsh*) CURRENT_SHELL="vsh" ;; - *pwsh*|*powershell*) CURRENT_SHELL="powershell" ;; - esac - fi - - # Fallback: check $SHELL env var - if [ "$CURRENT_SHELL" = "unknown" ] && [ -n "${SHELL:-}" ]; then - case "$SHELL" in - */bash) CURRENT_SHELL="bash" ;; - */zsh) CURRENT_SHELL="zsh" ;; - */fish) CURRENT_SHELL="fish" ;; - */dash) CURRENT_SHELL="dash" ;; - */ksh*) CURRENT_SHELL="ksh" ;; - */tcsh) CURRENT_SHELL="tcsh" ;; - */csh) CURRENT_SHELL="csh" ;; - */vsh) CURRENT_SHELL="vsh" ;; - esac - fi - - printf "%s" "$CURRENT_SHELL" -} - -# ── Platform Detection ── -detect_platform() { - OS="unknown" - DISTRO="unknown" - PKG_MGR="unknown" - ARCH=$(uname -m 2>/dev/null || echo "unknown") - - case "$(uname -s 2>/dev/null)" in - Linux*) - OS="linux" - if [ -f /etc/os-release ]; then - DISTRO=$(. /etc/os-release && echo "$ID") - elif [ -f /etc/redhat-release ]; then - DISTRO="rhel" - elif [ -f /etc/debian_version ]; then - DISTRO="debian" - fi - # Detect package manager - if command -v dnf >/dev/null 2>&1; then PKG_MGR="dnf" - elif command -v apt-get >/dev/null 2>&1; then PKG_MGR="apt" - elif command -v pacman >/dev/null 2>&1; then PKG_MGR="pacman" - elif command -v apk >/dev/null 2>&1; then PKG_MGR="apk" - elif command -v zypper >/dev/null 2>&1; then PKG_MGR="zypper" - elif command -v rpm-ostree >/dev/null 2>&1; then PKG_MGR="rpm-ostree" - elif command -v guix >/dev/null 2>&1; then PKG_MGR="guix" - fi - ;; - Darwin*) - OS="macos" - DISTRO="macos" - if command -v brew >/dev/null 2>&1; then PKG_MGR="brew" - elif command -v port >/dev/null 2>&1; then PKG_MGR="macports" - fi - ;; - CYGWIN*|MINGW*|MSYS*) - OS="windows" - DISTRO="msys" - if command -v winget >/dev/null 2>&1; then PKG_MGR="winget" - elif command -v scoop >/dev/null 2>&1; then PKG_MGR="scoop" - elif command -v choco >/dev/null 2>&1; then PKG_MGR="choco" - fi - ;; - FreeBSD*) - OS="freebsd" - DISTRO="freebsd" - PKG_MGR="pkg" - ;; - esac -} - -# ── Install just ── -# Fetch-then-run rather than `curl | sh`: piping a remote script straight into a -# shell executes whatever the network returns with no chance to inspect or -# verify it (CWE-494). Download to a temp file first, then run that file. -install_just_upstream() { - _ji_tmp=$(mktemp 2>/dev/null || echo "/tmp/just-install.$$.sh") - if curl -fsSL https://just.systems/install.sh -o "$_ji_tmp"; then - sh "$_ji_tmp" --to /usr/local/bin - _ji_rc=$? - else - fail "Could not download the just installer." - _ji_rc=1 - fi - rm -f "$_ji_tmp" - return $_ji_rc -} - -install_just() { - if command -v just >/dev/null 2>&1; then - ok "just already installed: $(just --version 2>/dev/null | head -1)" - return 0 - fi - - info "Installing just (task runner)..." - - case "$PKG_MGR" in - dnf) sudo dnf install -y just ;; - apt) sudo apt-get install -y just 2>/dev/null || install_just_upstream ;; - pacman) sudo pacman -S --noconfirm just ;; - apk) sudo apk add just ;; - brew) brew install just ;; - scoop) scoop install just ;; - winget) winget install Casey.Just ;; - rpm-ostree) sudo rpm-ostree install just ;; - guix) guix install just ;; - *) - info "Using just installer script..." - install_just_upstream - ;; - esac - - if command -v just >/dev/null 2>&1; then - ok "just installed: $(just --version 2>/dev/null | head -1)" - else - fail "Could not install just. Install manually: https://just.systems/" - return 1 - fi -} - -# ── Main ── -main() { - printf "%s=== rsr-template-repo Setup ===%s\n\n" "$BOLD" "$RESET" - - # Detect environment - SHELL_NAME=$(detect_shell) - detect_platform - - info "Shell: $SHELL_NAME" - info "Platform: $OS ($DISTRO)" - info "Arch: $ARCH" - info "Packages: $PKG_MGR" - printf "\n" - - # Warn about exotic shells - case "$SHELL_NAME" in - vsh) - info "Valence Shell detected — experimental support" - info "Falling back to POSIX sh for setup, vsh for post-setup" - ;; - nushell|elvish|murex|ion|hilbish|oil|xonsh|oh) - info "$SHELL_NAME detected — using POSIX sh for setup" - ;; - esac - - # Step 1: Install just - printf "%sStep 1: Install task runner%s\n" "$BOLD" "$RESET" - install_just || { fail "Cannot proceed without just"; exit 1; } - printf "\n" - - # Step 2: Check if we're in the repo directory - if [ ! -f "Justfile" ] && [ ! -f "justfile" ]; then - warn "Not in a repo directory (no Justfile found)" - info "Clone first: git clone https://github.com/hyperpolymath/rsr-template-repo.git" - info "Then: cd rsr-template-repo && ./setup.sh" - exit 1 - fi - - # Step 3: Run just setup - printf "%sStep 2: Project setup%s\n" "$BOLD" "$RESET" - if just --list 2>/dev/null | grep -q "^setup "; then - just setup - elif just --list 2>/dev/null | grep -q "^setup-dev "; then - just setup-dev - else - warn "No 'setup' recipe in Justfile — running 'just doctor' instead" - just doctor 2>/dev/null || true - fi - printf "\n" - - # Step 4: Post-install security snapshot - printf "%sStep 3: Security snapshot%s\n" "$BOLD" "$RESET" - if command -v firewall-cmd >/dev/null 2>&1; then - if firewall-cmd --state 2>/dev/null | grep -q running; then - ok "Firewall: firewalld active" - else - warn "Firewall: firewalld installed but not running" - info " Enable: sudo systemctl enable --now firewalld" - fi - elif command -v ufw >/dev/null 2>&1; then - if ufw status 2>/dev/null | grep -q "Status: active"; then - ok "Firewall: ufw active" - else - warn "Firewall: ufw installed but not active" - info " Enable: sudo ufw enable" - fi - else - warn "Firewall: none detected" - case "$PKG_MGR" in - dnf|rpm-ostree) info " Install: sudo dnf install firewalld && sudo systemctl enable --now firewalld" ;; - apt) info " Install: sudo apt install ufw && sudo ufw enable" ;; - *) info " Install a firewall for your platform" ;; - esac - fi - - if command -v getenforce >/dev/null 2>&1; then - SE_STATUS=$(getenforce 2>/dev/null || echo "unknown") - case "$SE_STATUS" in - Enforcing) ok "SELinux: Enforcing" ;; - Permissive) warn "SELinux: Permissive (recommend Enforcing: sudo setenforce 1)" ;; - *) warn "SELinux: $SE_STATUS" ;; - esac - fi - - # Write report - REPORT_FILE="INSTALL-SECURITY-REPORT.adoc" - { - printf "// SPDX-License-Identifier: MPL-2.0\n" - printf "= Install Security Report\n" - printf ":date: %s\n\n" "$(date -Iseconds 2>/dev/null || date)" - printf "== Platform\n" - printf "* OS: %s (%s)\n" "$OS" "$DISTRO" - printf "* Arch: %s\n" "$ARCH" - printf "* Package manager: %s\n" "$PKG_MGR" - printf "* Shell: %s\n\n" "$SHELL_NAME" - printf "== Security Status\n" - printf "Run \`just doctor\` for full diagnostic.\n" - } > "$REPORT_FILE" - info "Security report: $REPORT_FILE" - printf "\n" - - # Done - printf "%s=== Setup Complete ===%s\n\n" "${BOLD}${GREEN}" "$RESET" - printf "Next steps:\n" - printf " just doctor — verify everything works\n" - printf " just tour — guided tour of the project\n" - printf " just build — build the project\n" - printf " just help-me — get help if stuck\n" -} - -main "$@" diff --git a/container/0.1-AI-MANIFEST.a2ml b/container/0.1-AI-MANIFEST.a2ml index 43d6437..a25baa5 100644 --- a/container/0.1-AI-MANIFEST.a2ml +++ b/container/0.1-AI-MANIFEST.a2ml @@ -40,7 +40,7 @@ canonical_locations: monitoring: "container/stapeln/vordr.toml" deployment: "container/stapeln/deploy.k9.ncl" # Just module + opt-out - just_module: "build/just/container.just" + just_module: "none" # build/just/container.just retired with the build/ scaffolding removal --- ### [FILE_RELATIONSHIPS] diff --git a/container/README.adoc b/container/README.adoc index 1ec939b..7a2f805 100644 --- a/container/README.adoc +++ b/container/README.adoc @@ -32,8 +32,9 @@ or delete — the rest. https://github.com/hyperpolymath/stapeln[stapeln] stack. |=== -All files use `{{PLACEHOLDER}}` tokens, replaced by `just container-init` -(or the top-level `just init` during project bootstrap). +All files use `{{PLACEHOLDER}}` tokens, filled in when the container stack is +first configured (the template's `just init`/`just container-init` bootstrap +recipes were retired with the build/ scaffolding removal). The container engine is *auto-detected* (`podman`, then `nerdctl`, then `docker`). Override with `CONTAINER_ENGINE=docker just container-build`. @@ -142,12 +143,9 @@ The request path in the full stack is: == Initialise -[source,bash] ----- -just init # full project bootstrap (all placeholders) -# or -just container-init # container-only: prompts for service/port/registry ----- +The template's `just init` / `just container-init` bootstrap recipes were +retired with the build/ scaffolding removal; fill the `{{PLACEHOLDER}}` tokens +by hand if the container stack is ever configured for this repo. == Everyday workflow (tiers A + B) @@ -218,17 +216,11 @@ otherwise. == Removing containerisation -If your project does not need containers (e.g. a pure library), strip the whole -apparatus in one command: - -[source,bash] ----- -just no-container ----- - -This removes `container/`, `.devcontainer/`, the `build/just/container.just` -module and its Justfile import. Review `.github/workflows/` afterwards for any -image build/publish jobs you no longer need. +If your project does not need containers (e.g. a pure library), remove +`container/` and `.devcontainer/` directly (the template's `just no-container` +recipe and `build/just/container.just` module were retired with the build/ +scaffolding removal). Review `.github/workflows/` afterwards for any image +build/publish jobs you no longer need. == Base images