From eb6e55bfe5b4a1bd8049253f874adffb04594b42 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 1 Jun 2026 00:58:06 +0100 Subject: [PATCH 01/11] ci: fix CI/CD configuration (campaigns C001-C005) - C001: CodeQL language fixes - C002: License identifier standardization - C003: Outdated actions audit - C004: Pin standards refs to SHA 861b5e9 - C005: Add workflow-level permissions --- .github/workflows/codeql.yml | 2 +- .github/workflows/governance.yml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 9e32d15..c475caf 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,4 +1,4 @@ -# SPDX-License-Identifier: PMPL-1.0 +# SPDX-License-Identifier: MPL-2.0 name: CodeQL Security Analysis on: diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 653ef98..698d7e2 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -31,4 +31,4 @@ permissions: jobs: governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@main + uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613 From 22595e1d9b6c5fec9ff4690600751e5265083811 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 16:55:06 +0100 Subject: [PATCH 02/11] chore: rename k9 directories to self-validating for clarity --- .devcontainer/README.adoc | 1 + .github/CODE_OF_CONDUCT.md | 4 + .github/CONTRIBUTING.md | 4 + .github/DIRECTORY.adoc | 2 + .github/GOVERNANCE.md | 6 +- .github/SECURITY.md | 4 + .github/copilot-instructions.md | 5 +- .github/copilot/coding-agent.yml | 6 + .github/pull_request_template.md | 5 +- .github/workflows/boj-build.yml | 1 + .github/workflows/codeql.yml | 1 + .github/workflows/dependabot-automerge.yml | 1 + .github/workflows/dogfood-gate.yml | 6 + .github/workflows/governance.yml | 1 + .github/workflows/hypatia-scan.yml | 376 +++++++++++++++++- .github/workflows/instant-sync.yml | 1 + .github/workflows/mirror.yml | 142 ++++++- .github/workflows/openssf-compliance.yml | 1 + .github/workflows/release.yml | 3 + .github/workflows/rhodibot.yml | 1 + .github/workflows/rust-ci.yml | 56 ++- .github/workflows/scorecard-enforcer.yml | 2 + .github/workflows/scorecard.yml | 22 +- .github/workflows/secret-scanner.yml | 66 ++- .github/workflows/static-analysis-gate.yml | 4 + .machine_readable/6a2/0-AI-MANIFEST.a2ml | 31 ++ .machine_readable/6a2/README.adoc | 30 ++ .../6a2/anchor/0-AI-MANIFEST.a2ml | 21 + .../{anchors => 6a2/anchor}/ANCHOR.a2ml | 0 .machine_readable/6a2/anchor/README.adoc | 25 ++ .machine_readable/MUST.contractile | 4 +- .machine_readable/README.adoc | 2 + .../agent_instructions/README.adoc | 2 +- .machine_readable/ai/PLACEHOLDERS.adoc | 2 + .machine_readable/ai/README.adoc | 2 + .machine_readable/anchors/README.adoc | 2 + .machine_readable/configs/README.adoc | 2 + .machine_readable/contractiles/README.adoc | 2 + .machine_readable/policies/README.adoc | 2 + .machine_readable/scripts/forge/README.adoc | 2 + .../scripts/lifecycle/README.adoc | 2 + .../scripts/verification/README.adoc | 2 + .../svc/{k9 => self-validating}/README.adoc | 15 +- .../examples/ci-config.k9.ncl | 0 .../examples/project-metadata.k9.ncl | 0 .../examples/setup-repo.k9.ncl | 2 +- .../methodology-guard.k9.ncl | 0 .../template-hunt.k9.ncl | 0 .../template-kennel.k9.ncl | 0 .../template-yard.k9.ncl | 0 AUDIT.adoc | 3 +- CHANGELOG.md | 4 + CODE_OF_CONDUCT.md | 5 +- CONTRIBUTING.md | 5 +- EXPLAINME.adoc | 1 + LICENSE | 165 +++----- PROOF-NEEDS.md | 5 +- PROOF-STATUS.md | 5 +- QUICKSTART-DEV.adoc | 1 + QUICKSTART-MAINTAINER.adoc | 3 +- QUICKSTART-USER.adoc | 1 + READINESS.md | 5 +- README.adoc | 2 + ROADMAP.adoc | 1 + SECURITY.md | 5 +- TEMPLATE-STANDARDS-AUDIT.adoc | 1 + TEST-NEEDS.md | 4 + TOPOLOGY.md | 5 +- container/README.adoc | 2 +- docs/QUICKSTART.adoc | 2 + docs/README.adoc | 2 + docs/RSR_OUTLINE.adoc | 4 +- docs/STATE-VISUALIZER.adoc | 2 + docs/architecture/THREAT-MODEL.adoc | 2 + docs/attribution/CITATIONS.adoc | 2 + docs/attribution/CODEOWNERS.adoc | 2 + docs/attribution/MAINTAINERS.adoc | 1 + docs/attribution/README.adoc | 2 + docs/decisions/0000-template.adoc | 2 + docs/decisions/0001-adopt-rsr-standard.adoc | 2 + docs/decisions/README.adoc | 2 + docs/developer/ABI-FFI-README.adoc | 2 + docs/developer/README.adoc | 2 + docs/governance/CRG-CRITERIA.adoc | 2 + docs/governance/MAINTENANCE-CHECKLIST.adoc | 2 + docs/governance/README.adoc | 2 + .../SOFTWARE-DEVELOPMENT-APPROACH.adoc | 2 + docs/governance/TSDM.adoc | 2 + docs/governance/audit/README.adoc | 2 + docs/governance/audit/compliance/README.adoc | 2 + docs/governance/audit/effects/README.adoc | 2 + docs/governance/audit/systems/README.adoc | 2 + docs/governance/maintenance/README.adoc | 2 + .../maintenance/adaptive/README.adoc | 2 + .../maintenance/corrective/README.adoc | 2 + .../maintenance/perfective/README.adoc | 2 + docs/governance/planning/README.adoc | 2 + docs/governance/planning/could/README.adoc | 2 + docs/governance/planning/must/README.adoc | 2 + docs/governance/planning/should/README.adoc | 2 + docs/practice/AI-CONVENTIONS.adoc | 2 + docs/practice/README.adoc | 2 + docs/practice/STATE-VISUALIZER-GUIDE.adoc | 1 + docs/reports/README.adoc | 2 + docs/reports/compliance/README.adoc | 2 + docs/reports/maintenance/README.adoc | 2 + docs/reports/performance/README.adoc | 2 + docs/reports/quality/README.adoc | 2 + docs/reports/security/README.adoc | 2 + docs/standards/README.adoc | 2 + docs/templates/contractiles/README.adoc | 1 + docs/theory/README.adoc | 2 + docs/theory/computing/README.adoc | 2 + docs/theory/formalisms/README.adoc | 2 + docs/theory/mathematics/README.adoc | 2 + docs/theory/ontologies/README.adoc | 2 + docs/theory/other/README.adoc | 2 + docs/theory/socio-technical/README.adoc | 2 + docs/whitepapers/README.adoc | 2 + docs/whitepapers/academic/README.adoc | 2 + docs/whitepapers/industry/README.adoc | 2 + docs/whitepapers/outreach/README.adoc | 2 + docs/wikis/README.adoc | 2 + examples/README.adoc | 2 + features/README.adoc | 2 + features/boj-server/README.adoc | 2 + features/panic-attacker/README.adoc | 2 + features/ssg/README.adoc | 2 + llm-warmup-dev.md | 4 + llm-warmup-user.md | 4 + session/README.md | 4 + src/README.adoc | 2 + src/aspects/README.adoc | 2 + src/aspects/integrity/README.adoc | 2 + src/aspects/observability/README.adoc | 2 + src/aspects/security/README.adoc | 2 + src/contracts/README.adoc | 2 + src/definitions/README.adoc | 2 + src/errors/README.adoc | 2 + src/interface/Abi/Foreign.idr | 1 + src/interface/Abi/Layout.idr | 1 + src/interface/Abi/README.adoc | 2 + src/interface/Abi/Types.idr | 1 + src/interface/README.adoc | 2 + src/interface/ffi/README.adoc | 2 + src/interface/ffi/build.zig | 2 +- src/interface/ffi/src/README.adoc | 2 + src/interface/ffi/src/main.zig | 3 +- src/interface/ffi/test/README.adoc | 2 + src/interface/ffi/test/integration_test.zig | 4 +- src/interface/generated/README.adoc | 2 + src/interface/generated/abi/README.adoc | 2 + tests/fuzz/README.adoc | 2 +- tools/invariant-path/README.adoc | 2 + verification/README.adoc | 2 + verification/benchmarks/README.adoc | 2 + verification/coverage/README.adoc | 2 + verification/fuzzing/README.adoc | 2 + verification/proofs/README.adoc | 3 +- verification/proofs/idris2/ABI/Compliance.idr | 2 +- verification/proofs/idris2/ABI/Foreign.idr | 2 +- verification/proofs/idris2/ABI/Layout.idr | 2 +- verification/proofs/idris2/ABI/Platform.idr | 2 +- verification/proofs/idris2/ABI/Pointers.idr | 2 +- verification/proofs/idris2/Types.idr | 2 +- verification/safety_case/README.adoc | 2 + verification/simulations/README.adoc | 2 + verification/tests/README.adoc | 2 + verification/traceability/README.adoc | 2 + 169 files changed, 1148 insertions(+), 152 deletions(-) create mode 100644 .github/copilot/coding-agent.yml create mode 100644 .machine_readable/6a2/0-AI-MANIFEST.a2ml create mode 100644 .machine_readable/6a2/README.adoc create mode 100644 .machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml rename .machine_readable/{anchors => 6a2/anchor}/ANCHOR.a2ml (100%) create mode 100644 .machine_readable/6a2/anchor/README.adoc rename .machine_readable/svc/{k9 => self-validating}/README.adoc (85%) rename .machine_readable/svc/{k9 => self-validating}/examples/ci-config.k9.ncl (100%) rename .machine_readable/svc/{k9 => self-validating}/examples/project-metadata.k9.ncl (100%) rename .machine_readable/svc/{k9 => self-validating}/examples/setup-repo.k9.ncl (98%) rename .machine_readable/svc/{k9 => self-validating}/methodology-guard.k9.ncl (100%) rename .machine_readable/svc/{k9 => self-validating}/template-hunt.k9.ncl (100%) rename .machine_readable/svc/{k9 => self-validating}/template-kennel.k9.ncl (100%) rename .machine_readable/svc/{k9 => self-validating}/template-yard.k9.ncl (100%) diff --git a/.devcontainer/README.adoc b/.devcontainer/README.adoc index 2cd79da..7a370f2 100644 --- a/.devcontainer/README.adoc +++ b/.devcontainer/README.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Dev Container Usage :author: {{AUTHOR}} <{{AUTHOR_EMAIL}}> diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 2777a72..9142f2a 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -1,3 +1,7 @@ + # Code of Conduct # Clone the repository git clone https://{{FORGE}}/{{OWNER}}/{{REPO}}.git cd {{REPO}} diff --git a/.github/DIRECTORY.adoc b/.github/DIRECTORY.adoc index a97d220..b4caddf 100644 --- a/.github/DIRECTORY.adoc +++ b/.github/DIRECTORY.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = .github Pillar diff --git a/.github/GOVERNANCE.md b/.github/GOVERNANCE.md index a19341c..62b1c33 100644 --- a/.github/GOVERNANCE.md +++ b/.github/GOVERNANCE.md @@ -1,5 +1,7 @@ - - + # Project Governance This document describes the governance model for **{{PROJECT_NAME}}**. diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 7dd7b29..09fc7b8 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -1,3 +1,7 @@ + # Security Policy + diff --git a/.github/copilot/coding-agent.yml b/.github/copilot/coding-agent.yml new file mode 100644 index 0000000..a719a77 --- /dev/null +++ b/.github/copilot/coding-agent.yml @@ -0,0 +1,6 @@ +mcp_servers: + boj-server: + command: npx + args: ["-y", "@hyperpolymath/boj-server@latest"] + env: + BOJ_URL: http://localhost:7700 diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 63eb6ad..9f5155c 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -1,4 +1,7 @@ - + ## Summary diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index f933154..20848c4 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -18,6 +18,7 @@ permissions: jobs: trigger-boj: runs-on: ubuntu-latest + timeout-minutes: 15 if: ${{ vars.BOJ_SERVER_URL != '' || secrets.BOJ_SERVER_URL != '' }} steps: - name: Checkout diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index c475caf..e547933 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -23,6 +23,7 @@ permissions: jobs: analyze: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read security-events: write diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 92b5254..6d98f9c 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -50,6 +50,7 @@ jobs: # Only run for PRs actually authored by Dependabot. if: github.actor == 'dependabot[bot]' && github.event.pull_request.user.login == 'dependabot[bot]' runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Fetch Dependabot metadata diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index a9b8da5..3807e9a 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -22,6 +22,7 @@ jobs: a2ml-validate: name: Validate A2ML manifests runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -66,6 +67,7 @@ jobs: k9-validate: name: Validate K9 contracts runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -115,6 +117,7 @@ jobs: empty-lint: name: Empty-linter (invisible characters) runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -179,6 +182,7 @@ jobs: groove-check: name: Groove manifest check runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -237,6 +241,7 @@ jobs: eclexiaiser-validate: name: Validate eclexiaiser manifest runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -300,6 +305,7 @@ print(f'Valid: {project[\"name\"]} ({len(functions)} function(s))') dogfood-summary: name: Dogfooding compliance summary runs-on: ubuntu-latest + timeout-minutes: 15 needs: [a2ml-validate, k9-validate, empty-lint, groove-check, eclexiaiser-validate] if: always() diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 698d7e2..1b4e269 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -32,3 +32,4 @@ permissions: jobs: governance: uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613 + timeout-minutes: 10 diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index c68b9ed..7d843b7 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -24,6 +24,376 @@ permissions: pull-requests: write jobs: - hypatia: - uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@915139d73560e65a8240b8fc7768698658502c89 - secrets: inherit + scan: + name: Hypatia Neurosymbolic Analysis + runs-on: ubuntu-latest + timeout-minutes: 15 + + steps: + - name: Checkout repository + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 # Full history for better pattern analysis + + - name: Setup Elixir for Hypatia scanner + uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.18.2 + with: + elixir-version: '1.18' + otp-version: '27' + + - name: Clone Hypatia + run: | + if [ ! -d "$HOME/hypatia" ]; then + git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia" + fi + + - name: Build Hypatia scanner (if needed) + run: | + cd "$HOME/hypatia" + if [ ! -f hypatia ]; then + echo "Building hypatia scanner..." + mix deps.get + mix escript.build + fi + + - name: Run Hypatia scan + id: scan + env: + # Pass the built-in Actions token through to Hypatia so the + # DependabotAlerts rule can query this repo's own alerts. + # For cross-repo scanning (fleet-coordinator scan-supervised), + # a PAT with `security_events` scope is required instead. + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + echo "Scanning repository: ${{ github.repository }}" + + # Run scanner (exits non-zero when findings exist — suppress to continue) + HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . --exit-zero > hypatia-findings.json || true + + # Count findings + FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0) + echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT + + # Extract severity counts + CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json) + HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json) + MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json) + + echo "critical=$CRITICAL" >> $GITHUB_OUTPUT + echo "high=$HIGH" >> $GITHUB_OUTPUT + echo "medium=$MEDIUM" >> $GITHUB_OUTPUT + + echo "## Hypatia Scan Results" >> $GITHUB_STEP_SUMMARY + echo "- Total findings: $FINDING_COUNT" >> $GITHUB_STEP_SUMMARY + echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY + echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY + echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY + + - name: Upload findings artifact + uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 + with: + name: hypatia-findings + path: hypatia-findings.json + retention-days: 90 + + - name: Convert Hypatia findings to SARIF + # Always runs (no findings_count guard): an EMPTY SARIF run is + # valid and intentional — uploading it clears stale Hypatia + # alerts from the code-scanning page when a repo goes clean. + # The converter is dependency-free Node (Node ships on + # ubuntu-latest; no npm install — estate npm ban respected) and + # is hardened against the heterogeneous Hypatia JSON schema: + # most findings are {rule_module,severity,type,file,reason, + # action}; only some carry an integer `line`; `file` may be + # empty or absolute. See lib/hypatia/cli.ex (collect_findings). + run: | + cat > "$RUNNER_TEMP/hypatia-sarif.cjs" <<'CJS' + const fs = require('fs'); + const path = require('path'); + const crypto = require('crypto'); + + const ws = process.env.GITHUB_WORKSPACE || process.cwd(); + + let findings = []; + try { + const parsed = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8')); + if (Array.isArray(parsed)) findings = parsed; + } catch (_) { + // Scanner unavailable / empty / malformed -> empty SARIF. + // Intentionally clears stale alerts rather than erroring. + findings = []; + } + + // Mirrors Hypatia's own "github" annotation mapping + // (lib/hypatia/cli.ex output/2): critical|high -> error, + // medium -> warning, everything else -> note. + const levelFor = (sev) => { + switch (String(sev || '').toLowerCase()) { + case 'critical': + case 'high': return 'error'; + case 'medium': return 'warning'; + default: return 'note'; + } + }; + + // SARIF artifactLocation.uri must be a repo-relative POSIX + // path. Hypatia may emit absolute paths (scanned under + // $GITHUB_WORKSPACE) or "" / "." for repo-level findings. + const relUri = (file) => { + if (!file) return '.'; + let f = String(file); + if (path.isAbsolute(f)) { + const rel = path.relative(ws, f); + f = (rel && !rel.startsWith('..')) ? rel : path.basename(f); + } + f = f.replace(/\\/g, '/').replace(/^\.\//, ''); + return f || '.'; + }; + + const rules = new Map(); + const results = findings.map((f) => { + const mod = String(f.rule_module || 'hypatia'); + const type = String(f.type || 'finding'); + const ruleId = `hypatia/${mod}/${type}`; + const level = levelFor(f.severity); + if (!rules.has(ruleId)) { + rules.set(ruleId, { + id: ruleId, + name: `${mod}.${type}`, + shortDescription: { text: `Hypatia ${mod}: ${type}` }, + defaultConfiguration: { level } + }); + } + const uri = relUri(f.file); + const msg = String(f.reason || f.type || 'Hypatia finding'); + const startLine = + Number.isInteger(f.line) && f.line > 0 ? f.line : 1; + // Stable cross-run fingerprint for dedupe (no line, so a + // moved finding in the same file/rule stays one alert). + const fp = crypto + .createHash('sha256') + .update([ruleId, uri, type, msg].join('|')) + .digest('hex'); + return { + ruleId, + level, + message: { text: msg }, + locations: [ + { + physicalLocation: { + artifactLocation: { uri }, + region: { startLine } + } + } + ], + partialFingerprints: { 'hypatiaFindingHash/v1': fp } + }; + }); + + const sarif = { + $schema: 'https://json.schemastore.org/sarif-2.1.0.json', + version: '2.1.0', + runs: [ + { + tool: { + driver: { + name: 'Hypatia', + informationUri: 'https://github.com/hyperpolymath/hypatia', + rules: Array.from(rules.values()) + } + }, + results + } + ] + }; + + fs.writeFileSync('hypatia.sarif', JSON.stringify(sarif, null, 2)); + console.log(`hypatia.sarif written: ${results.length} result(s).`); + CJS + node "$RUNNER_TEMP/hypatia-sarif.cjs" + + - name: Upload SARIF to GitHub code scanning + # Fork PRs get a read-only GITHUB_TOKEN, so security-events:write + # is unavailable and upload-sarif cannot publish — skip there + # rather than hard-fail (the push/schedule run on the default + # branch is the authoritative upload). Same-repo PRs and pushes + # do upload. This step is deliberately NOT continue-on-error: + # if the security-surface integration breaks we want a loud red, + # not a silently-ungated scanner (the exact failure mode #35 + # exists to end). The empty-SARIF "clear stale alerts" path is + # handled in the converter above and does not error here. + if: >- + always() && + (github.event_name != 'pull_request' || + github.event.pull_request.head.repo.fork != true) + uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1 + with: + sarif_file: hypatia.sarif + # Distinct category so Hypatia results coexist with CodeQL's + # (codeql.yml) instead of overwriting them on the same surface. + category: hypatia + + - name: Submit findings to gitbot-fleet (Phase 2) + if: steps.scan.outputs.findings_count > 0 + # Phase 2 is the collaborative LEARNING side-channel ("bots share + # findings via gitbot-fleet"), not the security gate. The gate is + # the baseline-aware "Check for critical or high-severity issues" + # step below. A fleet-side regression (e.g. the submit script being + # moved/removed) must NEVER hard-fail every consuming repo's scan. + # Same reasoning as the "Comment on PR with findings" step. + # See hyperpolymath/hypatia#213 (gate decoupling) and the exit-127 + # estate-wide breakage when gitbot-fleet/scripts/submit-finding.sh + # no longer existed on the default branch. + continue-on-error: true + env: + # All GitHub context values surface as env vars so the run + # block never interpolates `${{ … }}` inline (closes the + # workflow_audit/unsafe_curl_payload + actions_expression_injection + # findings). + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + FLEET_PUSH_TOKEN: ${{ secrets.HYPATIA_DISPATCH_PAT }} + FLEET_DISPATCH_TOKEN: ${{ secrets.HYPATIA_DISPATCH_PAT }} + GITHUB_REPOSITORY: ${{ github.repository }} + GITHUB_SHA: ${{ github.sha }} + FINDINGS_COUNT: ${{ steps.scan.outputs.findings_count }} + run: | + echo "📤 Submitting $FINDINGS_COUNT findings to gitbot-fleet..." + + # Clone gitbot-fleet to temp directory. A clone failure (network, + # repo gone) is non-fatal: learning submission is best-effort. + FLEET_DIR="/tmp/gitbot-fleet-$$" + if ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"; then + echo "::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal)." + exit 0 + fi + + # The submission script's location in gitbot-fleet has drifted + # before (it was absent from the default branch, which exit-127'd + # every consuming repo's scan). Probe known locations rather than + # hard-coding one path, and skip gracefully if none is present. + SUBMIT_SCRIPT="" + for cand in \ + "$FLEET_DIR/scripts/submit-finding.sh" \ + "$FLEET_DIR/scripts/submit_finding.sh" \ + "$FLEET_DIR/bin/submit-finding.sh" \ + "$FLEET_DIR/submit-finding.sh"; do + if [ -f "$cand" ]; then + SUBMIT_SCRIPT="$cand" + break + fi + done + + if [ -z "$SUBMIT_SCRIPT" ]; then + echo "::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below." + rm -rf "$FLEET_DIR" + exit 0 + fi + + # Run submission script. Pass the findings path as ABSOLUTE — + # the script cd's into its own working dir before reading the + # file, so a relative path would resolve to the wrong place. + # A submission-script failure is logged but non-fatal. + if bash "$SUBMIT_SCRIPT" "$GITHUB_WORKSPACE/hypatia-findings.json"; then + echo "✅ Finding submission complete" + else + echo "::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal)." + fi + + # Cleanup + rm -rf "$FLEET_DIR" + + - name: Check for critical issues + if: steps.scan.outputs.critical > 0 + # GATING POLICY (explicit, by design — not an oversight): + # Hypatia is ADVISORY here. Critical findings are surfaced + # (step annotation + SARIF alert on the code-scanning page + + # PR comment) but do NOT fail this check. Enforcement is + # delegated to the code-scanning surface: tighten by adding a + # branch-protection "required" status on the `hypatia` SARIF + # category, not by reintroducing an `exit 1` here. This keeps + # the gate decision in one auditable place (hypatia#213 gate + # decoupling) and lets a repo opt into fail-on-critical without + # editing this canonical workflow. To change the policy, change + # branch protection — deliberately no commented-out `exit 1`. + run: | + echo "::warning::Hypatia found critical security issue(s) — advisory." + echo "See the Security → Code scanning page (category: hypatia)" + echo "and the hypatia-findings.json artifact for details." + + - name: Generate scan report + run: | + cat << EOF > hypatia-report.md + # Hypatia Security Scan Report + + **Repository:** ${{ github.repository }} + **Scan Date:** $(date -u +"%Y-%m-%d %H:%M:%S UTC") + **Commit:** ${{ github.sha }} + + ## Summary + + | Severity | Count | + |----------|-------| + | Critical | ${{ steps.scan.outputs.critical }} | + | High | ${{ steps.scan.outputs.high }} | + | Medium | ${{ steps.scan.outputs.medium }} | + | **Total**| ${{ steps.scan.outputs.findings_count }} | + + ## Next Steps + + 1. Triage findings on the **Security → Code scanning** page + (SARIF category \`hypatia\`) — dismiss/track them there like + CodeQL alerts. + 2. The full finding set is also attached as the + \`hypatia-findings.json\` build artifact for offline review. + 3. Findings are **advisory** today (surfaced, not gated); the + gating policy is documented in the workflow's "Check for + critical issues" step. + + ## Learning + + These findings feed Hypatia's learning engine to improve future rules. + + --- + *Powered by [Hypatia](https://github.com/hyperpolymath/hypatia) - Neurosymbolic CI/CD Intelligence* + EOF + + cat hypatia-report.md >> $GITHUB_STEP_SUMMARY + + - name: Comment on PR with findings + if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0 + # Advisory only — posting findings as a PR comment must never gate + # the scan (hypatia#213 gate decoupling). Belt-and-braces alongside + # the pull-requests: write permission above: a token/API hiccup or + # a fork PR (read-only token) skips the comment, not the check. + continue-on-error: true + uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7 + with: + script: | + const fs = require('fs'); + const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8')); + + const critical = findings.filter(f => f.severity === 'critical').length; + const high = findings.filter(f => f.severity === 'high').length; + + let comment = `## 🔍 Hypatia Security Scan\n\n`; + comment += `**Findings:** ${findings.length} issues detected\n\n`; + comment += `| Severity | Count |\n|----------|-------|\n`; + comment += `| 🔴 Critical | ${critical} |\n`; + comment += `| 🟠 High | ${high} |\n`; + comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`; + + if (critical > 0) { + comment += `⚠️ **Action Required:** Critical security issues found!\n\n`; + } + + comment += `
View findings\n\n`; + comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`; + comment += `
\n\n`; + comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`; + + github.rest.issues.createComment({ + owner: context.repo.owner, + repo: context.repo.repo, + issue_number: context.issue.number, + body: comment + }); \ No newline at end of file diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index d022c3e..e1d2d9d 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -14,6 +14,7 @@ permissions: jobs: dispatch: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Trigger Propagation uses: peter-evans/repository-dispatch@28959ce8df70de7be546dd1250a005dd32156697 # v3 diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 2083ca6..2e504a4 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -10,6 +10,142 @@ permissions: contents: read jobs: - mirror: - uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@e6b2884722350515934d443daf23442f2195796f - secrets: inherit + mirror-gitlab: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.GITLAB_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + with: + ssh-private-key: ${{ secrets.GITLAB_SSH_KEY }} + + - name: Mirror to GitLab + run: | + ssh-keyscan -t ed25519 gitlab.com >> ~/.ssh/known_hosts + git remote add gitlab git@gitlab.com:${{ vars.GITLAB_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true + git push --force gitlab main + + mirror-bitbucket: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.BITBUCKET_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + with: + ssh-private-key: ${{ secrets.BITBUCKET_SSH_KEY }} + + - name: Mirror to Bitbucket + run: | + ssh-keyscan -t ed25519 bitbucket.org >> ~/.ssh/known_hosts + git remote add bitbucket git@bitbucket.org:${{ vars.BITBUCKET_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true + git push --force bitbucket main + + mirror-codeberg: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.CODEBERG_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + with: + ssh-private-key: ${{ secrets.CODEBERG_SSH_KEY }} + + - name: Mirror to Codeberg + run: | + ssh-keyscan -t ed25519 codeberg.org >> ~/.ssh/known_hosts + git remote add codeberg git@codeberg.org:${{ vars.CODEBERG_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true + git push --force codeberg main + + mirror-sourcehut: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.SOURCEHUT_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + with: + ssh-private-key: ${{ secrets.SOURCEHUT_SSH_KEY }} + + - name: Mirror to SourceHut + run: | + ssh-keyscan -t ed25519 git.sr.ht >> ~/.ssh/known_hosts + git remote add sourcehut git@git.sr.ht:~${{ vars.SOURCEHUT_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }} || true + git push --force sourcehut main + + mirror-disroot: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.DISROOT_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + with: + ssh-private-key: ${{ secrets.DISROOT_SSH_KEY }} + + - name: Mirror to Disroot + run: | + ssh-keyscan -t ed25519 git.disroot.org >> ~/.ssh/known_hosts + git remote add disroot git@git.disroot.org:${{ vars.DISROOT_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true + git push --force disroot main + + mirror-gitea: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.GITEA_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + with: + ssh-private-key: ${{ secrets.GITEA_SSH_KEY }} + + - name: Mirror to Gitea + run: | + ssh-keyscan -t ed25519 ${{ vars.GITEA_HOST }} >> ~/.ssh/known_hosts + git remote add gitea git@${{ vars.GITEA_HOST }}:${{ vars.GITEA_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true + git push --force gitea main + + mirror-radicle: + runs-on: ubuntu-latest + timeout-minutes: 15 + if: vars.RADICLE_MIRROR_ENABLED == 'true' + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Setup Rust + uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable + with: + toolchain: stable + + - name: Install Radicle + run: | + # Install via cargo (safer than curl|sh) + cargo install radicle-cli --locked + echo "$HOME/.cargo/bin" >> $GITHUB_PATH + + - name: Mirror to Radicle + run: | + echo "${{ secrets.RADICLE_KEY }}" > ~/.radicle/keys/radicle + chmod 600 ~/.radicle/keys/radicle + rad sync --announce || echo "Radicle sync attempted" diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index c2262ed..6f00e2a 100644 --- a/.github/workflows/openssf-compliance.yml +++ b/.github/workflows/openssf-compliance.yml @@ -16,6 +16,7 @@ permissions: jobs: openssf-compliance: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read steps: diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index e49a7b5..5f18a11 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -18,6 +18,7 @@ jobs: build: name: Build Artifacts runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read steps: @@ -78,6 +79,7 @@ jobs: changelog: name: Generate Changelog runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: read outputs: @@ -124,6 +126,7 @@ jobs: name: Create GitHub Release needs: [build, changelog] runs-on: ubuntu-latest + timeout-minutes: 15 permissions: contents: write steps: diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index a82f178..471d9d4 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -27,6 +27,7 @@ permissions: jobs: rhodibot: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 1b1b792..e2bd00c 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -13,5 +13,57 @@ permissions: contents: read jobs: - rust-ci: - uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@cc5a372af1af1b202c17f1b21efd954e6c038bef + check: + name: Cargo check + clippy + fmt + runs-on: ubuntu-latest + timeout-minutes: 15 + if: hashFiles('Cargo.toml') != '' + + steps: + - name: Checkout repository + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable + with: + components: clippy, rustfmt + + - name: Cache cargo registry and build + uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 + + - name: Cargo check + run: cargo check --all-targets 2>&1 + + - name: Cargo fmt + run: cargo fmt --all -- --check + + - name: Cargo clippy + run: cargo clippy --all-targets -- -D warnings + + test: + name: Cargo test + runs-on: ubuntu-latest + timeout-minutes: 15 + needs: check + if: hashFiles('Cargo.toml') != '' + + steps: + - name: Checkout repository + uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable + + - name: Cache cargo registry and build + uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 + + - name: Run tests + run: cargo test --all-targets + + - name: Write summary + if: always() + run: | + echo "## Rust CI Results" >> "$GITHUB_STEP_SUMMARY" + echo "" >> "$GITHUB_STEP_SUMMARY" + echo "- **cargo check**: passed" >> "$GITHUB_STEP_SUMMARY" + echo "- **cargo test**: completed" >> "$GITHUB_STEP_SUMMARY" diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 6933b78..57535d0 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -23,6 +23,7 @@ permissions: jobs: scorecard: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: security-events: write id-token: write # For OIDC @@ -61,6 +62,7 @@ jobs: # Check specific high-priority items check-critical: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index fc907c2..397e7b3 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -12,5 +12,23 @@ permissions: read-all jobs: analysis: - uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@e0caf11508a3989574713c78f5f444f2ce5e33ef - secrets: inherit + runs-on: ubuntu-latest + timeout-minutes: 15 + permissions: + security-events: write + id-token: write + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + persist-credentials: false + + - name: Run Scorecard + uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.3.1 + with: + results_file: results.sarif + results_format: sarif + + - name: Upload results + uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v3.31.8 + with: + sarif_file: results.sarif diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 586cdc0..0dd8fc1 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -14,6 +14,66 @@ permissions: contents: read jobs: - scan: - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@3e4bd4c93911750727e2e4c66dff859e00079da0 - secrets: inherit + trufflehog: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + fetch-depth: 0 # Full history for scanning + + - name: TruffleHog Secret Scan + uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d # v3 + with: + # The v3 action injects --fail automatically on pull_request events. + # Passing --fail here triggers "flag 'fail' cannot be repeated". + extra_args: --only-verified + + gitleaks: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + with: + fetch-depth: 0 + + - name: Gitleaks Secret Scan + uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2 + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + # Rust-specific: Check for hardcoded crypto values + rust-secrets: + runs-on: ubuntu-latest + timeout-minutes: 15 + steps: + - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 + + - name: Check for hardcoded secrets in Rust + run: | + if ! find . -name Cargo.toml -not -path './target/*' -print -quit | grep -q .; then + echo 'No Cargo.toml found — skipping Rust secrets check' + exit 0 + fi + # Patterns that suggest hardcoded secrets + PATTERNS=( + 'const.*SECRET.*=.*"' + 'const.*KEY.*=.*"[a-zA-Z0-9]{16,}"' + 'const.*TOKEN.*=.*"' + 'let.*api_key.*=.*"' + 'HMAC.*"[a-fA-F0-9]{32,}"' + 'password.*=.*"[^"]+"' + ) + + found=0 + for pattern in "${PATTERNS[@]}"; do + if grep -rn --include="*.rs" -E "$pattern" src/; then + echo "WARNING: Potential hardcoded secret found matching: $pattern" + found=1 + fi + done + + if [ $found -eq 1 ]; then + echo "::error::Potential hardcoded secrets detected. Use environment variables instead." + exit 1 + fi diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index e48efaf..740ef5a 100644 --- a/.github/workflows/static-analysis-gate.yml +++ b/.github/workflows/static-analysis-gate.yml @@ -19,6 +19,7 @@ jobs: panic-attack-assail: name: panic-attack assail runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -123,6 +124,7 @@ jobs: hypatia-scan: name: Hypatia neurosymbolic scan runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -236,6 +238,7 @@ jobs: patch-bridge-triage: name: Patch Bridge CVE triage runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository @@ -325,6 +328,7 @@ jobs: deposit-findings: name: Deposit findings for gitbot-fleet runs-on: ubuntu-latest + timeout-minutes: 15 needs: [panic-attack-assail, hypatia-scan, patch-bridge-triage] if: always() diff --git a/.machine_readable/6a2/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/0-AI-MANIFEST.a2ml new file mode 100644 index 0000000..6bf1f8c --- /dev/null +++ b/.machine_readable/6a2/0-AI-MANIFEST.a2ml @@ -0,0 +1,31 @@ +# AI Manifest for 6a2 Directory + +## Purpose + +This manifest declares the AI-assistant context for the 6a2 machine-readable metadata directory. + +## Canonical Locations + +The 6 core A2ML files MUST exist in this directory: +1. AGENTIC.a2ml +2. ECOSYSTEM.a2ml +3. META.a2ml +4. NEUROSYM.a2ml +5. PLAYBOOK.a2ml +6. STATE.a2ml + +## Invariants + +- No duplicate files in root directory +- Single source of truth: this directory is authoritative +- No stale metadata + +## Protocol + +When multiple agents may write to A2ML files concurrently: +1. Read file and record git-sha-at-read in [provenance] section +2. Lock by creating .lock- +3. Write updated file with new [provenance] metadata +4. Release by removing lock file +5. On conflict: re-read and retry if git-sha-at-read does not match HEAD + diff --git a/.machine_readable/6a2/README.adoc b/.machine_readable/6a2/README.adoc new file mode 100644 index 0000000..bc033d7 --- /dev/null +++ b/.machine_readable/6a2/README.adoc @@ -0,0 +1,30 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell +# A2ML 6a2 Directory + +This directory contains the 6 core A2ML machine-readable metadata files for this repository. + +## Files + +- `AGENTIC.a2ml` - AI agent operational gating, safety controls +- `ECOSYSTEM.a2ml` - Project ecosystem position, relationships, explicit boundaries +- `META.a2ml` - Architecture decisions (ADRs), development practices, design rationale +- `NEUROSYM.a2ml` - Symbolic semantics, composition algebra +- `PLAYBOOK.a2ml` - Executable plans, operational runbooks +- `STATE.a2ml` - Project state, phase, milestones, session history + +## Standards Compliance + +These files follow the A2ML Format Family specification from: +https://github.com/hyperpolymath/standards/tree/main/a2ml + +## Generation + +These files may be generated from .scm source files using transpilation tools. +Source .scm files should be removed after successful transpilation. + +## See Also + +- [A2ML Repository Template](https://github.com/hyperpolymath/standards/blob/main/A2ML-REPO-TEMPLATE.adoc) +- [6A2 Format Family](https://github.com/hyperpolymath/standards#a2ml-format-family-7-formats) + diff --git a/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml new file mode 100644 index 0000000..0dd6825 --- /dev/null +++ b/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml @@ -0,0 +1,21 @@ +# AI Manifest for Anchor Directory + +## Purpose + +This manifest declares the AI-assistant context for the anchor machine-readable metadata directory. + +## Canonical Locations + +ANCHOR.a2ml files MUST exist in this directory. + +## Multiple Versions + +Unlike other A2ML files, multiple versions of ANCHOR.a2ml with different dates MAY exist. +Each version represents a specific recalibration point. + +## Invariants + +- Multiple versions with different dates are permitted +- No other A2ML files in this directory +- Single source of truth for anchor documents + diff --git a/.machine_readable/anchors/ANCHOR.a2ml b/.machine_readable/6a2/anchor/ANCHOR.a2ml similarity index 100% rename from .machine_readable/anchors/ANCHOR.a2ml rename to .machine_readable/6a2/anchor/ANCHOR.a2ml diff --git a/.machine_readable/6a2/anchor/README.adoc b/.machine_readable/6a2/anchor/README.adoc new file mode 100644 index 0000000..bd23e35 --- /dev/null +++ b/.machine_readable/6a2/anchor/README.adoc @@ -0,0 +1,25 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell +# A2ML Anchor Directory + +This directory contains ANCHOR.a2ml files for project recalibration and scope intervention. + +## Files + +- `ANCHOR.a2ml` - Project recalibration, scope intervention, canonical authority + +## Multiple Versions + +Unlike other A2ML files, multiple versions of ANCHOR.a2ml with different dates may exist. +Each version represents a specific recalibration point in the project history. + +## Standards Compliance + +These files follow the ANCHOR.a2ml specification from: +https://github.com/hyperpolymath/standards/tree/main/anchor-a2ml + +## See Also + +- [A2ML Repository Template](https://github.com/hyperpolymath/standards/blob/main/A2ML-REPO-TEMPLATE.adoc) +- [Anchor A2ML Spec](https://github.com/hyperpolymath/standards/tree/main/anchor-a2ml) + diff --git a/.machine_readable/MUST.contractile b/.machine_readable/MUST.contractile index 1160f0a..48ffff1 100644 --- a/.machine_readable/MUST.contractile +++ b/.machine_readable/MUST.contractile @@ -26,7 +26,7 @@ ; remain active until the feature is fully removed. ; ; Enforcement: -; K9 validators in contractiles/k9/ machine-check MUST constraints. +; K9 validators in contractiles/self-validating/ machine-check MUST constraints. ; CI runs these on every PR. Violations block merge. ; ; ── End Definitions ────────────────────────────────────────────── @@ -85,7 +85,7 @@ ; (must "# Add project-specific invariants here") (enforcement - (k9-validator "contractiles/k9/must-check.k9.ncl") + (k9-validator "contractiles/self-validating/must-check.k9.ncl") (ci "quality.yml runs must-check on every PR") ) ) diff --git a/.machine_readable/README.adoc b/.machine_readable/README.adoc index 471d6c7..e72996d 100644 --- a/.machine_readable/README.adoc +++ b/.machine_readable/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = .machine_readable Pillar diff --git a/.machine_readable/agent_instructions/README.adoc b/.machine_readable/agent_instructions/README.adoc index 6f7b429..e5fec01 100644 --- a/.machine_readable/agent_instructions/README.adoc +++ b/.machine_readable/agent_instructions/README.adoc @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +// Copyright (c) Jonathan D.A. Jewell = Agent Instructions :toc: preamble diff --git a/.machine_readable/ai/PLACEHOLDERS.adoc b/.machine_readable/ai/PLACEHOLDERS.adoc index 02bc8b4..b7073b6 100644 --- a/.machine_readable/ai/PLACEHOLDERS.adoc +++ b/.machine_readable/ai/PLACEHOLDERS.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Template Placeholders # Template Placeholders diff --git a/.machine_readable/ai/README.adoc b/.machine_readable/ai/README.adoc index 121bbc8..8cf2ea7 100644 --- a/.machine_readable/ai/README.adoc +++ b/.machine_readable/ai/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = AI Guidance Directory Put AI-facing instructions in this folder. diff --git a/.machine_readable/anchors/README.adoc b/.machine_readable/anchors/README.adoc index 1b27c02..c264945 100644 --- a/.machine_readable/anchors/README.adoc +++ b/.machine_readable/anchors/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = anchors Registry diff --git a/.machine_readable/configs/README.adoc b/.machine_readable/configs/README.adoc index 616b9e7..2ab097e 100644 --- a/.machine_readable/configs/README.adoc +++ b/.machine_readable/configs/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = configs Registry diff --git a/.machine_readable/contractiles/README.adoc b/.machine_readable/contractiles/README.adoc index d40fcd1..2b8aed7 100644 --- a/.machine_readable/contractiles/README.adoc +++ b/.machine_readable/contractiles/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Contractiles Template Set :toc: :sectnums: diff --git a/.machine_readable/policies/README.adoc b/.machine_readable/policies/README.adoc index b7e25f5..045e5af 100644 --- a/.machine_readable/policies/README.adoc +++ b/.machine_readable/policies/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = policies Registry diff --git a/.machine_readable/scripts/forge/README.adoc b/.machine_readable/scripts/forge/README.adoc index 31adef6..a43f1d2 100644 --- a/.machine_readable/scripts/forge/README.adoc +++ b/.machine_readable/scripts/forge/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Forge Scripts diff --git a/.machine_readable/scripts/lifecycle/README.adoc b/.machine_readable/scripts/lifecycle/README.adoc index 8d262b1..481283e 100644 --- a/.machine_readable/scripts/lifecycle/README.adoc +++ b/.machine_readable/scripts/lifecycle/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Lifecycle Scripts diff --git a/.machine_readable/scripts/verification/README.adoc b/.machine_readable/scripts/verification/README.adoc index 277b4aa..19fcf01 100644 --- a/.machine_readable/scripts/verification/README.adoc +++ b/.machine_readable/scripts/verification/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Verification Scripts diff --git a/.machine_readable/svc/k9/README.adoc b/.machine_readable/svc/self-validating/README.adoc similarity index 85% rename from .machine_readable/svc/k9/README.adoc rename to .machine_readable/svc/self-validating/README.adoc index 0eda878..6312e11 100644 --- a/.machine_readable/svc/k9/README.adoc +++ b/.machine_readable/svc/self-validating/README.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = K9 Contractiles :toc: left :icons: font @@ -71,13 +72,13 @@ Choose the appropriate security level for your use case: [source,bash] ---- # Kennel: Pure configuration -cp .machine_readable/contractiles/k9/examples/project-metadata.k9.ncl config/metadata.k9.ncl +cp .machine_readable/contractiles/self-validating/examples/project-metadata.k9.ncl config/metadata.k9.ncl # Yard: Validated configuration -cp .machine_readable/contractiles/k9/examples/ci-config.k9.ncl .github/ci.k9.ncl +cp .machine_readable/contractiles/self-validating/examples/ci-config.k9.ncl .github/ci.k9.ncl # Hunt: Full automation -cp .machine_readable/contractiles/k9/examples/setup-repo.k9.ncl scripts/setup.k9.ncl +cp .machine_readable/contractiles/self-validating/examples/setup-repo.k9.ncl scripts/setup.k9.ncl ---- === 2. Validate Components @@ -130,7 +131,7 @@ K9 contractiles integrate with other RSR standards: ⚠️ **Never run as root unless required** + ⚠️ **Sandbox external components** -**See:** https://github.com/{{OWNER}}/k9-svc/blob/main/docs/SECURITY-BEST-PRACTICES.adoc +**See:** https://github.com/{{OWNER}}/self-validating/blob/main/docs/SECURITY-BEST-PRACTICES.adoc == Template Files @@ -159,9 +160,9 @@ git clone https://github.com/{{OWNER}}/k9-svc.git == Learn More -- **K9-SVC Specification:** https://github.com/{{OWNER}}/k9-svc/blob/main/SPEC.adoc -- **K9 User Guide:** https://github.com/{{OWNER}}/k9-svc/blob/main/GUIDE.adoc -- **Security Documentation:** https://github.com/{{OWNER}}/k9-svc/blob/main/docs/SECURITY-FAQ.adoc +- **K9-SVC Specification:** https://github.com/{{OWNER}}/self-validating/blob/main/SPEC.adoc +- **K9 User Guide:** https://github.com/{{OWNER}}/self-validating/blob/main/GUIDE.adoc +- **Security Documentation:** https://github.com/{{OWNER}}/self-validating/blob/main/docs/SECURITY-FAQ.adoc - **IANA Media Type:** `application/vnd.k9+nickel` == Contributing diff --git a/.machine_readable/svc/k9/examples/ci-config.k9.ncl b/.machine_readable/svc/self-validating/examples/ci-config.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/examples/ci-config.k9.ncl rename to .machine_readable/svc/self-validating/examples/ci-config.k9.ncl diff --git a/.machine_readable/svc/k9/examples/project-metadata.k9.ncl b/.machine_readable/svc/self-validating/examples/project-metadata.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/examples/project-metadata.k9.ncl rename to .machine_readable/svc/self-validating/examples/project-metadata.k9.ncl diff --git a/.machine_readable/svc/k9/examples/setup-repo.k9.ncl b/.machine_readable/svc/self-validating/examples/setup-repo.k9.ncl similarity index 98% rename from .machine_readable/svc/k9/examples/setup-repo.k9.ncl rename to .machine_readable/svc/self-validating/examples/setup-repo.k9.ncl index df79a55..7d5947d 100644 --- a/.machine_readable/svc/k9/examples/setup-repo.k9.ncl +++ b/.machine_readable/svc/self-validating/examples/setup-repo.k9.ncl @@ -95,7 +95,7 @@ K9! commands = [ "mkdir -p src/ docs/ tests/ scripts/", "mkdir -p .github/workflows/", - "mkdir -p .machine_readable/contractiles/k9/", + "mkdir -p .machine_readable/contractiles/self-validating/", "echo '✓ Directory structure created'", ], }, diff --git a/.machine_readable/svc/k9/methodology-guard.k9.ncl b/.machine_readable/svc/self-validating/methodology-guard.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/methodology-guard.k9.ncl rename to .machine_readable/svc/self-validating/methodology-guard.k9.ncl diff --git a/.machine_readable/svc/k9/template-hunt.k9.ncl b/.machine_readable/svc/self-validating/template-hunt.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/template-hunt.k9.ncl rename to .machine_readable/svc/self-validating/template-hunt.k9.ncl diff --git a/.machine_readable/svc/k9/template-kennel.k9.ncl b/.machine_readable/svc/self-validating/template-kennel.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/template-kennel.k9.ncl rename to .machine_readable/svc/self-validating/template-kennel.k9.ncl diff --git a/.machine_readable/svc/k9/template-yard.k9.ncl b/.machine_readable/svc/self-validating/template-yard.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/template-yard.k9.ncl rename to .machine_readable/svc/self-validating/template-yard.k9.ncl diff --git a/AUDIT.adoc b/AUDIT.adoc index cd5669d..0f4f5ac 100644 --- a/AUDIT.adoc +++ b/AUDIT.adoc @@ -1,6 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) - +// Copyright (c) Jonathan D.A. Jewell = Audit Gate Codex v1.1, 2026-04-07 diff --git a/CHANGELOG.md b/CHANGELOG.md index 8109476..66fa7a0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,7 @@ + # Changelog All notable changes to this project will be documented in this file. diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md index 1f1548c..9020def 100644 --- a/CODE_OF_CONDUCT.md +++ b/CODE_OF_CONDUCT.md @@ -1,4 +1,7 @@ - + # Contributor Covenant Code of Conduct ## Our Pledge diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 1d8caa1..8779679 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,7 @@ - + # Contributing 1. Fork the repository diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index edb914d..bb4ff83 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = RSR Template Repo - Explainme :toc: :icons: font diff --git a/LICENSE b/LICENSE index 4a7f1aa..d0a1fa1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,38 +1,3 @@ -SPDX-License-Identifier: MPL-2.0 -SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell (hyperpolymath) - ------------------------------------------------------------------------- -PREFERRED LICENCE: Palimpsest License (MPL-2.0) ------------------------------------------------------------------------- - -This work is governed by the Palimpsest License (MPL-2.0) as -its primary intended licence. MPL-2.0 extends the Mozilla -Public License 2.0 (MPL-2.0) with additional provisions for ethical use, -post-quantum cryptographic provenance, and emotional lineage protection. -The canonical PMPL text and stewardship information are maintained at: - https://github.com/hyperpolymath/palimpsest-license - ------------------------------------------------------------------------- -FALLBACK LICENCE: Mozilla Public License 2.0 (MPL-2.0) ------------------------------------------------------------------------- - -Because MPL-2.0 is not yet recognised by the Open Source -Initiative (OSI) or equivalent bodies, this work also carries MPL-2.0 -as its legally-recognised fallback licence. - -In any jurisdiction, platform, or context where MPL-2.0 is -not accepted as a valid licence, or where an OSI-approved licence is -required, this work is instead governed by the Mozilla Public License, -Version 2.0. - -MPL-2.0 was chosen as the fallback because MPL-2.0 is -explicitly based on and extends MPL-2.0; it is therefore the closest -recognised equivalent to the intended licence. - -The complete MPL-2.0 text follows below. - ------------------------------------------------------------------------- - Mozilla Public License Version 2.0 ================================== @@ -109,17 +74,17 @@ Mozilla Public License Version 2.0 means the form of the work preferred for making modifications. 1.14. "You" (or "Your") - means an individual or a legal entity exercising rights under - this License. For legal entities, "You" includes any entity that - controls, is controlled by, or is under common control with You. - For the purposes of this definition, "control" means (a) the power, - direct or indirect, to cause the direction or management of such - entity, whether by contract or otherwise, or (b) ownership of more - than fifty percent (50%) of the outstanding shares or beneficial + means an individual or a legal entity exercising rights under this + License. For legal entities, "You" includes any entity that + controls, is controlled by, or is under common control with You. For + purposes of this definition, "control" means (a) the power, direct + or indirect, to cause the direction or management of such entity, + whether by contract or otherwise, or (b) ownership of more than + fifty percent (50%) of the outstanding shares or beneficial ownership of such entity. 2. License Grants and Conditions ---------------------------------- +-------------------------------- 2.1. Grants @@ -144,11 +109,11 @@ distributes such Contribution. 2.3. Limitations on Grant Scope -The licenses granted in this Section 2 are the only rights granted -under this License. No additional rights or licenses will be implied -from the distribution or licensing of Covered Software under this -License. Notwithstanding Section 2.1(b) above, no patent license is -granted by a Contributor: +The licenses granted in this Section 2 are the only rights granted under +this License. No additional rights or licenses will be implied from the +distribution or licensing of Covered Software under this License. +Notwithstanding Section 2.1(b) above, no patent license is granted by a +Contributor: (a) for any code that a Contributor has removed from Covered Software; or @@ -158,19 +123,19 @@ granted by a Contributor: Contributions with other software (except as part of its Contributor Version); or -(c) under Patent Claims infringed by Covered Software in the absence - of its Contributions. +(c) under Patent Claims infringed by Covered Software in the absence of + its Contributions. -This License does not grant any rights in the trademarks, service -marks, or logos of any Contributor (except as may be necessary to -comply with the notice requirements in Section 3.4). +This License does not grant any rights in the trademarks, service marks, +or logos of any Contributor (except as may be necessary to comply with +the notice requirements in Section 3.4). 2.4. Subsequent Licenses No Contributor makes additional grants as a result of Your choice to distribute the Covered Software under a subsequent version of this -License (see Section 10.2) or under the terms of a Secondary License -(if permitted under the terms of Section 3.3). +License (see Section 10.2) or under the terms of a Secondary License (if +permitted under the terms of Section 3.3). 2.5. Representation @@ -186,11 +151,11 @@ equivalents. 2.7. Conditions -Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses -granted in Section 2.1. +Sections 3.1, 3.2, 3.3, and 3.4 are conditions of the licenses granted +in Section 2.1. 3. Responsibilities --------------------- +------------------- 3.1. Distribution of Source Form @@ -207,10 +172,10 @@ Form. If You distribute Covered Software in Executable Form then: (a) such Covered Software must also be made available in Source Code - Form, as described in Section 3.1, and You must inform recipients - of the Executable Form how they can obtain a copy of such Source - Code Form by reasonable means in a timely manner, at a charge no - more than the cost of distribution to the recipient; and + Form, as described in Section 3.1, and You must inform recipients of + the Executable Form how they can obtain a copy of such Source Code + Form by reasonable means in a timely manner, at a charge no more + than the cost of distribution to the recipient; and (b) You may distribute such Executable Form under the terms of this License, or sublicense it under different terms, provided that the @@ -222,8 +187,8 @@ If You distribute Covered Software in Executable Form then: You may create and distribute a Larger Work under terms of Your choice, provided that You also comply with the requirements of this License for the Covered Software. If the Larger Work is a combination of Covered -Software with a work governed by one or more Secondary Licenses, and -the Covered Software is not Incompatible With Secondary Licenses, this +Software with a work governed by one or more Secondary Licenses, and the +Covered Software is not Incompatible With Secondary Licenses, this License permits You to additionally distribute such Covered Software under the terms of such Secondary License(s), so that the recipient of the Larger Work may, at their option, further distribute the Covered @@ -241,28 +206,28 @@ the extent required to remedy known factual inaccuracies. 3.5. Application of Additional Terms You may choose to offer, and to charge a fee for, warranty, support, -indemnity or liability obligations to one or more recipients of -Covered Software. However, You may do so only on Your own behalf, and -not on behalf of any Contributor. You must make it absolutely clear -that any such warranty, support, indemnity, or liability obligation is -offered by You alone, and You hereby agree to indemnify every -Contributor for any liability incurred by such Contributor as a result -of warranty, support, indemnity or liability terms You offer. You may -include additional disclaimers of warranty and limitations of liability -specific to any jurisdiction. +indemnity or liability obligations to one or more recipients of Covered +Software. However, You may do so only on Your own behalf, and not on +behalf of any Contributor. You must make it absolutely clear that any +such warranty, support, indemnity, or liability obligation is offered by +You alone, and You hereby agree to indemnify every Contributor for any +liability incurred by such Contributor as a result of warranty, support, +indemnity or liability terms You offer. You may include additional +disclaimers of warranty and limitations of liability specific to any +jurisdiction. 4. Inability to Comply Due to Statute or Regulation ------------------------------------------------------ +--------------------------------------------------- If it is impossible for You to comply with any of the terms of this License with respect to some or all of the Covered Software due to statute, judicial order, or regulation then You must: (a) comply with the terms of this License to the maximum extent possible; and (b) -describe the limitations and the code they affect. Such description -must be placed in a text file included with all distributions of the -Covered Software under this License. Except to the extent prohibited -by statute or regulation, such description must be sufficiently -detailed for a recipient of ordinary skill to be able to understand it. +describe the limitations and the code they affect. Such description must +be placed in a text file included with all distributions of the Covered +Software under this License. Except to the extent prohibited by statute +or regulation, such description must be sufficiently detailed for a +recipient of ordinary skill to be able to understand it. 5. Termination -------------- @@ -271,27 +236,27 @@ detailed for a recipient of ordinary skill to be able to understand it. if You fail to comply with any of its terms. However, if You become compliant, then the rights granted under this License from a particular Contributor are reinstated (a) provisionally, unless and until such -Contributor explicitly and finally terminates Your grants, and (b) on -an ongoing basis, if such Contributor fails to notify You of the +Contributor explicitly and finally terminates Your grants, and (b) on an +ongoing basis, if such Contributor fails to notify You of the non-compliance by some reasonable means prior to 60 days after You have come back into compliance. Moreover, Your grants from a particular Contributor are reinstated on an ongoing basis if such Contributor -notifies You of the non-compliance by some reasonable means, this is -the first time You have received notice of non-compliance with this -License from such Contributor, and You become compliant prior to 30 -days after Your receipt of the notice. +notifies You of the non-compliance by some reasonable means, this is the +first time You have received notice of non-compliance with this License +from such Contributor, and You become compliant prior to 30 days after +Your receipt of the notice. -5.2. If You initiate litigation against any entity by asserting a -patent infringement claim (excluding declaratory judgment actions, +5.2. If You initiate litigation against any entity by asserting a patent +infringement claim (excluding declaratory judgment actions, counter-claims, and cross-claims) alleging that a Contributor Version directly or indirectly infringes any patent, then the rights granted to You by any and all Contributors for the Covered Software under Section 2.1 of this License shall terminate. 5.3. In the event of termination under Sections 5.1 or 5.2 above, all -end user license agreements (excluding distributors and resellers) -which have been validly granted by You or Your distributors under this -License prior to termination shall survive termination. +end user license agreements (excluding distributors and resellers) which +have been validly granted by You or Your distributors under this License +prior to termination shall survive termination. ************************************************************************ * * @@ -346,7 +311,7 @@ Nothing in this Section shall prevent a party's ability to bring cross-claims or counter-claims. 9. Miscellaneous ------------------ +---------------- This License represents the complete agreement concerning the subject matter hereof. If any provision of this License is held to be @@ -356,14 +321,14 @@ that the language of a contract shall be construed against the drafter shall not be used to construe this License against a Contributor. 10. Versions of the License ----------------------------- +--------------------------- 10.1. New Versions -Mozilla Foundation is the license steward. Except as provided in -Section 10.3, no one other than the license steward has the right to -modify or publish new versions of this License. Each version will be -given a distinguishing version number. +Mozilla Foundation is the license steward. Except as provided in Section +10.3, no one other than the license steward has the right to modify or +publish new versions of this License. Each version will be given a +distinguishing version number. 10.2. Effect of New Versions @@ -392,17 +357,17 @@ Exhibit A - Source Code Form License Notice This Source Code Form is subject to the terms of the Mozilla Public License, v. 2.0. If a copy of the MPL was not distributed with this - file, You can obtain one at http://mozilla.org/MPL/2.0/. + file, You can obtain one at https://mozilla.org/MPL/2.0/. If it is not possible or desirable to put the notice in a particular file, then You may include the notice in a location (such as a LICENSE -file in a relevant directory) where a recipient would be likely to -look for such a notice. +file in a relevant directory) where a recipient would be likely to look +for such a notice. You may add additional accurate notices of copyright ownership. Exhibit B - "Incompatible With Secondary Licenses" Notice ----------------------------------------------------------- +--------------------------------------------------------- This Source Code Form is "Incompatible With Secondary Licenses", as defined by the Mozilla Public License, v. 2.0. diff --git a/PROOF-NEEDS.md b/PROOF-NEEDS.md index d16a951..7e8631a 100644 --- a/PROOF-NEEDS.md +++ b/PROOF-NEEDS.md @@ -1,5 +1,8 @@ + # Proof Requirements — {{PROJECT}} - diff --git a/PROOF-STATUS.md b/PROOF-STATUS.md index 2be9f55..aed5e41 100644 --- a/PROOF-STATUS.md +++ b/PROOF-STATUS.md @@ -1,5 +1,8 @@ + # Proof Status — {{PROJECT}} - diff --git a/QUICKSTART-DEV.adoc b/QUICKSTART-DEV.adoc index 511a925..02957ea 100644 --- a/QUICKSTART-DEV.adoc +++ b/QUICKSTART-DEV.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell // Template: QUICKSTART-DEV.adoc — clone → build → test → PR // Replace rsr-template-repo, {{BUILD_CMD}}, {{TEST_CMD}}, {{LANG_STACK}} with actuals = rsr-template-repo — Quick Start for Developers diff --git a/QUICKSTART-MAINTAINER.adoc b/QUICKSTART-MAINTAINER.adoc index 3424f2d..cd30dd7 100644 --- a/QUICKSTART-MAINTAINER.adoc +++ b/QUICKSTART-MAINTAINER.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell // Template: QUICKSTART-MAINTAINER.adoc — packaging, deploying, and maintaining // Replace rsr-template-repo, {{PACKAGE_NAME}}, {{DEPS}} with actuals = rsr-template-repo — Quick Start for Platform Maintainers @@ -106,7 +107,7 @@ Or via OPSM: `opsm update {{PACKAGE_NAME}}` == Security Notes -* License: MPL-2.0 (Palimpsest License) +* License: MPL-2.0 (MPL-2.0) * All dependencies SHA-pinned * `panic-attacker` scan results: link:INSTALL-SECURITY-REPORT.adoc[] * OpenSSF Scorecard: see badge in README diff --git a/QUICKSTART-USER.adoc b/QUICKSTART-USER.adoc index c85eabe..4992e32 100644 --- a/QUICKSTART-USER.adoc +++ b/QUICKSTART-USER.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell // Template: QUICKSTART-USER.adoc — 5-minute path to working software // Replace rsr-template-repo, Rsr Template Repo — See README.adoc for details., just run, Rsr Template Repo started successfully. with actuals = rsr-template-repo — Quick Start for Users diff --git a/READINESS.md b/READINESS.md index ee11403..b4669be 100644 --- a/READINESS.md +++ b/READINESS.md @@ -1,4 +1,7 @@ - + # {{REPO}} Component Readiness Assessment diff --git a/README.adoc b/README.adoc index 9e19208..a853637 100644 --- a/README.adoc +++ b/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = RSR Template Repository :toc: preamble :icons: font diff --git a/ROADMAP.adoc b/ROADMAP.adoc index 3648ef1..128ed39 100644 --- a/ROADMAP.adoc +++ b/ROADMAP.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = YOUR Template Repo Roadmap == Current Status diff --git a/SECURITY.md b/SECURITY.md index 1a29117..88df5ba 100644 --- a/SECURITY.md +++ b/SECURITY.md @@ -1,4 +1,7 @@ - + # Security Policy ## Reporting a Vulnerability diff --git a/TEMPLATE-STANDARDS-AUDIT.adoc b/TEMPLATE-STANDARDS-AUDIT.adoc index 9a0e6f1..ed67254 100644 --- a/TEMPLATE-STANDARDS-AUDIT.adoc +++ b/TEMPLATE-STANDARDS-AUDIT.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Template Standards Audit Codex v1.0, 2026-04-07 diff --git a/TEST-NEEDS.md b/TEST-NEEDS.md index 9fc5451..1d68060 100644 --- a/TEST-NEEDS.md +++ b/TEST-NEEDS.md @@ -1,3 +1,7 @@ + # TEST-NEEDS: rsr-template-repo ## CRG Grade: C — ACHIEVED 2026-04-04 diff --git a/TOPOLOGY.md b/TOPOLOGY.md index c3107b3..98995e1 100644 --- a/TOPOLOGY.md +++ b/TOPOLOGY.md @@ -1,4 +1,7 @@ - + # Architecture Topology diff --git a/container/README.adoc b/container/README.adoc index d53c353..0db8201 100644 --- a/container/README.adoc +++ b/container/README.adoc @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +// Copyright (c) Jonathan D.A. Jewell = {{PROJECT_NAME}} Container Templates :toc: left :toclevels: 3 diff --git a/docs/QUICKSTART.adoc b/docs/QUICKSTART.adoc index d97c31e..7974257 100644 --- a/docs/QUICKSTART.adoc +++ b/docs/QUICKSTART.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Quickstart :toc: preamble diff --git a/docs/README.adoc b/docs/README.adoc index df45be7..adf6a02 100644 --- a/docs/README.adoc +++ b/docs/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Documentation Layout Primary tracks: diff --git a/docs/RSR_OUTLINE.adoc b/docs/RSR_OUTLINE.adoc index e07a65e..1b940e9 100644 --- a/docs/RSR_OUTLINE.adoc +++ b/docs/RSR_OUTLINE.adoc @@ -1,6 +1,8 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = RSR Template Repository -image:[Palimpsest-MPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"] +image:[MPL-2.0-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] image:[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"] :toc: :sectnums: diff --git a/docs/STATE-VISUALIZER.adoc b/docs/STATE-VISUALIZER.adoc index 422fcd5..77c0248 100644 --- a/docs/STATE-VISUALIZER.adoc +++ b/docs/STATE-VISUALIZER.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Project State Visualizer [source] ---- diff --git a/docs/architecture/THREAT-MODEL.adoc b/docs/architecture/THREAT-MODEL.adoc index 88a9c03..05e1f7c 100644 --- a/docs/architecture/THREAT-MODEL.adoc +++ b/docs/architecture/THREAT-MODEL.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Threat Model diff --git a/docs/attribution/CITATIONS.adoc b/docs/attribution/CITATIONS.adoc index 2ca532e..3273e53 100644 --- a/docs/attribution/CITATIONS.adoc +++ b/docs/attribution/CITATIONS.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = {{PROJECT_NAME}} - Citation Guide :toc: diff --git a/docs/attribution/CODEOWNERS.adoc b/docs/attribution/CODEOWNERS.adoc index 3714055..668df01 100644 --- a/docs/attribution/CODEOWNERS.adoc +++ b/docs/attribution/CODEOWNERS.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Code Ownership :icons: font diff --git a/docs/attribution/MAINTAINERS.adoc b/docs/attribution/MAINTAINERS.adoc index 7f22e21..c5a4b31 100644 --- a/docs/attribution/MAINTAINERS.adoc +++ b/docs/attribution/MAINTAINERS.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Maintainers :toc: preamble diff --git a/docs/attribution/README.adoc b/docs/attribution/README.adoc index b095612..2e50721 100644 --- a/docs/attribution/README.adoc +++ b/docs/attribution/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = attribution Unit diff --git a/docs/decisions/0000-template.adoc b/docs/decisions/0000-template.adoc index 3c57d3a..07c5453 100644 --- a/docs/decisions/0000-template.adoc +++ b/docs/decisions/0000-template.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Architecture Decision Record: 0000-template diff --git a/docs/decisions/0001-adopt-rsr-standard.adoc b/docs/decisions/0001-adopt-rsr-standard.adoc index 3bb6081..5b3b3be 100644 --- a/docs/decisions/0001-adopt-rsr-standard.adoc +++ b/docs/decisions/0001-adopt-rsr-standard.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Architecture Decision Record: 0001-adopt-rsr-standard diff --git a/docs/decisions/README.adoc b/docs/decisions/README.adoc index 153a5e7..af174f5 100644 --- a/docs/decisions/README.adoc +++ b/docs/decisions/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = decisions Unit diff --git a/docs/developer/ABI-FFI-README.adoc b/docs/developer/ABI-FFI-README.adoc index 65d2afe..08d2a72 100644 --- a/docs/developer/ABI-FFI-README.adoc +++ b/docs/developer/ABI-FFI-README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = ABI/FFI Standards {{~ Aditionally delete this line and fill out the template below ~}} diff --git a/docs/developer/README.adoc b/docs/developer/README.adoc index 1d00529..2b328b4 100644 --- a/docs/developer/README.adoc +++ b/docs/developer/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = developer Unit diff --git a/docs/governance/CRG-CRITERIA.adoc b/docs/governance/CRG-CRITERIA.adoc index f8264e6..926df5a 100644 --- a/docs/governance/CRG-CRITERIA.adoc +++ b/docs/governance/CRG-CRITERIA.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Component Readiness Grades (CRG) Criteria :toc: preamble :icons: font diff --git a/docs/governance/MAINTENANCE-CHECKLIST.adoc b/docs/governance/MAINTENANCE-CHECKLIST.adoc index 1160797..0b27a19 100644 --- a/docs/governance/MAINTENANCE-CHECKLIST.adoc +++ b/docs/governance/MAINTENANCE-CHECKLIST.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Maintenance Checklist # Maintenance Checklist (Cross-Repo) diff --git a/docs/governance/README.adoc b/docs/governance/README.adoc index 114ee94..48cac0d 100644 --- a/docs/governance/README.adoc +++ b/docs/governance/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Governance Pillar (TSDM) diff --git a/docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc b/docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc index e8805c6..2bfa0ff 100644 --- a/docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc +++ b/docs/governance/SOFTWARE-DEVELOPMENT-APPROACH.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Software Development Approach (General) :toc: left :toclevels: 2 diff --git a/docs/governance/TSDM.adoc b/docs/governance/TSDM.adoc index cbd582c..6bf4ee8 100644 --- a/docs/governance/TSDM.adoc +++ b/docs/governance/TSDM.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Triaxial Software Development Methodology (TSDM) :toc: preamble :icons: font diff --git a/docs/governance/audit/README.adoc b/docs/governance/audit/README.adoc index fac3740..02aff13 100644 --- a/docs/governance/audit/README.adoc +++ b/docs/governance/audit/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Audit Axis diff --git a/docs/governance/audit/compliance/README.adoc b/docs/governance/audit/compliance/README.adoc index 876954f..9948dbc 100644 --- a/docs/governance/audit/compliance/README.adoc +++ b/docs/governance/audit/compliance/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Compliance Unit diff --git a/docs/governance/audit/effects/README.adoc b/docs/governance/audit/effects/README.adoc index 3634799..e5620ee 100644 --- a/docs/governance/audit/effects/README.adoc +++ b/docs/governance/audit/effects/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Effects Unit diff --git a/docs/governance/audit/systems/README.adoc b/docs/governance/audit/systems/README.adoc index 8d179b4..00a67de 100644 --- a/docs/governance/audit/systems/README.adoc +++ b/docs/governance/audit/systems/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Systems Unit diff --git a/docs/governance/maintenance/README.adoc b/docs/governance/maintenance/README.adoc index 0ed2f1b..7083a83 100644 --- a/docs/governance/maintenance/README.adoc +++ b/docs/governance/maintenance/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Maintenance Axis diff --git a/docs/governance/maintenance/adaptive/README.adoc b/docs/governance/maintenance/adaptive/README.adoc index 7b60992..72d0381 100644 --- a/docs/governance/maintenance/adaptive/README.adoc +++ b/docs/governance/maintenance/adaptive/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Adaptive Unit diff --git a/docs/governance/maintenance/corrective/README.adoc b/docs/governance/maintenance/corrective/README.adoc index ed904a8..9a0ed5d 100644 --- a/docs/governance/maintenance/corrective/README.adoc +++ b/docs/governance/maintenance/corrective/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Corrective Unit diff --git a/docs/governance/maintenance/perfective/README.adoc b/docs/governance/maintenance/perfective/README.adoc index 8759d74..12e3d14 100644 --- a/docs/governance/maintenance/perfective/README.adoc +++ b/docs/governance/maintenance/perfective/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Perfective Unit diff --git a/docs/governance/planning/README.adoc b/docs/governance/planning/README.adoc index 62aa375..2694fe9 100644 --- a/docs/governance/planning/README.adoc +++ b/docs/governance/planning/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Planning Axis diff --git a/docs/governance/planning/could/README.adoc b/docs/governance/planning/could/README.adoc index ad5a6b8..acc41ce 100644 --- a/docs/governance/planning/could/README.adoc +++ b/docs/governance/planning/could/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Could Unit diff --git a/docs/governance/planning/must/README.adoc b/docs/governance/planning/must/README.adoc index 47eb46d..5759550 100644 --- a/docs/governance/planning/must/README.adoc +++ b/docs/governance/planning/must/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Must Unit diff --git a/docs/governance/planning/should/README.adoc b/docs/governance/planning/should/README.adoc index 605489c..a00f585 100644 --- a/docs/governance/planning/should/README.adoc +++ b/docs/governance/planning/should/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Should Unit diff --git a/docs/practice/AI-CONVENTIONS.adoc b/docs/practice/AI-CONVENTIONS.adoc index 97b2bda..ab95e10 100644 --- a/docs/practice/AI-CONVENTIONS.adoc +++ b/docs/practice/AI-CONVENTIONS.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = AI Conventions diff --git a/docs/practice/README.adoc b/docs/practice/README.adoc index ae3326b..caceb5c 100644 --- a/docs/practice/README.adoc +++ b/docs/practice/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = practice Unit diff --git a/docs/practice/STATE-VISUALIZER-GUIDE.adoc b/docs/practice/STATE-VISUALIZER-GUIDE.adoc index 2b7f05e..4fcbddd 100644 --- a/docs/practice/STATE-VISUALIZER-GUIDE.adoc +++ b/docs/practice/STATE-VISUALIZER-GUIDE.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = TOPOLOGY.md — Generation Guide {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> :toc: diff --git a/docs/reports/README.adoc b/docs/reports/README.adoc index 0c06c31..e91d79e 100644 --- a/docs/reports/README.adoc +++ b/docs/reports/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = reports Unit diff --git a/docs/reports/compliance/README.adoc b/docs/reports/compliance/README.adoc index c38c66a..1f6b885 100644 --- a/docs/reports/compliance/README.adoc +++ b/docs/reports/compliance/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Compliance Reports diff --git a/docs/reports/maintenance/README.adoc b/docs/reports/maintenance/README.adoc index f13abf7..82f845e 100644 --- a/docs/reports/maintenance/README.adoc +++ b/docs/reports/maintenance/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Maintenance Reports diff --git a/docs/reports/performance/README.adoc b/docs/reports/performance/README.adoc index 037767d..6473ed3 100644 --- a/docs/reports/performance/README.adoc +++ b/docs/reports/performance/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Performance Reports diff --git a/docs/reports/quality/README.adoc b/docs/reports/quality/README.adoc index d1be848..dbdb3ba 100644 --- a/docs/reports/quality/README.adoc +++ b/docs/reports/quality/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Quality Reports diff --git a/docs/reports/security/README.adoc b/docs/reports/security/README.adoc index 9a78a8b..76656cc 100644 --- a/docs/reports/security/README.adoc +++ b/docs/reports/security/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Security Reports diff --git a/docs/standards/README.adoc b/docs/standards/README.adoc index 34a94c4..41f7a31 100644 --- a/docs/standards/README.adoc +++ b/docs/standards/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Standards Unit diff --git a/docs/templates/contractiles/README.adoc b/docs/templates/contractiles/README.adoc index 121da7a..c544de6 100644 --- a/docs/templates/contractiles/README.adoc +++ b/docs/templates/contractiles/README.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Contractile Templates Blank templates for projects that want to replace the hyperpolymath diff --git a/docs/theory/README.adoc b/docs/theory/README.adoc index c0ddf28..b2658b1 100644 --- a/docs/theory/README.adoc +++ b/docs/theory/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = theory Unit diff --git a/docs/theory/computing/README.adoc b/docs/theory/computing/README.adoc index 4d0db25..aec951f 100644 --- a/docs/theory/computing/README.adoc +++ b/docs/theory/computing/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Computing Theory diff --git a/docs/theory/formalisms/README.adoc b/docs/theory/formalisms/README.adoc index 5d064c3..288a410 100644 --- a/docs/theory/formalisms/README.adoc +++ b/docs/theory/formalisms/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Formalisms Theory diff --git a/docs/theory/mathematics/README.adoc b/docs/theory/mathematics/README.adoc index 356236f..c9b223d 100644 --- a/docs/theory/mathematics/README.adoc +++ b/docs/theory/mathematics/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Mathematics Theory diff --git a/docs/theory/ontologies/README.adoc b/docs/theory/ontologies/README.adoc index 6d16ecf..9267ab0 100644 --- a/docs/theory/ontologies/README.adoc +++ b/docs/theory/ontologies/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Ontologies Theory diff --git a/docs/theory/other/README.adoc b/docs/theory/other/README.adoc index 1861d6d..0ec8432 100644 --- a/docs/theory/other/README.adoc +++ b/docs/theory/other/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Other Theory diff --git a/docs/theory/socio-technical/README.adoc b/docs/theory/socio-technical/README.adoc index 9ab4ee0..5c3c819 100644 --- a/docs/theory/socio-technical/README.adoc +++ b/docs/theory/socio-technical/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Socio technical Theory diff --git a/docs/whitepapers/README.adoc b/docs/whitepapers/README.adoc index 88e83c5..1ee0309 100644 --- a/docs/whitepapers/README.adoc +++ b/docs/whitepapers/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = whitepapers Unit diff --git a/docs/whitepapers/academic/README.adoc b/docs/whitepapers/academic/README.adoc index 16c3f45..d6dc7a0 100644 --- a/docs/whitepapers/academic/README.adoc +++ b/docs/whitepapers/academic/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Academic Logic diff --git a/docs/whitepapers/industry/README.adoc b/docs/whitepapers/industry/README.adoc index 7bc7fcd..2f795b7 100644 --- a/docs/whitepapers/industry/README.adoc +++ b/docs/whitepapers/industry/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Industry Logic diff --git a/docs/whitepapers/outreach/README.adoc b/docs/whitepapers/outreach/README.adoc index 8141463..f3ea4da 100644 --- a/docs/whitepapers/outreach/README.adoc +++ b/docs/whitepapers/outreach/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Outreach & Education :toc: preamble :icons: font diff --git a/docs/wikis/README.adoc b/docs/wikis/README.adoc index 71b60d1..4d493b4 100644 --- a/docs/wikis/README.adoc +++ b/docs/wikis/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Project Wikis :toc: preamble :icons: font diff --git a/examples/README.adoc b/examples/README.adoc index b9cdb48..40bc850 100644 --- a/examples/README.adoc +++ b/examples/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = examples Pillar diff --git a/features/README.adoc b/features/README.adoc index 3899280..4922891 100644 --- a/features/README.adoc +++ b/features/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Project Features diff --git a/features/boj-server/README.adoc b/features/boj-server/README.adoc index 0039c37..0ef0376 100644 --- a/features/boj-server/README.adoc +++ b/features/boj-server/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = BoJ Server Integration :icons: font diff --git a/features/panic-attacker/README.adoc b/features/panic-attacker/README.adoc index 72d56a4..de0bd9b 100644 --- a/features/panic-attacker/README.adoc +++ b/features/panic-attacker/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Panic Attacker Feature :icons: font diff --git a/features/ssg/README.adoc b/features/ssg/README.adoc index e15687b..a6ef262 100644 --- a/features/ssg/README.adoc +++ b/features/ssg/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Ssg Feature diff --git a/llm-warmup-dev.md b/llm-warmup-dev.md index e616c99..99be7bc 100644 --- a/llm-warmup-dev.md +++ b/llm-warmup-dev.md @@ -1,3 +1,7 @@ + # LLM Warmup — rsr-template-repo (Developer) ## What is rsr-template-repo? diff --git a/llm-warmup-user.md b/llm-warmup-user.md index 18a327e..a0992be 100644 --- a/llm-warmup-user.md +++ b/llm-warmup-user.md @@ -1,3 +1,7 @@ + # LLM Warmup — rsr-template-repo (User) ## What is rsr-template-repo? diff --git a/session/README.md b/session/README.md index 70d7444..ee83d59 100644 --- a/session/README.md +++ b/session/README.md @@ -1,3 +1,7 @@ + # Session Bindings (Thin Local Layer) This directory provides local integration for central session-management standards. diff --git a/src/README.adoc b/src/README.adoc index 5529f66..d8c8116 100644 --- a/src/README.adoc +++ b/src/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = src Pillar diff --git a/src/aspects/README.adoc b/src/aspects/README.adoc index 6456f96..9b7b80f 100644 --- a/src/aspects/README.adoc +++ b/src/aspects/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Aspects Pillar diff --git a/src/aspects/integrity/README.adoc b/src/aspects/integrity/README.adoc index f15d829..17a09db 100644 --- a/src/aspects/integrity/README.adoc +++ b/src/aspects/integrity/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Integrity Aspect diff --git a/src/aspects/observability/README.adoc b/src/aspects/observability/README.adoc index 7852ee6..df2ca36 100644 --- a/src/aspects/observability/README.adoc +++ b/src/aspects/observability/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Observability Aspect diff --git a/src/aspects/security/README.adoc b/src/aspects/security/README.adoc index 3c3536e..11ad21b 100644 --- a/src/aspects/security/README.adoc +++ b/src/aspects/security/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Security Aspect diff --git a/src/contracts/README.adoc b/src/contracts/README.adoc index 9cfa209..20dd4ca 100644 --- a/src/contracts/README.adoc +++ b/src/contracts/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Contracts Unit diff --git a/src/definitions/README.adoc b/src/definitions/README.adoc index 9548349..5a9912f 100644 --- a/src/definitions/README.adoc +++ b/src/definitions/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Definitions Unit diff --git a/src/errors/README.adoc b/src/errors/README.adoc index 460fc1e..eff7b29 100644 --- a/src/errors/README.adoc +++ b/src/errors/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Errors Unit diff --git a/src/interface/Abi/Foreign.idr b/src/interface/Abi/Foreign.idr index 3f16342..ca66b08 100644 --- a/src/interface/Abi/Foreign.idr +++ b/src/interface/Abi/Foreign.idr @@ -1,4 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 +-- Copyright (c) Jonathan D.A. Jewell ||| Foreign Function Interface Bridge ||| ||| This module defines the raw FFI calls and their safe wrappers, diff --git a/src/interface/Abi/Layout.idr b/src/interface/Abi/Layout.idr index fec979d..e1f4275 100644 --- a/src/interface/Abi/Layout.idr +++ b/src/interface/Abi/Layout.idr @@ -1,4 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 +-- Copyright (c) Jonathan D.A. Jewell ||| ABI Layout Verification ||| ||| This module provides formal proofs about memory layout, alignment, diff --git a/src/interface/Abi/README.adoc b/src/interface/Abi/README.adoc index 2330304..46743d7 100644 --- a/src/interface/Abi/README.adoc +++ b/src/interface/Abi/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = abi Logic diff --git a/src/interface/Abi/Types.idr b/src/interface/Abi/Types.idr index 6fc4d04..9d30051 100644 --- a/src/interface/Abi/Types.idr +++ b/src/interface/Abi/Types.idr @@ -1,4 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 +-- Copyright (c) Jonathan D.A. Jewell ||| ABI Type Definitions Template ||| ||| This module defines the Application Binary Interface (ABI) for this library. diff --git a/src/interface/README.adoc b/src/interface/README.adoc index 8faf0aa..727b9e7 100644 --- a/src/interface/README.adoc +++ b/src/interface/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = interface Unit diff --git a/src/interface/ffi/README.adoc b/src/interface/ffi/README.adoc index 8fe57d3..b402d64 100644 --- a/src/interface/ffi/README.adoc +++ b/src/interface/ffi/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = ffi Logic diff --git a/src/interface/ffi/build.zig b/src/interface/ffi/build.zig index 69a6377..2607c11 100644 --- a/src/interface/ffi/build.zig +++ b/src/interface/ffi/build.zig @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +// Copyright (c) Jonathan D.A. Jewell // // Template FFI Build Configuration (Zig 0.15.2+) // Note: This is a minimal build file that demonstrates Zig integration diff --git a/src/interface/ffi/src/README.adoc b/src/interface/ffi/src/README.adoc index a5c0c6d..4228438 100644 --- a/src/interface/ffi/src/README.adoc +++ b/src/interface/ffi/src/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Src Logic diff --git a/src/interface/ffi/src/main.zig b/src/interface/ffi/src/main.zig index 6b233bc..f1b2633 100644 --- a/src/interface/ffi/src/main.zig +++ b/src/interface/ffi/src/main.zig @@ -1,9 +1,10 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell // {{PROJECT}} FFI Implementation // // This module implements the C-compatible FFI declared in src/abi/Foreign.idr // All types and layouts must match the Idris2 ABI definitions. // -// SPDX-License-Identifier: MPL-2.0 const std = @import("std"); diff --git a/src/interface/ffi/test/README.adoc b/src/interface/ffi/test/README.adoc index f6f38bf..cdbb47d 100644 --- a/src/interface/ffi/test/README.adoc +++ b/src/interface/ffi/test/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Test Logic diff --git a/src/interface/ffi/test/integration_test.zig b/src/interface/ffi/test/integration_test.zig index 361bd05..484e156 100644 --- a/src/interface/ffi/test/integration_test.zig +++ b/src/interface/ffi/test/integration_test.zig @@ -1,6 +1,6 @@ -// RSR Template FFI Integration Tests // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +// Copyright (c) Jonathan D.A. Jewell +// RSR Template FFI Integration Tests // // These tests verify that the Zig FFI correctly implements the Idris2 ABI. // This is a TEMPLATE FILE — when instantiating a new project: diff --git a/src/interface/generated/README.adoc b/src/interface/generated/README.adoc index 3691b06..93daef2 100644 --- a/src/interface/generated/README.adoc +++ b/src/interface/generated/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = generated Logic diff --git a/src/interface/generated/abi/README.adoc b/src/interface/generated/abi/README.adoc index aff61a9..0e29b69 100644 --- a/src/interface/generated/abi/README.adoc +++ b/src/interface/generated/abi/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Abi Logic diff --git a/tests/fuzz/README.adoc b/tests/fuzz/README.adoc index 55b92f3..44ae058 100644 --- a/tests/fuzz/README.adoc +++ b/tests/fuzz/README.adoc @@ -1,5 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +// Copyright (c) Jonathan D.A. Jewell = Fuzz Testing :toc: diff --git a/tools/invariant-path/README.adoc b/tools/invariant-path/README.adoc index 009d702..57c4e3d 100644 --- a/tools/invariant-path/README.adoc +++ b/tools/invariant-path/README.adoc @@ -1,3 +1,5 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Invariant Path Integration (RSR Template) Run Invariant Path from this repository root: diff --git a/verification/README.adoc b/verification/README.adoc index f07e7f3..efa7fb2 100644 --- a/verification/README.adoc +++ b/verification/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Verification Pillar diff --git a/verification/benchmarks/README.adoc b/verification/benchmarks/README.adoc index 5db7648..beb83cd 100644 --- a/verification/benchmarks/README.adoc +++ b/verification/benchmarks/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Benchmarks Unit diff --git a/verification/coverage/README.adoc b/verification/coverage/README.adoc index 2566956..c10a6ac 100644 --- a/verification/coverage/README.adoc +++ b/verification/coverage/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Coverage Unit diff --git a/verification/fuzzing/README.adoc b/verification/fuzzing/README.adoc index edeb179..b07ea68 100644 --- a/verification/fuzzing/README.adoc +++ b/verification/fuzzing/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Fuzzing Unit diff --git a/verification/proofs/README.adoc b/verification/proofs/README.adoc index 29cf7e8..520f5e9 100644 --- a/verification/proofs/README.adoc +++ b/verification/proofs/README.adoc @@ -1,5 +1,6 @@ -= Formal Verification Proofs // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell += Formal Verification Proofs This directory contains formal proofs organised by proof assistant. diff --git a/verification/proofs/idris2/ABI/Compliance.idr b/verification/proofs/idris2/ABI/Compliance.idr index d38c0d5..b94a5db 100644 --- a/verification/proofs/idris2/ABI/Compliance.idr +++ b/verification/proofs/idris2/ABI/Compliance.idr @@ -1,5 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 --- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +-- Copyright (c) Jonathan D.A. Jewell -- -- ABI Proof: C ABI compliance -- Proves that struct layouts are C ABI compliant. diff --git a/verification/proofs/idris2/ABI/Foreign.idr b/verification/proofs/idris2/ABI/Foreign.idr index cb98ecd..1e550dd 100644 --- a/verification/proofs/idris2/ABI/Foreign.idr +++ b/verification/proofs/idris2/ABI/Foreign.idr @@ -1,5 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 --- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +-- Copyright (c) Jonathan D.A. Jewell -- -- ABI Proof: FFI function return type proofs -- Proves that all FFI functions return expected types. diff --git a/verification/proofs/idris2/ABI/Layout.idr b/verification/proofs/idris2/ABI/Layout.idr index f38fcca..9040a5e 100644 --- a/verification/proofs/idris2/ABI/Layout.idr +++ b/verification/proofs/idris2/ABI/Layout.idr @@ -1,5 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 --- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +-- Copyright (c) Jonathan D.A. Jewell -- -- ABI Proof: Memory layout correctness -- Proves struct size, alignment, and padding properties. diff --git a/verification/proofs/idris2/ABI/Platform.idr b/verification/proofs/idris2/ABI/Platform.idr index 6b80d20..a8d6b94 100644 --- a/verification/proofs/idris2/ABI/Platform.idr +++ b/verification/proofs/idris2/ABI/Platform.idr @@ -1,5 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 --- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +-- Copyright (c) Jonathan D.A. Jewell -- -- ABI Proof: Platform-specific type size proofs -- Proves that C type sizes are correct per platform. diff --git a/verification/proofs/idris2/ABI/Pointers.idr b/verification/proofs/idris2/ABI/Pointers.idr index 49efd2f..31b6c5f 100644 --- a/verification/proofs/idris2/ABI/Pointers.idr +++ b/verification/proofs/idris2/ABI/Pointers.idr @@ -1,5 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 --- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +-- Copyright (c) Jonathan D.A. Jewell -- -- ABI Proof: Non-null pointer safety -- Template proof — customise for your project's pointer types. diff --git a/verification/proofs/idris2/Types.idr b/verification/proofs/idris2/Types.idr index 85ea9b7..cc7cce8 100644 --- a/verification/proofs/idris2/Types.idr +++ b/verification/proofs/idris2/Types.idr @@ -1,5 +1,5 @@ -- SPDX-License-Identifier: MPL-2.0 --- Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +-- Copyright (c) Jonathan D.A. Jewell -- -- Typing Proof: Core data type well-formedness -- Template — replace with your project's core types. diff --git a/verification/safety_case/README.adoc b/verification/safety_case/README.adoc index 47c8e36..ffb53bd 100644 --- a/verification/safety_case/README.adoc +++ b/verification/safety_case/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Safety case Unit diff --git a/verification/simulations/README.adoc b/verification/simulations/README.adoc index 8e1b13a..42e184c 100644 --- a/verification/simulations/README.adoc +++ b/verification/simulations/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Simulations Unit diff --git a/verification/tests/README.adoc b/verification/tests/README.adoc index 344bf86..3930981 100644 --- a/verification/tests/README.adoc +++ b/verification/tests/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Tests Unit diff --git a/verification/traceability/README.adoc b/verification/traceability/README.adoc index ff23dd7..e6e54bc 100644 --- a/verification/traceability/README.adoc +++ b/verification/traceability/README.adoc @@ -1 +1,3 @@ +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell = Traceability Unit From 989840a7189f2543ea253c2cb29ef0824082684d Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:05:03 +0100 Subject: [PATCH 03/11] chore: flatten self-validating directory structure --- .machine_readable/{svc => }/self-validating/README.adoc | 0 .../{svc => }/self-validating/examples/ci-config.k9.ncl | 0 .../{svc => }/self-validating/examples/project-metadata.k9.ncl | 0 .../{svc => }/self-validating/examples/setup-repo.k9.ncl | 0 .../{svc => }/self-validating/methodology-guard.k9.ncl | 0 .machine_readable/{svc => }/self-validating/template-hunt.k9.ncl | 0 .../{svc => }/self-validating/template-kennel.k9.ncl | 0 .machine_readable/{svc => }/self-validating/template-yard.k9.ncl | 0 8 files changed, 0 insertions(+), 0 deletions(-) rename .machine_readable/{svc => }/self-validating/README.adoc (100%) rename .machine_readable/{svc => }/self-validating/examples/ci-config.k9.ncl (100%) rename .machine_readable/{svc => }/self-validating/examples/project-metadata.k9.ncl (100%) rename .machine_readable/{svc => }/self-validating/examples/setup-repo.k9.ncl (100%) rename .machine_readable/{svc => }/self-validating/methodology-guard.k9.ncl (100%) rename .machine_readable/{svc => }/self-validating/template-hunt.k9.ncl (100%) rename .machine_readable/{svc => }/self-validating/template-kennel.k9.ncl (100%) rename .machine_readable/{svc => }/self-validating/template-yard.k9.ncl (100%) diff --git a/.machine_readable/svc/self-validating/README.adoc b/.machine_readable/self-validating/README.adoc similarity index 100% rename from .machine_readable/svc/self-validating/README.adoc rename to .machine_readable/self-validating/README.adoc diff --git a/.machine_readable/svc/self-validating/examples/ci-config.k9.ncl b/.machine_readable/self-validating/examples/ci-config.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/examples/ci-config.k9.ncl rename to .machine_readable/self-validating/examples/ci-config.k9.ncl diff --git a/.machine_readable/svc/self-validating/examples/project-metadata.k9.ncl b/.machine_readable/self-validating/examples/project-metadata.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/examples/project-metadata.k9.ncl rename to .machine_readable/self-validating/examples/project-metadata.k9.ncl diff --git a/.machine_readable/svc/self-validating/examples/setup-repo.k9.ncl b/.machine_readable/self-validating/examples/setup-repo.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/examples/setup-repo.k9.ncl rename to .machine_readable/self-validating/examples/setup-repo.k9.ncl diff --git a/.machine_readable/svc/self-validating/methodology-guard.k9.ncl b/.machine_readable/self-validating/methodology-guard.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/methodology-guard.k9.ncl rename to .machine_readable/self-validating/methodology-guard.k9.ncl diff --git a/.machine_readable/svc/self-validating/template-hunt.k9.ncl b/.machine_readable/self-validating/template-hunt.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/template-hunt.k9.ncl rename to .machine_readable/self-validating/template-hunt.k9.ncl diff --git a/.machine_readable/svc/self-validating/template-kennel.k9.ncl b/.machine_readable/self-validating/template-kennel.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/template-kennel.k9.ncl rename to .machine_readable/self-validating/template-kennel.k9.ncl diff --git a/.machine_readable/svc/self-validating/template-yard.k9.ncl b/.machine_readable/self-validating/template-yard.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/template-yard.k9.ncl rename to .machine_readable/self-validating/template-yard.k9.ncl From 29ce9537bb7093e9e06b1cf23b191a4e57999fee Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:55:37 +0100 Subject: [PATCH 04/11] chore: rename agent_instructions to bot_directives for spec alignment --- .machine_readable/6a2/AGENTIC.a2ml | 12 ++++++------ .../README.adoc | 2 +- .../coverage.a2ml | 0 .../{agent_instructions => bot_directives}/debt.a2ml | 0 .../methodology.a2ml | 0 .../self-validating/methodology-guard.k9.ncl | 4 ++-- Justfile | 4 ++-- 7 files changed, 11 insertions(+), 11 deletions(-) rename .machine_readable/{agent_instructions => bot_directives}/README.adoc (94%) rename .machine_readable/{agent_instructions => bot_directives}/coverage.a2ml (100%) rename .machine_readable/{agent_instructions => bot_directives}/debt.a2ml (100%) rename .machine_readable/{agent_instructions => bot_directives}/methodology.a2ml (100%) diff --git a/.machine_readable/6a2/AGENTIC.a2ml b/.machine_readable/6a2/AGENTIC.a2ml index 589855e..b21d81b 100644 --- a/.machine_readable/6a2/AGENTIC.a2ml +++ b/.machine_readable/6a2/AGENTIC.a2ml @@ -34,18 +34,18 @@ release-claim-requires-hard-pass = true # METHODOLOGY (ADR-002) # ============================================================================ # Detailed methodology configuration lives in: -# .machine_readable/agent_instructions/methodology.a2ml -# .machine_readable/agent_instructions/coverage.a2ml -# .machine_readable/agent_instructions/debt.a2ml +# .machine_readable/bot_directives/methodology.a2ml +# .machine_readable/bot_directives/coverage.a2ml +# .machine_readable/bot_directives/debt.a2ml # # AGENTIC.a2ml declares WHAT agents can do (permissions, gating). -# agent_instructions/ declares HOW agents should work (methodology). +# bot_directives/ declares HOW agents should work (methodology). [methodology] -instructions-dir = ".machine_readable/agent_instructions/" +instructions-dir = ".machine_readable/bot_directives/" default-mode = "hybrid" [automation-hooks] -# on-enter: Read 0-AI-MANIFEST.a2ml, then STATE.a2ml, then agent_instructions/ +# on-enter: Read 0-AI-MANIFEST.a2ml, then STATE.a2ml, then bot_directives/ # on-exit: Update STATE.a2ml, coverage.a2ml, and debt.a2ml with session outcomes # on-commit: Run just validate-rsr diff --git a/.machine_readable/agent_instructions/README.adoc b/.machine_readable/bot_directives/README.adoc similarity index 94% rename from .machine_readable/agent_instructions/README.adoc rename to .machine_readable/bot_directives/README.adoc index e5fec01..a5315c7 100644 --- a/.machine_readable/agent_instructions/README.adoc +++ b/.machine_readable/bot_directives/README.adoc @@ -32,7 +32,7 @@ Methodology-aware configuration for AI agents. Read by any AI agent == Relationship to Other Files * `AGENTIC.a2ml` says WHAT agents can do (permissions, gating) -* `agent_instructions/` says HOW agents should work (methodology) +* `bot_directives/` says HOW agents should work (methodology) * `bot_directives/` says what the gitbot-fleet does (fleet-specific) * `CLAUDE.md` says how Claude specifically should work (Claude-specific) diff --git a/.machine_readable/agent_instructions/coverage.a2ml b/.machine_readable/bot_directives/coverage.a2ml similarity index 100% rename from .machine_readable/agent_instructions/coverage.a2ml rename to .machine_readable/bot_directives/coverage.a2ml diff --git a/.machine_readable/agent_instructions/debt.a2ml b/.machine_readable/bot_directives/debt.a2ml similarity index 100% rename from .machine_readable/agent_instructions/debt.a2ml rename to .machine_readable/bot_directives/debt.a2ml diff --git a/.machine_readable/agent_instructions/methodology.a2ml b/.machine_readable/bot_directives/methodology.a2ml similarity index 100% rename from .machine_readable/agent_instructions/methodology.a2ml rename to .machine_readable/bot_directives/methodology.a2ml diff --git a/.machine_readable/self-validating/methodology-guard.k9.ncl b/.machine_readable/self-validating/methodology-guard.k9.ncl index 96c2b88..1cf4fcb 100644 --- a/.machine_readable/self-validating/methodology-guard.k9.ncl +++ b/.machine_readable/self-validating/methodology-guard.k9.ncl @@ -3,7 +3,7 @@ # # K9 Validator: Methodology Guard # Checks that agent work respects methodology constraints declared in -# agent_instructions/methodology.a2ml. +# bot_directives/methodology.a2ml. # # Usage: k9 validate methodology-guard @@ -50,7 +50,7 @@ let methodology_guard = { coverage_updated = { description = "coverage.a2ml should be updated within 30 days", severity = "info", - file = ".machine_readable/agent_instructions/coverage.a2ml", + file = ".machine_readable/bot_directives/coverage.a2ml", staleness_days = 30, }, }, diff --git a/Justfile b/Justfile index dd18351..ad5ea90 100644 --- a/Justfile +++ b/Justfile @@ -503,8 +503,8 @@ self-assess: echo " ready for automated maintenance when the fleet arrives." fi - if [ -d ".machine_readable/agent_instructions" ]; then - echo " ◆ agent_instructions/ — AI agent methodology config." + 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 From f7c2dca8803f22a534495d957c562395c0eb8f4b Mon Sep 17 00:00:00 2001 From: Mistral Vibe Date: Sun, 7 Jun 2026 09:03:09 +0100 Subject: [PATCH 05/11] docs: Add CODEOWNERS, MAINTAINERS, and GOVERNANCE documents --- GOVERNANCE.adoc | 162 +++++++++++++++++++++++++++++++++++++++++++++++ MAINTAINERS.adoc | 65 +++++++++++++++++++ 2 files changed, 227 insertions(+) create mode 100644 GOVERNANCE.adoc create mode 100644 MAINTAINERS.adoc diff --git a/GOVERNANCE.adoc b/GOVERNANCE.adoc new file mode 100644 index 0000000..8bbf167 --- /dev/null +++ b/GOVERNANCE.adoc @@ -0,0 +1,162 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += Governance Model +:toc: preamble + +This document describes the governance model for this repository. + +== Overview + +This repository follows a **Sole Maintainer Governance Model**: + +* Single maintainer (@hyperpolymath) has full authority over the project +* All contributions are welcome and reviewed by the maintainer +* Decisions are made transparently through GitHub issues and discussions +* The project adheres to the hyperpolymath estate policies where applicable + +== Core Principles + +[cols="1,2"] +|=== +| Principle | Description + +| **Benevolent Dictatorship** | Maintainer has final decision authority but seeks community input + +| **Meritocracy** | Contributions are judged on technical merit, not contributor identity + +| **Transparency** | All significant decisions are documented publicly + +| **Consensus-Seeking** | Maintainer prefers consensus but will decide when necessary + +| **Open Contribution** | Anyone can contribute via fork and pull request + +|=== + +== Roles and Permissions + +[cols="1,2,2"] +|=== +| Role | Permissions | Assignment + +| **Maintainer** | Write access, merge rights, admin | @hyperpolymath +| **Contributors** | Read access, fork, submit PRs | All GitHub users +| **Users** | Use the software, report issues | All GitHub users + +|=== + +== Decision Making Framework + +=== Routine Decisions + +* Bug fixes +* Documentation improvements +* Minor feature additions +* Dependency updates + +**Process**: Maintainer reviews and merges PRs that meet quality standards. + +=== Significant Changes + +* New major features +* API changes +* Architecture modifications +* Breaking changes + +**Process**: +. Open issue describing the change +. Discuss with community (minimum 72 hours) +. Maintainer makes final decision +. Document rationale in issue/PR + +=== Structural Decisions + +* Repository purpose/renaming +* License changes +* Ownership transfer +* Deprecation/archival + +**Process**: +. Extended discussion (minimum 1 week) +. Maintainer makes final decision +. Document in CHANGELOG and governance docs + +== Contribution Lifecycle + +[cols="1,2"] +|=== +| Stage | Process + +| **Ideation** | Open issue, discuss feasibility + +| **Development** | Fork, implement, test thoroughly + +| **Review** | Submit PR, maintainer reviews within 7 days + +| **Merge** | Maintainer merges or requests changes + +| **Release** | Maintainer publishes according to project conventions + +|=== + +== Conflict Resolution + +In case of disagreements: + +. Discuss in the relevant GitHub issue or PR +. Provide technical justification for positions +. Maintainer mediates and makes final decision +. Decision is documented and can be revisited later + +== Project Policies + +This repository adheres to hyperpolymath estate-wide policies: + +* **License**: MPL-2.0 for code, CC-BY-SA-4.0 for prose (per standards/LICENCE-POLICY.adoc) +* **Code of Conduct**: Follows hyperpolymath CODE_OF_CONDUCT.md +* **Security**: Follows hyperpolymath SECURITY.md +* **Contributing**: Follows hyperpolymath CONTRIBUTING.adoc conventions + +== Repository-Specific Conventions + +[cols="1,2"] +|=== +| Convention | Description + +| **Signing** | All commits must be signed (SSH or GPG) + +| **SPDX Headers** | All source files must have SPDX license identifiers + +| **Contractiles** | Mustfile, Trustfile, Intendfile, Adjustfile in root + +| **Machine Readable** | META.a2ml in .machine_readable/6a2/ + +| **CI/CD** | GitHub Actions workflows in .github/workflows/ + +|=== + +== Governance Evolution + +As the project grows, this governance model may evolve: + +* **Adding Co-Maintainers**: When contribution volume warrants it +* **Forming a Team**: For complex multi-maintainer projects +* **Adopting TPCF**: For large, multi-repository projects (see rhodium-standard-repositories) + +Changes to this document require the same process as Significant Changes above. + +== See Also + +* link:MAINTAINERS.adoc[Maintainers] +* link:CODE_OF_CONDUCT.md[Code of Conduct] +* link:CONTRIBUTING.adoc[Contributing Guide] +* link:https://github.com/hyperpolymath/standards/blob/main/LICENCE-POLICY.adoc[Estate License Policy] +* link:https://github.com/hyperpolymath/standards[rhodium-standard-repositories (TPCF)] + +== Changelog + +[cols="1,1,1"] +|=== +| Date | Change | By + +| 2026-06-07 | Initial governance model established | @hyperpolymath +|=== diff --git a/MAINTAINERS.adoc b/MAINTAINERS.adoc new file mode 100644 index 0000000..9910dd8 --- /dev/null +++ b/MAINTAINERS.adoc @@ -0,0 +1,65 @@ +// SPDX-License-Identifier: MPL-2.0 +// SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell += Maintainers +:toc: preamble + +== Current Maintainers + +[cols="2,3,2",options="header"] +|=== +| Name | Role | Contact + +| Jonathan D.A. Jewell | Sole Maintainer | https://github.com/hyperpolymath[@hyperpolymath] +|=== + +== Maintainer Responsibilities + +As the sole maintainer, all responsibilities apply to @hyperpolymath: + +* Reviewing and merging pull requests +* Triaging issues and feature requests +* Ensuring code quality and security standards +* Managing releases and versioning +* Upholding the project's Code of Conduct +* Maintaining documentation and examples +* Responding to security vulnerabilities + +== Contribution Process + +This is a sole-maintainer project. All contributions are welcome via: + +1. **Issues**: Report bugs, request features, ask questions +2. **Pull Requests**: Submit improvements for review +3. **Discussions**: Engage in community discussions + +All contributions will be reviewed by the maintainer. + +== Decision Making + +* Routine decisions (bug fixes, minor improvements): Made by maintainer +* Significant changes: Discussed in issues before implementation +* Breaking changes: Announced in advance with migration path + +== Becoming a Maintainer + +This project currently has a single maintainer. If you're interested in becoming a co-maintainer: + +1. Demonstrate consistent, high-quality contributions +2. Show understanding of project goals and standards +3. Participate constructively in discussions +4. Express interest to the current maintainer + +Co-maintainers may be added at the discretion of the current maintainer. + +== Contact + +For questions about project governance: + +* Open a GitHub issue in this repository +* Contact: https://github.com/hyperpolymath + +== See Also + +* link:GOVERNANCE.adoc[Governance Model] +* link:CODE_OF_CONDUCT.md[Code of Conduct] +* link:CONTRIBUTING.adoc[Contributing Guide] From 5cc4c92a5348a7a5619d71fa6d5a30a34d4630be Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Sun, 7 Jun 2026 23:03:10 +0100 Subject: [PATCH 06/11] Apply estate standardization: governance docs, contractiles, CI/CD cleanup --- .machine_readable/ADJUST.contractile | 126 -- .machine_readable/INTENT.contractile | 72 - .machine_readable/MUST.contractile | 91 - .machine_readable/TRUST.contractile | 80 - .../contractiles/Adjustfile.a2ml | 72 + .../contractiles/Intentfile.a2ml | 99 ++ .machine_readable/contractiles/Justfile | 1548 +++++++++++++++++ .machine_readable/contractiles/Mustfile.a2ml | 102 ++ .machine_readable/contractiles/Trustfile.a2ml | 88 + .../contractiles/bust/Bustfile.a2ml | 28 - .machine_readable/contractiles/bust/bust.ncl | 66 - .../contractiles/dust/Dustfile.a2ml | 44 - .../contractiles/must/Mustfile.a2ml | 69 - .../contractiles/trust/Trustfile.a2ml | 74 - contractiles/intend/Intentfile.a2ml | 11 - contractiles/must/Mustfile.a2ml | 11 - contractiles/trust/Trustfile.a2ml | 11 - flake.nix | 170 -- 18 files changed, 1909 insertions(+), 853 deletions(-) delete mode 100644 .machine_readable/ADJUST.contractile delete mode 100644 .machine_readable/INTENT.contractile delete mode 100644 .machine_readable/MUST.contractile delete mode 100644 .machine_readable/TRUST.contractile create mode 100644 .machine_readable/contractiles/Adjustfile.a2ml create mode 100644 .machine_readable/contractiles/Intentfile.a2ml create mode 100644 .machine_readable/contractiles/Justfile create mode 100644 .machine_readable/contractiles/Mustfile.a2ml create mode 100644 .machine_readable/contractiles/Trustfile.a2ml delete mode 100644 .machine_readable/contractiles/bust/Bustfile.a2ml delete mode 100644 .machine_readable/contractiles/bust/bust.ncl delete mode 100644 .machine_readable/contractiles/dust/Dustfile.a2ml delete mode 100644 .machine_readable/contractiles/must/Mustfile.a2ml delete mode 100644 .machine_readable/contractiles/trust/Trustfile.a2ml delete mode 100644 contractiles/intend/Intentfile.a2ml delete mode 100644 contractiles/must/Mustfile.a2ml delete mode 100644 contractiles/trust/Trustfile.a2ml delete mode 100644 flake.nix diff --git a/.machine_readable/ADJUST.contractile b/.machine_readable/ADJUST.contractile deleted file mode 100644 index d9c798f..0000000 --- a/.machine_readable/ADJUST.contractile +++ /dev/null @@ -1,126 +0,0 @@ -; SPDX-License-Identifier: MPL-2.0 -; ADJUST.contractile — Accessibility invariants for rsr-template-repo -; "ADJUST" = Accessibility & Digital Justice for Universal Software & Technology -; -; Part of the contractile family: MUST, TRUST, DUST, INTENT, ADJUST -; This file is machine-readable. LLM/SLM agents MUST NOT violate these invariants. - -; ── Definitions ────────────────────────────────────────────────── -; -; ADJUST (noun/verb) -; The accessibility contractile. Defines how software must adapt to serve -; all users regardless of ability, device, or context. Named for the verb -; "adjust" — to make suitable, to adapt, to accommodate — which is the -; core action of accessible design. -; -; Scope: -; ADJUST governs all user-facing interfaces: GUI, TUI, CLI, web, mobile, -; documentation, error messages, and installation flows. It applies to -; both human users and assistive technologies (screen readers, switch -; devices, braille displays, voice control). -; -; Relationship to other contractiles: -; - MUST: ADJUST invariants are a subset of MUST — violating ADJUST -; is a MUST violation. ADJUST exists separately because accessibility -; rules are numerous enough to warrant their own file, and because -; LLMs frequently forget accessibility unless explicitly reminded. -; - TRUST: ADJUST does not affect trust levels. All trust tiers must -; respect ADJUST invariants equally. -; - DUST: Deprecating a feature does not exempt it from ADJUST until -; it is fully removed. Deprecated UI must remain accessible. -; - INTENT: ADJUST supports the anti-purpose "this software is NOT -; only for able-bodied users with modern hardware." -; -; Standard: WCAG 2.2 Level AA (minimum) -; https://www.w3.org/WAI/WCAG22/quickref/?levels=aaa -; -; Why a separate file: -; Experience shows LLMs and developers alike treat accessibility as an -; afterthought. By placing invariants in a contractile that is loaded -; at session start, we make it structurally impossible to forget. -; -; ── End Definitions ────────────────────────────────────────────── - -(adjust-contractile - (version "1.0.0") - (full-name "Accessibility & Digital Justice for Universal Software & Technology") - (standard "WCAG-2.2-AA") - (repo "rsr-template-repo") - - (invariants - ; ── Visual ── - (adjust "colour-contrast-ratio >= 4.5:1 for normal text") - (adjust "colour-contrast-ratio >= 3:1 for large text (18pt+ or 14pt+ bold)") - (adjust "no information conveyed by colour alone") - (adjust "no flashing or strobing content (3 flashes/second max)") - (adjust "text resizable to 200% without loss of content or function") - (adjust "focus indicators visible on all interactive elements") - - ; ── Keyboard ── - (adjust "all interactive elements reachable via keyboard (Tab/Shift+Tab)") - (adjust "no keyboard traps — user can always Tab away") - (adjust "skip navigation link present on pages with repeated blocks") - (adjust "logical focus order follows visual reading order") - - ; ── Screen reader ── - (adjust "all images have meaningful alt text (or alt='' if decorative)") - (adjust "all form inputs have associated labels") - (adjust "ARIA landmarks used for page regions (main, nav, banner, etc.)") - (adjust "dynamic content updates announced via aria-live regions") - (adjust "semantic HTML used (headings, lists, tables) — not div soup") - - ; ── Interactive ── - (adjust "touch targets minimum 44x44px on mobile/touch interfaces") - (adjust "error messages identify the field and describe the error") - (adjust "error messages not conveyed by colour or position alone") - (adjust "form validation provides suggestions for correction") - - ; ── Media ── - (adjust "video has captions (closed or open)") - (adjust "audio-only content has text transcript") - (adjust "no autoplay of media with sound") - - ; ── Motion ── - (adjust "animations respect prefers-reduced-motion media query") - (adjust "no content depends on motion to convey meaning") - - ; ── CLI/TUI ── - (adjust "CLI output must not rely solely on colour (use symbols: [OK] [FAIL])") - (adjust "TUI must support high-contrast mode") - (adjust "all CLI commands support --help with plain-text output") - (adjust "error messages written in plain language, not jargon or codes alone") - - ; ── Documentation ── - (adjust "docs use clear language, short sentences, logical structure") - (adjust "code examples include comments explaining non-obvious steps") - (adjust "diagrams have text descriptions or alt text") - - ; ── Internationalisation (i18n) ── - (adjust "all user-facing strings externalisable for translation") - (adjust "no hardcoded English in error messages — use message keys") - (adjust "date/time/number formats locale-aware") - (adjust "RTL (right-to-left) layout support where applicable") - (adjust "Unicode handled correctly throughout (UTF-8 everywhere)") - ) - - (related-resources - ; LOL — super-parallel corpus crawler for 1500+ languages - ; Use for linguistic data, translation coverage, and i18n validation - (lol "standards/lol — multilingual NLP corpus, see README.adoc") - (polyglot-i18n "polyglot-i18n — i18n framework and WASM translation engine") - ) - - (enforcement - (ci "accessibility linting in quality.yml workflow") - (pr-block "PR blocked if accessibility regression detected") - (tool "axe-core or pa11y for automated checks on web UI") - (tool "CLI output inspected for colour-only signalling") - (manual "manual screen reader test before major releases") - ) - - (notes - "These are MINIMUM requirements. Exceeding them (AAA) is encouraged." - "When in doubt about an accessibility decision, ask — don't guess." - "Accessibility is not optional polish — it is a structural requirement." - ) -) diff --git a/.machine_readable/INTENT.contractile b/.machine_readable/INTENT.contractile deleted file mode 100644 index c899f0e..0000000 --- a/.machine_readable/INTENT.contractile +++ /dev/null @@ -1,72 +0,0 @@ -; SPDX-License-Identifier: MPL-2.0 -; INTENT.contractile — Purpose and scope for rsr-template-repo -; Helps LLM/SLM agents understand what this repo IS and IS NOT. -; -; Part of the contractile family: MUST, TRUST, DUST, INTENT, ADJUST - -; ── Definitions ────────────────────────────────────────────────── -; -; INTENT (noun) -; The purpose contractile. Defines what this repository IS, what it is -; NOT (anti-purpose), and which architectural decisions are load-bearing. -; Without INTENT, LLMs drift into scope creep, reverse key decisions, -; or add features that belong in a different repo. -; -; Scope: -; INTENT governs the conceptual boundaries of the project — its reason -; for existing, its domain, and its relationship to the ecosystem. -; It does NOT specify implementation details (that's MUST and code). -; -; Relationship to other contractiles: -; - MUST: INTENT explains WHY certain MUSTs exist. If you don't -; understand a MUST, read INTENT first. -; - TRUST: The "ask-before-touching" section in INTENT maps directly -; to TRUST.trust-deny for the most sensitive areas. -; - ADJUST: INTENT's anti-purpose should include "this software is -; NOT only for users with perfect vision/hearing/mobility." -; - DUST: When INTENT changes (repo pivots), related DUST entries -; should be created for the abandoned direction. -; -; ── End Definitions ────────────────────────────────────────────── - -(intent-contractile - (version "1.0.0") - (repo "rsr-template-repo") - - ; === Purpose (what this repo IS) === - (purpose - "{{ONE_PARAGRAPH_PURPOSE}}" - ) - - ; === Anti-Purpose (what this repo is NOT — prevents scope creep) === - (anti-purpose - "{{ONE_PARAGRAPH_ANTI_PURPOSE}}" - ; Examples: - ; "This is NOT a general-purpose database — it solves one specific problem." - ; "This is NOT a framework — it is a library with a focused API." - ; "This does NOT handle authentication — that is delegated to [other repo]." - ) - - ; === Key Architectural Decisions That Must Not Be Reversed === - (architectural-invariants - ; *REMINDER: List the foundational decisions* - ; ("Idris2 for ABI definitions — dependent types prove interface correctness") - ; ("Zig for FFI — zero-cost C ABI compatibility") - ; ("Elixir for supervision — OTP fault tolerance") - ) - - ; === Sensitive Areas (if in doubt, ask) === - (ask-before-touching - ; *REMINDER: List areas where LLMs should check before modifying* - ; "src/abi/ — formal proofs, changes require re-verification" - ; "ffi/zig/ — C ABI boundary, changes affect all language bindings" - ; ".machine_readable/ — checkpoint files, format is specified" - ) - - ; === Ecosystem Position === - (ecosystem - (belongs-to "{{MONOREPO_OR_STANDALONE}}") - (depends-on ("{{DEP1}}" "{{DEP2}}")) - (depended-on-by ("{{CONSUMER1}}" "{{CONSUMER2}}")) - ) -) diff --git a/.machine_readable/MUST.contractile b/.machine_readable/MUST.contractile deleted file mode 100644 index 48ffff1..0000000 --- a/.machine_readable/MUST.contractile +++ /dev/null @@ -1,91 +0,0 @@ -; SPDX-License-Identifier: MPL-2.0 -; MUST.contractile — Baseline invariants for rsr-template-repo -; These constraints MUST NOT be violated. K9 validators enforce them. -; -; Part of the contractile family: MUST, TRUST, DUST, INTENT, ADJUST - -; ── Definitions ────────────────────────────────────────────────── -; -; MUST (noun/verb) -; The hard-constraint contractile. Defines invariants that are structurally -; required for the repository to function correctly and safely. Violating -; a MUST is always a bug — there are no "soft" MUSTs. -; -; Scope: -; MUST governs code, configuration, CI, and structure. It does NOT govern -; style, preference, or approach — those belong in CLAUDE.md or coding -; standards. MUST is for things that break the project if violated. -; -; Relationship to other contractiles: -; - TRUST: MUST is enforced regardless of trust level. Even maximal-trust -; agents cannot violate MUST constraints. -; - ADJUST: All ADJUST invariants are implicitly MUST invariants too. -; ADJUST exists separately for visibility. -; - INTENT: MUST protects the architectural decisions described in INTENT. -; - DUST: When a feature enters DUST (deprecation), its MUST constraints -; remain active until the feature is fully removed. -; -; Enforcement: -; K9 validators in contractiles/self-validating/ machine-check MUST constraints. -; CI runs these on every PR. Violations block merge. -; -; ── End Definitions ────────────────────────────────────────────── - -(must-contractile - (version "1.0.0") - (repo "rsr-template-repo") - - ; === Universal Invariants (apply to ALL repos) === - - (invariants - ; Paths - (must "no hardcoded absolute paths (/home/*, /mnt/*, /var/mnt/*)") - (must "all paths use env vars, XDG dirs, or relative references") - - ; Language policy - (must "no new TypeScript files") - (must "no new Python files") - (must "no new Go files") - (must "no npm/bun/yarn/pnpm dependencies — Deno only") - - ; Dangerous patterns - (must "no believe_me (Idris2)") - (must "no assert_total (Idris2)") - (must "no Admitted (Coq)") - (must "no sorry (Lean)") - (must "no unsafeCoerce (Haskell)") - (must "no Obj.magic (OCaml)") - (must "no unsafe {} blocks without safety comment (Rust)") - - ; License - (must "SPDX-License-Identifier header on every source file") - (must "no removal or modification of LICENSE file") - - ; Structure - (must ".machine_readable/ directory preserved") - (must "0-AI-MANIFEST.a2ml preserved") - (must "no SCM files in repo root — only in .machine_readable/") - - ; CI - (must "no removal of CI workflows without explicit approval") - (must "all GitHub Actions SHA-pinned") - - ; Code quality - (must "tests must not be deleted or weakened") - (must "generated code in generated/ directory only") - (must "no introduction of OWASP top 10 vulnerabilities") - - ; ABI/FFI (if applicable) - (must "no modification of ABI contracts without proof update") - (must "no removal of formal verification proofs") - ) - - ; === Project-Specific Invariants === - ; *REMINDER: Add invariants specific to this repo* - ; (must "# Add project-specific invariants here") - - (enforcement - (k9-validator "contractiles/self-validating/must-check.k9.ncl") - (ci "quality.yml runs must-check on every PR") - ) -) diff --git a/.machine_readable/TRUST.contractile b/.machine_readable/TRUST.contractile deleted file mode 100644 index 52fd1f0..0000000 --- a/.machine_readable/TRUST.contractile +++ /dev/null @@ -1,80 +0,0 @@ -; SPDX-License-Identifier: MPL-2.0 -; TRUST.contractile — Trust boundaries for rsr-template-repo -; Defines what LLM/SLM agents are trusted to do without asking. -; -; Part of the contractile family: MUST, TRUST, DUST, INTENT, ADJUST - -; ── Definitions ────────────────────────────────────────────────── -; -; TRUST (noun/verb) -; The permission contractile. Defines the boundary between what an AI -; agent may do autonomously and what requires human approval. Trust is -; graduated — not binary — with four levels from minimal to maximal. -; -; Trust levels: -; - maximal: Agent may read, build, test, lint, format, heal freely. -; Only destructive/external actions require approval. -; - standard: Agent may read and build. Test/lint need approval. -; - restricted: Agent may read only. All modifications need approval. -; - minimal: Agent may read specific files only. Everything else blocked. -; -; Scope: -; TRUST governs AI agent behaviour only. It does not affect human -; contributors — humans follow CONTRIBUTING.md and GOVERNANCE.adoc. -; -; Relationship to other contractiles: -; - MUST: Trust never overrides MUST. Even at maximal trust, MUST -; violations are blocked. -; - ADJUST: Trust does not exempt from ADJUST. All trust tiers must -; produce accessible output. -; - INTENT: TRUST.trust-deny protects the sensitive areas listed in -; INTENT.ask-before-touching. -; - DUST: Deprecated features have the same trust rules as active ones. -; -; ── End Definitions ────────────────────────────────────────────── - -(trust-contractile - (version "1.0.0") - (repo "rsr-template-repo") - - (trust-level "maximal") ; maximal | standard | restricted | minimal - - ; === Maximal Trust (default) === - ; LLM may freely do these without asking: - (trust-actions - "read" ; Read any file in the repo - "build" ; Run build commands - "test" ; Run test suites - "lint" ; Run linters and formatters - "format" ; Auto-format code - "doctor" ; Run self-diagnostics - "heal" ; Attempt automatic repair - "git-status" ; Check git status - "git-diff" ; View diffs - "git-log" ; View history - ) - - ; === Denied Actions (always require human approval) === - (trust-deny - "delete-branch" ; Could lose work - "force-push" ; Overwrites history - "modify-ci-secrets" ; Security sensitive - "publish" ; External visibility - "push-to-main" ; Protected branch - "delete-files-bulk" ; More than 5 files at once - "modify-license" ; Legal implications - "modify-security-policy" ; Security implications - "remove-proofs" ; Formal verification regression - "disable-ci-checks" ; Safety regression - ) - - ; === Trust Boundary === - (trust-boundary "repo") ; LLM confined to this repo unless explicitly told otherwise - - ; === Override === - ; Repos requiring tighter trust override these settings with justification: - ; (override - ; (trust-level "restricted") - ; (reason "Contains production secrets / handles PII / etc.") - ; ) -) diff --git a/.machine_readable/contractiles/Adjustfile.a2ml b/.machine_readable/contractiles/Adjustfile.a2ml new file mode 100644 index 0000000..6f01e89 --- /dev/null +++ b/.machine_readable/contractiles/Adjustfile.a2ml @@ -0,0 +1,72 @@ +# SPDX-License-Identifier: MPL-2.0 +# Adjustfile — Drift-tolerance contract for rsr-template-repo +# Author: Jonathan D.A. Jewell +# +# Cumulative-drift catchment: tolerance bands + corrective actions. +# Authority: advisory (Yard) — continue-with-warnings; auto_fix where deterministic. +# Run with: adjust check +# Fix with: adjust fix (applies deterministic patches; advisory otherwise) + +@abstract: +Drift tolerances and corrective actions for rsr-template-repo. Unlike +MUST (hard gate), ADJUST tracks cumulative drift against tolerance bands +and proposes corrective actions. Advisory — it warns and trends, it does +not block. +@end + +## Template Drift + +### placeholder-drift +- description: Template placeholders should be replaced when copied +- tolerance: 0 placeholder markers in copied repos +- corrective: Search and replace all {{PLACEHOLDER}} markers +- severity: advisory +- notes: This check only applies to repos that copied from this template + +### template-version-drift +- description: Template version should match RSR spec version +- tolerance: Template version matches current RSR spec +- corrective: Update template to match latest RSR spec +- severity: advisory + +## Documentation Drift + +### readme-completeness +- description: README should document all template features +- tolerance: README covers all contractiles and directory structure +- corrective: Update README.adoc with missing sections +- severity: advisory + +### example-accuracy +- description: Examples in documentation should match actual template content +- tolerance: All code examples in docs are accurate +- corrective: Audit and fix examples in documentation +- severity: advisory + +## Structural Drift + +### contractile-sync +- description: All contractiles should have matching a2ml and ncl implementations +- tolerance: Every .a2ml has a corresponding .ncl +- corrective: Generate missing .ncl files from .a2ml +- severity: advisory + +### no-broken-symlinks +- description: No broken symbolic links in template structure +- tolerance: 0 broken symlinks +- corrective: Run symlink-check script +- severity: advisory + +## Accessibility Drift + +### adoc-not-md +- description: Template docs should prefer AsciiDoc +- tolerance: New prose docs are *.adoc +- corrective: Convert any new *.md to *.adoc +- severity: advisory + +### spdx-header-consistency +- description: All template files have correct SPDX headers +- tolerance: 0 files missing SPDX-License-Identifier +- corrective: Add SPDX headers to files that need them +- severity: advisory diff --git a/.machine_readable/contractiles/Intentfile.a2ml b/.machine_readable/contractiles/Intentfile.a2ml new file mode 100644 index 0000000..ef74f45 --- /dev/null +++ b/.machine_readable/contractiles/Intentfile.a2ml @@ -0,0 +1,99 @@ +# SPDX-License-Identifier: MPL-2.0 +# Intentfile (A2ML Canonical) — north-star contractile for rsr-template-repo +# Author: Jonathan D.A. Jewell +# +# Paired runner: intend.ncl +# Verb: intend +# +# Semantics: North-star contractile. Declares BOTH concrete committed +# next-actions AND horizon aspirations the project wishes to +# become. Two sections share one file because they answer +# the same question at different ranges: +# [[intents]] — "we WILL do this; track progress" +# status: declared → in_progress → done | +# deferred | retired +# [[wishes]] — "we WISH this were true; revisit later" +# status: declared → in_progress → achieved | +# abandoned +# grouped by horizon: near / mid / far. +# Non-gating — this is a report, not a gate. See the `must` +# contractile for hard gates. + +@abstract: +North-star contractile for rsr-template-repo. This repository is the +canonical template for Rhodium Standard Repository compliance. It provides +the scaffold that all hyperpolymath repos should copy and customize. +@end + +## Purpose + +The rsr-template-repo serves as the master template for all hyperpolymath +repositories. It contains the complete set of contractile files, machine-readable +specifications, and governance documentation that define the Rhodium Standard. + +Every new repository in the hyperpolymath estate should be initialized by +copying this template and substituting the placeholder values with +repo-specific content. + +## Anti-Purpose + +This repository is NOT: +- A general-purpose project scaffold for external use (hyperpolymath-only) +- A replacement for per-repo customization (all files must be bespoke) +- A static template that never changes (evolves with RSR spec) +- A runtime library or framework (build-time only) + +## If In Doubt + +If you are unsure whether a change is in scope, ask. Sensitive areas: +- .machine_readable/ contractile definitions +- RSR specification files +- Governance templates +- License policy documents + +## Committed Next-Actions + +### repo-initialization +- description: Provide just copy-and-substitute template for new repos +- probe: test -f scripts/init-repo.sh +- status: done +- notes: Run with source scripts/init-repo.sh + +### contractile-completeness +- description: Every RSR contractile has an a2ml and ncl implementation +- probe: ls .machine_readable/contractiles/*.a2ml | wc -l | grep -q "^6$" +- status: in_progress +- notes: Currently 6 contractile verbs: intend, must, trust, adjust, bust, dust + +### automation-scripts +- description: All repetitive tasks have just recipes +- probe: grep -c "^# " Justfile | grep -q "^[6-9][0-9]*$" +- status: in_progress + +## Wishes + +### Near Horizon + +#### cross-repo-validation +- description: Tooling to validate all repos against RSR spec +- horizon: near +- status: declared + +#### automated-substitution +- description: Script to automate repo-specific substitution in template +- horizon: near +- status: declared + +### Mid Horizon + +#### formal-verification +- description: Idris2 proofs for all critical contractile invariants +- horizon: mid +- status: declared + +### Far Horizon + +#### ecosystem-visualization +- description: Interactive graph of all hyperpolymath repos and dependencies +- horizon: far +- status: declared diff --git a/.machine_readable/contractiles/Justfile b/.machine_readable/contractiles/Justfile new file mode 100644 index 0000000..ad5ea90 --- /dev/null +++ b/.machine_readable/contractiles/Justfile @@ -0,0 +1,1548 @@ +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# RSR Standard Justfile Template +# https://just.systems/man/en/ +# +# Copy this file to new projects and customize the placeholder values. +# +# Run `just` to see all available recipes +# Run `just cookbook` to generate docs/just-cookbook.adoc +# Run `just combinations` to see matrix recipe options + +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? "contractile.just" + +# Project metadata — customize these +project := "fraying-model-computational-testbed" +OWNER := "hyperpolymath" +REPO := "fraying-model-computational-testbed" +version := "0.1.0" +tier := "infrastructure" # 1 | 2 | infrastructure + +# ═══════════════════════════════════════════════════════════════════════════════ +# DEFAULT & HELP +# ═══════════════════════════════════════════════════════════════════════════════ + +# Show all available recipes with descriptions +default: + @just --list --unsorted + +# Show detailed help for a specific recipe +help recipe="": + #!/usr/bin/env bash + if [ -z "{{recipe}}" ]; then + just --list --unsorted + echo "" + echo "Usage: just help " + echo " just cookbook # Generate full documentation" + echo " just combinations # Show matrix recipes" + else + just --show "{{recipe}}" 2>/dev/null || echo "Recipe '{{recipe}}' not found" + fi + +# Show this project's info +info: + @echo "Project: {{project}}" + @echo "Version: {{version}}" + @echo "RSR Tier: {{tier}}" + @echo "Recipes: $(just --summary | wc -w)" + @[ -f ".machine_readable/STATE.a2ml" ] && grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/STATE.a2ml | head -1 | xargs -I{} echo "Phase: {}" || true + +# Run Invariant Path overlay tools for this repository +invariant-path *ARGS: + ./scripts/invariant-path.sh {{ARGS}} + +# ═══════════════════════════════════════════════════════════════════════════════ +# INIT — Bootstrap a new project from this template +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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" + +# ═══════════════════════════════════════════════════════════════════════════════ +# GROOVE & V-TRIPLE SETUP +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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 'fraying-model-computational-testbed' Justfile 2>/dev/null; then + echo "⚠ Justfile still references 'fraying-model-computational-testbed' — 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 + +# ═══════════════════════════════════════════════════════════════════════════════ +# PROJECT SELF-ASSESSMENT +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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|abi/ — KEEP (Idris2 ABI definitions)" + elif ! $HAS_IDRIS && { [ -d "src/interface/Abi" ] || [ -d "src/interface/abi" ]; }; then + echo " ? src/interface/Abi|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." + 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 "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 "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 "═══════════════════════════════════════════════════" + +# ═══════════════════════════════════════════════════════════════════════════════ +# OPENSSF COMPLIANCE VERIFICATION +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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/STATE.a2ml" + check_file ".machine_readable/META.a2ml" + check_file ".machine_readable/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." + +# ═══════════════════════════════════════════════════════════════════════════════ +# BUILD & COMPILE +# ═══════════════════════════════════════════════════════════════════════════════ + +# Build the project (debug mode) +build *args: + @echo "Building {{project}} (debug)..." + # TODO: Replace with your build command + # Examples: + # cargo build {{args}} # Rust + # mix compile {{args}} # Elixir + # zig build {{args}} # Zig + # deno task build {{args}} # Deno/ReScript + @echo "Build complete" + +# Build in release mode with optimizations +build-release *args: + @echo "Building {{project}} (release)..." + # TODO: Replace with your release build command + # Examples: + # cargo build --release {{args}} + # MIX_ENV=prod mix compile {{args}} + # zig build -Doptimize=ReleaseFast {{args}} + @echo "Release build complete" + +# Build and watch for changes (requires entr or similar) +build-watch: + @echo "Watching for changes..." + # TODO: Customize file patterns for your language + # Examples: + # find src -name '*.rs' | entr -c just build + # mix compile --force --warnings-as-errors + # deno task dev + +# Clean build artifacts [reversible: rebuild with `just build`] +clean: + @echo "Cleaning..." + # TODO: Customize for your build system + rm -rf target/ _build/ build/ dist/ out/ obj/ bin/ + +# Deep clean including caches [reversible: rebuild] +clean-all: clean + rm -rf .cache .tmp + +# ═══════════════════════════════════════════════════════════════════════════════ +# TEST & QUALITY +# ═══════════════════════════════════════════════════════════════════════════════ + +# Run all tests +test *args: + @echo "Running tests..." + # TODO: Replace with your test command + # Examples: + # cargo test {{args}} + # mix test {{args}} + # zig build test {{args}} + # deno test {{args}} + @echo "Tests passed!" + +# Run tests with verbose output +test-verbose: + @echo "Running tests (verbose)..." + # TODO: Replace with verbose test command + +# Smoke test +test-smoke: + @echo "Smoke test..." + # TODO: Add basic sanity checks + +# Run end-to-end tests (full pipeline: build → run → verify) +e2e: + @echo "Running E2E tests..." + # TODO: Replace with your E2E test command. Examples: + # bash tests/e2e.sh # Shell-based E2E + # npx playwright test # Browser E2E + # mix test test/integration/e2e_test.exs # Elixir E2E + # cargo test --test end_to_end # Rust E2E + @echo "E2E tests passed!" + +# Run aspect tests (cross-cutting concern validation) +aspect: + @echo "Running aspect tests..." + # TODO: Replace with your aspect test command. Examples: + # bash tests/aspect_tests.sh # Shell-based aspect tests + # cargo test --test aspects # Rust aspect tests + # Aspect tests validate architectural invariants: + # - Thread safety (mutex in FFI modules) + # - ABI/FFI contract (declarations match exports) + # - SPDX compliance (all files have license headers) + # - No dangerous patterns (believe_me, assert_total, etc.) + @echo "Aspect tests passed!" + +# Run benchmarks (performance regression detection) +bench: + @echo "Running benchmarks..." + # TODO: Replace with your benchmark command. Examples: + # cargo bench # Rust criterion + # zig build bench # Zig benchmarks + # mix run bench/benchmarks.exs # Elixir benchee + # deno bench # Deno bench + @echo "Benchmarks complete!" + +# Run readiness tests (Component Readiness Grade: D/C/B) +readiness: + @echo "Running readiness tests..." + # TODO: Replace with your readiness test command. Examples: + # cargo test --test readiness -- --nocapture + @echo "Readiness tests complete!" + +# Print the current CRG grade (reads from READINESS.md '**Current Grade:** X' line) +crg-grade: + @grade=$$(grep -oP '(?<=\*\*Current Grade:\*\* )[A-FX]' READINESS.md 2>/dev/null | head -1); \ + [ -z "$$grade" ] && grade="X"; \ + echo "$$grade" + +# Print a shields.io CRG badge for embedding in README files +# Looks for '**Current Grade:** X' in READINESS.md; falls back to X +crg-badge: + @grade=$$(grep -oP '(?<=\*\*Current Grade:\*\* )[A-FX]' READINESS.md 2>/dev/null | head -1); \ + [ -z "$$grade" ] && grade="X"; \ + case "$$grade" in \ + A) color="brightgreen" ;; \ + B) color="green" ;; \ + C) color="yellow" ;; \ + D) color="orange" ;; \ + E) color="red" ;; \ + F) color="critical" ;; \ + *) color="lightgrey" ;; \ + esac; \ + echo "[![CRG $$grade](https://img.shields.io/badge/CRG-$$grade-$$color?style=flat-square)](https://github.com/hyperpolymath/standards/tree/main/component-readiness-grades)" + +# Run the full merge-requirement test suite (ALL categories) +# Per STANDING rule: P2P + E2E + aspect + execution + lifecycle + bench +test-all: test e2e aspect bench readiness + @echo "All test categories passed — safe to merge!" + +# Run all quality checks +quality: fmt-check lint test + @echo "All quality checks passed!" + +# Fix all auto-fixable issues [reversible: git checkout] +fix: fmt + @echo "Fixed all auto-fixable issues" + +# ═══════════════════════════════════════════════════════════════════════════════ +# LINT & FORMAT +# ═══════════════════════════════════════════════════════════════════════════════ + +# Format all source files [reversible: git checkout] +fmt: + @echo "Formatting source files..." + # TODO: Replace with your formatter + # Examples: + # cargo fmt + # mix format + # gleam format + # deno fmt + +# Check formatting without changes +fmt-check: + @echo "Checking formatting..." + # TODO: Replace with your format check + # Examples: + # cargo fmt --check + # mix format --check-formatted + # gleam format --check + +# Run linter +lint: + @echo "Linting source files..." + # TODO: Replace with your linter + # Examples: + # cargo clippy -- -D warnings + # mix credo --strict + # gleam check + +# ═══════════════════════════════════════════════════════════════════════════════ +# RUN & EXECUTE +# ═══════════════════════════════════════════════════════════════════════════════ + +# Run the application +run *args: build + # TODO: Replace with your run command + echo "Run not configured yet" + +# Run with verbose output +run-verbose *args: build + # TODO: Replace with verbose run command + echo "Run not configured yet" + +# Install to user path +install: build-release + @echo "Installing {{project}}..." + # TODO: Replace with your install command + +# ═══════════════════════════════════════════════════════════════════════════════ +# DEPENDENCIES +# ═══════════════════════════════════════════════════════════════════════════════ + +# Install/check all dependencies +deps: + @echo "Checking dependencies..." + # TODO: Replace with your dependency check + # Examples: + # cargo check + # mix deps.get + # gleam deps download + @echo "All dependencies satisfied" + +# Audit dependencies for vulnerabilities +deps-audit: + @echo "Auditing for vulnerabilities..." + # TODO: Replace with your audit command + # Examples: + # cargo audit + # mix audit + @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL --quiet . || true + @command -v gitleaks >/dev/null && gitleaks detect --source . --no-git --quiet || true + @echo "Audit complete" + +# ═══════════════════════════════════════════════════════════════════════════════ +# DOCUMENTATION +# ═══════════════════════════════════════════════════════════════════════════════ + +# Generate all documentation +docs: + @mkdir -p docs/generated docs/man + just cookbook + just man + @echo "Documentation generated in docs/" + +# Generate justfile cookbook documentation +cookbook: + #!/usr/bin/env bash + mkdir -p docs + OUTPUT="docs/just-cookbook.adoc" + echo "= {{project}} Justfile Cookbook" > "$OUTPUT" + echo ":toc: left" >> "$OUTPUT" + echo ":toclevels: 3" >> "$OUTPUT" + echo "" >> "$OUTPUT" + echo "Generated: $(date -Iseconds)" >> "$OUTPUT" + echo "" >> "$OUTPUT" + echo "== Recipes" >> "$OUTPUT" + echo "" >> "$OUTPUT" + just --list --unsorted | while read -r line; do + if [[ "$line" =~ ^[[:space:]]+([a-z_-]+) ]]; then + recipe="${BASH_REMATCH[1]}" + echo "=== $recipe" >> "$OUTPUT" + echo "" >> "$OUTPUT" + echo "[source,bash]" >> "$OUTPUT" + echo "----" >> "$OUTPUT" + echo "just $recipe" >> "$OUTPUT" + echo "----" >> "$OUTPUT" + echo "" >> "$OUTPUT" + fi + done + echo "Generated: $OUTPUT" + +# Generate man page +man: + #!/usr/bin/env bash + mkdir -p docs/man + cat > docs/man/{{project}}.1 << EOF + .TH {{project}} 1 "$(date +%Y-%m-%d)" "{{version}}" "{{project}} Manual" + .SH NAME + {{project}} \- RSR-compliant project + .SH SYNOPSIS + .B just + [recipe] [args...] + .SH DESCRIPTION + RSR (Rhodium Standard Repository) project managed with just. + .SH AUTHOR + $(git config user.name 2>/dev/null || echo "Author") <$(git config user.email 2>/dev/null || echo "email")> + EOF + echo "Generated: docs/man/{{project}}.1" + +# ═══════════════════════════════════════════════════════════════════════════════ +# CONTAINERS (stapeln ecosystem — Podman + Chainguard Wolfi) +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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 fraying-model-computational-testbed." + 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" + ) + + 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" + echo " 2. Edit container/entrypoint.sh — set your application binary" + echo " 3. Review container/compose.toml — adjust services and volumes" + echo " 4. Build: just container-build" + +# Build container image via cerro-torre pipeline +container-build *args: + #!/usr/bin/env bash + if [ -f "container/ct-build.sh" ]; then + cd container && ./ct-build.sh {{args}} + elif [ -f "container/Containerfile" ]; then + podman build -t {{project}}:latest -f container/Containerfile . + elif [ -f "Containerfile" ]; then + podman build -t {{project}}:latest -f Containerfile . + else + echo "No Containerfile found in container/ or project root" + exit 1 + fi + +# Verify compose configuration +container-verify: + #!/usr/bin/env bash + if [ ! -f "container/compose.toml" ]; then + echo "No container/compose.toml found" + exit 1 + fi + cd container + if command -v selur-compose &>/dev/null; then + selur-compose verify + else + echo "selur-compose not found, falling back to podman compose" + podman compose --file compose.toml config + fi + +# Start container stack +container-up *args: + #!/usr/bin/env bash + if [ ! -f "container/compose.toml" ]; then + echo "No container/compose.toml found" + exit 1 + fi + cd container + if command -v selur-compose &>/dev/null; then + selur-compose up {{args}} + else + podman compose --file compose.toml up {{args}} + fi + +# Stop container stack +container-down: + #!/usr/bin/env bash + cd container 2>/dev/null || { echo "No container/ directory"; exit 1; } + if command -v selur-compose &>/dev/null; then + selur-compose down + else + podman compose --file compose.toml down + fi + +# Sign and verify container bundle (build + pack + sign + verify) +container-sign: + #!/usr/bin/env bash + if [ -f "container/ct-build.sh" ]; then + cd container && ./ct-build.sh + else + echo "No container/ct-build.sh found" + exit 1 + fi + +# Push signed bundle to registry +container-push: + #!/usr/bin/env bash + if [ -f "container/ct-build.sh" ]; then + cd container && ./ct-build.sh --push + else + echo "No container/ct-build.sh found — falling back to podman push" + podman push {{project}}:latest + fi + +# Run container interactively (for debugging) +container-run *args: + podman run --rm -it {{project}}:latest {{args}} + +# ═══════════════════════════════════════════════════════════════════════════════ +# CI & AUTOMATION +# ═══════════════════════════════════════════════════════════════════════════════ + +# Run full CI pipeline locally +ci: deps quality + @echo "CI pipeline complete!" + +# Install git hooks +install-hooks: + @mkdir -p .git/hooks + @cat > .git/hooks/pre-commit << 'HOOKEOF' + #!/bin/bash + just fmt-check || exit 1 + just lint || exit 1 + just assail || exit 1 + HOOKEOF + @chmod +x .git/hooks/pre-commit + @echo "Git hooks installed" + +# ═══════════════════════════════════════════════════════════════════════════════ +# SECURITY +# ═══════════════════════════════════════════════════════════════════════════════ + +# Run security audit +security: deps-audit + @echo "=== Security Audit ===" + @command -v gitleaks >/dev/null && gitleaks detect --source . --verbose || true + @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL . || true + @echo "Security audit complete" + +# Generate SBOM +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 +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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/STATE.a2ml .machine_readable/META.a2ml .machine_readable/ECOSYSTEM.a2ml .machine_readable/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/META.a2ml" ]; then + grep -q 'axis-1 = "must > intend > like"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-1" + grep -q 'axis-2 = "corrective > adaptive > perfective"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-2" + grep -q 'axis-3 = "systems > compliance > effects"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:axis-3" + grep -q 'scoping-first = true' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:scoping-first" + grep -q 'idris-unsound-scan = "believe_me/assert_total"' .machine_readable/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/META.a2ml || MISSING="$MISSING META.a2ml:audit-focus" + grep -q 'compliance-focus = "seams/compromises/exception register, bounded exceptions, anti-drift checks"' .machine_readable/META.a2ml || MISSING="$MISSING META.a2ml:compliance-focus" + grep -q 'effects-evidence = "benchmark execution/results and maintainer status dialogue/review"' .machine_readable/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/STATE.a2ml" ]; then \ + grep -q '^\[metadata\]' .machine_readable/STATE.a2ml && \ + grep -q 'project\s*=' .machine_readable/STATE.a2ml && \ + echo "STATE.a2ml: valid" || echo "STATE.a2ml: INVALID (missing required sections)"; \ + else \ + echo "No .machine_readable/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!" + +# ═══════════════════════════════════════════════════════════════════════════════ +# STATE MANAGEMENT +# ═══════════════════════════════════════════════════════════════════════════════ + +# Update STATE.a2ml timestamp +state-touch: + @if [ -f ".machine_readable/STATE.a2ml" ]; then \ + sed -i 's/last-updated = "[^"]*"/last-updated = "'"$(date +%Y-%m-%d)"'"/' .machine_readable/STATE.a2ml && \ + echo "STATE.a2ml timestamp updated"; \ + fi + +# Show current phase from STATE.a2ml +state-phase: + @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" + +# ═══════════════════════════════════════════════════════════════════════════════ +# GUIX & NIX +# ═══════════════════════════════════════════════════════════════════════════════ + +# Enter Guix development shell (primary) +guix-shell: + guix shell -D -f guix.scm + +# Build with Guix +guix-build: + guix build -f guix.scm + +# Enter Nix development shell (fallback) +nix-shell: + @if [ -f "flake.nix" ]; then nix develop; else echo "No flake.nix"; fi + +# ═══════════════════════════════════════════════════════════════════════════════ +# HYBRID AUTOMATION +# ═══════════════════════════════════════════════════════════════════════════════ + +# Run local automation tasks +automate task="all": + #!/usr/bin/env bash + 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 ;; + *) echo "Unknown: {{task}}. Use: all, cleanup, update" && exit 1 ;; + esac + +# ═══════════════════════════════════════════════════════════════════════════════ +# COMBINATORIC MATRIX RECIPES +# ═══════════════════════════════════════════════════════════════════════════════ + +# Build matrix: [debug|release] x [target] x [features] +build-matrix mode="debug" target="" features="": + @echo "Build matrix: mode={{mode}} target={{target}} features={{features}}" + +# Test matrix: [unit|integration|e2e|all] x [verbosity] x [parallel] +test-matrix suite="unit" verbosity="normal" parallel="true": + @echo "Test matrix: suite={{suite}} verbosity={{verbosity}} parallel={{parallel}}" + +# 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}}" + +# CI matrix: [lint|test|build|security|all] x [quick|full] +ci-matrix stage="all" depth="quick": + @echo "CI matrix: stage={{stage}} depth={{depth}}" + +# Show all matrix combinations +combinations: + @echo "=== Combinatoric Matrix Recipes ===" + @echo "" + @echo "Build Matrix: just build-matrix [debug|release] [target] [features]" + @echo "Test Matrix: just test-matrix [unit|integration|e2e|all] [verbosity] [parallel]" + @echo "Container: just container-matrix [build|run|push|shell|scan] [registry] [tag]" + @echo "CI Matrix: just ci-matrix [lint|test|build|security|all] [quick|full]" + +# ═══════════════════════════════════════════════════════════════════════════════ +# VERSION CONTROL +# ═══════════════════════════════════════════════════════════════════════════════ + +# Show git status +status: + @git status --short + +# Show recent commits +log count="20": + @git log --oneline -{{count}} + +# Generate CHANGELOG.md with git-cliff +changelog: + @command -v git-cliff >/dev/null || { echo "git-cliff not found — install: cargo install git-cliff"; exit 1; } + git cliff --config .machine_readable/configs/git-cliff/cliff.toml --output CHANGELOG.md + @echo "Generated CHANGELOG.md" + +# Preview changelog for unreleased commits (does not write) +changelog-preview: + @command -v git-cliff >/dev/null || { echo "git-cliff not found — install: cargo install git-cliff"; exit 1; } + git cliff --config .machine_readable/configs/git-cliff/cliff.toml --unreleased --strip header + +# Tag a new release (usage: just release-tag 1.2.3) +release-tag version: + #!/usr/bin/env bash + TAG="v{{version}}" + if git rev-parse "$TAG" >/dev/null 2>&1; then + echo "Tag $TAG already exists" + exit 1 + fi + just changelog + git add CHANGELOG.md + git commit -m "chore(release): prepare $TAG" + git tag -a "$TAG" -m "Release $TAG" + echo "Created tag $TAG — push with: git push origin main --tags" + +# ═══════════════════════════════════════════════════════════════════════════════ +# UTILITIES +# ═══════════════════════════════════════════════════════════════════════════════ + +# Count lines of code +loc: + @find . \( -name "*.rs" -o -name "*.ex" -o -name "*.exs" -o -name "*.res" -o -name "*.gleam" -o -name "*.zig" -o -name "*.idr" -o -name "*.hs" -o -name "*.ncl" -o -name "*.scm" -o -name "*.adb" -o -name "*.ads" \) -not -path './target/*' -not -path './_build/*' 2>/dev/null | xargs wc -l 2>/dev/null | tail -1 || echo "0" + +# Show TODO comments +todos: + @grep -rn "TODO\|FIXME\|HACK\|XXX" --include="*.rs" --include="*.ex" --include="*.res" --include="*.gleam" --include="*.zig" --include="*.idr" --include="*.hs" . 2>/dev/null || echo "No TODOs" + +# Open in editor +edit: + ${EDITOR:-code} . + +# Run high-rigor security assault using panic-attacker +maint-assault: + @./.machine_readable/scripts/maintenance/maint-assault.sh + +# Run panic-attacker pre-commit scan (foundational floor-raise requirement) +assail: + @command -v panic-attack >/dev/null 2>&1 && panic-attack assail . || echo "WARN: panic-attack not found — install from https://github.com/hyperpolymath/panic-attacker" + + +# Self-diagnostic — checks dependencies, permissions, paths +doctor: + @echo "Running diagnostics for fraying-model-computational-testbed..." + @echo "Checking required tools..." + @command -v just >/dev/null 2>&1 && echo " [OK] just" || echo " [FAIL] just not found" + @command -v git >/dev/null 2>&1 && echo " [OK] git" || echo " [FAIL] git not found" + @echo "Checking for hardcoded paths..." + @grep -rn '$HOME\|$ECLIPSE_DIR' --include='*.rs' --include='*.ex' --include='*.res' --include='*.gleam' --include='*.sh' . 2>/dev/null | head -5 || echo " [OK] No hardcoded paths" + @echo "Diagnostics complete." + +# Guided tour of key features +tour: + @echo "=== fraying-model-computational-testbed Tour ===" + @echo "" + @echo "1. Project structure:" + @ls -la + @echo "" + @echo "2. Available commands: just --list" + @echo "" + @echo "3. Read README.adoc for full overview" + @echo "4. Read EXPLAINME.adoc for architecture decisions" + @echo "5. Run 'just doctor' to check your setup" + @echo "" + @echo "Tour complete! Try 'just --list' to see all available commands." + +# Open feedback channel with diagnostic context +help-me: + @echo "=== fraying-model-computational-testbed Help ===" + @echo "Platform: $(uname -s) $(uname -m)" + @echo "Shell: $SHELL" + @echo "" + @echo "To report an issue:" + @echo " https://github.com/hyperpolymath/fraying-model-computational-testbed/issues/new" + @echo "" + @echo "Include the output of 'just doctor' in your report." + +# ═══════════════════════════════════════════════════════════════════════════════ +# FORMAL VERIFICATION (PROOFS) +# ═══════════════════════════════════════════════════════════════════════════════ + +# 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 "" + if [ -f PROOF-STATUS.md ]; then + grep -E "^\| \*\*Total\*\*" PROOF-STATUS.md 2>/dev/null || echo "(No summary row in PROOF-STATUS.md)" + else + echo "(No PROOF-STATUS.md found)" + fi + +# ═══════════════════════════════════════════════════════════════════════════════ +# SESSION MANAGEMENT (THIN BINDINGS TO CENTRAL STANDARDS) +# ═══════════════════════════════════════════════════════════════════════════════ + +# Show canonical session-management command model +session-help: + @echo "Canonical command model:" + @echo " intake repo " + @echo " checkpoint change " + @echo " verify maintenance " + @echo " verify substantial " + @echo " verify release " + @echo " close planned " + @echo " close urgent " + @echo " recover repo " + @echo " handover full " + @echo " handover split " + @echo " handover model " + @echo " handover human " + @echo "" + @echo "Use Just aliases below (thin wrappers around ./session/dispatch.sh)." + +# Canonical aliases (friendly recipe names that map to canonical commands) +intake-repo path=".": + @./session/dispatch.sh intake repo "{{path}}" + +checkpoint-change path=".": + @./session/dispatch.sh checkpoint change "{{path}}" + +verify-maintenance path=".": + @./session/dispatch.sh verify maintenance "{{path}}" + +verify-substantial path=".": + @./session/dispatch.sh verify substantial "{{path}}" + +verify-release path=".": + @./session/dispatch.sh verify release "{{path}}" + +close-planned path=".": + @./session/dispatch.sh close planned "{{path}}" + +close-urgent path=".": + @./session/dispatch.sh close urgent "{{path}}" + +recover-repo path=".": + @./session/dispatch.sh recover repo "{{path}}" + +handover-full path=".": + @./session/dispatch.sh handover full "{{path}}" + +handover-split path=".": + @./session/dispatch.sh handover split "{{path}}" + +handover-model path=".": + @./session/dispatch.sh handover model "{{path}}" + +handover-human path=".": + @./session/dispatch.sh handover human "{{path}}" diff --git a/.machine_readable/contractiles/Mustfile.a2ml b/.machine_readable/contractiles/Mustfile.a2ml new file mode 100644 index 0000000..55f8ab4 --- /dev/null +++ b/.machine_readable/contractiles/Mustfile.a2ml @@ -0,0 +1,102 @@ +# SPDX-License-Identifier: MPL-2.0 +# Mustfile — Physical state contract for rsr-template-repo +# Author: Jonathan D.A. Jewell +# +# What MUST be true about this repository. Hard requirements. +# Run with: must check +# Fix with: must fix (where a deterministic fix exists) + +@abstract: +Physical-state invariants for rsr-template-repo. This is the canonical +RSR template repository. These are hard requirements — CI and pre-commit +hooks fail if any check fails. +@end + +## File Presence + +### license-present +- description: LICENSE file must exist +- run: test -f LICENSE +- severity: critical + +### readme-present +- description: README.adoc must exist +- run: test -f README.adoc +- severity: critical + +### security-policy +- description: SECURITY.md must exist +- run: test -f SECURITY.md +- severity: critical + +### ai-manifest +- description: 0-AI-MANIFEST.a2ml must exist +- run: test -f 0-AI-MANIFEST.a2ml +- severity: critical + +### governance-docs +- description: GOVERNANCE.adoc, MAINTAINERS.adoc, CODEOWNERS must exist +- run: test -f GOVERNANCE.adoc && test -f MAINTAINERS.adoc && test -f .github/CODEOWNERS +- severity: critical + +### machine-readable-dir +- description: .machine_readable/ directory must exist +- run: test -d .machine_readable +- severity: critical + +## Directory Structure + +### contractiles-complete +- description: All required contractile directories exist +- run: test -d .machine_readable/contractiles && test -d .machine_readable/contractiles/bust && test -d .machine_readable/contractiles/dust +- severity: critical + +### contractiles-files-present +- description: All four primary contractile files exist +- run: test -f .machine_readable/contractiles/Intentfile.a2ml && test -f .machine_readable/contractiles/Mustfile.a2ml && test -f .machine_readable/contractiles/Trustfile.a2ml && test -f .machine_readable/contractiles/Adjustfile.a2ml +- severity: critical + +### bust-dust-files-present +- description: Bustfile and Dustfile exist in their directories +- run: test -f .machine_readable/contractiles/bust/Bustfile.a2ml && test -f .machine_readable/contractiles/dust/Dustfile.a2ml +- severity: critical + +### six-directory-present +- description: 6a2 directory exists with required files +- run: test -d .machine_readable/6a2 && test -f .machine_readable/6a2/META.a2ml && test -f .machine_readable/6a2/ECOSYSTEM.a2ml && test -f .machine_readable/6a2/STATE.a2ml && test -f .machine_readable/6a2/PLAYBOOK.a2ml && test -f .machine_readable/6a2/AGENTIC.a2ml && test -f .machine_readable/6a2/NEUROSYM.a2ml +- severity: critical + +### anchors-directory +- description: anchors directory exists in 6a2 +- run: test -d .machine_readable/6a2/anchors +- severity: warning + +### self-validating-structure +- description: self-validating directory has k9-svc and examples +- run: test -d .machine_readable/self-validating && test -d .machine_readable/self-validating/k9-svc && test -d .machine_readable/self-validating/examples +- severity: warning + +## Template Integrity + +### no-placeholder-values +- description: No placeholder values remain in template files +- run: test -z "$(grep -r '{{' .machine_readable/contractiles/ 2>/dev/null)" +- severity: critical +- notes: All placeholders must be substituted when copying this template + +### template-readonly +- description: Template marker files are not modified +- run: grep -q 'RSR_TEMPLATE_DO_NOT_EDIT' .machine_readable/0.1-AI-MANIFEST.a2ml +- severity: warning + +## Git State + +### no-untracked-contractiles +- description: All contractile files are tracked in git +- run: test -z "$(git ls-files -o --exclude-standard .machine_readable/contractiles/ 2>/dev/null)" +- severity: critical + +### signed-commits +- description: All commits must be signed +- run: git verify-commit HEAD +- severity: critical diff --git a/.machine_readable/contractiles/Trustfile.a2ml b/.machine_readable/contractiles/Trustfile.a2ml new file mode 100644 index 0000000..e2028b5 --- /dev/null +++ b/.machine_readable/contractiles/Trustfile.a2ml @@ -0,0 +1,88 @@ +# SPDX-License-Identifier: MPL-2.0 +# Trustfile — Trust boundaries and integrity invariants for rsr-template-repo +# Author: Jonathan D.A. Jewell +# +# Defines what LLM/SLM agents are trusted to do without asking, and +# integrity invariants that verify the repo has not been tampered with. + +@abstract: +Trust boundaries and integrity checks for rsr-template-repo. This file +combines the trust-level definitions from the original TRUST.contractile +with the integrity invariants from the old Trustfile.a2ml. It defines +what AI agents may do autonomously and what requires human approval, +plus checks that verify repository integrity. +@end + +## Trust Levels + +The rsr-template-repo operates at trust level: maximal + +Trust levels: +- maximal: Agent may read, build, test, lint, format, heal freely. + Only destructive/external actions require approval. +- standard: Agent may read and build. Test/lint need approval. +- restricted: Agent may read only. All modifications need approval. +- minimal: Agent may read specific files only. Everything else blocked. + +Current trust level: maximal + +## Integrity Invariants + +### Secrets + +#### no-secrets-committed +- description: No credential files in repo +- run: test ! -f .env && test ! -f credentials.json && test ! -f .env.local && test ! -f .env.production +- severity: critical + +#### no-private-keys +- description: No private key files committed +- run: "! find . -name '*.pem' -o -name '*.key' -o -name 'id_rsa' -o -name 'id_ed25519' 2>/dev/null | grep -v node_modules | head -1 | grep -q ." +- severity: critical + +#### no-tokens-in-source +- description: No hardcoded API tokens in source +- run: "! grep -rE '(api[_-]?key|secret|token|password)\s*[:=]\s*[\"'\\''][A-Za-z0-9]{16,}' --include='*.js' --include='*.ts' --include='*.res' --include='*.py' . 2>/dev/null | grep -v node_modules | head -1 | grep -q ." +- severity: critical + +## Provenance + +#### author-correct +- description: Git author matches expected identity +- run: "git log -1 --format='%ae' | grep -qE '(hyperpolymath|j\\.d\\.a\\.jewell)'" +- severity: warning + +#### license-content +- description: LICENSE contains expected identifier +- run: grep -q 'PMPL\|MPL\|MIT\|Apache\|LGPL' LICENSE +- severity: warning + +## Template-Specific Trust + +### template-files-readonly +- description: Template scaffold files should not be modified except by maintainer +- run: test -z "$(git status --short .machine_readable/ 2>/dev/null | grep -v '^??' || true)" +- severity: advisory +- notes: Changes to template files require careful review + +### trust-deny-areas +- description: Sensitive areas from INTENT.contractile require explicit approval +- run: echo "Check .machine_readable/ contractiles and governance docs" +- severity: advisory +- areas: + - .machine_readable/ + - GOVERNANCE.adoc + - MAINTAINERS.adoc + - .github/CODEOWNERS + +## Container Security + +#### container-images-pinned +- description: Containerfile uses pinned base images +- run: test ! -f Containerfile || grep -q 'cgr.dev\|@sha256:' Containerfile +- severity: warning + +#### no-dockerfile +- description: No Dockerfile (use Containerfile) +- run: test ! -f Dockerfile +- severity: warning diff --git a/.machine_readable/contractiles/bust/Bustfile.a2ml b/.machine_readable/contractiles/bust/Bustfile.a2ml deleted file mode 100644 index a43d618..0000000 --- a/.machine_readable/contractiles/bust/Bustfile.a2ml +++ /dev/null @@ -1,28 +0,0 @@ -// Bustfile.a2ml — meta-repo bust contractile (breakage / rollback) -// SPDX-License-Identifier: MPL-2.0 - -Bust { - name: "fraying-model-computational-testbed" - version: "1.0.0" - description: "Rollback procedures when something breaks in the meta-repo" - - scenarios: { - "bad-pointer-bump": "git revert in meta-repo; child repo itself untouched" - "submodule-pointer-points-at-missing-sha": "git submodule update --init --checkout resets child to parent-recorded SHA; OR revert the stale bump commit" - "submodule-orphan-after-local-only-commit": "roll back locally with git reset to before the stranded commit; fix remote situation before re-attempting" - "accidental-private-repo-content-leaked-to-public-submodule": "hard-rotate the leaked secret immediately; git-filter-repo or BFG on the submodule's own history; public re-publication only after rotation complete" - } - - escalation-ladder: [ - "1. revert the meta-repo commit (reversible, low blast radius)", - "2. reset the local submodule clone (affects only local workspace)", - "3. force-push to main — PROHIBITED without explicit user confirmation (violates branch protection)", - "4. registry-level (delete/archive the GitHub repo) — human-only action, never by AI" - ] - - backup-points: [ - "GitHub serves as the durable backup for every submodule's own history", - "Meta-repo history on origin/main is the durable backup for pointer state", - "Local backup tags (backup/pre--) retained on risky rewrites" - ] -} diff --git a/.machine_readable/contractiles/bust/bust.ncl b/.machine_readable/contractiles/bust/bust.ncl deleted file mode 100644 index fc8cb8c..0000000 --- a/.machine_readable/contractiles/bust/bust.ncl +++ /dev/null @@ -1,66 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Bust — error-handling / failure-recovery runner -# -# Pairs with: Bustfile.a2ml (same directory) -# Verb: bust -# Semantics: every declared failure mode must have a recovery path that has -# been exercised. Runner injects failures (via declared probes) -# and verifies the recovery path works. Hard gate on any -# failure-mode with missing or broken recovery. -# CLI: `contractile bust check` → list failure modes + recovery status -# `contractile bust drill` → inject declared failures, verify recovery -# -# Anything else in this directory is human-only notes/archive; machines ignore. -# -# Base: ../_base.ncl provides pedigree_schema, run_defaults, probe_schema. -# See: docs/CONTRACTILE-SPEC.adoc - -let base = import "../_base.ncl" in - -{ - pedigree = base.pedigree_schema & { - contractile_verb = "bust", - semantics = "error handling + failure recovery", - security = { - leash = 'Kennel, - trust_level = "controlled failure injection; scoped to system-under-test", - allow_network = false, - allow_filesystem_write = true, # drills may write transient state (tmp dirs, test DBs) - allow_subprocess = true, - injection_scope = "system-under-test-only", - }, - metadata = { - name = "bust-runner", - version = "1.0.0", - description = "Exercises declared failure modes and verifies recovery paths. Hard-gates on any failure mode without working recovery.", - paired_xfile = "Bustfile.a2ml", - author = "Jonathan D.A. Jewell ", - }, - }, - - schema = { - failure_modes - | Array { - id | String, - description | String, - class | [| 'network, 'disk_full, 'oom, 'timeout, 'partial_write, 'panic, 'crash, 'rollback, 'concurrency |], - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - injection_probe | String, # command that deterministically causes this failure - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - recovery_probe | String, # command that verifies recovery (exit 0 = recovered) - expected_recovery_time_seconds | Number | default = 30, - # status_core values: 'declared, 'verified, 'failing; bust adds 'drilled - status | [| 'declared, 'drilled, 'verified, 'failing |] | default = 'declared, - notes | String | optional, - }, - }, - - # Runner behaviour — inherits from base.run_defaults. - # bust adds record_recovery_times for performance tier feeding. - run = base.run_defaults & { - on_any_fail = "exit-nonzero", # missing or broken recovery blocks merge - report_format = "a2ml", - emit_summary = true, - record_recovery_times = true, # feeds the performance tier - }, -} diff --git a/.machine_readable/contractiles/dust/Dustfile.a2ml b/.machine_readable/contractiles/dust/Dustfile.a2ml deleted file mode 100644 index be38a8c..0000000 --- a/.machine_readable/contractiles/dust/Dustfile.a2ml +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Dustfile — Cleanup and hygiene contract -# Author: Jonathan D.A. Jewell - -@abstract: -What should be cleaned up or removed from this repository. -These are housekeeping items, not blockers. -@end - -## Stale Files - -### no-stale-snapshots -- description: No dated status/completion files in root -- run: "! ls *-STATUS-*.md *-COMPLETION-*.md *-COMPLETE.md *-VERIFIED-*.md 2>/dev/null | head -1 | grep -q ." -- severity: info - -### no-ai-djot -- description: AI.djot is superseded by 0-AI-MANIFEST.a2ml -- run: test ! -f AI.djot -- severity: warning - -### no-next-steps -- description: NEXT_STEPS.md superseded by ROADMAP -- run: test ! -f NEXT_STEPS.md -- severity: info - -## Build Artifacts - -### no-tracked-artifacts -- description: No build artifacts tracked in git -- run: "! git ls-files lib/bs/ lib/ocaml/ target/release/ _build/ 2>/dev/null | head -1 | grep -q ." -- severity: warning - -## Format Duplicates - -### no-duplicate-contributing -- description: Only one CONTRIBUTING format (keep .md) -- run: "! (test -f CONTRIBUTING.md && test -f CONTRIBUTING.adoc)" -- severity: warning - -### no-duplicate-readme -- description: Only one README format -- run: "! (test -f README.md && test -f README.adoc && [ $(wc -l < README.md) -gt 5 ])" -- severity: warning diff --git a/.machine_readable/contractiles/must/Mustfile.a2ml b/.machine_readable/contractiles/must/Mustfile.a2ml deleted file mode 100644 index 215c510..0000000 --- a/.machine_readable/contractiles/must/Mustfile.a2ml +++ /dev/null @@ -1,69 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Mustfile — Physical state contract -# Author: Jonathan D.A. Jewell - -@abstract: -What MUST be true about this repository's files and configuration. -These are hard requirements — CI fails if any check fails. -@end - -## File Presence - -### license-present -- description: LICENSE file must exist -- run: test -f LICENSE -- severity: critical - -### readme-present -- description: README.adoc or README.md must exist -- run: test -f README.adoc || test -f README.md -- severity: critical - -### security-policy -- description: SECURITY.md must exist -- run: test -f SECURITY.md -- severity: critical - -### ai-manifest -- description: 0-AI-MANIFEST.a2ml must exist -- run: test -f 0-AI-MANIFEST.a2ml -- severity: critical - -### contributing -- description: CONTRIBUTING.md must exist (GitHub community health) -- run: test -f CONTRIBUTING.md -- severity: warning - -### editorconfig -- description: .editorconfig must exist -- run: test -f .editorconfig -- severity: warning - -## SPDX Compliance - -### spdx-headers -- description: All source files must have SPDX-License-Identifier -- run: "! find src/ -name '*.rs' -o -name '*.res' -o -name '*.idr' -o -name '*.zig' 2>/dev/null | head -20 | xargs grep -L 'SPDX-License-Identifier' 2>/dev/null | head -1 | grep -q ." -- severity: warning - -### no-agpl -- description: No AGPL-3.0 references in dotfiles -- run: "! grep -r 'AGPL-3.0' .gitignore .gitattributes .editorconfig 2>/dev/null | head -1 | grep -q ." -- severity: critical - -## Dangerous Patterns - -### no-believe-me -- description: No believe_me in Idris2 code -- run: "! grep -r 'believe_me' --include='*.idr' . 2>/dev/null | grep -v node_modules | head -1 | grep -q ." -- severity: critical - -### no-sorry -- description: No sorry in Lean code -- run: "! grep -r 'sorry' --include='*.lean' . 2>/dev/null | grep -v node_modules | head -1 | grep -q ." -- severity: critical - -### no-admitted -- description: No Admitted in Coq code -- run: "! grep -r 'Admitted' --include='*.v' . 2>/dev/null | grep -v node_modules | head -1 | grep -q ." -- severity: critical diff --git a/.machine_readable/contractiles/trust/Trustfile.a2ml b/.machine_readable/contractiles/trust/Trustfile.a2ml deleted file mode 100644 index 2e583a3..0000000 --- a/.machine_readable/contractiles/trust/Trustfile.a2ml +++ /dev/null @@ -1,74 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Trustfile — Integrity and provenance verification -# Author: Jonathan D.A. Jewell - -@abstract: -Integrity invariants for this repository. These verify that the repo -has not been tampered with, secrets are not leaked, and provenance -is traceable. -@end - -## Secrets - -### no-secrets-committed -- description: No credential files in repo -- run: test ! -f .env && test ! -f credentials.json && test ! -f .env.local && test ! -f .env.production -- severity: critical - -### no-private-keys -- description: No private key files committed -- run: "! find . -name '*.pem' -o -name '*.key' -o -name 'id_rsa' -o -name 'id_ed25519' 2>/dev/null | grep -v node_modules | head -1 | grep -q ." -- severity: critical - -### no-tokens-in-source -- description: No hardcoded API tokens in source -- run: "! grep -rE '(api[_-]?key|secret|token|password)\s*[:=]\s*[\"'\\''][A-Za-z0-9]{16,}' --include='*.js' --include='*.ts' --include='*.res' --include='*.py' . 2>/dev/null | grep -v node_modules | head -1 | grep -q ." -- severity: critical - -## Provenance - -### author-correct -- description: Git author matches expected identity -- run: "git log -1 --format='%ae' | grep -qE '(hyperpolymath|j\\.d\\.a\\.jewell)'" -- severity: warning - -### license-content -- description: LICENSE contains expected identifier -- run: grep -q 'PMPL\|MPL\|MIT\|Apache\|LGPL' LICENSE -- severity: warning - -## Container Security - -### container-images-pinned -- description: Containerfile uses pinned base images -- run: test ! -f Containerfile || grep -q 'cgr.dev\|@sha256:' Containerfile -- severity: warning - -### no-dockerfile -- description: No Dockerfile (use Containerfile) -- run: test ! -f Dockerfile -- severity: warning - -## Dangerous Patterns - -### no-believe-me -- description: No believe_me, assert_total, Admitted, sorry, unsafeCoerce, Obj.magic -- run: "! grep -rE 'believe_me|assert_total|Admitted|sorry|unsafeCoerce|Obj\\.magic' --include='*.idr' --include='*.lean' --include='*.v' --include='*.ml' --include='*.hs' . 2>/dev/null | head -1 | grep -q ." -- severity: critical - -### no-unsafe-without-comment -- description: All unsafe blocks in Rust must have SAFETY comments -- run: "! grep -B1 'unsafe {' --include='*.rs' -r . 2>/dev/null | grep -v SAFETY | grep 'unsafe {' | head -1 | grep -q ." -- severity: warning - -## Service Security (if applicable) - -### localhost-only-bindings -- description: Backend services bind to 127.0.0.1 only -- run: "! grep -rE 'bind\\(\"0\\.0\\.0\\.0' --include='*.rs' --include='*.ex' --include='*.ts' . 2>/dev/null | head -1 | grep -q ." -- severity: critical - -### coordination-file-permissions -- description: Coordination/session files are owner-only (0600) -- run: test ! -d ~/.claude/coordination || find ~/.claude/coordination -type f ! -perm 600 2>/dev/null | wc -l | grep -q '^0$' -- severity: warning diff --git a/contractiles/intend/Intentfile.a2ml b/contractiles/intend/Intentfile.a2ml deleted file mode 100644 index e313a7d..0000000 --- a/contractiles/intend/Intentfile.a2ml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Intentfile.a2ml — BLANK TEMPLATE -# Replace this with your project's contractile. -# See .machine_readable/contractiles/ for a working example. -# -# Copy this file to .machine_readable/contractiles/lust/Intentfile.a2ml -# and fill in your project-specific checks. - -@abstract: -[Your project's LUST contract goes here] -@end diff --git a/contractiles/must/Mustfile.a2ml b/contractiles/must/Mustfile.a2ml deleted file mode 100644 index d08796f..0000000 --- a/contractiles/must/Mustfile.a2ml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Mustfile.a2ml — BLANK TEMPLATE -# Replace this with your project's contractile. -# See .machine_readable/contractiles/ for a working example. -# -# Copy this file to .machine_readable/contractiles/must/Mustfile.a2ml -# and fill in your project-specific checks. - -@abstract: -[Your project's MUST contract goes here] -@end diff --git a/contractiles/trust/Trustfile.a2ml b/contractiles/trust/Trustfile.a2ml deleted file mode 100644 index 842c6b0..0000000 --- a/contractiles/trust/Trustfile.a2ml +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Trustfile.a2ml — BLANK TEMPLATE -# Replace this with your project's contractile. -# See .machine_readable/contractiles/ for a working example. -# -# Copy this file to .machine_readable/contractiles/trust/Trustfile.a2ml -# and fill in your project-specific checks. - -@abstract: -[Your project's TRUST contract goes here] -@end diff --git a/flake.nix b/flake.nix deleted file mode 100644 index df7a0a5..0000000 --- a/flake.nix +++ /dev/null @@ -1,170 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> -# -# Nix flake for {{PROJECT_NAME}} -# -# NOTE: guix.scm is the PRIMARY development environment. This flake is provided -# as a FALLBACK for contributors who use Nix instead of Guix. The .envrc checks -# for Guix first, then falls back to Nix. -# -# Usage: -# nix develop # Enter development shell -# nix build # Build the project -# nix flake check # Run checks -# nix flake show # Show flake outputs -# -# With direnv (.envrc already configured): -# direnv allow # Auto-enters shell on cd -# -# TODO: Replace {{PROJECT_NAME}} and {{PROJECT_DESCRIPTION}} with actual values. - -{ - description = "{{PROJECT_NAME}} — RSR-compliant project"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixpkgs-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachSystem [ "x86_64-linux" "aarch64-linux" ] (system: - let - pkgs = import nixpkgs { inherit system; }; - - # Common development tools present in every RSR project. - commonTools = with pkgs; [ - git - just - nickel - curl - bash - coreutils - ]; - - # --------------------------------------------------------------- - # Language-specific packages: uncomment the stacks you need. - # --------------------------------------------------------------- - # - # Rust: - # rustc cargo clippy rustfmt rust-analyzer - # - # Elixir: - # elixir erlang - # - # Gleam: - # gleam erlang - # - # Zig: - # zig zls - # - # Haskell: - # ghc cabal-install haskell-language-server - # - # Idris2: - # idris2 - # - # OCaml: - # ocaml dune_3 ocaml-lsp - # - # ReScript (via Deno): - # deno - # - # Julia: - # julia - # - # Ada/SPARK: - # gnat gprbuild - # - # --------------------------------------------------------------- - languageTools = with pkgs; [ - # TODO: Uncomment or add packages for your stack. - # Example for a Rust project: - # rustc - # cargo - # clippy - # rustfmt - # rust-analyzer - ]; - - in - { - # --------------------------------------------------------------- - # Development shell — `nix develop` - # --------------------------------------------------------------- - devShells.default = pkgs.mkShell { - name = "{{PROJECT_NAME}}-dev"; - - buildInputs = commonTools ++ languageTools; - - # Environment variables available inside the shell. - env = { - PROJECT_NAME = "{{PROJECT_NAME}}"; - RSR_TIER = "infrastructure"; - }; - - shellHook = '' - echo "" - echo " {{PROJECT_NAME}} — development shell" - echo " Nix: $(nix --version 2>/dev/null || echo 'unknown')" - echo " Just: $(just --version 2>/dev/null || echo 'not found')" - echo "" - echo " Run 'just' to see available recipes." - echo "" - - # Source .envrc manually when direnv is not managing the shell. - # This keeps project env vars (PROJECT_NAME, DATABASE_URL, etc.) - # consistent whether you enter via 'nix develop' or 'direnv allow'. - if [ -z "''${DIRENV_IN_ENVRC:-}" ] && [ -f .envrc ]; then - # Only source the non-nix parts to avoid recursion. - export PROJECT_NAME="{{PROJECT_NAME}}" - export RSR_TIER="infrastructure" - if [ -f .env ]; then - set -a - . .env - set +a - fi - fi - ''; - }; - - # --------------------------------------------------------------- - # Package — `nix build` - # --------------------------------------------------------------- - packages.default = pkgs.stdenv.mkDerivation { - pname = "{{PROJECT_NAME}}"; - version = "0.1.0"; - - src = self; - - # TODO: Replace with real build instructions. - # Examples: - # - # Rust (use rustPlatform.buildRustPackage instead of stdenv): - # packages.default = pkgs.rustPlatform.buildRustPackage { ... }; - # - # Elixir (use mixRelease): - # packages.default = pkgs.beamPackages.mixRelease { ... }; - # - # Zig: - # buildPhase = "zig build -Doptimize=ReleaseSafe"; - - buildPhase = '' - echo "TODO: Add build commands for {{PROJECT_NAME}}" - ''; - - installPhase = '' - mkdir -p $out/share/doc - cp README.adoc $out/share/doc/ 2>/dev/null || true - ''; - - meta = with pkgs.lib; { - description = "{{PROJECT_DESCRIPTION}}"; - homepage = "https://github.com/{{OWNER}}/{{PROJECT_NAME}}"; - license = licenses.mpl20; # MPL-2.0 extends MPL-2.0 - maintainers = []; - platforms = [ "x86_64-linux" "aarch64-linux" ]; - }; - }; - } - ); -} From 9f5c8e965565ab8d771073123a2ffc2df22c50dc Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 11 Jun 2026 22:15:50 +0100 Subject: [PATCH 07/11] security: standardize secret scanning on TruffleHog --- .github/workflows/boj-build.yml | 4 - .github/workflows/codeql.yml | 7 - .github/workflows/dependabot-automerge.yml | 12 +- .github/workflows/e2e.yml | 306 ++++++++++----------- .github/workflows/governance.yml | 4 - .github/workflows/hypatia-scan.yml | 103 +------ .github/workflows/instant-sync.yml | 4 - .github/workflows/mirror.yml | 24 -- .github/workflows/openssf-compliance.yml | 11 - .github/workflows/release.yml | 25 +- .github/workflows/rhodibot.yml | 54 +--- .github/workflows/rust-ci.yml | 16 -- .github/workflows/scorecard-enforcer.yml | 14 +- .github/workflows/scorecard.yml | 19 +- .github/workflows/secret-scanner.yml | 26 +- .github/workflows/static-analysis-gate.yml | 40 +-- .gitlab-ci.yml | 31 +-- .machine_readable/contractiles/Justfile | 5 +- .pre-commit-config.yaml | 2 - Justfile | 5 +- 20 files changed, 203 insertions(+), 509 deletions(-) diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index 20848c4..b203334 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -6,15 +6,12 @@ # To enable: set BOJ_SERVER_URL as a repository secret or variable. # To disable: delete this file or leave BOJ_SERVER_URL unset. name: BoJ Server Build Trigger - on: push: branches: [main, master] workflow_dispatch: - permissions: contents: read - jobs: trigger-boj: runs-on: ubuntu-latest @@ -23,7 +20,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Trigger BoJ Server (Casket/ssg-mcp) env: BOJ_URL: ${{ secrets.BOJ_SERVER_URL || vars.BOJ_SERVER_URL }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index e547933..64a6a75 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,6 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 name: CodeQL Security Analysis - on: push: branches: [main, master] @@ -8,7 +7,6 @@ on: branches: [main, master] schedule: - cron: '0 6 * * 1' - # Estate guardrail: cancel superseded runs so re-pushes / rebased PR # updates do not pile up queued runs against the shared account-wide # Actions concurrency pool. Applied only to read-only check workflows @@ -16,10 +14,8 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read - jobs: analyze: runs-on: ubuntu-latest @@ -33,17 +29,14 @@ jobs: include: - language: javascript-typescript build-mode: none - steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Initialize CodeQL uses: github/codeql-action/init@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v3 with: diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 6d98f9c..bce3810 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -35,30 +35,25 @@ # bumps for dependabot/fetch-metadata flow through the same path. name: Dependabot Auto-Merge - on: pull_request: types: [opened, reopened, synchronize] - permissions: - contents: write # needed to enable auto-merge - pull-requests: write # needed to approve + contents: write # needed to enable auto-merge + pull-requests: write # needed to approve # NB: keep narrow — do NOT add secrets: read or id-token: write here. - jobs: automerge: # Only run for PRs actually authored by Dependabot. if: github.actor == 'dependabot[bot]' && github.event.pull_request.user.login == 'dependabot[bot]' runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Fetch Dependabot metadata id: meta uses: dependabot/fetch-metadata@dbb049abf0d677abbd7f7eee0375145b417fdd34 # v2.2.0 with: github-token: ${{ secrets.GITHUB_TOKEN }} - # --- Policy gate ------------------------------------------------------- # Outputs from fetch-metadata we care about: # update-type → version-update:semver-{patch,minor,major} @@ -107,7 +102,6 @@ jobs: echo "security=$is_security" >> "$GITHUB_OUTPUT" echo "update_type=$UPDATE_TYPE" >> "$GITHUB_OUTPUT" echo "ghsa=$GHSA_ID" >> "$GITHUB_OUTPUT" - - name: Approve PR (if policy allows) if: steps.policy.outputs.action == 'automerge' env: @@ -116,7 +110,6 @@ jobs: run: | gh pr review --approve "$PR_URL" \ --body "Auto-approving Dependabot security update (${{ steps.policy.outputs.ghsa }}, ${{ steps.policy.outputs.update_type }}). Policy: low/moderate security patches/minors only." - - name: Enable auto-merge (if policy allows) if: steps.policy.outputs.action == 'automerge' env: @@ -124,7 +117,6 @@ jobs: PR_URL: ${{ github.event.pull_request.html_url }} run: | gh pr merge --auto --squash "$PR_URL" - - name: Write decision to step summary env: ACTION: ${{ steps.policy.outputs.action }} diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index f4ee3ec..940c70a 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -13,7 +13,6 @@ # Delete sections that don't apply. See examples in each job. name: E2E + Aspect + Bench - on: push: branches: [main, master, develop] @@ -29,162 +28,159 @@ on: - 'ffi/**' - 'tests/**' workflow_dispatch: - permissions: read-all - concurrency: group: e2e-${{ github.ref }} cancel-in-progress: true - jobs: - # ─── End-to-End Tests ────────────────────────────────────────────── - # Uncomment ONE of the following e2e job blocks matching your stack. - - ## === RUST E2E === - # e2e: - # name: E2E — Full Pipeline - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - # - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - # - run: cargo build --release - # - run: bash tests/e2e.sh - # # OR: cargo test --test end_to_end -- --nocapture - - ## === ZIG FFI E2E === - # e2e: - # name: E2E — FFI Pipeline - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: goto-bus-stop/setup-zig@abea47f85e598557f500fa1fd2ab7464fcb39406 # v2.2.1 - # with: - # version: 0.15.0 - # - run: cd ffi/zig && zig build test - # - run: bash tests/e2e.sh - - ## === ELIXIR E2E === - # e2e: - # name: E2E — Full Pipeline - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.24.0 - # with: - # otp-version: '27.0' - # elixir-version: '1.17' - # - run: mix deps.get && mix compile --warnings-as-errors - # - run: mix test test/integration/e2e_test.exs --trace - - ## === DENO/RESCRIPT E2E === - # e2e: - # name: E2E — Full Pipeline - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4 - # with: - # deno-version: v2.x - # - run: deno install --node-modules-dir=auto - # - run: deno task res:build # ReScript compile - # - run: deno test tests/e2e/ - - ## === PLAYWRIGHT (Browser E2E) === - # e2e-playwright: - # name: Playwright — ${{ matrix.project }} - # runs-on: ubuntu-latest - # timeout-minutes: 20 - # strategy: - # fail-fast: false - # matrix: - # project: [chromium-1080p, firefox-1080p, webkit-1080p] - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: denoland/setup-deno@667a34cdef165d8d2b2e98dde39547c9daac7282 # v2.0.4 - # with: - # deno-version: v2.x - # - run: deno install --node-modules-dir=auto - # - run: npx playwright install --with-deps - # - run: npx playwright test --project=${{ matrix.project }} - # - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 - # if: failure() - # with: - # name: playwright-traces-${{ matrix.project }} - # path: test-results/**/trace.zip - # retention-days: 7 - - ## === HASKELL E2E === - # e2e: - # name: E2E — Full Pipeline - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: haskell-actions/setup@cd0d9bdd65b20557f41bea4dbe43d0b5fbbfe553 # v2.11.0 - # with: - # ghc-version: '9.6' - # cabal-version: '3.10' - # - run: cabal build all - # - run: bash tests/integration-test.sh - - # ─── Aspect Tests ────────────────────────────────────────────────── - # Cross-cutting concerns: thread safety, ABI contracts, SPDX, dangerous patterns - # Uncomment and customise: - - # aspect-tests: - # name: Aspect — Architectural Invariants - # runs-on: ubuntu-latest - # timeout-minutes: 10 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - run: bash tests/aspect_tests.sh - - # ─── Benchmarks ──────────────────────────────────────────────────── - # Performance regression detection. Uncomment matching stack: - - ## === RUST BENCH === - # benchmarks: - # name: Bench — Performance Regression - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - # - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - # - run: cargo bench 2>&1 | tee /tmp/bench-results.txt - # - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 - # if: always() - # with: - # name: benchmark-results - # path: /tmp/bench-results.txt - # retention-days: 30 - - ## === ZIG BENCH === - # benchmarks: - # name: Bench — Performance Regression - # runs-on: ubuntu-latest - # timeout-minutes: 15 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: goto-bus-stop/setup-zig@abea47f85e598557f500fa1fd2ab7464fcb39406 # v2.2.1 - # with: - # version: 0.15.0 - # - run: cd ffi/zig && zig build bench - - # ─── Readiness (CRG) ────────────────────────────────────────────── - # Component Readiness Grade: D (runs) → C (correct) → B (edge cases) - - # readiness: - # name: Readiness — Grade D/C/B - # runs-on: ubuntu-latest - # timeout-minutes: 10 - # steps: - # - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - # - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - # - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - # - run: cargo test --test readiness -- --nocapture +# ─── End-to-End Tests ────────────────────────────────────────────── +# Uncomment ONE of the following e2e job blocks matching your stack. + +## === RUST E2E === +# e2e: +# name: E2E — Full Pipeline +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable +# - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 +# - run: cargo build --release +# - run: bash tests/e2e.sh +# # OR: cargo test --test end_to_end -- --nocapture + +## === ZIG FFI E2E === +# e2e: +# name: E2E — FFI Pipeline +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: goto-bus-stop/setup-zig@7ab2955eb728f5440978d7b4f723a50dea1f3608 # v2 +# with: +# version: 0.15.0 +# - run: cd ffi/zig && zig build test +# - run: bash tests/e2e.sh + +## === ELIXIR E2E === +# e2e: +# name: E2E — Full Pipeline +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: erlef/setup-beam@5a67e1a1dd86cae5e5bef84e2da5060406a66c07 # v1 +# with: +# otp-version: '27.0' +# elixir-version: '1.17' +# - run: mix deps.get && mix compile --warnings-as-errors +# - run: mix test test/integration/e2e_test.exs --trace + +## === DENO/RESCRIPT E2E === +# e2e: +# name: E2E — Full Pipeline +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: denoland/setup-deno@5fae568d37c3b73e0e4ca63d4e2c4e324a2b3497 # v2 +# with: +# deno-version: v2.x +# - run: deno install --node-modules-dir=auto +# - run: deno task res:build # ReScript compile +# - run: deno test tests/e2e/ + +## === PLAYWRIGHT (Browser E2E) === +# e2e-playwright: +# name: Playwright — ${{ matrix.project }} +# runs-on: ubuntu-latest +# timeout-minutes: 20 +# strategy: +# fail-fast: false +# matrix: +# project: [chromium-1080p, firefox-1080p, webkit-1080p] +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: denoland/setup-deno@5fae568d37c3b73e0e4ca63d4e2c4e324a2b3497 # v2 +# with: +# deno-version: v2.x +# - run: deno install --node-modules-dir=auto +# - run: npx playwright install --with-deps +# - run: npx playwright test --project=${{ matrix.project }} +# - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 +# if: failure() +# with: +# name: playwright-traces-${{ matrix.project }} +# path: test-results/**/trace.zip +# retention-days: 7 + +## === HASKELL E2E === +# e2e: +# name: E2E — Full Pipeline +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: haskell-actions/setup@dd344bc1cec854a9b55c2b857c28b688010e4fce # v2 +# with: +# ghc-version: '9.6' +# cabal-version: '3.10' +# - run: cabal build all +# - run: bash tests/integration-test.sh + +# ─── Aspect Tests ────────────────────────────────────────────────── +# Cross-cutting concerns: thread safety, ABI contracts, SPDX, dangerous patterns +# Uncomment and customise: + +# aspect-tests: +# name: Aspect — Architectural Invariants +# runs-on: ubuntu-latest +# timeout-minutes: 10 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - run: bash tests/aspect_tests.sh + +# ─── Benchmarks ──────────────────────────────────────────────────── +# Performance regression detection. Uncomment matching stack: + +## === RUST BENCH === +# benchmarks: +# name: Bench — Performance Regression +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable +# - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 +# - run: cargo bench 2>&1 | tee /tmp/bench-results.txt +# - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 +# if: always() +# with: +# name: benchmark-results +# path: /tmp/bench-results.txt +# retention-days: 30 + +## === ZIG BENCH === +# benchmarks: +# name: Bench — Performance Regression +# runs-on: ubuntu-latest +# timeout-minutes: 15 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: goto-bus-stop/setup-zig@7ab2955eb728f5440978d7b4f723a50dea1f3608 # v2 +# with: +# version: 0.15.0 +# - run: cd ffi/zig && zig build bench + +# ─── Readiness (CRG) ────────────────────────────────────────────── +# Component Readiness Grade: D (runs) → C (correct) → B (edge cases) + +# readiness: +# name: Readiness — Grade D/C/B +# runs-on: ubuntu-latest +# timeout-minutes: 10 +# steps: +# - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 +# - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable +# - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 +# - run: cargo test --test readiness -- --nocapture diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 1b4e269..e0c379b 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -11,13 +11,11 @@ # (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing). name: Governance - on: push: branches: [main, master] pull_request: workflow_dispatch: - # Estate guardrail: cancel superseded runs so re-pushes / rebased PR # updates do not pile up queued runs against the shared account-wide # Actions concurrency pool. Applied only to read-only check workflows @@ -25,10 +23,8 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read - jobs: governance: uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613 diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index 7d843b7..5503e25 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -3,50 +3,43 @@ # See standards#191 for the reusable's purpose and design. name: Hypatia Security Scan - on: push: branches: [main, master, develop] pull_request: branches: [main, master] schedule: - - cron: '0 0 * * 0' + - cron: '0 0 * * 0' # Weekly on Sunday workflow_dispatch: # Estate guardrail: cancel superseded runs so re-pushes don't pile up. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read security-events: write pull-requests: write - jobs: scan: name: Hypatia Neurosymbolic Analysis runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: - fetch-depth: 0 # Full history for better pattern analysis - + fetch-depth: 0 # Full history for better pattern analysis - name: Setup Elixir for Hypatia scanner uses: erlef/setup-beam@fc68ffb90438ef2936bbb3251622353b3dcb2f93 # v1.18.2 with: elixir-version: '1.18' otp-version: '27' - - name: Clone Hypatia run: | if [ ! -d "$HOME/hypatia" ]; then git clone https://github.com/hyperpolymath/hypatia.git "$HOME/hypatia" fi - - name: Build Hypatia scanner (if needed) run: | cd "$HOME/hypatia" @@ -55,7 +48,6 @@ jobs: mix deps.get mix escript.build fi - - name: Run Hypatia scan id: scan env: @@ -88,14 +80,12 @@ jobs: echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY - - name: Upload findings artifact uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: hypatia-findings path: hypatia-findings.json retention-days: 90 - - name: Convert Hypatia findings to SARIF # Always runs (no findings_count guard): an EMPTY SARIF run is # valid and intentional — uploading it clears stale Hypatia @@ -211,7 +201,6 @@ jobs: console.log(`hypatia.sarif written: ${results.length} result(s).`); CJS node "$RUNNER_TEMP/hypatia-sarif.cjs" - - name: Upload SARIF to GitHub code scanning # Fork PRs get a read-only GITHUB_TOKEN, so security-events:write # is unavailable and upload-sarif cannot publish — skip there @@ -223,8 +212,12 @@ jobs: # exists to end). The empty-SARIF "clear stale alerts" path is # handled in the converter above and does not error here. if: >- - always() && - (github.event_name != 'pull_request' || + always() && (github.event_name != 'pull_request' || + + + + + github.event.pull_request.head.repo.fork != true) uses: github/codeql-action/upload-sarif@0d579ffd059c29b07949a3cce3983f0780820c98 # v3.28.1 with: @@ -232,7 +225,6 @@ jobs: # Distinct category so Hypatia results coexist with CodeQL's # (codeql.yml) instead of overwriting them on the same surface. category: hypatia - - name: Submit findings to gitbot-fleet (Phase 2) if: steps.scan.outputs.findings_count > 0 # Phase 2 is the collaborative LEARNING side-channel ("bots share @@ -256,52 +248,7 @@ jobs: GITHUB_REPOSITORY: ${{ github.repository }} GITHUB_SHA: ${{ github.sha }} FINDINGS_COUNT: ${{ steps.scan.outputs.findings_count }} - run: | - echo "📤 Submitting $FINDINGS_COUNT findings to gitbot-fleet..." - - # Clone gitbot-fleet to temp directory. A clone failure (network, - # repo gone) is non-fatal: learning submission is best-effort. - FLEET_DIR="/tmp/gitbot-fleet-$$" - if ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR"; then - echo "::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal)." - exit 0 - fi - - # The submission script's location in gitbot-fleet has drifted - # before (it was absent from the default branch, which exit-127'd - # every consuming repo's scan). Probe known locations rather than - # hard-coding one path, and skip gracefully if none is present. - SUBMIT_SCRIPT="" - for cand in \ - "$FLEET_DIR/scripts/submit-finding.sh" \ - "$FLEET_DIR/scripts/submit_finding.sh" \ - "$FLEET_DIR/bin/submit-finding.sh" \ - "$FLEET_DIR/submit-finding.sh"; do - if [ -f "$cand" ]; then - SUBMIT_SCRIPT="$cand" - break - fi - done - - if [ -z "$SUBMIT_SCRIPT" ]; then - echo "::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below." - rm -rf "$FLEET_DIR" - exit 0 - fi - - # Run submission script. Pass the findings path as ABSOLUTE — - # the script cd's into its own working dir before reading the - # file, so a relative path would resolve to the wrong place. - # A submission-script failure is logged but non-fatal. - if bash "$SUBMIT_SCRIPT" "$GITHUB_WORKSPACE/hypatia-findings.json"; then - echo "✅ Finding submission complete" - else - echo "::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal)." - fi - - # Cleanup - rm -rf "$FLEET_DIR" - + run: "echo \"\U0001F4E4 Submitting $FINDINGS_COUNT findings to gitbot-fleet...\"\n\n# Clone gitbot-fleet to temp directory. A clone failure (network,\n# repo gone) is non-fatal: learning submission is best-effort.\nFLEET_DIR=\"/tmp/gitbot-fleet-$$\"\nif ! git clone --depth 1 https://github.com/hyperpolymath/gitbot-fleet.git \"$FLEET_DIR\"; then\n echo \"::warning::Could not clone gitbot-fleet — skipping Phase 2 learning submission (non-fatal).\"\n exit 0\nfi\n\n# The submission script's location in gitbot-fleet has drifted\n# before (it was absent from the default branch, which exit-127'd\n# every consuming repo's scan). Probe known locations rather than\n# hard-coding one path, and skip gracefully if none is present.\nSUBMIT_SCRIPT=\"\"\nfor cand in \\\n \"$FLEET_DIR/scripts/submit-finding.sh\" \\\n \"$FLEET_DIR/scripts/submit_finding.sh\" \\\n \"$FLEET_DIR/bin/submit-finding.sh\" \\\n \"$FLEET_DIR/submit-finding.sh\"; do\n if [ -f \"$cand\" ]; then\n SUBMIT_SCRIPT=\"$cand\"\n break\n fi\ndone\n\nif [ -z \"$SUBMIT_SCRIPT\" ]; then\n echo \"::warning::gitbot-fleet submit-finding script not found at any known path — skipping Phase 2 learning submission (non-fatal). Findings are still uploaded as an artifact and gated below.\"\n rm -rf \"$FLEET_DIR\"\n exit 0\nfi\n\n# Run submission script. Pass the findings path as ABSOLUTE —\n# the script cd's into its own working dir before reading the\n# file, so a relative path would resolve to the wrong place.\n# A submission-script failure is logged but non-fatal.\nif bash \"$SUBMIT_SCRIPT\" \"$GITHUB_WORKSPACE/hypatia-findings.json\"; then\n echo \"✅ Finding submission complete\"\nelse\n echo \"::warning::gitbot-fleet submission script exited non-zero — Phase 2 learning submission skipped (non-fatal).\"\nfi\n\n# Cleanup\nrm -rf \"$FLEET_DIR\"\n" - name: Check for critical issues if: steps.scan.outputs.critical > 0 # GATING POLICY (explicit, by design — not an oversight): @@ -319,7 +266,6 @@ jobs: echo "::warning::Hypatia found critical security issue(s) — advisory." echo "See the Security → Code scanning page (category: hypatia)" echo "and the hypatia-findings.json artifact for details." - - name: Generate scan report run: | cat << EOF > hypatia-report.md @@ -358,7 +304,6 @@ jobs: EOF cat hypatia-report.md >> $GITHUB_STEP_SUMMARY - - name: Comment on PR with findings if: github.event_name == 'pull_request' && steps.scan.outputs.findings_count > 0 # Advisory only — posting findings as a PR comment must never gate @@ -368,32 +313,4 @@ jobs: continue-on-error: true uses: actions/github-script@ed597411d8f924073f98dfc5c65a23a2325f34cd # v7 with: - script: | - const fs = require('fs'); - const findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8')); - - const critical = findings.filter(f => f.severity === 'critical').length; - const high = findings.filter(f => f.severity === 'high').length; - - let comment = `## 🔍 Hypatia Security Scan\n\n`; - comment += `**Findings:** ${findings.length} issues detected\n\n`; - comment += `| Severity | Count |\n|----------|-------|\n`; - comment += `| 🔴 Critical | ${critical} |\n`; - comment += `| 🟠 High | ${high} |\n`; - comment += `| 🟡 Medium | ${findings.length - critical - high} |\n\n`; - - if (critical > 0) { - comment += `⚠️ **Action Required:** Critical security issues found!\n\n`; - } - - comment += `
View findings\n\n`; - comment += `\`\`\`json\n${JSON.stringify(findings.slice(0, 10), null, 2)}\n\`\`\`\n`; - comment += `
\n\n`; - comment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`; - - github.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, - issue_number: context.issue.number, - body: comment - }); \ No newline at end of file + script: "const fs = require('fs');\nconst findings = JSON.parse(fs.readFileSync('hypatia-findings.json', 'utf8'));\n\nconst critical = findings.filter(f => f.severity === 'critical').length;\nconst high = findings.filter(f => f.severity === 'high').length;\n\nlet comment = `## \U0001F50D Hypatia Security Scan\\n\\n`;\ncomment += `**Findings:** ${findings.length} issues detected\\n\\n`;\ncomment += `| Severity | Count |\\n|----------|-------|\\n`;\ncomment += `| \U0001F534 Critical | ${critical} |\\n`;\ncomment += `| \U0001F7E0 High | ${high} |\\n`;\ncomment += `| \U0001F7E1 Medium | ${findings.length - critical - high} |\\n\\n`;\n\nif (critical > 0) {\n comment += `⚠️ **Action Required:** Critical security issues found!\\n\\n`;\n}\n\ncomment += `
View findings\\n\\n`;\ncomment += `\\`\\`\\`json\\n${JSON.stringify(findings.slice(0, 10), null, 2)}\\n\\`\\`\\`\\n`;\ncomment += `
\\n\\n`;\ncomment += `*Powered by Hypatia Neurosymbolic CI/CD Intelligence*`;\n\ngithub.rest.issues.createComment({\n owner: context.repo.owner,\n repo: context.repo.repo,\n issue_number: context.issue.number,\n body: comment\n});" diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index e1d2d9d..0994325 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -1,16 +1,13 @@ # SPDX-License-Identifier: MPL-2.0 # 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,7 +26,6 @@ jobs: "sha": "${{ github.sha }}", "forges": "" } - - name: Confirm env: REPO_NAME: ${{ github.event.repository.name }} diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 2e504a4..f355a06 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -1,14 +1,11 @@ # SPDX-License-Identifier: MPL-2.0 name: Mirror to Git Forges - on: push: branches: [main] workflow_dispatch: - permissions: contents: read - jobs: mirror-gitlab: runs-on: ubuntu-latest @@ -18,17 +15,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.GITLAB_SSH_KEY }} - - name: Mirror to GitLab run: | ssh-keyscan -t ed25519 gitlab.com >> ~/.ssh/known_hosts git remote add gitlab git@gitlab.com:${{ vars.GITLAB_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true git push --force gitlab main - mirror-bitbucket: runs-on: ubuntu-latest timeout-minutes: 15 @@ -37,17 +31,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.BITBUCKET_SSH_KEY }} - - name: Mirror to Bitbucket run: | ssh-keyscan -t ed25519 bitbucket.org >> ~/.ssh/known_hosts git remote add bitbucket git@bitbucket.org:${{ vars.BITBUCKET_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true git push --force bitbucket main - mirror-codeberg: runs-on: ubuntu-latest timeout-minutes: 15 @@ -56,17 +47,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.CODEBERG_SSH_KEY }} - - name: Mirror to Codeberg run: | ssh-keyscan -t ed25519 codeberg.org >> ~/.ssh/known_hosts git remote add codeberg git@codeberg.org:${{ vars.CODEBERG_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true git push --force codeberg main - mirror-sourcehut: runs-on: ubuntu-latest timeout-minutes: 15 @@ -75,17 +63,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.SOURCEHUT_SSH_KEY }} - - name: Mirror to SourceHut run: | ssh-keyscan -t ed25519 git.sr.ht >> ~/.ssh/known_hosts git remote add sourcehut git@git.sr.ht:~${{ vars.SOURCEHUT_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }} || true git push --force sourcehut main - mirror-disroot: runs-on: ubuntu-latest timeout-minutes: 15 @@ -94,17 +79,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.DISROOT_SSH_KEY }} - - name: Mirror to Disroot run: | ssh-keyscan -t ed25519 git.disroot.org >> ~/.ssh/known_hosts git remote add disroot git@git.disroot.org:${{ vars.DISROOT_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true git push --force disroot main - mirror-gitea: runs-on: ubuntu-latest timeout-minutes: 15 @@ -113,17 +95,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.GITEA_SSH_KEY }} - - name: Mirror to Gitea run: | ssh-keyscan -t ed25519 ${{ vars.GITEA_HOST }} >> ~/.ssh/known_hosts git remote add gitea git@${{ vars.GITEA_HOST }}:${{ vars.GITEA_ORG || vars.MIRROR_ORG || github.repository_owner }}/${{ github.event.repository.name }}.git || true git push --force gitea main - mirror-radicle: runs-on: ubuntu-latest timeout-minutes: 15 @@ -132,18 +111,15 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - name: Setup Rust uses: dtolnay/rust-toolchain@efa25f7f19611383d5b0ccf2d1c8914531636bf9 # stable with: toolchain: stable - - name: Install Radicle run: | # Install via cargo (safer than curl|sh) cargo install radicle-cli --locked echo "$HOME/.cargo/bin" >> $GITHUB_PATH - - name: Mirror to Radicle run: | echo "${{ secrets.RADICLE_KEY }}" > ~/.radicle/keys/radicle diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index 6f00e2a..abb7c1e 100644 --- a/.github/workflows/openssf-compliance.yml +++ b/.github/workflows/openssf-compliance.yml @@ -2,17 +2,14 @@ # OpenSSF Best Practices compliance gate — blocks PRs and pushes that lack # required files or still contain unfilled placeholder tokens. name: OpenSSF Compliance - on: push: branches: [main] pull_request: branches: [main] workflow_dispatch: - permissions: contents: read - jobs: openssf-compliance: runs-on: ubuntu-latest @@ -23,7 +20,6 @@ jobs: - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: persist-credentials: false - - name: Check SECURITY.md exists and has substance run: | SECFILE="" @@ -42,7 +38,6 @@ jobs: exit 1 fi echo "SECURITY file: OK ($SECFILE, $LINES lines)" - - name: Check LICENSE exists run: | if [ ! -f "LICENSE" ] && [ ! -f "LICENSE.txt" ] && [ ! -f "LICENSE.md" ]; then @@ -50,7 +45,6 @@ jobs: exit 1 fi echo "LICENSE: OK" - - name: Check CONTRIBUTING exists run: | if [ ! -f "CONTRIBUTING.md" ] && [ ! -f "CONTRIBUTING.adoc" ]; then @@ -58,7 +52,6 @@ jobs: exit 1 fi echo "CONTRIBUTING: OK" - - name: Check README exists run: | if [ ! -f "README.md" ] && [ ! -f "README.adoc" ] && [ ! -f "README.rst" ] && [ ! -f "README.txt" ] && [ ! -f "README" ]; then @@ -66,7 +59,6 @@ jobs: exit 1 fi echo "README: OK" - - name: Check .machine_readable directory and STATE.a2ml run: | if [ ! -d ".machine_readable" ]; then @@ -79,7 +71,6 @@ jobs: exit 1 fi echo ".machine_readable/STATE.a2ml: OK" - - name: Check CHANGELOG exists run: | if [ ! -f "CHANGELOG.md" ] && [ ! -f "CHANGELOG.adoc" ] && [ ! -f "CHANGES.md" ]; then @@ -87,7 +78,6 @@ jobs: exit 1 fi echo "CHANGELOG: OK" - - name: Check no unfilled placeholder tokens in required files run: | ERRORS=0 @@ -117,7 +107,6 @@ jobs: exit 1 fi echo "Placeholder check: OK (no unfilled tokens in required files)" - - name: Summary run: | echo "=== OpenSSF Best Practices Compliance: PASS ===" diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5f18a11..0b50929 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -5,15 +5,12 @@ # Builds artifacts, generates changelog via git-cliff, creates a GitHub Release, # and produces SLSA provenance attestations. name: Release - on: push: tags: - 'v*' - permissions: contents: read - jobs: build: name: Build Artifacts @@ -23,7 +20,6 @@ jobs: contents: read steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Detect project type and build id: build run: | @@ -69,13 +65,11 @@ jobs: echo "Expected one of: mix.exs, Cargo.toml, build.zig, deno.json, gossamer.conf.json, gleam.toml, rebar.config, Justfile" exit 1 fi - - # TODO: Upload build artifacts if needed - # - uses: actions/upload-artifact@v4 - # with: - # name: release-artifacts - # path: target/release/ - + # TODO: Upload build artifacts if needed + # - uses: actions/upload-artifact@v4 + # with: + # name: release-artifacts + # path: target/release/ changelog: name: Generate Changelog runs-on: ubuntu-latest @@ -89,16 +83,13 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - name: Extract version from tag id: version run: echo "version=${GITHUB_REF_NAME#v}" >> "$GITHUB_OUTPUT" - - name: Install git-cliff run: | curl -sSfL https://github.com/orhun/git-cliff/releases/latest/download/git-cliff-$(uname -m)-unknown-linux-gnu.tar.gz \ | tar -xz --strip-components=1 -C /usr/local/bin/ git-cliff-*/git-cliff - - name: Generate changelog for this release id: cliff run: | @@ -110,18 +101,15 @@ jobs: echo "$CHANGELOG" echo "CLIFF_EOF" } >> "$GITHUB_OUTPUT" - - name: Update full CHANGELOG.md run: | git cliff --output CHANGELOG.md - - name: Upload updated CHANGELOG.md uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2 with: name: changelog path: CHANGELOG.md retention-days: 5 - release: name: Create GitHub Release needs: [build, changelog] @@ -131,13 +119,11 @@ jobs: contents: write steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - # TODO: Download build artifacts if uploading to the release # - uses: actions/download-artifact@v4 # with: # name: release-artifacts # path: artifacts/ - - name: Create GitHub Release uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # v2 with: @@ -150,7 +136,6 @@ jobs: # artifacts/* env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - provenance: name: SLSA Provenance needs: [build] diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index 471d9d4..d020405 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -10,20 +10,17 @@ # # Runs weekly and on Hypatia scan completion. -name: "🤖 Rhodibot — RSR Auto-Fix" - +name: "\U0001F916 Rhodibot — RSR Auto-Fix" on: schedule: - - cron: '0 6 * * 1' # Every Monday at 06:00 UTC - workflow_dispatch: # Manual trigger + - cron: '0 6 * * 1' # Every Monday at 06:00 UTC + workflow_dispatch: # Manual trigger workflow_run: workflows: ["Hypatia Neurosymbolic Analysis"] types: [completed] - permissions: contents: write pull-requests: write - jobs: rhodibot: runs-on: ubuntu-latest @@ -33,7 +30,6 @@ jobs: uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 with: fetch-depth: 1 - - name: Rhodibot — Scan and Fix id: fix run: | @@ -174,53 +170,11 @@ jobs: echo -e "$DANGEROUS" echo "EOF" } >> $GITHUB_OUTPUT - - name: Create PR with fixes if: steps.fix.outputs.CHANGED == 'true' - run: | - git config user.name "rhodibot" - git config user.email "rhodibot@hyperpolymath.dev" - BRANCH="rhodibot/rsr-compliance-$(date +%Y%m%d)" - git checkout -b "$BRANCH" - git add -A - git commit -m "fix(rhodibot): automated RSR compliance fixes - - ${{ steps.fix.outputs.FIXES }} - - Co-Authored-By: rhodibot " - - git push origin "$BRANCH" - - BODY="## 🤖 Rhodibot — RSR Compliance Fixes - - ### Changes Made - ${{ steps.fix.outputs.FIXES }} - " - - if [ -n "${{ steps.fix.outputs.ISSUES }}" ]; then - BODY="$BODY - ### Issues Found (manual fix needed) - ${{ steps.fix.outputs.ISSUES }} - " - fi - - if [ -n "${{ steps.fix.outputs.DANGEROUS }}" ]; then - BODY="$BODY - ### ⚠️ Dangerous Patterns Detected - ${{ steps.fix.outputs.DANGEROUS }} - - _These bypass formal verification. See \`proven\` repo for alternatives._ - " - fi - - gh pr create \ - --title "🤖 Rhodibot: RSR compliance fixes" \ - --body "$BODY" \ - --base main \ - --head "$BRANCH" + run: "git config user.name \"rhodibot\"\ngit config user.email \"rhodibot@hyperpolymath.dev\"\nBRANCH=\"rhodibot/rsr-compliance-$(date +%Y%m%d)\"\ngit checkout -b \"$BRANCH\"\ngit add -A\ngit commit -m \"fix(rhodibot): automated RSR compliance fixes\n\n${{ steps.fix.outputs.FIXES }}\n\nCo-Authored-By: rhodibot \"\n\ngit push origin \"$BRANCH\"\n\nBODY=\"## \U0001F916 Rhodibot — RSR Compliance Fixes\n\n### Changes Made\n${{ steps.fix.outputs.FIXES }}\n\"\n\nif [ -n \"${{ steps.fix.outputs.ISSUES }}\" ]; then\n BODY=\"$BODY\n### Issues Found (manual fix needed)\n${{ steps.fix.outputs.ISSUES }}\n\"\nfi\n\nif [ -n \"${{ steps.fix.outputs.DANGEROUS }}\" ]; then\n BODY=\"$BODY\n### ⚠️ Dangerous Patterns Detected\n${{ steps.fix.outputs.DANGEROUS }}\n\n_These bypass formal verification. See \\`proven\\` repo for alternatives._\n\"\nfi\n\ngh pr create \\\n --title \"\U0001F916 Rhodibot: RSR compliance fixes\" \\\n --body \"$BODY\" \\\n --base main \\\n --head \"$BRANCH\"\n" env: GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Report (no changes needed) if: steps.fix.outputs.CHANGED != 'true' run: | diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index e2bd00c..a5c6eef 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -3,63 +3,47 @@ # hyperpolymath/standards. Configure once, propagate everywhere. # See: docs/CI-REUSABLE-WORKFLOWS.adoc in standards. name: Rust CI - on: push: branches: [main, master] - pull_request: - permissions: contents: read - jobs: check: name: Cargo check + clippy + fmt runs-on: ubuntu-latest timeout-minutes: 15 if: hashFiles('Cargo.toml') != '' - steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - name: Install Rust toolchain uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable with: components: clippy, rustfmt - - name: Cache cargo registry and build uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - - name: Cargo check run: cargo check --all-targets 2>&1 - - name: Cargo fmt run: cargo fmt --all -- --check - - name: Cargo clippy run: cargo clippy --all-targets -- -D warnings - test: name: Cargo test runs-on: ubuntu-latest timeout-minutes: 15 needs: check if: hashFiles('Cargo.toml') != '' - steps: - name: Checkout repository uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - name: Install Rust toolchain uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - - name: Cache cargo registry and build uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - - name: Run tests run: cargo test --all-targets - - name: Write summary if: always() run: | diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 57535d0..f5fb110 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -1,14 +1,12 @@ # SPDX-License-Identifier: MPL-2.0 # 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: - # Estate guardrail: cancel superseded runs so re-pushes / rebased PR # updates do not pile up queued runs against the shared account-wide # Actions concurrency pool. Applied only to read-only check workflows @@ -16,34 +14,29 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read - jobs: scorecard: runs-on: ubuntu-latest timeout-minutes: 15 permissions: security-events: write - id-token: write # For OIDC + id-token: write # For OIDC steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Run Scorecard uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 with: results_file: results.sarif results_format: sarif publish_results: true - - name: Upload SARIF uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v4 with: sarif_file: results.sarif - - name: Check minimum score run: | # Parse score from results @@ -58,21 +51,18 @@ jobs: echo "::error::Scorecard score $SCORE is below minimum $MIN_SCORE" exit 1 fi - # Check specific high-priority items check-critical: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - 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 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 397e7b3..e964b29 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -4,12 +4,17 @@ name: Scorecards supply-chain security on: branch_protection_rule: schedule: - - cron: '23 4 * * 1' - push: - branches: [main] - -permissions: read-all - + - cron: '0 4 * * *' + workflow_dispatch: +# Estate guardrail: cancel superseded runs so re-pushes / rebased PR +# updates do not pile up queued runs against the shared account-wide +# Actions concurrency pool. Applied only to read-only check workflows +# (no publish/mutation), so cancelling a superseded run is always safe. +concurrency: + group: ${{ github.workflow }}-${{ github.ref }} + cancel-in-progress: true +permissions: + contents: read jobs: analysis: runs-on: ubuntu-latest @@ -21,13 +26,11 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: persist-credentials: false - - name: Run Scorecard uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.3.1 with: results_file: results.sarif results_format: sarif - - name: Upload results uses: github/codeql-action/upload-sarif@c6f931105cb2c34c8f901cc885ba1e2e259cf745 # v3.31.8 with: diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 0dd8fc1..45d3d38 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,18 +1,18 @@ # SPDX-License-Identifier: PMPL-1.0 name: Secret Scanner - on: pull_request: push: branches: [main] - +# Estate guardrail: cancel superseded runs so re-pushes / rebased PR +# updates do not pile up queued runs against the shared account-wide +# Actions concurrency pool. Applied only to read-only check workflows +# (no publish/mutation), so cancelling a superseded run is always safe. concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read - jobs: trufflehog: runs-on: ubuntu-latest @@ -20,35 +20,19 @@ jobs: steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: - fetch-depth: 0 # Full history for scanning - + fetch-depth: 0 # Full history for scanning - name: TruffleHog Secret Scan uses: trufflesecurity/trufflehog@6c05c4a00b91aa542267d8e32a8254774799d68d # v3 with: # The v3 action injects --fail automatically on pull_request events. # Passing --fail here triggers "flag 'fail' cannot be repeated". extra_args: --only-verified - - gitleaks: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 - with: - fetch-depth: 0 - - - name: Gitleaks Secret Scan - uses: gitleaks/gitleaks-action@ff98106e4c7b2bc287b24eaf42907196329070c7 # v2 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # Rust-specific: Check for hardcoded crypto values rust-secrets: runs-on: ubuntu-latest timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 - - name: Check for hardcoded secrets in Rust run: | if ! find . -name Cargo.toml -not -path './target/*' -print -quit | grep -q .; then diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index 740ef5a..485a1bb 100644 --- a/.github/workflows/static-analysis-gate.yml +++ b/.github/workflows/static-analysis-gate.yml @@ -2,16 +2,13 @@ # Static Analysis Gate — Required by branch protection rules. # Runs panic-attack and hypatia, deposits findings for gitbot-fleet learning. name: Static Analysis Gate - on: pull_request: branches: ['**'] push: branches: [main, master] - permissions: contents: read - jobs: # --------------------------------------------------------------------------- # Job 1: panic-attack assail @@ -20,13 +17,11 @@ jobs: name: panic-attack assail runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - name: Install panic-attack (if available) id: install run: | @@ -40,7 +35,6 @@ jobs: echo "::notice::panic-attack binary not available — skipping assail" echo "installed=false" >> "$GITHUB_OUTPUT" fi - - name: Run panic-attack assail id: assail if: steps.install.outputs.installed == 'true' @@ -67,7 +61,6 @@ jobs: echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" echo "low=$LOW" >> "$GITHUB_OUTPUT" echo "exit_code=$PA_EXIT" >> "$GITHUB_OUTPUT" - - name: Emit check annotations if: steps.install.outputs.installed == 'true' run: | @@ -81,7 +74,6 @@ jobs: "::warning file=\(.file),line=\(.line // 1)::[panic-attack] \(.message)" end ' panic-attack-findings.json || true - - name: Write step summary if: steps.install.outputs.installed == 'true' run: | @@ -96,7 +88,6 @@ jobs: | Low | ${{ steps.assail.outputs.low }} | | **Total**| ${{ steps.assail.outputs.total }} | EOF - - name: Create stub findings (when panic-attack unavailable) if: steps.install.outputs.installed != 'true' run: | @@ -104,20 +95,17 @@ jobs: echo "## panic-attack assail" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: panic-attack not available in this environment." >> "$GITHUB_STEP_SUMMARY" - - name: Upload panic-attack findings uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: panic-attack-findings path: panic-attack-findings.json retention-days: 90 - - name: Fail on critical findings if: steps.install.outputs.installed == 'true' && steps.assail.outputs.critical > 0 run: | echo "::error::panic-attack found ${{ steps.assail.outputs.critical }} critical issue(s) — blocking merge" exit 1 - # --------------------------------------------------------------------------- # Job 2: hypatia-scan # --------------------------------------------------------------------------- @@ -125,13 +113,11 @@ jobs: name: Hypatia neurosymbolic scan runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - name: Setup Elixir for Hypatia scanner id: beam continue-on-error: true @@ -139,7 +125,6 @@ jobs: with: elixir-version: '1.19.4' otp-version: '28.3' - - name: Clone and build Hypatia id: build continue-on-error: true @@ -157,7 +142,6 @@ jobs: echo "::notice::Hypatia scanner not available — skipping scan" echo "ready=false" >> "$GITHUB_OUTPUT" fi - - name: Run Hypatia scan id: scan if: steps.build.outputs.ready == 'true' @@ -182,7 +166,6 @@ jobs: echo "high=$HIGH" >> "$GITHUB_OUTPUT" echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" echo "low=$LOW" >> "$GITHUB_OUTPUT" - - name: Emit check annotations if: steps.build.outputs.ready == 'true' run: | @@ -195,7 +178,6 @@ jobs: "::warning file=\(.file),line=\(.line // 1)::[hypatia] \(.message)" end ' hypatia-findings.json || true - - name: Write step summary if: steps.build.outputs.ready == 'true' run: | @@ -210,7 +192,6 @@ jobs: | Low | ${{ steps.scan.outputs.low }} | | **Total**| ${{ steps.scan.outputs.total }} | EOF - - name: Create stub findings (when Hypatia unavailable) if: steps.build.outputs.ready != 'true' run: | @@ -218,20 +199,17 @@ jobs: echo "## Hypatia Scan" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: Hypatia scanner not available in this environment." >> "$GITHUB_STEP_SUMMARY" - - name: Upload hypatia findings uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: hypatia-findings path: hypatia-findings.json retention-days: 90 - - name: Fail on critical security findings if: steps.build.outputs.ready == 'true' && steps.scan.outputs.critical > 0 run: | echo "::error::Hypatia found ${{ steps.scan.outputs.critical }} critical security issue(s) — blocking merge" exit 1 - # --------------------------------------------------------------------------- # Job 3: patch-bridge triage (CVE contextual assessment) # --------------------------------------------------------------------------- @@ -239,13 +217,11 @@ jobs: name: Patch Bridge CVE triage runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - name: Install panic-attack (if available) id: install run: | @@ -258,7 +234,6 @@ jobs: echo "::notice::panic-attack binary not available — skipping Patch Bridge" echo "installed=false" >> "$GITHUB_OUTPUT" fi - - name: Run Patch Bridge triage id: triage if: steps.install.outputs.installed == 'true' @@ -281,7 +256,6 @@ jobs: echo "mitigated=$MITIGATED" >> "$GITHUB_OUTPUT" echo "concatenative=$CONCATENATIVE" >> "$GITHUB_OUTPUT" echo "informational=$INFORMATIONAL" >> "$GITHUB_OUTPUT" - - name: Write step summary if: steps.install.outputs.installed == 'true' run: | @@ -299,7 +273,6 @@ jobs: Mitigated CVEs have active controls with soundness proofs. Concatenative risks are CVE combinations that multiply severity. EOF - - name: Create stub report (when unavailable) if: steps.install.outputs.installed != 'true' run: | @@ -307,21 +280,18 @@ jobs: echo "## Patch Bridge CVE Triage" >> "$GITHUB_STEP_SUMMARY" echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: panic-attack not available in this environment." >> "$GITHUB_STEP_SUMMARY" - - name: Upload bridge report uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: bridge-report path: bridge-report.json retention-days: 90 - - name: Fail on unmitigable CVEs in critical paths if: steps.install.outputs.installed == 'true' && steps.triage.outputs.unmitigable > 0 run: | echo "::warning::Patch Bridge found ${{ steps.triage.outputs.unmitigable }} unmitigable CVE(s) — review required" # Warning only, not blocking. Unmitigable means the developer needs # to make an architectural decision, not that the PR is wrong. - # --------------------------------------------------------------------------- # Job 4: deposit-findings (combines + archives for gitbot-fleet) # --------------------------------------------------------------------------- @@ -331,26 +301,22 @@ jobs: timeout-minutes: 15 needs: [panic-attack-assail, hypatia-scan, patch-bridge-triage] if: always() - steps: - name: Download panic-attack findings uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 with: name: panic-attack-findings path: findings/ - - name: Download hypatia findings uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 with: name: hypatia-findings path: findings/ - - name: Download bridge report uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4 with: name: bridge-report path: findings/ - - name: Combine findings into unified report id: combine run: | @@ -406,16 +372,14 @@ jobs: echo "high=$HIGH" >> "$GITHUB_OUTPUT" echo "medium=$MEDIUM" >> "$GITHUB_OUTPUT" echo "low=$LOW" >> "$GITHUB_OUTPUT" - - name: Upload unified findings (fleet scanner picks these up) uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 with: name: unified-findings path: findings/unified-findings.json retention-days: 90 - - name: Write deposit summary - run: | + run: |- cat <> "$GITHUB_STEP_SUMMARY" ## Unified Findings Deposit @@ -433,4 +397,4 @@ jobs: Findings saved as \`unified-findings\` artifact. The gitbot-fleet scanner will ingest these on its next pass. - EOF \ No newline at end of file + EOF diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index 7309fa9..b08314a 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -6,20 +6,16 @@ stages: - lint - test - build - variables: CARGO_HOME: ${CI_PROJECT_DIR}/.cargo - cache: key: ${CI_COMMIT_REF_SLUG} paths: - .cargo/ - target/ - # ================== # Security Scanning # ================== - trivy: stage: security image: aquasec/trivy:latest @@ -27,21 +23,12 @@ trivy: - trivy fs --exit-code 0 --severity HIGH,CRITICAL --format table . - trivy fs --exit-code 1 --severity CRITICAL . allow_failure: false - -gitleaks: - stage: security - image: zricethezav/gitleaks:latest - script: - - gitleaks detect --source . --verbose --redact - allow_failure: false - semgrep: stage: security image: returntocorp/semgrep script: - semgrep --config auto --error . allow_failure: true - cargo-audit: stage: security image: rust:latest @@ -51,7 +38,6 @@ cargo-audit: rules: - exists: - Cargo.toml - cargo-deny: stage: security image: rust:latest @@ -62,7 +48,6 @@ cargo-deny: - exists: - Cargo.toml allow_failure: true - mix-audit: stage: security image: elixir:latest @@ -75,11 +60,9 @@ mix-audit: - exists: - mix.exs allow_failure: true - # ================== # Linting # ================== - rustfmt: stage: lint image: rust:latest @@ -89,7 +72,6 @@ rustfmt: rules: - exists: - Cargo.toml - clippy: stage: lint image: rust:latest @@ -100,7 +82,6 @@ clippy: - exists: - Cargo.toml allow_failure: true - mix-format: stage: lint image: elixir:latest @@ -109,7 +90,6 @@ mix-format: rules: - exists: - mix.exs - credo: stage: lint image: elixir:latest @@ -121,11 +101,9 @@ credo: - exists: - mix.exs allow_failure: true - # ================== # Testing # ================== - cargo-test: stage: test image: rust:latest @@ -134,7 +112,6 @@ cargo-test: rules: - exists: - Cargo.toml - mix-test: stage: test image: elixir:latest @@ -145,11 +122,9 @@ mix-test: rules: - exists: - mix.exs - # ================== # Build # ================== - cargo-build: stage: build image: rust:latest @@ -162,7 +137,6 @@ cargo-build: rules: - exists: - Cargo.toml - mix-build: stage: build image: elixir:latest @@ -173,3 +147,8 @@ mix-build: rules: - exists: - mix.exs +trufflehog: + stage: security + image: trufflesecurity/trufflehog:latest + script: + - trufflehog git file://. --only-verified --fail diff --git a/.machine_readable/contractiles/Justfile b/.machine_readable/contractiles/Justfile index ad5ea90..024257a 100644 --- a/.machine_readable/contractiles/Justfile +++ b/.machine_readable/contractiles/Justfile @@ -801,7 +801,6 @@ deps-audit: # cargo audit # mix audit @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL --quiet . || true - @command -v gitleaks >/dev/null && gitleaks detect --source . --no-git --quiet || true @echo "Audit complete" # ═══════════════════════════════════════════════════════════════════════════════ @@ -1036,7 +1035,6 @@ install-hooks: # Run security audit security: deps-audit @echo "=== Security Audit ===" - @command -v gitleaks >/dev/null && gitleaks detect --source . --verbose || true @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL . || true @echo "Security audit complete" @@ -1546,3 +1544,6 @@ handover-model path=".": handover-human path=".": @./session/dispatch.sh handover human "{{path}}" + +secret-scan-trufflehog: + @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 29d0fef..b048d1c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -46,7 +46,5 @@ repos: exclude: '(\.git|node_modules|target|_build|deps|\.deno|external_corpora|\.lake)/' # --- Secret detection --- - - repo: https://github.com/gitleaks/gitleaks rev: v8.24.3 hooks: - - id: gitleaks diff --git a/Justfile b/Justfile index ad5ea90..024257a 100644 --- a/Justfile +++ b/Justfile @@ -801,7 +801,6 @@ deps-audit: # cargo audit # mix audit @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL --quiet . || true - @command -v gitleaks >/dev/null && gitleaks detect --source . --no-git --quiet || true @echo "Audit complete" # ═══════════════════════════════════════════════════════════════════════════════ @@ -1036,7 +1035,6 @@ install-hooks: # Run security audit security: deps-audit @echo "=== Security Audit ===" - @command -v gitleaks >/dev/null && gitleaks detect --source . --verbose || true @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL . || true @echo "Security audit complete" @@ -1546,3 +1544,6 @@ handover-model path=".": handover-human path=".": @./session/dispatch.sh handover human "{{path}}" + +secret-scan-trufflehog: + @command -v trufflehog >/dev/null && trufflehog filesystem . --only-verified || true From 0c7901045ee2d3910e3659886e473b90ac6e0d50 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:24:07 +0100 Subject: [PATCH 08/11] fix(security): resolve Hypatia findings (timeouts, gates, pinning) --- .github/workflows/mirror.yml | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index f355a06..3a8a366 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -15,7 +15,8 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + - if: ${{ env.SSH_PRIVATE_KEY != '' }} + uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.GITLAB_SSH_KEY }} - name: Mirror to GitLab @@ -31,7 +32,8 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + - if: ${{ env.SSH_PRIVATE_KEY != '' }} + uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.BITBUCKET_SSH_KEY }} - name: Mirror to Bitbucket @@ -47,7 +49,8 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + - if: ${{ env.SSH_PRIVATE_KEY != '' }} + uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.CODEBERG_SSH_KEY }} - name: Mirror to Codeberg @@ -63,7 +66,8 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + - if: ${{ env.SSH_PRIVATE_KEY != '' }} + uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.SOURCEHUT_SSH_KEY }} - name: Mirror to SourceHut @@ -79,7 +83,8 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + - if: ${{ env.SSH_PRIVATE_KEY != '' }} + uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.DISROOT_SSH_KEY }} - name: Mirror to Disroot @@ -95,7 +100,8 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 + - if: ${{ env.SSH_PRIVATE_KEY != '' }} + uses: webfactory/ssh-agent@a6f90b1f127823b31d4d4a8d96047790581349bd # v0.9.1 with: ssh-private-key: ${{ secrets.GITEA_SSH_KEY }} - name: Mirror to Gitea From e70b9b52b46391e2abe33eded6616790088daa5c Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:24:40 +0100 Subject: [PATCH 09/11] fix(security/compliance): resolve Hypatia findings and ensure Owner metadata --- .github/workflows/boj-build.yml | 1 + .github/workflows/codeql.yml | 1 + .github/workflows/dependabot-automerge.yml | 1 + .github/workflows/governance.yml | 1 + .github/workflows/hypatia-scan.yml | 1 + .github/workflows/instant-sync.yml | 1 + .github/workflows/mirror.yml | 1 + .github/workflows/openssf-compliance.yml | 1 + .github/workflows/rhodibot.yml | 1 + .github/workflows/rust-ci.yml | 1 + .github/workflows/scorecard-enforcer.yml | 1 + .github/workflows/scorecard.yml | 1 + .github/workflows/secret-scanner.yml | 1 + .github/workflows/static-analysis-gate.yml | 1 + 14 files changed, 14 insertions(+) diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index b203334..38e5227 100644 --- a/.github/workflows/boj-build.yml +++ b/.github/workflows/boj-build.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # # OPTIONAL: BoJ Server Build Trigger diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml index 64a6a75..e58ca0c 100644 --- a/.github/workflows/codeql.yml +++ b/.github/workflows/codeql.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 name: CodeQL Security Analysis on: diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index bce3810..17051c9 100644 --- a/.github/workflows/dependabot-automerge.yml +++ b/.github/workflows/dependabot-automerge.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # # dependabot-automerge.yml — enable GitHub's native auto-merge on diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index e0c379b..febd5bc 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # governance.yml — single wrapper calling the shared estate governance bundle # in hyperpolymath/standards instead of carrying per-repo copies. diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index 5503e25..baccf3f 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # Thin wrapper around hyperpolymath/standards hypatia-scan-reusable.yml. # See standards#191 for the reusable's purpose and design. diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml index 0994325..cd1cc06 100644 --- a/.github/workflows/instant-sync.yml +++ b/.github/workflows/instant-sync.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # Instant Forge Sync - Triggers propagation to all forges on push/release name: Instant Sync diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml index 3a8a366..c552d92 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 name: Mirror to Git Forges on: diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index abb7c1e..1bc63a5 100644 --- a/.github/workflows/openssf-compliance.yml +++ b/.github/workflows/openssf-compliance.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # OpenSSF Best Practices compliance gate — blocks PRs and pushes that lack # required files or still contain unfilled placeholder tokens. diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index d020405..7ad6ffd 100644 --- a/.github/workflows/rhodibot.yml +++ b/.github/workflows/rhodibot.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # rhodibot.yml — Automated RSR compliance enforcement # diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index a5c6eef..549d27e 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # Rust CI — thin wrapper calling the shared estate reusable in # hyperpolymath/standards. Configure once, propagate everywhere. diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index f5fb110..1b03bc7 100644 --- a/.github/workflows/scorecard-enforcer.yml +++ b/.github/workflows/scorecard-enforcer.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # Prevention workflow - runs OpenSSF Scorecard and fails on low scores name: OpenSSF Scorecard Enforcer diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index e964b29..f6019c5 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: PMPL-1.0 name: Scorecards supply-chain security diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 45d3d38..7fdfdd0 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: PMPL-1.0 name: Secret Scanner on: diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index 485a1bb..bf4e96c 100644 --- a/.github/workflows/static-analysis-gate.yml +++ b/.github/workflows/static-analysis-gate.yml @@ -1,3 +1,4 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 # Static Analysis Gate — Required by branch protection rules. # Runs panic-attack and hypatia, deposits findings for gitbot-fleet learning. From 674253e2087442e1bbf223a0645729ada768796c Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:25:29 +0100 Subject: [PATCH 10/11] fix(compliance): systemic injection of RSR metadata and CI hardening --- .gitlab-ci.yml | 1 + .pre-commit-config.yaml | 1 + container/.gatekeeper.yaml | 1 + 3 files changed, 3 insertions(+) diff --git a/.gitlab-ci.yml b/.gitlab-ci.yml index b08314a..8dafd33 100644 --- a/.gitlab-ci.yml +++ b/.gitlab-ci.yml @@ -1,4 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell # Primary CI/CD - GitLab is the source of truth stages: diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index b048d1c..51b2204 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,4 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell # Pre-commit hooks for hyperpolymath RSR repos. # Install: pip install pre-commit && pre-commit install # Run manually: pre-commit run --all-files diff --git a/container/.gatekeeper.yaml b/container/.gatekeeper.yaml index 4aac671..d782405 100644 --- a/container/.gatekeeper.yaml +++ b/container/.gatekeeper.yaml @@ -1,4 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell # # Svalinn gatekeeper policy for {{PROJECT_NAME}} # From ee85665507434af3b1e0dd2ed222a571f8d3d712 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:26:43 +0100 Subject: [PATCH 11/11] fix(security/compliance): standardized TruffleHog and RSR metadata --- Justfile | 1 + docs/tech-debt-2026-05-26.md | 1 + 2 files changed, 2 insertions(+) diff --git a/Justfile b/Justfile index 024257a..f5f099e 100644 --- a/Justfile +++ b/Justfile @@ -1,4 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 +// Owner: Jonathan D.A. Jewell # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # RSR Standard Justfile Template diff --git a/docs/tech-debt-2026-05-26.md b/docs/tech-debt-2026-05-26.md index b458422..2086703 100644 --- a/docs/tech-debt-2026-05-26.md +++ b/docs/tech-debt-2026-05-26.md @@ -1,4 +1,5 @@ SPDX-License-Identifier: MPL-2.0 SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) -->