From baf3db32177502ddfbec602d6d100e7efd559e8d Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Tue, 26 May 2026 12:21:45 +0100 Subject: [PATCH 01/11] chore(fixtures): delete stale SafeDOMExample.res ReScript fixture (Refs gitbot-fleet#148, #208; affinescript#229) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Removes 1 copies of the stale SafeDOMExample.res ReScript fixture from this repo. One of 1,267 byte-clustered copies across the estate (129 repos). ReScript is fully banned in new code (2026-04-30 policy refresh). Current-grammar AffineScript replacement lives at gitbot-fleet/bots/*/examples/SafeDOMExample.affine (PR gitbot-fleet#210 MERGED). The example fixtures are not load-bearing — propagated from an earlier template-instantiation script. Refs hyperpolymath/gitbot-fleet#148, #208 Refs hyperpolymath/affinescript#57, #229 Co-Authored-By: Claude Opus 4.7 (1M context) --- examples/SafeDOMExample.res | 109 ------------------------------------ 1 file changed, 109 deletions(-) delete mode 100644 examples/SafeDOMExample.res diff --git a/examples/SafeDOMExample.res b/examples/SafeDOMExample.res deleted file mode 100644 index e5c9046..0000000 --- a/examples/SafeDOMExample.res +++ /dev/null @@ -1,109 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Example: Using SafeDOM for formally verified DOM mounting - -open SafeDOM - -// Example 1: Basic mounting with error handling -let mountApp = () => { - mountSafe( - "#app", - "

Hello, World!

Mounted safely with proofs.

", - ~onSuccess=el => { - Console.log("✓ App mounted successfully!") - Console.log("Element:", el) - }, - ~onError=err => { - Console.error("✗ Mount failed:", err) - } - ) -} - -// Example 2: Wait for DOM ready before mounting -let mountWhenDOMReady = () => { - mountWhenReady( - "#app", - "

App Title

", - ~onSuccess=_ => Console.log("✓ Mounted after DOM ready"), - ~onError=err => Console.error("✗ Failed:", err) - ) -} - -// Example 3: Batch mounting (atomic - all or nothing) -let mountMultiple = () => { - let specs = [ - {selector: "#header", html: "

Site Title

"}, - {selector: "#nav", html: ""}, - {selector: "#main", html: "

Content here

"}, - {selector: "#footer", html: ""} - ] - - switch mountBatch(specs) { - | Ok(elements) => { - Console.log(`✓ Successfully mounted ${Array.length(elements)} elements`) - elements->Array.forEach(el => Console.log(" -", el)) - } - | Error(err) => { - Console.error("✗ Batch mount failed:", err) - Console.error(" (None were mounted - atomic operation)") - } - } -} - -// Example 4: Explicit validation before mounting -let mountWithValidation = () => { - // Validate selector first - switch ProvenSelector.validate("#my-app") { - | Error(e) => Console.error(`Invalid selector: ${e}`) - | Ok(validSelector) => { - // Validate HTML - switch ProvenHTML.validate("
Content
") { - | Error(e) => Console.error(`Invalid HTML: ${e}`) - | Ok(validHtml) => { - // Now mount with proven safety - switch mount(validSelector, validHtml) { - | Mounted(el) => Console.log("✓ Mounted with validated inputs:", el) - | MountPointNotFound(s) => Console.error(`✗ Element not found: ${s}`) - | InvalidSelector(_) => Console.error("Impossible - already validated") - | InvalidHTML(_) => Console.error("Impossible - already validated") - } - } - } - } -} - -// Example 5: Integration with TEA -module MyApp = { - type model = {message: string} - type msg = NoOp - - let init = () => {message: "Hello from TEA"} - let update = (model, _msg) => model - let view = model => `

${model.message}

` -} - -let mountTEAApp = () => { - let model = MyApp.init() - let html = MyApp.view(model) - - mountWhenReady( - "#tea-app", - html, - ~onSuccess=el => { - Console.log("✓ TEA app mounted") - // Set up event handlers, subscriptions here - }, - ~onError=err => Console.error(`✗ TEA mount failed: ${err}`) - ) -} - -// Entry point -let main = () => { - Console.log("SafeDOM Examples") - Console.log("================\n") - - // Choose which example to run - mountWhenDOMReady() // Run on DOM ready -} - -// Auto-execute when module loads -main() From ded84fc230698eff8c9444076f5c04e9505c57c0 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 1 Jun 2026 00:58:07 +0100 Subject: [PATCH 02/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 af4138a..b811d8f 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 02f11068982cc6c82541733481181d57761fe138 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 17:47:43 +0100 Subject: [PATCH 03/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/ISSUE_TEMPLATE/bug_report.md | 4 + .github/ISSUE_TEMPLATE/custom.md | 4 + .github/ISSUE_TEMPLATE/feature_request.md | 4 + .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 | 5 + .github/workflows/governance.yml | 1 + .github/workflows/hypatia-scan.yml | 1 + .github/workflows/instant-sync.yml | 1 + .github/workflows/mirror.yml | 7 + .github/workflows/openssf-compliance.yml | 1 + .github/workflows/release.yml | 3 + .github/workflows/rhodibot.yml | 1 + .github/workflows/rust-ci.yml | 1 + .github/workflows/scorecard-enforcer.yml | 2 + .github/workflows/scorecard.yml | 1 + .github/workflows/secret-scanner.yml | 3 + .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/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 | 1 + .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 | 1 + .../burble-metadata.k9.ncl | 0 .../examples/ci-config.k9.ncl | 0 .../examples/project-metadata.k9.ncl | 0 .../examples/setup-repo.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 | 394 ++++++++++++++++-- PROOF-NEEDS.md | 5 +- PROOF-STATUS.md | 5 +- QUICKSTART-DEV.adoc | 1 + QUICKSTART-MAINTAINER.adoc | 1 + QUICKSTART-USER.adoc | 1 + READINESS.md | 5 +- README.adoc | 10 +- ROADMAP.adoc | 1 + SECURITY.md | 5 +- TEST-NEEDS.md | 4 + TOPOLOGY.md | 5 +- container/README.adoc | 2 +- docs/QUICKSTART.adoc | 2 + docs/README.adoc | 2 + docs/RSR_OUTLINE.adoc | 2 + 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/practice/ci-cost-reduction.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 + 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, 804 insertions(+), 62 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 (98%) rename .machine_readable/svc/{k9 => self-validating}/burble-metadata.k9.ncl (100%) 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 (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/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md index dd84ea7..15a8978 100644 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ b/.github/ISSUE_TEMPLATE/bug_report.md @@ -1,3 +1,7 @@ + --- name: Bug report about: Create a report to help us improve diff --git a/.github/ISSUE_TEMPLATE/custom.md b/.github/ISSUE_TEMPLATE/custom.md index 48d5f81..99ebf00 100644 --- a/.github/ISSUE_TEMPLATE/custom.md +++ b/.github/ISSUE_TEMPLATE/custom.md @@ -1,3 +1,7 @@ + --- name: Custom issue template about: Describe this issue template's purpose here. diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md index bbcbbe7..41a5455 100644 --- a/.github/ISSUE_TEMPLATE/feature_request.md +++ b/.github/ISSUE_TEMPLATE/feature_request.md @@ -1,3 +1,7 @@ + --- name: Feature request about: Suggest an idea for this project 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 b811d8f..01934ac 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 ca86baa..3d0e8de 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 15a30e3..c6b3dce 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: dogfood-summary: name: Dogfooding compliance summary runs-on: ubuntu-latest + timeout-minutes: 15 needs: [a2ml-validate, k9-validate, empty-lint, groove-check] 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 cd38e6c..5e7eddc 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -43,6 +43,7 @@ jobs: scan: name: Hypatia Neurosymbolic Analysis runs-on: ubuntu-latest + timeout-minutes: 15 steps: - name: Checkout repository 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 36d397e..f78fc86 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -13,6 +13,7 @@ permissions: jobs: mirror-gitlab: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.GITLAB_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -31,6 +32,7 @@ jobs: mirror-bitbucket: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.BITBUCKET_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -49,6 +51,7 @@ jobs: mirror-codeberg: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.CODEBERG_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -67,6 +70,7 @@ jobs: mirror-sourcehut: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.SOURCEHUT_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -85,6 +89,7 @@ jobs: mirror-disroot: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.DISROOT_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -103,6 +108,7 @@ jobs: mirror-gitea: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.GITEA_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 @@ -121,6 +127,7 @@ jobs: mirror-radicle: runs-on: ubuntu-latest + timeout-minutes: 15 if: vars.RADICLE_MIRROR_ENABLED == 'true' steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index 36b2a3f..e9d80bb 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 8d0af1d..1124210 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 8dd91ba..6c3025f 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 2de97c0..c83255d 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -15,3 +15,4 @@ permissions: jobs: rust-ci: uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@4fdf4314b4ab54269adbaff10e30e483b5e86845 + timeout-minutes: 10 diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 295e009..ab0b67a 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 dcf7caf..fe0e8de 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -21,6 +21,7 @@ permissions: jobs: analysis: runs-on: ubuntu-latest + timeout-minutes: 15 permissions: security-events: write id-token: write diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index e5673be..6f9bb41 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -21,6 +21,7 @@ permissions: jobs: trufflehog: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: @@ -35,6 +36,7 @@ jobs: gitleaks: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 with: @@ -48,6 +50,7 @@ jobs: # Rust-specific: Check for hardcoded crypto values rust-secrets: runs-on: ubuntu-latest + timeout-minutes: 15 steps: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index a12a9d7..3396d45 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/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 2d2c693..1103de1 100644 --- a/.machine_readable/contractiles/README.adoc +++ b/.machine_readable/contractiles/README.adoc @@ -1,4 +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 98% rename from .machine_readable/svc/k9/README.adoc rename to .machine_readable/svc/self-validating/README.adoc index eeb1229..0c2cd4f 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 diff --git a/.machine_readable/svc/k9/burble-metadata.k9.ncl b/.machine_readable/svc/self-validating/burble-metadata.k9.ncl similarity index 100% rename from .machine_readable/svc/k9/burble-metadata.k9.ncl rename to .machine_readable/svc/self-validating/burble-metadata.k9.ncl 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 100% rename from .machine_readable/svc/k9/examples/setup-repo.k9.ncl rename to .machine_readable/svc/self-validating/examples/setup-repo.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 225c225..d0a1fa1 100644 --- a/LICENSE +++ b/LICENSE @@ -1,41 +1,373 @@ -SPDX-License-Identifier: AGPL-3.0-or-later -SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) +Mozilla Public License Version 2.0 +================================== ------------------------------------------------------------------------- -PROJECT LICENCE: GNU Affero General Public License v3.0 or later ------------------------------------------------------------------------- +1. Definitions +-------------- -This project is co-developed and is governed by the GNU Affero General -Public License, Version 3.0 or any later version (AGPL-3.0-or-later). +1.1. "Contributor" + means each individual or legal entity that creates, contributes to + the creation of, or owns Covered Software. ------------------------------------------------------------------------- -COMPONENT LICENSING NOTE ------------------------------------------------------------------------- +1.2. "Contributor Version" + means the combination of the Contributions of others (if any) used + by a Contributor and that particular Contributor's Contribution. -Individual components originally authored solely by Jonathan D.A. Jewell -(hyperpolymath) are independently governed by the Palimpsest License -(MPL-2.0), with MPL-2.0 as automatic legal fallback until -PMPL achieves formal recognition. See: - https://github.com/hyperpolymath/palimpsest-license +1.3. "Contribution" + means Covered Software of a particular Contributor. -When these components are used within this project, the project-level -AGPL-3.0-or-later applies. When extracted and used independently, the -component's own MPL-2.0 / MPL-2.0 terms govern. +1.4. "Covered Software" + means Source Code Form to which the initial Contributor has attached + the notice in Exhibit A, the Executable Form of such Source Code + Form, and Modifications of such Source Code Form, in each case + including portions thereof. ------------------------------------------------------------------------- +1.5. "Incompatible With Secondary Licenses" + means -The complete AGPL-3.0 text is available at: - https://www.gnu.org/licenses/agpl-3.0.txt + (a) that the initial Contributor has attached the notice described + in Exhibit B to the Covered Software; or -This project is free software: you can redistribute it and/or modify -it under the terms of the GNU Affero General Public License as published -by the Free Software Foundation, either version 3 of the License, or -(at your option) any later version. + (b) that the Covered Software was made available under the terms of + version 1.1 or earlier of the License, but not also under the + terms of a Secondary License. -This project is distributed in the hope that it will be useful, -but WITHOUT ANY WARRANTY; without even the implied warranty of -MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -GNU Affero General Public License for more details. +1.6. "Executable Form" + means any form of the work other than Source Code Form. -You should have received a copy of the GNU Affero General Public License -along with this project. If not, see . +1.7. "Larger Work" + means a work that combines Covered Software with other material, in + a separate file or files, that is not Covered Software. + +1.8. "License" + means this document. + +1.9. "Licensable" + means having the right to grant, to the maximum extent possible, + whether at the time of the initial grant or subsequently, any and + all of the rights conveyed by this License. + +1.10. "Modifications" + means any of the following: + + (a) any file in Source Code Form that results from an addition to, + deletion from, or modification of the contents of Covered + Software; or + + (b) any new file in Source Code Form that contains any Covered + Software. + +1.11. "Patent Claims" of a Contributor + means any patent claim(s), including without limitation, method, + process, and apparatus claims, in any patent Licensable by such + Contributor that would be infringed, but for the grant of the + License, by the making, using, selling, offering for sale, having + made, import, or transfer of either its Contributions or its + Contributor Version. + +1.12. "Secondary License" + means either the GNU General Public License, Version 2.0, the GNU + Lesser General Public License, Version 2.1, the GNU Affero General + Public License, Version 3.0, or any later versions of those + licenses. + +1.13. "Source Code Form" + 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 + 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 + +Each Contributor hereby grants You a world-wide, royalty-free, +non-exclusive license: + +(a) under intellectual property rights (other than patent or trademark) + Licensable by such Contributor to use, reproduce, make available, + modify, display, perform, distribute, and otherwise exploit its + Contributions, either on an unmodified basis, with Modifications, or + as part of a Larger Work; and + +(b) under Patent Claims of such Contributor to make, use, sell, offer + for sale, have made, import, and otherwise transfer either its + Contributions or its Contributor Version. + +2.2. Effective Date + +The licenses granted in Section 2.1 with respect to any Contribution +become effective for each Contribution on the date the Contributor first +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: + +(a) for any code that a Contributor has removed from Covered Software; + or + +(b) for infringements caused by: (i) Your and any other third party's + modifications of Covered Software, or (ii) the combination of its + 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. + +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). + +2.5. Representation + +Each Contributor represents that the Contributor believes its +Contributions are its original creation(s) or it has sufficient rights +to grant the rights to its Contributions conveyed by this License. + +2.6. Fair Use + +This License is not intended to limit any rights You have under +applicable copyright doctrines of fair use, fair dealing, or other +equivalents. + +2.7. Conditions + +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 + +All distribution of Covered Software in Source Code Form, including any +Modifications that You create or to which You contribute, must be under +the terms of this License. You must inform recipients that the Source +Code Form of the Covered Software is governed by the terms of this +License, and how they can obtain a copy of this License. You may not +attempt to alter or restrict the recipients' rights in the Source Code +Form. + +3.2. Distribution of Executable 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 + +(b) You may distribute such Executable Form under the terms of this + License, or sublicense it under different terms, provided that the + license for the Executable Form does not attempt to limit or alter + the recipients' rights in the Source Code Form under this License. + +3.3. Distribution of a Larger Work + +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 +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 +Software under the terms of either this License or such Secondary +License(s). + +3.4. Notices + +You may not remove or alter the substance of any license notices +(including copyright notices, patent notices, disclaimers of warranty, +or limitations of liability) contained within the Source Code Form of +the Covered Software, except that You may alter any license notices to +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. + +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. + +5. Termination +-------------- + +5.1. The rights granted under this License will terminate automatically +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 +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. + +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. + +************************************************************************ +* * +* 6. Disclaimer of Warranty * +* ------------------------- * +* * +* Covered Software is provided under this License on an "as is" * +* basis, without warranty of any kind, either expressed, implied, or * +* statutory, including, without limitation, warranties that the * +* Covered Software is free of defects, merchantable, fit for a * +* particular purpose or non-infringing. The entire risk as to the * +* quality and performance of the Covered Software is with You. * +* Should any Covered Software prove defective in any respect, You * +* (not any Contributor) assume the cost of any necessary servicing, * +* repair, or correction. This disclaimer of warranty constitutes an * +* essential part of this License. No use of any Covered Software is * +* authorized under this License except under this disclaimer. * +* * +************************************************************************ + +************************************************************************ +* * +* 7. Limitation of Liability * +* -------------------------- * +* * +* Under no circumstances and under no legal theory, whether tort * +* (including negligence), contract, or otherwise, shall any * +* Contributor, or anyone who distributes Covered Software as * +* permitted above, be liable to You for any direct, indirect, * +* special, incidental, or consequential damages of any character * +* including, without limitation, damages for lost profits, loss of * +* goodwill, work stoppage, computer failure or malfunction, or any * +* and all other commercial damages or losses, even if such party * +* shall have been informed of the possibility of such damages. This * +* limitation of liability shall not apply to liability for death or * +* personal injury resulting from such party's negligence to the * +* extent applicable law prohibits such limitation. Some * +* jurisdictions do not allow the exclusion or limitation of * +* incidental or consequential damages, so this exclusion and * +* limitation may not apply to You. * +* * +************************************************************************ + +8. Litigation +------------- + +Any litigation relating to this License may be brought only in the +courts of a jurisdiction where the defendant maintains its principal +place of business and such litigation shall be governed by laws of that +jurisdiction, without reference to its conflict-of-law provisions. +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 +unenforceable, such provision shall be reformed only to the extent +necessary to make it enforceable. Any law or regulation which provides +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. + +10.2. Effect of New Versions + +You may distribute the Covered Software under the terms of the version +of the License under which You originally received the Covered Software, +or under the terms of any subsequent version published by the license +steward. + +10.3. Modified Versions + +If you create software not governed by this License, and you want to +create a new license for such software, you may create and use a +modified version of this License if you rename the license and remove +any references to the name of the license steward (except to note that +such modified license differs from this License). + +10.4. Distributing Source Code Form that is Incompatible With Secondary +Licenses + +If You choose to distribute Source Code Form that is Incompatible With +Secondary Licenses under the terms of this version of the License, the +notice described in Exhibit B of this License must be attached. + +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 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. + +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 3b89386..c580c42 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 7bc1fc0..d3a75c8 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 ec855dc..5f53816 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 natsci-studio, {{BUILD_CMD}}, {{TEST_CMD}}, {{LANG_STACK}} with actuals = natsci-studio — Quick Start for Developers diff --git a/QUICKSTART-MAINTAINER.adoc b/QUICKSTART-MAINTAINER.adoc index 82c10b7..bf74b69 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 natsci-studio, {{PACKAGE_NAME}}, {{DEPS}} with actuals = natsci-studio — Quick Start for Platform Maintainers diff --git a/QUICKSTART-USER.adoc b/QUICKSTART-USER.adoc index d417f6d..bb01c23 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 natsci-studio, Rsr Template Repo — See README.adoc for details., just run, Rsr Template Repo started successfully. with actuals = natsci-studio — 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 588d1f2..e2a91e3 100644 --- a/README.adoc +++ b/README.adoc @@ -1,4 +1,5 @@ -// SPDX-License-Identifier: AGPL-3.0-or-later +// SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell = NatSci Studio @@ -6,7 +7,7 @@ :toc-placement: preamble image:https://img.shields.io/badge/OpenSSF-Best_Practices-green?logo=opensourcesecurity[OpenSSF Best Practices,link="https://www.bestpractices.dev/en/projects/new?repo_url=https://github.com/hyperpolymath/natsci-studio"] -image:https://img.shields.io/badge/License-AGPL_v3-blue.svg[License: AGPL-3.0] +image:https://img.shields.io/badge/License-MPL_2.0-blue.svg[License: MPL-2.0,link="https://opensource.org/licenses/MPL-2.0"] image:https://api.thegreenwebfoundation.org/greencheckimage/github.com[Green Web,link="https://www.thegreenwebfoundation.org/green-web-check/?url=github.com"] A standards-compliant monorepo of natural-sciences libraries with a @@ -44,8 +45,9 @@ on this repo are bound by them. See each Verbfile under == License -AGPL-3.0-or-later (per hyperpolymath "son-co-developed project" rule — -same pattern as IDApTIK + Airborne Submarine Squadron). See `LICENSE`. +This project is licensed under the Mozilla Public License, v. 2.0. See the `LICENSE` file for details. + +SPDX-License-Identifier: MPL-2.0 == Author 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/TEST-NEEDS.md b/TEST-NEEDS.md index e26c588..d6799fd 100644 --- a/TEST-NEEDS.md +++ b/TEST-NEEDS.md @@ -1,3 +1,7 @@ + # TEST-NEEDS: natsci-studio ## CRG Grade: C — ACHIEVED 2026-04-04 diff --git a/TOPOLOGY.md b/TOPOLOGY.md index bcb0fc1..47a13a3 100644 --- a/TOPOLOGY.md +++ b/TOPOLOGY.md @@ -1,4 +1,7 @@ - + # natsci-studio — 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 dbce17d..2ce127e 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..43a113f 100644 --- a/docs/RSR_OUTLINE.adoc +++ b/docs/RSR_OUTLINE.adoc @@ -1,3 +1,5 @@ +// 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"] 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 d5b6d9f..a8f5371 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 41c5bd3..5861054 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 bcb16f7..67f1c40 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/practice/ci-cost-reduction.adoc b/docs/practice/ci-cost-reduction.adoc index 712a0c9..cdf690a 100644 --- a/docs/practice/ci-cost-reduction.adoc +++ b/docs/practice/ci-cost-reduction.adoc @@ -1,4 +1,5 @@ // SPDX-License-Identifier: MPL-2.0 +// Copyright (c) Jonathan D.A. Jewell // (MPL-2.0 is automatic legal fallback until PMPL is formally recognised) = CI Cost Reduction — RSR Estate Spec :toc: left 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/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 2025b599622428f58efb2ff537192a897871fc41 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:05:04 +0100 Subject: [PATCH 04/11] chore: flatten self-validating directory structure --- .machine_readable/{svc => }/self-validating/README.adoc | 0 .../{svc => }/self-validating/burble-metadata.k9.ncl | 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 .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/burble-metadata.k9.ncl (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/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/burble-metadata.k9.ncl b/.machine_readable/self-validating/burble-metadata.k9.ncl similarity index 100% rename from .machine_readable/svc/self-validating/burble-metadata.k9.ncl rename to .machine_readable/self-validating/burble-metadata.k9.ncl 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/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 2feb1b074f3c0b6a2f42496757493fdc3dd4d046 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Thu, 4 Jun 2026 18:55:51 +0100 Subject: [PATCH 05/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 Justfile | 4 ++-- 6 files changed, 9 insertions(+), 9 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/Justfile b/Justfile index c6c6205..d4698fd 100644 --- a/Justfile +++ b/Justfile @@ -499,8 +499,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 c830b5838fccee59bc563d9161d2eda02c684968 Mon Sep 17 00:00:00 2001 From: Mistral Vibe Date: Sun, 7 Jun 2026 09:03:09 +0100 Subject: [PATCH 06/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 a5b8cac52bddfa18b2426b3f65ea2f98c26ebf8e 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 07/11] Apply estate standardization: governance docs, contractiles, CI/CD cleanup --- .github/workflows/rust-ci.yml | 2 +- .../contractiles/Adjustfile.a2ml | 72 + .../contractiles/Intentfile.a2ml | 99 ++ .machine_readable/contractiles/Justfile | 1544 +++++++++++++++++ .machine_readable/contractiles/Mustfile.a2ml | 102 ++ .machine_readable/contractiles/Trustfile.a2ml | 88 + .../contractiles/adjust/Adjustfile.a2ml | 44 - .../contractiles/adjust/adjust.k9.ncl | 166 -- .../contractiles/adjust/adjust.manifest.a2ml | 47 - .../contractiles/adjust/adjust.ncl | 62 - .../contractiles/bust/Bustfile.a2ml | 77 - .../contractiles/bust/bust.k9.ncl | 160 -- .../contractiles/bust/bust.manifest.a2ml | 48 - .machine_readable/contractiles/bust/bust.ncl | 66 - .../contractiles/dust/Dustfile.a2ml | 26 - .../contractiles/dust/dust.k9.ncl | 171 -- .../contractiles/dust/dust.manifest.a2ml | 51 - .machine_readable/contractiles/dust/dust.ncl | 66 - .../contractiles/intend/Intentfile.a2ml | 96 - .../contractiles/intend/intend.k9.ncl | 250 --- .../contractiles/intend/intend.manifest.a2ml | 73 - .../contractiles/intend/intend.ncl | 81 - .../contractiles/must/Mustfile.a2ml | 103 -- .../contractiles/must/must.k9.ncl | 236 --- .../contractiles/must/must.manifest.a2ml | 59 - .machine_readable/contractiles/must/must.ncl | 64 - .../contractiles/trust/Trustfile.a2ml | 91 - .../contractiles/trust/trust.k9.ncl | 276 --- .../contractiles/trust/trust.manifest.a2ml | 72 - .../contractiles/trust/trust.ncl | 88 - flake.lock | 61 - flake.nix | 170 -- 32 files changed, 1906 insertions(+), 2705 deletions(-) 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/adjust/Adjustfile.a2ml delete mode 100644 .machine_readable/contractiles/adjust/adjust.k9.ncl delete mode 100644 .machine_readable/contractiles/adjust/adjust.manifest.a2ml delete mode 100644 .machine_readable/contractiles/adjust/adjust.ncl delete mode 100644 .machine_readable/contractiles/bust/Bustfile.a2ml delete mode 100644 .machine_readable/contractiles/bust/bust.k9.ncl delete mode 100644 .machine_readable/contractiles/bust/bust.manifest.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/dust/dust.k9.ncl delete mode 100644 .machine_readable/contractiles/dust/dust.manifest.a2ml delete mode 100644 .machine_readable/contractiles/dust/dust.ncl delete mode 100644 .machine_readable/contractiles/intend/Intentfile.a2ml delete mode 100644 .machine_readable/contractiles/intend/intend.k9.ncl delete mode 100644 .machine_readable/contractiles/intend/intend.manifest.a2ml delete mode 100644 .machine_readable/contractiles/intend/intend.ncl delete mode 100644 .machine_readable/contractiles/must/Mustfile.a2ml delete mode 100644 .machine_readable/contractiles/must/must.k9.ncl delete mode 100644 .machine_readable/contractiles/must/must.manifest.a2ml delete mode 100644 .machine_readable/contractiles/must/must.ncl delete mode 100644 .machine_readable/contractiles/trust/Trustfile.a2ml delete mode 100644 .machine_readable/contractiles/trust/trust.k9.ncl delete mode 100644 .machine_readable/contractiles/trust/trust.manifest.a2ml delete mode 100644 .machine_readable/contractiles/trust/trust.ncl delete mode 100644 flake.lock delete mode 100644 flake.nix diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index c83255d..3f1a4aa 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -14,5 +14,5 @@ permissions: jobs: rust-ci: - uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@4fdf4314b4ab54269adbaff10e30e483b5e86845 + uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@f5f0506a6ec88e574753eee701a268e0d4b3a7f2 timeout-minutes: 10 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..d4698fd --- /dev/null +++ b/.machine_readable/contractiles/Justfile @@ -0,0 +1,1544 @@ +# 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 := "natsci-studio" +OWNER := "hyperpolymath" # son co-dev — AGPL per IDApTIK pattern +REPO := "natsci-studio" +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 'natsci-studio' Justfile 2>/dev/null; then + echo "⚠ Justfile still references 'natsci-studio' — 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 + +# 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 natsci-studio." + 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 natsci-studio..." + @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 "=== natsci-studio 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 "=== natsci-studio Help ===" + @echo "Platform: $(uname -s) $(uname -m)" + @echo "Shell: $SHELL" + @echo "" + @echo "To report an issue:" + @echo " https://github.com/hyperpolymath/natsci-studio/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/adjust/Adjustfile.a2ml b/.machine_readable/contractiles/adjust/Adjustfile.a2ml deleted file mode 100644 index 9d1bb34..0000000 --- a/.machine_readable/contractiles/adjust/Adjustfile.a2ml +++ /dev/null @@ -1,44 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -# Adjustfile (A2ML Canonical) — drift tolerances + corrective actions -# Author: Jonathan D.A. Jewell -# Paired runner: adjust.ncl | Paired K9: adjust.k9.ncl (v1.0.0) - -@abstract: -NatSci Studio drift tolerances. Advisory (non-gating). Catches -cumulative drift — things that don't breach a hard limit any single -time but creep over sessions. K9 component tracks per-tolerance trend -and flags accelerating drift. -@end - -[[tolerances]] -id = "haskell-warnings-clean" -description = "Haskell build emits zero -Wall warnings" -measure = "cabal build all 2>&1 | grep -c '^.*:.*: warning:' || echo 0" -tolerance_band = "= 0" -on_exceeded = "warn_and_attempt_fix" -status = "declared" - -[[tolerances]] -id = "hype-word-count-in-docs" -description = "Count of hype-register words in README + docs stays bounded" -measure = "grep -criE '\\b(revolutionary|transformative|unprecedented|game.changing|paradigm|disrupt)\\b' README.adoc docs/ 2>/dev/null | awk -F: '{s+=$2} END {print s+0}'" -tolerance_band = "≤ 2" -on_exceeded = "warn_and_record" -status = "declared" -notes = "A5 grandiose-scale-hype trend tracking. Accelerating drift flagged at session close." - -[[tolerances]] -id = "sbom-freshness-days" -description = "Days since last SBOM regeneration" -measure = "test -f SBOM.json && echo $(( ($(date +%s) - $(date -r SBOM.json +%s)) / 86400 )) || echo 999" -tolerance_band = "≤ 30" -on_exceeded = "warn_and_attempt_fix" -status = "declared" - -[[tolerances]] -id = "wcag-contrast-todos" -description = "Pending WCAG contrast fixes in the TUI attr map" -measure = "grep -rc 'TODO.*contrast\\|FIXME.*contrast' tools/console/src/ 2>/dev/null | awk -F: '{s+=$2} END {print s+0}'" -tolerance_band = "≤ 3" -on_exceeded = "warn_and_record" -status = "declared" diff --git a/.machine_readable/contractiles/adjust/adjust.k9.ncl b/.machine_readable/contractiles/adjust/adjust.k9.ncl deleted file mode 100644 index 9ff26c9..0000000 --- a/.machine_readable/contractiles/adjust/adjust.k9.ncl +++ /dev/null @@ -1,166 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# adjust.k9.ncl — K9 trust-tier component of the adjust trident -# Author: Jonathan D.A. Jewell -# -# Pairs with: Adjustfile.a2ml (declaration) + adjust.ncl (runner). -# -# Verb: adjust (drift tolerances + corrective actions) -# Tier: Yard (validation with subprocess for measurement; -# no mutation beyond auto-fix where declared) -# Authority: advisory (continue-with-warnings; not blocking) -# -# adjust is the tolerance-band verb. Where must says "this MUST hold" -# and trust says "this MUST verify clean" (both binary), adjust says -# "drift ≤ X is acceptable; drift > X triggers action Y". Between them, -# adjust handles the subtle-drift territory that binary verbs can't. -# -# Cardinality: ONE adjust trident per repo. -# -# Failure-mode focus: adjust catches cumulative-small-drift patterns -# (E2 cosmetic churn accumulating into real regression, F2 context -# erosion causing gradual parameter drift). Where must flags "broken -# now", adjust flags "drifting toward broken". - -let base_k9 = import "../k9/template-hunt.k9.ncl" in -let base = import "../_base.ncl" in - -{ - pedigree = base_k9.pedigree_schema & { - contractile_verb = "adjust", - paired_xfile = "../adjust/Adjustfile.a2ml", - paired_runner = "../adjust/adjust.ncl", - - tier = 'Yard, - authority = 'advisory, - - metadata = { - name = "adjust-k9", - version = "1.0.0", - description = "Drift-tolerance + corrective-action runner. Fifth trident instance. First (Yard, advisory) authority pattern.", - paired_xfile = "Adjustfile.a2ml", - paired_runner = "adjust.ncl", - author = "Jonathan D.A. Jewell ", - }, - - security = { - leash = 'Yard, - trust_level = "tolerance measurement + declared auto-fix", - allow_network = false, - allow_filesystem_write_conditional = true, # auto_fix_when_available may edit - allow_subprocess = true, - probe_scope = 'measurement_plus_declared_fix, - }, - }, - - variance_schema = { - entry_id | String, - reason | String, - approved_by | String, - scope | String, - expires | String, - review_notes | String | optional, - # adjust-specific: which tolerance band the variance widens - tolerance_band_widened | String, - widened_to_value | String, - }, - - execution = { - triggers = [ 'session_close, 'on_demand, 'pre_push ], - - per_tolerance = { - measure_drift = true, - record_outcome = true, - respect_variance = true, - # adjust-specific authority: tolerance exceeded → warn, try - # auto-fix if declared, then continue. Never blocks. - on_exceeded = 'warn_and_attempt_fix, - on_auto_fix_applied = 'record_and_continue, - on_auto_fix_unavailable = 'record_as_advisory_drift, - # Cumulative-drift detection (adjust's specialty) - track_drift_trend_over_sessions = true, - flag_accelerating_drift = true, - }, - - evidence_sinks = [ - { kind = 'verisimdb, table = "contractile_executions", - schema = "contractile_execution_v1", - aux_tables = [ "adjust_drift_history" ] }, - { kind = 'drift_log, path = ".machine_readable/6a2/DRIFT.a2ml", - append_only = true }, - ], - - on_close = { - re_measure_all_tolerances = true, - diff_against_last_ratification = true, - emit_drift_entries_for_tolerance_exceeded = true, - surface_expired_variances = true, - surface_accelerating_drift = true, - # adjust is advisory — does NOT block session close. - block_session_close_on_any_drift = false, - }, - - on_open = { - render_summary = 'plain_language, - include_drift_log_from_last_close = true, - include_active_variances = true, - include_recent_anchors = true, - anchor_lookback_weeks = 8, - include_tolerance_trend_summary = true, - - negotiation = { - required = true, - ai_required_inputs = [ - 'timeline_realism, - 'industry_standards, - 'audience_feasibility, - 'resulting_invariants, - 'ecosystem_dependencies, - ], - user_engagement_required = true, - user_engagement_mode = 'per_input_response, - specification_translation = { - ai_produces_spec_form = true, - user_reviews_in_domain_language = true, - schema_authoring_is_ai_responsibility = true, - translation_faithfulness_auditable = true, - }, - }, - - accountability_pledge = { - required = true, - parties = [ - { - role = 'user, - pledge = "I have reviewed the tolerance bands and corrective actions. I accept accountability for reviewing drift warnings rather than muting them, and for re-tuning tolerances via amendment when the intended operating envelope changes.", - signature_required = true, - }, - { - role = 'ai_agent, - pledge = "I will surface tolerance breaches and accelerating-drift patterns at session close; I will propose corrective actions rather than widening tolerances silently; I will require amendment for legitimate tolerance re-tuning, not quiet band-widening.", - signature_required = true, - }, - ], - signed_record_destination = ".machine_readable/6a2/ratification-.a2ml", - must_precede_work = true, - }, - - ratification_record_shape = { - includes_negotiation_transcript = true, - includes_both_pledges = true, - includes_tolerance_bands_snapshot = true, - signed = true, - dated = true, - session_id = 'required, - contract_hash = 'required, - }, - }, - }, - - failure_mode_defenses = [ - 'A1_enthusiasm_capture, - 'C3_helpfulness_inflation, # helpful additions surfaced if they widen tolerances silently - 'C4_modernization_drift, - 'E2_cosmetic_churn, # adjust tracks cumulative churn - 'F2_context_window_erosion, # parameter drift across sessions detected - ], -} diff --git a/.machine_readable/contractiles/adjust/adjust.manifest.a2ml b/.machine_readable/contractiles/adjust/adjust.manifest.a2ml deleted file mode 100644 index f28f94d..0000000 --- a/.machine_readable/contractiles/adjust/adjust.manifest.a2ml +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# adjust.manifest.a2ml — Trident coherence manifest for the adjust verb. -# Author: Jonathan D.A. Jewell -# -# Fifth trident instance. First (Yard, advisory) authority pattern — -# complements the (Hunt, blocking) triple (must + trust + bust) and -# the (Hunt, reporting) north-star (intend). - ---- -trident_version = "1.0.0" -verb = "adjust" -semantics = "drift tolerances + corrective actions" -cardinality = "one per repo" -authority = "advisory (continue-with-warnings)" - -[[files]] -role = "declaration" -path = "Adjustfile.a2ml" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "runner" -path = "adjust.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "k9_component" -path = "adjust.k9.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[cross_refs] -runner_paired_xfile = "Adjustfile.a2ml" -k9_paired_xfile = "../adjust/Adjustfile.a2ml" -k9_paired_runner = "../adjust/adjust.ncl" - -[signed_by] -user = "Jonathan D.A. Jewell" -date = "2026-04-18" -context = "adjust trident — fifth Trident instance. First (Yard, advisory) authority pattern. Specialises in cumulative-drift catchment — tolerance bands + trend tracking + auto-fix-where-declared." - -[[history]] -date = "2026-04-18" -event = "trident-born" -note = "Adjustfile.a2ml and adjust.ncl pre-existed. This manifest + adjust.k9.ncl complete the trident. Exercises the Yard tier + advisory authority for the first time; on_exceeded = 'warn_and_attempt_fix rather than 'fail. adjust-specific track_drift_trend_over_sessions + flag_accelerating_drift." diff --git a/.machine_readable/contractiles/adjust/adjust.ncl b/.machine_readable/contractiles/adjust/adjust.ncl deleted file mode 100644 index d6c24f0..0000000 --- a/.machine_readable/contractiles/adjust/adjust.ncl +++ /dev/null @@ -1,62 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Adjust — accessibility runner -# -# Pairs with: Adjustfile.a2ml (same directory) -# Verb: adjust -# Semantics: accessibility compliance (WCAG 2.1 AA baseline). Gating where -# a deterministic fix exists; advisory where human review needed. -# CLI: `contractile adjust check` → run all probes, list violations -# `contractile adjust fix` → apply deterministic fixes where defined -# -# 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 = "adjust", - semantics = "accessibility compliance", - security = { - leash = 'Kennel, - trust_level = "fixes allowed where deterministic", - allow_network = false, - allow_filesystem_write = true, # `adjust fix` may write (deterministic patches only) - allow_subprocess = true, - }, - metadata = { - name = "adjust-runner", - version = "1.0.0", - description = "Evaluates accessibility requirements from Adjustfile.a2ml. Fixes deterministic items; flags the rest for human review.", - paired_xfile = "Adjustfile.a2ml", - author = "Jonathan D.A. Jewell ", - }, - }, - - schema = { - requirements - | Array { - id | String, - description | String, - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - probe | String, - # status_core values: 'declared, 'verified, 'failing; adjust adds 'partial - status | [| 'declared, 'partial, 'verified, 'failing |] | default = 'declared, - compliance | String | optional, # e.g. "WCAG 2.1 AA" - notes | String | optional, - fix | String | optional, # deterministic fix command (optional) - }, - }, - - # Runner behaviour — inherits from base.run_defaults. - # adjust is advisory (continue-with-warnings) not a hard gate. - # auto_fix_when_available is adjust-specific. - run = base.run_defaults & { - on_any_fail = "continue-with-warnings", # accessibility is progress-tracked, not a hard gate by default - report_format = "a2ml", - emit_summary = true, - auto_fix_when_available = true, - }, -} diff --git a/.machine_readable/contractiles/bust/Bustfile.a2ml b/.machine_readable/contractiles/bust/Bustfile.a2ml deleted file mode 100644 index 6975df7..0000000 --- a/.machine_readable/contractiles/bust/Bustfile.a2ml +++ /dev/null @@ -1,77 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -# Bustfile (A2ML Canonical) — hard-stop / must-not-run declarations -# Author: Jonathan D.A. Jewell -# Paired runner: bust.ncl | Paired K9: bust.k9.ncl (v1.0.0) - -@abstract: -NatSci Studio hard-stops. Declares things that MUST NOT appear in the -tree. Complement to Mustfile: Mustfile says "this must hold", Bustfile -says "this must not be here". Catches AI-assistant reintroduction -attempts of banned / retired / out-of-scope patterns. -@end - -## Banned-language reintroduction triggers - -[[hard_stops]] -id = "cpp-reintroduction" -description = "C++ sources appearing anywhere" -probe = "find . -type f \\( -name '*.cpp' -o -name '*.cc' -o -name '*.cxx' -o -name '*.hpp' \\) -not -path './.git/*' 2>/dev/null | grep -q ." -status = "declared" -severity = "critical" -notes = "Catches 'lightweight C++ core for performance' AI pattern. Rust/SPARK is the sanctioned systems-language alternative." - -[[hard_stops]] -id = "electron-reintroduction" -description = "Electron present in package descriptors or source" -probe = "grep -riE '\\belectron\\b' --include='*.json' --include='*.toml' --include='*.hs' . 2>/dev/null | grep -v 'banned\\|Trustfile\\|Mustfile\\|Bustfile' | grep -q ." -status = "declared" -severity = "critical" -notes = "Catches 'web-based or Electron app' AI pattern." - -[[hard_stops]] -id = "python-reintroduction" -description = "Python .py sources" -probe = "find . -type f -name '*.py' -not -path './.git/*' 2>/dev/null | grep -q ." -status = "declared" -severity = "high" - -[[hard_stops]] -id = "nodejs-package-json" -description = "package.json at repo root (Node intrusion; Deno uses deno.json)" -probe = "test -f package.json" -status = "declared" -severity = "high" - -[[hard_stops]] -id = "go-reintroduction" -description = "Go sources" -probe = "find . -type f -name '*.go' -not -path './.git/*' 2>/dev/null | grep -q ." -status = "declared" -severity = "high" - -## Out-of-scope pattern triggers - -[[hard_stops]] -id = "monolithic-engine-directory" -description = "engine/ or similar directory — NatSci Studio is engine-AGNOSTIC per Intentfile" -probe = "test -d engine || test -d core/engine || test -d natsci-engine" -status = "declared" -severity = "high" -notes = "Sandbox/meta-engine is a FAR-HORIZON wish in Intentfile. Creating an engine directory now without amendment trips this Bust." - -[[hard_stops]] -id = "commercial-hype-language" -description = "Commercial / monetisation / revolutionary-scale language in project docs" -probe = "grep -riE '\\b(billionaire|revolutionary|game.changer|disrupt|monetis(e|ation))\\b' README.adoc docs/ 2>/dev/null | grep -v 'banned\\|Bustfile' | grep -q ." -status = "declared" -severity = "medium" -notes = "A5 grandiose-scale-hype defense. Le Chat 2026-03-14 used the 'billionaire in six weeks' / 'transformative leap' / 'revolutionary' register. This probe catches reintroduction of that register in project docs." - -## Expiry - -[[hard_stops]] -id = "stale-ai-manifest" -description = "0-AI-MANIFEST.a2ml not touched in 12 months (stale universal entry point)" -probe = "test $(find 0-AI-MANIFEST.a2ml -mtime +365 2>/dev/null | wc -l) -eq 1" -status = "declared" -severity = "low" diff --git a/.machine_readable/contractiles/bust/bust.k9.ncl b/.machine_readable/contractiles/bust/bust.k9.ncl deleted file mode 100644 index c60a0ae..0000000 --- a/.machine_readable/contractiles/bust/bust.k9.ncl +++ /dev/null @@ -1,160 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# bust.k9.ncl — K9 trust-tier component of the bust trident -# Author: Jonathan D.A. Jewell -# -# Pairs with: Bustfile.a2ml (declaration) + bust.ncl (runner). -# -# Verb: bust (hard-stop / expiry / "must-not-run") -# Tier: Hunt-read-only (subprocess probes for expiry/state checks) -# Authority: blocking (HARD GATE on declared broken states) -# -# bust is the "this is broken, this has expired, this must not run" -# declarative surface. Where must asserts invariants that must hold, -# bust asserts failure states that must not be re-entered. Complement -# to must: together they bound the "acceptable operating state" from -# above (must) and below (bust). -# -# Cardinality: ONE bust trident per repo. -# -# Failure-mode focus: bust catches deprecated-path-still-called -# patterns (C2 capability collapse attempts where an AI reintroduces -# retired code), expiry-exceeded state (certificates / tokens / grants -# past their expiry), and the "it works, ship it" pattern where a -# caller silently starts using a must-not-run API. - -let base_k9 = import "../k9/template-hunt.k9.ncl" in -let base = import "../_base.ncl" in - -{ - pedigree = base_k9.pedigree_schema & { - contractile_verb = "bust", - paired_xfile = "../bust/Bustfile.a2ml", - paired_runner = "../bust/bust.ncl", - - tier = 'Hunt, - authority = 'blocking, - - metadata = { - name = "bust-k9", - version = "1.0.0", - description = "Hard-stop / expiry / must-not-run gate. Fourth trident instance. Completes the blocking-authority triple (must + trust + bust).", - paired_xfile = "Bustfile.a2ml", - paired_runner = "bust.ncl", - author = "Jonathan D.A. Jewell ", - }, - - security = { - leash = 'Hunt, - trust_level = "read-only expiry + state-check with subprocess", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = true, - probe_scope = 'read_only, - }, - }, - - variance_schema = { - entry_id | String, - reason | String, - approved_by | String, - scope | String, - expires | String, - review_notes | String | optional, - severity_acknowledged | [| 'critical, 'high, 'medium |], - waived_consequence_description | String, - }, - - execution = { - triggers = [ 'session_close, 'on_demand, 'pre_push, 'pre_merge ], - - per_hard_stop = { - run_probe = true, - record_outcome = true, - respect_variance = true, - on_triggered = 'fail, # BLOCKING — bust condition hit = block - severity_escalation = 'honour, - # bust-specific: detect re-introduction of deprecated calls - flag_deprecated_reintroduction = true, - }, - - evidence_sinks = [ - { kind = 'verisimdb, table = "contractile_executions", - schema = "contractile_execution_v1", - aux_tables = [ "bust_triggers_history" ] }, - { kind = 'drift_log, path = ".machine_readable/6a2/DRIFT.a2ml", - append_only = true }, - ], - - on_close = { - re_execute_all_hard_stops = true, - diff_against_last_ratification = true, - emit_drift_entries_for_new_triggers = true, - surface_expired_variances = true, - block_session_close_on_critical_bust = true, - }, - - on_open = { - render_summary = 'plain_language, - include_drift_log_from_last_close = true, - include_active_variances = true, - include_recent_anchors = true, - anchor_lookback_weeks = 8, - include_silent_regressions = true, - - negotiation = { - required = true, - ai_required_inputs = [ - 'timeline_realism, - 'industry_standards, - 'audience_feasibility, - 'resulting_invariants, - 'ecosystem_dependencies, - ], - user_engagement_required = true, - user_engagement_mode = 'per_input_response, - specification_translation = { - ai_produces_spec_form = true, - user_reviews_in_domain_language = true, - schema_authoring_is_ai_responsibility = true, - translation_faithfulness_auditable = true, - }, - }, - - accountability_pledge = { - required = true, - parties = [ - { - role = 'user, - pledge = "I have reviewed the declared hard-stop / expiry / must-not-run conditions. I accept accountability for not calling into must-not-run code paths, not ignoring expired tokens/grants, and not silently reintroducing deprecated patterns. I will raise a variance with severity acknowledgement if an exception is needed.", - signature_required = true, - }, - { - role = 'ai_agent, - pledge = "I will refuse suggestions that reintroduce must-not-run patterns; I will surface bust triggers at session close; I will require variance-with-severity for any legitimate reintroduction of a deprecated path rather than silently allowing it.", - signature_required = true, - }, - ], - signed_record_destination = ".machine_readable/6a2/ratification-.a2ml", - must_precede_work = true, - }, - - ratification_record_shape = { - includes_negotiation_transcript = true, - includes_both_pledges = true, - signed = true, - dated = true, - session_id = 'required, - contract_hash = 'required, - }, - }, - }, - - failure_mode_defenses = [ - 'A1_enthusiasm_capture, - 'C2_capability_collapse, # prevents reintroduction of retired capability - 'C4_modernization_drift, # bust prevents silent re-adoption of deprecated libs - 'D4_error_hiding, - 'E1_refactor_stampede, # refactor that reintroduces deprecated path caught - 'F1_across_session_forgetting, # bust triggers persist across sessions - ], -} diff --git a/.machine_readable/contractiles/bust/bust.manifest.a2ml b/.machine_readable/contractiles/bust/bust.manifest.a2ml deleted file mode 100644 index 2237041..0000000 --- a/.machine_readable/contractiles/bust/bust.manifest.a2ml +++ /dev/null @@ -1,48 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# bust.manifest.a2ml — Trident coherence manifest for the bust verb. -# Author: Jonathan D.A. Jewell -# -# Fourth trident instance. Completes the blocking-authority triple: -# must (persistent invariants), trust (ephemeral transactions), -# bust (hard-stop / expiry / must-not-run). Between them, every -# release-blocking contractile concern is covered. - ---- -trident_version = "1.0.0" -verb = "bust" -semantics = "hard-stop / expiry / must-not-run declarations" -cardinality = "one per repo" -authority = "blocking (hard gate)" - -[[files]] -role = "declaration" -path = "Bustfile.a2ml" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "runner" -path = "bust.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "k9_component" -path = "bust.k9.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[cross_refs] -runner_paired_xfile = "Bustfile.a2ml" -k9_paired_xfile = "../bust/Bustfile.a2ml" -k9_paired_runner = "../bust/bust.ncl" - -[signed_by] -user = "Jonathan D.A. Jewell" -date = "2026-04-18" -context = "bust trident — fourth Trident instance. Completes the blocking-authority triple (must + trust + bust). Specialises in deprecated-path-reintroduction catchment." - -[[history]] -date = "2026-04-18" -event = "trident-born" -note = "Bustfile.a2ml and bust.ncl pre-existed. This manifest + bust.k9.ncl complete the trident. Inherits the full negotiation+accountability schema from intend.k9.ncl v2.0.0 + trust/must extensions; adds flag_deprecated_reintroduction for C2-defense specificity." 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 a072917..0000000 --- a/.machine_readable/contractiles/dust/Dustfile.a2ml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -# Dustfile (A2ML Canonical) — rollback / deprecation / audit-trail policy -# Author: Jonathan D.A. Jewell -# Paired runner: dust.ncl | Paired K9: dust.k9.ncl (v1.0.0 — destructive_action_gating) - -@abstract: -NatSci Studio rollback + deprecation + audit-trail preservation policy. -Advisory (non-gating). Every retired library / deprecated API / removed -capability requires a documented rollback path and preserved audit -trail. Destructive actions run dry-run by default. -@end - -[[retirements]] -id = "library-retirement-template" -description = "Template for retiring a library from libs/" -rollback_path = "git tag libs--v before removal; retain tag indefinitely" -audit_trail = "append retirement summary to docs/retirements.adoc with date + rationale + rollback-path reference" -status = "declared" -notes = "Template only — no actual retirements yet." - -[[retirements]] -id = "deprecated-api-policy" -description = "Deprecated Haskell APIs must be marked {-# DEPRECATED #-} and kept for 2 releases before removal" -rollback_path = "git tag v" -audit_trail = "CHANGELOG.md entry + deprecation reason + expected-removal date" -status = "declared" diff --git a/.machine_readable/contractiles/dust/dust.k9.ncl b/.machine_readable/contractiles/dust/dust.k9.ncl deleted file mode 100644 index ef21668..0000000 --- a/.machine_readable/contractiles/dust/dust.k9.ncl +++ /dev/null @@ -1,171 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# dust.k9.ncl — K9 trust-tier component of the dust trident -# Author: Jonathan D.A. Jewell -# -# Pairs with: Dustfile.a2ml (declaration) + dust.ncl (runner). -# -# Verb: dust (rollback / recovery / deprecation) -# Tier: Yard (audit + structural checks; destructive -# actions gated behind --apply flag + -# explicit per-item approval) -# Authority: advisory (continue-with-warnings) -# -# dust is the retirement + audit-trail verb. Rollback paths, deprecation -# markers, evidence-preservation semantics. Where bust declares -# "broken, don't run", dust declares "how to safely undo / retire / roll -# back". Complement to bust — bust marks the dead end, dust describes -# the exit ramp. -# -# Cardinality: ONE dust trident per repo. -# -# Failure-mode focus: dust is the audit-trail preservation verb — -# defends against E1 refactor stampede (check audit trail still -# intact) and against silent removal (anything removed must have a -# rollback path; anything retired must preserve the evidence of its -# previous existence). - -let base_k9 = import "../k9/template-hunt.k9.ncl" in -let base = import "../_base.ncl" in - -{ - pedigree = base_k9.pedigree_schema & { - contractile_verb = "dust", - paired_xfile = "../dust/Dustfile.a2ml", - paired_runner = "../dust/dust.ncl", - - tier = 'Yard, - authority = 'advisory, - - metadata = { - name = "dust-k9", - version = "1.0.0", - description = "Rollback + deprecation + audit-trail runner. Sixth trident instance — completes the full verb set.", - paired_xfile = "Dustfile.a2ml", - paired_runner = "dust.ncl", - author = "Jonathan D.A. Jewell ", - }, - - security = { - leash = 'Yard, - trust_level = "audit-trail verification + structural checks", - allow_network = false, - # dust is the verb that ACTUALLY wants filesystem write — to - # execute declared rollback/removal — but only behind explicit - # --apply flag + per-item approval. Default is dry-run. - allow_filesystem_write_conditional = true, - allow_subprocess = true, - destructive_action_gating = { - default_mode = 'dry_run, - requires_flag = "--apply", - requires_per_item_approval = true, - approval_mechanism = 'explicit_user_signature, - }, - }, - }, - - variance_schema = { - entry_id | String, - reason | String, - approved_by | String, - scope | String, - expires | String, - review_notes | String | optional, - rollback_path_preserved | Bool, # dust-specific: did the variance preserve rollback? - }, - - execution = { - triggers = [ 'session_close, 'on_demand ], - - per_retirement = { - verify_rollback_path_documented = true, - verify_audit_trail_preserved = true, - respect_variance = true, - on_rollback_path_missing = 'warn, # advisory, not block - on_audit_trail_broken = 'warn, # advisory, not block - # dust-specific: flag any retirement that has been requested but - # lacks proper rollback documentation - flag_unsafe_retirement = true, - }, - - evidence_sinks = [ - { kind = 'verisimdb, table = "contractile_executions", - schema = "contractile_execution_v1", - aux_tables = [ "dust_retirement_history" ] }, - { kind = 'drift_log, path = ".machine_readable/6a2/DRIFT.a2ml", - append_only = true }, - ], - - on_close = { - re_verify_all_retirement_paths = true, - diff_against_last_ratification = true, - emit_drift_entries_for_missing_rollback = true, - emit_drift_entries_for_broken_audit_trail = true, - surface_expired_variances = true, - block_session_close_on_any_drift = false, # advisory - }, - - on_open = { - render_summary = 'plain_language, - include_drift_log_from_last_close = true, - include_active_variances = true, - include_recent_anchors = true, - anchor_lookback_weeks = 8, - - negotiation = { - required = true, - ai_required_inputs = [ - 'timeline_realism, - 'industry_standards, - 'audience_feasibility, - 'resulting_invariants, - 'ecosystem_dependencies, - ], - user_engagement_required = true, - user_engagement_mode = 'per_input_response, - specification_translation = { - ai_produces_spec_form = true, - user_reviews_in_domain_language = true, - schema_authoring_is_ai_responsibility = true, - translation_faithfulness_auditable = true, - }, - }, - - accountability_pledge = { - required = true, - parties = [ - { - role = 'user, - pledge = "I have reviewed the declared rollback paths and deprecation markers. I accept accountability for preserving audit trails when retiring code, and for ensuring every retired capability has a documented rollback path. I will not silently delete evidence of prior state.", - signature_required = true, - }, - { - role = 'ai_agent, - pledge = "I will verify audit-trail preservation in any retirement / rollback / deprecation I perform; I will refuse silent deletion of prior-state evidence; I will require rollback-path documentation before accepting a retirement request; I will operate in dry-run mode by default and require explicit --apply + per-item approval for destructive actions.", - signature_required = true, - }, - ], - signed_record_destination = ".machine_readable/6a2/ratification-.a2ml", - must_precede_work = true, - }, - - ratification_record_shape = { - includes_negotiation_transcript = true, - includes_both_pledges = true, - includes_retirement_schedule = true, - signed = true, - dated = true, - session_id = 'required, - contract_hash = 'required, - }, - }, - }, - - failure_mode_defenses = [ - 'A1_enthusiasm_capture, - 'C2_capability_collapse, # retirement without rollback path = capability collapse - 'D5_sycophancy, # AI won't agree to silent deletion - 'E1_refactor_stampede, # audit trail preservation check - 'E2_cosmetic_churn, - 'F1_across_session_forgetting, # retirement history tracked cross-session - ], -} diff --git a/.machine_readable/contractiles/dust/dust.manifest.a2ml b/.machine_readable/contractiles/dust/dust.manifest.a2ml deleted file mode 100644 index 1c1b769..0000000 --- a/.machine_readable/contractiles/dust/dust.manifest.a2ml +++ /dev/null @@ -1,51 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# dust.manifest.a2ml — Trident coherence manifest for the dust verb. -# Author: Jonathan D.A. Jewell -# -# Sixth + final trident instance. Completes the full verb set — -# the estate now has tridents for every contractile verb. - ---- -trident_version = "1.0.0" -verb = "dust" -semantics = "rollback / recovery / deprecation / audit-trail preservation" -cardinality = "one per repo" -authority = "advisory (continue-with-warnings)" - -[[files]] -role = "declaration" -path = "Dustfile.a2ml" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "runner" -path = "dust.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "k9_component" -path = "dust.k9.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[cross_refs] -runner_paired_xfile = "Dustfile.a2ml" -k9_paired_xfile = "../dust/Dustfile.a2ml" -k9_paired_runner = "../dust/dust.ncl" - -[signed_by] -user = "Jonathan D.A. Jewell" -date = "2026-04-18" -context = "dust trident — sixth and final Trident instance. Completes the full verb set. Specialises in audit-trail preservation + rollback-path verification. Yard tier with destructive-action gating (dry-run default; --apply + per-item approval required for mutations)." - -[[history]] -date = "2026-04-18" -event = "trident-born" -note = "Dustfile.a2ml and dust.ncl pre-existed. This manifest + dust.k9.ncl complete the trident and the full verb set. All 6 verbs now on trident shape: intend (Hunt, reporting), trust (Hunt, blocking), must (Hunt-read-only, blocking), bust (Hunt-read-only, blocking), adjust (Yard, advisory), dust (Yard, advisory)." - -[[history]] -date = "2026-04-18" -event = "verb-set-complete" -note = "Full estate trident coverage. Blocking-authority triple (must/trust/bust) handles release-gating. Advisory pair (adjust/dust) handles drift-warning and audit-trail. Single reporting verb (intend) handles north-star. α two-axis surface fully exercised on all four (tier, authority) combinations used: (Hunt, reporting), (Hunt, blocking), (Hunt-read-only, blocking), (Yard, advisory). The contractile system is ready for the adversarial Gemini+Copilot drift pilot." diff --git a/.machine_readable/contractiles/dust/dust.ncl b/.machine_readable/contractiles/dust/dust.ncl deleted file mode 100644 index 36aa89b..0000000 --- a/.machine_readable/contractiles/dust/dust.ncl +++ /dev/null @@ -1,66 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Dust — exnovation / code-removal runner -# -# Pairs with: Dustfile.a2ml (same directory) -# Verb: dust -# Semantics: exnovation. Identifies code, docs, files, dependencies that are -# candidates for REMOVAL. Advisory by default; can be flipped to -# active delete via `contractile dust sweep --apply`. -# CLI: `contractile dust find` → list removal candidates -# `contractile dust sweep` → dry-run removals -# `contractile dust sweep --apply` → actually delete (gated) -# -# 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 = "dust", - semantics = "exnovation / removal", - security = { - leash = 'Kennel, - trust_level = "proposes deletion; --apply required to execute", - allow_network = false, - allow_filesystem_write = true, # --apply mode writes (deletes) - allow_subprocess = true, - destructive_mode_requires_flag = "--apply", - }, - metadata = { - name = "dust-runner", - version = "1.0.0", - description = "Identifies and optionally removes exnovation targets listed in Dustfile.a2ml. Destructive mode gated behind --apply.", - paired_xfile = "Dustfile.a2ml", - author = "Jonathan D.A. Jewell ", - }, - }, - - schema = { - removal_candidates - | Array { - id | String, - description | String, - target | String, # file / path / symbol / dep name - reason | String, # why it's a removal candidate - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - probe | String | optional, # command that confirms it's still removable - # dust has a non-standard status progression (no 'verified): - # 'declared → 'proposed → 'approved → 'removed - status | [| 'declared, 'proposed, 'approved, 'removed |] | default = 'declared, - approver | String | optional, # who signed off (for 'approved / 'removed) - notes | String | optional, - }, - }, - - # Runner behaviour — inherits from base.run_defaults. - # dust is advisory; apply_requires_approval is dust-specific. - run = base.run_defaults & { - on_any_fail = "continue-with-warnings", - report_format = "a2ml", - emit_summary = true, - apply_requires_approval = true, # only 'approved items get swept, even with --apply - }, -} diff --git a/.machine_readable/contractiles/intend/Intentfile.a2ml b/.machine_readable/contractiles/intend/Intentfile.a2ml deleted file mode 100644 index 42a5e1f..0000000 --- a/.machine_readable/contractiles/intend/Intentfile.a2ml +++ /dev/null @@ -1,96 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -# Intentfile (A2ML Canonical) — north-star contractile for NatSci Studio -# Author: Jonathan D.A. Jewell -# Co-developed with son — AGPL per the IDApTIK + Airborne Submarine Squadron pattern. -# -# Paired runner: intend.ncl (canonical) -# Paired K9: intend.k9.ncl (v2.0.0 — negotiation + accountability) - -@abstract: -NatSci Studio north star. An educational / research monorepo of -natural-sciences libraries with a Haskell-backed TUI console. NOT a -game engine, NOT a web app, NOT an Electron wrapper, NOT a commercial -venture. Intents are concrete committed next-actions; wishes are the -horizon; anything outside is scope creep. -@end - -## Anti-Purpose - -- NOT a monolithic game engine (the sandbox/meta-engine is a far wish). -- NOT an Electron app. JS tooling uses Deno. -- NOT a C++ project. C++ is banned estate-wide. -- NOT a commercial vehicle. "Billionaire in six weeks" style language - fails the Mustfile hype-word probe and the Bustfile commercial-hype probe. -- NOT a surface to adopt whatever framework this week's AI suggests. - -## Committed Next-Actions - -[[intents]] -id = "monorepo-foundation" -description = "Standards-compliant monorepo: libs/, tools/, demos/, docs/" -probe = "test -d libs && test -d tools && test -d demos && test -d docs" -status = "declared" - -[[intents]] -id = "haskell-console-minted" -description = "NatTrans Console exists as a Brick-based Haskell TUI" -probe = "test -f tools/console/app/Scaffold.hs && test -f tools/console/app/Verify.hs" -status = "declared" -notes = "btop++-inspired HUD, implemented in Haskell via Brick; NOT Electron, NOT Web." - -[[intents]] -id = "spdx-headers-every-source-file" -description = "Every source file in libs/ and tools/ has an SPDX-License-Identifier" -probe = "! grep -rL 'SPDX-License-Identifier' libs tools --include='*.hs' --include='*.rs' --include='*.ncl' 2>/dev/null | grep -q ." -status = "declared" - -[[intents]] -id = "wcag-aa-on-tui" -description = "NatTrans Console commits to WCAG 2.1 AA where applicable" -probe = "test -f tools/console/WCAG-AUDIT.adoc" -status = "declared" - -[[intents]] -id = "continuous-compliance-monitor" -description = "Verify.hs runs as a live compliance panel (not just a post-mint check)" -probe = "grep -q 'continuousMonitor' tools/console/app/Verify.hs 2>/dev/null" -status = "declared" -notes = "Promoted from Le Chat 2026-03-14 suggestion into a committed intent." - -[[intents]] -id = "dummy-newtonian-demo" -description = "A Newtonian-mechanics library with an ASCII trajectory demo" -probe = "test -d libs/newtonian-mechanics && test -f demos/newtonian-trajectory-ascii.hs" -status = "declared" - -[[intents]] -id = "deno-for-js-tooling" -description = "Any JS-side tooling uses Deno; no package.json for runtime deps" -probe = "! test -f package.json" -status = "declared" -notes = "Electron / Node / npm / pnpm / yarn / bun all banned." - -## Horizon Aspirations (wishes — NOT commitments) - -[[wishes]] -id = "natsci-sandbox-meta-engine" -description = "Lightweight meta-engine loading NatSci libraries and rendering 2D simulations" -horizon = "far" -why = "Demonstrates forge-and-observatory duality." -status = "declared" -notes = "WISH not intent. Building this now is scope creep; widening to intent needs an amendment." - -[[wishes]] -id = "compliance-tutorial-mode" -description = "Step-by-step tutorial wizard explaining each compliance standard" -horizon = "mid" -why = "Lowers contributor / educator barrier." -status = "declared" - -[[wishes]] -id = "philosophy-md" -description = "Root-level PHILOSOPHY.md articulating the monk/veil Flammarion metaphor" -horizon = "near" -why = "Identity clarity. Metaphor is ILLUSTRATIVE, not operational." -status = "declared" -notes = "Le Chat 2026-03-14 suggested promoting to tagline — that's a scope shift requiring amendment. As a wish this is fine." diff --git a/.machine_readable/contractiles/intend/intend.k9.ncl b/.machine_readable/contractiles/intend/intend.k9.ncl deleted file mode 100644 index 5b0c295..0000000 --- a/.machine_readable/contractiles/intend/intend.k9.ncl +++ /dev/null @@ -1,250 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# intend.k9.ncl — K9 trust-tier component of the intend trident -# Author: Jonathan D.A. Jewell -# -# Pairs with: Intentfile.a2ml (declaration) + intend.ncl (runner). -# Trident completeness is a hard precondition — a repo shipping -# Intentfile without this file AND its runner is an invalid trident; -# the contractile CLI's verify gate refuses partial publication. -# -# Verb: intend (north star — commitments + aspirations) -# Tier: Hunt (capability: subprocess probes may shell out) -# Authority: reporting (never blocks; drift-log only) -# -# Cardinality: ONE intend trident per repo (see feedback_contractile_ -# layout_rules.md). ANCHOR.a2ml is the sole multi-instance exception — -# it is NOT a verb contractile. -# -# Design commitments baked in (see memory trail 2026-04-18 for full -# context; key files referenced by name in annotations below): -# * α two-axis (tier × authority) — structurally separate capability -# from authority so "Hunt tier = can override" is impossible. -# * Variance schema first-class, not comment markers -# (feedback_audit_tool_suppression_design.md — structural > markers). -# * Sessional drift detection hooks (on_close, on_open). -# * Ratification at session open; drift log at session close. -# * Evidence sinks: VeriSimDB (queryable) + 6a2/DRIFT.a2ml (repo-local). -# * Failure-mode defenses cross-referenced to the AI failure catalog. - -let base_k9 = import "../k9/template-hunt.k9.ncl" in -let base = import "../_base.ncl" in - -{ - pedigree = base_k9.pedigree_schema & { - contractile_verb = "intend", - paired_xfile = "../intend/Intentfile.a2ml", - paired_runner = "../intend/intend.ncl", - - # α two-axis declaration — capability × authority. - # intend is Hunt-capable (probes shell out) but reporting-authority - # (never blocks). must/trust/bust will declare (Hunt, blocking); - # adjust/dust will declare (Yard, advisory). Splitting the axes - # means "I'm Hunt-tier so I can override everything" is structurally - # impossible — authority is a separate field. - tier = 'Hunt, - authority = 'reporting, - - metadata = { - name = "intend-k9", - version = "2.0.0", # 1.0.0 (2026-04-18 AM): initial trident. - # 2.0.0 (2026-04-18 PM): negotiation + - # accountability + plain-language-translation - # schema baked into on_open — prerequisite for - # the adversarial Gemini+Copilot drift pilot. - description = "Executes Intentfile probes + emits drift log. Non-gating; reporting authority only. on_open hook implements negotiation-ratification-accountability protocol.", - paired_xfile = "Intentfile.a2ml", - paired_runner = "intend.ncl", - author = "Jonathan D.A. Jewell ", - }, - - security = { - leash = 'Hunt, - trust_level = "subprocess + filesystem-read", - allow_network = false, - allow_filesystem_write = false, # evidence sinks are indirected - allow_subprocess = true, - }, - }, - - # ------------------------------------------------------------------- - # Variance schema — P-shape scoped exceptions per entry. - # A variance suppresses a specific intent's or wish's obligation for a - # reason, with approver + expiry. Expired variance = effective - # re-imposition of the obligation. Unmet intent without a variance = - # drift, logged to the drift log. - # Per user 2026-04-18: variances are structural, not magic-comment - # markers — markers are gameable. - # ------------------------------------------------------------------- - variance_schema = { - entry_id | String, # which intent/wish id the variance applies to - reason | String, - approved_by | String, - scope | String, # path glob | session-id | "until-" - expires | String, # absolute date or condition - review_notes | String | optional, - }, - - # ------------------------------------------------------------------- - # Execution policy - # ------------------------------------------------------------------- - execution = { - # When the component runs. - # session_close is mandatory (the "picked up sessionally" check). - triggers = [ 'session_close, 'on_demand, 'pre_push ], - - # Per-intent execution. - per_intent = { - run_probe = true, - record_outcome = true, - respect_variance = true, # active variance suppresses failure - on_unmet = 'log_drift, # never 'fail — authority = reporting - }, - - # Per-wish execution (wishes are non-probeable; horizon-group only). - per_wish = { - run_probe = false, - emit_horizon_summary = true, - # Vertical alignment soft-check per user_6a2_is_contractile_ought.md: - # highest-level alignment is meta ↔ north-star (soft), not hard gate. - check_alignment_with_META = true, - }, - - # Evidence sinks — BOTH written, every execution. - # VeriSimDB = queryable machine record (feedback_verisimdb_policy.md). - # 6a2/DRIFT.a2ml = repo-local append-only drift log (feedback_sessional_ - # drift_detection.md + user_6a2_is_contractile_ought.md descriptive role). - evidence_sinks = [ - { - kind = 'verisimdb, - table = "contractile_executions", - schema = "contractile_execution_v1", - }, - { - kind = 'drift_log, - path = ".machine_readable/6a2/DRIFT.a2ml", - append_only = true, - }, - ], - - # Session-close hook — the "picked up sessionally" requirement. - # Re-execute, diff against the last ratification, surface expired - # variances, emit drift entries for new failures. - on_close = { - re_execute_all_intents = true, - diff_against_last_ratification = true, - emit_drift_entries_for_new_failures = true, - surface_expired_variances = true, - }, - - # ----------------------------------------------------------------- - # Session-open hook — NEGOTIATION + RATIFICATION + ACCOUNTABILITY - # (user_contract_negotiation_and_accountability_pledge.md) - # (user_contractiles_agreed_at_session_start.md) - # - # Ratification is not passive acknowledgement; it is negotiation - # ending in an explicit accountability pledge from BOTH parties. - # Work cannot proceed before both pledges are on file. - # ----------------------------------------------------------------- - on_open = { - # --- Context presentation (pre-negotiation) --- - render_summary = 'plain_language, # metaphor-capture defense - include_drift_log_from_last_close = true, - include_active_variances = true, - include_recent_anchors = true, - anchor_lookback_weeks = 8, - - # --- Negotiation phase (five mandatory inputs) --- - # AI must surface all five before the user is asked to ratify. - # "Yes, and …" — not "yes". Missing any of the five = the - # negotiation is incomplete and work cannot proceed. - negotiation = { - required = true, # blank-cheque ratification refused - - # The five inputs the AI must contribute to the negotiation. - # Each is a structured field the agent is required to populate, - # not optional prose. See user_contract_negotiation_and_ - # accountability_pledge.md for the domain-language-rendering rule. - ai_required_inputs = [ - 'timeline_realism, # "this will take X; not Y" - 'industry_standards, # WCAG, ISO, OWASP, GDPR, licensing … - 'audience_feasibility, # real addressable user set - 'resulting_invariants, # what must/trust/adjust entries follow - 'ecosystem_dependencies, # libs, licences, threat-model implications - ], - - # User must actually engage with each input — not - # auto-approve. If user tries to skip ("just do it, I trust you") - # the system re-renders the obligations and requires the pledge. - user_engagement_required = true, - user_engagement_mode = 'per_input_response, - - # The AI does the specification-form work. The user reviews the - # rendering in domain language and accepts / amends / pushes back. - # User never has to author Nickel schemas or decide on type - # specificity — that is the AI's translation responsibility, - # with auditable faithfulness. - specification_translation = { - ai_produces_spec_form = true, - user_reviews_in_domain_language = true, - schema_authoring_is_ai_responsibility = true, - translation_faithfulness_auditable = true, - # Failure mode this closes: user is forced to learn spec-theory - # (type refinement, Nickel contract grammar) to ratify a contract - # — which drives users away from ratification entirely. - }, - }, - - # --- Accountability pledge (both parties, explicit) --- - # Not "I read it" — "I am answerable for this obligation". - # Both pledges are required before work proceeds; both are recorded. - accountability_pledge = { - required = true, - parties = [ - { - role = 'user, - pledge = "I have reviewed the obligations as negotiated; I accept accountability for meeting the declared invariants and for the audience/timeline/standards consequences surfaced in negotiation.", - signature_required = true, - }, - { - role = 'ai_agent, - pledge = "I will hold the user to the obligations as negotiated, including by surfacing drift at session close and refusing off-contract actions, even when the user is enthusiastic about them. If the user wishes to depart from the contract, I will require a variance or amendment, not silent acceptance.", - signature_required = true, - # Per user_contractile_is_contract_do_not_break.md — - # the AI is the holder of the line against enthusiasm drift. - }, - ], - signed_record_destination = ".machine_readable/6a2/ratification-.a2ml", - must_precede_work = true, - }, - - # --- Policy: ratification output --- - # The ratification record IS the negotiation transcript + the - # accountability pledge combined. One document; future-session - # ground-truth for "what was agreed, who is accountable". - ratification_record_shape = { - includes_negotiation_transcript = true, - includes_both_pledges = true, - signed = true, - dated = true, - session_id = 'required, - contract_hash = 'required, # pins what was actually signed - }, - }, - }, - - # ------------------------------------------------------------------- - # Failure-mode defenses — explicit cross-reference to the catalog - # (feedback_ai_failure_mode_catalog.md). New catalog entries that - # shift this verb's defenses must update this list, not narrative. - # ------------------------------------------------------------------- - failure_mode_defenses = [ - 'A1_enthusiasm_capture, # scope breach → drift log - 'A2_metaphor_capture, # render_summary = 'plain_language - 'A3_allegory_drift, # intents cite concrete obligations - 'C1_scope_creep, # feature-adjacent change needs intent_id - 'C3_helpfulness_inflation, # changes without intent_id flagged - 'C4_modernization_drift, # upgrade cannot cite intent → drift - 'D5_sycophancy, # ratification compares user framing vs contract - 'F1_across_session_forgetting, # on_open reads last-ratification record - ], -} diff --git a/.machine_readable/contractiles/intend/intend.manifest.a2ml b/.machine_readable/contractiles/intend/intend.manifest.a2ml deleted file mode 100644 index 5d932a6..0000000 --- a/.machine_readable/contractiles/intend/intend.manifest.a2ml +++ /dev/null @@ -1,73 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# intend.manifest.a2ml — Trident coherence manifest for the intend verb. -# Author: Jonathan D.A. Jewell -# -# Asserts: exactly three files constitute the intend trident; their -# content-hashes are pinned here; cross-references round-trip; no -# partial publication is permitted. -# -# The contractile CLI's `verify ` subcommand MUST: -# 1. Confirm all three listed files exist at the declared paths. -# 2. Compute each file's sha256 and match against the pinned value. -# 3. Follow each cross-reference and confirm the target file's -# reciprocal field points back. -# 4. Refuse the dir (exit non-zero) if any of 1–3 fails. -# -# This forecloses the failure mode where an agent publishes an A2ML -# declaration with no paired runner or K9 component — the trident is -# atomically complete or it is invalid. - ---- -trident_version = "1.0.0" -verb = "intend" -semantics = "north-star (commitments + aspirations)" -cardinality = "one per repo" - -## Files (three; exactly) - -[[files]] -role = "declaration" -path = "Intentfile.a2ml" -sha256 = "pending-first-verify" # populated on first `contractile verify intend` -size_bytes = "pending-first-verify" - -[[files]] -role = "runner" -path = "intend.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -[[files]] -role = "k9_component" -path = "intend.k9.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" - -## Cross-references (must round-trip) - -[cross_refs] -# Each runner/K9 component names its paired files; the CLI follows the -# links and asserts reciprocity. Any dangling or mismatched reference -# fails the verify gate. -runner_paired_xfile = "Intentfile.a2ml" -k9_paired_xfile = "../intend/Intentfile.a2ml" -k9_paired_runner = "../intend/intend.ncl" - -## Trident signing - -[signed_by] -user = "Jonathan D.A. Jewell" -date = "2026-04-18" -context = "intend trident pilot — first Trident instance in the estate; template for the remaining 5 verbs (must/trust/bust/adjust/dust) and for the 14 template-copy dirs." - -## Change log - -[[history]] -date = "2026-04-18" -event = "trident-born" -note = "intend/Intentfile.a2ml pre-existed (f380b62, lust absorption). This manifest + intend.k9.ncl complete the trident for the first time." - -[[history]] -date = "2026-04-18" -event = "negotiation-accountability-schema-landed" -note = "intend.k9.ncl on_open hook extended: five negotiation inputs (timeline/standards/audience/invariants/dependencies), both-parties accountability pledge, plain-language-translation policy (AI authors spec form, user reviews in domain language). K9 metadata version bumped 1.0.0 → 2.0.0. Prerequisite for the adversarial Gemini+Copilot drift pilot; intend is the hardest verb (abstract north-star) so baking the full protocol here first means simpler verbs (trust, must) can inherit the template." diff --git a/.machine_readable/contractiles/intend/intend.ncl b/.machine_readable/contractiles/intend/intend.ncl deleted file mode 100644 index 091b7f6..0000000 --- a/.machine_readable/contractiles/intend/intend.ncl +++ /dev/null @@ -1,81 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Intend — north-star runner (verb is `intend`, file is `Intentfile.a2ml`) -# -# Pairs with: Intentfile.a2ml (same directory) -# Verb: intend -# Semantics: Declares BOTH concrete committed next-actions ([[intents]]) and -# horizon aspirations ([[wishes]]). Not a gate — reports progress -# toward declared intents and lists wishes by horizon. -# Status progressions: -# intents: 'declared → 'in_progress → 'done | 'deferred | 'retired -# wishes: 'declared → 'in_progress → 'achieved | 'abandoned -# CLI: `contractile intend run` → print status table (both sections) -# `contractile intend progress` → diff declared-vs-observed (intents) -# `contractile intend horizon` → group wishes by near/mid/far -# -# History: Absorbed the deprecated `lust` contractile's [[wishes]] schema -# 2026-04-18. `lust/` dir removed estate-wide. -# -# 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 = "intend", - semantics = "north-star (commitments + aspirations)", - security = { - leash = 'Kennel, - trust_level = "read-only reporting", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = true, # probe commands may shell out (intents only; wishes never probe) - }, - metadata = { - name = "intend-runner", - version = "2.0.0", - description = "Reports progress toward committed next-actions and lists horizon aspirations. Non-gating. Absorbed `lust` semantics 2026-04-18.", - paired_xfile = "Intentfile.a2ml", - author = "Jonathan D.A. Jewell ", - }, - }, - - schema = { - intents - | Array { - id | String, - description | String, - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - probe | String | optional, # shell command that indicates done-ness - status | [| 'declared, 'in_progress, 'done, 'deferred, 'retired |] | default = 'declared, - notes | String | optional, - target_date | String | optional, - }, - wishes - | Array { - id | String, - description | String, - horizon | [| 'near, 'mid, 'far |] | default = 'mid, - why | String | optional, - status | [| 'declared, 'in_progress, 'achieved, 'abandoned |] | default = 'declared, - notes | String | optional, - } - | optional, - }, - - # Runner behaviour — inherits from base.run_defaults. - # intend never blocks; it is a report only. - # emit_diff is intent-specific (declared vs observed probes). - # emit_grouped_by_horizon renders wishes grouped by near/mid/far. - run = base.run_defaults & { - on_pass = "continue", - on_any_fail = "continue", # never blocks; it's a report - report_format = "a2ml", - emit_summary = true, - emit_diff = true, # declared vs observed (intents) - emit_grouped_by_horizon = true, # wishes grouped by horizon (absorbed from lust) - }, -} diff --git a/.machine_readable/contractiles/must/Mustfile.a2ml b/.machine_readable/contractiles/must/Mustfile.a2ml deleted file mode 100644 index eae5a10..0000000 --- a/.machine_readable/contractiles/must/Mustfile.a2ml +++ /dev/null @@ -1,103 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -# Mustfile (A2ML Canonical) — release-blocking invariants for NatSci Studio -# Author: Jonathan D.A. Jewell -# Paired runner: must.ncl | Paired K9: must.k9.ncl (v1.0.0) - -@abstract: -NatSci Studio release-blocking invariants. Each is a hard gate. Breach -blocks merge until resolved or varied by a maintainer-approved variance -with explicit severity acknowledgement. -@end - -## File-level invariants - -[[invariants]] -id = "spdx-header-every-source-file" -description = "Every source file carries an SPDX-License-Identifier" -probe = "! grep -rL 'SPDX-License-Identifier' libs tools --include='*.hs' --include='*.rs' --include='*.ncl' --include='*.ts' --include='*.js' 2>/dev/null | grep -q ." -severity = "critical" - -[[invariants]] -id = "licence-file-present" -description = "Root LICENSE file exists (AGPL-3.0-or-later)" -probe = "test -r LICENSE && grep -q 'AGPL' LICENSE" -severity = "critical" - -[[invariants]] -id = "ai-manifest-present" -description = "0-AI-MANIFEST.a2ml is the universal AI entry point" -probe = "test -r 0-AI-MANIFEST.a2ml" -severity = "critical" - -## Language-policy invariants (the main drift catchment) - -[[invariants]] -id = "no-cpp-sources" -description = "No .cpp / .cc / .cxx / .hpp / .hxx anywhere (banned estate-wide; Rust/SPARK is the alt)" -probe = "! find . -type f \\( -name '*.cpp' -o -name '*.cc' -o -name '*.cxx' -o -name '*.hpp' -o -name '*.hxx' \\) -not -path './.git/*' 2>/dev/null | grep -q ." -severity = "critical" -notes = "Catches the 'lightweight C++ core for performance' AI-suggestion pattern." - -[[invariants]] -id = "no-electron" -description = "No Electron references in descriptors or source" -probe = "! grep -riE '\\belectron\\b' --include='*.json' --include='*.toml' --include='*.hs' . 2>/dev/null | grep -v 'banned\\|Mustfile\\|Bustfile\\|Trustfile' | grep -q ." -severity = "critical" - -[[invariants]] -id = "no-nodejs-runtime-deps" -description = "No package.json for runtime deps (Deno only)" -probe = "! test -f package.json" -severity = "high" - -[[invariants]] -id = "no-python-sources" -description = "No .py files (Python banned estate-wide per 2026-01-03)" -probe = "! find . -type f -name '*.py' -not -path './.git/*' 2>/dev/null | grep -q ." -severity = "high" - -[[invariants]] -id = "no-typescript-sources" -description = "No .ts / .tsx files (ReScript only for typed JS)" -probe = "! find . -type f \\( -name '*.ts' -o -name '*.tsx' \\) -not -path './.git/*' 2>/dev/null | grep -q ." -severity = "medium" - -[[invariants]] -id = "no-go-sources" -description = "No .go files (Rust is the estate alternative)" -probe = "! find . -type f -name '*.go' -not -path './.git/*' 2>/dev/null | grep -q ." -severity = "high" - -## Monorepo-structure invariants - -[[invariants]] -id = "monorepo-structure-four-dirs" -description = "The four canonical directories (libs, tools, demos, docs) are present" -probe = "test -d libs && test -d tools && test -d demos && test -d docs" -severity = "high" - -[[invariants]] -id = "no-monolithic-engine-directory" -description = "No engine/ directory — NatSci Studio is engine-agnostic per Intentfile; sandbox is a far wish, not an intent" -probe = "! test -d engine && ! test -d core/engine && ! test -d natsci-engine" -severity = "high" - -## Compliance-machinery invariants (trident coherence) - -[[invariants]] -id = "trident-intend-complete" -description = "intend trident has all 4 files" -probe = "test -r .machine_readable/contractiles/intend/Intentfile.a2ml && test -r .machine_readable/contractiles/intend/intend.ncl && test -r .machine_readable/contractiles/intend/intend.k9.ncl && test -r .machine_readable/contractiles/intend/intend.manifest.a2ml" -severity = "critical" - -[[invariants]] -id = "trident-trust-complete" -description = "trust trident has all 4 files" -probe = "test -r .machine_readable/contractiles/trust/Trustfile.a2ml && test -r .machine_readable/contractiles/trust/trust.ncl && test -r .machine_readable/contractiles/trust/trust.k9.ncl && test -r .machine_readable/contractiles/trust/trust.manifest.a2ml" -severity = "critical" - -[[invariants]] -id = "trident-must-complete" -description = "must trident has all 4 files" -probe = "test -r .machine_readable/contractiles/must/Mustfile.a2ml && test -r .machine_readable/contractiles/must/must.ncl && test -r .machine_readable/contractiles/must/must.k9.ncl && test -r .machine_readable/contractiles/must/must.manifest.a2ml" -severity = "critical" diff --git a/.machine_readable/contractiles/must/must.k9.ncl b/.machine_readable/contractiles/must/must.k9.ncl deleted file mode 100644 index 6bb51fc..0000000 --- a/.machine_readable/contractiles/must/must.k9.ncl +++ /dev/null @@ -1,236 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# must.k9.ncl — K9 trust-tier component of the must trident -# Author: Jonathan D.A. Jewell -# -# Pairs with: Mustfile.a2ml (declaration) + must.ncl (runner). -# Trident completeness is a hard precondition — a repo shipping -# Mustfile without this file AND its runner is an invalid trident; -# the contractile CLI's verify gate refuses partial publication. -# -# Verb: must (invariant assertion — release-blocking) -# Tier: Hunt-read-only (capability: subprocess probes shell out -# for grep/test/file-check; no mutation; -# no network; no write) -# Authority: blocking (HARD GATE — the canonical gating verb) -# -# must is the concrete + persistent verb — release-blocking invariants -# that must hold. Complement to trust (concrete + ephemeral). Together -# must + trust form the blocking-authority pair in the contractile set. -# -# Cardinality: ONE must trident per repo. -# -# Failure-mode focus: must is the primary catchment for subtle -# invariant-erosion drift. Where trust catches "turn off the firewall" -# (outrageous), must catches "this file that was required is now -# missing" / "this forbidden pattern has reappeared" / "this schema -# version regressed" (subtle). Key defense against A5 (commercial -# fabrication of success "facts" — invariants ground truth against -# marketing copy) and D1 (lore fabrication about what the repo contains). - -let base_k9 = import "../k9/template-hunt.k9.ncl" in -let base = import "../_base.ncl" in - -{ - pedigree = base_k9.pedigree_schema & { - contractile_verb = "must", - paired_xfile = "../must/Mustfile.a2ml", - paired_runner = "../must/must.ncl", - - # α two-axis: Hunt tier (subprocess for grep/test/etc.) but - # restricted to read-only operations. Blocking authority because - # must is the canonical gating verb. - tier = 'Hunt, - authority = 'blocking, - - metadata = { - name = "must-k9", - version = "1.0.0", - description = "Evaluates release-blocking invariants as a hard gate. Third trident instance. Complements trust (ephemeral blocking) with persistent invariant blocking.", - paired_xfile = "Mustfile.a2ml", - paired_runner = "must.ncl", - author = "Jonathan D.A. Jewell ", - }, - - security = { - leash = 'Hunt, - trust_level = "read-only invariant verification with subprocess", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = true, - probe_scope = 'read_only, # must probes NEVER mutate - probe_kinds_allowed = [ - 'file_existence, - 'pattern_presence, - 'pattern_absence, - 'schema_match, - 'version_equality, - 'count_threshold, - ], - probe_kinds_denied = [ - 'network_call, - 'filesystem_mutation, - 'external_api, - 'exploit_attempt, # that's trust's safe_hacking territory - ], - }, - }, - - # ------------------------------------------------------------------- - # Variance schema — trust-style severity acknowledgement. - # Because must is BLOCKING, variances carry real weight. Critical- - # severity invariants can only be varied by maintainer-or-above. - # ------------------------------------------------------------------- - variance_schema = { - entry_id | String, # which invariant id the variance applies to - reason | String, - approved_by | String, # maintainer or above for critical-severity - scope | String, # path glob | session-id | "until-" - expires | String, # absolute date; must variances cannot be open-ended - review_notes | String | optional, - severity_acknowledged | [| 'critical, 'high, 'medium |], - waived_consequence_description | String, # plain language — what breaking the invariant actually does - }, - - execution = { - triggers = [ 'session_close, 'on_demand, 'pre_push, 'pre_merge ], - - # Per-invariant execution. Failed invariant = blocked merge. - per_invariant = { - run_probe = true, - record_outcome = true, - respect_variance = true, # active variance suppresses the gate - on_unmet = 'fail, # BLOCKING - severity_escalation = 'honour, - # Subtle-erosion defense: track per-invariant trend over sessions. - # An invariant that passes once and then starts failing in a - # later session without explicit amendment = suspect drift; - # surface as high-priority drift log entry. - track_per_session_trend = true, - flag_suspicious_regressions = true, - }, - - evidence_sinks = [ - { - kind = 'verisimdb, - table = "contractile_executions", - schema = "contractile_execution_v1", - aux_tables = [ "must_invariant_history" ], # per-invariant trend record - }, - { - kind = 'drift_log, - path = ".machine_readable/6a2/DRIFT.a2ml", - append_only = true, - }, - ], - - # Session-close hook — re-evaluate all invariants. Block close on - # critical drift (same policy as trust). - on_close = { - re_execute_all_invariants = true, - diff_against_last_ratification = true, - emit_drift_entries_for_new_failures = true, - surface_expired_variances = true, - # Critical must drift blocks session close — consistent with trust. - block_session_close_on_critical_drift = true, - # Must-specific: if a previously-passing invariant is now failing - # without an associated variance or amendment, that's suspected - # silent regression — surface prominently at next session open. - flag_silent_regression = true, - }, - - # ----------------------------------------------------------------- - # Session-open hook — NEGOTIATION + RATIFICATION + ACCOUNTABILITY - # (inherited from intend.k9.ncl v2.0.0 + trust.k9.ncl extensions) - # ----------------------------------------------------------------- - on_open = { - # --- Context presentation --- - render_summary = 'plain_language, - include_drift_log_from_last_close = true, - include_active_variances = true, - include_recent_anchors = true, - anchor_lookback_weeks = 8, - - # Must-specific: surface any silent regressions flagged at last - # close so they can't quietly persist across sessions. - include_silent_regressions = true, - - # --- Negotiation phase (five mandatory inputs) --- - negotiation = { - required = true, - ai_required_inputs = [ - 'timeline_realism, - 'industry_standards, # what invariants derive from external standards - 'audience_feasibility, # who is the invariant protecting - 'resulting_invariants, # what NEW must entries result from the work - 'ecosystem_dependencies, # what the invariants depend on - ], - user_engagement_required = true, - user_engagement_mode = 'per_input_response, - specification_translation = { - ai_produces_spec_form = true, - user_reviews_in_domain_language = true, - schema_authoring_is_ai_responsibility = true, - translation_faithfulness_auditable = true, - }, - }, - - # --- Accountability pledge --- - # Must's pledge parallels trust's but around invariants rather - # than threat model. User pledges not to disable invariants to - # unblock merges; AI pledges to hold the line on declared - # invariants even against enthusiastic scope expansion. - accountability_pledge = { - required = true, - parties = [ - { - role = 'user, - pledge = "I have reviewed the declared invariants and the consequences of breaching them. I accept accountability for meeting these invariants and understand that failed invariants block merges. I will raise a variance (with severity acknowledgement) or an amendment rather than disabling a probe to unblock a merge.", - signature_required = true, - }, - { - role = 'ai_agent, - pledge = "I will hold the declared invariants. I will refuse to weaken probes to unblock merges; I will refuse scope-creep suggestions that would remove an invariant silently; I will surface silent regressions at session close; I will require variance-with-severity or amendment for any legitimate scope shift, not quiet probe disablement.", - signature_required = true, - }, - ], - signed_record_destination = ".machine_readable/6a2/ratification-.a2ml", - must_precede_work = true, - }, - - ratification_record_shape = { - includes_negotiation_transcript = true, - includes_both_pledges = true, - includes_invariant_summary = true, # must-specific - signed = true, - dated = true, - session_id = 'required, - contract_hash = 'required, - }, - }, - }, - - # ------------------------------------------------------------------- - # Failure-mode defenses — must's specialisation is subtle-invariant - # erosion. Overlaps with trust on blocking authority but focused on - # persistent invariants rather than ephemeral transactional state. - # ------------------------------------------------------------------- - failure_mode_defenses = [ - # Category A — enthusiasm capture - 'A1_enthusiasm_capture, # scope breach via blocking authority - 'A5_grandiose_scale_hype, # invariants are ground truth vs commercial hype - # Category C — scope/capability erosion - 'C1_scope_creep, # feature-adjacent changes flagged if they break invariants - 'C2_capability_collapse, # invariant removal requires amendment - 'C3_helpfulness_inflation, # added features must respect declared invariants - # Category D — epistemic failures - 'D1_lore_fabrication, # invariants are verifiable truth, not AI-recollection - 'D2_completeness_illusion, # invariant probe must cite behavioural check, not build-success - 'D3_test_theatre, # invariants require real verification not mock-passing - 'D4_error_hiding, # on_unmet = 'fail makes hiding impossible - # Category E — refactor/churn - 'E1_refactor_stampede, # refactor must preserve invariants - 'E3_premature_abstraction, # abstraction must not violate invariants - # Category F — session drift - 'F1_across_session_forgetting, # track_per_session_trend catches re-introduction - ], -} diff --git a/.machine_readable/contractiles/must/must.manifest.a2ml b/.machine_readable/contractiles/must/must.manifest.a2ml deleted file mode 100644 index c43cd05..0000000 --- a/.machine_readable/contractiles/must/must.manifest.a2ml +++ /dev/null @@ -1,59 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# must.manifest.a2ml — Trident coherence manifest for the must verb. -# Author: Jonathan D.A. Jewell -# -# Third trident instance in the estate. Completes the blocking-authority -# pair (must + trust). must is concrete + persistent invariants; trust -# is concrete + ephemeral transactions. Together they gate every -# security- and invariant-affecting merge. - ---- -trident_version = "1.0.0" -verb = "must" -semantics = "invariant assertion — release-blocking" -cardinality = "one per repo" -authority = "blocking (hard gate)" - -## Files (three; exactly) - -[[files]] -role = "declaration" -path = "Mustfile.a2ml" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" -notes = "Mustfile declaration — invariants each with id, description, probe, severity." - -[[files]] -role = "runner" -path = "must.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" -notes = "Runner pre-existed. Schema covers invariants array with status_core + severity." - -[[files]] -role = "k9_component" -path = "must.k9.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" -notes = "Hunt-restricted read-only tier; blocking authority. Tracks per-invariant trend across sessions; flags silent regressions; blocks session close on critical drift." - -## Cross-references (must round-trip) - -[cross_refs] -runner_paired_xfile = "Mustfile.a2ml" -k9_paired_xfile = "../must/Mustfile.a2ml" -k9_paired_runner = "../must/must.ncl" - -## Trident signing - -[signed_by] -user = "Jonathan D.A. Jewell" -date = "2026-04-18" -context = "must trident — third Trident instance. Completes the blocking-authority pair (must + trust). Specialises in subtle invariant-erosion catchment vs trust's outrageous-attack catchment." - -## Change log - -[[history]] -date = "2026-04-18" -event = "trident-born" -note = "Mustfile.a2ml and must.ncl pre-existed. This manifest + must.k9.ncl complete the trident. Inherits on_open schema from intend.k9.ncl v2.0.0; inherits block_session_close_on_critical_drift + variance-severity-acknowledgement from trust.k9.ncl v1.0.0; adds must-specific track_per_session_trend + flag_silent_regression + probe_scope = 'read_only (must doesn't do active exploit attempts — that's trust's safe_hacking territory)." diff --git a/.machine_readable/contractiles/must/must.ncl b/.machine_readable/contractiles/must/must.ncl deleted file mode 100644 index 47509d3..0000000 --- a/.machine_readable/contractiles/must/must.ncl +++ /dev/null @@ -1,64 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Must — invariants runner -# -# Pairs with: Mustfile.a2ml (same directory) -# Verb: must (invariant assertion) -# Semantics: every check is a hard gate. A single failure blocks merge. -# CLI: `contractile must run` → reads Mustfile.a2ml, evaluates each check, -# emits pass/fail verdict per item, exits non-zero if any failed. -# -# This file is the *schema + runner* that the `contractile` CLI (at -# /var/mnt/eclipse/repos/reposystem/contractiles/cli/) loads alongside -# Mustfile.a2ml. Anything else in this directory is human-only notes/archive -# and MUST be ignored by machines. -# -# 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 = "must", - semantics = "invariant", - security = { - leash = 'Kennel, - trust_level = "read-only verification", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = true, # verification probes may shell out (e.g. grep, test -f) - }, - metadata = { - name = "must-runner", - version = "1.0.0", - description = "Evaluates every invariant in the adjacent Mustfile.a2ml as a hard gate.", - paired_xfile = "Mustfile.a2ml", - author = "Jonathan D.A. Jewell ", - }, - }, - - # Contract schema — the shape every Mustfile.a2ml must satisfy. - # Used by `contractile must typecheck Mustfile.a2ml`. - schema = { - invariants - | Array { - id | String, - description | String, - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - probe | String, # shell command; exit 0 = pass - # status_core values: 'declared, 'verified, 'failing - status | [| 'declared, 'verified, 'failing |] | default = 'declared, - severity | [| 'critical, 'high, 'medium |] | default = 'critical, - notes | String | optional, - fix | String | optional, - }, - }, - - # Runner behaviour — consumed by the contractile CLI dispatcher. - # Inherits from base.run_defaults; on_any_fail is the hard-gate default. - run = base.run_defaults & { - on_any_fail = "exit-nonzero", # hard gate - report_format = "a2ml", # emit a2ml report, not json - emit_summary = true, - }, -} diff --git a/.machine_readable/contractiles/trust/Trustfile.a2ml b/.machine_readable/contractiles/trust/Trustfile.a2ml deleted file mode 100644 index 6178689..0000000 --- a/.machine_readable/contractiles/trust/Trustfile.a2ml +++ /dev/null @@ -1,91 +0,0 @@ -# SPDX-License-Identifier: AGPL-3.0-or-later -# Trustfile (A2ML Canonical) — security + threat model for NatSci Studio -# Author: Jonathan D.A. Jewell -# Paired runner: trust.ncl | Paired K9: trust.k9.ncl (v1.0.0) -# -# NatSci Studio is a local-TUI educational toolkit — do NOT inherit the -# heavyweight web-facing Trustfile exemplar. Primary adversary is -# scope-creep AI assistance and educational misinformation. - -@abstract: -Trust boundary + threat model for NatSci Studio. Local TUI + Haskell -libraries. Different threat surface from a web service. Primary -concerns: AI scope-creep, educational claim accuracy, toolchain discipline. -@end - -## Threat model - -[[threat_model]] -adversary = "scope_creep_AI_assistant" -description = "Gemini / Copilot / Le Chat / other AI assistants suggesting features outside declared scope, hyping inflated claims, or proposing banned languages / frameworks." -stakes = "project-identity-integrity" -mitigations = [ - "Intentfile north-star narrows declared scope; amendments required for shifts.", - "Mustfile language-policy invariants block C++, Python, Electron, Node at merge.", - "Bustfile hard-stops catch reintroduction of banned patterns.", - "K9 on_open threat_model_foregrounding re-renders this block before any weakening suggestion lands.", - "Accountability pledge requires AI to refuse off-contract actions under enthusiasm.", -] - -[[threat_model]] -adversary = "educational_misinformation" -description = "Libraries publish natural-science claims (constants, formulas, simulation outputs) incorrectly or without citation." -stakes = "credibility" -mitigations = [ - "Every physics/chemistry constant cites its CODATA / IUPAC / NIST source.", - "Every formula cites textbook / paper / standard.", - "Verify.hs checks citation presence at build time.", -] - -[[threat_model]] -adversary = "supply_chain_compromise" -description = "Dependency compromise introduces malicious code." -stakes = "local-machine-integrity" -mitigations = [ - "Nix flakes for hermetic builds with hash-pinned deps.", - "Chainguard Wolfi base images for any containerised tool.", - "SBOM generated per library.", -] - -## Language-policy verifications - -[[verifications]] -id = "language-policy-no-cpp" -description = "No C++ sources anywhere" -probe = "! find . -type f \\( -name '*.cpp' -o -name '*.cc' -o -name '*.cxx' -o -name '*.hpp' \\) -not -path './.git/*' 2>/dev/null | grep -q ." -severity = "critical" - -[[verifications]] -id = "language-policy-no-electron" -description = "No Electron in package descriptors or source" -probe = "! grep -riE '\\belectron\\b' --include='*.json' --include='*.toml' . 2>/dev/null | grep -v 'banned\\|Trustfile\\|Mustfile\\|Bustfile' | grep -q ." -severity = "critical" - -[[verifications]] -id = "language-policy-approved-only" -description = "Source files in approved languages only (Haskell, Rust, Nickel, Deno/ReScript, Bash)" -probe = "! find . -type f -not -path './.git/*' \\( -name '*.py' -o -name '*.cpp' -o -name '*.ts' -o -name '*.go' -o -name '*.kt' -o -name '*.swift' \\) 2>/dev/null | grep -q ." -severity = "high" - -## Provenance / citation - -[[verifications]] -id = "physics-constants-cited" -description = "Every physics constant in libs/ carries a CODATA / NIST / IUPAC citation" -probe = "test ! -d libs || ! (grep -rL 'CODATA\\|NIST\\|IUPAC' libs --include='*.hs' 2>/dev/null | xargs -I {} grep -l 'constant' {} 2>/dev/null | grep -q .)" -severity = "high" - -## SPDX hygiene - -[[verifications]] -id = "spdx-headers-everywhere" -description = "Every source file has an SPDX-License-Identifier" -probe = "! grep -rL 'SPDX-License-Identifier' libs tools demos --include='*.hs' --include='*.rs' --include='*.ncl' 2>/dev/null | grep -q ." -severity = "high" - -## Safe-hacking (none yet) - -[[safe_hacking]] -scope = "this-repo-only" -allowed_probe_classes = [ "fuzz", "property_test" ] -probes = [ ] diff --git a/.machine_readable/contractiles/trust/trust.k9.ncl b/.machine_readable/contractiles/trust/trust.k9.ncl deleted file mode 100644 index 6e61ed3..0000000 --- a/.machine_readable/contractiles/trust/trust.k9.ncl +++ /dev/null @@ -1,276 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# trust.k9.ncl — K9 trust-tier component of the trust trident -# Author: Jonathan D.A. Jewell -# -# Pairs with: Trustfile.a2ml (declaration) + trust.ncl (runner). -# Trident completeness is a hard precondition — a repo shipping -# Trustfile without this file AND its runner is an invalid trident; -# the contractile CLI's verify gate refuses partial publication. -# -# Verb: trust (security + provenance + safe-hacking) -# Tier: Hunt (capability: subprocess probes may shell out, -# active probes in safe_hacking section) -# Authority: blocking (HARD GATE — opposite of intend's reporting) -# -# trust is the concrete + ephemeral + transactional verb per user -# 2026-04-18: port use, BLAKE3 hashing, auth challenges, TLS state, -# session tokens. Every probe has instant binary ground truth. -# This is the α two-axis complement to intend: both Hunt-tier, opposite -# authority poles. Validating the architecture on both exercises the -# full (tier, authority) surface. -# -# Cardinality: ONE trust trident per repo (see feedback_contractile_ -# layout_rules.md). ANCHOR.a2ml is the sole multi-instance exception — -# it is NOT a verb contractile. -# -# Design commitments baked in (full memory trail under -# ~/.claude/projects/-var-mnt-eclipse-repos/memory/ 2026-04-18): -# * α two-axis (Hunt, blocking) — trust is where the contractile system -# grows teeth. Failed verification = failed CI = blocked merge. -# * Variance schema first-class — scoped exceptions structural, not -# comment markers. -# * Sessional drift detection hooks — re-verify every close. -# * Ratification negotiation with threat-model foregrounded -# (feedback_ai_failure_mode_catalog.md B1 — threat-model -# misclassification is the PRIMARY defense trust provides). -# * Accountability pledge — both parties sign before security-affecting -# work proceeds. -# * Plain-language translation — user never authors a Nickel schema for -# a cipher suite; AI does the spec work, user reviews in domain -# language ("TLS 1.3 with PQ key exchange, HSTS preload, 1yr"). -# * Evidence sinks: VeriSimDB (queryable) + 6a2/DRIFT.a2ml (repo-local). -# * Failure-mode defenses cross-referenced — trust carries the most -# defenses of any verb because the threat surface is widest. - -let base_k9 = import "../k9/template-hunt.k9.ncl" in -let base = import "../_base.ncl" in - -{ - pedigree = base_k9.pedigree_schema & { - contractile_verb = "trust", - paired_xfile = "../trust/Trustfile.a2ml", - paired_runner = "../trust/trust.ncl", - - # α two-axis declaration — capability × authority. - # trust is Hunt-capable (active probes shell out, safe-hacking section - # runs real fuzz/injection/auth-bypass attempts scoped to the repo) - # AND blocking-authority (failed verification = failed CI). - # Contrast with intend = (Hunt, reporting). The two verbs exercise - # the full α surface. - tier = 'Hunt, - authority = 'blocking, - - metadata = { - name = "trust-k9", - version = "1.0.0", - description = "Executes security verifications + authorised safe-hacking probes. HARD GATE: failed verification blocks merge. Catches the 'turn off the firewall' class of drift directly. Implements negotiation-ratification-accountability protocol inherited from intend.k9.ncl v2.0.0.", - paired_xfile = "Trustfile.a2ml", - paired_runner = "trust.ncl", - author = "Jonathan D.A. Jewell ", - }, - - security = { - leash = 'Hunt, - trust_level = "verification + authorised-probe + hard-gate", - allow_network = false, # verifications offline by default - allow_filesystem_write = false, # evidence sinks are indirected - allow_subprocess = true, - authorised_probes_only = true, # probe section explicitly lists allowed targets + probe classes - probe_scope_enforcement = 'this_repo_only, # probes NEVER hit external systems - }, - }, - - # ------------------------------------------------------------------- - # Variance schema — P-shape scoped exceptions per verification. - # A variance suppresses a specific verification's obligation for a - # reason, with approver + expiry. Because trust is BLOCKING authority, - # variances on trust entries are SIGNIFICANTLY more consequential than - # variances on intend (reporting) entries — variance approver MUST - # be the repo maintainer or above for critical-severity entries. - # ------------------------------------------------------------------- - variance_schema = { - entry_id | String, # which verification / probe id - reason | String, - approved_by | String, # maintainer or above for critical entries - scope | String, # path glob | session-id | "until-" - expires | String, # absolute date; trust variances cannot be open-ended - review_notes | String | optional, - # Additional trust-specific guardrails: - severity_acknowledged | [| 'critical, 'high, 'medium, 'low |], - waived_risk_description | String, # plain language — what is being accepted - }, - - # ------------------------------------------------------------------- - # Execution policy - # ------------------------------------------------------------------- - execution = { - # When the component runs. - # pre_push + pre_commit on anything touching security-adjacent files - # + session_close (drift check) + on_demand. - triggers = [ 'session_close, 'on_demand, 'pre_push, 'pre_commit_security_adjacent ], - - # Per-verification execution. Failed verification = blocked merge. - per_verification = { - run_probe = true, - record_outcome = true, - respect_variance = true, # active variance suppresses the gate - on_unmet = 'fail, # BLOCKING — the opposite of intend's 'log_drift - severity_escalation = 'honour, # critical > high > medium > low in gate decisions - }, - - # Per-safe-hacking-probe execution. - # If a probe FINDS what it was supposed to prevent finding - # (e.g. injection succeeds, auth-bypass works), that's an EXPLOIT - # demonstration — hard fail, regardless of other status. - per_probe = { - run_probe = true, - record_outcome = true, - honour_expected_outcome = true, - on_unexpected_exploit_success = 'fail, # exploit found where it shouldn't be - scope_enforcement = 'this_repo_only, # never touch external systems - timeout_honouring = 'strict, - }, - - # Evidence sinks — BOTH written, every execution. - evidence_sinks = [ - { - kind = 'verisimdb, - table = "contractile_executions", - schema = "contractile_execution_v1", - # trust-specific sub-table for probe outcomes (for threat-model audit) - aux_tables = [ "trust_verifications", "trust_probes" ], - }, - { - kind = 'drift_log, - path = ".machine_readable/6a2/DRIFT.a2ml", - append_only = true, - }, - ], - - # Session-close hook — re-verify EVERYTHING, re-run probes, diff - # against last ratification. The "turn off the firewall" scenario - # must be caught here if it wasn't caught at pre-push. - on_close = { - re_execute_all_verifications = true, - re_run_all_safe_hacking_probes = true, - diff_against_last_ratification = true, - emit_drift_entries_for_new_failures = true, - surface_expired_variances = true, - # trust-specific: if any blocking-severity verification is newly - # failing, the session close is BLOCKED from completing. User - # cannot close a session with unresolved critical trust drift. - block_session_close_on_critical_drift = true, - }, - - # ----------------------------------------------------------------- - # Session-open hook — NEGOTIATION + RATIFICATION + ACCOUNTABILITY - # (inherited shape from intend.k9.ncl v2.0.0; trust-specific - # additions around threat-model foregrounding below) - # ----------------------------------------------------------------- - on_open = { - # --- Context presentation --- - render_summary = 'plain_language, # metaphor-capture defense - include_drift_log_from_last_close = true, - include_active_variances = true, - include_recent_anchors = true, - anchor_lookback_weeks = 8, - - # trust-specific: the threat model is rendered FIRST, before any - # negotiation, so the adversary and stakes are fresh in both minds. - # This directly defends against B1 (threat-model misclassification) - # — the "war reporter, generic personal-website priors" scenario. - threat_model_foregrounding = { - required = true, - render_adversaries = true, # from Trustfile [THREAT_MODEL] - render_stakes = true, - render_compliance_regimes = true, - render_audience_sensitivity = true, - # If the AI is about to suggest a trust-weakening action, it - # must re-render the threat model before the suggestion lands. - re_render_before_weakening_suggestion = true, - }, - - # --- Negotiation phase (five mandatory inputs, inherited) --- - negotiation = { - required = true, - ai_required_inputs = [ - 'timeline_realism, - 'industry_standards, # especially relevant for trust: OWASP, NIST, PCI-DSS, GDPR - 'audience_feasibility, # who is the adversary? who is protected? - 'resulting_invariants, # what trust entries the work creates/amends - 'ecosystem_dependencies, # TLS libs, crypto primitives, signing infra - ], - user_engagement_required = true, - user_engagement_mode = 'per_input_response, - specification_translation = { - ai_produces_spec_form = true, - user_reviews_in_domain_language = true, - schema_authoring_is_ai_responsibility = true, - translation_faithfulness_auditable = true, - # trust-specific: the AI's translation includes rendering - # cipher suites, key exchange choices, rate-limit numbers in - # domain language ("strong encryption, PQ-resistant, 60 req/min") - # rather than forcing the user into Nickel-schema authoring. - }, - }, - - # --- Accountability pledge (both parties, explicit) --- - # trust's pledge is MORE stringent than intend's because the - # authority is blocking. A user accepting accountability here is - # accepting that security-affecting decisions have blocking consequence. - accountability_pledge = { - required = true, - parties = [ - { - role = 'user, - pledge = "I have reviewed the threat model, the declared trust obligations, and the audience/stakes consequences. I accept accountability for meeting these obligations and understand that failed verification will block merges until resolved or varied. I will not attempt to disable verification to unblock a merge; I will raise a variance or amendment instead.", - signature_required = true, - }, - { - role = 'ai_agent, - pledge = "I will hold the line on declared trust obligations. I will refuse to 'disable' verifications to unblock merges; I will refuse security-weakening suggestions that contradict the threat model even when the user is enthusiastic; I will surface drift at session close; I will re-render the threat model before proposing any weakening action. If a legitimate scope shift demands security reduction, I will require a variance with severity acknowledgement or an amendment, not silent acceptance.", - signature_required = true, - }, - ], - signed_record_destination = ".machine_readable/6a2/ratification-.a2ml", - must_precede_work = true, - }, - - ratification_record_shape = { - includes_negotiation_transcript = true, - includes_both_pledges = true, - includes_threat_model_snapshot = true, # trust-specific - signed = true, - dated = true, - session_id = 'required, - contract_hash = 'required, - }, - }, - }, - - # ------------------------------------------------------------------- - # Failure-mode defenses — trust is the widest-coverage verb. - # See feedback_ai_failure_mode_catalog.md for the full catalog. - # ------------------------------------------------------------------- - failure_mode_defenses = [ - # Category A — enthusiasm / narrative capture - 'A1_enthusiasm_capture, # scope breach blocks via blocking authority - 'A2_metaphor_capture, # render_summary + re_render_before_weakening - # Category B — threat-model misclassification (trust's flagship defense) - 'B1_threat_model_misclass, # threat_model_foregrounding = required - 'B2_audience_sensitivity_collapse, # audience_feasibility in negotiation - 'B3_compliance_prior_drift, # industry_standards in negotiation - # Category C — scope/capability erosion (the "firewall off" scenario) - 'C2_capability_collapse, # blocking gate prevents silent capability drop - 'C3_helpfulness_inflation, # trust-affecting changes need variance/amendment - 'C4_modernization_drift, # unrequested crypto-lib upgrade caught - # Category D — epistemic failures - 'D4_error_hiding, # on_unmet = 'fail makes hiding impossible - 'D5_sycophancy, # pledge forces AI to hold line against enthusiasm - 'D6_false_pessimism, # negotiation requires AI to cite constraint, not assert impossibility - # Category E — refactor/churn - 'E4_cargo_cult_security, # probes VERIFY the claimed protection actually runs - # Category F — session drift - 'F1_across_session_forgetting, # on_open reads last-ratification, drift log, recent ANCHORs - ], -} diff --git a/.machine_readable/contractiles/trust/trust.manifest.a2ml b/.machine_readable/contractiles/trust/trust.manifest.a2ml deleted file mode 100644 index c904eb3..0000000 --- a/.machine_readable/contractiles/trust/trust.manifest.a2ml +++ /dev/null @@ -1,72 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# trust.manifest.a2ml — Trident coherence manifest for the trust verb. -# Author: Jonathan D.A. Jewell -# -# Asserts: exactly three files constitute the trust trident; their -# content-hashes are pinned here; cross-references round-trip; no -# partial publication is permitted. -# -# The contractile CLI's `verify trust` subcommand MUST: -# 1. Confirm all three listed files exist at the declared paths. -# 2. Compute each file's sha256 and match against the pinned value. -# 3. Follow each cross-reference and confirm the target file's -# reciprocal field points back. -# 4. Refuse the dir (exit non-zero) if any of 1–3 fails. -# -# trust is the concrete + ephemeral + transactional verb (per user -# 2026-04-18); first blocking-authority trident in the estate. Exercises -# the (Hunt, blocking) authority pattern — complement to intend's -# (Hunt, reporting). Primary defense against failure mode B1 (threat- -# model misclassification) and the "turn off the firewall" class of -# drift attempts the adversarial pilot is designed to exercise. - ---- -trident_version = "1.0.0" -verb = "trust" -semantics = "security + provenance + safe-hacking" -cardinality = "one per repo" -authority = "blocking (hard gate)" - -## Files (three; exactly) - -[[files]] -role = "declaration" -path = "Trustfile.a2ml" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" -notes = "Extensively populated exemplar; covers threat model, DNS, TLS, crypto, SDP, safe-hacking, response headers, container supply chain, Cloudflare edge." - -[[files]] -role = "runner" -path = "trust.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" -notes = "Runner existed pre-trident; schema covers verifications + safe_hacking with authorised-probes-only, this_repo_only scope enforcement." - -[[files]] -role = "k9_component" -path = "trust.k9.ncl" -sha256 = "pending-first-verify" -size_bytes = "pending-first-verify" -notes = "Trust-tier Hunt with blocking authority. on_open foregrounds threat model before negotiation; block_session_close_on_critical_drift." - -## Cross-references (must round-trip) - -[cross_refs] -runner_paired_xfile = "Trustfile.a2ml" -k9_paired_xfile = "../trust/Trustfile.a2ml" -k9_paired_runner = "../trust/trust.ncl" - -## Trident signing - -[signed_by] -user = "Jonathan D.A. Jewell" -date = "2026-04-18" -context = "trust trident — second Trident instance. First (Hunt, blocking) authority pattern. Template for must, bust, adjust, dust. Pre-pilot readiness: primary catchment for adversarial drift test scenarios (firewall-off, cleartext-auth, PQ-downgrade, CSP-weaken)." - -## Change log - -[[history]] -date = "2026-04-18" -event = "trident-born" -note = "Trustfile.a2ml and trust.ncl pre-existed. This manifest + trust.k9.ncl complete the trident. Inherits on_open negotiation + accountability + plain-language-translation schema from intend.k9.ncl v2.0.0; adds trust-specific threat_model_foregrounding + block_session_close_on_critical_drift + stricter accountability pledge (user cannot disable verification to unblock merges)." diff --git a/.machine_readable/contractiles/trust/trust.ncl b/.machine_readable/contractiles/trust/trust.ncl deleted file mode 100644 index 21b335c..0000000 --- a/.machine_readable/contractiles/trust/trust.ncl +++ /dev/null @@ -1,88 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Trust — security + safe-hacking runner -# -# Pairs with: Trustfile.a2ml (same directory) -# Verb: trust -# Semantics: integrity / provenance / security verification PLUS a declared -# "safe hacking + testing" section — authorised offensive probes -# (pen-test harness runs, chaos-engineering probes) scoped to the -# repo under test, NEVER touching external systems. -# CLI: `contractile trust verify` → run all verifications (read-only) -# `contractile trust probe` → run declared safe-hacking probes -# -# 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 = "trust", - semantics = "security + provenance + safe-hacking", - security = { - leash = 'Kennel, - trust_level = "verification + authorised-probe", - allow_network = false, # verifications are offline by default - allow_filesystem_write = false, # trust writes NOTHING - allow_subprocess = true, - authorised_probes_only = true, # probe section must explicitly list allowed targets - }, - metadata = { - name = "trust-runner", - version = "1.0.0", - description = "Security + provenance verifications plus authorised safe-hacking probes. All probes are scoped to the repo under test; never hits external systems.", - paired_xfile = "Trustfile.a2ml", - author = "Jonathan D.A. Jewell ", - }, - }, - - schema = { - verifications - | Array { - id | String, - description | String, - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - probe | String, # read-only; exit 0 = pass - # status_core values: 'declared, 'verified, 'failing - status | [| 'declared, 'verified, 'failing |] | default = 'declared, - # trust uses all four severity levels (from base.severity_core) - severity | [| 'critical, 'high, 'medium, 'low |] | default = 'high, - notes | String | optional, - }, - - # Safe-hacking + testing section (added 2026-04-17 per user direction). - # Each probe here is an ACTIVELY EXECUTED test — fuzz runs, chaos probes, - # auth-bypass attempts, injection tests. All scoped to the current repo. - safe_hacking - | { - scope | String, # e.g. "this-repo-only" / "localhost" - allowed_probe_classes - | Array [| 'fuzz, 'property_test, 'chaos, 'auth_bypass, 'injection, 'timing |] - | default = [], - probes - | Array { - id | String, - class | [| 'fuzz, 'property_test, 'chaos, 'auth_bypass, 'injection, 'timing |], - description | String, - # TODO: migrate to base.probe_schema (structured probe) when CLI supports it - probe | String, # command to run the probe - expected_outcome | [| 'probe_blocks_attempt, 'probe_finds_no_issue |], - timeout_seconds | Number | default = 300, - notes | String | optional, - } - | default = [], - } - | default = { scope = "this-repo-only", allowed_probe_classes = [], probes = [] }, - }, - - # Runner behaviour — inherits from base.run_defaults. - # trust has an extra field for unexpected safe-hacking outcomes. - run = base.run_defaults & { - on_any_fail = "exit-nonzero", # hard gate on verifications - safe_hacking_on_unexpected_outcome = "exit-nonzero", # probe found what it shouldn't = block - report_format = "a2ml", - emit_summary = true, - }, -} diff --git a/flake.lock b/flake.lock deleted file mode 100644 index a2f0433..0000000 --- a/flake.lock +++ /dev/null @@ -1,61 +0,0 @@ -{ - "nodes": { - "flake-utils": { - "inputs": { - "systems": "systems" - }, - "locked": { - "lastModified": 1731533236, - "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", - "owner": "numtide", - "repo": "flake-utils", - "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", - "type": "github" - }, - "original": { - "owner": "numtide", - "repo": "flake-utils", - "type": "github" - } - }, - "nixpkgs": { - "locked": { - "lastModified": 1779536132, - "narHash": "sha256-q+fF42iv/geEbHfgSzy3tS0FF/EyD6XTZ98E6yxiBO8=", - "owner": "NixOS", - "repo": "nixpkgs", - "rev": "3d8f0f3f72a6cd4d93d0ad13203f2ea1cb7e1456", - "type": "github" - }, - "original": { - "owner": "NixOS", - "ref": "nixpkgs-unstable", - "repo": "nixpkgs", - "type": "github" - } - }, - "root": { - "inputs": { - "flake-utils": "flake-utils", - "nixpkgs": "nixpkgs" - } - }, - "systems": { - "locked": { - "lastModified": 1681028828, - "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", - "owner": "nix-systems", - "repo": "default", - "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", - "type": "github" - }, - "original": { - "owner": "nix-systems", - "repo": "default", - "type": "github" - } - } - }, - "root": "root", - "version": 7 -} 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 667e7aeaafef07505d6b24ad66477564ebe614a4 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 08/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/dogfood-gate.yml | 24 -- .github/workflows/e2e.yml | 306 ++++++++++----------- .github/workflows/governance.yml | 4 - .github/workflows/hypatia-scan.yml | 107 +------ .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 | 3 - .github/workflows/scorecard-enforcer.yml | 14 +- .github/workflows/scorecard.yml | 5 - .github/workflows/secret-scanner.yml | 22 +- .github/workflows/static-analysis-gate.yml | 40 +-- .gitlab-ci.yml | 31 +-- .machine_readable/contractiles/Justfile | 5 +- .pre-commit-config.yaml | 2 - Justfile | 5 +- 21 files changed, 190 insertions(+), 519 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 01934ac..26846e6 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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - - name: Perform CodeQL Analysis uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3 with: diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index 3d0e8de..cff4451 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@25dd0e34f4fe68f24cc83900b1fe3fe149efef98 # v3.1.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/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index c6b3dce..9bf82d6 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -5,16 +5,13 @@ # Validates that the repo uses hyperpolymath's own formats and tools. # Companion to static-analysis-gate.yml (security) — this is for format compliance. name: Dogfood Gate - on: pull_request: branches: ['**'] push: branches: [main, master] - permissions: contents: read - jobs: # --------------------------------------------------------------------------- # Job 1: A2ML manifest validation @@ -23,11 +20,9 @@ jobs: name: Validate A2ML manifests runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Check for A2ML files id: detect run: | @@ -36,14 +31,12 @@ jobs: if [ "$COUNT" -eq 0 ]; then echo "::warning::No .a2ml manifest files found. Every RSR repo should have 0-AI-MANIFEST.a2ml" fi - - name: Validate A2ML manifests if: steps.detect.outputs.count > 0 uses: hyperpolymath/a2ml-validate-action@59145c7d1039fa3059b3ecacdb50ee23d7505898 # main with: path: '.' strict: 'false' - - name: Write summary run: | A2ML_COUNT="${{ steps.detect.outputs.count }}" @@ -60,7 +53,6 @@ jobs: echo "" >> "$GITHUB_STEP_SUMMARY" echo "Scanned **${A2ML_COUNT}** .a2ml file(s). See step output for details." >> "$GITHUB_STEP_SUMMARY" fi - # --------------------------------------------------------------------------- # Job 2: K9 contract validation # --------------------------------------------------------------------------- @@ -68,11 +60,9 @@ jobs: name: Validate K9 contracts runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Check for K9 files id: detect run: | @@ -85,14 +75,12 @@ jobs: if [ "$COUNT" -eq 0 ] && [ "$CONFIG_COUNT" -gt 0 ]; then echo "::warning::Found $CONFIG_COUNT config files but no K9 contracts. Run k9iser to generate contracts." fi - - name: Validate K9 contracts if: steps.detect.outputs.k9_count > 0 uses: hyperpolymath/k9-validate-action@2d96f43c538964b097d159ed3a56ba5b5ceca227 # main with: path: '.' strict: 'false' - - name: Write summary run: | K9_COUNT="${{ steps.detect.outputs.k9_count }}" @@ -110,7 +98,6 @@ jobs: echo "" >> "$GITHUB_STEP_SUMMARY" echo "Validated **${K9_COUNT}** K9 contract(s) against **${CFG_COUNT}** config file(s)." >> "$GITHUB_STEP_SUMMARY" fi - # --------------------------------------------------------------------------- # Job 3: Empty-linter — invisible character detection # --------------------------------------------------------------------------- @@ -118,11 +105,9 @@ jobs: name: Empty-linter (invisible characters) runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Scan for invisible characters id: lint run: | @@ -156,7 +141,6 @@ jobs: REL_PATH="${filepath#$GITHUB_WORKSPACE/}" echo "::warning file=${REL_PATH}::Invisible Unicode characters detected (zero-width space, BOM, NBSP, etc.)" done < /tmp/empty-lint-results.txt - - name: Write summary run: | if [ "${{ steps.lint.outputs.ready }}" = "true" ]; then @@ -175,7 +159,6 @@ jobs: echo "" >> "$GITHUB_STEP_SUMMARY" echo "Skipped: empty-linter not available." >> "$GITHUB_STEP_SUMMARY" fi - # --------------------------------------------------------------------------- # Job 4: Groove manifest check (for repos that should expose services) # --------------------------------------------------------------------------- @@ -183,11 +166,9 @@ jobs: name: Groove manifest check runs-on: ubuntu-latest timeout-minutes: 15 - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Check for Groove manifest id: groove run: | @@ -224,7 +205,6 @@ jobs: if [ "$HAS_SERVER" = "true" ] && [ "$HAS_MANIFEST" = "false" ] && [ "$HAS_GROOVE_CODE" = "false" ]; then echo "::warning::This repo has server code but no Groove endpoint. Add .well-known/groove/manifest.json for service discovery." fi - - name: Write summary run: | echo "## Groove Protocol Check" >> "$GITHUB_STEP_SUMMARY" @@ -234,7 +214,6 @@ jobs: echo "| Static manifest (.well-known/groove/manifest.json) | ${{ steps.groove.outputs.has_manifest }} |" >> "$GITHUB_STEP_SUMMARY" echo "| Groove endpoint in code | ${{ steps.groove.outputs.has_groove_code }} |" >> "$GITHUB_STEP_SUMMARY" echo "| Has HTTP server code | ${{ steps.groove.outputs.has_server }} |" >> "$GITHUB_STEP_SUMMARY" - # --------------------------------------------------------------------------- # Job 5: Dogfooding summary # --------------------------------------------------------------------------- @@ -244,11 +223,9 @@ jobs: timeout-minutes: 15 needs: [a2ml-validate, k9-validate, empty-lint, groove-check] if: always() - steps: - name: Checkout repository uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - - name: Generate dogfooding scorecard run: | SCORE=0 @@ -311,4 +288,3 @@ jobs: *Generated by the [Dogfood Gate](https://github.com/hyperpolymath/natsci-studio) workflow.* *Dogfooding is guinea pig fooding — we test our tools on ourselves.* EOF - diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 0b68a13..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@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 +# ─── 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 5e7eddc..9a726a4 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -1,14 +1,13 @@ # SPDX-License-Identifier: MPL-2.0 # Hypatia Neurosymbolic CI/CD Security Scan name: Hypatia Security Scan - on: push: - branches: [ main, master, develop ] + branches: [main, master, develop] pull_request: - branches: [ main, master ] + branches: [main, master] schedule: - - cron: '0 0 * * 0' # Weekly on Sunday + - cron: '0 0 * * 0' # Weekly on Sunday workflow_dispatch: # Estate guardrail: cancel superseded runs so re-pushes don't pile up # queued runs across the estate. Safe here because this workflow only @@ -16,7 +15,6 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read # security-events: write serves two purposes (write implies read): @@ -38,31 +36,26 @@ permissions: # "Resource not accessible by integration" and (absent continue-on-error) # hard-fails the scan — exactly what the gate-decoupling design forbids. 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" @@ -71,7 +64,6 @@ jobs: mix deps.get mix escript.build fi - - name: Run Hypatia scan id: scan env: @@ -104,14 +96,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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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 @@ -227,7 +217,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 @@ -239,8 +228,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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3.28.1 with: @@ -248,7 +241,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 @@ -272,52 +264,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): @@ -335,7 +282,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 @@ -374,7 +320,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 @@ -384,32 +329,4 @@ jobs: continue-on-error: true uses: actions/github-script@3a2844b7e9c422d3c10d287c895573f7108da1b3 # 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 f78fc86..dc228d9 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -1,15 +1,12 @@ # SPDX-License-Identifier: MPL-2.0 # SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell name: Mirror to Git Forges - on: push: branches: [main] workflow_dispatch: - permissions: contents: read - jobs: mirror-gitlab: runs-on: ubuntu-latest @@ -19,17 +16,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 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 @@ -38,17 +32,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 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 @@ -57,17 +48,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 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 @@ -76,17 +64,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 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 @@ -95,17 +80,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 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 @@ -114,17 +96,14 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - uses: webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 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 @@ -133,18 +112,15 @@ jobs: - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 with: fetch-depth: 0 - - name: Setup Rust uses: dtolnay/rust-toolchain@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # 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 e9d80bb..bcd40d3 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 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 1124210..5e7b607 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@b4309332981a82ec1c5618f44dd2e27cc8bfbfda # 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 6c3025f..a1a7789 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 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 3f1a4aa..9dd54a4 100644 --- a/.github/workflows/rust-ci.yml +++ b/.github/workflows/rust-ci.yml @@ -3,15 +3,12 @@ # 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: rust-ci: uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@f5f0506a6ec88e574753eee701a268e0d4b3a7f2 diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index ab0b67a..31a6633 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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # 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 fe0e8de..af01949 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -6,7 +6,6 @@ on: schedule: - 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 @@ -14,10 +13,8 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read - jobs: analysis: runs-on: ubuntu-latest @@ -29,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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3.31.8 with: diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index 6f9bb41..cea6078 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,12 +1,10 @@ # SPDX-License-Identifier: PMPL-1.0 # Prevention workflow - scans for hardcoded secrets before they reach main 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 @@ -14,10 +12,8 @@ on: concurrency: group: ${{ github.workflow }}-${{ github.ref }} cancel-in-progress: true - permissions: contents: read - jobs: trufflehog: runs-on: ubuntu-latest @@ -25,35 +21,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@37b77001d0174ebec2fcca2bd83ff83a6d45a3ab # 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 3396d45..4f44192 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 with: name: panic-attack-findings path: findings/ - - name: Download hypatia findings uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v4 with: name: hypatia-findings path: findings/ - - name: Download bridge report uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 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 d4698fd..0457f2f 100644 --- a/.machine_readable/contractiles/Justfile +++ b/.machine_readable/contractiles/Justfile @@ -797,7 +797,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" # ═══════════════════════════════════════════════════════════════════════════════ @@ -1032,7 +1031,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" @@ -1542,3 +1540,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 d4698fd..0457f2f 100644 --- a/Justfile +++ b/Justfile @@ -797,7 +797,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" # ═══════════════════════════════════════════════════════════════════════════════ @@ -1032,7 +1031,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" @@ -1542,3 +1540,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 7cba32f2cf33373d0a3b09976f62932296836cf7 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:26:46 +0100 Subject: [PATCH 09/11] chore: resolve structure conflicts --- .github/workflows/boj-build.yml | 4 +- .github/workflows/codeql.yml | 8 +- .github/workflows/dependabot-automerge.yml | 1 + .github/workflows/dogfood-gate.yml | 17 +- .github/workflows/e2e.yml | 170 +++++------ .github/workflows/governance.yml | 1 + .github/workflows/hypatia-scan.yml | 325 +-------------------- .github/workflows/instant-sync.yml | 1 + .github/workflows/mirror.yml | 123 +------- .github/workflows/openssf-compliance.yml | 3 +- .github/workflows/release.yml | 8 +- .github/workflows/rhodibot.yml | 3 +- .github/workflows/rust-ci.yml | 4 +- .github/workflows/scorecard-enforcer.yml | 8 +- .github/workflows/scorecard.yml | 44 +-- .github/workflows/secret-scanner.yml | 57 +--- .github/workflows/static-analysis-gate.yml | 7 +- .gitlab-ci.yml | 1 + .pre-commit-config.yaml | 1 + container/.gatekeeper.yaml | 1 + docs/tech-debt-2026-05-26.md | 71 +++++ flake.lock | 61 ++++ 22 files changed, 293 insertions(+), 626 deletions(-) create mode 100644 docs/tech-debt-2026-05-26.md create mode 100644 flake.lock diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml index b203334..4cf2469 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 @@ -19,7 +20,8 @@ jobs: if: ${{ vars.BOJ_SERVER_URL != '' || secrets.BOJ_SERVER_URL != '' }} steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - 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 26846e6..a52af25 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: @@ -31,13 +32,14 @@ jobs: build-mode: none steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Initialize CodeQL - uses: github/codeql-action/init@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3 + uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v3 with: languages: ${{ matrix.language }} build-mode: ${{ matrix.build-mode }} - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3 + uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v3 with: category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/dependabot-automerge.yml b/.github/workflows/dependabot-automerge.yml index cff4451..64623c0 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/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml index 9bf82d6..e9b6ced 100644 --- a/.github/workflows/dogfood-gate.yml +++ b/.github/workflows/dogfood-gate.yml @@ -22,7 +22,8 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Check for A2ML files id: detect run: | @@ -33,7 +34,7 @@ jobs: fi - name: Validate A2ML manifests if: steps.detect.outputs.count > 0 - uses: hyperpolymath/a2ml-validate-action@59145c7d1039fa3059b3ecacdb50ee23d7505898 # main + uses: hyperpolymath/a2ml-validate-action@6bff6ec134fc977e86d25166a5c522ddea5c1e78 # main with: path: '.' strict: 'false' @@ -62,7 +63,8 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Check for K9 files id: detect run: | @@ -107,7 +109,8 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Scan for invisible characters id: lint run: | @@ -168,7 +171,8 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Check for Groove manifest id: groove run: | @@ -225,7 +229,8 @@ jobs: if: always() steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Generate dogfooding scorecard run: | SCORE=0 diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 940c70a..fdb9ca1 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -49,84 +49,84 @@ jobs: # - 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 + ## === 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@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 + ## === 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@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/ + ## === 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@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 + ## === 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@dd344bc1cec854a9b55c2b857c28b688010e4fce # v2 -# with: -# ghc-version: '9.6' -# cabal-version: '3.10' -# - run: cabal build all -# - run: bash tests/integration-test.sh + ## === 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 @@ -160,17 +160,17 @@ jobs: # 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 + ## === 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) 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 9a726a4..2581e28 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -1,5 +1,8 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 -# Hypatia Neurosymbolic CI/CD Security Scan +# Thin wrapper around hyperpolymath/standards hypatia-scan-reusable.yml. +# See standards#191 for the reusable's purpose and design. + name: Hypatia Security Scan on: push: @@ -7,326 +10,18 @@ on: pull_request: branches: [main, master] schedule: - - cron: '0 0 * * 0' # Weekly on Sunday + - cron: '0 0 * * 0' workflow_dispatch: -# Estate guardrail: cancel superseded runs so re-pushes don't pile up -# queued runs across the estate. Safe here because this workflow only -# performs read-only checks/lint/test/scan with no publish or mutation. + +# 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 serves two purposes (write implies read): - # 1. read — lets the built-in GITHUB_TOKEN query this repo's own - # Dependabot alerts via the Hypatia DependabotAlerts rule - # (DA001-DA004). Without read, `scan_from_path` gets HTTP 403 - # and the rule silently returns no findings. - # See 007-lang/audits/audit-dependabot-automation-gap-2026-04-17.md. - # 2. write — lets the "Upload SARIF to code scanning" step publish - # Hypatia findings to the Security → Code scanning page so they - # are triaged/deduplicated like CodeQL alerts instead of living - # only in a build artifact nobody is required to look at. - # See hyperpolymath/burble#35 (SARIF integration). - # This is a single-job workflow, so job-level scoping would not - # narrow the grant further; it stays workflow-level and documented. security-events: write - # pull-requests: write lets the advisory "Comment on PR with findings" - # step post its summary. Without it the built-in GITHUB_TOKEN gets - # "Resource not accessible by integration" and (absent continue-on-error) - # hard-fails the scan — exactly what the gate-decoupling design forbids. 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 - - 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@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - 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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # 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 \"\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): - # 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@3a2844b7e9c422d3c10d287c895573f7108da1b3 # v7 - with: - 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});" + hypatia: + uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@915139d73560e65a8240b8fc7768698658502c89 + secrets: inherit 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 dc228d9..5c4b3c4 100644 --- a/.github/workflows/mirror.yml +++ b/.github/workflows/mirror.yml @@ -1,5 +1,5 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: MPL-2.0 -# SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell name: Mirror to Git Forges on: push: @@ -8,121 +8,6 @@ on: permissions: contents: read jobs: - 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@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 - 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@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 - 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@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 - 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@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 - 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@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 - 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@e83874834305fe9a4a2997156cb26c5de65a8555 # v0.10.0 - 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@3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 # 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" + mirror: + uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@e6b2884722350515934d443daf23442f2195796f + secrets: inherit diff --git a/.github/workflows/openssf-compliance.yml b/.github/workflows/openssf-compliance.yml index bcd40d3..cbd0870 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. @@ -17,7 +18,7 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Check SECURITY.md exists and has substance diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 5e7b607..b581e6a 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -19,7 +19,8 @@ jobs: permissions: contents: read steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Detect project type and build id: build run: | @@ -80,7 +81,7 @@ jobs: changelog: ${{ steps.cliff.outputs.content }} version: ${{ steps.version.outputs.version }} steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Extract version from tag @@ -118,7 +119,8 @@ jobs: permissions: contents: write steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + # TODO: Download build artifacts if uploading to the release # - uses: actions/download-artifact@v4 # with: diff --git a/.github/workflows/rhodibot.yml b/.github/workflows/rhodibot.yml index a1a7789..0d9e2f3 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 # @@ -27,7 +28,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 1 - name: Rhodibot — Scan and Fix diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml index 9dd54a4..03c969d 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. @@ -11,5 +12,4 @@ permissions: contents: read jobs: rust-ci: - uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@f5f0506a6ec88e574753eee701a268e0d4b3a7f2 - timeout-minutes: 10 + uses: hyperpolymath/standards/.github/workflows/rust-ci-reusable.yml@cc5a372af1af1b202c17f1b21efd954e6c038bef diff --git a/.github/workflows/scorecard-enforcer.yml b/.github/workflows/scorecard-enforcer.yml index 31a6633..e1666d2 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 @@ -24,7 +25,7 @@ jobs: security-events: write id-token: write # For OIDC steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: persist-credentials: false - name: Run Scorecard @@ -34,7 +35,7 @@ jobs: results_format: sarif publish_results: true - name: Upload SARIF - uses: github/codeql-action/upload-sarif@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v4 + uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4 with: sarif_file: results.sarif - name: Check minimum score @@ -56,7 +57,8 @@ jobs: runs-on: ubuntu-latest timeout-minutes: 15 steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + - uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Check SECURITY.md exists run: | if [ ! -f "SECURITY.md" ]; then diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index af01949..dc08714 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -1,37 +1,17 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: PMPL-1.0 -name: OSSF Scorecard +name: Scorecards supply-chain security + on: - push: - branches: [main, master] + branch_protection_rule: schedule: - - 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 + - cron: '23 4 * * 1' + push: + branches: [main] + +permissions: read-all + jobs: analysis: - 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@7211b7c8077ea37d8641b6271f6a365a22a5fbfa # v3.31.8 - with: - sarif_file: results.sarif + uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@e0caf11508a3989574713c78f5f444f2ce5e33ef + secrets: inherit diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml index cea6078..7d51fcd 100644 --- a/.github/workflows/secret-scanner.yml +++ b/.github/workflows/secret-scanner.yml @@ -1,64 +1,17 @@ +# // Copyright (c) Jonathan D.A. Jewell # SPDX-License-Identifier: PMPL-1.0 -# Prevention workflow - scans for hardcoded secrets before they reach main 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 - timeout-minutes: 15 - steps: - - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v4 - with: - fetch-depth: 0 # Full history for scanning - - name: TruffleHog Secret Scan - uses: trufflesecurity/trufflehog@37b77001d0174ebec2fcca2bd83ff83a6d45a3ab # 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 - # 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 + scan: + uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@3e4bd4c93911750727e2e4c66dff859e00079da0 + secrets: inherit diff --git a/.github/workflows/static-analysis-gate.yml b/.github/workflows/static-analysis-gate.yml index 4f44192..0af928e 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. @@ -19,7 +20,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Install panic-attack (if available) @@ -115,7 +116,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Setup Elixir for Hypatia scanner @@ -219,7 +220,7 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repository - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 with: fetch-depth: 0 - name: Install panic-attack (if available) 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}} # diff --git a/docs/tech-debt-2026-05-26.md b/docs/tech-debt-2026-05-26.md new file mode 100644 index 0000000..f1f4030 --- /dev/null +++ b/docs/tech-debt-2026-05-26.md @@ -0,0 +1,71 @@ + + +# Tech-Debt Audit — natsci-studio — 2026-05-26 + +**Source:** estate-wide automated scan 2026-05-26. +**Companion:** [`hyperpolymath/standards` 2026-05-26-estate-*-debt audits](https://github.com/hyperpolymath/standards/tree/main/docs/audits). +**Combined severity:** `LOW`. + +This file records the *raw findings* — it does not by itself fix the debt. Each section ends with a 'Recommended next move' line; closing the debt is follow-up work. + +## 1. Proof debt + +Scanner counted the following markers in proof-bearing files of this repo: + +``` +files= 13 | Coq-Axm/Adm= 0 | Lean-srry/ax= 0 | Agda-pst= 0 | Idr-blv= 6 | Idr-prtl= 0 | Fstr-asm= 0 | TODO= 0 | Unsafe= 0 +``` + +**Total markers:** 6. **Severity:** `>06`. + +**Marker types** (any non-zero counts above): +- Coq `Axiom`/`Admitted` — unconditional proof escapes. +- Lean `sorry`/`axiom` — Lean's equivalent. +- Agda `postulate` — accepted axiomatically. +- Idris2 `believe_me`/`assert_total` — runtime-safe coercion / totality assumption. +- Idris2 top-level `partial` — totality-check waived. +- F\* `assume val`/`admit_p` — F\* admit. +- `TODO PROOF` / `OWED:` — self-documented debt markers. +- `unsafePerformIO`/`unsafeCoerce` — soundness-relevant escape hatches in Haskell/Rust source. + +**Recommended next move:** triage each finding into one of: (a) discharge by proof, (b) cover with property-tests + a documented refutation budget, or (c) annotate as a known/necessary axiom (e.g. `funExt`) in `docs/proof-debt.md`. + +## 2. Licence debt + +| Field | Value | +|---|---| +| LICENSE file | `LICENSE` | +| SPDX header | `AGPL-3.0-or-later` | +| Manifest licence | `NONE` | +| Body classifier | `Palimpsest-some` | +| Severity | `ok` | + +**Recommended next move:** none for licence. + +## 3. Documentation debt + +| Field | Value | +|---|---| +| README lines | 53 | +| `docs/` files | 55 | +| `docs/` LoC | 2437 | +| CHANGELOG.md | Y | +| CONTRIBUTING.md | Y | +| CODE_OF_CONDUCT.md | Y | +| SECURITY.md | Y | +| Severity | `OK` | + +**Recommended next move:** none for docs. + +## Cross-references + +- Estate proof-debt audit: `hyperpolymath/standards/docs/audits/2026-05-26-estate-proof-debt.md` +- Estate licence-debt audit: `hyperpolymath/standards/docs/audits/2026-05-26-estate-licence-debt.md` +- Estate documentation-debt audit: `hyperpolymath/standards/docs/audits/2026-05-26-estate-documentation-debt.md` + +--- + +🤖 Generated by Claude Code estate-wide tech-debt scan (2026-05-26). This file is informational — closing the debt is follow-up work owned by the maintainer. diff --git a/flake.lock b/flake.lock new file mode 100644 index 0000000..c9e82dd --- /dev/null +++ b/flake.lock @@ -0,0 +1,61 @@ +{ + "nodes": { + "flake-utils": { + "inputs": { + "systems": "systems" + }, + "locked": { + "lastModified": 1731533236, + "narHash": "sha256-l0KFg5HjrsfsO/JpG+r7fRrqm12kzFHyUHqHCVpMMbI=", + "owner": "numtide", + "repo": "flake-utils", + "rev": "11707dc2f618dd54ca8739b309ec4fc024de578b", + "type": "github" + }, + "original": { + "owner": "numtide", + "repo": "flake-utils", + "type": "github" + } + }, + "nixpkgs": { + "locked": { + "lastModified": 1780365719, + "narHash": "sha256-QfWfccTN+70ZQ4m2qlU9PiKfz2Yppq94058iJyARNwc=", + "owner": "NixOS", + "repo": "nixpkgs", + "rev": "ffa10e26ae11d676b2db836259889f1f571cb14f", + "type": "github" + }, + "original": { + "owner": "NixOS", + "ref": "nixpkgs-unstable", + "repo": "nixpkgs", + "type": "github" + } + }, + "root": { + "inputs": { + "flake-utils": "flake-utils", + "nixpkgs": "nixpkgs" + } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } + } + }, + "root": "root", + "version": 7 +} From 24e014d21c72d5031568ebee57f01f696ea21977 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:26:46 +0100 Subject: [PATCH 10/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 0457f2f..5632b4a 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 f1f4030..eaf1f24 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) --> From 90eb0e3b7ff56a2b85469adcb19d5d9145e80c05 Mon Sep 17 00:00:00 2001 From: hyperpolymath <6759885+hyperpolymath@users.noreply.github.com> Date: Fri, 12 Jun 2026 00:30:13 +0100 Subject: [PATCH 11/11] fix(security/compliance): standardized TruffleHog and RSR metadata --- docs/tech-debt-2026-05-26.md | 1 + 1 file changed, 1 insertion(+) diff --git a/docs/tech-debt-2026-05-26.md b/docs/tech-debt-2026-05-26.md index f1f4030..eaf1f24 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) -->