From 6dddd93c74270df0dfa56645d75621676383d052 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" Date: Thu, 24 Sep 2026 02:18:09 +0000 Subject: [PATCH] test(proof): run the generated Rust proof gate on a runner Scratch branch: the tree is a project produced by main's own generator, so .github/workflows/proof.yml executes exactly as shipped. Not intended to merge. --- .claude/CLAUDE.md | 84 - .editorconfig | 48 +- .gitattributes | 49 +- .github/CODEOWNERS | 11 - .github/CONTRIBUTING.md | 109 - .github/FUNDING.yml | 3 - .github/copilot/coding-agent.yml | 6 - .github/dependabot.yml | 24 - .github/funding.yml | 4 - .github/hooks/validate-a2ml.sh | 413 --- .github/hooks/validate-k9.sh | 357 -- .github/label-classifier.json | 739 ---- .github/labels.json | 260 -- .github/scripts/classify-issue.jq | 164 - .github/workflows/actions.lock | 128 +- .github/workflows/boj-build.yml | 24 - .github/workflows/casket-pages.yml | 122 - .github/workflows/changelog.yml | 47 - .../rust/.github => .github}/workflows/ci.yml | 0 .github/workflows/codeql.yml | 59 - .github/workflows/dogfood-gate.yml | 386 -- .github/workflows/governance.yml | 2 - .github/workflows/hypatia-scan.yml | 2 - .github/workflows/instant-sync.yml | 40 - .github/workflows/label-triage.yml | 117 - .github/workflows/labels.yml | 106 - .github/workflows/mirror.yml | 19 - .github/workflows/pages.yml | 61 - .../.github => .github}/workflows/proof.yml | 0 .github/workflows/push-email-notify.yml | 59 - .github/workflows/rust-ci.yml | 89 - .github/workflows/scorecard.yml | 22 - .github/workflows/secret-scanner.yml | 25 - .gitignore | 143 +- .gitmodules | 8 - .hypatia-ignore | 23 - .hypatia/activity.jsonl | 1 - .hypatia/last-visit.json | 6 - .machine_readable/6a2/0-AI-MANIFEST.a2ml | 31 - .machine_readable/6a2/AGENTIC.a2ml | 24 - .machine_readable/6a2/ECOSYSTEM.a2ml | 16 - .machine_readable/6a2/META.a2ml | 20 - .machine_readable/6a2/NEUROSYM.a2ml | 14 - .machine_readable/6a2/PLAYBOOK.a2ml | 23 - .machine_readable/6a2/README.adoc | 30 - .machine_readable/6a2/STATE.a2ml | 141 - .../6a2/anchor/0-AI-MANIFEST.a2ml | 21 - .machine_readable/6a2/anchor/ANCHOR.a2ml | 28 - .machine_readable/6a2/anchor/README.adoc | 25 - .machine_readable/CLADE.a2ml | 47 - .machine_readable/bot_directives/README.adoc | 61 - .../bot_directives/coverage.a2ml | 61 - .machine_readable/bot_directives/debt.a2ml | 49 - .../bot_directives/git-private-farm.a2ml | 21 - .../bot_directives/gitbot-fleet.a2ml | 55 - .machine_readable/bot_directives/hypatia.a2ml | 26 - .../bot_directives/methodology.a2ml | 107 - .../contractiles/Adjustfile.a2ml | 126 - .machine_readable/contractiles/Bustfile.a2ml | 46 - .machine_readable/contractiles/Dustfile.a2ml | 82 - .../contractiles/Intentfile.a2ml | 100 - .machine_readable/contractiles/Justfile | 20 - .machine_readable/contractiles/Mustfile.a2ml | 94 - .machine_readable/contractiles/Trustfile.a2ml | 87 - .../integrations/feedback-o-tron.a2ml | 13 - .machine_readable/integrations/proven.a2ml | 18 - .machine_readable/integrations/verisimdb.a2ml | 15 - .machine_readable/integrations/vexometer.a2ml | 18 - .machine_readable/rsr-profile.a2ml | 39 +- .machine_readable/self-validating/README.adoc | 179 - .../self-validating/examples/ci-config.k9.ncl | 126 - .../examples/project-metadata.k9.ncl | 57 - .../examples/setup-repo.k9.ncl | 167 - .../self-validating/template-hunt.k9.ncl | 136 - .../self-validating/template-kennel.k9.ncl | 54 - .../self-validating/template-yard.k9.ncl | 84 - .machine_readable/svc/README.adoc | 17 - .tool-versions | 7 +- .well-known/ai.txt | 16 +- .well-known/humans.txt | 14 +- .well-known/security.txt | 10 +- 0-AI-MANIFEST.a2ml | 132 +- ARCHITECTURE.adoc | 48 - CHANGELOG.adoc | 82 +- CHANGELOG.md | 3266 ----------------- CODE_OF_CONDUCT.adoc | 42 +- CONTRIBUTING.adoc | 58 +- .../templates/rust/Cargo.toml => Cargo.toml | 6 +- DELIVERY-186-197.md | 854 ----- EXPLAINME-new.adoc | 140 - EXPLAINME.adoc | 228 -- GLOSSARY.adoc | 70 - GOVERNANCE.adoc | 60 - Justfile | 144 +- LICENSE | 376 +- LICENSES/AGPL-3.0-or-later.txt | 661 ---- MAINTAINERS | 43 - MAINTAINERS.adoc | 43 +- Mustfile | 13 - NOTICE | 22 - PROOF-NEEDS.adoc | 119 - QUICKSTART-DEV.adoc | 113 - QUICKSTART-MAINTAINER.adoc | 130 - QUICKSTART-USER.adoc | 125 - README.adoc | 265 +- ROADMAP.adoc | 92 - SECURITY.adoc | 76 +- TEST-NEEDS.adoc | 139 - TOPOLOGY.adoc | 87 - absolute-zero | 1 - aletheia/.claude/CLAUDE.md | 87 - aletheia/.clippy.toml | 26 - aletheia/.clusterfuzzlite/Containerfile | 7 - aletheia/.clusterfuzzlite/build.sh | 7 - aletheia/.clusterfuzzlite/project.yaml | 2 - aletheia/.dockerignore | 46 - aletheia/.editorconfig | 57 - aletheia/.gitattributes | 54 - aletheia/.github/FUNDING.yml | 7 - aletheia/.github/ISSUE_TEMPLATE/bug_report.md | 42 - aletheia/.github/ISSUE_TEMPLATE/custom.md | 14 - .../.github/ISSUE_TEMPLATE/documentation.md | 70 - .../.github/ISSUE_TEMPLATE/feature_request.md | 24 - aletheia/.github/ISSUE_TEMPLATE/question.md | 59 - aletheia/.github/dependabot.yml | 22 - aletheia/.github/workflows/README.md | 51 - aletheia/.github/workflows/aletheia.yml | 78 - aletheia/.github/workflows/cflite_batch.yml | 33 - aletheia/.github/workflows/cflite_pr.yml | 32 - aletheia/.github/workflows/codeql.yml | 42 - .../generator-generic-ossf-slsa3-publish.yml | 68 - aletheia/.github/workflows/ghcr-publish.yml | 61 - aletheia/.github/workflows/governance.yml | 26 - aletheia/.github/workflows/hypatia-scan.yml | 180 - aletheia/.github/workflows/instant-sync.yml | 34 - .../.github/workflows/jekyll-gh-pages.yml | 54 - aletheia/.github/workflows/mirror.yml | 50 - .../.github/workflows/publish-container.yml | 45 - aletheia/.github/workflows/rust-ci.yml | 53 - .../.github/workflows/scorecard-enforcer.yml | 74 - aletheia/.github/workflows/scorecard.yml | 32 - aletheia/.github/workflows/secret-scanner.yml | 70 - aletheia/.gitignore | 89 - aletheia/.gitlab-ci.yml | 295 -- aletheia/.machine_readable/6a2/AGENTIC.a2ml | 34 - aletheia/.machine_readable/6a2/ECOSYSTEM.a2ml | 20 - aletheia/.machine_readable/6a2/META.a2ml | 27 - aletheia/.machine_readable/6a2/NEUROSYM.a2ml | 21 - aletheia/.machine_readable/6a2/PLAYBOOK.a2ml | 26 - aletheia/.machine_readable/6a2/STATE.a2ml | 39 - aletheia/.nojekyll | 0 aletheia/.rustfmt.toml | 75 - aletheia/.well-known/ai.txt | 38 - aletheia/.well-known/humans.txt | 31 - aletheia/.well-known/security.txt | 15 - aletheia/ABI-FFI-README.adoc | 409 --- aletheia/ALETHEIA-HANDOVER.adoc | 203 - aletheia/CHANGELOG.adoc | 204 - aletheia/CLAUDE.md | 421 --- aletheia/CODE_OF_CONDUCT.adoc | 204 - aletheia/CONTRIBUTING.adoc | 60 - aletheia/CROSSREPO-HANDOVER.adoc | 440 --- aletheia/Cargo.lock | 7 - aletheia/Cargo.toml | 33 - aletheia/Containerfile | 44 - aletheia/FINAL_SUMMARY.adoc | 732 ---- aletheia/HANDOVER.scm | 261 -- aletheia/Justfile | 209 -- aletheia/LICENSE | 160 - aletheia/LICENSES/CC-BY-SA-4.0.txt | 428 --- aletheia/LICENSES/PMPL-1.0-or-later.txt | 162 - aletheia/MAINTAINERS.adoc | 195 - aletheia/Mustfile | 13 - aletheia/PALIMPSEST.adoc | 43 - aletheia/PROJECT_STATUS.adoc | 119 - aletheia/QUICK_REFERENCE.adoc | 230 -- aletheia/README.adoc | 292 -- aletheia/ROADMAP.adoc | 309 -- aletheia/RSR-CONFORMITY.adoc | 45 - aletheia/RSR_OUTLINE.adoc | 220 -- aletheia/SECURITY.adoc | 212 -- aletheia/benches/verification_benchmark.rs | 260 -- aletheia/conformance/ECHIDNA-CONFORMANCE.adoc | 132 - aletheia/conformance/OIKOS-CONFORMANCE.adoc | 105 - .../conformance/PALIMPSEST-CONFORMANCE.adoc | 98 - aletheia/conformance/README.adoc | 88 - aletheia/conformance/RSR-CONFORMANCE.adoc | 118 - aletheia/contractiles/README.adoc | 21 - aletheia/contractiles/dust/Dustfile | 29 - aletheia/contractiles/must/Mustfile | 35 - aletheia/docs/ARCHITECTURE.adoc | 410 --- aletheia/docs/BADGES.adoc | 253 -- aletheia/docs/CITATIONS.adoc | 38 - aletheia/docs/DEPLOYMENT.adoc | 583 --- aletheia/docs/FAQ.adoc | 348 -- aletheia/docs/MIGRATION-GUIDE.adoc | 677 ---- aletheia/docs/PRIORITIES.adoc | 258 -- aletheia/docs/QUICK_START.adoc | 353 -- aletheia/docs/RSR-SPECIFICATION.adoc | 352 -- aletheia/docs/SILVER-LEVEL.adoc | 423 --- aletheia/docs/VALUE-CHAIN-POLICY.adoc | 204 - aletheia/eclexiaiser.toml | 26 - aletheia/examples/simple_verification.rs | 48 - aletheia/examples/web-project-deno.json | 20 - .../rhodibot/.github/workflows/ci.yml | 105 - aletheia/extraction/rhodibot/.gitlab-ci.yml | 104 - .../extraction/rhodibot/.well-known/ai.txt | 18 - .../rhodibot/.well-known/humans.txt | 17 - .../rhodibot/.well-known/security.txt | 13 - aletheia/extraction/rhodibot/Cargo.lock | 7 - aletheia/extraction/rhodibot/Cargo.toml | 30 - aletheia/extraction/rhodibot/Justfile | 85 - aletheia/extraction/rhodibot/README.adoc | 198 - .../rhodibot/docs/VALUE-CHAIN-POLICY.adoc | 204 - aletheia/extraction/rhodibot/manifest.scm | 24 - aletheia/extraction/rhodibot/src/bot.rs | 349 -- aletheia/extraction/rhodibot/src/lib.rs | 1055 ------ aletheia/extraction/rhodibot/src/main.rs | 904 ----- .../rhodibot/tests/integration_tests.rs | 141 - .../extraction/rhodium-pipeline/Cargo.lock | 7 - .../extraction/rhodium-pipeline/Cargo.toml | 30 - .../extraction/rhodium-pipeline/README.adoc | 236 -- .../docs/VALUE-CHAIN-POLICY.adoc | 204 - .../extraction/rhodium-pipeline/src/lib.rs | 563 --- .../extraction/rhodium-pipeline/src/main.rs | 222 -- aletheia/ffi/zig/build.zig | 95 - aletheia/ffi/zig/src/main.zig | 275 -- aletheia/ffi/zig/test/integration_test.zig | 183 - aletheia/fuzz/Cargo.toml | 24 - aletheia/fuzz/fuzz_targets/fuzz_input.rs | 21 - aletheia/manifest.scm | 24 - aletheia/rust-toolchain.toml | 6 - aletheia/scripts/create-template.sh | 492 --- aletheia/scripts/install.sh | 135 - aletheia/src/checks.rs | 2105 ----------- aletheia/src/config.rs | 848 ----- aletheia/src/main.rs | 446 --- aletheia/src/output.rs | 629 ---- aletheia/src/types.rs | 246 -- aletheia/templates/ada/.editorconfig | 19 - .../templates/ada/.github/workflows/ci.yml | 40 - .../templates/ada/.github/workflows/proof.yml | 92 - aletheia/templates/ada/.gitignore | 24 - .../ada/.machine_readable/rsr-profile.a2ml | 12 - aletheia/templates/ada/.tool-versions | 3 - aletheia/templates/ada/@@MOD_NAME@@.gpr | 37 - aletheia/templates/ada/Justfile | 50 - aletheia/templates/ada/README.adoc | 118 - aletheia/templates/ada/src/@@MOD_NAME@@.adb | 31 - aletheia/templates/ada/src/@@MOD_NAME@@.ads | 50 - aletheia/templates/ada/src/main.adb | 82 - aletheia/templates/ada/tests/run_tests.adb | 64 - aletheia/templates/ada/tests/tests.gpr | 13 - aletheia/templates/agda/.editorconfig | 19 - .../templates/agda/.github/workflows/ci.yml | 41 - aletheia/templates/agda/.gitignore | 4 - .../agda/.machine_readable/rsr-profile.a2ml | 12 - aletheia/templates/agda/.tool-versions | 2 - .../templates/agda/@@PROJECT_NAME@@.agda-lib | 2 - aletheia/templates/agda/Justfile | 36 - aletheia/templates/agda/README.adoc | 83 - .../templates/agda/src/@@MOD_CAMEL@@.agda | 52 - aletheia/templates/agda/src/Properties.agda | 29 - aletheia/templates/common/.gitattributes | 11 - .../common/.github/workflows/actions.lock | 9 - .../common/.github/workflows/governance.yml | 18 - .../common/.github/workflows/hypatia-scan.yml | 21 - aletheia/templates/common/.well-known/ai.txt | 15 - .../templates/common/.well-known/humans.txt | 13 - .../templates/common/.well-known/security.txt | 9 - aletheia/templates/common/0-AI-MANIFEST.a2ml | 52 - aletheia/templates/common/CHANGELOG.adoc | 19 - .../templates/common/CODE_OF_CONDUCT.adoc | 36 - aletheia/templates/common/CONTRIBUTING.adoc | 43 - aletheia/templates/common/LICENSE | 9 - .../common/LICENSES/CC-BY-SA-4.0.txt | 428 --- .../templates/common/LICENSES/MPL-2.0.txt | 373 -- aletheia/templates/common/MAINTAINERS.adoc | 29 - aletheia/templates/common/SECURITY.adoc | 33 - aletheia/templates/elixir/.editorconfig | 19 - aletheia/templates/elixir/.formatter.exs | 5 - .../templates/elixir/.github/workflows/ci.yml | 42 - aletheia/templates/elixir/.gitignore | 9 - .../elixir/.machine_readable/rsr-profile.a2ml | 12 - aletheia/templates/elixir/.tool-versions | 3 - aletheia/templates/elixir/Justfile | 37 - aletheia/templates/elixir/README.adoc | 83 - aletheia/templates/elixir/lib/@@MOD_NAME@@.ex | 47 - .../templates/elixir/lib/@@MOD_NAME@@/cli.ex | 62 - aletheia/templates/elixir/mix.exs | 21 - .../elixir/test/@@MOD_NAME@@_test.exs | 45 - .../templates/elixir/test/test_helper.exs | 2 - aletheia/templates/haskell/.editorconfig | 19 - .../haskell/.github/workflows/ci.yml | 39 - aletheia/templates/haskell/.gitignore | 7 - .../.machine_readable/rsr-profile.a2ml | 12 - aletheia/templates/haskell/.tool-versions | 3 - .../templates/haskell/@@PROJECT_NAME@@.cabal | 44 - aletheia/templates/haskell/Justfile | 35 - aletheia/templates/haskell/README.adoc | 83 - aletheia/templates/haskell/app/Main.hs | 51 - aletheia/templates/haskell/cabal.project | 2 - aletheia/templates/haskell/src/Core.hs | 24 - aletheia/templates/haskell/test/Main.hs | 45 - aletheia/templates/rust/.editorconfig | 22 - aletheia/templates/rust/.gitignore | 23 - .../rust/.machine_readable/rsr-profile.a2ml | 16 - aletheia/templates/rust/.tool-versions | 5 - aletheia/templates/rust/Justfile | 69 - aletheia/templates/rust/README.adoc | 112 - aletheia/templates/zig/.editorconfig | 19 - .../templates/zig/.github/workflows/ci.yml | 41 - aletheia/templates/zig/.gitignore | 5 - .../zig/.machine_readable/rsr-profile.a2ml | 12 - aletheia/templates/zig/.tool-versions | 2 - aletheia/templates/zig/Justfile | 37 - aletheia/templates/zig/README.adoc | 83 - aletheia/templates/zig/build.zig | 71 - aletheia/templates/zig/src/main.zig | 73 - aletheia/templates/zig/src/root.zig | 48 - .../templates/zig/test/integration_test.zig | 37 - aletheia/tests/integration_tests.rs | 1717 --------- contractile.just | 75 - docs/STATE-OF-PLAY-2026-07-29.adoc | 320 -- docs/architecture.adoc | 79 - docs/contributing.adoc | 91 - docs/decisions/0001-template.adoc | 54 - docs/proof-debt.adoc | 254 -- docs/tech-debt-2026-05-26.adoc | 88 - docs/troubleshooting.adoc | 58 - docs/usage.adoc | 82 - llm-warmup-dev.adoc | 19 - llm-warmup-user.adoc | 19 - manifest.scm | 14 - mise.toml | 17 - setup.sh | 278 -- {aletheia/templates/rust/src => src}/impl.rs | 0 {aletheia/templates/rust/src => src}/lib.rs | 2 +- {aletheia/templates/rust/src => src}/main.rs | 12 +- stapeln.toml | 90 - tests/aspect/security_test.rs | 176 - tests/e2e/brainfuck_e2e_test.rs | 168 - tests/fuzz/placeholder.txt | 1 - .../rust/tests => tests}/integration_test.rs | 2 +- tests/property_test.rs | 203 - .../verification => verification}/Cargo.toml | 4 +- .../verification => verification}/README.adoc | 0 .../verification => verification}/src/lib.rs | 2 +- .../why3find.json | 0 www/.well-known/ai.txt | 18 - www/.well-known/humans.txt | 14 - www/.well-known/security.txt | 9 - 352 files changed, 364 insertions(+), 43277 deletions(-) delete mode 100644 .claude/CLAUDE.md delete mode 100644 .github/CODEOWNERS delete mode 100644 .github/CONTRIBUTING.md delete mode 100644 .github/FUNDING.yml delete mode 100644 .github/copilot/coding-agent.yml delete mode 100644 .github/dependabot.yml delete mode 100644 .github/funding.yml delete mode 100755 .github/hooks/validate-a2ml.sh delete mode 100755 .github/hooks/validate-k9.sh delete mode 100644 .github/label-classifier.json delete mode 100644 .github/labels.json delete mode 100644 .github/scripts/classify-issue.jq delete mode 100644 .github/workflows/boj-build.yml delete mode 100644 .github/workflows/casket-pages.yml delete mode 100644 .github/workflows/changelog.yml rename {aletheia/templates/rust/.github => .github}/workflows/ci.yml (100%) delete mode 100644 .github/workflows/codeql.yml delete mode 100644 .github/workflows/dogfood-gate.yml delete mode 100644 .github/workflows/instant-sync.yml delete mode 100644 .github/workflows/label-triage.yml delete mode 100644 .github/workflows/labels.yml delete mode 100644 .github/workflows/mirror.yml delete mode 100644 .github/workflows/pages.yml rename {aletheia/templates/rust/.github => .github}/workflows/proof.yml (100%) delete mode 100644 .github/workflows/push-email-notify.yml delete mode 100644 .github/workflows/rust-ci.yml delete mode 100644 .github/workflows/scorecard.yml delete mode 100644 .github/workflows/secret-scanner.yml delete mode 100644 .gitmodules delete mode 100644 .hypatia-ignore delete mode 100644 .hypatia/activity.jsonl delete mode 100644 .hypatia/last-visit.json delete mode 100644 .machine_readable/6a2/0-AI-MANIFEST.a2ml delete mode 100644 .machine_readable/6a2/AGENTIC.a2ml delete mode 100644 .machine_readable/6a2/ECOSYSTEM.a2ml delete mode 100644 .machine_readable/6a2/META.a2ml delete mode 100644 .machine_readable/6a2/NEUROSYM.a2ml delete mode 100644 .machine_readable/6a2/PLAYBOOK.a2ml delete mode 100644 .machine_readable/6a2/README.adoc delete mode 100644 .machine_readable/6a2/STATE.a2ml delete mode 100644 .machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml delete mode 100644 .machine_readable/6a2/anchor/ANCHOR.a2ml delete mode 100644 .machine_readable/6a2/anchor/README.adoc delete mode 100644 .machine_readable/CLADE.a2ml delete mode 100644 .machine_readable/bot_directives/README.adoc delete mode 100644 .machine_readable/bot_directives/coverage.a2ml delete mode 100644 .machine_readable/bot_directives/debt.a2ml delete mode 100644 .machine_readable/bot_directives/git-private-farm.a2ml delete mode 100644 .machine_readable/bot_directives/gitbot-fleet.a2ml delete mode 100644 .machine_readable/bot_directives/hypatia.a2ml delete mode 100644 .machine_readable/bot_directives/methodology.a2ml delete mode 100644 .machine_readable/contractiles/Adjustfile.a2ml delete mode 100644 .machine_readable/contractiles/Bustfile.a2ml delete mode 100644 .machine_readable/contractiles/Dustfile.a2ml delete mode 100644 .machine_readable/contractiles/Intentfile.a2ml delete mode 100644 .machine_readable/contractiles/Justfile delete mode 100644 .machine_readable/contractiles/Mustfile.a2ml delete mode 100644 .machine_readable/contractiles/Trustfile.a2ml delete mode 100644 .machine_readable/integrations/feedback-o-tron.a2ml delete mode 100644 .machine_readable/integrations/proven.a2ml delete mode 100644 .machine_readable/integrations/verisimdb.a2ml delete mode 100644 .machine_readable/integrations/vexometer.a2ml delete mode 100644 .machine_readable/self-validating/README.adoc delete mode 100644 .machine_readable/self-validating/examples/ci-config.k9.ncl delete mode 100644 .machine_readable/self-validating/examples/project-metadata.k9.ncl delete mode 100644 .machine_readable/self-validating/examples/setup-repo.k9.ncl delete mode 100644 .machine_readable/self-validating/template-hunt.k9.ncl delete mode 100644 .machine_readable/self-validating/template-kennel.k9.ncl delete mode 100644 .machine_readable/self-validating/template-yard.k9.ncl delete mode 100644 .machine_readable/svc/README.adoc mode change 120000 => 100644 .well-known/ai.txt mode change 120000 => 100644 .well-known/humans.txt mode change 120000 => 100644 .well-known/security.txt delete mode 100644 ARCHITECTURE.adoc delete mode 100644 CHANGELOG.md rename aletheia/templates/rust/Cargo.toml => Cargo.toml (87%) delete mode 100644 DELIVERY-186-197.md delete mode 100644 EXPLAINME-new.adoc delete mode 100644 EXPLAINME.adoc delete mode 100644 GLOSSARY.adoc delete mode 100644 GOVERNANCE.adoc delete mode 100644 LICENSES/AGPL-3.0-or-later.txt delete mode 100644 MAINTAINERS delete mode 100644 Mustfile delete mode 100644 NOTICE delete mode 100644 PROOF-NEEDS.adoc delete mode 100644 QUICKSTART-DEV.adoc delete mode 100644 QUICKSTART-MAINTAINER.adoc delete mode 100644 QUICKSTART-USER.adoc delete mode 100644 ROADMAP.adoc delete mode 100644 TEST-NEEDS.adoc delete mode 100644 TOPOLOGY.adoc delete mode 160000 absolute-zero delete mode 100644 aletheia/.claude/CLAUDE.md delete mode 100644 aletheia/.clippy.toml delete mode 100644 aletheia/.clusterfuzzlite/Containerfile delete mode 100755 aletheia/.clusterfuzzlite/build.sh delete mode 100644 aletheia/.clusterfuzzlite/project.yaml delete mode 100644 aletheia/.dockerignore delete mode 100644 aletheia/.editorconfig delete mode 100644 aletheia/.gitattributes delete mode 100644 aletheia/.github/FUNDING.yml delete mode 100644 aletheia/.github/ISSUE_TEMPLATE/bug_report.md delete mode 100644 aletheia/.github/ISSUE_TEMPLATE/custom.md delete mode 100644 aletheia/.github/ISSUE_TEMPLATE/documentation.md delete mode 100644 aletheia/.github/ISSUE_TEMPLATE/feature_request.md delete mode 100644 aletheia/.github/ISSUE_TEMPLATE/question.md delete mode 100644 aletheia/.github/dependabot.yml delete mode 100644 aletheia/.github/workflows/README.md delete mode 100644 aletheia/.github/workflows/aletheia.yml delete mode 100644 aletheia/.github/workflows/cflite_batch.yml delete mode 100644 aletheia/.github/workflows/cflite_pr.yml delete mode 100644 aletheia/.github/workflows/codeql.yml delete mode 100644 aletheia/.github/workflows/generator-generic-ossf-slsa3-publish.yml delete mode 100644 aletheia/.github/workflows/ghcr-publish.yml delete mode 100644 aletheia/.github/workflows/governance.yml delete mode 100644 aletheia/.github/workflows/hypatia-scan.yml delete mode 100644 aletheia/.github/workflows/instant-sync.yml delete mode 100644 aletheia/.github/workflows/jekyll-gh-pages.yml delete mode 100644 aletheia/.github/workflows/mirror.yml delete mode 100644 aletheia/.github/workflows/publish-container.yml delete mode 100644 aletheia/.github/workflows/rust-ci.yml delete mode 100644 aletheia/.github/workflows/scorecard-enforcer.yml delete mode 100644 aletheia/.github/workflows/scorecard.yml delete mode 100644 aletheia/.github/workflows/secret-scanner.yml delete mode 100644 aletheia/.gitignore delete mode 100644 aletheia/.gitlab-ci.yml delete mode 100644 aletheia/.machine_readable/6a2/AGENTIC.a2ml delete mode 100644 aletheia/.machine_readable/6a2/ECOSYSTEM.a2ml delete mode 100644 aletheia/.machine_readable/6a2/META.a2ml delete mode 100644 aletheia/.machine_readable/6a2/NEUROSYM.a2ml delete mode 100644 aletheia/.machine_readable/6a2/PLAYBOOK.a2ml delete mode 100644 aletheia/.machine_readable/6a2/STATE.a2ml delete mode 100644 aletheia/.nojekyll delete mode 100644 aletheia/.rustfmt.toml delete mode 100644 aletheia/.well-known/ai.txt delete mode 100644 aletheia/.well-known/humans.txt delete mode 100644 aletheia/.well-known/security.txt delete mode 100644 aletheia/ABI-FFI-README.adoc delete mode 100644 aletheia/ALETHEIA-HANDOVER.adoc delete mode 100644 aletheia/CHANGELOG.adoc delete mode 100644 aletheia/CLAUDE.md delete mode 100644 aletheia/CODE_OF_CONDUCT.adoc delete mode 100644 aletheia/CONTRIBUTING.adoc delete mode 100644 aletheia/CROSSREPO-HANDOVER.adoc delete mode 100644 aletheia/Cargo.lock delete mode 100644 aletheia/Cargo.toml delete mode 100644 aletheia/Containerfile delete mode 100644 aletheia/FINAL_SUMMARY.adoc delete mode 100644 aletheia/HANDOVER.scm delete mode 100644 aletheia/Justfile delete mode 100644 aletheia/LICENSE delete mode 100644 aletheia/LICENSES/CC-BY-SA-4.0.txt delete mode 100644 aletheia/LICENSES/PMPL-1.0-or-later.txt delete mode 100644 aletheia/MAINTAINERS.adoc delete mode 100644 aletheia/Mustfile delete mode 100644 aletheia/PALIMPSEST.adoc delete mode 100644 aletheia/PROJECT_STATUS.adoc delete mode 100644 aletheia/QUICK_REFERENCE.adoc delete mode 100644 aletheia/README.adoc delete mode 100644 aletheia/ROADMAP.adoc delete mode 100644 aletheia/RSR-CONFORMITY.adoc delete mode 100644 aletheia/RSR_OUTLINE.adoc delete mode 100644 aletheia/SECURITY.adoc delete mode 100644 aletheia/benches/verification_benchmark.rs delete mode 100644 aletheia/conformance/ECHIDNA-CONFORMANCE.adoc delete mode 100644 aletheia/conformance/OIKOS-CONFORMANCE.adoc delete mode 100644 aletheia/conformance/PALIMPSEST-CONFORMANCE.adoc delete mode 100644 aletheia/conformance/README.adoc delete mode 100644 aletheia/conformance/RSR-CONFORMANCE.adoc delete mode 100644 aletheia/contractiles/README.adoc delete mode 100644 aletheia/contractiles/dust/Dustfile delete mode 100644 aletheia/contractiles/must/Mustfile delete mode 100644 aletheia/docs/ARCHITECTURE.adoc delete mode 100644 aletheia/docs/BADGES.adoc delete mode 100644 aletheia/docs/CITATIONS.adoc delete mode 100644 aletheia/docs/DEPLOYMENT.adoc delete mode 100644 aletheia/docs/FAQ.adoc delete mode 100644 aletheia/docs/MIGRATION-GUIDE.adoc delete mode 100644 aletheia/docs/PRIORITIES.adoc delete mode 100644 aletheia/docs/QUICK_START.adoc delete mode 100644 aletheia/docs/RSR-SPECIFICATION.adoc delete mode 100644 aletheia/docs/SILVER-LEVEL.adoc delete mode 100644 aletheia/docs/VALUE-CHAIN-POLICY.adoc delete mode 100644 aletheia/eclexiaiser.toml delete mode 100644 aletheia/examples/simple_verification.rs delete mode 100644 aletheia/examples/web-project-deno.json delete mode 100644 aletheia/extraction/rhodibot/.github/workflows/ci.yml delete mode 100644 aletheia/extraction/rhodibot/.gitlab-ci.yml delete mode 100644 aletheia/extraction/rhodibot/.well-known/ai.txt delete mode 100644 aletheia/extraction/rhodibot/.well-known/humans.txt delete mode 100644 aletheia/extraction/rhodibot/.well-known/security.txt delete mode 100644 aletheia/extraction/rhodibot/Cargo.lock delete mode 100644 aletheia/extraction/rhodibot/Cargo.toml delete mode 100644 aletheia/extraction/rhodibot/Justfile delete mode 100644 aletheia/extraction/rhodibot/README.adoc delete mode 100644 aletheia/extraction/rhodibot/docs/VALUE-CHAIN-POLICY.adoc delete mode 100644 aletheia/extraction/rhodibot/manifest.scm delete mode 100644 aletheia/extraction/rhodibot/src/bot.rs delete mode 100644 aletheia/extraction/rhodibot/src/lib.rs delete mode 100644 aletheia/extraction/rhodibot/src/main.rs delete mode 100644 aletheia/extraction/rhodibot/tests/integration_tests.rs delete mode 100644 aletheia/extraction/rhodium-pipeline/Cargo.lock delete mode 100644 aletheia/extraction/rhodium-pipeline/Cargo.toml delete mode 100644 aletheia/extraction/rhodium-pipeline/README.adoc delete mode 100644 aletheia/extraction/rhodium-pipeline/docs/VALUE-CHAIN-POLICY.adoc delete mode 100644 aletheia/extraction/rhodium-pipeline/src/lib.rs delete mode 100644 aletheia/extraction/rhodium-pipeline/src/main.rs delete mode 100644 aletheia/ffi/zig/build.zig delete mode 100644 aletheia/ffi/zig/src/main.zig delete mode 100644 aletheia/ffi/zig/test/integration_test.zig delete mode 100644 aletheia/fuzz/Cargo.toml delete mode 100644 aletheia/fuzz/fuzz_targets/fuzz_input.rs delete mode 100644 aletheia/manifest.scm delete mode 100644 aletheia/rust-toolchain.toml delete mode 100755 aletheia/scripts/create-template.sh delete mode 100755 aletheia/scripts/install.sh delete mode 100644 aletheia/src/checks.rs delete mode 100644 aletheia/src/config.rs delete mode 100644 aletheia/src/main.rs delete mode 100644 aletheia/src/output.rs delete mode 100644 aletheia/src/types.rs delete mode 100644 aletheia/templates/ada/.editorconfig delete mode 100644 aletheia/templates/ada/.github/workflows/ci.yml delete mode 100644 aletheia/templates/ada/.github/workflows/proof.yml delete mode 100644 aletheia/templates/ada/.gitignore delete mode 100644 aletheia/templates/ada/.machine_readable/rsr-profile.a2ml delete mode 100644 aletheia/templates/ada/.tool-versions delete mode 100644 aletheia/templates/ada/@@MOD_NAME@@.gpr delete mode 100644 aletheia/templates/ada/Justfile delete mode 100644 aletheia/templates/ada/README.adoc delete mode 100644 aletheia/templates/ada/src/@@MOD_NAME@@.adb delete mode 100644 aletheia/templates/ada/src/@@MOD_NAME@@.ads delete mode 100644 aletheia/templates/ada/src/main.adb delete mode 100644 aletheia/templates/ada/tests/run_tests.adb delete mode 100644 aletheia/templates/ada/tests/tests.gpr delete mode 100644 aletheia/templates/agda/.editorconfig delete mode 100644 aletheia/templates/agda/.github/workflows/ci.yml delete mode 100644 aletheia/templates/agda/.gitignore delete mode 100644 aletheia/templates/agda/.machine_readable/rsr-profile.a2ml delete mode 100644 aletheia/templates/agda/.tool-versions delete mode 100644 aletheia/templates/agda/@@PROJECT_NAME@@.agda-lib delete mode 100644 aletheia/templates/agda/Justfile delete mode 100644 aletheia/templates/agda/README.adoc delete mode 100644 aletheia/templates/agda/src/@@MOD_CAMEL@@.agda delete mode 100644 aletheia/templates/agda/src/Properties.agda delete mode 100644 aletheia/templates/common/.gitattributes delete mode 100644 aletheia/templates/common/.github/workflows/actions.lock delete mode 100644 aletheia/templates/common/.github/workflows/governance.yml delete mode 100644 aletheia/templates/common/.github/workflows/hypatia-scan.yml delete mode 100644 aletheia/templates/common/.well-known/ai.txt delete mode 100644 aletheia/templates/common/.well-known/humans.txt delete mode 100644 aletheia/templates/common/.well-known/security.txt delete mode 100644 aletheia/templates/common/0-AI-MANIFEST.a2ml delete mode 100644 aletheia/templates/common/CHANGELOG.adoc delete mode 100644 aletheia/templates/common/CODE_OF_CONDUCT.adoc delete mode 100644 aletheia/templates/common/CONTRIBUTING.adoc delete mode 100644 aletheia/templates/common/LICENSE delete mode 100644 aletheia/templates/common/LICENSES/CC-BY-SA-4.0.txt delete mode 100644 aletheia/templates/common/LICENSES/MPL-2.0.txt delete mode 100644 aletheia/templates/common/MAINTAINERS.adoc delete mode 100644 aletheia/templates/common/SECURITY.adoc delete mode 100644 aletheia/templates/elixir/.editorconfig delete mode 100644 aletheia/templates/elixir/.formatter.exs delete mode 100644 aletheia/templates/elixir/.github/workflows/ci.yml delete mode 100644 aletheia/templates/elixir/.gitignore delete mode 100644 aletheia/templates/elixir/.machine_readable/rsr-profile.a2ml delete mode 100644 aletheia/templates/elixir/.tool-versions delete mode 100644 aletheia/templates/elixir/Justfile delete mode 100644 aletheia/templates/elixir/README.adoc delete mode 100644 aletheia/templates/elixir/lib/@@MOD_NAME@@.ex delete mode 100644 aletheia/templates/elixir/lib/@@MOD_NAME@@/cli.ex delete mode 100644 aletheia/templates/elixir/mix.exs delete mode 100644 aletheia/templates/elixir/test/@@MOD_NAME@@_test.exs delete mode 100644 aletheia/templates/elixir/test/test_helper.exs delete mode 100644 aletheia/templates/haskell/.editorconfig delete mode 100644 aletheia/templates/haskell/.github/workflows/ci.yml delete mode 100644 aletheia/templates/haskell/.gitignore delete mode 100644 aletheia/templates/haskell/.machine_readable/rsr-profile.a2ml delete mode 100644 aletheia/templates/haskell/.tool-versions delete mode 100644 aletheia/templates/haskell/@@PROJECT_NAME@@.cabal delete mode 100644 aletheia/templates/haskell/Justfile delete mode 100644 aletheia/templates/haskell/README.adoc delete mode 100644 aletheia/templates/haskell/app/Main.hs delete mode 100644 aletheia/templates/haskell/cabal.project delete mode 100644 aletheia/templates/haskell/src/Core.hs delete mode 100644 aletheia/templates/haskell/test/Main.hs delete mode 100644 aletheia/templates/rust/.editorconfig delete mode 100644 aletheia/templates/rust/.gitignore delete mode 100644 aletheia/templates/rust/.machine_readable/rsr-profile.a2ml delete mode 100644 aletheia/templates/rust/.tool-versions delete mode 100644 aletheia/templates/rust/Justfile delete mode 100644 aletheia/templates/rust/README.adoc delete mode 100644 aletheia/templates/zig/.editorconfig delete mode 100644 aletheia/templates/zig/.github/workflows/ci.yml delete mode 100644 aletheia/templates/zig/.gitignore delete mode 100644 aletheia/templates/zig/.machine_readable/rsr-profile.a2ml delete mode 100644 aletheia/templates/zig/.tool-versions delete mode 100644 aletheia/templates/zig/Justfile delete mode 100644 aletheia/templates/zig/README.adoc delete mode 100644 aletheia/templates/zig/build.zig delete mode 100644 aletheia/templates/zig/src/main.zig delete mode 100644 aletheia/templates/zig/src/root.zig delete mode 100644 aletheia/templates/zig/test/integration_test.zig delete mode 100644 aletheia/tests/integration_tests.rs delete mode 100644 contractile.just delete mode 100644 docs/STATE-OF-PLAY-2026-07-29.adoc delete mode 100644 docs/architecture.adoc delete mode 100644 docs/contributing.adoc delete mode 100644 docs/decisions/0001-template.adoc delete mode 100644 docs/proof-debt.adoc delete mode 100644 docs/tech-debt-2026-05-26.adoc delete mode 100644 docs/troubleshooting.adoc delete mode 100644 docs/usage.adoc delete mode 100644 llm-warmup-dev.adoc delete mode 100644 llm-warmup-user.adoc delete mode 100644 manifest.scm delete mode 100644 mise.toml delete mode 100755 setup.sh rename {aletheia/templates/rust/src => src}/impl.rs (100%) rename {aletheia/templates/rust/src => src}/lib.rs (97%) rename {aletheia/templates/rust/src => src}/main.rs (84%) delete mode 100644 stapeln.toml delete mode 100644 tests/aspect/security_test.rs delete mode 100644 tests/e2e/brainfuck_e2e_test.rs delete mode 100644 tests/fuzz/placeholder.txt rename {aletheia/templates/rust/tests => tests}/integration_test.rs (97%) delete mode 100644 tests/property_test.rs rename {aletheia/templates/rust/verification => verification}/Cargo.toml (87%) rename {aletheia/templates/rust/verification => verification}/README.adoc (100%) rename {aletheia/templates/rust/verification => verification}/src/lib.rs (91%) rename {aletheia/templates/rust/verification => verification}/why3find.json (100%) delete mode 100644 www/.well-known/ai.txt delete mode 100644 www/.well-known/humans.txt delete mode 100644 www/.well-known/security.txt diff --git a/.claude/CLAUDE.md b/.claude/CLAUDE.md deleted file mode 100644 index 7ffe99c..0000000 --- a/.claude/CLAUDE.md +++ /dev/null @@ -1,84 +0,0 @@ -## Machine-Readable Artefacts - -The following files in `.machine_readable/` contain structured project metadata: - -- `.machine_readable/6a2/STATE.a2ml` - Current project state and progress -- `.machine_readable/6a2/META.a2ml` - Architecture decisions and development practices -- `.machine_readable/6a2/ECOSYSTEM.a2ml` - Position in the ecosystem and related projects -- `.machine_readable/6a2/AGENTIC.a2ml` - AI agent interaction patterns -- `.machine_readable/6a2/NEUROSYM.a2ml` - Neurosymbolic integration config -- `.machine_readable/6a2/PLAYBOOK.a2ml` - Operational runbook - ---- - -# CLAUDE.md - AI Assistant Instructions - -## Language Policy (Hyperpolymath Standard) - -### ALLOWED Languages & Tools - -| Language/Tool | Use Case | Notes | -|---------------|----------|-------| -| **AffineScript** | Primary application code | Affine-typed, compiles to typed-wasm or ESM | -| **Bun** | JS runtime & package management (tier 1) | Default for all new work. Runs compiled ESM/JS directly — no bundler step. Uses an npm-compatible `package.json` plus `bun.lock` — both are expected, not anti-patterns. | -| **Rust** | Performance-critical, systems, WASM | Preferred for CLI tools | -| **Tauri 2.0+** | Mobile apps (iOS/Android) | Rust backend + web UI | -| **Dioxus** | Mobile apps (native UI) | Pure Rust, React-like | -| **Gleam** | Backend services | Runs on BEAM or compiles to JS | -| **Bash/POSIX Shell** | Scripts, automation | Keep minimal | -| **JavaScript** | Only where AffineScript cannot | MCP protocol glue, Bun APIs | -| **Nickel** | Configuration language | For complex configs | -| **Guile Scheme** | State/meta files | .machine_readable/6a2/STATE.a2ml, .machine_readable/6a2/META.a2ml, .machine_readable/6a2/ECOSYSTEM.a2ml | -| **Julia** | Batch scripts, data processing | Per RSR | -| **OCaml** | AffineScript compiler | Language-specific | -| **Ada** | Safety-critical systems | Where required | - -### BANNED - Do Not Use - -| Banned | Replacement | -|--------|-------------| -| TypeScript | AffineScript | -| ReScript | AffineScript | -| Deno | Bun | -| Node.js | Bun | -| npm | Bun | -| pnpm/yarn | Bun | -| Go | Rust | -| Python | Julia/Rust/AffineScript | -| Java/Kotlin | Rust/Tauri/Dioxus | -| Swift | Tauri/Dioxus | -| React Native | Tauri/Dioxus | -| Flutter/Dart | Tauri/Dioxus | - -### Mobile Development - -**No exceptions for Kotlin/Swift** - use Rust-first approach: - -1. **Tauri 2.0+** - Web UI (AffineScript) + Rust backend, MIT/Apache-2.0 -2. **Dioxus** - Pure Rust native UI, MIT/Apache-2.0 - -Both are FOSS with independent governance (no Big Tech). - -### Enforcement Rules - -1. **No new TypeScript files** - Convert existing TS to AffineScript -2. **Use `package.json` + `bun.lock` for JS runtime deps** - Bun is npm-compatible; a manifest is REQUIRED -3. **`bun install --production --frozen-lockfile` for production deps** - resolved from `package.json` and pinned via `bun.lock`; `--frozen-lockfile` makes a lockfile mismatch a build failure rather than a silent re-resolve -4. **No Go code** - Use Rust instead -5. **No Python anywhere** - Use Julia for data/batch, Rust for systems, AffineScript for apps -6. **No Kotlin/Swift for mobile** - Use Tauri 2.0+ or Dioxus - -### Package Management - -- **Primary**: Guix (guix.scm) -- **Fallback**: Nix (flake.nix) -- **JS deps**: Bun (`package.json` + `bun.lock`). Declare tooling as a devDependency and run `bunx --no-install --bun ` — a bare `bunx ` can fetch an unpinned package and may start Node via its shebang. - -### Security Requirements - -- No MD5/SHA1 for security (use SHA256+) -- HTTPS only (no HTTP URLs) -- No hardcoded secrets -- SHA-pinned dependencies -- SPDX license headers on all files - diff --git a/.editorconfig b/.editorconfig index 861b83a..7830469 100644 --- a/.editorconfig +++ b/.editorconfig @@ -1,4 +1,4 @@ -# maa-framework - Editor Configuration +# proofgateway - Editor Configuration # https://editorconfig.org root = true @@ -11,58 +11,12 @@ indent_style = space insert_final_newline = true trim_trailing_whitespace = true -[*.md] -trim_trailing_whitespace = false - [*.adoc] trim_trailing_whitespace = false [*.rs] indent_size = 4 -[*.ex] -indent_size = 2 - -[*.exs] -indent_size = 2 - -[*.zig] -indent_size = 4 - -[*.ada] -indent_size = 3 - -[*.adb] -indent_size = 3 - -[*.ads] -indent_size = 3 - -[*.hs] -indent_size = 2 - -[*.res] -indent_size = 2 - -[*.resi] -indent_size = 2 - -[*.ncl] -indent_size = 2 - -[*.rkt] -indent_size = 2 - -[*.scm] -indent_size = 2 - -[*.nix] -indent_size = 2 - [Justfile] indent_style = space indent_size = 4 - -[justfile] -indent_style = space -indent_size = 4 diff --git a/.gitattributes b/.gitattributes index e860a85..f27ed40 100644 --- a/.gitattributes +++ b/.gitattributes @@ -1,54 +1,11 @@ # SPDX-License-Identifier: MPL-2.0 -# RSR-compliant .gitattributes - * text=auto eol=lf -# Source *.rs text eol=lf diff=rust -*.ex text eol=lf diff=elixir -*.exs text eol=lf diff=elixir -*.jl text eol=lf -*.res text eol=lf -*.resi text eol=lf -*.ada text eol=lf diff=ada -*.adb text eol=lf diff=ada -*.ads text eol=lf diff=ada -*.hs text eol=lf -*.chpl text eol=lf -*.scm text eol=lf -*.ncl text eol=lf -*.nix text eol=lf - -# Docs -*.md text eol=lf diff=markdown *.adoc text eol=lf -*.txt text eol=lf - -# Data -*.json text eol=lf -*.yaml text eol=lf +*.a2ml text eol=lf *.yml text eol=lf +*.yaml text eol=lf *.toml text eol=lf -# Config -.gitignore text eol=lf -.gitattributes text eol=lf -justfile text eol=lf -Makefile text eol=lf -Containerfile text eol=lf - -# Scripts -*.sh text eol=lf - -# Binary -*.png binary -*.jpg binary -*.gif binary -*.pdf binary -*.woff2 binary -*.zip binary -*.gz binary - -# Lock files -Cargo.lock text eol=lf -diff -flake.lock text eol=lf -diff +LICENSES/* text eol=lf diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS deleted file mode 100644 index 0d0d666..0000000 --- a/.github/CODEOWNERS +++ /dev/null @@ -1,11 +0,0 @@ -# CODEOWNERS - Defines code ownership for review requirements -# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners - -# Default owners for everything in the repo -* @hyperpolymath - -# Workflow files require maintainer review (security-critical) -/.github/workflows/ @hyperpolymath - -# Security policy requires maintainer review -/SECURITY.md @hyperpolymath diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md deleted file mode 100644 index 1a0b917..0000000 --- a/.github/CONTRIBUTING.md +++ /dev/null @@ -1,109 +0,0 @@ - - -# Contributing — maa-framework - -## Audience - -Developers working **on** `maa-framework`. For consumers (people calling -or depending on it) see usage. - -## Local-dev setup - -Prerequisites — the minimum versions and where to get them: - -- `` v\`\\` — ``. - -- `` v\`\\` — ``. - -- GPG signing key configured (estate policy — all commits must be - signed). See - [standards/docs/secure-coding-training.md](https://github.com/hyperpolymath/standards/blob/main/docs/secure-coding-training.md). - -One-shot setup: - -``` bash -git clone git@github.com:hyperpolymath/maa-framework.git -cd maa-framework -just setup # installs deps, sets up hooks -just test # runs the full test suite -``` - -## Running tests - -- **Unit**: `just` `test-unit` — fast, no I/O. - -- **Integration**: `just` `test-int` — uses real services (database, - HTTP, etc.). Estate policy: prefer real over mocked (see - `feedback_integration_tests_real_db` in maintainer’s memory). - -- **Property**: `just` `test-prop` — randomised, slower; budget - documented in `docs/proof-debt.md` if applicable. - -- **Full**: `just` `test` — runs all of the above. - -## Code style - -We enforce style via CI (governance-reusable.yml from -hyperpolymath/standards). Locally: - -``` bash -just fmt # auto-format -just lint # static checks -``` - -- All commits must be **GPG-signed** (CI enforces; see - [standards](https://github.com/hyperpolymath/standards)). - -- All source files must carry an **SPDX-License-Identifier** header (CI - enforces). - -- Conventional commits — `feat`, `fix`, `chore`, `refactor`, `docs`, - `test`, `ci`, `revert` (CHANGELOG is auto-generated from these via - [`changelog-reusable.yml`](https://github.com/hyperpolymath/standards/blob/main/.github/workflows/changelog-reusable.yml)). - -## Branching & PR workflow - -1. Branch off `main` as `claude/` (for AI agents) or - `/` (for humans). - -2. Make focused, narrow commits — one logical change per commit. - -3. Open a PR against `main`. - -4. **Enable auto-merge immediately** on every PR you open (`gh` `pr` - `merge` `` `--auto` `--squash`) — estate standing policy (see - standards#196 audit and policies). - -5. CI must be green. The PR auto-merges when checks pass + reviews - land. - -## Adding a new dependency - -1. State the **why** in the PR body — what does this dependency unlock? - -2. Check provenance (maintained, audited, no malicious history). - -3. Pin to a SHA, not a tag. - -4. Update `docs/architecture.adoc#Dependencies`. - -## Adding an ADR - -When you make a non-obvious design decision, write it down: - -1. Copy `docs/decisions/0001-template.adoc` → `0002-.adoc`. - -2. Fill in: Context, Decision, Consequences, Alternatives. - -3. Link the ADR from the README or relevant code as a comment. - -## Reporting issues - -- Bugs in `maa-framework`: file at `hyperpolymath/maa-framework/issues`. - -- Estate-wide concerns (policy, conventions, CI): file at - `hyperpolymath/standards/issues`. diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml deleted file mode 100644 index 0e3ca0d..0000000 --- a/.github/FUNDING.yml +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -github: hyperpolymath - diff --git a/.github/copilot/coding-agent.yml b/.github/copilot/coding-agent.yml deleted file mode 100644 index a719a77..0000000 --- a/.github/copilot/coding-agent.yml +++ /dev/null @@ -1,6 +0,0 @@ -mcp_servers: - boj-server: - command: npx - args: ["-y", "@hyperpolymath/boj-server@latest"] - env: - BOJ_URL: http://localhost:7700 diff --git a/.github/dependabot.yml b/.github/dependabot.yml deleted file mode 100644 index 5ebf196..0000000 --- a/.github/dependabot.yml +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -version: 2 -updates: - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "daily" - open-pull-requests-limit: 10 - # Batch this ecosystem into a single PR. Ungrouped, Dependabot - # opens one PR per dependency, and each PR re-fires every - # workflow in the repo. - groups: - github-actions: - patterns: - - "*" - ignore: - # HOLD: github/codeql-action at v4.38.0 (SHA-pinned). v4.38.1 fails - # GitHub workflow-startup validation estate-wide (nexia-list#100; - # SHA-form re-bump bypassed versions-scoped ignores - see - # nexia-list#101/#104). Hold until upstream clears 4.38.1 or a - # newer release verifies green; revisit deliberately. - - dependency-name: "github/codeql-action" - - diff --git a/.github/funding.yml b/.github/funding.yml deleted file mode 100644 index e4f7c07..0000000 --- a/.github/funding.yml +++ /dev/null @@ -1,4 +0,0 @@ -# Funding Configuration -# See: https://docs.github.com/en/repositories/managing-your-repositorys-custom-fields/displaying-a-sponsor-button-in-your-repository - -github: metadatastician diff --git a/.github/hooks/validate-a2ml.sh b/.github/hooks/validate-a2ml.sh deleted file mode 100755 index b16fa85..0000000 --- a/.github/hooks/validate-a2ml.sh +++ /dev/null @@ -1,413 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# validate-a2ml.sh — A2ML manifest validation script -# -# Scans for .a2ml and .deed files and validates: -# 1. Required fields: agent-id or pedigree name, version -# 2. SPDX-License-Identifier header presence -# 3. Attestation block structure (if present) -# 4. Section heading syntax ([section] or ## section) -# -# Environment variables: -# INPUT_PATH — Directory to scan (default: .) -# INPUT_STRICT — Promote warnings to errors (default: false) -# -# Exit codes: -# 0 — All files valid (or only warnings in non-strict mode) -# 1 — Validation errors found - -set -euo pipefail - -# --------------------------------------------------------------------------- -# Configuration -# --------------------------------------------------------------------------- - -SCAN_PATH="${INPUT_PATH:-.}" -STRICT="${INPUT_STRICT:-false}" -PATHS_IGNORE_RAW="${INPUT_PATHS_IGNORE:-}" -GITHUB_OUTPUT_FILE="${GITHUB_OUTPUT:-/dev/null}" - -# Parse paths-ignore: newline-separated fragments, blank lines and # comments -# stripped. Each fragment is a substring match against the file path. Pattern -# adopted from hyperpolymath/hypatia#243 — content-pattern validators must -# distinguish a target from a vendored / fixture file that legitimately -# contains the very pattern being checked. -PATHS_IGNORE=() -while IFS= read -r _frag; do - # Strip leading and trailing whitespace (canonical bash idiom). - _frag="${_frag#"${_frag%%[![:space:]]*}"}" - _frag="${_frag%"${_frag##*[![:space:]]}"}" - [[ -z "$_frag" || "$_frag" == \#* ]] && continue - PATHS_IGNORE+=("$_frag") -done <<< "$PATHS_IGNORE_RAW" - -# Returns 0 if path should be skipped (matches any ignore fragment) -path_ignored() { - local p="$1" frag - for frag in "${PATHS_IGNORE[@]}"; do - [[ "$p" == *"$frag"* ]] && return 0 - done - return 1 -} - -# Counters -FILES_SCANNED=0 -ERRORS=0 -WARNINGS=0 - -# --------------------------------------------------------------------------- -# Helper: emit GitHub annotation -# --------------------------------------------------------------------------- -# Usage: annotate -# level: error | warning | notice -annotate() { - local level="$1" file="$2" line="$3" message="$4" - echo "::${level} file=${file},line=${line}::${message}" -} - -# --------------------------------------------------------------------------- -# Helper: report issue (respects strict mode) -# --------------------------------------------------------------------------- -# Usage: report_issue -# severity: error | warning -report_issue() { - local severity="$1" file="$2" line="$3" message="$4" - - if [[ "$severity" == "warning" && "$STRICT" == "true" ]]; then - severity="error" - fi - - annotate "$severity" "$file" "$line" "$message" - - if [[ "$severity" == "error" ]]; then - ERRORS=$((ERRORS + 1)) - else - WARNINGS=$((WARNINGS + 1)) - fi -} - -# --------------------------------------------------------------------------- -# Validator: check a single .a2ml or .deed file -# --------------------------------------------------------------------------- -validate_a2ml() { - local file="$1" - FILES_SCANNED=$((FILES_SCANNED + 1)) - - # --- Check 1: SPDX header --- - # The SPDX-License-Identifier should appear in the first 10 lines - local has_spdx=false - local line_num=0 - while IFS= read -r line; do - line_num=$((line_num + 1)) - if [[ $line_num -gt 10 ]]; then - break - fi - if [[ "$line" == *"SPDX-License-Identifier"* ]]; then - has_spdx=true - break - fi - done < "$file" - - if [[ "$has_spdx" == "false" ]]; then - report_issue "warning" "$file" 1 \ - "Missing SPDX-License-Identifier in first 10 lines" - fi - - # --- Check 2: Required identity fields --- - # A2ML files must contain either: - # - agent-id = "..." or agent_id = "..." - # - pedigree block with name field - # - name = "..." at top level (for AI manifests) - # - project = "..." (for STATE.a2ml) - local has_identity=false - local has_version=false - local first_form_seen=false - line_num=0 - - while IFS= read -r line; do - line_num=$((line_num + 1)) - - # Check for identity fields (various A2ML patterns) - # TOML/kv form: `name = "..."`, `project = "..."`, `agent-id = "..."` - if [[ "$line" =~ ^[[:space:]]*(agent[-_]id|name|project)[[:space:]]*= ]]; then - has_identity=true - fi - # S-expression form: `(name "...")`, `(project "...")`, - # `(agent-id "...")`. Some A2ML dialects (audit registries, - # classification stores) use Lisp-style s-expressions for the - # metadata block instead of TOML. Identity carries the same - # semantics; only the syntax differs. Match at any indent so it - # also picks up entries nested under `(metadata ...)`. - if [[ "$line" =~ ^[[:space:]]*\([[:space:]]*(agent[-_]id|name|project)[[:space:]]+\" ]]; then - has_identity=true - fi - # Colon / brace-block form: `name: "..."`, `id: "..."`, `project: "..."`. - # YAML-ish and brace-block A2ML dialects (e.g. `Trust { name: "..." }`, - # `id: "tsdm-standard"`) carry the same identity semantics; only the - # delimiter (`:` vs `=`) differs. `id` is the brace-block spelling of an - # identity key. - if [[ "$line" =~ ^[[:space:]]*(agent[-_]id|name|project|id)[[:space:]]*: ]]; then - has_identity=true - fi - # DEED s-expression head form: `(estate-deed`, `(repo-deed`, - # `(estate-atlas-deed`, `(praxis-deed`. Per DEED-GRAMMAR-SPEC - # <>, a file whose first form is one of the four declared - # heads is a deed of that kind, and the head satisfies the structural - # half of identity. This is what lets ATLAS.deed — which carries - # :registry-version and legitimately no :canonical-name — validate. - # The head is the FIRST form (DEED-GRAMMAR-SPEC <>: - # `Deed ::= Header Sep? Form Sep?` — one form, and it carries the head). - # Checking every line let a malformed file open with some other form and - # then append `(estate-deed ...)` lower down to buy identity. Only the - # first form is eligible. - if [[ "$first_form_seen" == "false" && "$line" =~ ^[[:space:]]*\( ]]; then - first_form_seen=true - if [[ "$line" =~ ^[[:space:]]*\((estate-deed|repo-deed|estate-atlas-deed|praxis-deed)([[:space:]]|$) ]]; then - has_identity=true - fi - fi - # DEED keyword identity form: `:canonical-name "..."` and the two other - # identity keywords the spec names. Note the leading colon: none of the - # three forms above match it, because they test the bare words. - if [[ "$line" =~ ^[[:space:]]*:(canonical-name|estate-authority|agent-id)[[:space:]] ]]; then - has_identity=true - fi - # Check for version field — TOML form - if [[ "$line" =~ ^[[:space:]]*(version|schema_version)[[:space:]]*= ]]; then - has_version=true - fi - # Version field — s-expression form - if [[ "$line" =~ ^[[:space:]]*\([[:space:]]*(version|schema_version)[[:space:]]+\" ]]; then - has_version=true - fi - # Version field — colon / brace-block form - if [[ "$line" =~ ^[[:space:]]*(version|schema_version)[[:space:]]*: ]]; then - has_version=true - fi - # DEED keyword version form: `:schema-version "1.0.0"` — leading colon, - # hyphenated, REQUIRED on all four deed heads (DEED-GRAMMAR-SPEC - # <>). All three patterns above spell it `schema_version` - # with no leading colon, so a conforming deed matched none of them. - # `:registry-version` is a distinct field, optional on the atlas. - # `:schema-version` ONLY. `:registry-version` is a distinct, optional - # atlas field (see the note above) and never satisfies the version - # requirement, which DEED-GRAMMAR-SPEC <> makes REQUIRED - # on all four heads. Accepting it let a registry-only atlas head pass - # with no schema version at all. - if [[ "$line" =~ ^[[:space:]]*:schema-version[[:space:]] ]]; then - has_version=true - fi - done < "$file" - - # AI manifest files (0-AI-MANIFEST.a2ml, 0.1-AI-MANIFEST.a2ml, etc.) - # use markdown-style headers and free text, so identity check is relaxed - local basename - basename="$(basename "$file")" - local is_manifest=false - # `.a2ml` ONLY. The exemption exists because AI manifests are markdown-ish - # prose with no in-file identity; it is not a property of the name. Matching - # the bare basename meant `example-AI-MANIFEST.deed` was exempted from BOTH - # the identity and version checks — a deed that skipped the whole gate. - if [[ "$basename" == *"AI-MANIFEST"*.a2ml ]]; then - is_manifest=true - fi - # Canonical typed manifests under /descriptiles/ — identity comes - # from the enclosing directory + filename, not an in-file field. Sibling - # files in the same directory (ECOSYSTEM.a2ml, STATE.a2ml) DO carry their - # own $name/project and continue to be validated normally. - case "$basename" in - AGENTIC.a2ml|META.a2ml|NEUROSYM.a2ml|PLAYBOOK.a2ml|AI.a2ml) - # AI.a2ml = free-text "AI Assistant Instructions" manifest, the same - # doc type as 0-AI-MANIFEST.a2ml but with the bare name; identity is - # carried by the enclosing repo/plugin dir, not an in-file field. - is_manifest=true - ;; - # Dockerfile-style top-level typed manifests (Intentfile, Trustfile, …) - # use markdown-flavoured A2ML; identity is carried by the parent repo. - *file.a2ml) - is_manifest=true - ;; - esac - - # Contractile-shape A2ML files use `@directive:` syntax instead of - # TOML `key = value`. Trustfile.a2ml, Intentfile.a2ml, Mustfile.a2ml, - # Adjustfile.a2ml etc. are policy / trust / intent / abstract files - # whose identity is implicit in their @-prefixed directives - # (`@trust-level`, `@intent`, ...) rather than a TOML name/version - # pair. Treating them as manifest-shape produces 100% false positives — - # they're a different A2ML doc type. Detected by the presence of any - # contractile directive in the file body. - local is_contractile_shape=false - if grep -qE '^@(abstract|trust-level|trust-boundary|trust-actions|trust-deny|intent|must|adjust|end)([[:space:]]*:|$)' "$file"; then - is_contractile_shape=true - fi - - # The structured A2ML tree. Everything under a repo's machine tree — - # `machine-readable/` canonically, `.machine_readable/` in the legacy - # layout — is a typed agent-readable doc (CLADE, ANCHOR, STATE, ECOSYSTEM, - # bot_directives/{debt,coverage,methodology}, ai/AI, policies/*, - # integrations/*, …). Per the RSR convention these carry identity - # structurally — owning repo + path + filename — not via an in-file - # `name`/`agent-id`. This generalises the `descriptiles/` rationale above - # to the whole tree: rsr-template-repo itself ships these files without an - # in-file identity key, so requiring one produces estate-wide false - # positives on every repo built from the canonical template. Files outside - # the machine tree are still validated. - # - # The machine tree is named `machine-readable/` canonically (un-hidden - # 2026-08); `.machine_readable/` is the LEGACY name. BOTH are matched: the - # canon, scaffoldia, the julia variant and ~300 minted repos still carry the - # dotted form, while rsr-template-repo has moved. Matching only one name - # makes whichever half of the estate has not migrated fail this check with - # 16 spurious "missing identity field" errors -- which is exactly what - # happened when the template renamed its tree and this action, being a - # separate implementation from the template's vendored copy, kept matching - # the old name only. - local is_structural_identity=false - # `*` matches the empty string, so */machine-readable/* already covers the - # ./-prefixed form that `find .` emits; spelling it out separately (as the - # original three-branch test did) is redundant. Verified equivalent across - # ./-prefixed, bare and absolute paths, and on the negative cases. - case "$file" in - */machine-readable/*|machine-readable/*|*/.machine_readable/*|.machine_readable/*) - is_structural_identity=true - ;; - esac - - if [[ "$has_identity" == "false" && "$is_manifest" == "false" && "$is_contractile_shape" == "false" && "$is_structural_identity" == "false" ]]; then - report_issue "error" "$file" 1 \ - "Missing required identity field (agent-id, name, or project)" - fi - - # DEED is the live, grammar-bearing format: its schema version is required even - # under a machine-readable tree. The structural-identity exemption below stays - # scoped to legacy *.a2ml, which is no longer authored. (CodeRabbit, PR review.) - local version_exempt_structural="$is_structural_identity" - case "$file" in *.deed) version_exempt_structural=false ;; esac - if [[ "$has_version" == "false" && "$is_manifest" == "false" && "$is_contractile_shape" == "false" && "$version_exempt_structural" == "false" ]]; then - report_issue "warning" "$file" 1 \ - "Missing version or schema_version field" - fi - - # --- Check 3: Attestation block structure --- - # If file contains [attestation] or ## ATTESTATION, validate it has - # required sub-fields: proof or signature - local in_attestation=false - local attestation_line=0 - local attestation_has_content=false - line_num=0 - - while IFS= read -r line; do - line_num=$((line_num + 1)) - - # Detect attestation section start - if [[ "$line" =~ ^\[attestation\] ]] || [[ "$line" =~ ^##[[:space:]]+[Aa]ttestation ]] || [[ "$line" =~ ^##[[:space:]]+ATTESTATION ]]; then - in_attestation=true - attestation_line=$line_num - continue - fi - - # Detect next section (ends attestation block) - if [[ "$in_attestation" == "true" ]]; then - if [[ "$line" =~ ^\[.+\] ]] || [[ "$line" =~ ^##[[:space:]] ]]; then - in_attestation=false - continue - fi - # Check for content in attestation block - if [[ "$line" =~ (proof|signature|verified|hash)[[:space:]]*= ]]; then - attestation_has_content=true - fi - fi - done < "$file" - - if [[ $attestation_line -gt 0 && "$attestation_has_content" == "false" && "$is_manifest" == "false" ]]; then - report_issue "warning" "$file" "$attestation_line" \ - "Attestation block found but missing proof/signature/hash fields" - fi - - # --- Check 4: Section heading syntax --- - # Validate that [section] headings are well-formed (no unclosed brackets) - line_num=0 - while IFS= read -r line; do - line_num=$((line_num + 1)) - # Lines starting with [ should have a matching ] - if [[ "$line" =~ ^\[ && ! "$line" =~ ^\[.+\] ]]; then - # Exclude markdown-style links and multi-line values - if [[ ! "$line" =~ ^\[.*\]\( && ! "$line" =~ ^\[TODO && ! "$line" =~ ^\[YOUR ]]; then - report_issue "warning" "$file" "$line_num" \ - "Possibly malformed section heading: unclosed bracket" - fi - fi - done < "$file" -} - -# --------------------------------------------------------------------------- -# Main: discover and validate .a2ml and .deed files -# --------------------------------------------------------------------------- - -echo "::group::A2ML Manifest Validation" -echo "Scanning ${SCAN_PATH} for .a2ml and .deed files..." -echo "" - -# Find all .a2ml and .deed files, excluding .git directory -mapfile -t a2ml_candidates < <(find "$SCAN_PATH" \( -name '*.a2ml' -o -name '*.deed' \) -not -path '*/.git/*' -type f | sort) - -# Apply paths-ignore filter -a2ml_files=() -SKIPPED=0 -for _f in "${a2ml_candidates[@]}"; do - if path_ignored "$_f"; then - SKIPPED=$((SKIPPED + 1)) - continue - fi - a2ml_files+=("$_f") -done - -if [[ $SKIPPED -gt 0 ]]; then - echo "::notice::Skipped ${SKIPPED} file(s) matching paths-ignore" -fi - -if [[ ${#a2ml_files[@]} -eq 0 ]]; then - echo "::notice::No .a2ml or .deed files found in ${SCAN_PATH}" - echo "files_scanned=0" >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - echo "errors=0" >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - echo "warnings=0" >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - echo "::endgroup::" - exit 0 -fi - -echo "Found ${#a2ml_files[@]} .a2ml/.deed file(s)" -echo "" - -for file in "${a2ml_files[@]}"; do - echo " Validating: ${file}" - validate_a2ml "$file" -done - -echo "" -echo "────────────────────────────────────────" -echo "Files scanned: ${FILES_SCANNED}" -echo "Errors: ${ERRORS}" -echo "Warnings: ${WARNINGS}" -echo "Strict mode: ${STRICT}" -echo "────────────────────────────────────────" - -# Write outputs for GitHub Actions -{ - echo "files_scanned=${FILES_SCANNED}" - echo "errors=${ERRORS}" - echo "warnings=${WARNINGS}" -} >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - -echo "::endgroup::" - -# Exit with failure if errors were found -if [[ $ERRORS -gt 0 ]]; then - echo "::error::A2ML validation failed with ${ERRORS} error(s)" - exit 1 -fi - -echo "A2ML validation passed." -exit 0 diff --git a/.github/hooks/validate-k9.sh b/.github/hooks/validate-k9.sh deleted file mode 100755 index c83e290..0000000 --- a/.github/hooks/validate-k9.sh +++ /dev/null @@ -1,357 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# validate-k9.sh — K9 configuration file validation script -# -# Scans for .k9 and .k9.ncl files and validates: -# 1. K9! magic number on line 1 -# 2. Pedigree block presence with required fields (name, version) -# 3. Security level is one of: kennel, yard, hunt (case-insensitive) -# 4. Hunt-level files must have a signature or signature_required field -# 5. SPDX-License-Identifier header presence -# -# Environment variables: -# INPUT_PATH — Directory to scan (default: .) -# INPUT_STRICT — Promote warnings to errors (default: false) -# -# Exit codes: -# 0 — All files valid (or only warnings in non-strict mode) -# 1 — Validation errors found - -set -euo pipefail - -# --------------------------------------------------------------------------- -# Configuration -# --------------------------------------------------------------------------- - -SCAN_PATH="${INPUT_PATH:-.}" -STRICT="${INPUT_STRICT:-false}" -PATHS_IGNORE_RAW="${INPUT_PATHS_IGNORE:-}" -GITHUB_OUTPUT_FILE="${GITHUB_OUTPUT:-/dev/null}" - -# Parse paths-ignore: newline-separated fragments, blank lines and # comments -# stripped. Each fragment is a substring match against the file path. Pattern -# adopted from hyperpolymath/hypatia#243 — content-pattern validators must -# distinguish a target from a vendored / fixture file that legitimately -# contains the very pattern being checked. -PATHS_IGNORE=() -while IFS= read -r _frag; do - # Strip leading and trailing whitespace (canonical bash idiom). - _frag="${_frag#"${_frag%%[![:space:]]*}"}" - _frag="${_frag%"${_frag##*[![:space:]]}"}" - [[ -z "$_frag" || "$_frag" == \#* ]] && continue - PATHS_IGNORE+=("$_frag") -done <<< "$PATHS_IGNORE_RAW" - -# Returns 0 if path should be skipped (matches any ignore fragment) -path_ignored() { - local p="$1" frag - for frag in "${PATHS_IGNORE[@]}"; do - [[ "$p" == *"$frag"* ]] && return 0 - done - return 1 -} - -# Counters -FILES_SCANNED=0 -ERRORS=0 -WARNINGS=0 - -# Valid security levels (the leash metaphor) -VALID_LEVELS="kennel yard hunt" - -# --------------------------------------------------------------------------- -# Helper: emit GitHub annotation -# --------------------------------------------------------------------------- -annotate() { - local level="$1" file="$2" line="$3" message="$4" - echo "::${level} file=${file},line=${line}::${message}" -} - -# --------------------------------------------------------------------------- -# Helper: report issue (respects strict mode) -# --------------------------------------------------------------------------- -report_issue() { - local severity="$1" file="$2" line="$3" message="$4" - - if [[ "$severity" == "warning" && "$STRICT" == "true" ]]; then - severity="error" - fi - - annotate "$severity" "$file" "$line" "$message" - - if [[ "$severity" == "error" ]]; then - ERRORS=$((ERRORS + 1)) - else - WARNINGS=$((WARNINGS + 1)) - fi -} - -# --------------------------------------------------------------------------- -# Helper: normalise a security level string -# --------------------------------------------------------------------------- -# Strips quotes, leading/trailing whitespace, Nickel enum tick prefix -normalise_level() { - local raw="$1" - # Remove surrounding quotes, tick prefix ('Kennel -> Kennel), whitespace - raw="${raw#*=}" # Remove everything before = - raw="${raw//\"/}" # Remove double quotes - raw="${raw//\'/}" # Remove single quotes (Nickel tick) - raw="${raw//,/}" # Remove trailing commas - raw="${raw## }" # Trim leading space - raw="${raw%% }" # Trim trailing space - raw="${raw%%#*}" # Remove inline comments - raw="${raw## }" # Trim again - raw="${raw%% }" - echo "${raw,,}" # Lowercase -} - -# --------------------------------------------------------------------------- -# Validator: check a single K9 file -# --------------------------------------------------------------------------- -validate_k9() { - local file="$1" - FILES_SCANNED=$((FILES_SCANNED + 1)) - - # --- Check 1: K9! magic number on first non-empty line --- - local first_content_line="" - local first_content_line_num=0 - local line_num=0 - - while IFS= read -r line; do - line_num=$((line_num + 1)) - # Skip empty lines - if [[ -z "${line// /}" ]]; then - continue - fi - first_content_line="$line" - first_content_line_num=$line_num - break - done < "$file" - - if [[ "$first_content_line" != "K9!" ]]; then - report_issue "error" "$file" "$first_content_line_num" \ - "Missing K9! magic number. First non-empty line must be exactly 'K9!'" - fi - - # --- Check 2: SPDX header --- - local has_spdx=false - line_num=0 - while IFS= read -r line; do - line_num=$((line_num + 1)) - if [[ $line_num -gt 10 ]]; then - break - fi - if [[ "$line" == *"SPDX-License-Identifier"* ]]; then - has_spdx=true - break - fi - done < "$file" - - if [[ "$has_spdx" == "false" ]]; then - report_issue "warning" "$file" 1 \ - "Missing SPDX-License-Identifier in first 10 lines" - fi - - # --- Check 3: Pedigree block with required fields --- - local has_pedigree=false - local has_pedigree_name=false - local has_pedigree_version=false - local has_security_level=false - local security_level_value="" - local security_level_line=0 - local has_signature_field=false - local in_pedigree=false - local pedigree_depth=0 - - line_num=0 - while IFS= read -r line; do - line_num=$((line_num + 1)) - - # Detect pedigree block start. Note: do NOT `continue` here — the - # `pedigree = {` line itself contains the opening brace that - # establishes the block. Falling through to the brace counter - # below makes depth start at 1, so a subsequent `security = {…},` - # closing brace correctly takes depth to 1 (not 0), keeping us - # inside the pedigree block when later fields (name/version/leash) - # are checked. Previously the `continue` skipped this opening - # brace, depth started at 0, and the first nested block's close - # prematurely terminated the validator's view of the pedigree — - # making `pedigree.metadata.name` invisible. - if [[ "$line" =~ ^[[:space:]]*pedigree[[:space:]]*= ]]; then - has_pedigree=true - in_pedigree=true - pedigree_depth=0 - # fall through - fi - - if [[ "$in_pedigree" == "true" ]]; then - # Track brace depth to know when pedigree block ends - local opens closes - opens="${line//[^\{]/}" - closes="${line//[^\}]/}" - pedigree_depth=$(( pedigree_depth + ${#opens} - ${#closes} )) - - if [[ $pedigree_depth -le 0 && "$has_pedigree" == "true" ]]; then - # Check this final line too before leaving - : - fi - - # Check for name field within pedigree.metadata or pedigree directly. - # Two patterns cover both multi-line and single-line pedigrees: - # 1. ^[[:space:]]+name[[:space:]]*= — the normal multi-line case where - # `name = "..."` appears on its own indented line. - # 2. [[:space:]]name[[:space:]]*= — inline within a single-line - # pedigree assignment such as: - # pedigree = component_pedigree & { name = "foo" } - # (root cause: developer-ecosystem@baab1534 — single-line form - # was missed entirely because the pedigree block opened and - # closed in one line, never reaching the ^[[:space:]]+ check on - # a subsequent iteration.) - if [[ "$line" =~ ^[[:space:]]+name[[:space:]]*= ]] || \ - [[ "$line" =~ [[:space:]]name[[:space:]]*= ]]; then - has_pedigree_name=true - fi - - # Check for version field - if [[ "$line" =~ ^[[:space:]]+(version|schema_version)[[:space:]]*= ]] || \ - [[ "$line" =~ [[:space:]](version|schema_version)[[:space:]]*= ]]; then - has_pedigree_version=true - fi - - # Check for security level (leash field) - if [[ "$line" =~ ^[[:space:]]+(leash|security_level)[[:space:]]*= ]]; then - has_security_level=true - security_level_value="$(normalise_level "$line")" - security_level_line=$line_num - fi - - # Check for signature fields - if [[ "$line" =~ ^[[:space:]]+(signature|signature_required)[[:space:]]*= ]]; then - has_signature_field=true - fi - - # End of pedigree block - if [[ $pedigree_depth -le 0 && "$has_pedigree" == "true" && "$line" == *"}"* ]]; then - in_pedigree=false - fi - fi - - # Also check for signature fields outside pedigree (top-level) - if [[ "$line" =~ ^[[:space:]]*(signature)[[:space:]]*= ]]; then - has_signature_field=true - fi - done < "$file" - - if [[ "$has_pedigree" == "false" ]]; then - report_issue "error" "$file" 1 \ - "Missing pedigree block. K9 files must contain a 'pedigree = { ... }' section" - else - if [[ "$has_pedigree_name" == "false" ]]; then - report_issue "error" "$file" 1 \ - "Pedigree block missing 'name' field (in pedigree.metadata.name or pedigree.name)" - fi - - if [[ "$has_pedigree_version" == "false" ]]; then - report_issue "warning" "$file" 1 \ - "Pedigree block missing 'version' or 'schema_version' field" - fi - fi - - # --- Check 4: Security level validation --- - if [[ "$has_security_level" == "true" ]]; then - local level_valid=false - for valid in $VALID_LEVELS; do - if [[ "$security_level_value" == "$valid" ]]; then - level_valid=true - break - fi - done - - if [[ "$level_valid" == "false" ]]; then - report_issue "error" "$file" "$security_level_line" \ - "Invalid security level '${security_level_value}'. Must be one of: kennel, yard, hunt" - fi - else - if [[ "$has_pedigree" == "true" ]]; then - report_issue "warning" "$file" 1 \ - "No security level (leash/security_level) found in pedigree block" - fi - fi - - # --- Check 5: Hunt-level signature requirement --- - if [[ "$security_level_value" == "hunt" && "$has_signature_field" == "false" ]]; then - report_issue "error" "$file" "$security_level_line" \ - "Hunt-level K9 file must include a 'signature' or 'signature_required' field" - fi -} - -# --------------------------------------------------------------------------- -# Main: discover and validate K9 files -# --------------------------------------------------------------------------- - -echo "::group::K9 Configuration Validation" -echo "Scanning ${SCAN_PATH} for K9 files (.k9, .k9.ncl)..." -echo "" - -# Find all K9 files, excluding .git directory -mapfile -t k9_candidates < <(find "$SCAN_PATH" \( -name '*.k9' -o -name '*.k9.ncl' \) -not -path '*/.git/*' -type f | sort) - -# Apply paths-ignore filter -k9_files=() -SKIPPED=0 -for _f in "${k9_candidates[@]}"; do - if path_ignored "$_f"; then - SKIPPED=$((SKIPPED + 1)) - continue - fi - k9_files+=("$_f") -done - -if [[ $SKIPPED -gt 0 ]]; then - echo "::notice::Skipped ${SKIPPED} file(s) matching paths-ignore" -fi - -if [[ ${#k9_files[@]} -eq 0 ]]; then - echo "::notice::No K9 files found in ${SCAN_PATH}" - echo "files_scanned=0" >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - echo "errors=0" >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - echo "warnings=0" >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - echo "::endgroup::" - exit 0 -fi - -echo "Found ${#k9_files[@]} K9 file(s)" -echo "" - -for file in "${k9_files[@]}"; do - echo " Validating: ${file}" - validate_k9 "$file" -done - -echo "" -echo "────────────────────────────────────────" -echo "Files scanned: ${FILES_SCANNED}" -echo "Errors: ${ERRORS}" -echo "Warnings: ${WARNINGS}" -echo "Strict mode: ${STRICT}" -echo "────────────────────────────────────────" - -# Write outputs for GitHub Actions -{ - echo "files_scanned=${FILES_SCANNED}" - echo "errors=${ERRORS}" - echo "warnings=${WARNINGS}" -} >> "$GITHUB_OUTPUT_FILE" 2>/dev/null || true - -echo "::endgroup::" - -# Exit with failure if errors were found -if [[ $ERRORS -gt 0 ]]; then - echo "::error::K9 validation failed with ${ERRORS} error(s)" - exit 1 -fi - -echo "K9 validation passed." -exit 0 diff --git a/.github/label-classifier.json b/.github/label-classifier.json deleted file mode 100644 index d349eaa..0000000 --- a/.github/label-classifier.json +++ /dev/null @@ -1,739 +0,0 @@ -{ - "_generated_from": ".github/label-classifier.yml + .github/labels.yml in hyperpolymath/.git-private-farm", - "_do_not_edit": "regenerate with scripts/gen-classifier-json.py", - "version": 1, - "prefix_split_on": "/", - "title_prefix": { - "docs": { - "type": "documentation" - }, - "ci": { - "type": "chore", - "areas": [ - "cicd" - ] - }, - "governance": { - "type": "chore", - "areas": [ - "governance" - ] - }, - "roadmap": { - "type": "enhancement", - "meta": "meta:roadmap" - }, - "chore": { - "type": "chore" - }, - "build": { - "type": "chore", - "areas": [ - "cicd" - ] - }, - "security": { - "type": "chore", - "areas": [ - "security" - ] - }, - "proof": { - "type": "chore", - "areas": [ - "proofs" - ] - }, - "proofs": { - "type": "chore", - "areas": [ - "proofs" - ] - }, - "proof-debt": { - "type": "tech-debt", - "areas": [ - "proofs" - ] - }, - "epic": { - "type": "enhancement", - "meta": "meta:umbrella" - }, - "umbrella": { - "type": "enhancement", - "meta": "meta:umbrella" - }, - "tracking": { - "type": "chore", - "meta": "meta:umbrella" - }, - "campaign": { - "type": "enhancement", - "meta": "meta:campaign" - }, - "hygiene": { - "type": "tech-debt" - }, - "audit": { - "type": "research" - }, - "estate": { - "type": "chore", - "scope": "scope:estate" - }, - "automation": { - "type": "enhancement", - "areas": [ - "automation" - ] - }, - "research": { - "type": "research" - }, - "refactor": { - "type": "refactor" - }, - "test": { - "type": "testing" - }, - "tests": { - "type": "testing" - }, - "feat": { - "type": "enhancement" - }, - "fix": { - "type": "bug" - }, - "bug": { - "type": "bug" - }, - "perf": { - "type": "enhancement", - "areas": [ - "performance" - ] - }, - "codegen": { - "type": "enhancement", - "areas": [ - "architecture" - ] - }, - "packaging": { - "type": "chore", - "areas": [ - "packaging" - ] - }, - "policy": { - "type": "chore", - "areas": [ - "governance" - ] - }, - "ops": { - "type": "chore", - "areas": [ - "automation" - ] - }, - "standard": { - "type": "chore", - "areas": [ - "governance" - ] - }, - "migration": { - "type": "refactor", - "areas": [ - "migration" - ] - }, - "drift": { - "type": "tech-debt" - }, - "corrective": { - "type": "bug" - }, - "adaptive": { - "type": "enhancement" - }, - "perfective": { - "type": "enhancement" - }, - "preventive": { - "type": "tech-debt" - }, - "machine-readable": { - "type": "tech-debt" - }, - "parser": { - "type": "bug" - }, - "lang": { - "type": "bug" - }, - "clippy": { - "type": "tech-debt" - }, - "release": { - "type": "chore" - }, - "upstream": { - "type": "chore" - }, - "hardening": { - "type": "chore", - "areas": [ - "security" - ] - }, - "deps": { - "type": "chore" - }, - "rustsec": { - "type": "chore", - "areas": [ - "security" - ] - }, - "track": { - "type": "chore", - "meta": "meta:umbrella" - }, - "tracker": { - "type": "chore", - "meta": "meta:umbrella" - }, - "wiki": { - "type": "documentation" - }, - "reclassify": { - "type": "refactor" - }, - "backlog": { - "type": "chore" - }, - "core": { - "type": "enhancement", - "areas": [ - "design" - ] - }, - "evidence": { - "type": "enhancement", - "areas": [ - "design" - ] - }, - "manifest": { - "type": "enhancement", - "areas": [ - "design" - ] - }, - "backends": { - "type": "enhancement", - "areas": [ - "design" - ] - } - }, - "bracket_tag": { - "campaign": { - "meta": "meta:campaign" - }, - "umbrella": { - "meta": "meta:umbrella" - }, - "gov": { - "areas": [ - "governance" - ] - }, - "proofs/a": { - "areas": [ - "proofs" - ] - }, - "proofs/b": { - "areas": [ - "proofs" - ] - }, - "proofs/c": { - "areas": [ - "proofs" - ] - }, - "estate": { - "scope": "scope:estate" - }, - "repo": { - "scope": "scope:repo" - }, - "feature": { - "type": "enhancement" - }, - "integration": { - "areas": [ - "conformance" - ] - }, - "reference": { - "type": "documentation" - }, - "register": { - "type": "documentation" - }, - "p0": { - "priority": "priority:p0" - }, - "p1": { - "priority": "priority:p1" - }, - "p2": { - "priority": "priority:p2" - }, - "et-l2": { - "areas": [ - "conformance" - ] - }, - "et-l4": { - "areas": [ - "conformance" - ] - } - }, - "keyword_area": { - "proofs": [ - "agda", - "coq", - "rocq", - "idris", - "lean", - "isabelle", - "hol", - "mizar", - "why3", - "tla", - "alloy", - "dafny", - "acl2", - "pvs", - "metamath", - "z3", - "smt", - "prover", - "provers", - "theorem", - "theorems", - "axiom", - "axioms", - "postulate", - "postulates", - "believe_me", - "sorry", - "proof obligation", - "proof obligations", - "proof hole", - "proof holes", - "proof suite", - "proof-pipeline", - "proof debt", - "proof-debt", - "metatheory", - "mechanize", - "qed" - ], - "cicd": [ - "workflow", - "github action", - "actions.lock", - "lockfile", - "runner", - "startup_failure", - "dependabot", - "check run", - "required context", - "scorecard", - "codeql", - "ci/cd" - ], - "licensing": [ - "spdx", - "licence", - "license", - "reuse", - "copyright", - "attribution", - "agpl", - "mpl" - ], - "security": [ - "gitleaks", - "secret", - "vulnerabilit", - "advisory", - "supply chain", - "cve" - ], - "bindings": [ - "abi", - "ffi", - "wasm", - "jni", - "c api", - "interop", - "extern \"c\"", - "nif", - "snif" - ], - "packaging": [ - "guix", - "nix", - "container", - "containerfile", - "docker", - "flatpak", - "oci image" - ], - "scaffolding": [ - "rsr", - "scaffold", - "template", - "repo-init", - "instantiat", - "placeholder" - ], - "governance": [ - "ruleset", - "policy", - "compliance", - "governance", - "branch protection", - "codeowners", - "code of conduct" - ], - "migration": [ - "rescript", - "to-affinescript", - "\u2192 affinescript", - "port", - "deno", - "bun" - ], - "automation": [ - "bot", - "gitbot", - "hypatia", - "sustainabot", - "oikosbot", - "fan-out", - "fanout", - "dispatch", - "self-heal" - ], - "performance": [ - "latency", - "throughput", - "binary size", - "memory", - "hot path", - "regression" - ] - }, - "keyword_type": { - "tech-debt": [ - "debt", - "drift", - "hygiene", - "stale", - "cleanup", - "follow-up", - "clean up", - "left over", - "leftover", - "anti-pattern", - "inconsistency", - "inconsistent", - "placeholder", - "placeholders", - "tbd", - "todo", - "todos", - "unfilled" - ], - "documentation": [ - "document", - "docs", - "readme", - "adoc", - "prose", - "docs/", - "changelog", - "explainme", - "quickstart", - "wiki", - "docstring", - "doc tree" - ], - "testing": [ - "test", - "tests", - "fuzz", - "bench", - "coverage", - "crash-consistency", - "linearizability", - "equivalence", - "property-correspondence", - "property-based", - "test suite", - "proptest" - ], - "bug": [ - "broken", - "fails", - "failing", - "crash", - "oom", - "regression", - "incorrect", - "does not", - "panic", - "panics", - "unreachable", - "mangled", - "never run", - "never ran", - "never succeeded", - "never fires", - "cannot fail", - "deadlock", - "hangs" - ], - "refactor": [ - "refactor", - "restructure", - "consolidate", - "consolidation", - "reconcile", - "reconciliation", - "unify", - "dedupe", - "re-point", - "repoint", - "extract", - "retire", - "retire duplicate", - "deduplicate", - "reclassify", - "migrate" - ], - "research": [ - "investigat", - "explore", - "spike", - "work out", - "triage", - "assess", - "survey", - "gap analysis", - "self-audit", - "inventory", - "weakness list", - "theory", - "synthesis", - "prioritised weakness", - "feasibility" - ], - "decision": [ - "ruling", - "decide", - "decision", - "adjudicat", - "which of" - ], - "enhancement": [ - "add", - "implement", - "support", - "introduce", - "enable", - "expand", - "expansion", - "extend", - "wire", - "complete", - "build", - "create", - "port" - ] - }, - "meta_signal": { - "meta:umbrella": [ - "umbrella", - "epic", - "master issue", - "parent issue", - "sub-issues", - "child issues" - ], - "meta:campaign": [ - "campaign" - ], - "meta:roadmap": [ - "roadmap", - "capability-expansion", - "future work" - ], - "meta:recurring": [ - "recurring", - "recurrence", - "standing", - "every run", - "each week" - ] - }, - "status_signal": { - "status:blocked": [ - "blocked on", - "blocked:", - "(blocked", - "is blocked", - "gated on", - "waiting on upstream", - "needs upstream" - ], - "status:needs-owner": [ - "unassigned", - "needs an owner", - "no owner" - ], - "status:needs-ruling": [ - "needs a ruling", - "awaiting ruling", - "owner decision needed" - ] - }, - "scope_signal": { - "scope:estate": [ - "estate-wide", - "estate wide", - "across the estate", - "all repos", - "fleet-wide" - ] - }, - "tier_of": { - "bug": "type", - "enhancement": "type", - "documentation": "type", - "refactor": "type", - "tech-debt": "type", - "testing": "type", - "chore": "type", - "research": "type", - "decision": "type", - "question": "type", - "cicd": "area", - "security": "area", - "proofs": "area", - "governance": "area", - "design": "area", - "architecture": "area", - "performance": "area", - "bindings": "area", - "migration": "area", - "packaging": "area", - "licensing": "area", - "automation": "area", - "scaffolding": "area", - "conformance": "area", - "priority:p0": "priority", - "priority:p1": "priority", - "priority:p2": "priority", - "priority:p3": "priority", - "status:blocked": "status", - "status:ready": "status", - "status:needs-owner": "status", - "status:needs-ruling": "status", - "status:do-not-automate": "status", - "meta:umbrella": "meta", - "meta:campaign": "meta", - "meta:roadmap": "meta", - "meta:recurring": "meta", - "scope:estate": "scope", - "scope:repo": "scope" - }, - "tier_max": { - "type": 1, - "area": null, - "priority": 1, - "status": 1, - "meta": 1, - "scope": 1 - }, - "types": [ - "bug", - "enhancement", - "documentation", - "refactor", - "tech-debt", - "testing", - "chore", - "research", - "decision", - "question" - ], - "frozen": [ - "dependencies", - "duplicate", - "elixir", - "gitar-approved", - "github_actions", - "good first issue", - "help wanted", - "invalid", - "javascript", - "never-stale", - "nix", - "pinned", - "python", - "rust", - "security", - "stale", - "wontfix" - ], - "precedence": { - "meta:campaign": 0, - "meta:umbrella": 1, - "meta:recurring": 2, - "meta:roadmap": 3, - "priority:p0": 0, - "priority:p1": 1, - "priority:p2": 2, - "priority:p3": 3, - "status:blocked": 0, - "status:needs-ruling": 1, - "status:needs-owner": 2, - "status:do-not-automate": 3, - "status:ready": 4, - "scope:estate": 0, - "scope:repo": 1, - "bug": 0, - "decision": 1, - "tech-debt": 2, - "testing": 3, - "documentation": 4, - "refactor": 5, - "research": 6, - "enhancement": 7, - "chore": 8, - "question": 9 - } -} diff --git a/.github/labels.json b/.github/labels.json deleted file mode 100644 index 78786d4..0000000 --- a/.github/labels.json +++ /dev/null @@ -1,260 +0,0 @@ -{ - "_generated_from": ".github/labels.yml in hyperpolymath/.git-private-farm", - "_do_not_edit": "regenerate with scripts/gen-labels-json.py", - "version": 1, - "labels": [ - { - "name": "bug", - "color": "d73a4a", - "description": "Something is broken or behaves incorrectly", - "tier": "type" - }, - { - "name": "enhancement", - "color": "a2eeef", - "description": "New capability or improvement to existing behaviour", - "tier": "type" - }, - { - "name": "documentation", - "color": "0075ca", - "description": "Docs, prose, diagrams, READMEs, ADRs", - "tier": "type" - }, - { - "name": "refactor", - "color": "c5def5", - "description": "Restructuring that preserves observable behaviour", - "tier": "type" - }, - { - "name": "tech-debt", - "color": "fbca04", - "description": "Known shortcut, drift, or hygiene owed - includes cleanup", - "tier": "type" - }, - { - "name": "testing", - "color": "bfd4f2", - "description": "Tests, benchmarks, fuzzing, property checks, coverage", - "tier": "type" - }, - { - "name": "chore", - "color": "ededed", - "description": "Routine maintenance with no behaviour change", - "tier": "type" - }, - { - "name": "research", - "color": "d4c5f9", - "description": "Open investigation; the outcome is knowledge, not code", - "tier": "type" - }, - { - "name": "decision", - "color": "8b5cf6", - "description": "A ruling is required before work can proceed", - "tier": "type" - }, - { - "name": "question", - "color": "d876e3", - "description": "Further information is requested", - "tier": "type" - }, - { - "name": "cicd", - "color": "006b75", - "description": "CI/CD: workflows, actions, lockfiles, pins, runners, release gates", - "tier": "area" - }, - { - "name": "security", - "color": "006b75", - "description": "Security posture, secrets, scanning, advisories, supply chain", - "tier": "area" - }, - { - "name": "proofs", - "color": "006b75", - "description": "Formal verification: Agda, Coq, Idris, Lean, Z3/SMT, axiom debt", - "tier": "area" - }, - { - "name": "governance", - "color": "006b75", - "description": "Policy, rulesets, standards, compliance, and their enforcement", - "tier": "area" - }, - { - "name": "design", - "color": "006b75", - "description": "Design of an interface, protocol, grammar, or type theory", - "tier": "area" - }, - { - "name": "architecture", - "color": "006b75", - "description": "Structural/system-level shape and runtime behaviour", - "tier": "area" - }, - { - "name": "performance", - "color": "006b75", - "description": "Throughput, latency, memory, binary size", - "tier": "area" - }, - { - "name": "bindings", - "color": "006b75", - "description": "ABI, FFI, WASM, and cross-language interop surfaces", - "tier": "area" - }, - { - "name": "migration", - "color": "006b75", - "description": "Porting between languages or toolchains (e.g. -> AffineScript)", - "tier": "area" - }, - { - "name": "packaging", - "color": "006b75", - "description": "Guix, Nix, containers, distribution artefacts", - "tier": "area" - }, - { - "name": "licensing", - "color": "006b75", - "description": "Licences, SPDX headers, REUSE compliance, attribution", - "tier": "area" - }, - { - "name": "automation", - "color": "006b75", - "description": "Bots, schedulers, dispatch, self-healing, fan-out", - "tier": "area" - }, - { - "name": "scaffolding", - "color": "006b75", - "description": "RSR templates, repo init, instantiation, project skeletons", - "tier": "area" - }, - { - "name": "conformance", - "color": "006b75", - "description": "Conformance to an external or internal specification", - "tier": "area" - }, - { - "name": "priority:p0", - "color": "b60205", - "description": "Critical - drop other work", - "tier": "priority" - }, - { - "name": "priority:p1", - "color": "d93f0b", - "description": "High - schedule next", - "tier": "priority" - }, - { - "name": "priority:p2", - "color": "e99695", - "description": "Normal - queue it", - "tier": "priority" - }, - { - "name": "priority:p3", - "color": "f9d0c4", - "description": "Low - nice to have", - "tier": "priority" - }, - { - "name": "status:blocked", - "color": "fbca04", - "description": "Cannot proceed until a dependency clears", - "tier": "status" - }, - { - "name": "status:ready", - "color": "fbca04", - "description": "Fully specified and ready to be picked up", - "tier": "status" - }, - { - "name": "status:needs-owner", - "color": "fbca04", - "description": "Unassigned and needs someone to take it", - "tier": "status" - }, - { - "name": "status:needs-ruling", - "color": "fbca04", - "description": "Awaiting an owner decision", - "tier": "status" - }, - { - "name": "status:do-not-automate", - "color": "fbca04", - "description": "Bots and sweeps must not touch this issue", - "tier": "status" - }, - { - "name": "meta:umbrella", - "color": "5319e7", - "description": "Parent issue aggregating child issues", - "tier": "meta" - }, - { - "name": "meta:campaign", - "color": "5319e7", - "description": "Coordinated multi-repo push with a defined end state", - "tier": "meta" - }, - { - "name": "meta:roadmap", - "color": "5319e7", - "description": "Forward planning; not yet actionable work", - "tier": "meta" - }, - { - "name": "meta:recurring", - "color": "5319e7", - "description": "Recurs on a schedule or by trigger; never finally closed", - "tier": "meta" - }, - { - "name": "scope:estate", - "color": "bfdadc", - "description": "Affects many or all repos across the estate", - "tier": "scope" - }, - { - "name": "scope:repo", - "color": "bfdadc", - "description": "Confined to this repository", - "tier": "scope" - } - ], - "frozen": [ - "dependencies", - "duplicate", - "elixir", - "gitar-approved", - "github_actions", - "good first issue", - "help wanted", - "invalid", - "javascript", - "never-stale", - "nix", - "pinned", - "python", - "rust", - "security", - "stale", - "wontfix" - ] -} diff --git a/.github/scripts/classify-issue.jq b/.github/scripts/classify-issue.jq deleted file mode 100644 index 6467c74..0000000 --- a/.github/scripts/classify-issue.jq +++ /dev/null @@ -1,164 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# -# Classify one issue title against the estate label taxonomy. -# -# jq -r --arg title "docs: fix the README" \ -# --argjson have '[]' \ -# -f .github/scripts/classify-issue.jq .github/label-classifier.json -# -# Prints one label per line, or NOTHING when it cannot place the issue -# confidently. Nothing printed means "leave it for a human" -- a correct -# outcome, not a failure. -# -# WHY jq AND NOT PYTHON -# -# Python is fully banned estate-wide: the `governance / Language / package -# anti-pattern policy` gate runs `git ls-files '*.py'` and fails the PR -# ("Python is fully banned -- use AffineScript/Rust/SPARK/Julia"). This file -# is dispatched into every repo in the estate, so shipping it as .py would -# mean shipping an exemption into every repo too -- normalising the policy -# away by sweep. jq is preinstalled on every GitHub runner, is not on the -# banned list, needs no action (so no actions.lock entry can drift), and the -# rules are already JSON. -# -# The canonical implementation remains scripts/label-classify.py in the hub, -# which never runs in CI. tests/test-classifier-parity.py asserts this file -# agrees with it on every title in the corpus. -# -# `$have` lists labels the issue already carries. Anything already present is -# never re-suggested, and the classifier stays out of any max-1 tier the issue -# already has a label in, so a human's classification is never overridden. - -# Escape every non-alphanumeric so a keyword is matched literally. Escaping -# punctuation that needs no escape is harmless in Oniguruma. -def reesc: gsub("(?[^A-Za-z0-9 _])"; "\\\(.c)"); - -def norm: (. // "") | ascii_downcase - | sub("^[[:space:]]+"; "") | sub("[[:space:]]+$"; ""); - -# Asymmetric boundary: STRICT on the left, inflection-tolerant on the right. -# -# Measured over the issue corpus, the two error directions are not symmetric: -# * every false positive is a LEFT-side prefix -- `lean` in "clean up", -# `abi` in "capability", `mpl` in "Implement", `ffi` in "AffineScript", -# `smt` in "wasmtime". The left boundary must stay strict. -# * every real miss is a RIGHT-side inflection -- `test` vs "tests", -# `theorem` vs "theorems", `todo` vs "TODOs", `scaffold` vs "scaffolding". -# -# The right side therefore admits a CLOSED set of inflections. Closed, not open -# (`.*`), because an open right side re-admits the prefix false positives. -# -# `ion`/`ation` are excluded from the base set: they mint unrelated words -# (`port` + `ion` = "portion", and `port` is a live keyword). They are enabled -# only for shapes that are unambiguously truncated stems -- `-at` -# (instantiat, investigat, adjudicat) and `-ment` (document, implement). -def kwrx($kw): - ( "s|es|ed|d|ing|er|ers|y|ies" - + (if ($kw | endswith("at")) then "|ion|ions|e" - elif ($kw | endswith("ment")) then "|ation|ations" - else "" end) - ) as $suf - # Boundaries are conditional: a keyword not starting alphanumeric has no left - # boundary to enforce, and one not ending alphanumeric takes no suffix. - | (if ($kw | test("^[A-Za-z0-9]")) then "(?[^\\]]{1,25})\\]")) // null) as $m - | if $m == null then {rule: null, rest: $t} - else (($m.tag | norm | split("#")[0]) | norm) as $tag - | { rule: ($R.bracket_tag[$tag] // null), - rest: ($t | sub("^[[:space:]]*\\[[^\\]]{1,25}\\]"; "")) } - end; - -# Leading `word:` / `word(scope):` conventional-commit prefix. -def prefixrule($R; $t): - (($t | capture("^[[:space:]]*(?[A-Za-z][A-Za-z0-9_./-]{1,24})(?:[[:space:]]*\\([^)]*\\))?[[:space:]]*:")) // null) as $m - | if $m == null then null - else ($m.w | norm) as $k - # Compound prefixes such as "adaptive/must:" carry their meaning in the - # ISO 14764 category only; the modality does not label. - | (if ($R.prefix_split_on // "") != "" and ($k | contains($R.prefix_split_on)) - then ($k | split($R.prefix_split_on) | .[0]) else $k end) as $key - | ($R.title_prefix[$key] // null) - end; - -def signals($R; $tl; $sec): - [ ($R[$sec] // {}) | to_entries[] - | select(.value | any(. as $k | kwhit($k; $tl))) - | .key ]; - -# The HIGHEST-PRECEDENCE matching type, not merely the first in key order. -def kwtype($R; $tl): - [ $R.keyword_type | to_entries[] - | select(.value | any(. as $k | kwhit($k; $tl))) - | .key ] - | if length == 0 then null - else min_by([($R.precedence[.] // 99), .]) end; - -# Drop violations of each tier's `max`, keeping the highest-precedence member. -def enforce($R; $labels): - ($labels | unique) - | group_by($R.tier_of[.] // "?") - | map( ($R.tier_of[.[0]] // "?") as $tier - | ($R.tier_max[$tier] // null) as $mx - | if $mx == null or (length <= $mx) then . - else (sort_by([($R.precedence[.] // 99), .]))[0:$mx] end ) - | flatten; - -def classify($R; $title; $have0): - ($title // "") as $t0 - | ($t0 | norm) as $tl - | ($have0 | map(select(. != null and . != "")) - | unique) as $have - | ($R.tier_of | keys) as $canon - | $R.types as $types - | bracket($R; $t0) as $b - | (if $b.rule != null then ($b.rule | rulelabels) else [] end) as $l1 - | prefixrule($R; $b.rest) as $pr - | (if $pr != null then ($pr | rulelabels) else [] end) as $l2 - | (($b.rule != null) or ($pr != null)) as $matched0 - # 3. keyword areas are additive and never contribute a type - | ($l1 + $l2 + signals($R; $tl; "keyword_area")) as $acc - # 4. a type only if neither the rules nor the issue already supplied one - | (if (($acc + $have) | any(. as $x | $types | index($x))) - then null else kwtype($R; $tl) end) as $ty - | ($acc + (if $ty != null then [$ty] else [] end)) as $acc - | ($matched0 or ($ty != null)) as $matched - | ( $acc - + signals($R; $tl; "status_signal") - + signals($R; $tl; "meta_signal") - + signals($R; $tl; "scope_signal") ) as $acc - # NOTE: `frozen` is deliberately NOT subtracted. Frozen means "never rename or - # delete this label" -- `security` is frozen because triage.yml pins it in - # exempt-issue-labels. APPLYING it to an issue is correct; only the - # definition is protected. - | ($acc | map(select(. as $x | $canon | index($x))) | unique) as $acc - | enforce($R; $acc + ($have | map(select(. as $x | $canon | index($x))))) as $acc - | ($acc - $have) as $out - # Stay out of any max-1 tier the issue ALREADY has a label in -- a human's, - # or one an ISSUE_TEMPLATE applied. A prefix rule fires unconditionally, so - # "fix: ..." on an issue already labelled `enhancement` would otherwise add - # `bug` beside it. This covers every max-1 tier (type, priority, status, - # meta, scope), not just type. - | ( [ $R.tier_max | to_entries[] | select(.value == 1) | .key ] - | map(. as $t | select($have | any(($R.tier_of[.] // "?") == $t))) - ) as $lockedtiers - | ($out | map(select(($R.tier_of[.] // "?") as $t | ($lockedtiers | index($t)) | not))) as $out - # A rule must actually have FIRED: keyword-area hits alone are not enough. - | if ($matched | not) then [] - # a type is mandatory - elif ((($out + $have) | any(. as $x | $types | index($x))) | not) then [] - else ($out | sort) end; - -classify(.; $title; $have) | .[] diff --git a/.github/workflows/actions.lock b/.github/workflows/actions.lock index 551b54b..523511c 100644 --- a/.github/workflows/actions.lock +++ b/.github/workflows/actions.lock @@ -3,133 +3,7 @@ # Docs: https://gh.io/actions-lockfile version: 'v0.0.2' workflows: - '.github/workflows/boj-build.yml': - - 'actions/checkout@v7.0.1' - '.github/workflows/casket-pages.yml': - - 'actions/cache@v6.1.0' - - 'actions/checkout@v7.0.1' - - 'actions/configure-pages@v6.0.0' - - 'actions/deploy-pages@v5.0.1' - - 'actions/upload-pages-artifact@v5.0.0' - - 'haskell-actions/setup@v2.12.0' - '.github/workflows/changelog.yml': [] - '.github/workflows/codeql.yml': - - 'actions/checkout@v7.0.1' - - 'github/codeql-action@b96794f015dfd88f77b49b1c93e0fa7110f94c63' - '.github/workflows/dogfood-gate.yml': + '.github/workflows/ci.yml': - 'actions/checkout@v7.0.1' '.github/workflows/governance.yml': [] '.github/workflows/hypatia-scan.yml': [] - '.github/workflows/instant-sync.yml': - - 'peter-evans/repository-dispatch@v4.0.1' - '.github/workflows/label-triage.yml': [] - '.github/workflows/labels.yml': [] - '.github/workflows/mirror.yml': [] - '.github/workflows/pages.yml': - - 'actions/checkout@v7.0.1' - - 'actions/deploy-pages@v5.0.1' - - 'actions/upload-pages-artifact@v5.0.0' - '.github/workflows/push-email-notify.yml': - - 'hyperpolymath/smtp-notify-action@v0.3.0' - '.github/workflows/rust-ci.yml': - - 'actions/checkout@v7.0.1' - '.github/workflows/scorecard.yml': [] - '.github/workflows/secret-scanner.yml': [] -dependencies: - 'actions/cache@v6.1.0': - ref: 'v6.1.0' - commit: 'sha1-55cc8345863c7cc4c66a329aec7e433d2d1c52a9' - owner_id: 44036562 - repo_id: 215566462 - 'actions/checkout@v7.0.1': - ref: 'v7.0.1' - commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1' - owner_id: 44036562 - repo_id: 197814629 - 'actions/configure-pages@v6.0.0': - ref: 'v6.0.0' - commit: 'sha1-45bfe0192ca1faeb007ade9deae92b16b8254a0d' - owner_id: 44036562 - repo_id: 513659658 - 'actions/deploy-pages@v5.0.1': - ref: 'v5.0.1' - commit: 'sha1-368f82528645a54fb793d4d04e342629a3f51346' - owner_id: 44036562 - repo_id: 438112499 - 'actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f': - ref: 'v7.0.0' - commit: 'sha1-bbbca2ddaa5d8feaa63e36b76fdaad77386f024f' - owner_id: 44036562 - repo_id: 192625955 - 'actions/upload-pages-artifact@v5.0.0': - ref: 'v5.0.0' - commit: 'sha1-fc324d3547104276b827a68afc52ff2a11cc49c9' - owner_id: 44036562 - repo_id: 496012378 - uses: - - 'actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f' - 'github/codeql-action@b96794f015dfd88f77b49b1c93e0fa7110f94c63': - ref: 'b96794f015dfd88f77b49b1c93e0fa7110f94c63' - commit: 'sha1-b96794f015dfd88f77b49b1c93e0fa7110f94c63' - owner_id: 9919 - repo_id: 259445878 - 'haskell-actions/setup@v2.12.0': - ref: 'v2.12.0' - commit: 'sha1-6037f33647c3f17758a2356c80fc4a53d7e0685d' - owner_id: 75048950 - repo_id: 623796603 - 'hyperpolymath/smtp-notify-action@v0.3.0': - ref: 'v0.3.0' - commit: 'sha1-22e7bdb322c430c1d0dac6b3bb307f4bb139d0be' - owner_id: 6759885 - repo_id: 1352485172 - 'peter-evans/repository-dispatch@v4.0.1': - ref: 'v4.0.1' - commit: 'sha1-28959ce8df70de7be546dd1250a005dd32156697' - owner_id: 18365890 - repo_id: 220359305 - 'actions/cache@55cc8345863c7cc4c66a329aec7e433d2d1c52a9': - ref: 'v6.1.0' - commit: 'sha1-55cc8345863c7cc4c66a329aec7e433d2d1c52a9' - owner_id: 44036562 - repo_id: 215566462 - 'actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1': - ref: 'v7.0.1' - commit: 'sha1-3d3c42e5aac5ba805825da76410c181273ba90b1' - owner_id: 44036562 - repo_id: 197814629 - 'actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a': - ref: 'v7.0.1' - commit: 'sha1-043fb46d1a93c77aae656e7c1c64a875d1fc6a0a' - owner_id: 44036562 - repo_id: 192625955 - 'denoland/setup-deno@22d081ff2d3a40755e97629de92e3bcbfa7cf2ed': - ref: 'v2.0.5' - commit: 'sha1-22d081ff2d3a40755e97629de92e3bcbfa7cf2ed' - owner_id: 42048915 - repo_id: 356423100 - 'dtolnay/rust-toolchain@6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772': - ref: 'stable' - commit: 'sha1-6c977a6ca4077a0ceb28ffbe03f59d46e9ac8772' - owner_id: 1940490 - repo_id: 260749683 - 'editorconfig-checker/action-editorconfig-checker@840e866d93b8e032123c23bac69dece044d4d84c': - ref: 'v2.2.0' - commit: 'sha1-840e866d93b8e032123c23bac69dece044d4d84c' - owner_id: 26415196 - repo_id: 297874902 - 'erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124': - ref: 'v1.24.1' - commit: 'sha1-54075bcc5e249e4758d363f27d099f55d843f124' - owner_id: 47606891 - repo_id: 331103973 - 'ossf/scorecard-action@2d1146689b8cda280b9bc96326124645441f03bc': - ref: 'v2.4.4' - commit: 'sha1-2d1146689b8cda280b9bc96326124645441f03bc' - owner_id: 67707773 - repo_id: 421101922 - 'webfactory/ssh-agent@e83874834305fe9a4a2997156cb26c5de65a8555': - ref: 'v0.10.0' - commit: 'sha1-e83874834305fe9a4a2997156cb26c5de65a8555' - owner_id: 135788 - repo_id: 208510314 diff --git a/.github/workflows/boj-build.yml b/.github/workflows/boj-build.yml deleted file mode 100644 index 2b87b13..0000000 --- a/.github/workflows/boj-build.yml +++ /dev/null @@ -1,24 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -name: BoJ Server Build Trigger -on: - push: - branches: [main, master] - workflow_dispatch: -jobs: - trigger-boj: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - name: Trigger BoJ Server (Casket/ssg-mcp) - run: | - # Send a secure trigger to boj-server to build this repository - curl -X POST "http://boj-server.local:7700/cartridges/ssg-mcp/invoke" -H "Content-Type: application/json" -d "{\"repo\": \"${{ github.repository }}\", \"branch\": \"${{ github.ref_name }}\", \"engine\": \"casket\\"}"} - continue-on-error: true -permissions: - actions: read - contents: read diff --git a/.github/workflows/casket-pages.yml b/.github/workflows/casket-pages.yml deleted file mode 100644 index e32d095..0000000 --- a/.github/workflows/casket-pages.yml +++ /dev/null @@ -1,122 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -name: GitHub Pages - -on: - push: - branches: [main, master] - workflow_dispatch: - -permissions: - actions: read - contents: read - pages: write - id-token: write - -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Checkout casket-ssg - uses: actions/checkout@v7.0.1 - with: - repository: hyperpolymath/casket-ssg - path: .casket-ssg - - - name: Setup GHCup - uses: haskell-actions/setup@v2.12.0 - with: - ghc-version: '9.8.2' - cabal-version: '3.10' - - - name: Cache Cabal - uses: actions/cache@v6.1.0 - with: - path: | - ~/.cabal/packages - ~/.cabal/store - .casket-ssg/dist-newstyle - key: ${{ runner.os }}-casket-${{ hashFiles('.casket-ssg/casket-ssg.cabal') }} - - - name: Build casket-ssg - working-directory: .casket-ssg - run: cabal build - - - name: Prepare site source - shell: bash - run: | - set -euo pipefail - rm -rf .site-src _site - - if [ -d site ]; then - cp -R site .site-src - else - mkdir -p .site-src - TODAY="$(date +%Y-%m-%d)" - REPO_NAME="${{ github.event.repository.name }}" - REPO_URL="https://github.com/${{ github.repository }}" - README_URL="" - - if [ -f README.md ]; then - README_URL="${REPO_URL}/blob/${{ github.ref_name }}/README.md" - elif [ -f README.adoc ]; then - README_URL="${REPO_URL}/blob/${{ github.ref_name }}/README.adoc" - fi - - { - echo "---" - echo "title: ${REPO_NAME}" - echo "date: ${TODAY}" - echo "---" - echo - echo "# ${REPO_NAME}" - echo - echo "Static documentation site for ${REPO_NAME}." - echo - echo "- Source repository: [${{ github.repository }}](${REPO_URL})" - if [ -n "${README_URL}" ]; then - echo "- README: [project README](${README_URL})" - fi - if [ -d docs ]; then - echo "- Docs directory: [docs/](${REPO_URL}/tree/${{ github.ref_name }}/docs)" - fi - echo - echo "Project-specific site content can be added later under site/." - } > .site-src/index.md - fi - - - name: Build site - run: | - mkdir -p _site - cd .casket-ssg && cabal run casket-ssg -- build ../.site-src ../_site - touch ../_site/.nojekyll - - - name: Setup Pages - uses: actions/configure-pages@v6.0.0 - - - name: Upload artifact - uses: actions/upload-pages-artifact@v5.0.0 - with: - path: '_site' - - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v5.0.1 diff --git a/.github/workflows/changelog.yml b/.github/workflows/changelog.yml deleted file mode 100644 index 4556010..0000000 --- a/.github/workflows/changelog.yml +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# CHANGELOG automation (issue #100): regenerates CHANGELOG.md from -# conventional commits on every push to main and opens a PR with the result -# (pr-back). Two hard lessons baked in: (1) main is guarded by the -# Optimus-Branch ruleset (PR-required, signed commits, zero bypass actors — -# see the optimus-branch-ruleset landmine in STATE.a2ml), which rejects a -# commit-back direct push; (2) the reusable's `generate` job requests -# `contents: write` + `pull-requests: write`, and empirically GitHub checks -# those against the CALLER's TOP-LEVEL permissions only: every working -# caller in this repo (governance, secret-scanner) requests nothing above -# top-level read, while every changelog run with top-level `contents: read` -# died startup_failure with zero jobs and no log. So the write grants live -# HERE at top level — do NOT "tidy" them into a job-level block (a job -# block replaces top-level for that job and does not merge). Saga: #188 -# added top-level actions:read (still failed); #190 was comment-only (the -# job-block edit was lost to a tooling race); this PR grants write at top. -# Merge the changelog PRs it opens (squash keeps required_signatures -# satisfied — GitHub signs the squash commit). Uses the canonical cliff.toml -# from standards (no local cliff.toml by design — one config for the -# estate). CHANGELOG.adoc is retained as a frozen pointer. -name: changelog -on: - push: - branches: [main] -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true -permissions: - actions: read - contents: write - pull-requests: write -jobs: - changelog: - # Pinned to standards@main as of 2026-09-21 (commits/changelog: #886). - # NOTE: the reusable checks out cliff.toml from standards@main at - # runtime (not from the pinned SHA), so cliff.toml fixes propagate to - # this caller immediately without a SHA bump — only changes to the - # reusable workflow YAML itself require re-pinning here. - uses: hyperpolymath/standards/.github/workflows/changelog-reusable.yml@b77c53c85e5734756a793497845735485c9dc933 - with: - mode: pr-back - # Loop-prevention defense-in-depth (maa-framework#219 / standards#988): - # don't even invoke the reusable if the push's head commit already - # carries [skip changelog]. The reusable itself has an internal guard - # job and cliff.toml has a subject-matcher skip rule; this is a third - # layer that saves spinning up a runner at all. - if: ${{ !contains(github.event.head_commit.message, '[skip changelog]') }} diff --git a/aletheia/templates/rust/.github/workflows/ci.yml b/.github/workflows/ci.yml similarity index 100% rename from aletheia/templates/rust/.github/workflows/ci.yml rename to .github/workflows/ci.yml diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 91f3364..0000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,59 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -name: CodeQL Security Analysis - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - schedule: - - cron: '0 6 1 * *' # monthly 1st 06:00 UTC - -# 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: - actions: read - contents: read - -jobs: - analyze: - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - contents: read - security-events: write - strategy: - fail-fast: false - matrix: - include: - # maa-framework has no JavaScript/TypeScript source — the - # javascript-typescript extractor errors with "no source code seen" - # (exit 32, configuration error). CodeQL's GitHub Actions analysis - # scans the workflow YAML that does exist here, keeping this a - # meaningful security check (same fix as oblibeny's codeql.yml). - - language: actions - build-mode: none - - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Initialize CodeQL - uses: github/codeql-action/init@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.0 (4.38.1 blocked estate-wide; nexia-list#100) - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@1c5b675653bb5c22dbe9b12b556ec555138e09fd # v4.38.0 (4.38.1 blocked estate-wide; nexia-list#100) - with: - category: "/language:${{ matrix.language }}" diff --git a/.github/workflows/dogfood-gate.yml b/.github/workflows/dogfood-gate.yml deleted file mode 100644 index cba13ea..0000000 --- a/.github/workflows/dogfood-gate.yml +++ /dev/null @@ -1,386 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# dogfood-gate.yml — Hyperpolymath Dogfooding Quality Gate -# 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: - actions: read - contents: read - -jobs: - # --------------------------------------------------------------------------- - # Job 1: A2ML manifest validation - # --------------------------------------------------------------------------- - a2ml-validate: - name: Validate DEED manifests - runs-on: ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout repository - uses: actions/checkout@v7.0.1 - - - name: Check for A2ML files - id: detect - run: | - COUNT=$(find . -type f \( -name '*.a2ml' -o -name '*.deed' \) -not -path './.git/*' | wc -l) - echo "count=$COUNT" >> "$GITHUB_OUTPUT" - if [ "$COUNT" -eq 0 ]; then - echo "::warning::No .a2ml/.deed manifest files found. Every RSR repo should have a repo deed (_chora.deed); legacy 0-AI-MANIFEST.a2ml accepted mid-migration — standards #837" - fi - - - name: Validate A2ML manifests - if: steps.detect.outputs.count > 0 - run: bash .github/hooks/validate-a2ml.sh - - name: Write summary - run: | - A2ML_COUNT="${{ steps.detect.outputs.count }}" - if [ "$A2ML_COUNT" -eq 0 ]; then - cat <<'EOF' >> "$GITHUB_STEP_SUMMARY" - ## A2ML Validation - - :warning: **No .a2ml/.deed manifest files found.** Every RSR-compliant repo should have a repo deed (`_chora.deed`) at its root. - - Copy one from [rsr-template-repo](https://github.com/hyperpolymath/rsr-template-repo). - EOF - else - echo "## A2ML Validation" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "Scanned **${A2ML_COUNT}** manifest file(s) (.deed, or legacy .a2ml). See step output for details." >> "$GITHUB_STEP_SUMMARY" - fi - - # --------------------------------------------------------------------------- - # Job 2: K9 contract validation - # --------------------------------------------------------------------------- - k9-validate: - name: Validate K9 contracts - runs-on: ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout repository - uses: actions/checkout@v7.0.1 - - - name: Check for K9 files - id: detect - run: | - COUNT=$(find . \( -name '*.k9' -o -name '*.k9.ncl' \) -not -path './.git/*' | wc -l) - CONFIG_COUNT=$(find . \( -name '*.toml' -o -name '*.yaml' -o -name '*.yml' -o -name '*.json' \) \ - -not -path './.git/*' -not -path './node_modules/*' -not -path './.deno/*' \ - -not -name 'package-lock.json' -not -name 'Cargo.lock' -not -name 'deno.lock' | wc -l) - echo "k9_count=$COUNT" >> "$GITHUB_OUTPUT" - echo "config_count=$CONFIG_COUNT" >> "$GITHUB_OUTPUT" - 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 - run: bash .github/hooks/validate-k9.sh - - name: Write summary - run: | - K9_COUNT="${{ steps.detect.outputs.k9_count }}" - CFG_COUNT="${{ steps.detect.outputs.config_count }}" - if [ "$K9_COUNT" -eq 0 ]; then - cat <<'EOF' >> "$GITHUB_STEP_SUMMARY" - ## K9 Contract Validation - - :warning: **No .a2ml/.deed manifest files found.** Every RSR-compliant repo should have a repo deed (`_chora.deed`) at its root. - - Generate contracts with: `k9iser generate .` - EOF - else - echo "## K9 Contract Validation" >> "$GITHUB_STEP_SUMMARY" - 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 - # --------------------------------------------------------------------------- - empty-lint: - name: Empty-linter (invisible characters) - runs-on: ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout repository - uses: actions/checkout@v7.0.1 - - - name: Scan for invisible characters - id: lint - run: | - # Inline invisible character detection (from empty-linter's core patterns). - # Checks for: zero-width spaces, zero-width joiners, BOM, soft hyphens, - # non-breaking spaces, null bytes, and other invisible Unicode in source files. - python3 - <<'PY' - import os - from pathlib import Path - - root = Path(os.environ["GITHUB_WORKSPACE"]) - skipped_dirs = { - ".cache", ".deno", ".elixir_ls", ".git", ".lake", ".zig-cache", - "_build", "build", "coverage", "deps", "dist", "external_corpora", - "node_modules", "out", "target", "vendor", "zig-cache", "zig-out", - } - intentional_fixture_dirs = { - ("tests", "fixtures", "bom-detection"), - ("tests", "fixtures", "empty-linter"), - } - # Generated files are not linted for invisible characters: their - # content comes from tooling/history, not authors. CHANGELOG.md is - # regenerated by the changelog bot from squash-merge commit messages - # that contain GitHub's ZWSP-defused @-mentions (@\u200buser) — linting - # it flips main red on every bot regeneration (#192 did exactly - # that: 206 hits, zero of them authored). Estate-grade fix (strip - # at generation in canonical cliff.toml) is tracked upstream. - generated_files = {"CHANGELOG.md"} - source_suffixes = { - ".adoc", ".adb", ".ads", ".agda", ".c", ".cc", ".clj", ".cljs", - ".cpp", ".erl", ".ex", ".exs", ".fs", ".fsi", ".fsx", ".gleam", - ".h", ".hh", ".hpp", ".hrl", ".hs", ".idr", ".java", ".jl", - ".js", ".json", ".kt", ".kts", ".lean", ".lua", ".md", ".ml", - ".php", ".r", ".rb", ".res", ".rs", ".scala", ".sh", ".swift", - ".toml", ".ts", ".v", ".yaml", ".yml", ".zig", - } - invisible_codepoints = { - 0x00A0, 0x00AD, 0x2060, 0xFEFF, - *range(0x200B, 0x2010), - *range(0x202A, 0x2030), - *range(0x2066, 0x206A), - } - - def command_escape(value): - return str(value).replace("%", "%25").replace("\r", "%0D").replace("\n", "%0A") - - def property_escape(value): - return command_escape(value).replace(":", "%3A").replace(",", "%2C") - - # Runtime regression for GitHub workflow-command property delimiters. - assert property_escape("docs/a,b::c.md") == "docs/a%2Cb%3A%3Ac.md" - - def intentionally_invalid_fixture(relative): - return any(relative.parts[:len(prefix)] == prefix for prefix in intentional_fixture_dirs) - - findings = [] - errors = [] - for directory, dirnames, filenames in os.walk(root, topdown=True): - dirnames[:] = [name for name in dirnames if name not in skipped_dirs] - directory_path = Path(directory) - for filename in filenames: - path = directory_path / filename - relative = path.relative_to(root) - if ( - path.is_symlink() - or path.suffix.lower() not in source_suffixes - or intentionally_invalid_fixture(relative) - or relative.as_posix() in generated_files - ): - continue - try: - data = path.read_bytes() - except OSError as error: - errors.append((relative, f"could not read file: {error}")) - continue - - reasons = set() - if data.startswith(b"\xef\xbb\xbf"): - reasons.add("leading UTF-8 BOM") - if any(byte <= 0x08 or byte in (0x0B, 0x0C) or 0x0E <= byte <= 0x1F for byte in data): - reasons.add("C0 control character") - try: - text_content = data.decode("utf-8", errors="strict") - except UnicodeDecodeError as error: - errors.append((relative, f"invalid UTF-8 at byte {error.start}")) - continue - if any(ord(character) in invisible_codepoints for character in text_content): - reasons.add("invisible Unicode code point") - if reasons: - findings.append((relative, ", ".join(sorted(reasons)))) - - with open(os.environ["GITHUB_OUTPUT"], "a", encoding="utf-8") as output: - output.write(f"findings={len(findings)}\n") - output.write(f"exit_code={2 if errors else 0}\n") - output.write("ready=true\n") - - for relative, reasons in findings: - print(f"::warning file={property_escape(relative)}::Invisible characters detected: {command_escape(reasons)}") - for relative, reason in errors: - print(f"::error file={property_escape(relative)}::Invisible-character scan failed: {command_escape(reason)}") - PY - - - name: Write summary - run: | - if [ "${{ steps.lint.outputs.ready }}" = "true" ]; then - FINDINGS="${{ steps.lint.outputs.findings }}" - EXIT_CODE="${{ steps.lint.outputs.exit_code }}" - if [ "$EXIT_CODE" -ne 0 ] 2>/dev/null; then - echo "## Empty-Linter Results" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo ":x: Scanner execution failed; see error annotations above." >> "$GITHUB_STEP_SUMMARY" - exit 1 - fi - if [ "$FINDINGS" -gt 0 ] 2>/dev/null; then - echo "## Empty-Linter Results" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "Found **${FINDINGS}** invisible character issue(s). See annotations above." >> "$GITHUB_STEP_SUMMARY" - exit 1 - else - echo "## Empty-Linter Results" >> "$GITHUB_STEP_SUMMARY" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo ":white_check_mark: No invisible character issues found." >> "$GITHUB_STEP_SUMMARY" - fi - else - echo "## Empty-Linter" >> "$GITHUB_STEP_SUMMARY" - 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) - # --------------------------------------------------------------------------- - groove-check: - name: Groove manifest check - runs-on: ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout repository - uses: actions/checkout@v7.0.1 - - - name: Check for Groove manifest - id: groove - run: | - # Check for static or dynamic Groove endpoints - HAS_MANIFEST="false" - HAS_GROOVE_CODE="false" - - if [ -f ".well-known/groove/manifest.json" ]; then - HAS_MANIFEST="true" - # Validate the manifest JSON - if ! jq empty .well-known/groove/manifest.json 2>/dev/null; then - echo "::error file=.well-known/groove/manifest.json::Invalid JSON in Groove manifest" - else - SVC_ID=$(jq -r '.service_id // "unknown"' .well-known/groove/manifest.json) - echo "service_id=$SVC_ID" >> "$GITHUB_OUTPUT" - fi - fi - - # Check for Groove endpoint code (Rust, Elixir, Zig, V) - if grep -rl 'well-known/groove' --include='*.rs' --include='*.ex' --include='*.zig' --include='*.v' --include='*.res' . 2>/dev/null | head -1 | grep -q .; then - HAS_GROOVE_CODE="true" - fi - - # Check if this repo likely serves HTTP (has server/listener code) - HAS_SERVER="false" - if grep -rl 'TcpListener\|Bandit\|Plug.Cowboy\|httpz\|vweb\|axum::serve\|actix_web' --include='*.rs' --include='*.ex' --include='*.zig' --include='*.v' . 2>/dev/null | head -1 | grep -q .; then - HAS_SERVER="true" - fi - - echo "has_manifest=$HAS_MANIFEST" >> "$GITHUB_OUTPUT" - echo "has_groove_code=$HAS_GROOVE_CODE" >> "$GITHUB_OUTPUT" - echo "has_server=$HAS_SERVER" >> "$GITHUB_OUTPUT" - - 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" - echo "" >> "$GITHUB_STEP_SUMMARY" - echo "| Check | Status |" >> "$GITHUB_STEP_SUMMARY" - echo "|-------|--------|" >> "$GITHUB_STEP_SUMMARY" - 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 - # --------------------------------------------------------------------------- - dogfood-summary: - name: Dogfooding compliance summary - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: [a2ml-validate, k9-validate, empty-lint, groove-check] - if: always() - - steps: - - name: Checkout repository - uses: actions/checkout@v7.0.1 - - - name: Generate dogfooding scorecard - run: | - SCORE=0 - MAX=5 - - # A2ML manifest present? - if find . -type f \( -name '*.a2ml' -o -name '*.deed' \) -not -path './.git/*' | head -1 | grep -q .; then - SCORE=$((SCORE + 1)) - A2ML_STATUS=":white_check_mark:" - else - A2ML_STATUS=":x:" - fi - - # K9 contracts present? - if find . \( -name '*.k9' -o -name '*.k9.ncl' \) -not -path './.git/*' | head -1 | grep -q .; then - SCORE=$((SCORE + 1)) - K9_STATUS=":white_check_mark:" - else - K9_STATUS=":x:" - fi - - # .editorconfig present? - if [ -f ".editorconfig" ]; then - SCORE=$((SCORE + 1)) - EC_STATUS=":white_check_mark:" - else - EC_STATUS=":x:" - fi - - # Groove manifest or code? - if [ -f ".well-known/groove/manifest.json" ] || grep -rl 'well-known/groove' --include='*.rs' --include='*.ex' --include='*.zig' . 2>/dev/null | head -1 | grep -q .; then - SCORE=$((SCORE + 1)) - GROOVE_STATUS=":white_check_mark:" - else - GROOVE_STATUS=":ballot_box_with_check:" - fi - - # VeriSimDB integration? - if grep -rl 'verisimdb\|VeriSimDB' --include='*.toml' --include='*.yaml' --include='*.yml' --include='*.json' --include='*.rs' --include='*.ex' . 2>/dev/null | head -1 | grep -q .; then - SCORE=$((SCORE + 1)) - VSDB_STATUS=":white_check_mark:" - else - VSDB_STATUS=":ballot_box_with_check:" - fi - - cat <> "$GITHUB_STEP_SUMMARY" - ## Dogfooding Scorecard - - **Score: ${SCORE}/${MAX}** - - | Tool/Format | Status | Notes | - |-------------|--------|-------| - | AI manifest (0-AI-MANIFEST.deed, or legacy .a2ml) | ${A2ML_STATUS} | Required for all RSR repos | - | K9 contracts | ${K9_STATUS} | Required for repos with config files | - | .editorconfig | ${EC_STATUS} | Required for all repos | - | Groove endpoint | ${GROOVE_STATUS} | Required for service repos | - | VeriSimDB integration | ${VSDB_STATUS} | Required for stateful repos | - - --- - *Generated by the [Dogfood Gate](https://github.com/hyperpolymath/rsr-template-repo) workflow.* - *Dogfooding is guinea pig fooding — we test our tools on ourselves.* - EOF - diff --git a/.github/workflows/governance.yml b/.github/workflows/governance.yml index 8719e6b..5c808fe 100644 --- a/.github/workflows/governance.yml +++ b/.github/workflows/governance.yml @@ -1,7 +1,5 @@ # This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. name: Governance on: diff --git a/.github/workflows/hypatia-scan.yml b/.github/workflows/hypatia-scan.yml index a5a2131..f839298 100644 --- a/.github/workflows/hypatia-scan.yml +++ b/.github/workflows/hypatia-scan.yml @@ -1,7 +1,5 @@ # This workflow is managed by gh actions-lock. # SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. name: Hypatia Security Scan on: diff --git a/.github/workflows/instant-sync.yml b/.github/workflows/instant-sync.yml deleted file mode 100644 index 74669b7..0000000 --- a/.github/workflows/instant-sync.yml +++ /dev/null @@ -1,40 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# Instant Forge Sync - Triggers propagation to all forges on push/release -name: Instant Sync - -on: - push: - branches: [main, master] - release: - types: [published] - -permissions: - actions: read - contents: read - -jobs: - dispatch: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Trigger Propagation - # Without the secret this step fails on every push (gitbot-fleet#433). - # Skipping is honest; a red tick on a misconfigured repo is not a signal. - if: ${{ secrets.FARM_DISPATCH_TOKEN != '' }} - uses: peter-evans/repository-dispatch@v4.0.1 - with: - token: ${{ secrets.FARM_DISPATCH_TOKEN }} - repository: hyperpolymath/.git-private-farm - event-type: propagate - client-payload: |- - { - "repo": "${{ github.event.repository.name }}", - "ref": "${{ github.ref }}", - "sha": "${{ github.sha }}", - "forges": "" - } - - - name: Confirm - run: echo "::notice::Propagation triggered for ${{ github.event.repository.name }}" diff --git a/.github/workflows/label-triage.yml b/.github/workflows/label-triage.yml deleted file mode 100644 index 814a192..0000000 --- a/.github/workflows/label-triage.yml +++ /dev/null @@ -1,117 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -name: Label Triage - -# Classify newly-filed issues against the estate label taxonomy. -# -# The sweep that established the taxonomy is a one-off; this is what stops it -# decaying. Without it every new issue arrives unlabelled and the 55%-unlabelled -# state rebuilds itself. -# -# ⚠ NO `uses:` ANYWHERE, DELIBERATELY. The estate enforces -# .github/workflows/actions.lock, which is keyed BY WORKFLOW PATH: a workflow -# the lock does not list is rejected before any step runs (startup_failure, and -# therefore no check run at all). A dispatched workflow lands in repos whose -# lock has not been regenerated, so it must not depend on any action. -# -# ⚠ THE CLASSIFIER IS jq, NOT PYTHON. Python is fully banned estate-wide -- the -# `governance / Language / package anti-pattern policy` gate runs -# `git ls-files '*.py'` and fails the PR. Shipping a .py into 416 repos would -# mean shipping an exemption into 416 repos. jq is preinstalled on every GitHub -# runner, is not banned, and needs no action. -# -# Deliberately conservative: -# - ADDITIVE ONLY. It never removes a label and never overrides a human's -# classification: anything already on the issue is passed in via `have` and -# is never re-suggested, and the classifier stays out of any max-1 tier the -# issue already carries a label in. -# - SILENT WHEN UNSURE. Nothing is printed unless a prefix, bracket or type -# rule actually fired. Roughly 70% of the historical corpus classified this -# way; the rest is meant to reach a human. -# - NEVER FAILS THE ISSUE. Every step is best-effort; a missing payload or an -# API hiccup exits 0 rather than leaving a red mark on someone's bug report. - -on: - issues: - types: [opened, reopened] - workflow_dispatch: - inputs: - issue: - description: "Issue number to (re)classify" - required: true - -permissions: - issues: write - contents: read - -jobs: - triage: - runs-on: ubuntu-latest - steps: - - name: Classify and label - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - NUM: ${{ github.event.issue.number || inputs.issue }} - run: | - set -uo pipefail - work=$(mktemp -d); RULES=$work/rules.json; SCRIPT=$work/classify.jq - - # fetch instead of checking out -- no action means no lock entry to drift - gh api "repos/$GITHUB_REPOSITORY/contents/.github/label-classifier.json?ref=$GITHUB_SHA" \ - --jq '.content' 2>/dev/null | base64 -d > "$RULES" || true - gh api "repos/$GITHUB_REPOSITORY/contents/.github/scripts/classify-issue.jq?ref=$GITHUB_SHA" \ - --jq '.content' 2>/dev/null | base64 -d > "$SCRIPT" || true - if [[ ! -s "$RULES" || ! -s "$SCRIPT" ]]; then - echo "no classifier payload in this repo - nothing to do" - exit 0 - fi - - TITLE=$(gh issue view "$NUM" -R "$GITHUB_REPOSITORY" --json title --jq .title) || exit 0 - echo "issue #$NUM: $TITLE" - - # Labels this repo actually defines. --limit 1000 is GitHub's real - # per-repo ceiling; the default of 30 would silently hide most of the - # taxonomy. Fetched BEFORE the label read below so that read stays as - # close to the write as possible. - mapfile -t DEFINED < <(gh label list -R "$GITHUB_REPOSITORY" --limit 1000 \ - --json name --jq '.[].name' 2>/dev/null) - - # Labels already present; a human's work is never overridden. Read - # HERE rather than earlier: every API call between this read and the - # edit below widens a window in which someone could add a type label - # and get a second one back from us. Only the local jq call is inside it. - HAVE=$(gh issue view "$NUM" -R "$GITHUB_REPOSITORY" \ - --json labels --jq '[.labels[].name]' 2>/dev/null) || HAVE='[]' - [[ -n "$HAVE" ]] || HAVE='[]' - echo "already has: $HAVE" - - mapfile -t ADD < <(jq -r --arg title "$TITLE" --argjson have "$HAVE" \ - -f "$SCRIPT" "$RULES" 2>/dev/null) - if [[ ${#ADD[@]} -eq 0 || -z "${ADD[0]:-}" ]]; then - echo "no confident classification - leaving for a human" - exit 0 - fi - - apply=() - for want in "${ADD[@]}"; do - for def in "${DEFINED[@]}"; do - if [[ "$want" == "$def" ]]; then apply+=("$want"); break; fi - done - done - if [[ ${#apply[@]} -eq 0 ]]; then - echo "classified as ${ADD[*]} but this repo defines none of them - run the label sync" - exit 0 - fi - - printf 'applying: %s\n' "${apply[*]}" - # Build the arguments as an ARRAY. The previous form was an unquoted - # command substitution, so the shell re-split its output on spaces and - # a label name containing whitespace would arrive as several broken - # arguments. No canonical label contains a space today, which is - # exactly why this would have failed quietly the first time one did. - # (Also clears actionlint SC2046.) - edit_args=() - for lab in "${apply[@]}"; do edit_args+=(--add-label "$lab"); done - gh issue edit "$NUM" -R "$GITHUB_REPOSITORY" "${edit_args[@]}" \ - || echo "label apply failed - not failing the run" - exit 0 diff --git a/.github/workflows/labels.yml b/.github/workflows/labels.yml deleted file mode 100644 index 83ab941..0000000 --- a/.github/workflows/labels.yml +++ /dev/null @@ -1,106 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -name: Labels - -# Applies the canonical estate label set from .github/labels.json. -# -# Additive and idempotent by design: it CREATES missing labels and UPDATES -# colour/description drift. It never deletes, and it never touches a label in -# the `frozen` list -- those are applied by Dependabot / PR automation, or are -# wired into triage.yml's exempt-issue-labels, and renaming them breaks things. -# -# jq is preinstalled on GitHub runners; PyYAML is not, which is why the payload -# is JSON rather than YAML. -# -# ⚠ NO `uses:` ANYWHERE, DELIBERATELY. The estate enforces -# .github/workflows/actions.lock, which is keyed BY WORKFLOW PATH: a workflow -# the lock does not list is rejected before any step runs (startup_failure, and -# therefore no check run at all). A dispatched workflow lands in repos whose -# lock has not been regenerated, so it must not depend on any action. - -on: - workflow_dispatch: - push: - paths: - - '.github/labels.json' - schedule: - - cron: "23 4 1 * *" # monthly drift repair - -permissions: - issues: write - contents: read - -jobs: - sync: - runs-on: ubuntu-latest - steps: - - name: Apply canonical labels - env: - GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} - # ⚠ LOAD-BEARING. This workflow deliberately does not check the repo - # out (no `uses:`, so no actions.lock entry can drift), which means - # `gh label create` / `gh label edit` have no git remote to infer a - # target from. Without GH_REPO every mutation fails, and because the - # errors used to be discarded the step still exited 0 reporting - # "created=0 updated=0" -- a silent, estate-wide no-op. - GH_REPO: ${{ github.repository }} - run: | - set -uo pipefail - work=$(mktemp -d); PAYLOAD=$work/labels.json - - # fetch instead of checking out -- no action means no lock entry to drift - gh api "repos/$GITHUB_REPOSITORY/contents/.github/labels.json?ref=$GITHUB_SHA" \ - --jq '.content' 2>/dev/null | base64 -d > "$PAYLOAD" || true - [ -s "$PAYLOAD" ] || { echo "no .github/labels.json - nothing to do"; exit 0; } - - mapfile -t FROZEN < <(jq -r '.frozen[]' "$PAYLOAD") - created=0; updated=0; skipped=0; failed=0 - - existing=$(gh api "repos/$GITHUB_REPOSITORY/labels" --paginate \ - --jq '.[] | [.name, .color, (.description // "")] | @tsv') - - while IFS=$'\t' read -r name color desc; do - [ -z "$name" ] && continue - frozen=0 - for f in "${FROZEN[@]}"; do [ "$f" = "$name" ] && frozen=1 && break; done - - cur=$(printf '%s\n' "$existing" | awk -F'\t' -v n="$name" '$1==n{print;exit}') - if [ -z "$cur" ]; then - # A MISSING label is created even when frozen. "Frozen" protects a - # label's DEFINITION from being renamed or recoloured -- it was - # never meant to stop the label existing. Skipping creation broke - # `security`, the one canonical label that is also frozen: it was - # absent from 10 of 12 sampled repos, and label-triage drops any - # label the repo does not define, so every `security` finding was - # silently discarded estate-wide. - if err=$(gh label create "$name" --color "$color" \ - --description "$desc" 2>&1 >/dev/null); then - created=$((created+1)); sleep 0.4 - else - echo " create failed: $name -- ${err:-unknown}"; failed=$((failed+1)) - fi - else - # Present AND frozen: leave it exactly as it is. - if [ "$frozen" -eq 1 ]; then skipped=$((skipped+1)); continue; fi - ccol=$(cut -f2 <<<"$cur"); cdesc=$(cut -f3- <<<"$cur") - if [ "${ccol,,}" != "${color,,}" ] || [ "$cdesc" != "$desc" ]; then - if err=$(gh label edit "$name" --color "$color" \ - --description "$desc" 2>&1 >/dev/null); then - updated=$((updated+1)); sleep 0.4 - else - echo " edit failed: $name -- ${err:-unknown}"; failed=$((failed+1)) - fi - fi - fi - done < <(jq -r '.labels[] | [.name, .color, .description] | @tsv' "$PAYLOAD") - - echo "created=$created updated=$updated frozen-skipped=$skipped failed=$failed" - - # Fail ONLY on the misconfiguration shape: work was attempted, every - # attempt failed. That is the silent-no-op signature. A single flaky - # label must not turn the whole estate's CI red. - if [ "$failed" -gt 0 ] && [ "$((created + updated))" -eq 0 ]; then - echo "every label mutation failed - the sync did nothing. Check GH_REPO and token scope." - exit 1 - fi - exit 0 diff --git a/.github/workflows/mirror.yml b/.github/workflows/mirror.yml deleted file mode 100644 index b95ea10..0000000 --- a/.github/workflows/mirror.yml +++ /dev/null @@ -1,19 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -name: Mirror to Git Forges - -on: - push: - branches: [main] - workflow_dispatch: - -permissions: - actions: read - contents: read - -jobs: - mirror: - uses: hyperpolymath/standards/.github/workflows/mirror-reusable.yml@84355587cb2a1f86e6882de83514a32db2646e7a - secrets: inherit diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml deleted file mode 100644 index 1189bee..0000000 --- a/.github/workflows/pages.yml +++ /dev/null @@ -1,61 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# pages.yml — GitHub Pages deployment via Ddraig SSG. -name: GitHub Pages (Ddraig SSG) -on: - push: - branches: [main, master] - workflow_dispatch: -permissions: - actions: read - contents: read - pages: write - id-token: write -concurrency: - group: "pages" - cancel-in-progress: false -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 15 - container: - image: ghcr.io/stefan-hoeck/idris2-pack@sha256:f0758996a931fb35d9ecb1de273c4d59dabe2a09b433afc7e357f65a08b7e1ff - steps: - - name: Checkout Site - uses: actions/checkout@v7.0.1 - - name: Checkout Ddraig SSG - uses: actions/checkout@v7.0.1 - with: - repository: hyperpolymath/ddraig-ssg - path: .ddraig-ssg - - name: Compile Ddraig - working-directory: .ddraig-ssg - run: idris2 Ddraig.idr -o ddraig - - name: Build site - run: | - mkdir -p src - if [ ! -f src/index.md ] && [ -f README.md ]; then - cp README.md src/index.md - elif [ ! -f src/index.md ]; then - echo "# ${GITHUB_REPOSITORY}" > src/index.md - fi - ./.ddraig-ssg/build/exec/ddraig build src _site https://hyperpolymath.github.io/${GITHUB_REPOSITORY#*/} - - name: Upload artifact - uses: actions/upload-pages-artifact@v5.0.0 - with: - path: '_site' - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@v5.0.1 diff --git a/aletheia/templates/rust/.github/workflows/proof.yml b/.github/workflows/proof.yml similarity index 100% rename from aletheia/templates/rust/.github/workflows/proof.yml rename to .github/workflows/proof.yml diff --git a/.github/workflows/push-email-notify.yml b/.github/workflows/push-email-notify.yml deleted file mode 100644 index 8a96bf9..0000000 --- a/.github/workflows/push-email-notify.yml +++ /dev/null @@ -1,59 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# Dormant push-email notification. ARMED by setting the repo variable -# PUSH_EMAIL_ENABLED=true (the single on/off switch). Addresses are pre-filled; -# sending needs the org SMTP secrets (SMTP_HOST/PORT/USER/PASS). Inherited by -# new repos from the template; placed on existing repos by the farm sweep. -# -# Re-landed after the 2026-07-20 notification-storm freeze (removed in -# 09f94c5), now on hyperpolymath/smtp-notify-action: Node-free, the SMTP -# session is Idris2-specified and machine-checked, the binary is Zig-built, -# byte-reproducible, and SHA-256-pinned inside the action itself. -name: Push email notification -on: - push: - # Branch pushes only: tag and deletion payloads mislabel Branch:/head_commit. - branches: ['**'] -concurrency: - # Deliberately per-RUN, so no run is ever queued behind another and none is - # ever cancelled. Do NOT "tidy" this into a shared group such as - # ${{ github.workflow }}-${{ github.ref }}. GitHub's workflow-syntax docs: - # "By default, any existing pending job or workflow in the same concurrency - # group will be canceled and the new queued job or workflow will take its - # place." That happens regardless of cancel-in-progress, which governs only - # the RUNNING job. On this workflow it silently loses a notification email, - # with no error anywhere. Every run here reports a DISTINCT commit, so there - # is no redundant work for a concurrency limit to remove. - # The docs also offer `queue: max` (up to 100 pending); not used, because 100 - # is still a cap whereas a per-run group needs none. - # Verified with zizmor 1.30.0: deleting this block raises concurrency-limits; - # this form silences it exactly as a shared group would. - group: push-email-${{ github.run_id }} - cancel-in-progress: false -permissions: - contents: read -jobs: - notify: - name: Email on push - if: ${{ vars.PUSH_EMAIL_ENABLED == 'true' }} - runs-on: ubuntu-latest - timeout-minutes: 5 - steps: - - name: Send push notification email - uses: hyperpolymath/smtp-notify-action@v0.3.0 - with: - server_address: ${{ secrets.SMTP_HOST }} - server_port: ${{ secrets.SMTP_PORT }} - secure: true - username: ${{ secrets.SMTP_USER }} - password: ${{ secrets.SMTP_PASS }} - from: "GitHub Push <${{ secrets.SMTP_USER }}>" - to: "jonathan.jewell@gmail.com j.d.a.jewell@open.ac.uk" - subject: "[${{ github.repository }}] push to ${{ github.ref_name }} by ${{ github.actor }}" - body: | - Repository: ${{ github.repository }} - Branch: ${{ github.ref_name }} - Pusher: ${{ github.actor }} - Compare: ${{ github.event.compare }} - Head msg: ${{ github.event.head_commit.message }} diff --git a/.github/workflows/rust-ci.yml b/.github/workflows/rust-ci.yml deleted file mode 100644 index 36fbbcb..0000000 --- a/.github/workflows/rust-ci.yml +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Root Rust CI gate for the aletheia crate. -# -# Restored 2026-09-21: the previous gate was deleted in the commit that -# moved the crate to aletheia/ and never re-pointed, so main has had no -# Rust CI since. This version re-points every step at aletheia/ and adds -# the clippy -D warnings job (the blocking gate half of issue #125). -# -# Action refs are tags resolved by .github/workflows/actions.lock (the -# estate mechanism — governance verifies the lock and forbids inline SHAs -# alongside it). Every job below has a same-named recipe in the root -# Justfile; keep them in lockstep so `just check` means the same thing -# locally as this gate. Toolchain is the runner's ambient Rust (the crate -# declares rust-version 1.80; there is deliberately no pinned toolchain -# action here, to keep the lockfile surface to checkout alone). No -# #![allow(dead_code)] workarounds: dead code here is either wired or -# deleted (see the never-allow-dead-code landmine in STATE.a2ml). -name: rust-ci -on: - push: - branches: [main] - paths: - - 'aletheia/**' - - 'Justfile' - - '.github/workflows/rust-ci.yml' - pull_request: - paths: - - 'aletheia/**' - - 'Justfile' - - '.github/workflows/rust-ci.yml' -permissions: - contents: read -concurrency: - group: rust-ci-${{ github.ref }} - cancel-in-progress: true -defaults: - run: - working-directory: aletheia -jobs: - build: - name: build (debug + release) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/checkout@v7.0.1 - - name: Toolchain versions - run: cargo --version && rustc --version - - name: Build all targets (debug, locked) - run: cargo build --locked --all-targets - - name: Build release (locked) - run: cargo build --locked --release - test: - name: test (unit + integration) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/checkout@v7.0.1 - - name: Full test suite (locked) - run: cargo test --locked - fmt: - name: fmt --check - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v7.0.1 - - name: Check formatting - run: cargo fmt --check - clippy: - name: clippy -D warnings - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - uses: actions/checkout@v7.0.1 - - name: Lint all targets, warnings denied - run: cargo clippy --locked --all-targets -- -D warnings - deps-check: - name: zero-dependency check - runs-on: ubuntu-latest - timeout-minutes: 10 - steps: - - uses: actions/checkout@v7.0.1 - - name: Enforce the zero-dependency RSR Bronze constraint - run: | - if cargo tree --depth 1 | tail -n +2 | grep -q '[a-z]'; then - echo "ERROR: Aletheia must have zero dependencies (see aletheia/CLAUDE.md)" - cargo tree --depth 1 - exit 1 - fi - echo "OK: zero dependencies" diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml deleted file mode 100644 index 5d212f3..0000000 --- a/.github/workflows/scorecard.yml +++ /dev/null @@ -1,22 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -name: OSSF Scorecard - -on: - schedule: - - cron: '0 4 * * *' - workflow_dispatch: - -permissions: - actions: read - contents: read - -jobs: - scorecard: - uses: hyperpolymath/standards/.github/workflows/scorecard-reusable.yml@84355587cb2a1f86e6882de83514a32db2646e7a - permissions: - contents: read - security-events: write - id-token: write diff --git a/.github/workflows/secret-scanner.yml b/.github/workflows/secret-scanner.yml deleted file mode 100644 index fffde78..0000000 --- a/.github/workflows/secret-scanner.yml +++ /dev/null @@ -1,25 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -# This workflow is managed by gh actions-lock. -name: Secret Scanner - -on: - pull_request: - push: - branches: [main] - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - scan: - permissions: - contents: read - uses: hyperpolymath/standards/.github/workflows/secret-scanner-reusable.yml@84355587cb2a1f86e6882de83514a32db2646e7a - secrets: inherit diff --git a/.gitignore b/.gitignore index a2b798a..469d74f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,136 +1,23 @@ -# RSR-compliant .gitignore -# OS generated files -.DS_Store -.DS_Store? -._* -.Spotlight-V100 -.Trashes -ehthumbs.db -Thumbs.db - -# IDE and editor files -.idea/ -.vscode/ -*.swp -*.swo -*~ - -# Secrets and credentials (never commit these) -*.pem -*.key -.env -.env.* -!.env.example -credentials.json -secrets.yaml - -# Rust +# SPDX-License-Identifier: MPL-2.0 +# Build artefacts /target/ +**/target/ +Cargo.lock -# Logs -*.log -logs/ +# Creusot/Why3 proof artefacts +*.coma +*.mlcfg +verification/verif/ +verification/target/ +.why3find/ - -# OS & Editor +# Editors and OS .DS_Store -Thumbs.db -*.swp -*.swo -*~ .idea/ .vscode/ +*.swp +*~ - -# Build -/target/ -/_build/ -/build/ -/dist/ -/out/ -/zig-out/ -/zig-cache/ - - -# Dependencies -/node_modules/ -/vendor/ -/deps/ -/.elixir_ls/ - - -# Cargo.lock # Keep for binaries - - -# Elixir -/cover/ -/doc/ -*.ez -erl_crash.dump - - -# Julia -*.jl.cov -*.jl.mem -/Manifest.toml - - -# ReScript -/lib/bs/ -/.bsb.lock - - -# Python (SaltStack only) -__pycache__/ -*.py[cod] -.venv/ - - -# Ada/SPARK -*.ali -/obj/ -/bin/ - - -# Haskell -/.stack-work/ -/dist-newstyle/ - - -# Chapel -*.chpl.tmp.* - - -# Secrets +# Local environment .env -.env.* -*.pem -*.key -secrets/ - - -# Test/Coverage -/coverage/ -htmlcov/ - - -# Machine-readable locks -.machine_readable/.locks/ - - -# Temp -/tmp/ -*.tmp -*.baktarget/ -node_modules/ -_build/ -deps/ -.elixir_ls/ -.cache/ -build/ -dist/ - -# Claude Code worktrees — local scratch, never tracked. -# A worktree committed as a gitlink has no .gitmodules entry, which breaks -# every `git submodule update` and recursive checkout (see PR #145). -.claude/worktrees/ +.env.local diff --git a/.gitmodules b/.gitmodules deleted file mode 100644 index 234b575..0000000 --- a/.gitmodules +++ /dev/null @@ -1,8 +0,0 @@ -# The Certified Null Operation (CNO) reference is developed in the standalone -# hyperpolymath/absolute-zero repository and pinned here as a submodule (PR #89). -# CNO development happens upstream; this pointer is bumped as a deliberate act -# (see .machine_readable/contractiles/Intentfile.a2ml and Trustfile.a2ml). -[submodule "absolute-zero"] - path = absolute-zero - url = https://github.com/hyperpolymath/absolute-zero.git - branch = main diff --git a/.hypatia-ignore b/.hypatia-ignore deleted file mode 100644 index 7befcdb..0000000 --- a/.hypatia-ignore +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# -# Hypatia scanner exemptions for maa-framework. There are currently NO -# active exemptions: this file is intentionally rules-free, kept as an -# audit record so the absence of exemptions is a deliberate state rather -# than a missing file. -# -# HISTORY (pruned 2026-09-21, issue #98): -# - 10 cicd_rules/banned_language_file entries (9 absolute-zero/ demo -# files + aletheia/examples/SafeDOMExample.res) were dropped after -# verifying every referenced path dead at the pinned submodule commit: -# the ReScript->AffineScript migration landed upstream and the vendored -# demo subtree is gone. The TODO 2026-Q3 comment and the standards#180 -# note went with them (standards#180 has since merged — file_pattern -# globs are available if per-file exemptions ever return). -# - Upstream follow-up lives in the owning repo, not here: -# hyperpolymath/absolute-zero#77 (prune that repo's own stale entries). -# -# VERIFY (re-run before adding any exemption back): -# git submodule status absolute-zero # note the pinned commit -# for f in ; do test -e "$f" && echo "ALIVE: $f"; done -# An exemption for a path that does not exist at the pinned commit is -# theater, not coverage — do not re-add dead entries. diff --git a/.hypatia/activity.jsonl b/.hypatia/activity.jsonl deleted file mode 100644 index c29582a..0000000 --- a/.hypatia/activity.jsonl +++ /dev/null @@ -1 +0,0 @@ -{"timestamp":"2026-03-08T02:04:29Z","bot":"hypatia-autofix","action":"scan","details":"fixes=0"} diff --git a/.hypatia/last-visit.json b/.hypatia/last-visit.json deleted file mode 100644 index b81d885..0000000 --- a/.hypatia/last-visit.json +++ /dev/null @@ -1,6 +0,0 @@ -{ - "last_visit": "2026-03-08T02:04:29Z", - "last_bot": "hypatia-autofix", - "last_action": "scan", - "visits_total": 1 -} diff --git a/.machine_readable/6a2/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/0-AI-MANIFEST.a2ml deleted file mode 100644 index 6bf1f8c..0000000 --- a/.machine_readable/6a2/0-AI-MANIFEST.a2ml +++ /dev/null @@ -1,31 +0,0 @@ -# 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/AGENTIC.a2ml b/.machine_readable/6a2/AGENTIC.a2ml deleted file mode 100644 index 9931a7a..0000000 --- a/.machine_readable/6a2/AGENTIC.a2ml +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# AGENTIC.a2ml — AI agent constraints and capabilities -# Defines what AI agents can and cannot do in this repository. - -[metadata] -version = "0.1.0" -last-updated = "2026-03-16" - -[agent-permissions] -can-edit-source = true -can-edit-tests = true -can-edit-docs = true -can-edit-config = true -can-create-files = true - -[agent-constraints] -# What AI agents must NOT do: -# - Never use banned language patterns (believe_me, unsafeCoerce, etc.) -# - Never commit secrets or credentials -# - Never use banned languages (TypeScript, Python, Go, etc.) -# - Never place state files in repository root (must be in .machine_readable/) -# - Never use AGPL license (use MPL-2.0) diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/6a2/ECOSYSTEM.a2ml deleted file mode 100644 index 19e0188..0000000 --- a/.machine_readable/6a2/ECOSYSTEM.a2ml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# ECOSYSTEM.a2ml — Ecosystem position -# Converted from ECOSYSTEM.scm on 2026-03-15 - -[metadata] -project = "maa-framework" -ecosystem = "hyperpolymath" - -[position] -type = "coordinator" # maa-framework is the coordinating hub for its ecosystem - -[related-projects] -# Coordinating hub: the projects below are standalone top-level repos, -# referenced/contextualised here — NOT vendored as submodules. -absolute-zero = "hyperpolymath/absolute-zero — Certified Null Operation (CNO); standalone repo, coordinated here (submodule removed 2026-06-13)" -oblibeny = "hyperpolymath/oblibeny — reference language designed for the framework" diff --git a/.machine_readable/6a2/META.a2ml b/.machine_readable/6a2/META.a2ml deleted file mode 100644 index 69e4756..0000000 --- a/.machine_readable/6a2/META.a2ml +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# META.a2ml — Project meta-information -# Converted from META.scm on 2026-03-15 - -[metadata] -project = "maa-framework" -author = "Jonathan D.A. Jewell " -license = "MPL-2.0" -standard = "RSR 2026" -last-updated = "2026-06-12" - -[architecture-decisions] -# ADR-001 (2026-04-18): K9 self-validation lives outside contractiles/ so the -# contractile directory stays a pure verb set. Location updated by the -# 2026-06 estate standardization: .machine_readable/self-validating/ -# (formerly .machine_readable/svc/k9/). -# 2026-06 estate wave: Guix manifest.scm is the package entrypoint -# (flake.nix removed in the estate-standardization merge). -adr-001 = "K9 self-validation outside contractiles/; now at .machine_readable/self-validating/ per estate standardization" -packaging = "Guix (guix.scm + manifest.scm); flake.nix removed in estate wave 2026-06" diff --git a/.machine_readable/6a2/NEUROSYM.a2ml b/.machine_readable/6a2/NEUROSYM.a2ml deleted file mode 100644 index 767d7dd..0000000 --- a/.machine_readable/6a2/NEUROSYM.a2ml +++ /dev/null @@ -1,14 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# NEUROSYM.a2ml — Neurosymbolic integration metadata -# Configuration for Hypatia scanning and symbolic reasoning. - -[metadata] -version = "0.1.0" -last-updated = "2026-03-16" - -[hypatia-config] -scan-enabled = true -scan-depth = "standard" -report-format = "logtalk" diff --git a/.machine_readable/6a2/PLAYBOOK.a2ml b/.machine_readable/6a2/PLAYBOOK.a2ml deleted file mode 100644 index 08bac4a..0000000 --- a/.machine_readable/6a2/PLAYBOOK.a2ml +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# PLAYBOOK.a2ml — Operational playbook -# Runbooks, incident response, deployment procedures. - -[metadata] -version = "0.1.0" -last-updated = "2026-06-12" - -[deployment] -# method = "gitops" -# target = "container" - -[incident-response] -# 1. Check .machine_readable/6a2/STATE.a2ml for current status -# 2. Review recent commits and CI results -# 3. Run just validate to check compliance - -[release-process] -# 1. Update version in STATE.a2ml, META.a2ml -# 2. Run just quality (format, lint, test) -# 3. Tag and push diff --git a/.machine_readable/6a2/README.adoc b/.machine_readable/6a2/README.adoc deleted file mode 100644 index 916a702..0000000 --- a/.machine_readable/6a2/README.adoc +++ /dev/null @@ -1,30 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.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/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml deleted file mode 100644 index 7ebfd6c..0000000 --- a/.machine_readable/6a2/STATE.a2ml +++ /dev/null @@ -1,141 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# STATE.a2ml — Project state checkpoint -# Last updated: 2026-09-21 (all-open-issues campaign: #98, #100, #102, #124, #125 closed; previous: 2026-07-29 CI-reality checkpoint) -# -# Human-readable counterpart: docs/STATE-OF-PLAY-2026-07-29.adoc - -[metadata] -project = "maa-framework" -version = "0.1.0" -last-updated = "2026-09-21" -status = "Aletheia CLI built to the RSR v2 SSOT (111/111 tests, clippy blocking); root rust-ci restored; changelog automated; all 5 open issues closed" -measured-against = "measured 2026-07-29 vs origin/main 7d964ee; re-verified 2026-08-03 vs 2bf7a13; re-measured 2026-09-21 on fix/all-open-issues-98-100-102-124-125 vs main b77c53c" - -[project-context] -name = "maa-framework" -completion-percentage = 50 -phase = "Governance & estate standardization (post-CRG-C; spec/implementation phases per ROADMAP.adoc still open)" - -[testing-status] -aletheia-unit-tests = "66 pass, 0 fail (2026-09-21: CLI rebuild + lock-aware pins + Bun carve-out)" -aletheia-integration-tests = "45 pass, 0 fail — CLI built to the RSR v2 SSOT; issue #124 closed 2026-09-21" -aletheia-clippy = "0 findings; `clippy --all-targets -- -D warnings` blocks in rust-ci.yml + `just lint` (issue #125 closed 2026-09-21)" -absolute-zero-tests = "13 brainfuck + 5 whitespace unit, 10 E2E, 11 property, 11 aspect — run in the upstream repo, not here" -benchmarks = "criterion-based (absolute-zero/benches/cno_benchmarks.rs)" -test-result = "main: build + full suite (68+47) + fmt + clippy -D + zero-dep all GREEN via `just check`; root rust-ci.yml restored to run the same on main" -integration-test-caveat = "RETIRED 2026-09-21 (the warning was heeded): the suite still asserts on stdout substrings (a UI contract), but the checks were built to the upstream SSOT criteria — each cites its v2 criterion — not to the strings. Keep that direction: SSOT first, strings second." -note = "absolute-zero/ is a git submodule since PR #89; aletheia/ is VENDORED plain files, not a submodule" - -[ci-status] -# Measured 2026-07-29 on origin/main 7d964ee -rust-ci = "RESTORED 2026-09-21 (the tree-move commit had deleted it without re-pointing): 5 jobs — build, full test suite, fmt, clippy -D warnings, zero-dep — each mirrored by a root Justfile recipe" -governance = "PASS — 10 jobs; workflow linter and staleness both green" -codeql = "PASS" -secret-scanner = "PASS" -hypatia-scan = "PASS" -dogfood-gate = "PASS — repaired in #140/#141 by vendoring the validation scripts" -ossf-scorecard = "PASS — was dying at checkout on a stray gitlink; fixed in #145 (merged) and green on main since. NOTE: scorecard.yml triggers only on push-to-main/schedule/workflow_dispatch, NOT pull_request, so it cannot be proven on a PR." -mirror = "PASS" -boj-trigger = "PASS" -disabled-manually = "GitHub Pages (Ddraig SSG), Instant Sync, Push email notification — these report NOTHING; a green board is not full coverage" - -[gating-reality] -only-real-rust-gate = ".github/workflows/rust-ci.yml AT THE REPOSITORY ROOT (added 2026-07-21 in PR #123; deleted by the tree-move commit; restored 2026-09-21 re-pointed at aletheia/ with clippy blocking)" -inert-workflows = "The 16 files under aletheia/.github/workflows/ have NEVER executed. GitHub Actions reads .github/workflows/ at the repository ROOT ONLY, and aletheia/ is vendored (mode 100644), not a submodule. Editing them has no effect on CI." -cost-of-that-gap = "b5322c2 (2026-06-17) dropped a brace in aletheia/src/config.rs; main did not compile FOR OVER A MONTH because nothing was compiling it. Repaired in PR #123." -local-gates = "just build/test/fmt/lint/deps-check/check now run the same commands as CI (PR #144, closes #99). Before that every recipe echoed 'not configured yet' and exited 0." -falsifiability-proven = "just fmt exits 1 on deliberately malformed Rust while just build stays 0; reverting restores 0. A gate nobody has watched fail is not a gate." - -[proof-state] -# Measured 2026-07-29 against absolute-zero @87902bb7 -admitted-count = 0 -axiom-count = 23 -axiom-files = "physics/LandauerDerivation.v (6), quantum/QuantumCNO.v (6), common/StatMechBasis.v (5), physics/StatMech.v (3), common/PhysicsConstants.v (2), lambda/LambdaCNO.v (1)" -falsified-claim = "PROOF-NEEDS.md previously claimed '1 Admitted in LambdaCNO.v'. There are ZERO. y_not_cno is a KEPT AXIOM with a written rationale. The claim was wrong in BOTH directions — it overstated the incompleteness and understated the trusted base 23x. Corrected in PR #144." -gate-implication = "An Axiom PASSES a 'no sorry / no Admitted' gate silently. Counting only Admitted measures the wrong thing; any proof gate here must scan for Axiom too." -authoritative-record = "The in-source AXIOM AUDIT at the end of proofs/coq/physics/LandauerDerivation.v, NOT PROOF-NEEDS.md. It is self-critical: it records that cno_zero_energy_dissipation_derived is an axiom DESPITE its _derived name, and that the triage docs' DISCHARGE marks are inaccurate." -urgent-proof-item = "NOT y_not_cno. The audit's own SOUNDNESS WARNINGS: prob_nonneg and prob_normalized are false over unconstrained function-type distributions, and shannon_entropy_maximum's inequality is BACKWARDS. All three currently UNUSED — cheap now, expensive later." - -[crg-compliance] -tier = "C" -requirements = "unit + smoke + build + P2P + E2E + reflexive + contract + aspect + benchmarks" -status = "COMPLETE" -notes = "Zero-dependency aletheia (RSR Bronze), no unsafe code, criterion benchmarks established" - -[recent-work] -# Summarized from `git log --since=2026-04-04 origin/main` (51 commits, 2026-05-13..2026-06-04) -# plus the 2026-06-12 estate-standardization merge. -license-migration = "PMPL-1.0-or-later -> MPL-2.0 estate-wide sweep (commit e4e3db0)" -ci-canonicalization = "hypatia-scan/mirror/secret-scanner/scorecard converted to thin wrappers of hyperpolymath/standards reusables (PRs #52, #54, #73, #76, #77, #80); concurrency-cancel guards (#56, #58); scorecard-enforcer OSSF run-step fix (#87); scorecard job-level permissions (#90); CI/CD fix campaigns C001-C005" -absolute-zero-submodule = "re-vendored subtree to upstream HEAD (#83), then converted absolute-zero/ to a git submodule pinned to upstream (#89, closes #84)" -language-policy = "ReScript guidance retired -> AffineScript (#53 Item 9); stale SafeDOMExample.res fixture deleted (#74); CLAUDE.md flip per 2026-05-25 estate policy (#88)" -docs = "CHANGELOG.md seeded, Keep-a-Changelog format (#81); docs-template/ skeleton adopted (#79); tech-debt audit recorded 2026-05-26 (#75); proof-debt.md seeded per standards#203 (#82)" -dependabot = "actions bumps #59-#69, #92-#96 (checkout, artifacts, codeql-action, rust-toolchain, trufflehog, cache, pages)" -estate-standardization = "2026-06-12: merged estate-standardization-20260607 — 6a2 manifest + README, anchors/ -> 6a2/anchor/, agent_instructions/ -> bot_directives/, flat contractiles, svc/k9 -> self-validating/, GOVERNANCE.adoc, Guix manifest.scm replaces flake.nix; codeql cron weekly -> monthly cherry-picked (standards#288)" - -[recent-work-2026-07] -# The CI repair campaign, 2026-07-21..29. All merged unless noted. -pr-123 = "aletheia had not compiled since 2026-06-17 (dropped brace) — repaired, and root rust-ci.yml added: the first real Rust gate this repo has ever had" -pr-128 = "SHA-pinned the four unpinned actions in pages.yml (missed the #123 squash by 10 minutes; relanded)" -pr-139 = "removed the unrunnable SonarCloud step that was breaking Governance AND CodeQL" -pr-140-141 = "validate-action repos had been deleted upstream; validation scripts vendored, Dogfood Gate green again" -pr-142 = "repointed codeql-action at a SHA that exists — BUT was a `git commit -a` on a dirty tree and carried TWO unrelated defects onto main (see [incidents])" -pr-143 = "restored guix.scm identity + licence after the squisher-corpus clobber" -pr-144 = "aletheia SHA-pin check made real; root Justfile wired (closes #99); PROOF-NEEDS.md and aletheia/CLAUDE.md corrected" -pr-145 = "removed the stray worktree gitlink breaking every recursive checkout — MERGED; OSSF Scorecard green on main since" - -[recent-work-2026-09] -# The all-open-issues campaign, 2026-09-21. All five open issues closed. -issue-124 = "Aletheia CLI rebuilt on the RSR v2 SSOT (standards rsr-criteria-v2.a2ml v2.1.0-draft): 26-check offline subset, TOML config, human/JSON/SARIF/HTML/badge/quiet/verbose output, exit codes 0-4; 68 unit + 47 integration green (review-response R1: T1/T2/T4-T10 addressed)" -issue-125 = "Clippy findings wired away (no allow(dead_code)); `clippy --all-targets -- -D warnings` blocks in rust-ci.yml + `just lint`" -issue-102 = "Root Justfile declared canonical; contractiles/Justfile stub (fake gates) replaced by a forwarding shim; repaired crg-grade/crg-badge (Make-style $$ broke every run)" -issue-100 = "changelog.yml adopted (pr-back; commit-back blocked by Optimus-Branch ruleset); CHANGELOG.md seeded; CHANGELOG.adoc frozen as pointer" -issue-98 = ".hypatia-ignore pruned to a comments-only audit record (all 10 entries verified dead); upstream residue in absolute-zero#77" -review-response-185 = "CodeRabbit T1-T10 triaged: T6 parser (flags after positional), T4 symlink depth/truncation, T5 unterminated array, T7 hook exit codes, T8 HTML tier label, T9 pid fixtures, T10 submodule test, T2 SHA pin, T1 perm kept+documented; T3 perf consolidation deferred with reason" -main-health-red-to-green = "2026-09-21: changelog caller fixed (top-level actions:read — the reusable requests it — plus pr-back for the ruleset-guarded main); actions.lock reconciled to codeql-action v4.38.1 (#187 fallout); U+200B removed from CHANGELOG.md (empty-linter); root CONTRIBUTING.adoc added (docs-gate cutoff passed)" -rust-ci-restore = "Root rust-ci.yml restored re-pointed at aletheia/ (5 jobs mirroring `just check`); pin check taught the estate tags+actions.lock mechanism; Bun lockfile carve-out for no-node-runtime" -followups-silver-gaps = "2026-09-21: .tool-versions + mise.toml carry the real rust 1.98.1 pin (30-entry all-latest template retired); manifest.scm shipped (rust/just/git, reviewed-not-executed); root .well-known/ symlinks to the www/ bundle; rsr-profile.a2ml declares [rust bash cli docs-site] with rationale (partial-governance + guix.scm-only gaps documented, checker exit 1 expected); QUICKSTART-DEV filled with measured values" - -[incidents] -squisher-corpus-clobber = "An automated sweep on 2026-07-26 ~16:00 BST copied hyper-repos/squisher-corpus/guix.scm BYTE-FOR-BYTE into a large number of estate repos instead of generating one per repo. Its own commit message names the bug: 'chore: update guix.scm from squisher-corpus'. Here it rewrote the package identity AND replaced MPL-2.0 with PMPL-1.0-or-later. Fixed in #143." -clobber-is-a-policy-violation = "absolute-zero/.claude/CLAUDE.md lists PMPL-1.0 / PMPL-1.0-or-later under BANNED ('License: MPL-2.0 only'), and [recent-work].license-migration below records an estate-wide migration AWAY from PMPL to MPL-2.0. The licence half was a policy violation, not merely an error." -stray-worktree-gitlink = ".claude/worktrees/maa-ci-repair was committed as a gitlink (mode 160000) with NO .gitmodules entry. Git refuses: 'fatal: No url found for submodule path ... in .gitmodules'. This broke OSSF Scorecard AT CHECKOUT, before a single probe ran, and breaks any recursive clone. Fixed in #145; .claude/worktrees/ now gitignored." -gitlink-shape-is-a-repeat = "639f389 (2026-02-21) left aletheia as a gitlink with no .gitmodules entry. A gitlink WITHOUT its mapping resolves to a silently-empty directory — git's quietest failure — and went unnoticed for over a month." -dead-sha-pin-check = "aletheia's own Silver-level 'GitHub Actions SHA pinning' check used `line.contains(\"@v\") && !line.contains(\"@\")`, which is UNSATISFIABLE — every repo passed unconditionally, including this one while it carried the unpinned @master action that had broken Governance and CodeQL. Fixed with 3 tests in #144." -changelog-startup-failure = "2026-09-21/22: FIVE changelog runs on main (900c141, e6d02db, 0f837de, 6620744, dc4514e) startup_failed with zero jobs and no log. #188's top-level actions:read did not help; #190 was comment-only (job-block edit lost to a batched-edit tooling race — never batch two edits to one file). Empirical rule found by comparing callers: the reusable job's {contents:write, PR:write} is checked against the CALLER's TOP-LEVEL permissions (governance + secret-scanner callers request nothing above top-level read and work; standards' own changelog caller also fails). Fixed by granting write at caller top-level with no job block (#191; runs on 270f65d + e22eacb both success). FOLLOW-UP: bot regen (#192) reintroduced the same 206 ZWSP from squash-merge messages and reddened empty-linter — fixed by stripping + excluding generated CHANGELOG.md from the scan (don't lint generated artifacts); estate-grade generation-time strip tracked upstream." - -[open-questions] -# These need a human ruling; they are not research tasks. -rsr-source-of-truth = "ANSWERED 2026-09-21 (closed #124 + #125): hypatia's rsr-conformance oracle is normative; the criteria text lives in standards 0-canon/rsr/rsr-criteria-v2.a2ml; aletheia evaluates the offline file-presence subset (26 checks) and labels itself non-normative. The tests were kept as the UI contract and the checks were built to the SSOT, not the strings." -absolute-zero-pin = "Is 87902bb7 the intended CNO state? The re-pin was a SEMANTIC BUMP, not a restore — the original pin ad085baa was orphaned by an upstream force-push and its content is unrecoverable, so this cannot be verified from inside the repo." -submodule-or-vendored = "Settle permanently. The repo has oscillated three times (#89 -> bef4c92 -> #117). While absolute-zero accepts force-pushes to main, ANY pin will be orphaned again by the next rollout." -aletheia-licence = "Is PR #135's move of aletheia to PMPL-1.0-or-later + CC-BY-SA-4.0 intended? It runs against the written ban noted in [incidents].clobber-is-a-policy-violation." - -[blockers] -spec-uploads = "ROADMAP Phase 1 (specification documents for framework, Oblibeny, Aletheia) not yet uploaded" -proof-debt = "See [proof-state]. Note the older figure in docs/proof-debt.md (80 Coq Axiom/Admitted + 54 Lean markers) is ESTATE/vendored scope; absolute-zero itself measures 0 Admitted + 23 Axiom as of 2026-07-29." - -[next-actions] -resolve-rsr-source-of-truth = "RESOLVED 2026-09-21: oracle normative, criteria in standards SSOT, aletheia takes the offline subset (see [open-questions].rsr-source-of-truth)" -empty-merged-prs = "#146 (ci(codeql) cron weekly->monthly) and #147 (Worktree maa ci repair) are BOTH EMPTY — git diff between parent and merge is blank. #146 stated change was already present. A merged PR title is not evidence the change happened; check git diff --stat." -soundness-axioms = "Fix or delete prob_nonneg, prob_normalized, shannon_entropy_maximum while they are still unused" -changelog-automation = "RESOLVED 2026-09-21 (#100): changelog.yml adopted (pr-back — commit-back rejected by the Optimus-Branch ruleset, zero bypass actors; caller needed actions:read on the job block — job-level replaces top-level — after three main runs startup_failed), CHANGELOG.md seeded with the exact reusable recipe, CHANGELOG.adoc frozen as a pointer" -hypatia-ignore-prune = "RESOLVED 2026-09-21 (#98): all 10 entries verified dead at the pinned submodule commit; .hypatia-ignore is a comments-only audit record, upstream residue in absolute-zero#77" -submodule-docs = "RESOLVED 2026-09-21: clone block in QUICKSTART-DEV documents `git submodule update --init`" - -[landmines] -root-only-workflows = "GitHub Actions reads .github/workflows/ at the repository ROOT ONLY. The 16 files under aletheia/.github/workflows/ are inert." -merged-pr-is-not-landed-work = "A push to a branch whose PR has ALREADY merged fires no pull_request event and produces ZERO runs, with no error. Verify by comparing each run's headSha against `git rev-parse HEAD`." -early-exit-linter = "The Governance workflow linter exits after its SPDX/permissions block, BEFORE the SHA-pin check. Fixing the first defect REVEALS the second; expect the bar to stay red." -gh-pr-checks-hides-startup-failure = "A parse-rejected or policy-rejected workflow produces NO check run at all. Use `gh run list --json conclusion`." -generic-summary-is-not-detection = "The staleness job prints 'Remove legacy scorecard-enforcer.yml' on ANY failure regardless of whether that file exists. Only ##[error] lines naming a path are real." -never-commit-dash-a = "Two separate defects reached main in one `git commit -a` (#142). Never use it in this repo." -never-allow-dead-code = "Do not silence #125 with #![allow(dead_code)]. The dead code is the specification of the missing feature, and rust-ci.yml's header forbids it." -never-restore-aletheia-from-mirror = "The in-tree copy is AHEAD — 134 tracked files vs 108, 45 in-tree only. The mirrors' only unique asset is 62 commits of history to 2026-01-03." -optimus-nch-ruleset = "main is guarded by the Optimus-Branch RULESET (not branch protection — the legacy API 404s): PR-required, signed commits, strict CodeRabbit+governance checks, code-scanning gates, ZERO bypass actors. Direct pushes fail; workflows use pr-back, humans squash-merge." -checker-unwired-until-expressiveness = "check-rsr-profile.sh reports 3 MISSING (nested aletheia/ crate vs root-anchored rust rows) + 1 VESTIGIAL (partial governance quad) — gate-format gaps, not repo defects. Do NOT wire it into CI or trim true declarations until upstream represents partial/nested modules." -setup-sh-handoff-missing = "setup.sh hands off to `just setup`, but no `setup` recipe exists in Justfile or contractile.just — the universal path is broken until someone writes it. Observed 2026-09-21." -pages-builds-stub = "pages.yml mkdirs src/ and builds a one-line stub index (README.md absent, docs/ not wired in) — enabling Pages deploys a stub, not the docs. Observed 2026-09-21." -." -ath is broken until someone writes it. Observed 2026-09-21." -pages-builds-stub = "pages.yml mkdirs src/ and builds a one-line stub index (README.md absent, docs/ not wired in) — enabling Pages deploys a stub, not the docs. Observed 2026-09-21." diff --git a/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml b/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml deleted file mode 100644 index 0dd6825..0000000 --- a/.machine_readable/6a2/anchor/0-AI-MANIFEST.a2ml +++ /dev/null @@ -1,21 +0,0 @@ -# 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/6a2/anchor/ANCHOR.a2ml b/.machine_readable/6a2/anchor/ANCHOR.a2ml deleted file mode 100644 index 9bcbb52..0000000 --- a/.machine_readable/6a2/anchor/ANCHOR.a2ml +++ /dev/null @@ -1,28 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# ANCHOR: maa-framework -# This is the canonical authority for the maa-framework repository. -# Converted from the YAML-style authority record to TOML-A2ML on 2026-06-12 -# (field content preserved); realignment entries follow estate convention. - -[metadata] -id = "org.hyperpolymath.maa-framework" -version = "1.0.0" -clade = "unknown" -status = "active" -last-updated = "2026-06-12" - -# SSG Configuration (Unified boj-server build) -[ssg] -engine = "casket" -output_dir = "public" -boj_trigger = true -cartridge = "ssg-mcp" - -[relationships] -parents = ["org.hyperpolymath.boj-server"] - -[[realignments]] -date = "2026-06-12" -what = "Estate standardization + governance checkpoint: merged estate-standardization-20260607 (6a2 manifest/README, anchors/ -> 6a2/anchor/, agent_instructions/ -> bot_directives/, flat contractiles, svc/k9 -> self-validating/, GOVERNANCE.adoc, Guix manifest.scm replacing flake.nix); cherry-picked codeql cron weekly -> monthly (standards#288); refreshed 6a2 STATE/META; wrote repo-true flat Mustfile/Trustfile/Adjustfile/Intentfile and ported nested dust/bust into flat Dustfile/Bustfile; added bot_directives trio (hypatia, gitbot-fleet, git-private-farm)." -why = "Adopt the newer estate standard (landed in echo-types main via PR #185) and bring machine-readable metadata current with the 2026-04-04..2026-06-04 work (PRs #48-#96)." -evidence = "merge of origin/estate-standardization-20260607; cherry-pick of origin/cicd/codeql-cron-monthly; git log --since=2026-04-04" diff --git a/.machine_readable/6a2/anchor/README.adoc b/.machine_readable/6a2/anchor/README.adoc deleted file mode 100644 index 13cae63..0000000 --- a/.machine_readable/6a2/anchor/README.adoc +++ /dev/null @@ -1,25 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.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/CLADE.a2ml b/.machine_readable/CLADE.a2ml deleted file mode 100644 index f8741ed..0000000 --- a/.machine_readable/CLADE.a2ml +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Clade declaration — part of the gv-clade-index registry -# See: https://github.com/hyperpolymath/gv-clade-index - -[identity] -uuid = "e22e99d9-cd00-5764-95de-5e49d7151ea3" -primary-forge = "github" -primary-owner = "hyperpolymath" -canonical-name = "maa-framework" -prefixed-name = "pt-maa-framework" - -[clade] -primary = "pt" -secondary = ["gv"] -assigned = "2026-03-16" -rationale = "" - -[forges] -github = "hyperpolymath/maa-framework" -gitlab = "hyperpolymath/maa-framework" -bitbucket = "hyperpolymath/maa-framework" - -[lineage] -type = "standalone" -parent = "Mutually Assured Accountability Framework" -born = "2026-03-16" - -# Lifecycle status (added by clade-status-backfill; see gv-clade-index ADR 0006). -# Identity (uuid) and status are SEPARATE layers: uuid is immortal; phase is a -# mutable pointer. No phase is terminal (extinct -> active is a legal "Gitassic -# Park" transition on the same uuid). A rename is NOT a phase change — the old -# prefixed-name goes to aliases[], uuid and phase are untouched. -[status] -# One of: reserved incubating active dormant | merged superseded archived extinct -phase = "active" -since = "2026-03-16" -present = true -aliases = [] -merged-into = "" -superseded-by = "" -successors = [] -ended = "" - -[[status.history]] -phase = "active" -since = "2026-03-16" -note = "backfilled default — correct if the true phase differs" diff --git a/.machine_readable/bot_directives/README.adoc b/.machine_readable/bot_directives/README.adoc deleted file mode 100644 index 96abe99..0000000 --- a/.machine_readable/bot_directives/README.adoc +++ /dev/null @@ -1,61 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Bot Directives -:toc: preamble - -Per-repo directives for automated agents, read at session start by any AI -agent (Claude, Gemini, Copilot, etc.) and by the estate's automated bots. -Renamed from `agent_instructions/` in the 2026-06 estate standardization. - -== Purpose and Precedence - -Purpose: per-repo directives for automated agents — both methodology -(how to work) and bot-specific operating rules (what each bot may do). - -Precedence: *maintainer > these directives > bot defaults.* - -Scope: applies to the Hypatia scanner, the gitbot fleet, and -`.git-private-farm` propagation. - -== Files - -[cols="1,3"] -|=== -| File | Purpose - -| `methodology.a2ml` -| Default mode, invariants, ring ceiling, priority weights, convergent budget - -| `coverage.a2ml` -| Session coverage tracking — what was visited, what was skipped, what has MUSTs - -| `debt.a2ml` -| Meander debt — things found but not fixed, carried between sessions - -| `hypatia.a2ml` -| Hypatia scanner directives: ignore-file, workflow, accepted findings, prohibited actions - -| `gitbot-fleet.a2ml` -| Fleet roster (rhodibot, echidnabot, sustainabot, glambot, seambot, finishbot), branch policy, per-bot allow/deny - -| `git-private-farm.a2ml` -| Propagation to `hyperpolymath/.git-private-farm` via `instant-sync.yml`; token-rotation runbook -|=== - -== How Agents Use These - -1. Read `methodology.a2ml` at session start — know mode, invariants, ceiling -2. Read `coverage.a2ml` — know what was visited last time, what was skipped -3. Read `debt.a2ml` — know what's outstanding from previous sessions -4. Read your bot-specific file (`hypatia.a2ml` / `gitbot-fleet.a2ml` / `git-private-farm.a2ml`) — know your allow/deny boundaries -5. At session end, update `coverage.a2ml` and `debt.a2ml` - -== Relationship to Other Files - -* `../6a2/AGENTIC.a2ml` says WHAT agents can do (permissions, gating) -* `bot_directives/` says HOW agents should work (methodology) and what each bot may do (fleet-specific) -* `.claude/CLAUDE.md` says how Claude specifically should work (Claude-specific) - -== Reference - -ADR-002 in `standards/agentic-a2ml/docs/ADR-002-methodology-layer.adoc` diff --git a/.machine_readable/bot_directives/coverage.a2ml b/.machine_readable/bot_directives/coverage.a2ml deleted file mode 100644 index 6979664..0000000 --- a/.machine_readable/bot_directives/coverage.a2ml +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# coverage.a2ml — Session coverage tracking -# Updated at the end of each AI agent session. -# Persists what was visited, what was skipped, and what has MUSTs. -# -# Reference: ADR-002 in standards/agentic-a2ml/docs/ - -[metadata] -version = "1.0.0" -last-updated = "2026-03-24" - -# ============================================================================ -# COVERAGE STATE -# ============================================================================ -# Updated by agents at session end. Tracks which components have been -# visited and which have known MUSTs that were skipped. - -[coverage] -total-components = 0 -visited-components = 0 -coverage-percent = 0 - -# ============================================================================ -# VISITED COMPONENTS -# ============================================================================ -# Component → session date + ring reached -# Agents add entries as they work through components. -# -# Example: -# [coverage.visited.emergency-room] -# date = "2026-03-23" -# ring = 2 -# fixes = 3 -# notes = "boot-guardian built, shutdown-marshal built" - -# ============================================================================ -# SKIPPED COMPONENTS WITH MUSTS -# ============================================================================ -# Components with known MUSTs that were not visited in the most recent session. -# These become P1 inputs for the next session's Phase 0. -# -# Example: -# [coverage.skipped-musts.session-sentinel] -# priority = "P0" -# issue = "56 SIGABRTs in 4 days, D-Bus race condition" -# discovered = "2026-03-23" - -# ============================================================================ -# CHERRY-PICKING AUDIT -# ============================================================================ -# At session end, agents report whether they chose easy work over hard work. -# This is the accountability mechanism for the weighted priority system. -# -# [coverage.cherry-picking] -# easy-high-completed = 3 -# hard-high-completed = 1 -# easy-low-completed = 2 -# hard-low-deferred = 4 -# assessment = "Correctly prioritised — all MUST items addressed before COULDs" diff --git a/.machine_readable/bot_directives/debt.a2ml b/.machine_readable/bot_directives/debt.a2ml deleted file mode 100644 index c0238c5..0000000 --- a/.machine_readable/bot_directives/debt.a2ml +++ /dev/null @@ -1,49 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# debt.a2ml — Meander debt list -# Things found but not fixed. Carried between sessions. -# Becomes the next session's Phase 0 input. -# -# Reference: ADR-002 in standards/agentic-a2ml/docs/ - -[metadata] -version = "1.0.0" -last-updated = "2026-03-24" - -# ============================================================================ -# DEBT ITEMS -# ============================================================================ -# Each item has: component, issue, effort (easy|medium|hard), impact (high|medium|low), -# priority (should|could), and discovered date. -# -# Items are consumed (removed) when fixed. New items are added at session end. -# The debt list prevents the "one more wave" loop — found things are persisted, -# not forgotten, and not used as justification for infinite meandering. - -# ============================================================================ -# SHOULD — would fix next wave -# ============================================================================ -# These are inputs for the next session if the user says "keep going". -# -# Example: -# [[debt.should]] -# component = "system-tools/monitoring/observatory" -# issue = "Stale duplicate of root observatory/" -# effort = "easy" -# impact = "medium" -# discovered = "2026-03-23" - -# ============================================================================ -# COULD — would fix eventually -# ============================================================================ -# These are low-priority items that don't justify a session on their own. -# They get picked up when an agent is in the area for other reasons. -# -# Example: -# [[debt.could]] -# component = "cicada" -# issue = "RSR_OUTLINE.adoc references banned AGPL-3.0" -# effort = "easy" -# impact = "low" -# discovered = "2026-03-23" diff --git a/.machine_readable/bot_directives/git-private-farm.a2ml b/.machine_readable/bot_directives/git-private-farm.a2ml deleted file mode 100644 index b45a0a9..0000000 --- a/.machine_readable/bot_directives/git-private-farm.a2ml +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# git-private-farm.a2ml — .git-private-farm propagation directives for maa-framework - -[metadata] -repo = "maa-framework" -last-updated = "2026-06-12" -owner = "hyperpolymath" - -[propagation] -enabled = true -workflow = ".github/workflows/instant-sync.yml" # present; fires on push to main/master and on published releases -target = "hyperpolymath/.git-private-farm" -event-type = "propagate" -secret-name = "FARM_DISPATCH_TOKEN" # secret NAME only — value lives in GitHub Actions secrets -presence-gated = false # the dispatch step runs unconditionally; no `if:` presence gate on the secret in the current workflow - -[never-propagate] -items = ["secrets", "unmerged branches", "work-in-progress"] - -[on-token-rotation] -command = "gh secret set FARM_DISPATCH_TOKEN --repo hyperpolymath/maa-framework" # name only; paste the new value when prompted diff --git a/.machine_readable/bot_directives/gitbot-fleet.a2ml b/.machine_readable/bot_directives/gitbot-fleet.a2ml deleted file mode 100644 index c2d6f19..0000000 --- a/.machine_readable/bot_directives/gitbot-fleet.a2ml +++ /dev/null @@ -1,55 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# gitbot-fleet.a2ml — gitbot fleet directives for maa-framework -# Per-repo directives for the hyperpolymath gitbot fleet. - -[metadata] -repo = "maa-framework" -last-updated = "2026-06-12" -owner = "hyperpolymath" - -[fleet] -bots = ["rhodibot", "echidnabot", "sustainabot", "glambot", "seambot", "finishbot"] -rhodibot = "git operations" -echidnabot = "code quality" -sustainabot = "dependency updates" -glambot = "documentation" -seambot = "integration" -finishbot = "task completion" - -[branch-policy] -working-branch-pattern = "bot//" -draft-PRs-only = true -ci-green-before-merge = true -never-touch = [ - ".claude/CLAUDE.md", - ".gitmodules", - "absolute-zero", # submodule pointer — bumps are deliberate human acts (PR #89) - ".github/workflows/", - "LICENSE", - "LICENSES/", -] - -[per-bot.rhodibot] -allow = ["branch create", "rebase of own bot branches"] -deny = ["submodule pointer bumps", "force-push to shared branches"] - -[per-bot.sustainabot] -allow = ["dependency-update PRs for aletheia/Cargo.toml"] -deny = ["GitHub Actions version bumps"] -note = "Actions bumps are handled by dependabot in this repo (see PRs #59-#69, #92-#96); duplicating them creates conflicting PRs." - -[per-bot.echidnabot] -allow = ["lint/format suggestions on aletheia/ and tests/"] -deny = ["edits under .machine_readable/ without maintainer review"] - -[per-bot.glambot] -allow = ["docs/ and README/EXPLAINME currency fixes as draft PRs"] -deny = ["governance docs (GOVERNANCE.adoc, MAINTAINERS.adoc) edits"] - -[per-bot.seambot] -allow = ["integration metadata under .machine_readable/integrations/"] -deny = ["workflow wiring changes"] - -[per-bot.finishbot] -allow = ["closing checklists, marking task completion in PR descriptions"] -deny = ["merging PRs (humans merge after CI green)"] diff --git a/.machine_readable/bot_directives/hypatia.a2ml b/.machine_readable/bot_directives/hypatia.a2ml deleted file mode 100644 index c310722..0000000 --- a/.machine_readable/bot_directives/hypatia.a2ml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# hypatia.a2ml — Hypatia scanner directives for maa-framework -# Per-repo directives for the Hypatia security/policy scanner. - -[metadata] -repo = "maa-framework" -last-updated = "2026-09-21" -owner = "hyperpolymath" - -[scanner] -ignore-file = ".hypatia-ignore" # present at repo root -workflow = ".github/workflows/hypatia-scan.yml" # thin wrapper of hyperpolymath/standards hypatia-scan-reusable.yml (standards#191), weekly cron + push/PR -report-format = "logtalk" # per 6a2/NEUROSYM.a2ml [hypatia-config] - -[accepted-findings] -# No active exemptions (2026-09-21, issue #98): the 10 mirrored -# banned_language_file entries were pruned after verifying every path dead -# at the pinned absolute-zero commit. Upstream residue is tracked in the -# owning repo (hyperpolymath/absolute-zero#77). standards#180 has merged, -# so file_pattern globs are available if per-file exemptions ever return. - -[prohibited-actions] -auto-delete-branches = false -auto-merge = false -modify-workflows = false -escalation = "open an issue, do not spam PR comments" diff --git a/.machine_readable/bot_directives/methodology.a2ml b/.machine_readable/bot_directives/methodology.a2ml deleted file mode 100644 index 754f357..0000000 --- a/.machine_readable/bot_directives/methodology.a2ml +++ /dev/null @@ -1,107 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# methodology.a2ml — AI agent methodology configuration -# Declares how agents should approach work in this repository. -# Read at session start by any AI agent (Claude, Gemini, Copilot, etc.) -# -# Reference: ADR-002 in standards/agentic-a2ml/docs/ - -[metadata] -version = "1.0.0" -last-updated = "2026-03-24" -spec = "https://github.com/hyperpolymath/standards/blob/main/agentic-a2ml/docs/ADR-002-methodology-layer.adoc" - -# ============================================================================ -# MODE SELECTION -# ============================================================================ -# convergent: find gaps, fill them, build infrastructure (default for ops/infra) -# divergent: find what's strongest, push it further (for research/creative) -# hybrid: audit 20% of budget, then focus 80% on top MUSTs (default for most) - -[methodology] -default-mode = "hybrid" -ring-ceiling = 2 # Hard ceiling for ring expansion (0-3) -wave-cap = 2 # Max waves before requiring user "keep going" -spike-required = true # Every session must ship code, not just designs - -# ============================================================================ -# PRIORITY WEIGHTS -# ============================================================================ -# MUST (3x): Blocking the current work → fix immediately -# SHOULD (2x): Degrading quality of current work → fix if in zone -# COULD (1x): Improving quality of adjacent work → add to debt list - -[methodology.priority-weights] -must = 3 -should = 2 -could = 1 - -# ============================================================================ -# CONVERGENT BUDGET (when mode = convergent or hybrid) -# ============================================================================ -# How to allocate effort across work types. -# Prevents over-polishing docs while structural work waits. - -[methodology.convergent-budget] -structural = 70 # % for new modules, compilation fixes, wiring, integration -corrective = 20 # % for bugs found, broken imports, stale references -perfective = 10 # % for SPDX headers, doc updates, formatting, style - -# ============================================================================ -# UNIQUE STRENGTH (when mode = divergent) -# ============================================================================ -# What makes this project special. Agents should DEEPEN this, not broaden it. -# Customise this per project — the template default is generic. - -[methodology.unique-strength] -description = "{{PROJECT_UNIQUE_STRENGTH}}" -deepen-not-broaden = true - -# ============================================================================ -# DIVERGENT INVARIANTS -# ============================================================================ -# Constraints that divergent mode must NOT violate. -# These are the riverbanks — diverge within them, not across. -# "Amplify uniqueness" means deepen, not broaden. -# -# Test before any divergent action: -# "Does this deepen the existing strength, or add a parallel strength?" -# If parallel → stop. Note as cross-project insight. - -[methodology.divergent-invariants] -rules = [ - # Customise per project. Examples: - # "Idris2 only for formal verification — no Lean4, Coq, Agda", - # "believe_me count must remain zero", - # "FFI architecture: Idris2 → RefC → Zig → C ABI (no shortcuts)", -] - -# Optional: language invariant for the core strength -# If set, divergent mode will not introduce other languages for this purpose -# language-invariant = "idris2" - -# ============================================================================ -# CONSTRAINT HINTS -# ============================================================================ -# Help Phase 0 find the critical chain faster. -# Updated at session end with newly discovered constraints. - -[methodology.known-constraints] -constraints = [ - # Customise per project. Examples: - # "End-to-end build has never been verified", - # "libproject.so does not exist yet — all bindings call stubs", -] - -# ============================================================================ -# STATE FILE VALIDATION -# ============================================================================ -# Phase 0 reads STATE.a2ml first but it may be broken. -# These rules detect corrupt/template/stale state files. - -[methodology.state-validation] -reject-if-contains = ["{{PLACEHOLDER}}", "{{PROJECT}}", "rsr-template-repo"] -reject-if-project-name-mismatch = true -staleness-threshold-days = 90 -fallback-files = ["TODO.md", "TODO.adoc", "ROADMAP.adoc", "README.adoc"] diff --git a/.machine_readable/contractiles/Adjustfile.a2ml b/.machine_readable/contractiles/Adjustfile.a2ml deleted file mode 100644 index fe3a810..0000000 --- a/.machine_readable/contractiles/Adjustfile.a2ml +++ /dev/null @@ -1,126 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Adjustfile — Drift-tolerance and accessibility contract for maa-framework -# Author: Jonathan D.A. Jewell -# -# Cumulative-drift catchment (tolerance bands + corrective actions) PLUS the -# accessibility invariants. Authority: advisory (Yard) — continue-with-warnings; -# auto_fix where deterministic. Unlike MUST (hard gate), ADJUST warns and -# trends; it does not block — except that accessibility invariants are -# implicitly MUST per the contractile family rules. -# -# Provenance: rewritten 2026-06-12 (governance checkpoint). The accessibility -# section ports the former root .machine_readable/ADJUST.contractile -# ("Accessibility & Digital Justice for Universal Software & Technology", -# WCAG 2.2 AA, removed by the estate-standardization merge); the drift -# section adapts the estate Adjustfile shape to maa-framework reality. - -[metadata] -repo = "maa-framework" -version = "2.0.0" -format = "a2ml" -last-updated = "2026-06-12" -accessibility-standard = "WCAG-2.2-AA" -accessibility-full-name = "Accessibility & Digital Justice for Universal Software & Technology" - -[documentation-drift] -readme-completeness = { description = "README documents the repo's actual contents (aletheia/, absolute-zero submodule, governance layer)", tolerance = "no claims contradicted by the tree", corrective = "update README.adoc sections", severity = "advisory" } -example-accuracy = { description = "code examples in docs match actual content", tolerance = "all examples accurate", corrective = "audit and fix examples (EXPLAINME.adoc receipts)", severity = "advisory" } -roadmap-currency = { description = "ROADMAP.adoc status reflects landed work", tolerance = "status note current within one checkpoint", corrective = "refresh Current Status note", severity = "advisory" } - -[structural-drift] -no-broken-symlinks = { description = "no broken symbolic links", tolerance = "0 broken symlinks", corrective = "remove or re-point", severity = "advisory" } -submodule-pointer-current = { description = "absolute-zero submodule pointer should not lag upstream by more than a release", tolerance = "pointer within one upstream release", corrective = "deliberate pointer bump PR", severity = "advisory" } -changelog-sync = { description = "CHANGELOG.md tracks conventional commits", tolerance = "Unreleased section current", corrective = "adopt changelog-reusable.yml (standards#206)", severity = "advisory" } - -[style-drift] -adoc-not-md = { description = "prose docs prefer AsciiDoc", tolerance = "new prose docs are *.adoc", corrective = "convert new *.md to *.adoc", severity = "advisory" } -spdx-header-consistency = { description = "all files have SPDX-License-Identifier headers", tolerance = "0 files missing headers", corrective = "add headers per format comment style", severity = "advisory" } - -[accessibility.visual] -invariants = [ - "colour-contrast-ratio >= 4.5:1 for normal text", - "colour-contrast-ratio >= 3:1 for large text (18pt+ or 14pt+ bold)", - "no information conveyed by colour alone", - "no flashing or strobing content (3 flashes/second max)", - "text resizable to 200% without loss of content or function", - "focus indicators visible on all interactive elements", -] - -[accessibility.keyboard] -invariants = [ - "all interactive elements reachable via keyboard (Tab/Shift+Tab)", - "no keyboard traps — user can always Tab away", - "skip navigation link present on pages with repeated blocks", - "logical focus order follows visual reading order", -] - -[accessibility.screen-reader] -invariants = [ - "all images have meaningful alt text (or alt='' if decorative)", - "all form inputs have associated labels", - "ARIA landmarks used for page regions (main, nav, banner, etc.)", - "dynamic content updates announced via aria-live regions", - "semantic HTML used (headings, lists, tables) — not div soup", -] - -[accessibility.interactive] -invariants = [ - "touch targets minimum 44x44px on mobile/touch interfaces", - "error messages identify the field and describe the error", - "error messages not conveyed by colour or position alone", - "form validation provides suggestions for correction", -] - -[accessibility.media] -invariants = [ - "video has captions (closed or open)", - "audio-only content has text transcript", - "no autoplay of media with sound", -] - -[accessibility.motion] -invariants = [ - "animations respect prefers-reduced-motion media query", - "no content depends on motion to convey meaning", -] - -[accessibility.cli-tui] -invariants = [ - "CLI output must not rely solely on colour (use symbols: [OK] [FAIL])", - "TUI must support high-contrast mode", - "all CLI commands support --help with plain-text output", - "error messages written in plain language, not jargon or codes alone", -] - -[accessibility.documentation] -invariants = [ - "docs use clear language, short sentences, logical structure", - "code examples include comments explaining non-obvious steps", - "diagrams have text descriptions or alt text", -] - -[accessibility.i18n] -invariants = [ - "all user-facing strings externalisable for translation", - "no hardcoded English in error messages — use message keys", - "date/time/number formats locale-aware", - "RTL (right-to-left) layout support where applicable", - "Unicode handled correctly throughout (UTF-8 everywhere)", -] - -[accessibility.related-resources] -lol = "standards/lol — multilingual NLP corpus (linguistic data, translation coverage, i18n validation)" -polyglot-i18n = "polyglot-i18n — i18n framework and WASM translation engine" - -[accessibility.enforcement] -ci = "accessibility linting in the estate quality workflow where a web UI exists" -pr-block = "PR blocked if accessibility regression detected" -tools = ["axe-core or pa11y for automated checks on web UI", "CLI output inspected for colour-only signalling"] -manual = "manual screen reader test before major releases" - -[accessibility.notes] -text = [ - "These are MINIMUM requirements. Exceeding them (AAA) is encouraged.", - "When in doubt about an accessibility decision, ask — don't guess.", - "Accessibility is not optional polish — it is a structural requirement.", -] diff --git a/.machine_readable/contractiles/Bustfile.a2ml b/.machine_readable/contractiles/Bustfile.a2ml deleted file mode 100644 index d3d2a2f..0000000 --- a/.machine_readable/contractiles/Bustfile.a2ml +++ /dev/null @@ -1,46 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Bustfile — Breakage / rollback contract for maa-framework -# Author: Jonathan D.A. Jewell -# -# BUST defines what to do when something breaks: named failure scenarios -# with their rollback procedures, the escalation ladder, and durable -# backup points. -# -# Provenance: created 2026-06-12 (governance checkpoint), porting the former -# nested .machine_readable/contractiles/bust/Bustfile.a2ml (Nickel-style -# record, removed by the estate-standardization merge) into TOML-A2ML in -# the flat estate layout. Content unchanged in substance; it is if anything -# MORE accurate post-PR #89, since absolute-zero/ is now a real submodule. - -[metadata] -repo = "maa-framework" -version = "2.0.0" -format = "a2ml" -last-updated = "2026-06-12" -description = "Rollback procedures when something breaks in the meta-repo" - -[scenarios] -bad-pointer-bump = "git revert in meta-repo; child repo itself untouched" -submodule-pointer-points-at-missing-sha = "git submodule update --init --checkout resets child to parent-recorded SHA; OR revert the stale bump commit" -submodule-orphan-after-local-only-commit = "roll back locally with git reset to before the stranded commit; fix remote situation before re-attempting" -accidental-private-repo-content-leaked-to-public-submodule = "hard-rotate the leaked secret immediately; git-filter-repo or BFG on the submodule's own history; public re-publication only after rotation complete" -bad-estate-merge = "git revert -m 1 on the meta-repo branch; re-attempt with path-level conflict resolution toward origin/main" - -[escalation-ladder] -steps = [ - "1. revert the meta-repo commit (reversible, low blast radius)", - "2. reset the local submodule clone (affects only local workspace)", - "3. force-push to main — PROHIBITED without explicit user confirmation (violates branch protection)", - "4. registry-level (delete/archive the GitHub repo) — human-only action, never by AI", -] - -[backup-points] -points = [ - "GitHub serves as the durable backup for every submodule's own history", - "Meta-repo history on origin/main is the durable backup for pointer state", - "Local backup tags (backup/pre--) retained on risky rewrites", -] - -[not-applicable] -database-restore = { status = "not-applicable", reason = "no databases or stateful services in this repo" } -deployment-rollback = { status = "not-applicable", reason = "nothing is deployed from this repo; it is a governance + source monorepo" } diff --git a/.machine_readable/contractiles/Dustfile.a2ml b/.machine_readable/contractiles/Dustfile.a2ml deleted file mode 100644 index 8ff6bfb..0000000 --- a/.machine_readable/contractiles/Dustfile.a2ml +++ /dev/null @@ -1,82 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Dustfile — Cleanup, hygiene and deprecation contract for maa-framework -# Author: Jonathan D.A. Jewell -# -# DUST tracks what is being swept away: cleanup policy, hygiene rules, and -# the deprecation register. When a feature enters DUST, its MUST constraints -# remain active until the feature is fully removed. -# -# Provenance: created 2026-06-12 (governance checkpoint), porting the former -# nested .machine_readable/contractiles/dust/Dustfile.a2ml (removed by the -# estate-standardization merge) into the flat estate layout, extended with -# the repo's real deprecation register from git history. - -[metadata] -repo = "maa-framework" -version = "2.0.0" -format = "a2ml" -last-updated = "2026-06-12" - -[cleanup] -stale-branch-policy = "delete-after-merge" -artifact-retention = "90-days" -cache-policy = "clear-on-release" - -[hygiene] -linting = "required" -formatting = "required" -dead-code-removal = "encouraged" -todo-tracking = "tracked-in-issues" - -[reversibility] -backup-before-destructive = true -rollback-mechanism = "git-revert" -data-retention-policy = "preserve-30-days" - -# ── Deprecation register (real, dated, from git history) ────────────── - -[[deprecations]] -name = "rescript-guidance" -status = "removed" -date = "2026-05" -evidence = "PRs #53 (Item 9 guidance retirement), #74 (SafeDOMExample.res fixture deleted), #88 (CLAUDE.md flip)" -replacement = "AffineScript per the 2026-05-25 estate language policy" -residue = "RESOLVED 2026-09-21 (#98): .hypatia-ignore pruned to a comments-only audit record; upstream residue tracked in hyperpolymath/absolute-zero#77" - -[[deprecations]] -name = "pmpl-license" -status = "removed" -date = "2026-05" -evidence = "commit e4e3db0 — migrate license from PMPL-1.0-or-later to MPL-2.0" -replacement = "MPL-2.0" - -[[deprecations]] -name = "vendored-absolute-zero-subtree" -status = "removed" -date = "2026-05" -evidence = "PR #83 (re-vendor to upstream HEAD) then PR #89 (convert to git submodule, closes #84)" -replacement = "absolute-zero/ git submodule pinned to hyperpolymath/absolute-zero" - -[[deprecations]] -name = "flake-nix" -status = "removed" -date = "2026-06-12" -evidence = "estate-standardization-20260607 merge removed flake.nix and aletheia/flake.{nix,lock}" -replacement = "Guix manifest.scm (aletheia/manifest.scm, aletheia/extraction/rhodibot/manifest.scm) alongside guix.scm" - -[[deprecations]] -name = "pre-estate-machine-readable-layout" -status = "removed" -date = "2026-06-12" -evidence = "estate-standardization-20260607 merge: root *.contractile files and nested contractiles/{bust,dust,trust}/ replaced by flat contractiles/; agent_instructions/ -> bot_directives/; svc/k9/ -> self-validating/; anchors/ -> 6a2/anchor/" -replacement = "flat estate layout; content ported into Mustfile/Trustfile/Adjustfile/Dustfile/Bustfile.a2ml" - -[[deprecations]] -name = "per-repo-ci-workflow-copies" -status = "removed" -date = "2026-05" -evidence = "PRs #52/#54/#73 (hypatia-scan), #76 (mirror), #77 (secret-scanner), #80 (scorecard), commit 8f03d8d (governance bundle)" -replacement = "thin wrappers around hyperpolymath/standards reusable workflows" - -[not-applicable] -runtime-data-purging = { status = "not-applicable", reason = "no runtime services or user data in this repo; it is a governance + microkernel-source monorepo" } diff --git a/.machine_readable/contractiles/Intentfile.a2ml b/.machine_readable/contractiles/Intentfile.a2ml deleted file mode 100644 index c7e7374..0000000 --- a/.machine_readable/contractiles/Intentfile.a2ml +++ /dev/null @@ -1,100 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Intentfile (A2ML Canonical) — north-star contractile for maa-framework -# Author: Jonathan D.A. Jewell -# -# Semantics: north-star contractile. Declares BOTH concrete committed -# next-actions AND horizon aspirations: -# [[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 -# horizon: near / mid / far -# Non-gating — this is a report, not a gate. See Mustfile.a2ml for hard gates. -# -# Provenance: written 2026-06-12 (governance checkpoint) from README.adoc, -# EXPLAINME.adoc and ROADMAP.adoc. The former root INTENT.contractile's -# purpose/anti-purpose fields were unfilled {{...}} placeholders, so no -# repo-specific content existed there to port; this file supplies the real -# purpose for the first time. - -[metadata] -repo = "maa-framework" -version = "2.0.0" -format = "a2ml" -last-updated = "2026-06-12" - -[purpose] -text = """ -Hub and governance centre for the MAA Framework: a full-stack, open-source -paradigm for building verifiably-compliant, secure, and sustainable systems. -The monorepo coordinates three components — the MAA Framework itself (the -paradigm and governance rules), Oblibeny (the reference language, developed -in its own repo), and Aletheia (the microkernel trusted execution base, -in-tree under aletheia/). The formal anchor is the Certified Null Operation -(CNO) in absolute-zero/ (git submodule): every system operation must have a -well-defined inverse whose composition with the operation is provably -equivalent to the CNO. -""" - -[anti-purpose] -text = [ - "NOT a single deployable binary — the components are coordinated design decisions, not one artifact", - "NOT the home of the Oblibeny language — that lives in hyperpolymath/oblibeny", - "NOT the home of CNO development — absolute-zero/ is a pinned submodule; changes go upstream", - "NOT a general-purpose project template — rsr-template-repo serves that role", -] - -[if-in-doubt] -ask-before-touching = [ - ".machine_readable/ contractile definitions", - "governance documents (GOVERNANCE.adoc, MAINTAINERS.adoc, CODEOWNERS)", - "the absolute-zero submodule pointer", - "license policy documents", -] - -[[intents]] -name = "phase-1-specification" -description = "Upload MAA Framework specification documents; document Aletheia architecture; define API boundaries (ROADMAP Phase 1)" -status = "declared" - -[[intents]] -name = "changelog-automation" -description = "Adopt changelog-reusable.yml (standards#206) so CHANGELOG.md stays in sync with conventional commits" -status = "done" -notes = "Closed #100 on 2026-09-21: changelog.yml (pr-back — Optimus-Branch ruleset rejects direct pushes), CHANGELOG.md seeded, CHANGELOG.adoc frozen as pointer" - -[[intents]] -name = "root-justfile-wiring" -description = "Wire root Justfile build/test/fmt/lint recipes to the real aletheia/ cargo targets (currently placeholders)" -status = "done" -notes = "Wired in #144 (closes #99); canonicalised in #102 (contractiles stub is now a forwarding shim); lint is -D warnings since #125" - -[[intents]] -name = "crg-c-compliance" -description = "CRG Tier C: unit + smoke + build + P2P + E2E + reflexive + contract + aspect + benchmarks" -status = "done" -notes = "Achieved 2026-04-04; see 6a2/STATE.a2ml [crg-compliance]" - -[[intents]] -name = "estate-standardization" -description = "Adopt the estate-standardization layout (6a2 manifest, flat contractiles, bot_directives, self-validating, GOVERNANCE.adoc, Guix manifest.scm)" -status = "done" -notes = "Merged 2026-06-12 from estate-standardization-20260607" - -[[wishes]] -name = "toolchain-bootstrap" -description = "Oblibeny lexer/parser, initial type system, REPL, Guix/Nix build integration (ROADMAP Phase 2)" -horizon = "mid" -status = "declared" - -[[wishes]] -name = "proof-debt-zero" -description = "Eliminate recorded proof debt (docs/proof-debt.md: Coq Axiom/Admitted + Lean sorry markers in vendored/submodule scope)" -horizon = "mid" -status = "declared" - -[[wishes]] -name = "risc-v-support" -description = "Aletheia on open RISC-V hardware with minimal trusted computing base" -horizon = "far" -status = "declared" diff --git a/.machine_readable/contractiles/Justfile b/.machine_readable/contractiles/Justfile deleted file mode 100644 index ca47c23..0000000 --- a/.machine_readable/contractiles/Justfile +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# SHIM — do not add recipes here. -# -# Issue #102 decision: the canonical Justfile lives at the repo root. This -# estate-supplied path used to carry its own recipe bodies, which drifted -# into fake gates (build/test/fmt/lint/clean that echo "not configured yet" -# and exit 0 — the exact failure mode of issue #99). It now forwards -# everything to the root Justfile: the import re-exports root's recipes and -# the working-directory override executes them at the root, so -# `just -f .machine_readable/contractiles/Justfile ` behaves exactly -# like `just ` from the root (verified from root, contractiles/ and -# unrelated cwd). New recipes belong in the root Justfile, full stop. -# -# Scoped Justfiles that are NOT duplicates (each owns a different tree): -# Justfile (root) canonical, wired to rust-ci.yml -# aletheia/Justfile aletheia crate (run from aletheia/) -# aletheia/extraction/rhodibot/Justfile rhodibot crate (run from rhodibot/) -# absolute-zero/Justfile upstream-owned (submodule, untouched) -set working-directory := "../../" -import "../../Justfile" diff --git a/.machine_readable/contractiles/Mustfile.a2ml b/.machine_readable/contractiles/Mustfile.a2ml deleted file mode 100644 index ce5fe39..0000000 --- a/.machine_readable/contractiles/Mustfile.a2ml +++ /dev/null @@ -1,94 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Mustfile — Physical-state contract for maa-framework -# Author: Jonathan D.A. Jewell -# -# What MUST be true about this repository. Hard requirements — violating -# a MUST is always a bug; there are no "soft" MUSTs. CI and pre-commit -# hooks fail if any check fails. -# -# Provenance: written 2026-06-12 from repo reality, porting the universal -# invariants of the former root .machine_readable/MUST.contractile -# (S-expression form, removed by the estate-standardization merge) into -# the flat estate contractile layout. Relationship to the other -# contractiles is unchanged: TRUST never overrides MUST; ADJUST invariants -# are implicitly MUST; DUST-deprecated features keep their MUSTs until -# fully removed. - -[metadata] -repo = "maa-framework" -version = "2.0.0" -format = "a2ml" -last-updated = "2026-06-12" - -[file-presence] -# Each check: shell command that must exit 0. severity: critical | warning -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 = "root 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-flat = { description = "flat contractile files exist (estate layout)", 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 && test -f .machine_readable/contractiles/Dustfile.a2ml && test -f .machine_readable/contractiles/Bustfile.a2ml", severity = "critical" } -six-directory-present = { description = "6a2 directory exists with all six 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" } -anchor-directory = { description = "anchor directory exists in 6a2 (estate layout)", run = "test -d .machine_readable/6a2/anchor", severity = "warning" } -self-validating-structure = { description = "self-validating directory has templates and examples", run = "test -d .machine_readable/self-validating && test -d .machine_readable/self-validating/examples", severity = "warning" } -bot-directives-present = { description = "bot_directives directory with hypatia/gitbot-fleet/git-private-farm directives", run = "test -f .machine_readable/bot_directives/hypatia.a2ml && test -f .machine_readable/bot_directives/gitbot-fleet.a2ml && test -f .machine_readable/bot_directives/git-private-farm.a2ml", severity = "warning" } -submodule-recorded = { description = "absolute-zero/ stays a recorded git submodule (PR #89)", run = "git config -f .gitmodules submodule.absolute-zero.url", severity = "critical" } - -[universal-invariants] -# Ported from the former root MUST.contractile. Statement-form invariants -# enforced by review, hypatia scan, and the estate CI bundle. -paths = [ - "no hardcoded absolute paths (/home/*, /mnt/*, /var/mnt/*)", - "all paths use env vars, XDG dirs, or relative references", -] -language-policy = [ - "no new TypeScript files", - "no new Python files", - "no new Go files", - "no npm/bun/yarn/pnpm dependencies — Deno only", -] -dangerous-patterns = [ - "no believe_me (Idris2)", - "no assert_total (Idris2)", - "no Admitted (Coq)", - "no sorry (Lean)", - "no unsafeCoerce (Haskell)", - "no Obj.magic (OCaml)", - "no unsafe {} blocks without safety comment (Rust)", -] -license = [ - "SPDX-License-Identifier header on every source file", - "no removal or modification of LICENSE file", -] -structure = [ - ".machine_readable/ directory preserved", - "0-AI-MANIFEST.a2ml preserved", - "no SCM files in repo root — only in .machine_readable/", -] -ci = [ - "no removal of CI workflows without explicit approval", - "all GitHub Actions SHA-pinned", -] -code-quality = [ - "tests must not be deleted or weakened", - "generated code in generated/ directory only", - "no introduction of OWASP top 10 vulnerabilities", -] -abi-ffi = [ - "no modification of ABI contracts without proof update", - "no removal of formal verification proofs", -] - -[project-specific-invariants] -submodule = "absolute-zero/ is a pinned submodule — never re-inline it as a subtree; bump the pointer instead" -proof-debt = "docs/proof-debt.md entries may shrink but must not silently grow (standards#203 schema)" - -[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" } - -[enforcement] -ci = "estate CI bundle (governance.yml, dogfood-gate.yml) + hypatia-scan.yml run on every PR" -hooks = "pre-commit hooks fail on MUST violations where configured" diff --git a/.machine_readable/contractiles/Trustfile.a2ml b/.machine_readable/contractiles/Trustfile.a2ml deleted file mode 100644 index 793928a..0000000 --- a/.machine_readable/contractiles/Trustfile.a2ml +++ /dev/null @@ -1,87 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Trustfile — Trust boundaries and integrity invariants for maa-framework -# 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. -# -# Provenance: rewritten 2026-06-12 (governance checkpoint), combining the -# trust-level definitions of the former root .machine_readable/TRUST.contractile -# with the integrity invariants of the former nested -# contractiles/trust/Trustfile.a2ml (both removed by the -# estate-standardization merge). Trust never overrides MUST: even -# maximal-trust agents cannot violate Mustfile invariants. - -[metadata] -repo = "maa-framework" -version = "2.0.0" -format = "a2ml" -last-updated = "2026-06-12" - -[trust] -level = "maximal" -boundary = "repo" # agent confined to this repo unless explicitly told otherwise - -[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" - -[trust.actions] -# Allowed freely at maximal trust: -allowed = [ - "read", # read any file in the repo - "build", # run build commands - "test", # run test suites - "lint", # run linters and formatters - "format", # auto-format code - "doctor", # run self-diagnostics (just doctor) - "heal", # attempt automatic repair (just heal) - "git-status", - "git-diff", - "git-log", -] -# Always require human approval: -denied = [ - "delete-branch", # could lose work - "force-push", # overwrites history - "modify-ci-secrets", # security sensitive - "publish", # external visibility - "push-to-main", # protected branch - "delete-files-bulk", # more than 5 files at once - "modify-license", # legal implications - "modify-security-policy", # security implications - "remove-proofs", # formal verification regression - "disable-ci-checks", # safety regression - "bump-submodule-pointer", # absolute-zero/ pointer moves are deliberate acts -] - -[trust.sensitive-areas] -# Changes here require explicit approval regardless of trust level. -areas = [ - ".machine_readable/", - ".claude/CLAUDE.md", - "GOVERNANCE.adoc", - "MAINTAINERS.adoc", - ".github/CODEOWNERS", - ".github/workflows/", - ".gitmodules", -] - -[integrity.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 (*.pem, *.key, id_rsa, id_ed25519) committed", severity = "critical" } -no-tokens-in-source = { description = "no hardcoded API keys/secrets/tokens/passwords in source", severity = "critical" } - -[integrity.provenance] -author-correct = { description = "git author matches expected identity (hyperpolymath / j.d.a.jewell)", severity = "warning" } -license-content = { description = "LICENSE contains the MPL-2.0 text (estate migration, commit e4e3db0)", run = "grep -q 'Mozilla Public License' LICENSE", severity = "warning" } - -[integrity.container] -container-images-pinned = { description = "Containerfile uses pinned base images (cgr.dev or @sha256:)", severity = "warning" } -no-dockerfile = { description = "no Dockerfile (use Containerfile)", run = "test ! -f Dockerfile", severity = "warning" } - -[integrity.supply-chain] -actions-sha-pinned = { description = "GitHub Actions pinned to full SHAs (dependabot keeps them current)", severity = "critical" } -secret-names-only = { description = "workflow files reference secret NAMES only (e.g. FARM_DISPATCH_TOKEN), never values", severity = "critical" } diff --git a/.machine_readable/integrations/feedback-o-tron.a2ml b/.machine_readable/integrations/feedback-o-tron.a2ml deleted file mode 100644 index 5381604..0000000 --- a/.machine_readable/integrations/feedback-o-tron.a2ml +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Feedback-o-Tron Integration — Autonomous Bug Reporting - -[integration] -name = "feedback-o-tron" -type = "bug-reporter" -repository = "https://github.com/hyperpolymath/feedback-o-tron" - -[reporting-config] -platforms = ["github", "gitlab", "bugzilla"] -deduplication = true -audit-logging = true -auto-file-upstream = "on-external-dependency-failure" diff --git a/.machine_readable/integrations/proven.a2ml b/.machine_readable/integrations/proven.a2ml deleted file mode 100644 index 9af33ff..0000000 --- a/.machine_readable/integrations/proven.a2ml +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Proven Integration — Formally Verified Safety Library - -[integration] -name = "proven" -type = "safety-library" -repository = "https://github.com/hyperpolymath/proven" -version = "1.2.0" - -[binding-policy] -approach = "thin-ffi-wrapper" -unsafe-patterns = "replace-with-proven-equivalent" -modules-available = ["SafeMath", "SafeString", "SafeJSON", "SafeURL", "SafeRegex", "SafeSQL", "SafeFile", "SafeTemplate", "SafeCrypto"] - -[adoption-guidance] -priority = "high" -scope = "all-string-json-url-crypto-operations" -migration = "incremental — replace unsafe patterns as encountered" diff --git a/.machine_readable/integrations/verisimdb.a2ml b/.machine_readable/integrations/verisimdb.a2ml deleted file mode 100644 index 164c522..0000000 --- a/.machine_readable/integrations/verisimdb.a2ml +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# VeriSimDB Feed — Cross-Repo Analytics Data Store - -[integration] -name = "verisimdb" -type = "data-feed" -repository = "https://github.com/hyperpolymath/nextgen-databases" -data-store = "verisimdb-data" - -[feed-config] -emit-scan-results = true -emit-build-metrics = true -emit-dependency-graph = true -format = "hexad" -destination = "verisimdb-data/feeds/" diff --git a/.machine_readable/integrations/vexometer.a2ml b/.machine_readable/integrations/vexometer.a2ml deleted file mode 100644 index 238b3d2..0000000 --- a/.machine_readable/integrations/vexometer.a2ml +++ /dev/null @@ -1,18 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Vexometer Integration — Irritation Surface Analysis - -[integration] -name = "vexometer" -type = "friction-measurement" -repository = "https://github.com/hyperpolymath/vexometer" - -[measurement-config] -dimensions = 10 -emit-isa-reports = true -lazy-eliminator = true -satellite-interventions = true - -[hooks] -cli-tools = "measure-on-error" -ui-panels = "measure-on-interaction" -build-failures = "measure-on-failure" diff --git a/.machine_readable/rsr-profile.a2ml b/.machine_readable/rsr-profile.a2ml index fefc395..1011374 100644 --- a/.machine_readable/rsr-profile.a2ml +++ b/.machine_readable/rsr-profile.a2ml @@ -1,31 +1,16 @@ # SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for maa-framework. Declares what this repo -# carries so the capability gates (template-capability-gates.toml v0.3.0) -# compute the applicable criterion set. Direct declaration (the policy's -# primary form) — no preset fits exactly (rust-cli would add `library`, -# and aletheia is binary-only). [canon] omitted: only canon-bearing repos -# declare it, and none of the four canon criteria pass here. Role -# omitted: this repo is neither spine nor canon. +# RSR capability profile for proofgateway. Declares what this repo +# carries so the capability gates compute the applicable criterion set. [profile] -capabilities = ["rust", "bash", "cli", "docs-site"] +capabilities = ["rust", "cli", "docs"] [rationale] -# One line per declared capability and per declined module (policy shape). -rust = "FORCED + true: rust-ci.yml fires the rust gate; aletheia is a Rust 2021 crate (MSRV 1.80)" -bash = "true: 6 tracked *.sh (setup.sh, .github/hooks/, aletheia/scripts/) + bash-shebang Just recipes; no criterion gates on bash today" -cli = "true: aletheia is a binary-only CLI" -docs-site = "true: pages.yml Ddraig pipeline present (builds a stub index; docs/ not wired in); DEPLOYMENT DISABLED (see STATE) so gold 9.1.4 is carried-but-not-served" -no-library = "binary-only; no lib target, no published crate" -no-governance-tier = "PARTIAL QUAD: MAINTAINERS.adoc + root GOVERNANCE.adoc only; AUDIT.adoc + AFFIRMATION.adoc absent and 2.1.8 wants 0-canon/GOVERNANCE.adoc — declaring would fail Silver/Gold criteria it cannot pass" -no-reproducible-build = "manifest.scm (+ stapeln.toml) ship, but gates v0.3.0 + criterion 1.2.1 only recognise guix.scm — filed upstream" -no-container = "stapeln.toml is a build manifest, not a Containerfile; container/ absent" -no-benchmarks = "criterion benches are nested in aletheia/, the gate is root-anchored" -no-formal-proofs = "Coq proofs live in the absolute-zero submodule (proofs/coq/), not in-tree verification/" - -# NOTE: the reference checker (check-rsr-profile.sh @ gates v0.3.0) -# reports 3 MISSING + 1 VESTIGIAL (exit 1) against this profile, both -# understood: the MISSINGs are the root-anchored rust rows (the aletheia -# crate is nested under aletheia/, a legitimate multi-concern-root layout -# the gate format cannot express), and the VESTIGIAL is MAINTAINERS.adoc -# (partial governance quad — also unrepresentable). Both tracked as -# upstream standards gaps; the checker stays unwired in CI until then. +rust = "true: a Rust 2021 crate (MSRV 1.80) with zero dependencies" +cli = "true: src/main.rs produces a binary" +docs = "true: README.adoc + SECURITY.adoc + CONTRIBUTING.adoc + CODE_OF_CONDUCT.adoc + CHANGELOG.adoc" +no-library = "DECLINED unless a lib target is added; src/lib.rs currently backs the binary's tests" +no-bash = "true: no tracked *.sh; all automation is in the Justfile" +no-container = "true: no Containerfile in the scaffold" +no-reproducible-build = "true: no guix.scm; the zero-dependency crate is offline-buildable via `cargo build --offline`" +no-formal-proofs = "PARTIAL: verification/ carries Creusot proof obligations, but they are not wired into CI until the Creusot toolchain is pinned (see verification/README.adoc)" +no-docs-site = "true: no pages workflow" diff --git a/.machine_readable/self-validating/README.adoc b/.machine_readable/self-validating/README.adoc deleted file mode 100644 index c99953c..0000000 --- a/.machine_readable/self-validating/README.adoc +++ /dev/null @@ -1,179 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= K9 Contractiles -:toc: left -:icons: font - -== What Are K9 Contractiles? - -K9 contractiles are self-validating components that combine configuration, validation, and deployment logic in a single file format. They implement the RSR principle of "self-describing artifacts" by embedding contracts and orchestration directly in the component. - -== The Three Security Levels - -K9 components declare their trust requirements using "The Leash" security model: - -[horizontal] -`'Kennel`:: Pure data, no execution (safest) -`'Yard`:: Nickel evaluation with contracts (medium trust) -`'Hunt`:: Full execution with Just recipes (requires signature) - -== Example Components - -This directory contains example K9 contractiles for common repository tasks: - -=== Kennel Level (Pure Data) - -**File:** `examples/project-metadata.k9.ncl` - -Pure configuration data with no execution. Safe to include in any repository. - -**Use cases:** -- Project metadata (name, version, description) -- Build configuration -- Tool settings -- Data schemas - -**Security:** No signature required, data-only. - -=== Yard Level (Validated Config) - -**File:** `examples/ci-config.k9.ncl` - -Configuration with Nickel contracts for runtime validation. Evaluated safely without I/O. - -**Use cases:** -- CI/CD configuration with validation -- Deployment parameters -- Database schemas with constraints -- API specifications - -**Security:** Signature recommended, Nickel evaluation only. - -=== Hunt Level (Full Execution) - -**File:** `examples/setup-repo.k9.ncl` - -Full execution with Just recipes. Can run shell commands and modify filesystem. - -**Use cases:** -- Repository setup scripts -- Deployment automation -- System configuration -- Package installation - -**Security:** **Signature required**, full system access. - -== Usage in Your Repository - -=== 1. Create K9 Components - -Choose the appropriate security level for your use case: - -[source,bash] ----- -# Kennel: Pure configuration -cp contractiles/k9/examples/project-metadata.k9.ncl config/metadata.k9.ncl - -# Yard: Validated configuration -cp contractiles/k9/examples/ci-config.k9.ncl .github/ci.k9.ncl - -# Hunt: Full automation -cp contractiles/k9/examples/setup-repo.k9.ncl scripts/setup.k9.ncl ----- - -=== 2. Validate Components - -[source,bash] ----- -# Validate Nickel syntax and contracts -nickel typecheck config/metadata.k9.ncl - -# Verify Hunt-level signature (if signed) -./must verify scripts/setup.k9.ncl ----- - -=== 3. Execute Components - -[source,bash] ----- -# Kennel: Export as JSON -nickel export config/metadata.k9.ncl > metadata.json - -# Yard: Evaluate with validation -nickel eval .github/ci.k9.ncl - -# Hunt: Run with Just (dry-run first!) -./must --dry-run run scripts/setup.k9.ncl -./must run scripts/setup.k9.ncl ----- - -== Integration with RSR - -K9 contractiles integrate with other RSR standards: - -**STATE.scm**:: K9 components can generate or validate STATE.scm -**ECOSYSTEM.scm**:: K9 can automate cross-repo operations -**META.scm**:: K9 can enforce architectural decisions - -== Security Best Practices - -=== For Kennel/Yard Components - -✅ **Safe to use without signatures** + -✅ **Review Nickel code before use** + -✅ **Validate contracts match expectations** - -=== For Hunt Components - -⚠️ **ALWAYS verify signatures** + -⚠️ **Review Just recipes carefully** + -⚠️ **Run dry-run mode first** + -⚠️ **Never run as root unless required** + -⚠️ **Sandbox external components** - -**See:** https://github.com/hyperpolymath/standards/blob/main/k9-svc/docs/SECURITY-BEST-PRACTICES.adoc - -== Template Files - -Use these as starting points for your own K9 components: - -- `template-kennel.k9.ncl` - Pure data template -- `template-yard.k9.ncl` - Validated config template -- `template-hunt.k9.ncl` - Full execution template - -== Dependencies - -To use K9 contractiles in your repository: - -[source,bash] ----- -# Install Nickel (configuration language) -curl -L https://github.com/tweag/nickel/releases/latest/download/nickel-linux-x86_64 -o nickel -chmod +x nickel && sudo mv nickel /usr/local/bin/ - -# Install Just (task runner, for Hunt level) -cargo install just - -# Clone K9-SVC (for must shim and tooling) -git clone https://github.com/hyperpolymath/standards.git -# Note: K9-SVC is located in standards/k9-svc ----- - -== Learn More - -- **K9-SVC Specification:** https://github.com/hyperpolymath/standards/blob/main/k9-svc/SPEC.adoc -- **K9 User Guide:** https://github.com/hyperpolymath/standards/blob/main/k9-svc/GUIDE.adoc -- **Security Documentation:** https://github.com/hyperpolymath/standards/blob/main/k9-svc/docs/SECURITY-FAQ.adoc -- **IANA Media Type:** `application/vnd.k9+nickel` - -== Contributing - -When adding K9 contractiles to your repository: - -1. Use appropriate security level (Kennel > Yard > Hunt) -2. Document what each component does -3. Include validation contracts in Yard/Hunt components -4. Sign Hunt-level components before committing -5. Add K9 validation to CI/CD pipeline - -**Questions?** Open an issue on https://github.com/hyperpolymath/standards/tree/main/k9-svc diff --git a/.machine_readable/self-validating/examples/ci-config.k9.ncl b/.machine_readable/self-validating/examples/ci-config.k9.ncl deleted file mode 100644 index 9fe314e..0000000 --- a/.machine_readable/self-validating/examples/ci-config.k9.ncl +++ /dev/null @@ -1,126 +0,0 @@ -K9! -# SPDX-License-Identifier: MPL-2.0 -# Example Yard-level K9 component: CI/CD configuration with validation -# Security Level: Yard (Nickel evaluation, contract validation) -# Signature recommended but not required - -{ - pedigree = { - schema_version = "1.0.0", - component_type = "ci-configuration", - security = { - leash = 'Yard, - trust_level = "validated-config", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = false, - }, - metadata = { - name = "ci-config", - version = "1.0.0", - description = "CI/CD configuration with runtime validation", - author = "Jonathan D.A. Jewell ", - }, - }, - - # CI/CD configuration with Nickel contracts - ci = { - # Platform must be a known CI provider - platform - | [| 'GitHubActions, 'GitLabCI, 'CircleCI, 'TravisCI |] - = 'GitHubActions, - - # Build matrix with validation - matrix = { - # Operating systems to test on - os - | Array String - | std.array.NonEmpty - = ["ubuntu-latest", "macos-latest"], - - # Language versions to test - versions - | Array String - | std.array.NonEmpty - = ["stable", "beta"], - }, - - # Workflow steps with validation - steps = [ - { - name = "Checkout", - action = "actions/checkout@v4", - # Version must be SHA-pinned for security - sha | String | std.string.NonEmpty = "b4ffde65f46336ab88eb53be808477a3936bae11", - }, - { - name = "Build", - run = "just build", - }, - { - name = "Test", - run = "just test", - }, - { - name = "Lint", - run = "just lint", - }, - ], - - # Deployment configuration - deploy = { - enabled | Bool = false, - - # Only deploy from main branch - branch - | String - | std.contract.from_predicate (fun b => b == "main" || b == "master") - = "main", - - # Deployment requires manual approval - requires_approval | Bool = true, - }, - - # Security scanning - security = { - enabled | Bool = true, - - scanners = [ - { - name = "CodeQL", - languages = ["rust", "javascript"], - }, - { - name = "OSSF Scorecard", - enabled = true, - }, - { - name = "TruffleHog", - scan_for = "secrets", - }, - ], - }, - - # Notification settings - notifications = { - on_success = "never", - on_failure = "always", - channels = ["email"], - }, - }, - - # Validation rules (enforced by Nickel) - validation = { - # At least one OS must be specified - check_os = std.array.length ci.matrix.os > 0, - - # At least one version must be tested - check_versions = std.array.length ci.matrix.versions > 0, - - # Must have at least build and test steps - check_steps = std.array.length ci.steps >= 2, - - # Security scanning must be enabled - check_security = ci.security.enabled == true, - }, -} diff --git a/.machine_readable/self-validating/examples/project-metadata.k9.ncl b/.machine_readable/self-validating/examples/project-metadata.k9.ncl deleted file mode 100644 index b2299b4..0000000 --- a/.machine_readable/self-validating/examples/project-metadata.k9.ncl +++ /dev/null @@ -1,57 +0,0 @@ -K9! -# SPDX-License-Identifier: MPL-2.0 -# Example Kennel-level K9 component: Project metadata -# Security Level: Kennel (pure data, no execution) -# No signature required - -{ - pedigree = { - schema_version = "1.0.0", - component_type = "project-metadata", - security = { - leash = 'Kennel, - trust_level = "data-only", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = false, - }, - metadata = { - name = "project-metadata", - version = "1.0.0", - description = "Pure data configuration for project metadata", - author = "Jonathan D.A. Jewell ", - }, - }, - - # Project configuration - project = { - name = "my-project", - version = "0.1.0", - description = "A project following Rhodium Standard Repositories", - - repository = { - url = "https://github.com/hyperpolymath/my-project", - type = "git", - }, - - author = { - name = "Jonathan D.A. Jewell", - email = "j.d.a.jewell@open.ac.uk", - organization = "The Open University", - }, - - license = "MPL-2.0", - - keywords = [ - "rhodium-standard", - "rsr", - "hyperpolymath", - ], - }, - - # Export as JSON for other tools - export = { - format = "json", - destination = "project-metadata.json", - }, -} diff --git a/.machine_readable/self-validating/examples/setup-repo.k9.ncl b/.machine_readable/self-validating/examples/setup-repo.k9.ncl deleted file mode 100644 index b635d5b..0000000 --- a/.machine_readable/self-validating/examples/setup-repo.k9.ncl +++ /dev/null @@ -1,167 +0,0 @@ -K9! -# SPDX-License-Identifier: MPL-2.0 -# Example Hunt-level K9 component: Repository setup automation -# Security Level: Hunt (full execution with Just recipes) -# ⚠️ SIGNATURE REQUIRED - DO NOT RUN WITHOUT VERIFICATION - -{ - pedigree = { - schema_version = "1.0.0", - component_type = "repository-setup", - security = { - leash = 'Hunt, - trust_level = "full-system-access", - allow_network = true, - allow_filesystem_write = true, - allow_subprocess = true, - signature_required = true, - }, - metadata = { - name = "setup-repo", - version = "1.0.0", - description = "Automated repository setup with RSR standards", - author = "Jonathan D.A. Jewell ", - }, - warnings = [ - "This component has full system access", - "Only run from trusted sources with verified signatures", - "Review Just recipes before execution", - "Use dry-run mode first: ./must --dry-run run setup-repo.k9.ncl", - ], - }, - - # Configuration with contracts - config = { - repo_name - | String - | std.string.NonEmpty - = "my-new-repo", - - repo_type - | [| 'Library, 'Application, 'Tool, 'Specification |] - = 'Application, - - primary_language - | String - | std.string.NonEmpty - = "rust", - - # RSR compliance features to enable - features = { - checkpoint_files | Bool = true, # STATE.scm, ECOSYSTEM.scm, META.scm - security_workflows | Bool = true, # CodeQL, Scorecard, etc. - quality_checks | Bool = true, # Linting, formatting - mirroring | Bool = false, # GitLab/Bitbucket mirrors - }, - - # Git configuration - git = { - default_branch = "main", - initial_commit | Bool = true, - remote_url | String = "", - }, - }, - - # Just recipes for execution - # These run when: ./must run setup-repo.k9.ncl - recipes = { - # Main entry point - default = { - recipe = "setup", - description = "Set up RSR-compliant repository", - }, - - # Individual setup tasks - setup = { - dependencies = ["check-env", "create-structure", "init-git", "setup-workflows"], - commands = [ - "echo '✅ Repository setup complete!'", - "echo 'Run: git status to see changes'", - ], - }, - - "check-env" = { - description = "Verify required tools are installed", - commands = [ - "command -v git || (echo 'ERROR: git not found' && exit 1)", - "command -v just || (echo 'ERROR: just not found' && exit 1)", - "command -v nickel || (echo 'ERROR: nickel not found' && exit 1)", - "echo '✓ All required tools present'", - ], - }, - - "create-structure" = { - description = "Create RSR directory structure", - commands = [ - "mkdir -p src/ docs/ tests/ scripts/", - "mkdir -p .github/workflows/", - "mkdir -p contractiles/k9/", - "echo '✓ Directory structure created'", - ], - }, - - "init-git" = { - description = "Initialize Git repository", - commands = [ - "git init -b %{config.git.default_branch}", - "git config user.name 'Jonathan D.A. Jewell'", - "git config user.email 'j.d.a.jewell@open.ac.uk'", - "echo '✓ Git initialized'", - ], - }, - - "setup-workflows" = { - description = "Add RSR-compliant workflows", - commands = [ - # This would copy workflow templates - # In a real implementation, would fetch from rsr-template-repo - "echo '✓ Workflows configured'", - ], - }, - - "create-checkpoint-files" = { - description = "Create STATE.scm, ECOSYSTEM.scm, META.scm", - commands = [ - "echo '(state (version \"1.0.0\") (project \"%{config.repo_name}\"))' > STATE.scm", - "echo '(ecosystem (version \"1.0.0\") (name \"%{config.repo_name}\"))' > ECOSYSTEM.scm", - "echo '(meta (version \"1.0.0\") (project \"%{config.repo_name}\"))' > META.scm", - "echo '✓ Checkpoint files created'", - ], - }, - - "add-license" = { - description = "Add PMPL-1.0 license", - commands = [ - "curl -sL https://raw.githubusercontent.com/hyperpolymath/pmpl/main/LICENSE -o LICENSE", - "echo '✓ License added'", - ], - }, - - "add-readme" = { - description = "Create README.adoc from template", - commands = [ - "echo '= %{config.repo_name}' > README.adoc", - "echo '' >> README.adoc", - "echo 'Part of the Hyperpolymath ecosystem.' >> README.adoc", - "echo '✓ README created'", - ], - }, - - clean = { - description = "Remove generated files (careful!)", - commands = [ - "echo '⚠️ This will delete all generated files'", - "echo 'Press Ctrl+C to cancel, or wait 5 seconds...'", - "sleep 5", - "rm -f STATE.scm ECOSYSTEM.scm META.scm", - "echo '✓ Cleaned'", - ], - }, - }, - - # Validation (Yard-level checks before Hunt execution) - validation = { - check_repo_name = std.string.length config.repo_name > 0, - check_language = std.string.length config.primary_language > 0, - }, -} diff --git a/.machine_readable/self-validating/template-hunt.k9.ncl b/.machine_readable/self-validating/template-hunt.k9.ncl deleted file mode 100644 index b3fcb47..0000000 --- a/.machine_readable/self-validating/template-hunt.k9.ncl +++ /dev/null @@ -1,136 +0,0 @@ -K9! -# SPDX-License-Identifier: MPL-2.0 -# K9 Hunt-level template: Full execution with Just recipes -# Security Level: Hunt (full system access) -# ⚠️ SIGNATURE REQUIRED - Review carefully before use - -{ - pedigree = { - schema_version = "1.0.0", - component_type = "TODO: describe component type (e.g., 'deployment', 'setup-script')", - security = { - leash = 'Hunt, - trust_level = "full-system-access", - allow_network = true, - allow_filesystem_write = true, - allow_subprocess = true, - signature_required = true, - }, - metadata = { - name = "TODO: component-name", - version = "1.0.0", - description = "TODO: Detailed description of what this component does", - author = "Jonathan D.A. Jewell ", - }, - warnings = [ - "This component has full system access", - "Only run from trusted sources with verified signatures", - "Review all Just recipes before execution", - "Use dry-run mode first: ./must --dry-run run your-file.k9.ncl", - ], - side_effects = [ - "TODO: List what files/directories this creates or modifies", - "TODO: List what commands this executes", - "TODO: List what network access this requires", - ], - }, - - # Configuration with contracts (Yard-level validation) - config = { - # Add your configuration here with appropriate contracts - target_dir - | String - | std.string.NonEmpty - = "/tmp/k9-output", - - dry_run | Bool = false, - - # Add more config as needed - }, - - # Just recipes for execution - # These run when: ./must run your-file.k9.ncl - recipes = { - # Main entry point (runs by default) - default = { - recipe = "TODO: main-task", - description = "TODO: What the default recipe does", - }, - - # Define your recipes here - "main-task" = { - dependencies = ["check-prerequisites"], - commands = [ - "echo 'TODO: Add your commands here'", - # Example: Create directory - # "mkdir -p %{config.target_dir}", - # Example: Run a command - # "just build", - # Example: Conditional execution - # "@if [ \"%{config.dry_run}\" = \"true\" ]; then echo '[DRY-RUN] Would execute'; else actual-command; fi", - ], - }, - - "check-prerequisites" = { - description = "Verify required tools and permissions", - commands = [ - # Example: Check for required tools - # "command -v git || (echo 'ERROR: git not found' && exit 1)", - # Example: Check permissions - # "[ -w %{config.target_dir} ] || (echo 'ERROR: Cannot write to target directory' && exit 1)", - "echo '✓ Prerequisites checked'", - ], - }, - - # Add more recipes as needed - "build" = { - description = "Build the project", - commands = [ - "echo 'TODO: Add build commands'", - ], - }, - - "deploy" = { - description = "Deploy the application", - dependencies = ["build"], - commands = [ - "echo 'TODO: Add deployment commands'", - ], - }, - - "clean" = { - description = "Clean up generated files", - commands = [ - "echo '⚠️ This will delete files - waiting 3 seconds...'", - "sleep 3", - "echo 'TODO: Add cleanup commands'", - # "rm -rf %{config.target_dir}", - ], - }, - }, - - # Validation (Yard-level checks before Hunt execution) - validation = { - check_target_dir = std.string.length config.target_dir > 0, - # Add more validation as needed - }, -} - -# Usage: -# 1. Fill in TODO items above -# 2. Define configuration with contracts -# 3. Implement Just recipes with your commands -# 4. Test with dry-run: ./must --dry-run run your-file.k9.ncl -# 5. Review dry-run output carefully -# 6. Sign the component: ./must sign your-file.k9.ncl -# 7. Distribute with signature: your-file.k9.ncl.sig -# 8. Users verify and run: ./must verify && ./must run your-file.k9.ncl -# -# Security checklist: -# ✓ All TODO items filled in -# ✓ side_effects documented accurately -# ✓ Commands reviewed for safety -# ✓ No hardcoded secrets or credentials -# ✓ Proper error handling in recipes -# ✓ Tested in dry-run mode -# ✓ Component signed with trusted key diff --git a/.machine_readable/self-validating/template-kennel.k9.ncl b/.machine_readable/self-validating/template-kennel.k9.ncl deleted file mode 100644 index 4228b26..0000000 --- a/.machine_readable/self-validating/template-kennel.k9.ncl +++ /dev/null @@ -1,54 +0,0 @@ -K9! -# SPDX-License-Identifier: MPL-2.0 -# K9 Kennel-level template: Pure data configuration -# Security Level: Kennel (data-only, no execution) -# No signature required - safe for any use - -{ - pedigree = { - schema_version = "1.0.0", - component_type = "TODO: describe component type (e.g., 'build-config', 'metadata')", - security = { - leash = 'Kennel, - trust_level = "data-only", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = false, - }, - metadata = { - name = "TODO: component-name", - version = "1.0.0", - description = "TODO: Brief description of what this component contains", - author = "Jonathan D.A. Jewell ", - }, - }, - - # Your configuration data here - config = { - # Example: Pure data values - setting_1 = "value", - setting_2 = 42, - setting_3 = true, - - nested = { - key = "value", - }, - - list = [ - "item1", - "item2", - ], - }, - - # Optional: Export format specification - export = { - format = "json", # or "yaml", "toml" - destination = "output.json", - }, -} - -# Usage: -# 1. Fill in TODO items above -# 2. Add your configuration data to config = { ... } -# 3. Validate: nickel typecheck your-file.k9.ncl -# 4. Export: nickel export your-file.k9.ncl > output.json diff --git a/.machine_readable/self-validating/template-yard.k9.ncl b/.machine_readable/self-validating/template-yard.k9.ncl deleted file mode 100644 index a723f5a..0000000 --- a/.machine_readable/self-validating/template-yard.k9.ncl +++ /dev/null @@ -1,84 +0,0 @@ -K9! -# SPDX-License-Identifier: MPL-2.0 -# K9 Yard-level template: Configuration with validation -# Security Level: Yard (Nickel evaluation with contracts) -# Signature recommended but not required - -{ - pedigree = { - schema_version = "1.0.0", - component_type = "TODO: describe component type (e.g., 'validated-config', 'schema')", - security = { - leash = 'Yard, - trust_level = "validated-config", - allow_network = false, - allow_filesystem_write = false, - allow_subprocess = false, - }, - metadata = { - name = "TODO: component-name", - version = "1.0.0", - description = "TODO: Brief description with validation details", - author = "Jonathan D.A. Jewell ", - }, - }, - - # Configuration with Nickel contracts for validation - config = { - # Example: String that cannot be empty - name - | String - | std.string.NonEmpty - = "TODO: default value", - - # Example: Number with range constraint - port - | Number - | std.contract.from_predicate (fun p => p > 0 && p < 65536) - = 8080, - - # Example: Boolean flag - enabled | Bool = true, - - # Example: Enum (one of several values) - environment - | [| 'Development, 'Staging, 'Production |] - = 'Development, - - # Example: List with non-empty constraint - items - | Array String - | std.array.NonEmpty - = ["item1", "item2"], - - # Example: Nested object with contracts - database = { - host | String | std.string.NonEmpty = "localhost", - port | Number | std.contract.from_predicate (fun p => p > 0 && p < 65536) = 5432, - name | String | std.string.NonEmpty = "mydb", - }, - }, - - # Validation rules (additional cross-field checks) - validation = { - # Example: Check that at least one item exists - check_items = std.array.length config.items > 0, - - # Example: Check that production has secure settings - check_production = - if config.environment == 'Production then - config.enabled == true - else - true, - - # Add your custom validation rules here - }, -} - -# Usage: -# 1. Fill in TODO items above -# 2. Define your config with appropriate contracts -# 3. Add validation rules in validation = { ... } -# 4. Validate: nickel typecheck your-file.k9.ncl -# 5. Evaluate: nickel eval your-file.k9.ncl -# 6. If validation passes, use in your application diff --git a/.machine_readable/svc/README.adoc b/.machine_readable/svc/README.adoc deleted file mode 100644 index 56a2899..0000000 --- a/.machine_readable/svc/README.adoc +++ /dev/null @@ -1,17 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= `.machine_readable/svc/` — Service components (relocated) -:toc: - -The K9 self-validating templates and validators that lived here under -`svc/k9/` moved to `.machine_readable/self-validating/` in the 2026-06 -estate standardization. This directory remains only as a pointer. - -The intent of **ADR-001 (2026-04-18)** — that K9 lives outside -`contractiles/` so the contractile directory stays a pure verb set — -is preserved by the new location. - -== Pointers - -* K9 self-validation: `.machine_readable/self-validating/` -* Verb contractiles: `.machine_readable/contractiles/` diff --git a/.tool-versions b/.tool-versions index 6361280..a87d31a 100644 --- a/.tool-versions +++ b/.tool-versions @@ -1,4 +1,5 @@ -# Toolchain pins, asdf/mise compatible (measured 2026-09-21, stable channel). -# Kept in sync with mise.toml [tools]. just is intentionally unpinned (any -# recent just works — install via `cargo install just`). +# Toolchain pins, asdf/mise compatible. +# The main crate builds on stable with zero dependencies; verification/ +# additionally needs the Creusot toolchain (nightly Rust + Why3), which is +# pinned separately in verification/README.adoc. rust 1.98.1 diff --git a/.well-known/ai.txt b/.well-known/ai.txt deleted file mode 120000 index 741ed75..0000000 --- a/.well-known/ai.txt +++ /dev/null @@ -1 +0,0 @@ -../www/.well-known/ai.txt \ No newline at end of file diff --git a/.well-known/ai.txt b/.well-known/ai.txt new file mode 100644 index 0000000..d30fbd9 --- /dev/null +++ b/.well-known/ai.txt @@ -0,0 +1,15 @@ +# SPDX-License-Identifier: MPL-2.0 +# ai.txt - AI interaction policy + +User-Agent: * +Disallow-Training: yes +Disallow-Summarization: no +Disallow-Generation: yes + +# This project's code is licensed under MPL-2.0. +# AI agents may read and analyse this code to assist contributors. +# AI agents must NOT use this code for model training without explicit consent. +# +# Agent integration instructions: +# 0-AI-MANIFEST.a2ml (universal AI entry point) +# .machine_readable/ (structured project state) diff --git a/.well-known/humans.txt b/.well-known/humans.txt deleted file mode 120000 index 0ec3042..0000000 --- a/.well-known/humans.txt +++ /dev/null @@ -1 +0,0 @@ -../www/.well-known/humans.txt \ No newline at end of file diff --git a/.well-known/humans.txt b/.well-known/humans.txt new file mode 100644 index 0000000..41c4230 --- /dev/null +++ b/.well-known/humans.txt @@ -0,0 +1,13 @@ +# SPDX-License-Identifier: MPL-2.0 +# humanstxt.org + +/* TEAM */ +Maintainer: Jonathan D.A. Jewell +Contact: j.d.a.jewell@open.ac.uk + +/* SITE */ +Last update: 2026-09-24 +Standards: RSR (Rhodium Standard Repository) +Language: Rust/Creusot +License: MPL-2.0 +Tools: just, cargo diff --git a/.well-known/security.txt b/.well-known/security.txt deleted file mode 120000 index 4982a45..0000000 --- a/.well-known/security.txt +++ /dev/null @@ -1 +0,0 @@ -../www/.well-known/security.txt \ No newline at end of file diff --git a/.well-known/security.txt b/.well-known/security.txt new file mode 100644 index 0000000..72d7465 --- /dev/null +++ b/.well-known/security.txt @@ -0,0 +1,9 @@ +# SPDX-License-Identifier: MPL-2.0 +# RFC 9116 - security.txt +# https://securitytxt.org/ + +Contact: mailto:j.d.a.jewell@open.ac.uk +Expires: 2027-09-24T02:18:08.000Z +Preferred-Languages: en +Canonical: https://github.com/hyperpolymath/proofgateway/blob/main/.well-known/security.txt +Policy: https://github.com/hyperpolymath/proofgateway/blob/main/SECURITY.adoc diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml index c7ce197..ae2a099 100644 --- a/0-AI-MANIFEST.a2ml +++ b/0-AI-MANIFEST.a2ml @@ -1,116 +1,52 @@ -# ⚠️ STOP - CRITICAL READING REQUIRED +# SPDX-License-Identifier: MPL-2.0 +# proofgateway — universal AI agent entry point. -**THIS FILE MUST BE READ FIRST BY ALL AI AGENTS** +# THIS FILE MUST BE READ FIRST BY ALL AI AGENTS -## WHAT IS THIS? +## What Is This? -This is the AI manifest for **maa-framework**. It declares: -- Canonical file locations (where things MUST be, and nowhere else) -- Critical invariants (rules that must NEVER be violated) -- Repository structure and organization +The AI manifest for **proofgateway**. It declares canonical file +locations and the invariants an agent must not violate. -## CANONICAL LOCATIONS (UNIVERSAL RULE) +## Canonical Locations ### Machine-Readable Metadata: `.machine_readable/` ONLY -These 6 SCM files MUST exist in `.machine_readable/` directory ONLY: -1. **.machine_readable/6a2/STATE.a2ml** - Project state, progress, blockers -2. **.machine_readable/6a2/META.a2ml** - Architecture decisions, governance -3. **.machine_readable/6a2/ECOSYSTEM.a2ml** - Position in ecosystem, relationships -4. **.machine_readable/6a2/AGENTIC.a2ml** - AI agent interaction patterns -5. **.machine_readable/6a2/NEUROSYM.a2ml** - Neurosymbolic integration config -6. **.machine_readable/6a2/PLAYBOOK.a2ml** - Operational runbook +* `.machine_readable/rsr-profile.a2ml` — capability declaration driving the + applicable RSR criterion set -**CRITICAL:** If ANY of these files exist in the root directory, this is an ERROR. - -### Bot Directives: `.bot_directives/` ONLY - -Bot-specific instructions for: -- rhodibot - Git operations -- echidnabot - Code quality -- sustainabot - Dependency updates -- glambot - Documentation -- seambot - Integration -- finishbot - Task completion +If any machine-readable metadata appears in the repository root, that is an +error: the root must contain only the agent front door +(`0-AI-MANIFEST.a2ml`). ### Agent Instructions -- `.claude/CLAUDE.md` - Claude-specific patterns (if exists) -- `0-AI-MANIFEST.a2ml` - THIS FILE (universal entry point) - -## CORE INVARIANTS - -1. **No SCM duplication** - Root must NOT contain .machine_readable/6a2/STATE.a2ml, .machine_readable/6a2/META.a2ml, etc. -2. **Single source of truth** - `.machine_readable/` is authoritative -3. **No stale metadata** - If root SCMs exist, they are OUT OF DATE -4. **License consistency** - All code MPL-2.0 unless platform requires MPL-2.0 -5. **Author attribution** - Always "Jonathan D.A. Jewell " - -## REPOSITORY STRUCTURE - - - -This repo contains: - -``` -maa-framework/ -├── 0-AI-MANIFEST.a2ml # THIS FILE (start here) -├── README.md # Project overview -├── [your source files] # Main code -├── .machine_readable/ # SCM files (6 files) -│ ├── .machine_readable/6a2/STATE.a2ml -│ ├── .machine_readable/6a2/META.a2ml -│ ├── .machine_readable/6a2/ECOSYSTEM.a2ml -│ ├── .machine_readable/6a2/AGENTIC.a2ml -│ ├── .machine_readable/6a2/NEUROSYM.a2ml -│ └── .machine_readable/6a2/PLAYBOOK.a2ml -└── .bot_directives/ # Bot instructions -``` - -## SESSION STARTUP CHECKLIST - -✅ Read THIS file (0-AI-MANIFEST.a2ml) first -✅ Understand canonical locations (.machine_readable/, .bot_directives/) -✅ Know the invariants (no SCM duplication, etc.) -✅ Check for MCP enforcement (if applicable) -✅ Read `.machine_readable/6a2/STATE.a2ml` for current status -✅ Read `.machine_readable/6a2/AGENTIC.a2ml` for interaction patterns - -## LIFECYCLE HOOKS - -### on-enter (Session Start) - -When starting a new session: - -1. Read and acknowledge this manifest -2. Log session start (optional but recommended) - - Format: `[YYYY-MM-DD HH:MM:SS] Session started: [agent-name]` - - Location: `.machine_readable/session-log.txt` -3. Read `.machine_readable/6a2/STATE.a2ml` -4. Check for blockers -5. State understanding of canonical locations - -### on-exit (Session End) +* `0-AI-MANIFEST.a2ml` — THIS FILE (universal entry point) +* `.claude/CLAUDE.md` — Claude-specific patterns (if present) -When ending a session: +## Core Invariants -1. Update `.machine_readable/6a2/STATE.a2ml` if changes made -2. Log session end (optional but recommended) - - Format: `[YYYY-MM-DD HH:MM:SS] Session ended: [summary]` - - Location: `.machine_readable/session-log.txt` -3. Document new blockers -4. Summarize outcomes +1. *No metadata duplication* — `.machine_readable/` is the single source of truth. +2. *Standalone by construction* — the build fetches nothing. Do not add network calls to the build, test, or scaffolding path. +3. *Dependency budget* — the crate depends only on `std`. Adding a dependency breaks the air-gapped guarantee and RSR Bronze. +4. *Language policy* — Rust here means Rust/Creusot — a specification that is not discharged by `just proof` is a bug, never a claim. The verified source is the shipped source: both crates `include!` `src/impl.rs`. +5. *No fake gates* — a recipe that echoes a message and exits 0 is a + violation. Fail loudly. +6. *SPDX headers* — every source file carries an `SPDX-License-Identifier` + within its first ten lines. Code is `MPL-2.0`; docs are `CC-BY-SA-4.0`. +7. *Licence consistency* — MPL-2.0 across the repository. -## ATTESTATION PROOF +## Session Startup Checklist -After reading this file, demonstrate understanding by stating: +* Read THIS file first. +* Read `.machine_readable/rsr-profile.a2ml` for declared capabilities. +* Run `just check` to confirm the tree is green before changing anything. +* State understanding of canonical locations before writing files. -**"I have read the AI manifest. SCM files are located in `.machine_readable/` ONLY, bot directives in `.bot_directives/`, and I will not create duplicate files in the root directory."** +## Attestation -## META +After reading this file, state: -- **Format Version:** 1.0.0 -- **Created:** [DATE] -- **Maintained By:** [YOUR-NAME/ORG] -- **License:** MPL-2.0 -- **Protocol:** https://github.com/hyperpolymath/0-ai-gatekeeper-protocol +**"I have read the AI manifest. Machine-readable metadata lives in +`.machine_readable/` only, the build is standalone, and Rust/Creusot +means what the estate language policy says it means."** diff --git a/ARCHITECTURE.adoc b/ARCHITECTURE.adoc deleted file mode 100644 index 1c0a7a6..0000000 --- a/ARCHITECTURE.adoc +++ /dev/null @@ -1,48 +0,0 @@ -== Architecture - -=== Overview - -This repository follows a modular, maintainable architecture designed -for clarity, scalability, and long-term sustainability. - -=== Directory Structure - -.... -. -├── src/ # Source code -├── tests/ # Test suites -├── docs/ # Documentation -├── scripts/ # Utility scripts -├── config/ # Configuration files -├── LICENSE # License file -├── LICENSES/ # Full license texts -└── README.adoc # Project documentation -.... - -=== Design Principles - -* *Separation of Concerns*: Each module has a single responsibility -* *Testability*: Code is written to be easily testable -* *Documentation*: All public APIs are documented -* *Configuration*: Environment-specific settings are externalized - -=== Dependencies - -* External dependencies are minimized and clearly declared -* Version pinning is used for reproducibility - -=== Security Considerations - -* Sensitive data is never committed to the repository -* Secrets are managed through environment variables or secure vaults -* Regular dependency audits are performed - -=== Maintainability - -* Code follows consistent style guidelines -* Pull requests require review and CI checks -* Issues and discussions are tracked transparently - -''''' - -_Last updated: 2026-07-18_ diff --git a/CHANGELOG.adoc b/CHANGELOG.adoc index c12e2c8..2b98660 100644 --- a/CHANGELOG.adoc +++ b/CHANGELOG.adoc @@ -1,79 +1,19 @@ -[NOTE] -==== -The live changelog is link:CHANGELOG.md[CHANGELOG.md], generated from -conventional commits by `.github/workflows/changelog.yml` (issue #100) on -every push to `main`. This `.adoc` file is frozen as of 2026-09-21 and -retained for history only — do not add entries here. -==== +// SPDX-License-Identifier: CC-BY-SA-4.0 += Changelog -== Changelog +All notable changes to this project are documented in this file. -All notable changes to `+maa-framework+` will be documented in this -file. +The format is based on https://keepachangelog.com/[Keep a Changelog], and +this project adheres to https://semver.org/[Semantic Versioning]. -This file is generated from conventional commits by the -https://github.com/hyperpolymath/standards/blob/main/.github/workflows/changelog-reusable.yml[`+changelog-reusable.yml+`] -workflow (`+hyperpolymath/standards#206+`). Adopt the workflow in this -repo’s CI to keep this file in sync automatically — see -https://github.com/hyperpolymath/standards/blob/main/templates/cliff.toml[`+templates/cliff.toml+`] -for the canonical config. +== [Unreleased] -The format follows https://keepachangelog.com/en/1.1.0/[Keep a -Changelog]; this project aims to follow -https://semver.org/spec/v2.0.0.html[Semantic Versioning]. +=== Added -=== [Unreleased] +* Initial project structure. -==== Added +== [0.1.0] - 2026-09-24 -* feat(crg): add crg-grade and crg-badge justfile recipes -* feat: add comprehensive test suite to achieve CRG C compliance -* feat: add benchmarks, unit tests, E2E and aspect tests for -absolute-zero -* feat: add stapeln.toml container definition -* feat: deploy UX Manifesto infrastructure -* feat: add CLADE.a2ml — clade taxonomy declaration +=== Added -==== Fixed - -* fix(baseline): unblock 2 baseline-rot checks blocking dependabot #69 -(#70) -* fix(ci): pin upload-artifact to valid SHA in hypatia-scan.yml (Refs -standards#48) (#57) -* fix(ci): bump a2ml/k9-validate-action pins to canonical (#55) -* fix(ci): sync hypatia-scan.yml to canonical (#54) -* fix(ci): build Hypatia escript from repo root (estate dogfood drift) -* fix(ci): adopt canonical hypatia-scan.yml (#52) -* fix(ci): rsr-antipattern.yml duplicate heredoc (#49) -* fix(ci): move secret-scanner Cargo.toml gate from job-level if: to -step-level (#50) -* fix: remove eval, quote vars, use mktemp in absolute-zero shell -scripts -* fix: eliminate all 3 sorry in LambdaCNO proofs - -==== Documentation - -* docs: substantive CRG C annotation (EXPLAINME.adoc) -* docs(test): achieve CRG C — document all test categories passing -* docs: add EXPLAINME.adoc — prove-it file backing README claims - -==== CI - -* build(deps): bump dtolnay/rust-toolchain from -efa25f7f19611383d5b0ccf2d1c8914531636bf9 to -3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 (#69) -* build(deps): bump haskell-actions/setup from 2.7.5 to 2.11.0 (#68) -* build(deps): bump actions/upload-pages-artifact from 3.0.1 to 5.0.0 -(#67) -* build(deps): bump actions/checkout from 4.1.1 to 6.0.2 (#66) -* build(deps): bump actions/configure-pages from 5.0.0 to 6.0.0 (#65) - -=== Pre-history - -Prior commits to this file’s introduction are recorded in git history -but not formally classified into Keep-a-Changelog sections. To backfill, -run `+git cliff -o CHANGELOG.md+` locally using the canonical -https://github.com/hyperpolymath/standards/blob/main/templates/cliff.toml[`+cliff.toml+`] -— this is one-shot mechanical work. - -''''' +* Initial release. diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index 9599b2c..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,3266 +0,0 @@ -# Changelog - -All notable changes to this project are documented here. - -This file is generated by [git-cliff](https://git-cliff.org) from conventional -commits. The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) -and the project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added - -- V2 six-language templates and a single-pass scanner (#186, #197) (#228) (e477b40) -- Close Silver gaps — toolchain, guix manifest, well-known, profile, quickstart (#189) (6620744) -- Estate label tooling + auto-triage for new issues (#166) (3913c4d) -- Add crg-grade and crg-badge justfile recipes (23a38ac) -- Add comprehensive test suite to achieve CRG C compliance (fc5e8bf) -- Add benchmarks, unit tests, E2E and aspect tests for absolute-zero (77af9b9) -- Add stapeln.toml container definition (abc3938) -- Deploy UX Manifesto infrastructure (12a1907) -- Add CLADE.a2ml — clade taxonomy declaration (49f2363) -- Add AI Gatekeeper Protocol manifest (8bbd63a) -- Enable Hypatia scanning (a71d44c) - - -### CI - -- Re-pin codeql-action to the true v4.38.0 commit (#224) (a330c21) -- Standardise the wrapper caller id to the canonical `hypatia` (#182) (0cd1756) -- Gate the dispatch on FARM_DISPATCH_TOKEN being present (#178) (97ca1cb) -- Cron weekly→monthly (cut 3, standards#288) (#146) (a9cfa26) -- Vendor validation scripts and remove remote action pins (#141) (f3c7ee1) -- SHA-pin the four unpinned actions in pages.yml (missed the #123 merge) (#128) (6a7ca7c) -- Deploy docs via Ddraig SSG (#121) (ba29a18) -- Secret Scanner caller must grant the reusable's job permissions (#119) (2b07677) -- Refresh standards reusable pins to current HEAD (d7c2271) (#112) (95b98b4) -- Adopt standards reusable workflows for Scorecard, Hypatia, and Governance (fb01868) -- Fix CI/CD configuration (campaigns C001-C005) (ca24a9e) -- Fix CI/CD configuration (campaigns C001-C005) (1ac4970) -- Fix CI/CD configuration (campaigns C001-C005) (1946e80) -- Add job-level permissions for reusable workflow (#90) (e5350be) -- Split score-threshold from publish job (OSSF run-step ban) (#87) (9fd8269) -- Redistribute concurrency-cancel guard to read-only check workflows (#58) (783f912) -- Bump actions/upload-artifact SHA to current v4 (#48) (cff9395) -- SHA-pin hyperpolymath validate-actions in dogfood-gate (46c7275) -- Fix top-level dir + benchmark/lsp filename matching (#47) (37dfb3e) -- TS check reads .claude/CLAUDE.md exemption table (#46) (8883fc9) -- Broaden TS allowlist (cli, mod.ts, lsp-server, *vscode*, deno-*) (#45) (b85f4ed) -- Allowlist legit TS bridge/adapter paths (#44) (737a8ca) -- Wire hypatia-scan.yml to query own Dependabot alerts (e06ac81) -- Deploy dogfood-gate, fix hypatia-scan, add pre-commit hooks (cb3b790) -- Add E2E + aspect + bench + panic-attack workflow for absolute-zero (69ba44a) -- Migrate CodeQL Action v3 → v4 (a9ca308) -- Update SHA pins for codeql-action and trufflehog (fa646ac) -- Deploy missing standard workflows (1 added) (1e61df9) - - -### Changed - -- Move root artefacts to their canonical locations (#176) (3098b7d) -- Migrate Markdown to AsciiDoc (#161) (43734c1) -- Migrate 6SCM → 6A2 (.scm → .a2ml format) (6f1db7d) - - -### Chores - -- Remove dead Codecov upload steps + lock pins (#181) (443a4e4) -- Migrate root .well-known/ to www/.well-known/ (#175) (1cb4d52) -- Relock drifted action pins (#173) (ca810e4) -- Repoint push-email-notify to smtp-notify-action (#169) (2bd3ee3) -- Delete Nix estate-wide (#138) (415e4b0) -- Quality pass - fix stub/invalid names (#139) (d1c2aab) -- SPDX headers on line 1 and Actions lockfile minted (#153) (15c0327) -- Make Scorecard periodic, not per-push (#151) (bf88376) -- Backfill [status] lifecycle block (#108) (133f70e) -- Normalise to MPL-2.0 + CC-BY-SA-4.0 (canonical pair) (#107) (a969c7a) -- Add dormant push-email notification workflow (#109) (efa1cab) -- Bump standards reusable workflow pins (#106) (73b3440) -- Retire local issue/discussion templates -> inherit org .github canon (f888c8f) -- Remove absolute-zero submodule — coordinate, don't vendor (bef4c92) -- Adopt estate-standardization wave + 2026-06-12 checkpoint (6a2 refresh, contractiles, bot_directives) (#97) (db66b53) -- Convert absolute-zero/ to git submodule pinned to upstream (closes #84) (#89) (b34e4f9) -- Replace scorecard.yml with reusable wrapper (#80) (7727db3) -- Replace secret-scanner.yml with reusable wrapper (#77) (a85f5a2) -- Replace mirror.yml with reusable wrapper (#76) (ee1dc62) -- Delete stale SafeDOMExample.res ReScript fixture (Refs gitbot-fleet#148, #208) (#74) (908defc) -- Bump hypatia-scan-reusable pin off orphan SHA to canonical main (#85) (4b4db46) -- Convert hypatia-scan.yml to wrapper of standards reusable (#73) (f4ba523) -- Exempt vendored absolute-zero Java/Kotlin demos (#71) (701c11f) -- Migrate license from PMPL-1.0-or-later to MPL-2.0 (e4e3db0) -- Remove stale session notes / obsolete CI / OS cruft (5bd8408) -- Replace per-repo governance copies with shared bundle wrapper (8f03d8d) -- Item 9 — retire ReScript guidance → AffineScript (#53) (2d92437) -- Bump k9/a2ml validate-action pins to current main (#51) (66e6b4f) -- Update codeql-action SHA to v3.35.2 (111b724) -- K9 → svc/, remove lust dir (ADR-001 2026-04-18) (6a3061b) -- Add bust/ + relocate k9 to svc/ (607c118) -- Remove lust (not in 6-verb set: intend trust must bust adjust dust) (ca02fc3) -- Estate-wide chore + stale-path sweep (2026-04-17) (3a45352) -- Update LICENSE to PMPL-1.0-or-later with MPL-2.0 fallback (5589e74) -- M5 CI/Workflow Sweep - final synchronisation (04c230b) -- M5 CI/Workflow Sweep - add blockers and contractile.just (5ef48b4) -- Commit 6a2 sweep — a2ml drift (d163f19) -- Clarify MPL-2.0 fallback — PMPL-1.0-or-later preferred (1a1c39c) -- Automated sync of local changes (d903b56) -- Update eclexiaiser.toml with real function entries (27cab88) -- Add eclexiaiser.toml manifests for container sub-services (3d9b7c0) -- Update STATE.a2ml with CRG C compliance achievement (1219f0a) -- Deploy UX infrastructure (contractile.just, .well-known, manifest) (66f71b3) -- Add UX infrastructure (quickstart, doctor, setup) (c87e331) -- Add agent_instructions methodology layer (452e3e0) -- Standardise, Justfile, (rename,, fix, parse, errors,, remove, useless, commands) (b5b882c) -- Batch RSR compliance — SPDX headers, SHA-pin actions, forbid(unsafe_code), CODE_OF_CONDUCT, CONTRIBUTING (e857469) -- Add foundational tool integrations (3235b58) -- Maximize ci/cd values via dependabot and permissions (320942e) -- Big Unification — attach to BoJ Server / Casket architecture (ec975c6) -- Big Unification — attach to BoJ Server / Casket architecture (c9a5488) -- RSR sync and mass repository update (8520a5b) -- Add #![forbid(unsafe_code)] to safe Rust crates (b1bbe31) -- Update manifest paths to .machine_readable/6a2/ (a807ea3) -- Restructure nested 6a2ml files into .machine_readable/6a2/ (7eb5b3b) -- Clean up legacy Trustfile.hs, example Trustfiles, and AI.djot files (c996519) -- Restructure 6a2ml files into .machine_readable/6a2/ (6883c63) -- RSR compliance — delete AI.djot, rename AI manifest, remove stale files (b94f0d2) -- RSR compliance — fix email, PMPL license, AGPL refs, placeholders, CITATIONS, editorconfig (f3054be) -- Sync local changes (2605828) -- Add /target/ to .gitignore (22ddfcd) -- Sync (c094097) -- Fix license headers to PMPL-1.0-or-later (a05211c) -- Commit local changes for sync (c4eda7c) -- Sync template files and configuration (d42b6f7) - - -### Documentation - -- Remove a token prefix that should not have been recorded (ab53573) -- Record measured state of play, for humans and for machines (#148) (de054c2) -- Convert README.adoc -> Markdown (renders on Glama/profile/community-health) (#110) (307d672) -- Flip ReScript→AffineScript per 2026-05-25 estate language policy (#88) (9dbf56b) -- Seed CHANGELOG.md (Keep-a-Changelog format) (#81) (b80aecf) -- Adopt docs-template/ skeleton from rsr-template-repo#75 (#79) (2386f0a) -- Record tech-debt audit findings (2026-05-26) (#75) (d05a500) -- Seed proof-debt.md per standards#203 schema (all 150 markers §(e) vendored) (#82) (6f66f90) -- Substantive CRG C annotation (EXPLAINME.adoc) (9917a32) -- Achieve CRG C — document all test categories passing (b0fa5f1) -- Add EXPLAINME.adoc — prove-it file backing README claims (58e6ffc) -- Update SCM files with project information (b38fc35) -- Add CONTRIBUTING.md (0848205) -- Add checkpoint files for state tracking (1d70b71) -- Update license from AGPL to PMPL (b6c9075) - - -### Fixed - -- Break infinite changelog-regenerate loop (#221) (ad34228) -- Codeql-action v4.38.1 -> v4.38.0 SHA pin + dependabot hold (estate-wide startup_failure) (#198) (918f434) -- Strip reintroduced ZWSP + exclude generated CHANGELOG.md from empty-lint (#194) (9730f65) -- Grant contents+PR write at caller TOP level (5/5 caller evidence) (#191) (270f65d) -- Changelog caller needs actions:read on the JOB block (top-level is replaced, not merged) (#190) (dc4514e) -- Restore green main — changelog perms, lock, ZWSP, docs gate, review port (#188) (0f837de) -- Gate on the DEED grammar, per the template and standards#837 (#183) (93e8625) -- Reconcile actions.lock so the lockfile validates (#184) (3beb02a) -- Reconcile the workflows with actions.lock (gh-actions-lock) (#180) (ef7691a) -- Pin third-party actions to full commit SHAs (#179) (afb63a6) -- Repoint references to the relocated contributing guide (#177) (45fdcb4) -- Make the dogfood gate .deed-aware (#174) (8285709) -- Remove rust-ci.yml as repo has no Cargo.toml (#171) (7d8feda) -- The invisible-character gate never matched anything (#165) (8ecd4cb) -- Unbreak workflow YAML and add a complete actions.lock (#164) (2e9b818) -- Repair workflows that are not valid YAML and have never run (#150) (d682669) -- Remove stray worktree gitlink that breaks every recursive checkout (#145) (649bd51) -- Real SHA-pinning check, real Justfile targets, and docs that match the code (#144) (7d964ee) -- Restore guix.scm identity and licence (squisher-corpus clobber is live on main) (#143) (b61df34) -- Repoint codeql-action at a SHA that exists (#142) (541f47f) -- Re-point validate-action references at the ecosystem repos (#140) (c5175f3) -- Remove the unrunnable SonarCloud step breaking Governance + CodeQL (#139) (f508c03) -- Close the governance gate — SPDX, permissions, SHA pins, reusable bump (#136) (75ab929) -- Group Dependabot updates into one PR per ecosystem (#127) (e895aa4) -- Aletheia has not compiled since June — repair it, then gate it (#123) (0392152) -- Drop invalid timeout-minutes from reusable-workflow calls (parse-dead) (#120) (85b7a22) -- Clear OSSF Scorecard startup_failure (#118) (dc4a8b7) -- Restore missing .gitmodules for absolute-zero submodule (#117) (082f45d) -- Unblock 2 baseline-rot checks blocking dependabot #69 (#70) (b834329) -- Pin upload-artifact to valid SHA in hypatia-scan.yml (Refs standards#48) (#57) (5d1a25f) -- Bump a2ml/k9-validate-action pins to canonical (#55) (9e01cf8) -- Sync hypatia-scan.yml to canonical (#54) (c701495) -- Build Hypatia escript from repo root (estate dogfood drift) (1fb5b1c) -- Adopt canonical hypatia-scan.yml (#52) (721e3ad) -- Rsr-antipattern.yml duplicate heredoc (#49) (f1c6f5e) -- Move secret-scanner Cargo.toml gate from job-level if: to step-level (#50) (9699724) -- Remove eval, quote vars, use mktemp in absolute-zero shell scripts (250311f) -- Eliminate all 3 sorry in LambdaCNO proofs (29259c0) -- Enforce granular permissions and add fuzzing placeholder (1fe0a35) -- Resolve 12 of 19 Lean4 sorry proofs in absolute-zero (4de6387) -- Correct email jonathan.jewell → j.d.a.jewell (47c4070) -- SPDX headers (AGPL→PMPL), email, author name (9e7755f) -- SPDX AGPL-3.0 → PMPL-1.0-or-later in dotfiles (588abe8) -- Remove duplicate SCM files from root (46a4513) - - -### Other - -- Bump the github-actions group with 2 updates (#226) (7b1b3c1) -- Bump the github-actions group with 2 updates (#200) (3be3969) -- Close all open issues: aletheia rebuild (#124/#125), rust-ci restore, just shim (#102), changelog (#100), hypatia prune (#98) (#185) - -Closes all five open issues in one campaign branch (7 focused commits, -each independently reviewable). Nothing here merges itself — review and -merge when satisfied. - -**#124 — Aletheia CLI rebuilt on the RSR v2 SSOT** (`9323897`) -- 26-check offline file-presence subset (13 Bronze / 12 Silver / 1 -Gold), every check citing its v2 criterion (`SSOT_PROVENANCE` in -`checks.rs`) -- Full CLI: `[repo-path]`, `--format X`/`=X`, -`--json/--sarif/--html/--badge`, `-v/-q`, `--config`, `--init-hook`; -exit codes 0/1/2/3/4 -- Real `.aletheia.toml` (level / per-check toggles / ignore globs); -submodule skipping, symlink-escape criticals, per-check suggestions -- **111/111 tests green** (66 unit + 45 integration), zero warnings, -zero dependencies -- The pin check learned the estate mechanism (`d8a0483`): tags covered -by `actions.lock` pass (governance *forbids* inline SHAs with a lock — -verified against governance-reusable); plus the tier-1 Bun carve-out - -**#125 — Clippy clean and blocking** (`9323897` + `5aa5041`) -- Findings wired into real code, not silenced; `clippy --all-targets -- --D warnings` blocks in CI and `just lint` - -**rust-ci restored** (`5aa5041`, part of the #125 gate half) -- The tree-move commit deleted the root gate without re-pointing it — -main has had no Rust CI since. Restored with 5 jobs mirroring `just -check`, tags + lock entry, validated YAML - -**#102 — Justfile canonicity** (`40b57fa`) -- Root declared canonical; the contractiles stub (fake gates echoing -"not configured yet") is now a forwarding shim — verified from three -working directories (a bare `import` runs recipes in the wrong tree; the -`working-directory` override fixes it) -- Drive-by: `crg-grade`/`crg-badge` failed 100% of runs (Make-style -`$$`); repaired and verified via root and shim - -**#100 — Changelog automation** (`12d123c`) -- `changelog.yml` adopted (commit-back; main has no branch protection, -verified via API), pinned to standards@b77c53c; no local cliff.toml by -design -- `CHANGELOG.md` seeded with the exact reusable recipe (git-cliff 2.6.1 -+ canonical config); `CHANGELOG.adoc` frozen as a pointer with content -preserved - -**#98 — hypatia-ignore pruned** (`a7c768a`) -- All 10 entries verified dead at the pinned submodule commit; file is -now a comments-only audit record (history, re-verification commands, -upstream pointer absolute-zero#77); cross-refs in `hypatia.a2ml` / -`Dustfile.a2ml` / STATE updated - -**Docs sync** (`9ff1e99`) -- Every doc describing the pre-campaign state re-measured: STATE.a2ml -(rsr-source-of-truth ANSWERED), TEST-NEEDS, README, both EXPLAINMEs, -CLAUDE.md, PROJECT_STATUS, full QUICK_REFERENCE v2 rewrite, -superseded-spec banners, working `install.sh` (tested end to end), -dead-GitLab contacts repointed - -**Deliberately not in this PR** -- `create-template.sh` still *emits* the v1 shape — that is a generator -rewrite, filed as a follow-up issue, not a docs touch-up -- `docs/STATE-OF-PLAY-2026-07-29.adoc` untouched (dated snapshot) -- Upstream `absolute-zero#77` owns that repo's stale ignore entries - -Verification: `just check` green (build + 111 tests + fmt + clippy `-D` -+ zero-dep); aletheia self-verifies Bronze ACHIEVED (23/26); new -workflows YAML-validated with no duplicate keys; `install.sh` tested end -to end. - -Closes #98 -Closes #100 -Closes #102 -Closes #124 -Closes #125 - ---------- - -Co-authored-by: Arena Agent (900c141) -- Bump the github-actions group with 2 updates (#172) (f00707d) -- Bump the github-actions group across 1 directory with 2 updates (#170) (9dfe403) -- Bun is tier 1, Deno is being removed (#163) (f19c544) -- Expand glossary with core concepts and components - -Added glossary entries for core concepts, components, architecture, and pronunciation guide. - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (b446352) -- Add EXPLAINME documentation for MAA Framework - -This document provides a detailed claim-to-implementation map for the MAA Framework, outlining the implementation status and caveats for various components, including the Rust microkernel and CI workflows. - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (a9fe4c1) -- Add README documentation for MAA Framework - -Added comprehensive documentation for the MAA Framework, including governance, project scope, known gaps, and build instructions. - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (13aba6f) -- Delete README.md - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (3a9b5d3) -- Change license to MPL-2.0 and revise project overview - -Updated license information and project description in README. - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (80e3e36) -- Worktree maa ci repair (#147) - - -## Summary - - - -Closes # - -## Type of change - -- [ ] 🐛 Bug fix (non-breaking change that fixes an issue) -- [ ] ✨ New feature (non-breaking change that adds functionality) -- [ ] 💥 Breaking change (would change existing behaviour) -- [ ] 🕳️ Soundness fix (fixes a checker/proof false-negative) -- [ ] 📖 Documentation -- [ ] 🧹 Refactor / tech debt (behaviour-preserving) -- [ ] ⚡ Performance -- [ ] 🔧 Build / CI / tooling - -## How has this been verified? - - - -## Checklist - -- [ ] My commits are **signed** (`git commit -S`). -- [ ] I ran the project's own checks/tests locally and they pass. -- [ ] New files carry the correct `SPDX-License-Identifier` (code/config -`MPL-2.0`, - prose `CC-BY-SA-4.0`); I did not relicense existing files. -- [ ] Docs are updated, and no public claim now overstates what the code -does. -- [ ] I have not introduced a soundness hole (or I have flagged where I -might have). - -## Notes for reviewers - - - ---------- - -Co-authored-by: Claude Opus 4.8 (2bf7a13) -- Bump the github-actions group with 2 updates (#138) (7b6a293) -- Update/licensing to pmpl ccby (#135) - - -## Summary - - - -Closes # - -## Type of change - -- [ ] 🐛 Bug fix (non-breaking change that fixes an issue) -- [ ] ✨ New feature (non-breaking change that adds functionality) -- [ ] 💥 Breaking change (would change existing behaviour) -- [ ] 🕳️ Soundness fix (fixes a checker/proof false-negative) -- [ ] 📖 Documentation -- [ ] 🧹 Refactor / tech debt (behaviour-preserving) -- [ ] ⚡ Performance -- [ ] 🔧 Build / CI / tooling - -## How has this been verified? - - - -## Checklist - -- [ ] My commits are **signed** (`git commit -S`). -- [ ] I ran the project's own checks/tests locally and they pass. -- [ ] New files carry the correct `SPDX-License-Identifier` (code/config -`MPL-2.0`, - prose `CC-BY-SA-4.0`); I did not relicense existing files. -- [ ] Docs are updated, and no public claim now overstates what the code -does. -- [ ] I have not introduced a soundness hole (or I have flagged where I -might have). - -## Notes for reviewers - - - ---------- - -Co-authored-by: Mistral Vibe (276fa6d) -- Bump dawidd6/action-send-mail from c50dc4cc848ade21f848990889906d804fae78c5 to 12335b969ae3fb71bee5f2c6b829744261aec34c (#133) (da60a2a) -- Re-pin secret scanner onto the real gitleaks gate (#122) (729de3a) -- Bump dawidd6/action-send-mail from 994f270325d4f7257aff241a35488ef54ba364a4 to c50dc4cc848ade21f848990889906d804fae78c5 (#114) (34ee83b) -- Bump dawidd6/action-send-mail from 6e502825a508b867ab2954ad6343b68787624c01 to 994f270325d4f7257aff241a35488ef54ba364a4 (#111) (8b1eb07) -- Bump actions/cache from 5.0.5 to 6.0.0 (35efd74) -- Bump actions/checkout from 6.0.3 to 7.0.0 (5f66c0f) -- Remediate Track C and Track E findings (b5322c2) -- Bump actions/checkout from 6.0.2 to 6.0.3 (#95) (34b7301) -- Re-vendor absolute-zero/ subtree to upstream HEAD (trusted-base + 16-commit catch-up) (#83) (d22378d) -- Bump dtolnay/rust-toolchain from efa25f7f19611383d5b0ccf2d1c8914531636bf9 to 3c5f7ea28cd621ae0bf5283f0e981fb97b8a7af9 (#69) (51700e7) -- Bump actions/checkout from 4.1.1 to 6.0.2 (#66) (83f5afa) -- Concurrency-cancel guard on canonical check workflows (#56) (7033454) -- Make CNO echo bridge relation-first (0538283) -- Add concrete echo bridge model for CNO (e80c5fb) -- Complete CNO composition proof and fix modulo parsing (1e7d169) -- Add Agda echo/CNO bridge scaffold and integration pointers (24fae59) -- Further proofs (56d29c8) -- Standardize workspace: Capitalize Justfile references in scripts and docs (a417457) -- Standardize workspace: Justfile migration and A2ML directive cleanup (cce7c4d) -- Add casket pages workflow (0881573) -- Remove template-only ABI files that falsely implied formal verification - -Template Idris2 ABI files (Types.idr, Layout.idr, Foreign.idr) contained -only RSR template scaffolding with unresolved placeholders and no -domain-specific proofs. Removed to prevent false impression of formal -verification coverage. - -Co-Authored-By: Claude Opus 4.6 (1M context) (3c1744f) -- Bump github/codeql-action from 4.33.0 to 4.34.0 (b4cfa8c) -- Bump actions/checkout from 4 to 6 (0456db0) -- Bump github/codeql-action from 4.32.6 to 4.33.0 (e4547e2) -- Bump erlef/setup-beam from 1.22.0 to 1.23.0 (f1c26e2) -- .scm → .a2ml state files in .machine_readable/ (7994051) -- SHA-pin GitHub Actions and upgrade deprecated checkout versions - -- Upgrade actions/checkout from v2/v3 to SHA-pinned v4 -- SHA-pin all unshelled action tags (pages, CodeQL, scorecard, - rust-cache, upload/download-artifact, setup-node, cache) -- Standardise scorecard-action to v2.4.0 -- Fix setup-node@v6 → SHA-pinned v4 - -Co-Authored-By: Claude Opus 4.6 (1M context) (5668860) -- Fix SPDX headers: AGPL-3.0-or-later → PMPL-1.0-or-later - -Replace legacy AGPL-3.0-or-later SPDX identifiers with the correct -PMPL-1.0-or-later (Palimpsest License) across justfiles, Mustfiles, -shell scripts, config files, dotfiles, and source code. - -Co-Authored-By: Claude Opus 4.6 (1M context) (7b86dcc) -- Bump webfactory/ssh-agent from 0.9.1 to 0.10.0 (b538011) -- Standardise license setup: MPL-2.0 + PMPL-1.0-or-later (REUSE) - -- LICENSE: pure MPL-2.0 text for machine detection (GitHub, registries) -- LICENSES/MPL-2.0.txt: standard MPL-2.0 text -- LICENSES/PMPL-1.0-or-later.txt: Palimpsest License text -- NOTICE: explains the dual-license relationship -- Source SPDX headers remain PMPL-1.0-or-later - -This ensures OSI compliance checks pass while preserving PMPL as -the governing license for source code. - -Co-Authored-By: Claude Opus 4.6 (d052e8e) -- Bump erlef/setup-beam from 1.21.0 to 1.22.0 (a61c7fe) -- Bump github/codeql-action from 4.32.5 to 4.32.6 (cd98b49) -- Sync changes [2026-03-05] (3f491d4) -- Fix stale submodule pointers after repo cleanup - -Co-Authored-By: Claude Opus 4.6 (25cf219) -- Bump github/codeql-action from 4.32.4 to 4.32.5 (3d95e19) -- Bump erlef/setup-beam from 1.20.4 to 1.21.0 (80b4802) -- Sync changes [2026-02-21] (639f389) -- Bump github/codeql-action from 4.32.3 to 4.32.4 (eab8654) -- Bump github/codeql-action from 4.32.2 to 4.32.3 (1c06e68) -- Bump dtolnay/rust-toolchain from f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 to efa25f7f19611383d5b0ccf2d1c8914531636bf9 (#27) (45efbc9) -- Update README.adoc - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (e17936d) -- Update README.adoc - -Signed-off-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (6733ff2) -- Merge branch 'main' of github.com:hyperpolymath/maa-framework (972f66d) -- Add Rhodium dotfiles (173fdfb) -- Update issue templates (6793698) -- Bump trufflesecurity/trufflehog from 3.92.4 to 3.92.5 (#13) - -Bumps -[trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) -from 3.92.4 to 3.92.5. -
-Release notes -

Sourced from trufflesecurity/trufflehog's -releases.

-
-

v3.92.5

-

What's Changed

- -

New Contributors

- -

Full Changelog: https://github.com/trufflesecurity/trufflehog/compare/v3.92.4...v3.92.5

-
-
-
-Commits -
    -
  • 116e717 -[INS-243] Fix jdbc detector detecting incomplete connection string and -fixed ...
  • -
  • b924c0b -added monthly requests limit to postman api request metrics collection -(#4667)
  • -
  • f3eff52 -fix: report accurate line numbers for chunked file scanning (#1876) -(#4615)
  • -
  • 6a0bc78 -fix(git): use --iso-strict git arg to prevent locale issue -(#4653)
  • -
  • fc3f35c -Gitlab Source: Backoff from Scan2 which is experimental to legacy -pagination ...
  • -
  • 728d71f -Rework JWT detector to better block local IPs; add HTTP instrumentation -(#4607)
  • -
  • 89cc34b -Fix typo in help description for Postman API metric (#4656)
  • -
  • 6904595 -detectors/twilio: add exponential backoff retry logic (#4652)
  • -
  • 4e02afb -[INS-170] Unify JDBC URL Parsing Across Detector and Analyzer -(Continued) (#4...
  • -
  • 964eab0 -[INS-232] Fix S3 Source "panic: runtime error: index out of -range" bug (#4610)
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=trufflesecurity/trufflehog&package-manager=github_actions&previous-version=3.92.4&new-version=3.92.5)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> -Co-authored-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (f59d518) -- Bump actions/checkout from 6.0.1 to 6.0.2 (#14) - -Bumps [actions/checkout](https://github.com/actions/checkout) from 6.0.1 -to 6.0.2. -
-Release notes -

Sourced from actions/checkout's -releases.

-
-

v6.0.2

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v6.0.1...v6.0.2

-
-
-
-Changelog -

Sourced from actions/checkout's -changelog.

-
-

Changelog

-

v6.0.2

- -

v6.0.1

- -

v6.0.0

- -

v5.0.1

- -

v5.0.0

- -

v4.3.1

- -

v4.3.0

- -

v4.2.2

- -

v4.2.1

- -

v4.2.0

- -

v4.1.7

- -

v4.1.6

- - -
-

... (truncated)

-
-
-Commits -
    -
  • de0fac2 -Fix tag handling: preserve annotations and explicit fetch-tags (#2356)
  • -
  • 064fe7f -Add orchestration_id to git user-agent when ACTIONS_ORCHESTRATION_ID is -set (...
  • -
  • See full diff in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=6.0.1&new-version=6.0.2)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> -Co-authored-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (cd0a0a4) -- Add STATE.scm - -Co-Authored-By: Claude Opus 4.5 (4e7183f) - - -### Security - -- Bump github/codeql-action from 4.38.0 to 4.38.1 in the github-actions group (#187) (e6d02db) -- Bump github/codeql-action from 4.37.7 to 4.37.8 in the github-actions group (#162) (8d726d5) -- Bump dawidd6/action-send-mail from 3.12.0 to 18 in the github-actions group (#160) (6519a5f) -- Bump github/codeql-action from 4.37.6 to 4.37.7 in the github-actions group (#159) (827237d) -- Bump github/codeql-action from 4.37.5 to 4.37.6 in the github-actions group (#154) (8caa296) -- Bump the github-actions group with 4 updates (#152) (88fa28e) -- Bump the github-actions group with 4 updates (#137) (54670cc) -- Bump github/codeql-action/analyze from 4.36.3 to 4.37.2 (#131) (f7d1b2a) -- Bump github/codeql-action/init from 4.36.3 to 4.37.2 (#132) (a79e6b2) -- Bump actions/checkout from 7.0.0 to 7.0.1 (#130) (9ade01f) -- Bump hyperpolymath/a2ml-validate-action from 59145c7d1039fa3059b3ecacdb50ee23d7505898 to 5468b7ff0f5129a74d25af5f2468df11a706dc70 (#134) (e9f4e08) -- Bump hyperpolymath/k9-validate-action from 2d96f43c538964b097d159ed3a56ba5b5ceca227 to 08958c9bab64f9941a85938a78122a0d4a3058e8 (#129) (d2e37ac) -- Bump github/codeql-action/analyze from 4.36.2 to 4.36.3 (#115) (8c13869) -- Bump github/codeql-action/init from 4.36.2 to 4.36.3 (#116) (60b0b29) -- Bump actions/cache from 6.0.0 to 6.1.0 (#113) (e8630e8) -- Bump github/codeql-action from 4.36.1 to 4.36.2 (#96) (0f0cf2f) -- Bump actions/upload-artifact from 5.0.0 to 7.0.1 (#94) (bf50a4e) -- Bump actions/download-artifact from 6.0.0 to 8.0.1 (#93) (0739268) -- Bump github/codeql-action from 4.34.0 to 4.36.1 (#92) (39b748a) -- Bump haskell-actions/setup from 2.7.5 to 2.11.0 (#68) (2ae2d5a) -- Bump actions/upload-pages-artifact from 3.0.1 to 5.0.0 (#67) (c902996) -- Bump actions/configure-pages from 5.0.0 to 6.0.0 (#65) (050d936) -- Bump actions/upload-artifact from 4.6.2 to 7.0.1 (#64) (1401d0b) -- Bump trufflesecurity/trufflehog from 3.93.8 to 3.95.3 (#63) (0402360) -- Bump actions/cache from 4.3.0 to 5.0.5 (#62) (1944bd5) -- Bump github/codeql-action from 4.32.6 to 4.36.0 (#61) (8bd70b7) -- Bump actions/github-script from 8.0.0 to 9.0.0 (#60) (943568a) -- Bump actions/deploy-pages from 4.0.5 to 5.0.0 (#59) (d2bbf8a) -- Bump trufflesecurity/trufflehog from 3.93.8 to 3.94.0 (8cc5a78) -- Bump trufflesecurity/trufflehog from 3.93.7 to 3.93.8 (0890277) -- Bump trufflesecurity/trufflehog from 3.93.6 to 3.93.7 (31292ec) -- Bump trufflesecurity/trufflehog from 3.93.4 to 3.93.6 (8f29647) -- Bump trufflesecurity/trufflehog from 3.93.3 to 3.93.4 (bff4326) -- Bump trufflesecurity/trufflehog from 3.93.1 to 3.93.3 (#24) (7fbab8e) -- Bump github/codeql-action from 4.32.1 to 4.32.2 (#23) (a36f7e2) -- Bump trufflesecurity/trufflehog from 3.93.0 to 3.93.1 (#22) (b78abd7) -- Bump github/codeql-action from 4.32.0 to 4.32.1 (#20) (5195125) -- Bump trufflesecurity/trufflehog from 3.92.5 to 3.93.0 (#21) (a5aef00) -- Bump actions/github-script from 7.0.1 to 8.0.0 (#18) (ce93d9b) -- Bump erlef/setup-beam from 1.17.5 to 1.20.4 (#17) (30d973f) -- Bump actions/checkout from 4.1.1 to 6.0.2 (#19) (7b00374) -- Bump github/codeql-action from 4.31.11 to 4.32.0 (#16) (004d691) -- Bump github/codeql-action from 4.31.10 to 4.31.11 (#15) (28bad6c) - -## [1.0.0] — 2026-01-17 - -### CI - -- Add hub-and-spoke mirror workflow (96c5ef6) - - -### Chores - -- Add RSR enforcement workflows (290a0dc) - - -### Fixed - -- Update editorconfig SHA and CodeQL language (3922b4b) - - -### Other - -- Add PMPL-1.0 license - -Co-Authored-By: Claude Opus 4.5 (65fd94b) -- Bump github/codeql-action from 4.31.9 to 4.31.10 (#12) - -Bumps [github/codeql-action](https://github.com/github/codeql-action) -from 4.31.9 to 4.31.10. -
-Release notes -

Sourced from github/codeql-action's -releases.

-
-

v4.31.10

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.10 - 12 Jan 2026

-
    -
  • Update default CodeQL bundle version to 2.23.9. #3393
  • -
-

See the full CHANGELOG.md -for more information.

-
-
-
-Changelog -

Sourced from github/codeql-action's -changelog.

-
-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

[UNRELEASED]

-

No user facing changes.

-

4.31.10 - 12 Jan 2026

-
    -
  • Update default CodeQL bundle version to 2.23.9. #3393
  • -
-

4.31.9 - 16 Dec 2025

-

No user facing changes.

-

4.31.8 - 11 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.8. #3354
  • -
-

4.31.7 - 05 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.7. #3343
  • -
-

4.31.6 - 01 Dec 2025

-

No user facing changes.

-

4.31.5 - 24 Nov 2025

-
    -
  • Update default CodeQL bundle version to 2.23.6. #3321
  • -
-

4.31.4 - 18 Nov 2025

-

No user facing changes.

-

4.31.3 - 13 Nov 2025

-
    -
  • CodeQL Action v3 will be deprecated in December 2026. The Action now -logs a warning for customers who are running v3 but could be running v4. -For more information, see Upcoming -deprecation of CodeQL Action v3.
  • -
  • Update default CodeQL bundle version to 2.23.5. #3288
  • -
-

4.31.2 - 30 Oct 2025

-

No user facing changes.

-

4.31.1 - 30 Oct 2025

-
    -
  • The add-snippets input has been removed from the -analyze action. This input has been deprecated since CodeQL -Action 3.26.4 in August 2024 when this removal was announced.
  • -
-

4.31.0 - 24 Oct 2025

- -
-

... (truncated)

-
-
-Commits -
    -
  • cdefb33 -Merge pull request #3394 -from github/update-v4.31.10-0fa411efd
  • -
  • cfa77c6 -Update changelog for v4.31.10
  • -
  • 0fa411e -Merge pull request #3393 -from github/update-bundle/codeql-bundle-v2.23.9
  • -
  • c284324 -Add changelog note
  • -
  • 83e7d00 -Update default bundle to codeql-bundle-v2.23.9
  • -
  • f6a16be -Merge pull request #3391 -from github/dependabot/npm_and_yarn/npm-minor-f1cdf5...
  • -
  • c1f5f1a -Rebuild
  • -
  • 1805d8d -Bump the npm-minor group with 2 updates
  • -
  • b2951d2 -Merge pull request #3353 -from github/kaspersv/bump-min-cli-v-for-overlay
  • -
  • 41448d9 -Merge pull request #3287 -from github/henrymercer/generate-mergeback-last
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=4.31.9&new-version=4.31.10)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (359f66b) -- Remove legacy README.md (primary content is in README.adoc) (89f4d0c) -- Add MAINTAINERS.adoc (ad0e847) -- Bump trufflesecurity/trufflehog from 3.92.3 to 3.92.4 (#7) - -Bumps -[trufflesecurity/trufflehog](https://github.com/trufflesecurity/trufflehog) -from 3.92.3 to 3.92.4. -
-Release notes -

Sourced from trufflesecurity/trufflehog's -releases.

-
-

v3.92.4

-

What's Changed

- -

Full Changelog: https://github.com/trufflesecurity/trufflehog/compare/v3.92.3...v3.92.4

-
-
-
-Commits -
    -
  • ef6e76c -enable line numbers for ghr (#4611)
  • -
  • 8c1219a -[INS-207] Add Role-Aware Resumption Support for Legacy S3 Scan (#4600)
  • -
  • 606a7ed -Update module golang.org/x/crypto to v0.45.0 [SECURITY] (#4562)
  • -
  • 8aea6cd -[INS-226] use pinned image for quay registry test (#4602)
  • -
  • 3cb2166 -Pagination and Rate-Limit Handling In Docker Registry Namespace API -Calls (#4...
  • -
  • 0fab92f -[INS-170] Unify JDBC URL parsing across detectors and analyzers (#4574)
  • -
  • See full diff in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=trufflesecurity/trufflehog&package-manager=github_actions&previous-version=3.92.3&new-version=3.92.4)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> -Co-authored-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (7bafa61) -- Bump actions/checkout from 4.1.1 to 6.0.1 (#6) - -Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 -to 6.0.1. -
-Release notes -

Sourced from actions/checkout's -releases.

-
-

v6.0.1

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v6...v6.0.1

-

v6.0.0

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v5.0.0...v6.0.0

-

v6-beta

-

What's Changed

-

Updated persist-credentials to store the credentials under -$RUNNER_TEMP instead of directly in the local git -config.

-

This requires a minimum Actions Runner version of v2.329.0 -to access the persisted credentials for Docker -container action scenarios.

-

v5.0.1

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v5...v5.0.1

-

v5.0.0

-

What's Changed

- -

⚠️ Minimum Compatible Runner Version

-

v2.327.1
-Release -Notes

-

Make sure your runner is updated to this version or newer to use this -release.

-

Full Changelog: https://github.com/actions/checkout/compare/v4...v5.0.0

-

v4.3.1

-

What's Changed

- - -
-

... (truncated)

-
-
-Changelog -

Sourced from actions/checkout's -changelog.

-
-

Changelog

-

v6.0.0

- -

v5.0.1

- -

v5.0.0

- -

v4.3.1

- -

v4.3.0

- -

v4.2.2

- -

v4.2.1

- -

v4.2.0

- -

v4.1.7

- -

v4.1.6

- -

v4.1.5

- - -
-

... (truncated)

-
-
-Commits - -
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=6.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (876a6e8) -- Bump webfactory/ssh-agent from 0.9.0 to 0.9.1 (#8) - -Bumps [webfactory/ssh-agent](https://github.com/webfactory/ssh-agent) -from 0.9.0 to 0.9.1. -
-Release notes -

Sourced from webfactory/ssh-agent's -releases.

-
-

v0.9.1

-

What's Changed

- -

New Contributors

- -

Full Changelog: https://github.com/webfactory/ssh-agent/compare/v0.9.0...v0.9.1

-
-
-
-Changelog -

Sourced from webfactory/ssh-agent's -changelog.

-
-

Changelog

-

All notable changes to this project will be documented in this -file.

-

The format is based on Keep a Changelog, -and this project adheres to Semantic Versioning.

-

[Unreleased]

-

v0.9.1 [2024-03-17]

-

Fixed

-
    -
  • Fix path used to execute ssh-agent in cleanup.js to respect custom -paths set by input (#235)
  • -
-

v0.9.0 [2024-02-06]

-

Changed

-
    -
  • Update all versions of actions/checkout to v4 (#199)
  • -
  • Update to Node 20 (#201)
  • -
-

v0.8.0 [2023-03-24]

-

Changed

-
    -
  • No longer writing GitHub's SSH host keys to known_hosts -(#171)
  • -
  • Update to actions/checkout@v3 (#143)
  • -
  • Allow the user to override the commands for git, ssh-agent, and -ssh-add (#154)
  • -
-

v0.7.0 [2022-10-19]

-

Added

-
    -
  • Add the log-public-key input that can be used to turn -off logging key identities (#122)
  • -
-

Fixed

-
    -
  • Fix path to git binary on Windows, assuming -GitHub-hosted runners (#136, -#137)
  • -
  • Fix a nonsensical log message (#139)
  • -
-

v0.6.0 [2022-10-19]

-

Changed

- -

v0.5.4 [2021-11-21]

-

Fixed

- -
-

... (truncated)

-
-
-Commits - -
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=webfactory/ssh-agent&package-manager=github_actions&previous-version=0.9.0&new-version=0.9.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (2172844) -- Bump ossf/scorecard-action from 2.4.0 to 2.4.3 (#9) - -Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) -from 2.4.0 to 2.4.3. -
-Release notes -

Sourced from ossf/scorecard-action's -releases.

-
-

v2.4.3

-

What's Changed

-

This update bumps the Scorecard version to the v5.3.0 release. For a -complete list of changes, please refer to the Scorecard -v5.3.0 release notes.

-

Documentation

- -

Other

- -

New Contributors

- -

Full Changelog: https://github.com/ossf/scorecard-action/compare/v2.4.2...v2.4.3

-

v2.4.2

-

What's Changed

-

This update bumps the Scorecard version to the v5.2.1 release. For a -complete list of changes, please refer to the Scorecard v5.2.0 -and v5.2.1 -release notes.

-

Full Changelog: https://github.com/ossf/scorecard-action/compare/v2.4.1...v2.4.2

-

v2.4.1

-

What's Changed

-
    -
  • This update bumps the Scorecard version to the v5.1.1 release. For a -complete list of changes, please refer to the v5.1.0 -and v5.1.1 -release notes.
  • -
  • Publishing results now uses half the API quota as before. The exact -savings depends on the repository in question. - -
  • -
  • Some errors were made into annotations to make them more visible - -
  • -
  • There is now an optional file_mode input which controls -how repository files are fetched from GitHub. The default is -archive, but git produces the most accurate -results for repositories with .gitattributes files at the -cost of analysis speed. - -
  • -
  • The underlying container for the action is now hosted -on GitHub Container Registry. There should be no functional changes. - -
  • -
-

Docs

- -

New Contributors

- -
-
-
-Commits -
    -
  • 4eaacf0 -bump docker to ghcr v2.4.3 (#1587)
  • -
  • 42e3a01 -:seedling: Bump the github-actions group with 3 updates (#1585)
  • -
  • 88c07ac -:seedling: Bump github.com/sigstore/cosign/v2 from 2.5.2 to 2.6.0 (#1579)
  • -
  • 6c690f2 -Bump github.com/ossf/scorecard/v5 from v5.2.1 to v5.3.0 (#1586)
  • -
  • 92083b5 -:book: Fix recommended command to test the image in development (#1583)
  • -
  • 7975ea6 -:seedling: Bump the docker-images group across 1 directory with 2 -updates (#1...
  • -
  • 0d1a743 -:seedling: Bump github.com/spf13/cobra from 1.9.1 to 1.10.1 (#1575)
  • -
  • 46e6e0c -:seedling: Bump the github-actions group with 2 updates (#1580)
  • -
  • c3f1350 -:seedling: Improve printing options (#1584)
  • -
  • 43e475b -:seedling: Bump golang.org/x/net from 0.42.0 to 0.44.0 (#1578)
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=ossf/scorecard-action&package-manager=github_actions&previous-version=2.4.0&new-version=2.4.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (48bbc37) -- Bump dtolnay/rust-toolchain from 56f84321dbccf38fb67ce29ab63e4754056677e0 to f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561 (#11) - -Bumps -[dtolnay/rust-toolchain](https://github.com/dtolnay/rust-toolchain) from -56f84321dbccf38fb67ce29ab63e4754056677e0 to -f7ccc83f9ed1e5b9c81d8a67d7ad1a747e22a561. -
-Commits -
    -
  • f7ccc83 -Merge pull request #177 -from dtolnay/permitcopyrename
  • -
  • 1c0547f -Permit cross-device copy
  • -
  • 0b1efab -Update actions/checkout@v5 -> v6
  • -
  • 0f44b27 -Add 1.91.1 patch release
  • -
  • 6d653ac -Merge pull request #171 -from dtolnay/up
  • -
  • 30dc51d -Update Linux arm64 runner to Ubuntu 24.04
  • -
  • e97e2d8 -Update actions/checkout@v4 -> v5
  • -
  • 3bd6ba1 -Merge pull request #168 -from dtolnay/sed
  • -
  • 0185c06 -Fix update-revs.sh to recognize only the intended required: -true
  • -
  • 350b817 -Merge pull request #166 -from dtolnay/fix1
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (db91c2b) -- Bump github/codeql-action from 3.27.0 to 4.31.9 (#10) - -Bumps [github/codeql-action](https://github.com/github/codeql-action) -from 3.27.0 to 4.31.9. -
-Release notes -

Sourced from github/codeql-action's -releases.

-
-

v4.31.9

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.9 - 16 Dec 2025

-

No user facing changes.

-

See the full CHANGELOG.md -for more information.

-

v4.31.8

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.8 - 11 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.8. #3354
  • -
-

See the full CHANGELOG.md -for more information.

-

v4.31.7

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.7 - 05 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.7. #3343
  • -
-

See the full CHANGELOG.md -for more information.

-

v4.31.6

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.6 - 01 Dec 2025

-

No user facing changes.

-

See the full CHANGELOG.md -for more information.

-

v4.31.5

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.5 - 24 Nov 2025

- -
-

... (truncated)

-
-
-Changelog -

Sourced from github/codeql-action's -changelog.

-
-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

[UNRELEASED]

-

No user facing changes.

-

4.31.9 - 16 Dec 2025

-

No user facing changes.

-

4.31.8 - 11 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.8. #3354
  • -
-

4.31.7 - 05 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.7. #3343
  • -
-

4.31.6 - 01 Dec 2025

-

No user facing changes.

-

4.31.5 - 24 Nov 2025

-
    -
  • Update default CodeQL bundle version to 2.23.6. #3321
  • -
-

4.31.4 - 18 Nov 2025

-

No user facing changes.

-

4.31.3 - 13 Nov 2025

-
    -
  • CodeQL Action v3 will be deprecated in December 2026. The Action now -logs a warning for customers who are running v3 but could be running v4. -For more information, see Upcoming -deprecation of CodeQL Action v3.
  • -
  • Update default CodeQL bundle version to 2.23.5. #3288
  • -
-

4.31.2 - 30 Oct 2025

-

No user facing changes.

-

4.31.1 - 30 Oct 2025

-
    -
  • The add-snippets input has been removed from the -analyze action. This input has been deprecated since CodeQL -Action 3.26.4 in August 2024 when this removal was announced.
  • -
-

4.31.0 - 24 Oct 2025

-
    -
  • Bump minimum CodeQL bundle version to 2.17.6. #3223
  • -
  • When SARIF files are uploaded by the analyze or -upload-sarif actions, the CodeQL Action automatically -performs post-processing steps to prepare the data for the upload. -Previously, these post-processing steps were only performed before an -upload took place. We are now changing this so that the post-processing -steps will always be performed, even when the SARIF files are not -uploaded. This does not change anything for the -upload-sarif action. For analyze, this may -affect Advanced Setup for CodeQL users who specify a value other than -always for the upload input. #3222
  • -
- -
-

... (truncated)

-
-
-Commits -
    -
  • 5d4e8d1 -Merge pull request #3371 -from github/update-v4.31.9-998798e34
  • -
  • 1dc115f -Update changelog for v4.31.9
  • -
  • 998798e -Merge pull request #3352 -from github/nickrolfe/jar-min-ff-cleanup
  • -
  • 5eb7519 -Merge pull request #3358 -from github/henrymercer/database-upload-telemetry
  • -
  • d29eddb -Extract version number to constant
  • -
  • e962687 -Merge branch 'main' into henrymercer/database-upload-telemetry
  • -
  • 19c7f96 -Rename isOverlayBase
  • -
  • ae5de9a -Use getErrorMessage in log too
  • -
  • 0cb8633 -Prefer performance.now()
  • -
  • c07cc0d -Merge pull request #3351 -from github/henrymercer/ghec-dr-determine-tools-vers...
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.27.0&new-version=4.31.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (fa9cd95) -- Ban Python completely (no exceptions) (3578391) -- Standardize repo structure (hyperpolymath/mustfile pattern) - -- Add .machine_readable/ with 6 SCM files (STATE, META, ECOSYSTEM, AGENTIC, NEUROSYM, PLAYBOOK) -- Add Mustfile and justfile (replacing any Makefiles) -- Update .claude/CLAUDE.md with .machine_readable reference -- Clean up duplicate documentation files - -🤖 Generated with [Claude Code](https://claude.com/claude-code) - -Co-Authored-By: Claude Opus 4.5 (ed73a90) -- Bump actions/checkout from 4.1.1 to 6.0.1 (#3) - -[//]: # (dependabot-start) -⚠️ **Dependabot is rebasing this PR** ⚠️ - -Rebasing might not happen immediately, so don't worry if this takes some -time. - -Note: if you make any changes to this PR yourself, they will take -precedence over the rebase. - ---- - -[//]: # (dependabot-end) - -Bumps [actions/checkout](https://github.com/actions/checkout) from 4.1.1 -to 6.0.1. -
-Release notes -

Sourced from actions/checkout's -releases.

-
-

v6.0.1

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v6...v6.0.1

-

v6.0.0

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v5.0.0...v6.0.0

-

v6-beta

-

What's Changed

-

Updated persist-credentials to store the credentials under -$RUNNER_TEMP instead of directly in the local git -config.

-

This requires a minimum Actions Runner version of v2.329.0 -to access the persisted credentials for Docker -container action scenarios.

-

v5.0.1

-

What's Changed

- -

Full Changelog: https://github.com/actions/checkout/compare/v5...v5.0.1

-

v5.0.0

-

What's Changed

- -

⚠️ Minimum Compatible Runner Version

-

v2.327.1
-Release -Notes

-

Make sure your runner is updated to this version or newer to use this -release.

-

Full Changelog: https://github.com/actions/checkout/compare/v4...v5.0.0

-

v4.3.1

-

What's Changed

- - -
-

... (truncated)

-
-
-Changelog -

Sourced from actions/checkout's -changelog.

-
-

Changelog

-

v6.0.0

- -

v5.0.1

- -

v5.0.0

- -

v4.3.1

- -

v4.3.0

- -

v4.2.2

- -

v4.2.1

- -

v4.2.0

- -

v4.1.7

- -

v4.1.6

- -

v4.1.5

- - -
-

... (truncated)

-
-
-Commits - -
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=actions/checkout&package-manager=github_actions&previous-version=4.1.1&new-version=6.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> -Co-authored-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (6c0f17a) -- Bump peter-evans/repository-dispatch from 3.0.0 to 4.0.1 (#5) - -Bumps -[peter-evans/repository-dispatch](https://github.com/peter-evans/repository-dispatch) -from 3.0.0 to 4.0.1. -
-Release notes -

Sourced from peter-evans/repository-dispatch's -releases.

-
-

v4.0.1

-

What's Changed

- -

Full Changelog: https://github.com/peter-evans/repository-dispatch/compare/v4.0.0...v4.0.1

-

Repository Dispatch v4.0.0

-

⚙️ Requires Actions -Runner v2.327.1 or later if you are using a self-hosted runner for -Node 24 support.

-

What's Changed

- - -
-

... (truncated)

-
-
-Commits -
    -
  • 28959ce -Fix node version in actions.yml (#433)
  • -
  • 25d29c2 -build(deps-dev): bump @​types/node in the npm group (#432)
  • -
  • 830136c -build(deps): bump the github-actions group with 3 updates (#431)
  • -
  • 2c856c6 -ci: update dependabot config
  • -
  • 6673907 -build(deps-dev): bump @​types/node from 18.19.127 to -18.19.129 (#429)
  • -
  • 952a211 -build(deps): bump peter-evans/repository-dispatch from 3 to 4 (#428)
  • -
  • 5fc4efd -docs: update readme
  • -
  • a628c95 -feat: v4 (#427)
  • -
  • de78ac1 -build(deps-dev): bump @​vercel/ncc from 0.38.3 to 0.38.4 -(#425)
  • -
  • f49fa7f -build(deps-dev): bump @​types/node from 18.19.124 to -18.19.127 (#426)
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=peter-evans/repository-dispatch&package-manager=github_actions&previous-version=3.0.0&new-version=4.0.1)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> -Co-authored-by: Jonathan D.A. Jewell <6759885+hyperpolymath@users.noreply.github.com> (a8430d3) -- Bump github/codeql-action from 3.27.0 to 4.31.9 (#4) - -Bumps [github/codeql-action](https://github.com/github/codeql-action) -from 3.27.0 to 4.31.9. -
-Release notes -

Sourced from github/codeql-action's -releases.

-
-

v4.31.9

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.9 - 16 Dec 2025

-

No user facing changes.

-

See the full CHANGELOG.md -for more information.

-

v4.31.8

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.8 - 11 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.8. #3354
  • -
-

See the full CHANGELOG.md -for more information.

-

v4.31.7

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.7 - 05 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.7. #3343
  • -
-

See the full CHANGELOG.md -for more information.

-

v4.31.6

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.6 - 01 Dec 2025

-

No user facing changes.

-

See the full CHANGELOG.md -for more information.

-

v4.31.5

-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

4.31.5 - 24 Nov 2025

- -
-

... (truncated)

-
-
-Changelog -

Sourced from github/codeql-action's -changelog.

-
-

CodeQL Action Changelog

-

See the releases -page for the relevant changes to the CodeQL CLI and language -packs.

-

[UNRELEASED]

-

No user facing changes.

-

4.31.9 - 16 Dec 2025

-

No user facing changes.

-

4.31.8 - 11 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.8. #3354
  • -
-

4.31.7 - 05 Dec 2025

-
    -
  • Update default CodeQL bundle version to 2.23.7. #3343
  • -
-

4.31.6 - 01 Dec 2025

-

No user facing changes.

-

4.31.5 - 24 Nov 2025

-
    -
  • Update default CodeQL bundle version to 2.23.6. #3321
  • -
-

4.31.4 - 18 Nov 2025

-

No user facing changes.

-

4.31.3 - 13 Nov 2025

-
    -
  • CodeQL Action v3 will be deprecated in December 2026. The Action now -logs a warning for customers who are running v3 but could be running v4. -For more information, see Upcoming -deprecation of CodeQL Action v3.
  • -
  • Update default CodeQL bundle version to 2.23.5. #3288
  • -
-

4.31.2 - 30 Oct 2025

-

No user facing changes.

-

4.31.1 - 30 Oct 2025

-
    -
  • The add-snippets input has been removed from the -analyze action. This input has been deprecated since CodeQL -Action 3.26.4 in August 2024 when this removal was announced.
  • -
-

4.31.0 - 24 Oct 2025

-
    -
  • Bump minimum CodeQL bundle version to 2.17.6. #3223
  • -
  • When SARIF files are uploaded by the analyze or -upload-sarif actions, the CodeQL Action automatically -performs post-processing steps to prepare the data for the upload. -Previously, these post-processing steps were only performed before an -upload took place. We are now changing this so that the post-processing -steps will always be performed, even when the SARIF files are not -uploaded. This does not change anything for the -upload-sarif action. For analyze, this may -affect Advanced Setup for CodeQL users who specify a value other than -always for the upload input. #3222
  • -
- -
-

... (truncated)

-
-
-Commits -
    -
  • 5d4e8d1 -Merge pull request #3371 -from github/update-v4.31.9-998798e34
  • -
  • 1dc115f -Update changelog for v4.31.9
  • -
  • 998798e -Merge pull request #3352 -from github/nickrolfe/jar-min-ff-cleanup
  • -
  • 5eb7519 -Merge pull request #3358 -from github/henrymercer/database-upload-telemetry
  • -
  • d29eddb -Extract version number to constant
  • -
  • e962687 -Merge branch 'main' into henrymercer/database-upload-telemetry
  • -
  • 19c7f96 -Rename isOverlayBase
  • -
  • ae5de9a -Use getErrorMessage in log too
  • -
  • 0cb8633 -Prefer performance.now()
  • -
  • c07cc0d -Merge pull request #3351 -from github/henrymercer/ghec-dr-determine-tools-vers...
  • -
  • Additional commits viewable in compare -view
  • -
-
-
- - -[![Dependabot compatibility -score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=github/codeql-action&package-manager=github_actions&previous-version=3.27.0&new-version=4.31.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores) - -Dependabot will resolve any conflicts with this PR as long as you don't -alter it yourself. You can also trigger a rebase manually by commenting -`@dependabot rebase`. - -[//]: # (dependabot-automerge-start) -[//]: # (dependabot-automerge-end) - ---- - -
-Dependabot commands and options -
- -You can trigger Dependabot actions by commenting on this PR: -- `@dependabot rebase` will rebase this PR -- `@dependabot recreate` will recreate this PR, overwriting any edits -that have been made to it -- `@dependabot merge` will merge this PR after your CI passes on it -- `@dependabot squash and merge` will squash and merge this PR after -your CI passes on it -- `@dependabot cancel merge` will cancel a previously requested merge -and block automerging -- `@dependabot reopen` will reopen this PR if it is closed -- `@dependabot close` will close this PR and stop Dependabot recreating -it. You can achieve the same result by closing it manually -- `@dependabot show ignore conditions` will show all -of the ignore conditions of the specified dependency -- `@dependabot ignore this major version` will close this PR and stop -Dependabot creating any more for this major version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this minor version` will close this PR and stop -Dependabot creating any more for this minor version (unless you reopen -the PR or upgrade to it yourself) -- `@dependabot ignore this dependency` will close this PR and stop -Dependabot creating any more for this dependency (unless you reopen the -PR or upgrade to it yourself) - - -
- -Signed-off-by: dependabot[bot] -Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> (c452393) -- Add license badges to README (6ea7de1) -- Add code of conduct (9e7b33d) -- Add contributing guide (a88ebf4) -- Add CodeQL security scanning (c0f670f) -- Add sponsorship configuration (39c4972) -- Add dependabot configuration (69c1a71) -- Add README.adoc and ROADMAP.adoc for project specification (#2) - -- README.adoc: Documents current project state (specification pending), - lists components (MAA Framework, Oblíbený language, Aletheia microkernel), - covers project scope, infrastructure, and language policy summary -- ROADMAP.adoc: Outlines 6 development phases from foundation through - ecosystem, includes architecture vision diagram - -Both files accurately reflect that this is currently a governance/ -infrastructure hub awaiting specification uploads. - -Co-authored-by: Claude (fe56bd2) -- Update README.adoc (310d8f4) -- Add instant-sync for automatic forge propagation (852e964) -- Update language policy: Add Gleam, Tauri 2.0+, Dioxus (6cd23c0) -- Add language policy CLAUDE.md (fa3e76b) -- Add README.adoc - -🤖 Generated with Claude Code (936f190) -- Remove contamination (3d9ba03) -- Create README.md (e955bc0) - - -### Security - -- Harden mirror workflow and add security documentation (#1) (238b896) - - diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc index bd2a83c..2d05a77 100644 --- a/CODE_OF_CONDUCT.adoc +++ b/CODE_OF_CONDUCT.adoc @@ -1,24 +1,36 @@ -== Contributor Covenant Code of Conduct +// SPDX-License-Identifier: CC-BY-SA-4.0 += Code of Conduct +:toc: -=== Our Pledge +== Our Pledge -We pledge to make participation a harassment-free experience for -everyone. +We pledge to make participation in this project a harassment-free +experience for everyone, regardless of age, body size, disability, +ethnicity, gender identity and expression, level of experience, +nationality, personal appearance, race, religion, or sexual identity and +orientation. -=== Our Standards +== Our Standards -*Positive behavior:* * Using welcoming language * Being respectful of -differing viewpoints * Accepting constructive criticism * Focusing on -what is best for the community +Examples of behaviour that creates a positive environment: -*Unacceptable behavior:* * Harassment, trolling, or personal attacks * -Publishing private information without permission +* Being respectful of differing viewpoints and experiences +* Giving and accepting constructive feedback +* Focusing on what is best for the community +* Showing empathy towards other community members -=== Enforcement +Examples of unacceptable behaviour: -Report issues to the maintainers. All complaints will be reviewed. +* Harassment, trolling, or insulting comments +* Publishing others' private information without permission +*Other conduct which could reasonably be considered inappropriate -=== Attribution +== Enforcement -Adapted from https://www.contributor-covenant.org/[Contributor Covenant] -v2.1. +Report violations to **j.d.a.jewell@open.ac.uk**. All complaints will be +reviewed and investigated promptly and fairly. Maintainers are obligated to +respect the privacy and security of the reporter. + +== Attribution + +Adapted from the Contributor Covenant, version 2.1. diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc index 64101d4..2d2f3b7 100644 --- a/CONTRIBUTING.adoc +++ b/CONTRIBUTING.adoc @@ -1,17 +1,43 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Contributing to maa-framework - -New contributors start at `QUICKSTART-DEV.adoc` (setup, build, test, and -the repo layout in one page). The long-form guide is -`.github/CONTRIBUTING.md` — note it still carries template placeholders -in places; treat it as an outline, not gospel. - -The rules that will block your PR if you miss them: - -* `main` merges squash-only, on PRs only, with signed commits - (Optimus-Branch ruleset, zero bypass actors — direct pushes fail). -* `just check` must pass locally: it mirrors the CI gate exactly - (build, test, fmt, clippy with warnings denied, zero-dependency). -* Normative state lives in `.machine_readable/6a2/STATE.a2ml` — read the - `[landmines]` section before touching CI, workflows, or contracts. += Contributing +:toc: + +== Getting Started + +[source,bash] +---- +git clone https://github.com/hyperpolymath/proofgateway +cd proofgateway +just check +---- + +`just check` is the same gate CI runs. It must pass before you open a pull +request. + +== Workflow + +. Fork the repository. +. Create a branch: `+git checkout -b feat/my-feature+`. +. Make your change, with tests. +. Run `+just check+`. +. Commit using Conventional Commits (`+feat:+`, `+fix:+`, `+docs:+`, `+chore:+`). +. Open a pull request. + +== Standards + +This project follows the RSR (Rhodium Standard Repository) criteria. Two +rules bite most often: + +* *No silent skips.* A recipe that echoes a message and exits 0 is a fake + gate. Fail loudly. +* *SPDX headers.* Every source file carries an `+SPDX-License-Identifier+` + in its first ten lines. + +== Language Policy + +Rust here is always *Rust/Creusot*: Rust plus the Creusot deductive verifier. `just proof` translates `+src/impl.rs+` and discharges every obligation with Why3/Z3/CVC5, exiting non-zero on any unproved goal; the main crate stays zero-dependency because the specifications are gated behind `+cfg(creusot)+`. + +== Review + +Pull requests require review before merge. See link:MAINTAINERS.adoc[MAINTAINERS.adoc] +for decision-making. diff --git a/aletheia/templates/rust/Cargo.toml b/Cargo.toml similarity index 87% rename from aletheia/templates/rust/Cargo.toml rename to Cargo.toml index 6648724..05cee7f 100644 --- a/aletheia/templates/rust/Cargo.toml +++ b/Cargo.toml @@ -1,11 +1,11 @@ [package] -name = "@@PROJECT_NAME@@" +name = "proofgateway" version = "0.1.0" edition = "2021" rust-version = "1.80" license = "MPL-2.0" -description = "@@PROJECT_DESCRIPTION@@" -repository = "@@REPO_URL@@" +description = "An RSR v2-compliant Rust/Creusot project." +repository = "https://github.com/hyperpolymath/proofgateway" # ZERO DEPENDENCIES — keeps this crate buildable with no network at all # (`cargo build --offline`) and RSR-Bronze compliant. Adding a dependency diff --git a/DELIVERY-186-197.md b/DELIVERY-186-197.md deleted file mode 100644 index a77d138..0000000 --- a/DELIVERY-186-197.md +++ /dev/null @@ -1,854 +0,0 @@ -# Delivering the two open issues in `hyperpolymath/maa-framework` - -**Status:** both delivered and verified in the working tree. **Nothing is committed yet.** -**Date:** 2026-09-22 · **Repo:** `hyperpolymath/maa-framework` (commit `939b8c3`) - -Your two additions to the brief — *make it standalone* and *Rust here is always Rust/Creusot* — are both built in. -One correction I need to flag on the licence, in the last section. - ---- - -## TL;DR - -| Issue | Status | Headline evidence | -|---|---|---| -| **#186** `create-template.sh` scaffolds retired v1 shape | **Delivered** — exceeds acceptance | Fresh scaffold now scores **26/26, Bronze + Silver ACHIEVED, exit 0** (was 14/26, NOT MET) | -| **#197** consolidate `Scanner::walk_files` traversals | **Delivered** | 7 traversals → 1; **212 ms → 150 ms** on an 18,602-file tree; verdicts byte-identical | - -Suite went from 68+47 to **72+48 = 120 tests**, clippy `-D warnings` clean, `cargo fmt --check` clean, `just check` exit 0. - ---- - -## Issue #186 — the generator emitted the retired v1 shape - -### Reproduced first - -I scaffolded with the unmodified generator and ran the unmodified checker: - -``` -$ create-template.sh repro-project rust && aletheia repro-project -Score: 14/26 checks passed (53.8%) -Bronze-level RSR compliance: NOT MET -``` - -Failing Bronze checks: `.github/`, `LICENSE` (it wrote `LICENSE.txt`), `.gitignore`+`.gitattributes`, -SPDX headers, CI pipeline. Exactly as filed. - -### What changed - -**1. A real v2 template** — `aletheia/templates/bronze-rust/`, 30 files replacing the single stale -`README-template.adoc`: - -``` -LICENSE + LICENSES/ MPL-2.0 + CC-BY-SA-4.0, full texts shipped in-tree -Justfile capital J, real recipes, no silent-skip -Cargo.toml zero dependencies, offline by construction -src/, tests/ working code + 8 tests -verification/ Rust/Creusot proof crate (see below) -.github/workflows/ ci.yml, hypatia-scan.yml, governance.yml, actions.lock -.machine_readable/ rsr-profile.a2ml capability declaration -.well-known/ security.txt, ai.txt, humans.txt -0-AI-MANIFEST.a2ml agent front door - README/SECURITY/CONTRIBUTING/CoC/CHANGELOG/MAINTAINERS .adoc -``` - -**2. A rewritten generator** — `scripts/create-template.sh`, 832 lines changed down to 334. -It now renders the template tree with 11 `@@PLACEHOLDER@@` tokens, and its help text documents both -what the v2 shape *is* and what it deliberately no longer emits. - -**3. A regression guard** — `test_scaffold_passes_bronze_and_silver` in `tests/integration_tests.rs`. -It runs the real generator, asserts no v1 artefact reappears, asserts no unresolved placeholder is -left, and runs the real checker over the output. The acceptance criterion is now enforced by CI, so -the template and the checker can't drift apart again without the suite going red. - -### Acceptance — met and exceeded - -The issue asked for "Bronze (ideally Silver)". A fresh scaffold now gets: - -``` -Score: 26/26 checks passed (100.0%) -Bronze-level RSR compliance: ACHIEVED -Silver-level RSR compliance: ACHIEVED ← the "ideally" -✅ No silent-skip in recipes [Gold] ← Gold's only check passes too -``` - -with **no hand edits**, and `just check` (build, test, fmt, clippy, deps-check) exits 0. - -### "Standalone" — nothing to download, and I proved it - -The generated project fetches nothing, and neither does the generator: - -- licence texts are **shipped in the template**, not `curl`ed (the old script fetched MIT from - opensource.org and Apache from apache.org, falling back to writing stub files on failure) -- no `flake.nix`, no Python/`flake8`, no Makefile, no Dockerfile -- the dead `gitlab.com/maa-framework/...` install URL is gone; the v1 GitLab mirror 403 is not - reintroduced anywhere -- zero dependencies, so `cargo build --offline` always succeeds - -Proven by running generation *and* build inside a network namespace with no network at all: - -``` -lo DOWN ; ping 1.1.1.1 → Network is unreachable - -GENERATED: 30 files -$ cargo build ← note: no --offline flag, and no network to fall back on - Finished `dev` profile -$ cargo test - test result: ok. 5 passed ... ok. 3 passed -``` - -### "Rust is always Rust/Creusot" — built in - -`verification/` is a Creusot proof crate carrying real `#[requires]` / `#[ensures]` obligations for -two functions in the main crate. It is **deliberately detached** from the Cargo workspace -(`exclude = ["verification"]`), because Creusot needs `creusot-contracts` + Why3 and the main crate -must stay zero-dependency. `just proof` / `just proof-prove` drive it; `just check` never needs it. - -Two honest caveats, both documented in `verification/README.adoc` rather than papered over: - -- **The obligations are not wired into CI yet.** Creusot is research software tracking a specific - nightly; a CI job would be non-reproducible until that nightly and the SMT solver set are pinned. - Shipping a job that can't run reproducibly would be the fake gate this estate explicitly bans. -- **The specs are mirrors, not single-source.** Creusot must see the annotated source, so - `verification/src/lib.rs` mirrors `src/`. Change one, change the other in the same commit. The - README notes the tighter `#[cfg_attr(creusot, …)]` + `include!` option if you want single-source later. - ---- - -## Issue #197 — consolidate `Scanner::walk_files` - -### Design: one traversal, four buckets - -Each check used to call `walk_files` for itself — seven full walks of the same tree in the same -order, differing only in which files they collected. Now one traversal fills a `ScanSet` with four -buckets (`all`, `spdx`, `secret`, `banned`), memoised in a `OnceCell` on the `Scanner`, so the seven -call sites read from it instead of re-walking. - -The saving is in the traversal (`read_dir` + `file_type` per entry), not the extension filter applied -afterwards. That's why the buckets pay off: `.rs` is an SPDX-header *and* a secret-scan extension, and -`.py` is secret-scanned *and* banned — one file now serves several checks in one pass. - -### Budget semantics - -The issue required **identical budget semantics**, so this is where the care went. A bucket accepts at -most `MAX_SCAN_FILES` *matches of its own* — mirroring the old behaviour where -`walk_files(Some(exts))` counted only files passing its filter, not every file seen. When a bucket -fills it stops growing and the traversal continues, so the other buckets still get their own first -50,000 matches. `MAX_SCAN_DEPTH`, `SKIP_DIR_NAMES`, submodule boundaries, `[ignore]` globs and the -never-follow-symlinks rule are untouched. The symlink sweep keeps its own separate budget. - -Four unit tests pin this, including that filling `all` does **not** consume the filtered buckets' budgets. - -One deliberate refinement, called out because it is a real (benign) difference: the truncation warning -now fires when a file is actually *refused*, rather than when a walk happens to pass the cap. Same -trigger condition in practice, but it now means "results really are partial". - -### Evidence - -**Fewer traversals, measured** on a synthetic tree of 18,602 files across 673 directories, best-of-10 -with release binaries: - -| | time | -|---|---| -| baseline (7 walks) | **212 ms** | -| new (1 walk) | **150 ms** | -| | **~29% faster overall; traversal itself ~7× reduced** | - -**Semantics preserved, checked** — old vs new binary on five repositories, comparing full output with -the timestamp line stripped: - -``` -IDENTICAL bigtree (18k files) IDENTICAL demo-service (fresh scaffold) -IDENTICAL maa-framework IDENTICAL aletheia -IDENTICAL standards (29 MB) -exit codes match: bigtree 1/1, demo-service 0/0, aletheia 0/0 -``` - -**Suite green** — 72 unit + 48 integration = 120 tests; clippy `-D warnings` clean; `cargo fmt --check` clean; -estate root `just check` exit 0; `just self-verify` 26/26. - ---- - -## What is left - -1. **Push the branch and open the PR.** Everything is committed locally — three commits, messages - below — but I have no push credentials, so nothing is on the remote yet. See "Commits". -2. **Rotate the GitHub token you pasted into chat.** Please treat it as compromised — see the note below. -3. **Decide on the remaining Tier-1 language templates.** The v1 generator offered `python`, - `typescript` and `go`. Those extensions are *banned* by the v2 estate language policy, so those - paths could never pass Bronze — I removed them rather than port them. Zig, Elixir, Haskell, Ada, - Agda and AffineScript are Tier-1 per your `standards` canon and are reasonable follow-on templates. -4. **Wire the proof gates into CI.** **Partly done in this pass.** Both templates ship an opt-in - `.github/workflows/proof.yml`. Attempting to execute them from scratch (below) found one real - defect in the Rust one, now fixed. Neither has run on a GitHub runner yet, so the templates - still do not claim CI-verified proofs — the first green run is what makes them load-bearing. -5. **Close #186 and #197** with the acceptance evidence above. - ---- - -## Two things worth your attention - -### 1. Your MPL-2.0 correction exposes drift inside `aletheia` itself - -You said MPL-2.0, and the estate agrees — but the checker's own directory disagrees with itself. -I first wrote PMPL-1.0 into the template from `aletheia/LICENSE`; you corrected it to MPL-2.0. Counting -the actual usage across the repo: - -``` -128 × MPL-2.0 ← dominant, and what aletheia's own src/*.rs headers say - 36 × CC-BY-SA-4.0 ← docs, consistent - 2 × PMPL-1.0-or-later ← the outliers -``` - -`aletheia/LICENSE` declares **Palimpsest PMPL-1.0-or-later**; `aletheia/LICENSES/` ships -`PMPL-1.0-or-later.txt` instead of `MPL-2.0.txt`; yet **aletheia's own source files carry -`SPDX-License-Identifier: MPL-2.0`**. The root repo is clean (full MPL-2.0 `LICENSE` text, -`LICENSES/{MPL-2.0,CC-BY-SA-4.0,AGPL-3.0-or-later}.txt`), so the drift is confined to the nested -`aletheia/` crate. - -Worth knowing that **`aletheia` cannot currently catch this**: `KNOWN_LICENSE_IDS` accepts both -`"Palimpsest"`/`"PMPL-1.0"` and `"Mozilla Public License"`/`"MPL-2.0"`, so `check_licence_class` -passes either way. That's a deliberate structural check (it only asserts *something* known is named), -and real classification is the hypatia oracle's job — but it means nothing in this repo will flag the -inconsistency. The template now emits MPL-2.0 throughout, per your correction. - -This is a separate piece of work from #186/#197, so I have **not** touched `aletheia/LICENSE`. -Say the word and I'll align it. - -### 2. That GitHub token - -You pasted a token mid-conversation, and I did not use it or add it to any remote: everything I needed (your repo, MaaXYZ, `standards`) was readable -anonymously, and the repo path you gave turned out to be redundant once you supplied the URL. -**Please revoke it at github.com/settings/tokens and issue a fresh one.** It lives in this -transcript now, and fine-grained PATs are exactly the credential the estate's own secret-scanner -workflow exists to catch. An earlier revision of this document also recorded the token's -visible prefix — the part GitHub itself shows in your token list — which was a mistake even -though that half is not usable as a credential. It has been removed. - ---- - -## Verification log - -Every claim above is reproducible. The commands, run in order: - -```bash -# #186 — reproduce the filed failure -bash aletheia/scripts/create-template.sh repro-project rust -aletheia repro-project # 14/26, NOT MET - -# #186 — after the fix -bash aletheia/scripts/create-template.sh demo-service -d "A demo service" -aletheia demo-service # 26/26, Bronze + Silver, exit 0 -cd demo-service && just check # exit 0 -cargo fmt --check && cargo clippy --offline --all-targets -- -D warnings - -# #186 — air-gap proof -unshare -rn bash -c 'cd /tmp/nettest && create-template.sh isolated-demo && cd isolated-demo && cargo build && cargo test' - -# #197 — correctness and cost -cargo test # 120 passed -cargo clippy --all-targets -- -D warnings # clean -diff <(baseline /tmp/bigtree) <(new /tmp/bigtree) # identical - -# estate gate -cd .. && just check && just self-verify # 26/26 -``` - ---- - -## Files touched - -``` -M aletheia/scripts/create-template.sh (six languages, fixed MOD_ADA derivation) -M aletheia/src/checks.rs (ScanSet + single traversal, +238/-…) -M aletheia/tests/integration_tests.rs (+82 scaffold guard, +143 six-language guard) -D aletheia/templates/bronze-rust/README-template.adoc (superseded) -+ aletheia/templates/common/** (16 shared files) -+ aletheia/templates/{rust,zig,elixir,haskell,ada,agda}/** (per-language overlays) -``` - -The follow-on touched, within those overlays: - -``` -rust src/impl.rs (new, single source of truth) src/lib.rs src/main.rs Cargo.toml - tests/integration_test.rs Justfile .gitignore README.adoc - verification/{Cargo.toml, src/lib.rs, why3find.json, README.adoc} -ada src/.ads src/.adb src/main.adb tests/run_tests.adb - .gpr tests/tests.gpr Justfile .gitignore README.adoc -zig test/integration_test.zig .github/workflows/ci.yml -elixir, haskell .github/workflows/ci.yml haskell/Justfile (@@ARGS@@ -> {{ARGS}}) -``` - -Environment note: `rust`, `just` and the release builds were installed into this sandbox, not committed. - ---- - -# Follow-on: the six-language template set, with proofs that actually run - -You asked two things after the first delivery: make `Rust/Creusot` and `Ada/SPARK` **real** rather -than aspirational, and get **all six** templates to 26/26. Both are done, and both were verified by -making the provers themselves give a verdict — including negative controls, so you can see the gates -actually fail when the claim is false. - -## Headline - -| | Result | -|---|---| -| Six-language sweep (real generator) | **rust · zig · elixir · haskell · ada · agda — all 26/26, Bronze + Silver, `just check` exit 0** | -| Rust/Creusot | **`Proved (2 files) ✔`** — Creusot 0.14 translates and Why3 discharges every obligation | -| Ada/SPARK | **35 checks, 100% proved** — `gnatprove --level=2`, Z3 + Alt-Ergo + CVC5 | -| Negative controls | Breaking either specification makes the corresponding `just proof` **exit 1** | -| aletheia suite | **72 + 49 = 121 tests**, clippy `-D warnings` clean, `cargo fmt --check` clean | -| Estate gate | root `just check` exit 0; `just self-verify` **26/26** | - -## Rust/Creusot is real now - -The first delivery shipped `verification/` with `#[requires]`/`#[ensures]` that had **never been run**. -It also used the pre-0.14 contract crate and a floating git branch. All of that is replaced. - -### The toolchain actually works - -Getting there took real work, because Creusot does not use released Why3: it pins forks. - -``` -nightly-2026-08-03 (rustup, + rustc-dev) # Creusot's rust-toolchain pin -opam switch → why3 # pinned to git-c369bc4c - git+https://gitlab.inria.fr/why3/why3.git -why3find # pinned to git-0f054b93 - git+https://github.com/creusot-rs/why3find.git -z3 4.13.3, cvc5 1.1.2 # 7 provers detected -cargo-creusot, creusot-rustc # from the Creusot tree -``` - -Three specific traps, recorded so nobody repeats them: - -1. **Released `why3` cannot even parse Creusot's output.** With stock Why3 1.8.2 the generated - `.coma` dies with `syntax error`; with the pinned commit it proves. The pin is not optional. -2. **Released `why3find` will not compile against the pinned Why3** (`Unbound record field - "Why3.Term.t_loc"`). Creusot's fork is required, in lockstep. -3. **`cargo-creusot` looks for `why3find` inside its own data dir**, not on `PATH`, and loads - provers from `$XDG_DATA_HOME/creusot/creusot_why3.conf`. This is where "Package 'creusot' not - found" came from: why3find resolves packages through `DUNE_DIR_LOCATIONS`, which `cargo-creusot` - sets — running `why3find` by hand does not. - -### The design: the proof cannot drift from the code - -The obvious Creusot layout is a second, annotated copy of the functions. That copy drifts, and then -the proof describes code that no longer exists — worse than no proof. This template removes the -possibility: - -```rust -// src/impl.rs — the single source of truth -#[cfg(creusot)] -use creusot_std::prelude::*; - -#[cfg_attr(creusot, requires(lo@ <= hi@))] -#[cfg_attr(creusot, ensures(lo@ <= result@ && result@ <= hi@))] -pub fn clamp(value: u32, lo: u32, hi: u32) -> u32 { ... } - -// src/lib.rs (main crate) include!("impl.rs"); -// verification/src/lib.rs (Creusot crate) include!("../../src/impl.rs"); -``` - -`creusot-rustc` is the only thing that sets `--cfg creusot`. Under plain `cargo build` every -`#[cfg_attr]` vanishes and the Creusot prelude is never imported, so the main crate keeps its -**zero-dependency, air-gapped** build. Under `cargo creusot`, Creusot verifies the *actual* function -bodies — the failure messages name `../../src/impl.rs`, which is the real file. - -### Evidence - -``` -$ just proof -Proved (verif/proj_rust_verification_rlib/clamp.coma) ✔ -Proved (verif/proj_rust_verification_rlib/midpoint.coma) ✔ -Proved (2 files) ✔ # exit 0 - -# negative control 1 — clamp: result <= hi - 1 -File ".../src/impl.rs", line 27: proof failed Goal Coma.vc_clamp: ✘ (2/3) -Error: 1 unproved file # exit 1 - -# negative control 2 — midpoint: result == (a + b) / 2 + 1 -File ".../src/impl.rs", line 45: proof failed Goal Coma.vc_midpoint: ✘ (4/5) -Error: 1 unproved file # exit 1 -``` - -### One specification had to change, and here is the honest reason - -The sample `mean_floor` was `(a & b) + ((a ^ b) >> 1)` — a neat overflow-free mean. **Creusot 0.14 -cannot verify it, and cannot verify anything about it.** The `@` view operator maps an integer to a -mathematical `Int`, and `creusot_std::logic` provides no `BitAnd`, `BitXor` or `Shr` for it; there is -no bitvector theory in the backend. This is not a missing postcondition — even with *no* `ensures` at -all, Creusot still has to discharge overflow-freedom for the `+`, and fails: - -``` -Goal Coma.vc_mean_floor: ✘ (1/2) # a function with no contract at all -``` - -So the template ships `midpoint` — the same idea as `a + (b - a) / 2`, which needs only linear -arithmetic and whose exact half-sum identity **is** proved: - -```rust -#[cfg_attr(creusot, requires(a@ <= b@))] -#[cfg_attr(creusot, ensures(a@ <= result@ && result@ <= b@))] -#[cfg_attr(creusot, ensures(result@ == (a@ + b@) / 2))] -pub fn midpoint(a: u32, b: u32) -> u32 { a + (b - a) / 2 } -``` - -This is written up in `verification/README.adoc` with the failing example, so the boundary is -documented rather than quietly worked around. - -## Ada/SPARK is real now - -The first delivery called it Ada/SPARK while the sources had **no `SPARK_Mode` and no `gnatprove`** — -only Ada 2012 runtime contracts, and `src/main.adb` full of `Ada.Text_IO`, exceptions and -`'Value`/`'Image`, none of which are in the SPARK subset. - -Now the core package declares `pragma SPARK_Mode (On);` and its contracts are statically proved: - -```ada -function Clamp (Value, Lo, Hi : U32) return U32 - with Pre => Lo <= Hi, - Post => Clamp'Result in Lo .. Hi; - -function Midpoint (A, B : U32) return U32 - with Pre => A <= B, - Post => Midpoint'Result in A .. B - and then BI (Midpoint'Result) = (BI (A) + BI (B)) / 2; -``` - -`BI` is a ghost function over `Ada.Numerics.Big_Numbers.Big_Integers.Unsigned_Conversions`, which is -how SPARK states a *mathematical* half-sum — U32 arithmetic would wrap. - -**The same exact-identity obligation that Rust proves, SPARK proves too.** That took four `pragma -Assert` stepping stones in the body (modular subtraction and division agreeing with their exact -integer counterparts, and the final addition not wrapping); without them the provers returned -"medium: postcondition might fail". - -### A fake gate, caught - -`gnatprove` **exits 0 when a check is unproved.** With a deliberately false postcondition it printed -`high: postcondition might fail` and still returned success — `just proof` would have been decorative -and every template would have looked green forever. The fix is `--checks-as-errors`, which now lives -in the GPR so a bare `gnatprove -P .gpr` is already correct: - -``` -$ just proof # false postcondition: Post => Clamp'Result in Lo .. Hi - 1 -proj_ada.ads:36:19: high: postcondition might fail -gnatprove: unproved check messages considered as errors -error: recipe `proof` failed on line 39 with exit code 1 # exit 1 - -$ just proof # restored -Total 35 . 35 (100%) # Z3, Alt-Ergo, CVC5 # exit 0 -``` - -Note also what is *not* proved: `src/main.adb` is `pragma SPARK_Mode (Off);` on purpose — the I/O -boundary is outside the SPARK subset. gnatprove skips it rather than pretending to verify it, and -that is stated in the README. - -## Three defects found while doing this that the first pass had missed - -These are the reason the follow-on was worth doing rather than just relabelling. - -1. **`@@ARGS@@` broke Haskell generation outright.** `templates/haskell/Justfile` used `@@ARGS@@`, - which is not a placeholder the generator knows. The generator's own unresolved-placeholder guard - then aborted: `create-template.sh foo -l haskell` exited 1 with *"the generator and the template - tree are out of sync"*. It is now `{{ARGS}}`, matching the other five templates. My earlier probe - had rendered templates directly and so had never exercised the guard. - -2. **`MOD_ADA` derivation was wrong for single-letter segments.** `g-ada` produced the Ada unit - `GAda`, but the template ships `g_ada.ads`; GNAT then looked for `gada.ads` and failed with - `file "gada.ads" not found`. Fixed by deriving the unit name from the project name directly - (`G_Ada`, `Proj_Ada`, `My_Neat_Project`) instead of inserting underscores at case boundaries in - the camel form. Verified clean across `g-ada`, `proj-ada`, `my-neat-project`, `ab-cd`, `a-b`, - `wtest` — with no `Naming` workaround needed. - -3. **`zig fmt --check` rejected the template's own test file** (a multi-line array literal needing - zig's column alignment). Restructured to one element per line, which formats stably. Zig is now - 26/26 instead of 25/26. - -Plus the Silver miss: **the three remaining actions are now genuinely SHA-pinned**, resolved from -real tags rather than invented: - -``` -mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 → v2.2.1 -erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124 # v1 → v1.24.1 -haskell-actions/setup@0f8e8c99d88aeb3fbfd523f1ef2c6f762d10d64d # v2 → v2.12.1 -``` - -`actions/checkout@v7.0.1` is left as-is: it is the estate's canonical ref and is covered by -`.github/workflows/actions.lock`, which is the lock mechanism the checker itself implements. - -## Build output no longer breaks the gate - -The one finding from the follow-on that was worth fixing immediately, rather than leaving as an -issue. Reproducing it first: - -``` -# a minimal compliant project, freshly built -$ aletheia . -Score: 20/26 checks passed (76.9%) Bronze-level RSR compliance: ACHIEVED - -# same tree, `.gitignore` present but not honoured by the scanner -$ aletheia . -Score: 18/26 checks passed (69.2%) Bronze-level RSR compliance: NOT MET -Fix Suggestions: - - SPDX license headers: Add SPDX-License-Identifier headers (first 10 lines) to: - obj/b__main.ads, obj/deep/gen.rs; v2 4.1.1. -``` - -Two things were wrong with that. The obvious one is that the gate was only meaningful on a clean -checkout. The dangerous one is that **any CI job running the gate after a build would fail**, which -is exactly the order the estate's own `just check` uses — so the gate was quietly unusable in the -arrangement it was most wanted. - -The scanner now reads `.gitignore` as it descends. Rules are pushed when the walk enters a -directory and popped on the way out, so a nested `.gitignore` stays scoped to its own subtree. -A directory-only rule (`obj/`) is evaluated against the entry's real file type, so it skips the -directory *without* exempting a file of the same name — a path string alone cannot tell those -apart, which is why the walk asks the type-aware question. - -Implemented: comments, blank lines, `!` negation with last-match-wins, trailing slash, -leading-slash anchoring, `*` crossing directory boundaries (matching this crate's existing -`glob_match`). **Not** implemented, and not claimed: character classes, backslash escapes, and -re-inclusion inside an ignored directory. - -It stays separate from the existing `[ignore]` config on purpose: `[ignore]` is a choice made in -aletheia's own configuration, whereas `.gitignore` is the repository's declaration of what is not -part of the published artefact. - -Evidence, on a freshly generated Rust template: - -``` -$ just check # builds, tests, lints — leaves target/ full of artefacts -$ aletheia . -Score: 26/26 checks passed (100.0%) Bronze + Silver ACHIEVED -``` - -Three integration tests and ten unit tests cover it, including the negative controls: a -non-ignored file with no SPDX header still reports, and a file whose name matches a directory-only -rule is still audited. - ---- - -## Commits - -Six commits, split so each is coherent and individually green when checked out. `#197` and the -`.gitignore` work share a file *and* interleave within the same function, so they are one commit -rather than a fabricated split. - -``` -47d9e3b perf(scanner): one traversal, and honour the repository's .gitignore - aletheia/src/checks.rs, aletheia/src/config.rs - -8327b13 feat(scaffold): emit the v2 six-language template set - aletheia/templates/**, aletheia/scripts/create-template.sh, - aletheia/tests/integration_tests.rs - -123710a docs: delivery write-up for #186 and #197 -de3e2e9 docs: explain why the six templates do not share one sample API - -b28e539 fix(ci): the Rust proof workflow could not have worked as written -a318d02 fix(ci): finish the Creusot install, and stop hard-coding the Why3 pin - aletheia/templates/rust/.github/workflows/proof.yml - - docs: record what running the proof workflows actually found - DELIVERY-186-197.md -``` - -The last two exist because the first version of that workflow was wrong and no amount of reading it -had shown that — see "Proof workflows: what *not yet executed* was hiding". - -Two things were deliberately left uncommitted: - -* `absolute-zero` shows as a deleted submodule. It was never initialised in this sandbox (there is - no network checkout of it), so committing the deletion would be wrong. `git submodule update - --init` restores it. -* The lost executable bits on `setup.sh`, the `.github/hooks/*` scripts and - `aletheia/scripts/install.sh` are restored, not committed — they changed because the sandbox - restore does not preserve modes, not because anything meant to change. - ---- - -## Proof workflows: what "not yet executed" was hiding - -Both proof workflows shipped with a caveat: written from commands run by hand, never executed as -workflows. Exercising them properly meant rebuilding the Creusot toolchain from nothing, because -this sandbox had lost it. That was worth doing — the Rust one was wrong in three separate ways. - -**What already held up.** Every command in the toolchain half ran exactly as written: the apt list, -`git clone`, `rustup toolchain install --component rustc-dev,llvm-tools`, `opam init --bare ---disable-sandboxing`, `opam switch create creusot ocaml-system`, and both `opam pin` commands for -Creusot's forks of why3 and why3find. - -One of those was already fixed for the right reason. Creusot's `rust-toolchain` file is TOML — -`channel = "nightly-2026-08-03"` — but has no `.toml` extension, so the obvious `head -1` yields -`[toolchain]` and the job installs the wrong toolchain. The workflow parses the key and fails -loudly if it cannot; Creusot's own installer parses the same key, so this is not just belt-and-braces. - -**What was wrong.** - -1. *It never installed `creusot-rustc` where `cargo creusot` looks.* Not on `PATH` — under its data - dir, along with the prelude and the generated `why3.conf`: - - ``` - creusot-rustc not found (expected at - "/home/user/.local/share/creusot/toolchains/nightly-2026-08-03/bin/creusot-rustc"). - You should reinstall Creusot. - ``` - - Installing the two binaries and running `cargo creusot config --update` leaves all three pieces - missing. Fixed by running Creusot's own installer for the rest. - -2. *It never installed the provers, or why3/why3find in the data dir either.* This is the - interesting one, because it fails much later and more confusingly. `why3` is launched with the - data dir's `bin` **first on `PATH`**, and `creusot_why3.conf` names provers by bare name - (`alt-ergo --timelimit %.t %f`). So: - - ``` - $ just proof - Error: 'why3find prove' failed to launch - Caused by: No such file or directory (os error 2) - ``` - - That is `alt-ergo` not existing. `cargo creusot` also resolves `why3` and `why3find` themselves - as `$XDG_DATA_HOME/creusot/bin/why3[find]`, not from `PATH` — so having them in an opam switch - is not enough either. The installer's `provers` component fetches the exact versions the drivers - name (alt-ergo 2.6.2, z3 4.15.3, cvc4 1.8, cvc5 1.3.1); apt `z3` is a different build behind the - same driver name, which is a quiet way to get different answers from the same proof. The - workflow now installs those, provides `why3`/`why3find` the way the installer's own `why3` - component does (it builds a second opam switch inside the data dir and pulls in the GTK why3 - IDE for the privilege; its last act is to symlink those two binaries, so we do that directly), - and asserts `cargo creusot version` resolves all four provers before attempting to prove. - -3. *Its Why3 pin was already stale.* The workflow hard-coded the fork commits; the checkout now - declares a different Why3 commit. A proof gate that silently changes toolchain underneath a - passing build is not a gate. The workflow now pins the Creusot revision and **derives** both - forks from that revision's `creusot-deps.opam`, failing if the parse comes up empty. - -**The gate, run for real.** On the rebuilt toolchain, `cargo creusot version` resolves all four -provers, and `just proof` in the generated template reports: - -``` -$ just proof -Proved (2 files) ✔ -exit 0 -``` - -with Why3 pinned to the same commit the workflow will use. The negative control — a false -postcondition, `result@ == (a@ + b@) / 2 + 1` — gives: - -``` -File ".../src/impl.rs", line 45: proof failed -Goal Coma.vc_midpoint: ✘ (4/5) -Error: 1 unproved file -Error: 'why3find prove' failed -exit 1 -``` - -**A false pass, and why it is written down here.** My first attempt at that negative control -reported `Proved (2 files)` and exit 0 — a false gate, which is the one result that must never be -waved away. It reproduced, deliberately: take a tree *together with its build output and its -`verif/` directory*, plant a false obligation in the shared `src/impl.rs`, run `just proof`, and -the run finishes in 0.01 s and reports success without re-translating the changed source file. Hit -the same tree after forcing a re-translation (`touch verification/src/lib.rs`) and it fails -correctly, as it does on a freshly generated tree. - -The practical consequence is small, and the templates are already safe: `verification/verif/`, -`verification/target/`, `*.coma` and `.why3find/` are all in the templates' `.gitignore`, so a -clone or a CI checkout never starts with stale proof state — CI runs from a clean tree by -construction. Locally, the lesson is to treat proof artefacts as build output: don't move a tree -around with them attached, and if a proof result looks wrong, force re-translation before believing -it. `cargo creusot clean` is a no-op in the healthy case ("No dangling files found", exit 0). - -**The Ada workflow had the same kind of hole.** Not the same hole — the same *species*. `gnatprove` -is a frontend, not a toolchain: the release archive that job downloads contains a single binary, no -compiler and no `gprbuild`. Nothing in `proof.yml` installed those, so the job would have failed at -`gprbuild --version` one step later. `ci.yml` in the same template has installed `gnat gprbuild` -since it was written; `proof.yml` was added later and forgot. Both files being in the same directory -is what makes that findable — and it is not findable by reading either one alone. - -**Ada, re-checked on the rebuilt toolchain.** The `gnatprove` asset the Ada workflow installs was -downloaded and its SHA-256 checked against the value hard-coded in the workflow -(`28fc3583…f4017` — matched), then the proof was run end-to-end on a freshly generated template: -**35 checks proved, 0 unproved, exit 0** (`Adafix.Clamp` 1 check, `Adafix.Midpoint` 34). The -negative control fails as it should: - -``` -$ just proof # false postcondition: Clamp'Result in Lo .. Hi - 1 -neg_ada.ads:36:19: high: postcondition might fail -gnatprove: unproved check messages considered as errors -exit 1 -``` - -**Two environment traps that look like template bugs and are not.** Worth recording because both -cost time here and will cost time for anyone else running these proofs in a small container: - -- *Memory.* Translating `creusot-std` on a 2 GB, swapless box gets SIGKILLed ("signal: 9") partway - through — it looks like a slow build, then dies. Dropping debuginfo for the proof run - (`CARGO_PROFILE_DEV_DEBUG=0 CARGO_INCREMENTAL=0`) makes it fit, and translation then takes about - 35 seconds. CI runners have room; a small local VM may not. -- *Disk.* `/tmp` here is a 993 MB tmpfs, and filling it with build trees makes the **generator** - fail with `cp: error writing '…/.gitattributes': No space left on device`. That reads as a - template defect and is nothing of the sort: a full disk fails whichever step needs to write next. - Generate and build under a directory on the main filesystem, and check `df` before diagnosing. - -**Re-verified on the rebased tree.** Before this was handed over, the commits were rebased onto -current upstream `main` (upstream had moved on by seven commits, all of them CHANGELOG churn). A -rebase is a rewrite, so nothing was assumed about it: the whole toolchain was rebuilt from nothing -and both proofs plus both negative controls were re-run *through the generator*, on the rebased -tree, rather than in the repo's template directory. - -``` -tree under test: a35ef12 (= upstream main + the delivery commits) - -rust positive : "Proved (2 files) ✔" exit 0 -rust negative : false postcondition (half-sum + 1) exit 1 -ada positive : Total 35 checks, 35 (100%) proved exit 0 -ada negative : false postcondition (Clamp'Result in Lo .. Hi - 1) exit 1 - -aletheia : 83 + 52 = 135 tests pass, fmt clean, clippy -D warnings clean -estate : just check exit 0; just self-verify 26/26, Bronze + Silver ACHIEVED -``` - -That also closes the gap this document previously carried about the rebased tree not having been -tested. Two things the rebuild taught, both now in `toolchain-rebuild/rebuild-toolchain.sh`: - -- `cargo creusot` resolves `creusot-rustc` at - `$XDG_DATA_HOME/creusot/toolchains//bin/creusot-rustc` and refuses to run without it, - even when the binary is installed and on `PATH`. Installing Creusot's own binaries is not enough - on its own; the toolchain-dir placement is part of the contract. -- `rustup toolchain install stable --component rustfmt clippy` fails with "invalid toolchain name: - 'clippy'" — the second value is read as a toolchain, not a component. Several components need one - comma-separated value. This is the same failure mode as the `rust-toolchain` parsing bug in the CI - job, in a different disguise: a tool argument silently reinterpreted. - -**Still unproven.** Neither workflow has run on a GitHub runner. That caveat stays until it does: -the commands are known-good, but "known-good commands in the right order in a YAML file" is a -weaker claim than a green run, and the templates are not claiming the stronger one. - - ---- - -## Findings I did not fix, for your judgement - -1. ~~**`aletheia` does not honour `.gitignore` when scanning.**~~ **Fixed in this pass** — see - "Build output no longer breaks the gate" below. It turned out to be worse than a clean-tree - annoyance: it also meant the gate would fail in any CI job that ran it after a build. - -2. ~~**The sample-function names now differ across templates.**~~ **Looked at again, and kept — - the difference is load-bearing.** Rust and Ada use `midpoint` (`a + (b - a) / 2`, precondition - `a ≤ b`); Zig, Elixir and Haskell use `meanFloor` (`(a & b) + ((a ^ b) >> 1)`, *total*, no - precondition). Agda is a proofs library rather than a sample API, and always was. - - The split follows the toolchains, not taste. The bit-trick is the better API — it is total, and - it is the reason it was chosen originally — but Creusot has no bitvector theory and SPARK's - provers cannot discharge the identity, so a proof-carrying template cannot ship it. Unifying - would mean adding an `a ≤ b` precondition to three languages that do not need one, purely for - cosmetic symmetry, and would make those three strictly worse. - - So the six templates are not identical on purpose. Each README states which formulation it ships - and why; if you would rather have uniformity over totality, say so and it is a small change. - -3. **`agda/.github/workflows/ci.yml` installs the distro's Agda**, not the 2.6.4.3 that - `agda/.tool-versions` pins. They happened to be the same version here (Debian 13's `agda` is - 2.6.4.3), so the local run says nothing either way about a different base image. The typecheck - is simple enough that a patch-level difference is unlikely to matter, but it is a pin the - workflow does not honour. Building 2.6.4.3 from source in CI would take longer than the job's - whole timeout, so the fix would be to relax the pin in `.tool-versions` rather than chase it. - -4. **`aletheia/LICENSE` still says PMPL-1.0-or-later** while its sources say MPL-2.0. Carried over - from the first delivery; unchanged, since you had not asked for it. - -## Where the toolchains live - -Everything heavy is installed under `/usr/local/` (Rust at `/usr/local/cargo` + `/usr/local/rustup`, -Zig at `/usr/local/zig`, `just` at `/usr/local/bin`; the language packages come from apt). Nothing -in the repo depends on any of it — the templates need a prover only to run `just proof`, and that is -the point of the standalone requirement. - -**Correction, recorded because the first version of this section was wrong.** It said that installing -outside `/home/user` meant the toolchain would survive between sessions. That was tested by the -sandbox resetting, and it is false: everything outside the workspace was reclaimed — Rust, Cargo, -`just`, Zig, opam, Creusot, `gnatprove` — leaving only the workspace itself. The practical position -is that **no toolchain location is durable here**, so the recipes below are written to be re-run, not -to be relied on. What makes that survivable is the repo's own property: nothing in it needs any of -this until you ask for a proof or a real-language build. - -For the record, the layout the rebuild scripts create, so a re-run lands in the same place: - -| Piece | Location | -|---|---| -| Rust stable + pinned nightly | `/usr/local/rustup`, `/usr/local/cargo` | -| `just`, Zig | `/usr/local/bin`, `/usr/local/zig` | -| gnatprove 13.2.0-1 | `/usr/local/gnatprove` (release archive; it is not an Alire component and `alr install` does not exist) | -| Creusot source | `/usr/local/creusot` | -| Creusot's opam switch | `/usr/local/opam` (switch `creusot`) | -| Creusot runtime layout | `/usr/local/share/creusot` — `bin/{why3,why3find,alt-ergo,z3,cvc4,cvc5}`, `toolchains//bin/creusot-rustc`, `share/why3find/packages/creusot` | - -Two settings in that layout are load-bearing and easy to miss. `XDG_DATA_HOME` decides where -`cargo-creusot` looks for *everything* — `why3`, `why3find`, the prover binaries and `creusot-rustc` -itself — and the default (`~/.local/share`) is excluded from the workspace snapshot, so a Creusot -runtime installed there is doubly lost. Point it at `/usr/local/share` (or anywhere you control) and -`cargo creusot version` can be made to resolve all four provers. The second is `RUSTUP_TOOLCHAIN`: -`creusot-rustc` and `cargo creusot` must both run under Creusot's pinned nightly, not the default one. - -`gnatprove`'s CI asset is pinned by URL **and verifies its SHA-256** (`28fc3583…f4017`, checked -against the real download). - -## Follow-on verification log - -```bash -# all six, via the real generator, gated on a clean tree -for L in rust zig elixir haskell ada agda; do - create-template.sh "g-$L" -l "$L" && cd "g-$L" - aletheia . # Score: 26/26 (100.0%) — Bronze + Silver ACHIEVED - just check # exit 0 -done - -# proofs -cd g-rust && just proof # Proved (2 files) ✔ exit 0 -cd g-ada && just proof # Total 35 . 35 (100%) exit 0 - -# negative controls — both must fail -# (clamp postcondition weakened) → proof failed, exit 1 -# (midpoint identity + 1) → proof failed, exit 1 -# (Clamp postcondition weakened) → "unproved check messages considered as errors", exit 1 - -# air-gap, no network namespace at all -unshare -rn bash -c 'cd airrust && cargo build --offline && cargo test --offline' # ok -unshare -rn bash -c 'cd airada && gprbuild -p -P airada.gpr' # ok - -# aletheia itself -cargo test # 83 + 52 = 135 passed -cargo clippy --all-targets -- -D warnings # clean -cargo fmt --check # clean -cd .. && just check && just self-verify # exit 0, 26/26 - -# the .gitignore fix, end to end -just check && aletheia . # 26/26 AFTER a build (was 18/26, Bronze NOT MET) -# negative control: remove .gitignore from the same tree - # 18/26, Bronze NOT MET, flags obj/b__main.ads - -# the Creusot toolchain, rebuilt from nothing and then used -cargo creusot version # alt-ergo 2.6.2 / z3 4.15.3 / cvc4 1.8 / cvc5 1.3.1 — all resolved - # (before the `provers` component: all four "not found") -cd g-rust && just proof # Proved (2 files) ✔ exit 0 - # re-run after re-pinning Why3 to the commit creusot-deps.opam - # declares: Proved (2 files) ✔ exit 0 -# negative control on a fresh tree: midpoint identity + 1 - # Goal Coma.vc_midpoint: ✘ (4/5), 1 unproved file, exit 1 -# same negative control on a tree copied WITH its verif/ + target/: "Proved (2 files)", exit 0 - # then `touch verification/src/lib.rs` → fails correctly, exit 1 - # (templates .gitignore verif/ and target/, so CI never sees this) - -# the Ada proof, re-run on a regenerated template after fixing proof.yml -rm -rf obj/gnatprove && just proof # exit 0 -# obj/gnatprove/gnatprove.out: Clamp 1 check + Midpoint 34 checks proved, 0 unproved - -# the proof workflows: commands run for real, not simulated -python3 -c "import yaml; yaml.safe_load(open('.../proof.yml'))" # valid YAML for both -# rust-toolchain channel parsed from the clone → nightly-2026-08-03 -# why3/why3find pins derived from creusot-deps.opam (the hard-coded one had gone stale) -# gnatprove asset sha256 verified against the workflow's pinned value -# four defects found (three Rust, one Ada) — all fixed; neither job has run on a runner yet -``` diff --git a/EXPLAINME-new.adoc b/EXPLAINME-new.adoc deleted file mode 100644 index f5fd6b2..0000000 --- a/EXPLAINME-new.adoc +++ /dev/null @@ -1,140 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -= MAA Framework — EXPLAINME -:toc: preamble -:toc-title: Contents -:icons: font -:doctype: article - -This file backs every factual claim in link:README.adoc[README.adoc] with code paths and honest caveats. Read it if you are doing due diligence on whether the story matches the code. - -== Claim-to-implementation map - -=== Aletheia builds, passes 68 unit + 47 integration tests, has zero dependencies - -[quote, README.adoc] -____ -Aletheia microkernel (Rust): Builds, 68 unit + 47 integration tests passing, zero dependencies.____ - -How this is implemented:: -`link:aletheia/[]` contains the Rust microkernel. `link:.github/workflows/rust-ci.yml[]` gates `cargo build` (debug + release), the full `cargo test` suite, formatting, `clippy -- -D warnings`, and the zero-dependency assertion — each mirrored by a root Justfile recipe (`just check`). CI is green. The `Cargo.toml` has zero external dependencies (enforced by CI). - -Caveat:: -68 unit + 47 integration tests pass. The integration suite *was* a specification for an unbuilt CLI (27 of 29 failing by design, #124); the CLI has since been built to the upstream RSR criteria and the suite is in the CI gate. - -=== CI is green across every enabled workflow and each gate has been shown capable of failing - -[quote, README.adoc] -____CI is green across every enabled workflow, and each gate has been shown capable of failing.____ - -How this is implemented:: -`.github/workflows/` at the repository root contains the CI gates. Each gate was verified to fail before being merged (standard CI hygiene). - -Caveat:: -The `aletheia/.github/workflows/` directory contains 16 workflow files that **have never executed**. GitHub Actions reads workflows at the repository root only. Those files are inert. See <<_aletheia_workflows_are_inert>>. - -=== CRG Tier-C test suite landed 2026-04-04 - -[quote, README.adoc] -____A CRG Tier-C test suite (unit, E2E, property, aspect, benchmarks) landed 2026-04-04.____ - -How this is implemented:: -`link:tests/[]` contains the test suite. The tier classification (CRG Tier-C) is documented in the estate standards. - -Caveat:: -The test suite exists and runs. The "E2E, property, aspect, benchmarks" categories describe the *structure* of the suite, not all passing results. The integration (E2E) tests pass: 45/45 since the CLI rebuild closed #124. - -=== absolute-zero is a git submodule pinned here - -[quote, README.adoc] -____The Certified Null Operation is developed in the standalone hyperpolymath/absolute-zero repository and pinned here as a git submodule.____ - -How this is implemented:: -`link:absolute-zero/[]` is a git submodule (PR #89). Development happens upstream; this pointer is bumped deliberately. - -Caveat:: -The submodule points to a specific commit in `absolute-zero`. Changes to CNO proofs happen upstream first, then the submodule pointer is updated here. There is no automated synchronisation. - -=== The MAA paradigm is symmetric accountability - -[quote, README.adoc] -____Mutually Assured Accountability (MAA) is a paradigm where accountability between system participants is symmetric.____ - -How this is implemented:: -The paradigm is defined in the governance and specification documents. Aletheia is the microkernel intended to enforce it. The paradigm definition exists; the enforcement mechanism is under construction. - -Caveat:: -**The paradigm is stated; the enforcement covers the offline file-presence subset.** Aletheia's CLI surface exists since #124 closed (26 checks, machine-readable output), so invocation is no longer the gap — depth of checking (proofs, containers, Scorecard) still lives with the hypatia oracle, not here. - -== Dogfooded Across The Account - -[cols="1,2,2", options="header"] -|=== -| Technology / Pattern | Used here | Also used in - -| Rust microkernel -| `aletheia/` -| link:https://github.com/hyperpolymath/typell[Typell] (kernel) - -| CNO formalisation -| `absolute-zero/` submodule -| link:https://github.com/hyperpolymath/absolute-zero[absolute-zero] (upstream) - -| Hub-and-spoke mirroring -| Root CI workflows -| Estate-wide pattern -|=== - -== Known gaps - -[[_aletheia_workflows_are_inert]] -[CAUTION] -==== -**`aletheia/.github/workflows/` is inert.** 16 workflow files exist inside `aletheia/` but GitHub Actions only reads `.github/workflows/` at the repository root. Since `aletheia/` is vendored as plain tracked files (not a submodule), these workflows have never executed. Gates must be added at the root level. -==== - -[CAUTION] -==== -**CLI surface rebuilt 2026-09-21 (was: unbuilt, #124).** 26 checks over the RSR v2 offline subset; 68 unit + 47 integration tests pass; hypatia oracle stays normative. -==== - -[CAUTION] -==== -**Clippy clean and blocking since 2026-09-21 (was: 23 findings, #125).** Findings wired into real code; `-D warnings` in CI and `just lint`. -==== - -[CAUTION] -==== -**Specifications are pending.** ROADMAP Phase 1 (specification publication) is incomplete. The project scope (11 domains) is stated; the formal specifications for most domains are not yet in-tree. -==== - -[CAUTION] -==== -**Oblíbený is at specification stage.** The reference language has no implementation in this repository. -==== - -[CAUTION] -==== -**Scope-to-implementation gap is large.** The stated scope covers 11 domains (security, AI ethics, dependability, language design, microkernel, RISC-V, sustainability, economics-as-code, distributed computing, reversibility, web protocols). Only the microkernel domain has running code. The remaining 10 domains are at specification or intention stage. -==== - -== Evidence Index - -[cols="2,3", options="header"] -|=== -| Path | Proves / Implements - -| `aletheia/` -| Rust microkernel (builds, 68 unit + 47 integration tests, zero dependencies) - -| `absolute-zero/` -| CNO formalisation (git submodule, upstream pointer) - -| `tests/` -| CRG Tier-C test suite (unit, E2E, property, aspect, benchmarks) - -| `.github/workflows/rust-ci.yml` -| Aletheia CI gate - -| `docs/STATE-OF-PLAY-2026-07-29.adoc` -| Full measured snapshot: CI, proof state, open questions -|=== diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc deleted file mode 100644 index dcdb443..0000000 --- a/EXPLAINME.adoc +++ /dev/null @@ -1,228 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= MAA Framework — Show Me The Receipts -:toc: -:toclevels: 3 -:icons: font -:author: Jonathan D.A. Jewell - -The README makes claims. This file backs them up with architectural context, -code paths, and honest caveats sufficient for an external reviewer to -understand what this monorepo coordinates and where the real implementation -lives. - -== Claim 1: "A full-stack paradigm for verifiably-compliant, secure, and sustainable systems" - -[quote, README] -____ -A full-stack, open-source paradigm for building verifiably-compliant, secure, -and sustainable systems. -____ - -=== How it works - -MAA stands for the three-component architecture that defines the framework: - -* *MAA Framework* — the overarching paradigm and governance rules -* *Oblíbený* — the reference programming language designed for the framework -* *Aletheia* — the microkernel providing the trusted execution base - -These are not deployed together as a single binary; they are coordinated design -decisions that ensure any system built under MAA carries provable correctness -guarantees at the language, OS, and application level simultaneously. - -The formal anchor is the Certified Null Operation (CNO) defined in -`absolute-zero/src/main.rs`: - -[source,rust] ----- -#![forbid(unsafe_code)] -fn main() { - // At the application level, the main function contains no instructions. - // The Rust runtime handles standard entry/exit procedures, resulting in - // a near-minimal binary that does nothing observable. -} ----- - -This is not a joke program. It is the formally verified base case — the proof -that a MAA-compliant executable can be reduced to provably nothing. Aletheia -builds on this: every system operation must have a well-defined inverse, and -the composition of an operation with its inverse must be provably equivalent -to the CNO. The CNO is the semantic zero of the framework. - -=== Code path - -`absolute-zero/` — CNO implementation in Rust. The VERIFICATION_RESULTS.adoc -documents which properties have been machine-checked. The `proofs/` directory -contains the formal proof objects. - -`aletheia/src/main.rs` — The microkernel entry point. Aletheia v1.9.0 -implements RSR Bronze and Silver compliance checks (51 total) against itself -and other repositories. The `checks.rs` module is the full check suite; -`types.rs` defines compliance levels; `confidence.rs` scores check results. -The zero-dependency, zero-unsafe design is intentional: the auditor tool that -certifies others must be auditable itself. - -The key architectural claim — "reversibility" — is formalised as: -`∀ σ : State, ∀ op : Operation, IsReversible(op) ↔ (∃ op_inv, (op ;; op_inv) ≡ CNO)` - -This formula lives in the Aletheia README and is backed by Coq/Idris2 proofs -in `aletheia/ffi/` and `absolute-zero/proofs/`. - -=== Honest caveat - -This is an *early-stage* project. The README explicitly marks status as -"Project Specification — implementation forthcoming." What is implemented -and machine-checked is the base case (CNO, absolute-zero) and the compliance -checker (Aletheia v1.9.0). The full MAA stack — including Oblíbený compiler, -r-Minix derivation, and complete reversibility proofs — is a multi-year -research programme. The honest status is: foundations are proven; the rest -is a roadmap. - -== Claim 2: "Aletheia is the microkernel; absolute-zero is the formal base case" - -[quote, README] -____ -Aletheia: Microkernel implementation. Absolute Zero: Reference language -designed for the framework. -____ - -(Note: The README table description is slightly misleading — Oblíbený is the -reference language; Absolute Zero is the CNO base case. Both live here.) - -=== How it works - -`aletheia/` is currently a Rust compliance-checker (v1.9.0), not yet a -microkernel. It functions as a self-verifying RSR compliance tool: -20/20 self-verification checks pass, 16 Bronze checks, 4 Silver checks, -zero dependencies, zero unsafe blocks, ~2100 lines of code. - -The path from current Aletheia (compliance checker) to r-Minix (reversible -microkernel) is documented in `aletheia/ROADMAP.adoc`. The compliance checker -phase exists to establish the auditing infrastructure before the kernel work -begins — you cannot verify a kernel without a trustworthy verifier. - -`absolute-zero/` provides reference benchmarks. Because the CNO exits cleanly -with no allocations, no I/O, and no side effects, it is the performance floor -against which any MAA-compliant program is measured. The benchmark suite in -`absolute-zero/benches/` captures this baseline. - -=== Honest caveat - -Aletheia v1.9.0 is a compliance-checking CLI, not a microkernel. The roadmap -targets "r-Minix" as a far-future goal (v5.0+). An external reviewer should -not expect kernel source code in this repo today. What they will find is a -high-quality Rust tool that enforces the compliance standards the eventual -kernel will need to satisfy. - -== Dogfooded Across The Account - -[cols="1,2,2"] -|=== -| Technology | Role in MAA Framework | Also Used In - -| *Rust* -| Primary language for Aletheia (compliance checker) and absolute-zero (CNO). -`#![forbid(unsafe_code)]` throughout. -| protocol-squisher, verisimdb, ephapax, gitbot-fleet - -| *Idris2* (planned, per ABI/FFI Universal Standard) -| Formal proofs of reversibility properties in `absolute-zero/proofs/` -| Gossamer, Groove, Stapeln, VeriSimDB — everywhere an ABI layer exists - -| *Zig FFI* (per ABI/FFI Universal Standard) -| `aletheia/ffi/` and `absolute-zero/ffi/` — C-compatible FFI for kernel -interfaces -| Gossamer, Stapeln, game-server-admin - -| *Stapeln containers* -| `stapeln.toml` + `Containerfile` for deployment -| All containerised services in the account - -| *Hypatia scanning* -| `.hypatia/` + CI workflows; Aletheia v1.9.0 is conceptually adjacent to -Hypatia's compliance scanner -| Every RSR repo in the account - -| *Contractile.just* -| `contractile.just` + `contractiles/` — shared build recipes -| Universal across hyperpolymath repos - -| *Guix (preferred dev shell; manifest.scm in tree)* -| `manifest.scm` ships rust/just/git (specs verified 2026-09-21; bare `guix shell` auto-discovers it). The #97 estate-standardization retired `flake.nix` but the manifest itself never landed until now -| Ecosystem-wide where adopted (no guix-nix-policy gate in this repo; criterion 1.2.1 + gates v0.3.0 only recognise `guix.scm` — filed upstream) -|=== - -== File Map - -[cols="1,3"] -|=== -| Path | What It Proves - -| `absolute-zero/` -| The Certified Null Operation reference implementation. `src/main.rs` is -the CNO binary (17 lines, zero allocations, zero I/O). `proofs/` contains -formal proof objects. `benches/` establishes the performance floor. -`MACHINE_VERIFICATION.adoc` documents what has been machine-checked. -`PROOF-CLASSIFICATION-CNO-FOCUSED.adoc` classifies CNO properties by proof -status. - -| `absolute-zero/src/main.rs` -| The literal anchor: `#![forbid(unsafe_code)]` + empty `main()`. Every -formal claim in MAA Framework ultimately bottoms out here. - -| `aletheia/` -| Microkernel research project (current phase: RSR compliance checker v1.9.0). -`src/checks.rs` — 51 compliance checks (Bronze + Silver). `src/types.rs` — -`ComplianceLevel`, `CheckResult`, severity types. `src/confidence.rs` — -check scoring. Zero dependencies, zero unsafe blocks. - -| `aletheia/src/` -| `main.rs` — CLI entry, `checks.rs` — full check suite, `config.rs` — -per-repo configuration, `output.rs` — report formatting, `types.rs` — type -definitions. - -| `aletheia/ROADMAP.adoc` -| The path from compliance checker (today) to r-Minix (future). The roadmap -milestones from v1.9.0 through v10.0.0 are the honest statement of what is -done and what is not. - -| `aletheia/ffi/` -| Zig FFI layer for kernel interface primitives (per ABI/FFI Universal Standard). - -| `aletheia/conformance/` -| Conformance test suite — checks that Aletheia correctly identifies -compliant and non-compliant repos. - -| `aletheia/extraction/` -| Metadata extraction utilities used during compliance scanning. - -| `absolute-zero/ffi/` -| Zig FFI primitives for CNO-adjacent low-level operations. - -| `absolute-zero/ECHIDNA_INTEGRATION.adoc` -| How ECHIDNA (the neurosymbolic theorem prover from neural-foundations) is -integrated to verify CNO properties. - -| `.machine_readable/` -| A2ML checkpoint files. Canonical AI session state. Six files including -AGENTIC.a2ml, NEUROSYM.a2ml, PLAYBOOK.a2ml beyond the standard three. - -| `.hypatia/` -| Hypatia rule overrides for this repo. - -| `contractiles/` -| Contractile.just ecosystem integration. - -| `TOPOLOGY.md` -| Visual diagram of MAA component relationships and the reversibility stack. -Start here for the full picture. -|=== - -== Questions? - -Start with `TOPOLOGY.md` for the architecture diagram, then -`absolute-zero/src/main.rs` for the formal base case, then -`aletheia/ROADMAP.adoc` for the honest statement of what exists today versus -what is planned. For the reversibility mathematics, see -`aletheia/README.adoc` which contains the Aletheia formula. diff --git a/GLOSSARY.adoc b/GLOSSARY.adoc deleted file mode 100644 index 25a67ed..0000000 --- a/GLOSSARY.adoc +++ /dev/null @@ -1,70 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= MAA Framework — Glossary -:toc: preamble -:toc-title: Contents -:icons: font -:doctype: article - -Cross-reference glossary for link:README.adoc[README.adoc], link:EXPLAINME.adoc[EXPLAINME.adoc], and the MAA Framework wiki. - -== Core concepts - -[[maa]] -Mutually Assured Accountability (MAA):: - A paradigm where accountability between system participants is symmetric: each party can verify the other's compliance, and no party is above audit. Named by analogy to Mutually Assured Destruction (MAD), but with accountability replacing destruction as the enforcement mechanism. - *Classification:* **project-specific** (paradigm definition). - -[[symmetric-accountability]] -Symmetric accountability:: - The core property of MAA: for any participants A and B, A can audit B *and* B can audit A. No participant holds a privileged audit position. - *Classification:* **project-specific**. - -== Components - -[[aletheia]] -Aletheia:: - The MAA microkernel implementation (Rust). Named after the Greek concept of truth as unconcealment. Currently: builds, passes 29 unit tests, zero dependencies. CLI surface is unbuilt (#124). - *Classification:* **project-specific**. - -[[oblibeny]] -Oblíbený:: - The reference language designed for the MAA framework. Named from Czech ("favourite" / "beloved"). Currently at specification stage with no in-tree implementation. - *Classification:* **project-specific**. - -[[cno-submodule]] -CNO submodule (`absolute-zero/`):: - A git submodule pointer to the `link:https://github.com/hyperpolymath/absolute-zero[absolute-zero]` repository, which formalises Certified Null Operations and Observational Null Disclosure. Development happens upstream; this pointer is bumped deliberately. - *Classification:* **project-specific** (integration point). - -== Architecture - -[[hub-and-spoke]] -Hub-and-spoke mirroring:: - The repository mirroring pattern: GitHub (canonical) → GitLab, Codeberg, Bitbucket. Automated via CI workflows. - *Classification:* **standard** (repository management). - -[[crg-tier-c]] -CRG Tier-C test suite:: - The estate's test suite classification covering unit, E2E, property, aspect, and benchmark tests. - *Classification:* **project-specific** (estate standard). - -[[inert-workflows]] -Inert workflows:: - GitHub Actions workflow files located inside a subdirectory (e.g., `aletheia/.github/workflows/`) that GitHub Actions never reads, because it only scans `.github/workflows/` at the repository root. These files exist but have never executed. - *Classification:* **standard** (GitHub Actions behaviour), surfaced as a **project-specific gotcha**. - -== Pronunciation guide - -[cols="1,2", options="header"] -|=== -| Written | Spoken - -| MAA -| "em-ay-ay" - -| Oblíbený -| "ob-lee-be-nee" (Czech) - -| Aletheia -| "al-uh-thay-uh" (Greek) -|=== diff --git a/GOVERNANCE.adoc b/GOVERNANCE.adoc deleted file mode 100644 index 9b836fb..0000000 --- a/GOVERNANCE.adoc +++ /dev/null @@ -1,60 +0,0 @@ -== Governance - -=== Overview - -This project is governed by the following principles and structures to -ensure transparent, inclusive, and effective decision-making. - -=== Roles and Responsibilities - -==== Maintainers - -Maintainers are responsible for: - Reviewing and merging pull requests - -Managing releases and versioning - Ensuring code quality and standards - -Triaging issues and bug reports - Community engagement and support - -==== Contributors - -Contributors are expected to: - Follow the code of conduct - Submit -well-documented pull requests - Write tests for new functionality - -Maintain existing tests - Update documentation as needed - -=== Decision Making - -==== Minor Changes - -* Can be made by any maintainer -* Include bug fixes, documentation updates, dependency updates - -==== Major Changes - -* Require discussion in issues or pull requests -* Include new features, architectural changes, API changes -* Need approval from at least 2 maintainers - -==== Breaking Changes - -* Require RFC (Request for Comments) process -* Need approval from majority of maintainers -* Must include migration guide - -=== Code of Conduct - -All participants are expected to follow our Code of Conduct. Violations -can be reported to the maintainers. - -=== Communication - -* *Issues*: For bug reports and feature requests -* *Discussions*: For questions and general discussion -* *Pull Requests*: For code contributions - -=== Licensing - -All contributions are made under the terms of the repository’s LICENSE -file. By submitting a pull request, you agree to license your -contributions accordingly. - -''''' - -_Last updated: 2026-07-18_ diff --git a/Justfile b/Justfile index ad91b21..0515796 100644 --- a/Justfile +++ b/Justfile @@ -1,129 +1,69 @@ # SPDX-License-Identifier: MPL-2.0 -# justfile - Just recipes for this project -# See: https://github.com/hyperpolymath/mustfile - -# Default recipe -import? "contractile.just" +# Justfile — build automation for proofgateway. +# See: https://github.com/casey/just +# +# Every recipe here is offline: the crate has zero dependencies, so +# `--offline` always succeeds. Recipes fail loudly — a recipe that echoes a +# message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). default: @just --list -# These recipes mirror the root `.github/workflows/rust-ci.yml` gate exactly, so -# `just check` locally means the same thing as CI. They MUST fail loudly — a recipe -# that echoes and exits 0 is a fake gate (issue #99 was exactly that). - -# Build aletheia (debug + release, locked) +# Build the crate (debug) build: - cd aletheia && cargo build --locked --all-targets - cd aletheia && cargo build --locked --release + cargo build --offline + +# Build the crate in release mode +build-release: + cargo build --offline --release -# Run aletheia's full test suite (unit + integration; mirrors rust-ci.yml) +# Run the binary; pass arguments after the recipe name +run *ARGS: + cargo run --offline --quiet -- {{ARGS}} + +# Run the full test suite (unit + integration) test: - # The integration suite used to be a specification for an unbuilt CLI - # (issue #124: 27 of 29 failing by design). It is green now, so the - # full suite runs here and in CI. - cd aletheia && cargo test --locked + cargo test --offline -# Check formatting (does not modify files) +# Check formatting without modifying files fmt: - cd aletheia && cargo fmt --check + cargo fmt --check # Apply formatting fmt-fix: - cd aletheia && cargo fmt + cargo fmt -# Lint aletheia, warnings denied (mirrors rust-ci.yml; issue #125) +# Lint with warnings denied lint: - # The `-- -D warnings` flag is here AND in rust-ci.yml in the same - # change, so local and CI never disagree about what "lint passes" means. - cd aletheia && cargo clippy --locked --all-targets -- -D warnings + cargo clippy --offline --all-targets -- -D warnings -# Enforce the zero-dependency RSR Bronze constraint (mirrors rust-ci.yml) +# Enforce the zero-dependency guarantee (RSR Bronze, air-gapped build) deps-check: #!/usr/bin/env bash set -euo pipefail - cd aletheia - if cargo tree --depth 1 | tail -n +2 | grep -q '[a-z]'; then - echo "ERROR: Aletheia must have zero dependencies (see aletheia/CLAUDE.md)" - cargo tree --depth 1 + if cargo tree --offline --depth 1 | tail -n +2 | grep -q '[a-z]'; then + echo "ERROR: dependencies detected — this crate must stay zero-dependency." + cargo tree --offline --depth 1 exit 1 fi echo "OK: zero dependencies" -# Everything the root CI gate runs, in the same order -check: build test fmt lint deps-check - -# Self-verify: run aletheia against this repository -self-verify: - cd aletheia && cargo run --locked --quiet -- .. +# Verify RSR compliance using the estate checker +verify: + aletheia . -# Clean build artifacts -clean: - cd aletheia && cargo clean +# --- Rust/Creusot deductive verification (opt-in) --------------------- +# These recipes need the Creusot toolchain (nightly Rust + Why3 + SMT +# solvers). The default build never needs it — see verification/README.adoc. -# Run panic-attacker pre-commit scan -assail: - @command -v panic-attack >/dev/null 2>&1 && panic-attack assail . || echo "panic-attack not found — install from https://github.com/hyperpolymath/panic-attacker" +# Translate the annotated source to Coma and discharge every obligation +# with Why3. Fails loudly on any unproved goal — this is a real gate. +proof: + cd verification && cargo creusot -# Self-diagnostic — checks dependencies, permissions, paths -doctor: - @echo "Running diagnostics for maa-framework..." - @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." +# Remove generated Creusot/Why3 artefacts +proof-clean: + cd verification && cargo creusot clean -# Auto-repair common issues -heal: - @echo "Attempting auto-repair for maa-framework..." - @echo "Fixing permissions..." - @find . -name "*.sh" -exec chmod +x {} \; 2>/dev/null || true - @echo "Cleaning stale caches..." - @rm -rf .cache/stale 2>/dev/null || true - @echo "Repair complete." - -# Guided tour of key features -tour: - @echo "=== maa-framework 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 "=== maa-framework Help ===" - @echo "Platform: $(uname -s) $(uname -m)" - @echo "Shell: $SHELL" - @echo "" - @echo "To report an issue:" - @echo " https://github.com/hyperpolymath/maa-framework/issues/new" - @echo "" - @echo "Include the output of 'just doctor' in your report." - - -# 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" - -# Generate a shields.io badge markdown for the current CRG grade -# 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)" +# Everything the CI gate runs, in the same order +check: build test fmt lint deps-check diff --git a/LICENSE b/LICENSE index 14e2f77..b306f89 100644 --- a/LICENSE +++ b/LICENSE @@ -1,373 +1,9 @@ -Mozilla Public License Version 2.0 -================================== +Mozilla Public License Version 2.0 (MPL-2.0) -1. Definitions --------------- +Code in this repository is licensed under the Mozilla Public License, +version 2.0. Documentation is licensed under Creative Commons +Attribution-ShareAlike 4.0 International (CC-BY-SA-4.0). -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. +See the LICENSES/ directory for the full license texts. -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -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 - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (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. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -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 http://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. +SPDX-License-Identifier: MPL-2.0 diff --git a/LICENSES/AGPL-3.0-or-later.txt b/LICENSES/AGPL-3.0-or-later.txt deleted file mode 100644 index be3f7b2..0000000 --- a/LICENSES/AGPL-3.0-or-later.txt +++ /dev/null @@ -1,661 +0,0 @@ - GNU AFFERO GENERAL PUBLIC LICENSE - Version 3, 19 November 2007 - - Copyright (C) 2007 Free Software Foundation, Inc. - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The GNU Affero General Public License is a free, copyleft license for -software and other kinds of works, specifically designed to ensure -cooperation with the community in the case of network server software. - - The licenses for most software and other practical works are designed -to take away your freedom to share and change the works. By contrast, -our General Public Licenses are intended to guarantee your freedom to -share and change all versions of a program--to make sure it remains free -software for all its users. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -them if you wish), that you receive source code or can get it if you -want it, that you can change the software or use pieces of it in new -free programs, and that you know you can do these things. - - Developers that use our General Public Licenses protect your rights -with two steps: (1) assert copyright on the software, and (2) offer -you this License which gives you legal permission to copy, distribute -and/or modify the software. - - A secondary benefit of defending all users' freedom is that -improvements made in alternate versions of the program, if they -receive widespread use, become available for other developers to -incorporate. Many developers of free software are heartened and -encouraged by the resulting cooperation. However, in the case of -software used on network servers, this result may fail to come about. -The GNU General Public License permits making a modified version and -letting the public access it on a server without ever releasing its -source code to the public. - - The GNU Affero General Public License is designed specifically to -ensure that, in such cases, the modified source code becomes available -to the community. It requires the operator of a network server to -provide the source code of the modified version running there to the -users of that server. Therefore, public use of a modified version, on -a publicly accessible server, gives the public access to the source -code of the modified version. - - An older license, called the Affero General Public License and -published by Affero, was designed to accomplish similar goals. This is -a different license, not a version of the Affero GPL, but Affero has -released a new version of the Affero GPL which permits relicensing under -this license. - - The precise terms and conditions for copying, distribution and -modification follow. - - TERMS AND CONDITIONS - - 0. Definitions. - - "This License" refers to version 3 of the GNU Affero General Public License. - - "Copyright" also means copyright-like laws that apply to other kinds of -works, such as semiconductor masks. - - "The Program" refers to any copyrightable work licensed under this -License. Each licensee is addressed as "you". "Licensees" and -"recipients" may be individuals or organizations. - - To "modify" a work means to copy from or adapt all or part of the work -in a fashion requiring copyright permission, other than the making of an -exact copy. The resulting work is called a "modified version" of the -earlier work or a work "based on" the earlier work. - - A "covered work" means either the unmodified Program or a work based -on the Program. - - To "propagate" a work means to do anything with it that, without -permission, would make you directly or secondarily liable for -infringement under applicable copyright law, except executing it on a -computer or modifying a private copy. Propagation includes copying, -distribution (with or without modification), making available to the -public, and in some countries other activities as well. - - To "convey" a work means any kind of propagation that enables other -parties to make or receive copies. Mere interaction with a user through -a computer network, with no transfer of a copy, is not conveying. - - An interactive user interface displays "Appropriate Legal Notices" -to the extent that it includes a convenient and prominently visible -feature that (1) displays an appropriate copyright notice, and (2) -tells the user that there is no warranty for the work (except to the -extent that warranties are provided), that licensees may convey the -work under this License, and how to view a copy of this License. If -the interface presents a list of user commands or options, such as a -menu, a prominent item in the list meets this criterion. - - 1. Source Code. - - The "source code" for a work means the preferred form of the work -for making modifications to it. "Object code" means any non-source -form of a work. - - A "Standard Interface" means an interface that either is an official -standard defined by a recognized standards body, or, in the case of -interfaces specified for a particular programming language, one that -is widely used among developers working in that language. - - The "System Libraries" of an executable work include anything, other -than the work as a whole, that (a) is included in the normal form of -packaging a Major Component, but which is not part of that Major -Component, and (b) serves only to enable use of the work with that -Major Component, or to implement a Standard Interface for which an -implementation is available to the public in source code form. A -"Major Component", in this context, means a major essential component -(kernel, window system, and so on) of the specific operating system -(if any) on which the executable work runs, or a compiler used to -produce the work, or an object code interpreter used to run it. - - The "Corresponding Source" for a work in object code form means all -the source code needed to generate, install, and (for an executable -work) run the object code and to modify the work, including scripts to -control those activities. However, it does not include the work's -System Libraries, or general-purpose tools or generally available free -programs which are used unmodified in performing those activities but -which are not part of the work. For example, Corresponding Source -includes interface definition files associated with source files for -the work, and the source code for shared libraries and dynamically -linked subprograms that the work is specifically designed to require, -such as by intimate data communication or control flow between those -subprograms and other parts of the work. - - The Corresponding Source need not include anything that users -can regenerate automatically from other parts of the Corresponding -Source. - - The Corresponding Source for a work in source code form is that -same work. - - 2. Basic Permissions. - - All rights granted under this License are granted for the term of -copyright on the Program, and are irrevocable provided the stated -conditions are met. This License explicitly affirms your unlimited -permission to run the unmodified Program. The output from running a -covered work is covered by this License only if the output, given its -content, constitutes a covered work. This License acknowledges your -rights of fair use or other equivalent, as provided by copyright law. - - You may make, run and propagate covered works that you do not -convey, without conditions so long as your license otherwise remains -in force. You may convey covered works to others for the sole purpose -of having them make modifications exclusively for you, or provide you -with facilities for running those works, provided that you comply with -the terms of this License in conveying all material for which you do -not control copyright. Those thus making or running the covered works -for you must do so exclusively on your behalf, under your direction -and control, on terms that prohibit them from making any copies of -your copyrighted material outside their relationship with you. - - Conveying under any other circumstances is permitted solely under -the conditions stated below. Sublicensing is not allowed; section 10 -makes it unnecessary. - - 3. Protecting Users' Legal Rights From Anti-Circumvention Law. - - No covered work shall be deemed part of an effective technological -measure under any applicable law fulfilling obligations under article -11 of the WIPO copyright treaty adopted on 20 December 1996, or -similar laws prohibiting or restricting circumvention of such -measures. - - When you convey a covered work, you waive any legal power to forbid -circumvention of technological measures to the extent such circumvention -is effected by exercising rights under this License with respect to -the covered work, and you disclaim any intention to limit operation or -modification of the work as a means of enforcing, against the work's -users, your or third parties' legal rights to forbid circumvention of -technological measures. - - 4. Conveying Verbatim Copies. - - You may convey verbatim copies of the Program's source code as you -receive it, in any medium, provided that you conspicuously and -appropriately publish on each copy an appropriate copyright notice; -keep intact all notices stating that this License and any -non-permissive terms added in accord with section 7 apply to the code; -keep intact all notices of the absence of any warranty; and give all -recipients a copy of this License along with the Program. - - You may charge any price or no price for each copy that you convey, -and you may offer support or warranty protection for a fee. - - 5. Conveying Modified Source Versions. - - You may convey a work based on the Program, or the modifications to -produce it from the Program, in the form of source code under the -terms of section 4, provided that you also meet all of these conditions: - - a) The work must carry prominent notices stating that you modified - it, and giving a relevant date. - - b) The work must carry prominent notices stating that it is - released under this License and any conditions added under section - 7. This requirement modifies the requirement in section 4 to - "keep intact all notices". - - c) You must license the entire work, as a whole, under this - License to anyone who comes into possession of a copy. This - License will therefore apply, along with any applicable section 7 - additional terms, to the whole of the work, and all its parts, - regardless of how they are packaged. This License gives no - permission to license the work in any other way, but it does not - invalidate such permission if you have separately received it. - - d) If the work has interactive user interfaces, each must display - Appropriate Legal Notices; however, if the Program has interactive - interfaces that do not display Appropriate Legal Notices, your - work need not make them do so. - - A compilation of a covered work with other separate and independent -works, which are not by their nature extensions of the covered work, -and which are not combined with it such as to form a larger program, -in or on a volume of a storage or distribution medium, is called an -"aggregate" if the compilation and its resulting copyright are not -used to limit the access or legal rights of the compilation's users -beyond what the individual works permit. Inclusion of a covered work -in an aggregate does not cause this License to apply to the other -parts of the aggregate. - - 6. Conveying Non-Source Forms. - - You may convey a covered work in object code form under the terms -of sections 4 and 5, provided that you also convey the -machine-readable Corresponding Source under the terms of this License, -in one of these ways: - - a) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by the - Corresponding Source fixed on a durable physical medium - customarily used for software interchange. - - b) Convey the object code in, or embodied in, a physical product - (including a physical distribution medium), accompanied by a - written offer, valid for at least three years and valid for as - long as you offer spare parts or customer support for that product - model, to give anyone who possesses the object code either (1) a - copy of the Corresponding Source for all the software in the - product that is covered by this License, on a durable physical - medium customarily used for software interchange, for a price no - more than your reasonable cost of physically performing this - conveying of source, or (2) access to copy the - Corresponding Source from a network server at no charge. - - c) Convey individual copies of the object code with a copy of the - written offer to provide the Corresponding Source. This - alternative is allowed only occasionally and noncommercially, and - only if you received the object code with such an offer, in accord - with subsection 6b. - - d) Convey the object code by offering access from a designated - place (gratis or for a charge), and offer equivalent access to the - Corresponding Source in the same way through the same place at no - further charge. You need not require recipients to copy the - Corresponding Source along with the object code. If the place to - copy the object code is a network server, the Corresponding Source - may be on a different server (operated by you or a third party) - that supports equivalent copying facilities, provided you maintain - clear directions next to the object code saying where to find the - Corresponding Source. Regardless of what server hosts the - Corresponding Source, you remain obligated to ensure that it is - available for as long as needed to satisfy these requirements. - - e) Convey the object code using peer-to-peer transmission, provided - you inform other peers where the object code and Corresponding - Source of the work are being offered to the general public at no - charge under subsection 6d. - - A separable portion of the object code, whose source code is excluded -from the Corresponding Source as a System Library, need not be -included in conveying the object code work. - - A "User Product" is either (1) a "consumer product", which means any -tangible personal property which is normally used for personal, family, -or household purposes, or (2) anything designed or sold for incorporation -into a dwelling. In determining whether a product is a consumer product, -doubtful cases shall be resolved in favor of coverage. For a particular -product received by a particular user, "normally used" refers to a -typical or common use of that class of product, regardless of the status -of the particular user or of the way in which the particular user -actually uses, or expects or is expected to use, the product. A product -is a consumer product regardless of whether the product has substantial -commercial, industrial or non-consumer uses, unless such uses represent -the only significant mode of use of the product. - - "Installation Information" for a User Product means any methods, -procedures, authorization keys, or other information required to install -and execute modified versions of a covered work in that User Product from -a modified version of its Corresponding Source. The information must -suffice to ensure that the continued functioning of the modified object -code is in no case prevented or interfered with solely because -modification has been made. - - If you convey an object code work under this section in, or with, or -specifically for use in, a User Product, and the conveying occurs as -part of a transaction in which the right of possession and use of the -User Product is transferred to the recipient in perpetuity or for a -fixed term (regardless of how the transaction is characterized), the -Corresponding Source conveyed under this section must be accompanied -by the Installation Information. But this requirement does not apply -if neither you nor any third party retains the ability to install -modified object code on the User Product (for example, the work has -been installed in ROM). - - The requirement to provide Installation Information does not include a -requirement to continue to provide support service, warranty, or updates -for a work that has been modified or installed by the recipient, or for -the User Product in which it has been modified or installed. Access to a -network may be denied when the modification itself materially and -adversely affects the operation of the network or violates the rules and -protocols for communication across the network. - - Corresponding Source conveyed, and Installation Information provided, -in accord with this section must be in a format that is publicly -documented (and with an implementation available to the public in -source code form), and must require no special password or key for -unpacking, reading or copying. - - 7. Additional Terms. - - "Additional permissions" are terms that supplement the terms of this -License by making exceptions from one or more of its conditions. -Additional permissions that are applicable to the entire Program shall -be treated as though they were included in this License, to the extent -that they are valid under applicable law. If additional permissions -apply only to part of the Program, that part may be used separately -under those permissions, but the entire Program remains governed by -this License without regard to the additional permissions. - - When you convey a copy of a covered work, you may at your option -remove any additional permissions from that copy, or from any part of -it. (Additional permissions may be written to require their own -removal in certain cases when you modify the work.) You may place -additional permissions on material, added by you to a covered work, -for which you have or can give appropriate copyright permission. - - Notwithstanding any other provision of this License, for material you -add to a covered work, you may (if authorized by the copyright holders of -that material) supplement the terms of this License with terms: - - a) Disclaiming warranty or limiting liability differently from the - terms of sections 15 and 16 of this License; or - - b) Requiring preservation of specified reasonable legal notices or - author attributions in that material or in the Appropriate Legal - Notices displayed by works containing it; or - - c) Prohibiting misrepresentation of the origin of that material, or - requiring that modified versions of such material be marked in - reasonable ways as different from the original version; or - - d) Limiting the use for publicity purposes of names of licensors or - authors of the material; or - - e) Declining to grant rights under trademark law for use of some - trade names, trademarks, or service marks; or - - f) Requiring indemnification of licensors and authors of that - material by anyone who conveys the material (or modified versions of - it) with contractual assumptions of liability to the recipient, for - any liability that these contractual assumptions directly impose on - those licensors and authors. - - All other non-permissive additional terms are considered "further -restrictions" within the meaning of section 10. If the Program as you -received it, or any part of it, contains a notice stating that it is -governed by this License along with a term that is a further -restriction, you may remove that term. If a license document contains -a further restriction but permits relicensing or conveying under this -License, you may add to a covered work material governed by the terms -of that license document, provided that the further restriction does -not survive such relicensing or conveying. - - If you add terms to a covered work in accord with this section, you -must place, in the relevant source files, a statement of the -additional terms that apply to those files, or a notice indicating -where to find the applicable terms. - - Additional terms, permissive or non-permissive, may be stated in the -form of a separately written license, or stated as exceptions; -the above requirements apply either way. - - 8. Termination. - - You may not propagate or modify a covered work except as expressly -provided under this License. Any attempt otherwise to propagate or -modify it is void, and will automatically terminate your rights under -this License (including any patent licenses granted under the third -paragraph of section 11). - - However, if you cease all violation of this License, then your -license from a particular copyright holder is reinstated (a) -provisionally, unless and until the copyright holder explicitly and -finally terminates your license, and (b) permanently, if the copyright -holder fails to notify you of the violation by some reasonable means -prior to 60 days after the cessation. - - Moreover, your license from a particular copyright holder is -reinstated permanently if the copyright holder notifies you of the -violation by some reasonable means, this is the first time you have -received notice of violation of this License (for any work) from that -copyright holder, and you cure the violation prior to 30 days after -your receipt of the notice. - - Termination of your rights under this section does not terminate the -licenses of parties who have received copies or rights from you under -this License. If your rights have been terminated and not permanently -reinstated, you do not qualify to receive new licenses for the same -material under section 10. - - 9. Acceptance Not Required for Having Copies. - - You are not required to accept this License in order to receive or -run a copy of the Program. Ancillary propagation of a covered work -occurring solely as a consequence of using peer-to-peer transmission -to receive a copy likewise does not require acceptance. However, -nothing other than this License grants you permission to propagate or -modify any covered work. These actions infringe copyright if you do -not accept this License. Therefore, by modifying or propagating a -covered work, you indicate your acceptance of this License to do so. - - 10. Automatic Licensing of Downstream Recipients. - - Each time you convey a covered work, the recipient automatically -receives a license from the original licensors, to run, modify and -propagate that work, subject to this License. You are not responsible -for enforcing compliance by third parties with this License. - - An "entity transaction" is a transaction transferring control of an -organization, or substantially all assets of one, or subdividing an -organization, or merging organizations. If propagation of a covered -work results from an entity transaction, each party to that -transaction who receives a copy of the work also receives whatever -licenses to the work the party's predecessor in interest had or could -give under the previous paragraph, plus a right to possession of the -Corresponding Source of the work from the predecessor in interest, if -the predecessor has it or can get it with reasonable efforts. - - You may not impose any further restrictions on the exercise of the -rights granted or affirmed under this License. For example, you may -not impose a license fee, royalty, or other charge for exercise of -rights granted under this License, and you may not initiate litigation -(including a cross-claim or counterclaim in a lawsuit) alleging that -any patent claim is infringed by making, using, selling, offering for -sale, or importing the Program or any portion of it. - - 11. Patents. - - A "contributor" is a copyright holder who authorizes use under this -License of the Program or a work on which the Program is based. The -work thus licensed is called the contributor's "contributor version". - - A contributor's "essential patent claims" are all patent claims -owned or controlled by the contributor, whether already acquired or -hereafter acquired, that would be infringed by some manner, permitted -by this License, of making, using, or selling its contributor version, -but do not include claims that would be infringed only as a -consequence of further modification of the contributor version. For -purposes of this definition, "control" includes the right to grant -patent sublicenses in a manner consistent with the requirements of -this License. - - Each contributor grants you a non-exclusive, worldwide, royalty-free -patent license under the contributor's essential patent claims, to -make, use, sell, offer for sale, import and otherwise run, modify and -propagate the contents of its contributor version. - - In the following three paragraphs, a "patent license" is any express -agreement or commitment, however denominated, not to enforce a patent -(such as an express permission to practice a patent or covenant not to -sue for patent infringement). To "grant" such a patent license to a -party means to make such an agreement or commitment not to enforce a -patent against the party. - - If you convey a covered work, knowingly relying on a patent license, -and the Corresponding Source of the work is not available for anyone -to copy, free of charge and under the terms of this License, through a -publicly available network server or other readily accessible means, -then you must either (1) cause the Corresponding Source to be so -available, or (2) arrange to deprive yourself of the benefit of the -patent license for this particular work, or (3) arrange, in a manner -consistent with the requirements of this License, to extend the patent -license to downstream recipients. "Knowingly relying" means you have -actual knowledge that, but for the patent license, your conveying the -covered work in a country, or your recipient's use of the covered work -in a country, would infringe one or more identifiable patents in that -country that you have reason to believe are valid. - - If, pursuant to or in connection with a single transaction or -arrangement, you convey, or propagate by procuring conveyance of, a -covered work, and grant a patent license to some of the parties -receiving the covered work authorizing them to use, propagate, modify -or convey a specific copy of the covered work, then the patent license -you grant is automatically extended to all recipients of the covered -work and works based on it. - - A patent license is "discriminatory" if it does not include within -the scope of its coverage, prohibits the exercise of, or is -conditioned on the non-exercise of one or more of the rights that are -specifically granted under this License. You may not convey a covered -work if you are a party to an arrangement with a third party that is -in the business of distributing software, under which you make payment -to the third party based on the extent of your activity of conveying -the work, and under which the third party grants, to any of the -parties who would receive the covered work from you, a discriminatory -patent license (a) in connection with copies of the covered work -conveyed by you (or copies made from those copies), or (b) primarily -for and in connection with specific products or compilations that -contain the covered work, unless you entered into that arrangement, -or that patent license was granted, prior to 28 March 2007. - - Nothing in this License shall be construed as excluding or limiting -any implied license or other defenses to infringement that may -otherwise be available to you under applicable patent law. - - 12. No Surrender of Others' Freedom. - - If conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot convey a -covered work so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you may -not convey it at all. For example, if you agree to terms that obligate you -to collect a royalty for further conveying from those to whom you convey -the Program, the only way you could satisfy both those terms and this -License would be to refrain entirely from conveying the Program. - - 13. Remote Network Interaction; Use with the GNU General Public License. - - Notwithstanding any other provision of this License, if you modify the -Program, your modified version must prominently offer all users -interacting with it remotely through a computer network (if your version -supports such interaction) an opportunity to receive the Corresponding -Source of your version by providing access to the Corresponding Source -from a network server at no charge, through some standard or customary -means of facilitating copying of software. This Corresponding Source -shall include the Corresponding Source for any work covered by version 3 -of the GNU General Public License that is incorporated pursuant to the -following paragraph. - - Notwithstanding any other provision of this License, you have -permission to link or combine any covered work with a work licensed -under version 3 of the GNU General Public License into a single -combined work, and to convey the resulting work. The terms of this -License will continue to apply to the part which is the covered work, -but the work with which it is combined will remain governed by version -3 of the GNU General Public License. - - 14. Revised Versions of this License. - - The Free Software Foundation may publish revised and/or new versions of -the GNU Affero General Public License from time to time. Such new versions -will be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - - Each version is given a distinguishing version number. If the -Program specifies that a certain numbered version of the GNU Affero General -Public License "or any later version" applies to it, you have the -option of following the terms and conditions either of that numbered -version or of any later version published by the Free Software -Foundation. If the Program does not specify a version number of the -GNU Affero General Public License, you may choose any version ever published -by the Free Software Foundation. - - If the Program specifies that a proxy can decide which future -versions of the GNU Affero General Public License can be used, that proxy's -public statement of acceptance of a version permanently authorizes you -to choose that version for the Program. - - Later license versions may give you additional or different -permissions. However, no additional obligations are imposed on any -author or copyright holder as a result of your choosing to follow a -later version. - - 15. Disclaimer of Warranty. - - THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY -APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT -HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY -OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, -THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE PROGRAM -IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF -ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. Limitation of Liability. - - IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS -THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY -GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING OUT OF THE -USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED TO LOSS OF -DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD -PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), -EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF -SUCH DAMAGES. - - 17. Interpretation of Sections 15 and 16. - - If the disclaimer of warranty and limitation of liability provided -above cannot be given local legal effect according to their terms, -reviewing courts shall apply local law that most closely approximates -an absolute waiver of all civil liability in connection with the -Program, unless a warranty or assumption of liability accompanies a -copy of the Program in return for a fee. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -state the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program 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. - - This program 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. - - You should have received a copy of the GNU Affero General Public License - along with this program. If not, see . - -Also add information on how to contact you by electronic and paper mail. - - If your software can interact with users remotely through a computer -network, you should also make sure that it provides a way for users to -get its source. For example, if your program is a web application, its -interface could display a "Source" link that leads users to an archive -of the code. There are many ways you could offer source, and different -solutions will be better for different programs; see section 13 for the -specific requirements. - - You should also get your employer (if you work as a programmer) or school, -if any, to sign a "copyright disclaimer" for the program, if necessary. -For more information on this, and how to apply and follow the GNU AGPL, see -. diff --git a/MAINTAINERS b/MAINTAINERS deleted file mode 100644 index 37f6411..0000000 --- a/MAINTAINERS +++ /dev/null @@ -1,43 +0,0 @@ -# Maintainers - -This file lists the current maintainers of this project. - -## Active Maintainers - -| Name | GitHub | Role | Since | -|------|--------|------|-------| -| Metadatastician | @metadatastician | Primary | Project Start | - -## Emeritus Maintainers - -None at this time. - -## Becoming a Maintainer - -To become a maintainer: - -1. Demonstrate consistent, high-quality contributions -2. Show understanding of the project's goals and architecture -3. Be active in code reviews and community discussions -4. Be nominated by an existing maintainer -5. Be approved by consensus of existing maintainers - -## Maintainer Responsibilities - -- Reviewing and merging pull requests -- Managing releases -- Triaging issues -- Enforcing code standards -- Mentoring new contributors -- Participating in decision-making - -## Maintainer Expectations - -- Respond to issues and PRs in a timely manner -- Follow the code of conduct -- Be transparent in decision-making -- Communicate clearly and respectfully - ---- - -*Last updated: 2026-07-18* diff --git a/MAINTAINERS.adoc b/MAINTAINERS.adoc index aa23a55..1e6c39b 100644 --- a/MAINTAINERS.adoc +++ b/MAINTAINERS.adoc @@ -1,48 +1,29 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell = Maintainers -:toc: preamble - -This document lists the maintainers of this project and their responsibilities. == Current Maintainers -[cols="2,3,2",options="header"] -|=== -| Name | Role | Contact - -| Jonathan D.A. Jewell -| Lead Maintainer -| https://github.com/hyperpolymath[@hyperpolymath] -|=== +* *Jonathan D.A. Jewell* — Project Lead — j.d.a.jewell@open.ac.uk == Responsibilities -Maintainers are responsible for: - -* 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 +Maintainers review pull requests, triage issues, cut releases, and uphold +the project's security and conduct policies. == Becoming a Maintainer -Contributors who demonstrate: - -* Consistent, high-quality contributions -* Understanding of the project's goals and standards -* Constructive participation in discussions -* Commitment to the project's long-term health - -May be invited to become maintainers at the discretion of existing maintainers. +Maintainers are invited based on sustained, constructive contribution. == Decision Making -* Routine decisions (bug fixes, minor improvements) can be made by any maintainer -* Significant changes require discussion and consensus among maintainers -* Breaking changes or major features should be discussed in issues before implementation +[cols="1,2"] +|=== +|Minor change |one maintainer approval +|Major change |consensus among maintainers +|Security fix |one maintainer approval, expedited +|=== == Contact -For questions about project governance, open an issue or contact the maintainers listed above. +Use the repository's issue tracker for project questions, and +j.d.a.jewell@open.ac.uk for security matters. diff --git a/Mustfile b/Mustfile deleted file mode 100644 index 5f07541..0000000 --- a/Mustfile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Mustfile - hyperpolymath mandatory checks -# See: https://github.com/hyperpolymath/mustfile - -version: 1 - -checks: - - name: security - run: just lint - - name: tests - run: just test - - name: format - run: just fmt diff --git a/NOTICE b/NOTICE deleted file mode 100644 index e047656..0000000 --- a/NOTICE +++ /dev/null @@ -1,22 +0,0 @@ -Licensing Notice -================ - -This project is authored by Jonathan D.A. Jewell (hyperpolymath) and -is licensed under the Palimpsest License (MPL-2.0). - -The MPL-2.0 is a philosophical extension of the Mozilla Public -License 2.0, adding provisions for cryptographic provenance, emotional -lineage preservation, and quantum-safe signatures. The full PMPL text is -available in LICENSES/MPL-2.0.txt. - -For compatibility with automated license detection tools and platforms -that require OSI-approved licenses, the root LICENSE file contains the -standard Mozilla Public License 2.0 text. This ensures that package -registries, CI systems, and other tooling correctly identify the license. - -The legally binding terms are: - - Source files: governed by MPL-2.0 (per SPDX headers) - - Combined works: compatible with MPL-2.0 (per PMPL Section 6) - -For more information about the Palimpsest License: - https://github.com/hyperpolymath/palimpsest-license diff --git a/PROOF-NEEDS.adoc b/PROOF-NEEDS.adoc deleted file mode 100644 index 501a955..0000000 --- a/PROOF-NEEDS.adoc +++ /dev/null @@ -1,119 +0,0 @@ -== PROOF-NEEDS.md — maa-framework - -=== Current State - -_Re-measured 2026-07-27 against the `+absolute-zero+` submodule at -`+87902bb7+`._ - -* **src/abi/*.idr**: NO -* *`+Admitted+` count*: *0* -(`+grep -rn Admitted absolute-zero --include=*.v+`) -* *Trusted base*: *23 `+Axiom+` declarations across 6 `+.v+` files*, -each classified in-source. See the *AXIOM AUDIT* block at the end of -`+proofs/coq/physics/LandauerDerivation.v+` — that audit, not this file, -is the authoritative record. -* *LOC*: ~22,700 (Rust + Coq) -* *ABI layer*: Missing -* *Existing proofs*: Coq proofs for lambda CNO, Landauer derivation -chain, quantum mechanics exactness - -____ -*Correction (2026-07-27).* This file previously claimed _"`1 -`+Admitted+` in `+proofs/coq/lambda/LambdaCNO.v+` (y_not_cno)`"_. There -are *zero* `+Admitted+` anywhere. `+y_not_cno+` is a *KEPT AXIOM* — a -declared trust assumption with a written rationale -(`+LambdaCNO.v:388-399+`), not an unproven hole. The old wording was -wrong in both directions: it overstated the incompleteness _and_ -understated the trusted base by a factor of 23. - -The distinction matters operationally: an `+Axiom+` *passes* a "`no -`+sorry+` / no `+Admitted+``" gate silently, so counting only -`+Admitted+` measures the wrong thing. Any proof gate for this repo must -scan for `+Axiom+` too. -____ - -==== Axiom classification (summarised from the in-source audit) - -[width="100%",cols="34%,33%,33%",options="header",] -|=== -|Class |Count |Meaning -|METAL-BOUNDARY |6 |genuine empirical physics, not derivable (k_B, -temperature, Second Law, isothermal work bound, Landauer lower bound, -reversible ⇒ zero dissipation) - -|SPECIFICATION |4 |sound, but not dischargeable while -`+shannon_entropy+` / `+product_dist+` stay opaque - -|NOT-YET-DISCHARGED (class A) |2 |`+cno_preserves_shannon_entropy+`, -`+cno_zero_energy_dissipation_derived+` - -|SOUNDNESS WARNINGS |3 |*false as stated*, currently *unused* — see -below -|=== - -The audit is notably self-critical: it records that -`+cno_zero_energy_dissipation_derived+` is an axiom *despite its -`+_derived+` name*, and that the triage docs’ "`DISCHARGE`" marks on it -and on `+reversible_zero_dissipation+` are *inaccurate*. Both are kept -honestly rather than fake-derived. - -=== What Needs Proving - -[width="100%",cols="51%,27%,22%",options="header",] -|=== -|Component |What |Why -|*Unsound-but-unused axioms* |Fix or delete `+prob_nonneg+`, -`+prob_normalized+` (false over unconstrained function-type -distributions — need a bundled distribution type) and -`+shannon_entropy_maximum+` (*stated inequality is backwards* — asserts -uniform _minimises_ entropy) |They are false. Unused today, so harmless -today; the moment anything cites one, it proves anything. *Highest -priority.* - -|`+cno_preserves_shannon_entropy+` |Discharge, or accept as a stated -postulate |class A — carrier/quotient issue - -|`+cno_zero_energy_dissipation_derived+` |Rename, or supply -`+internal_energy+` CNO-invariance |`+internal_energy+` is an opaque -`+Parameter+` with no preservation law, so this cannot be a pure -derivation - -|Absolute-zero brainfuck interpreter |Interpreter preserves CNO -properties |Claims of computational zero need formal backing - -|Absolute-zero whitespace interpreter |Same as brainfuck — CNO -preservation |Both esoteric interpreters need the same guarantee - -|Aletheia verification checks |Verification pipeline produces sound -results |Rhodibot extraction depends on correct checks - -|Quantum mechanics proofs |Extend QuantumMechanicsExact.v coverage -|Existing proofs are partial -|=== - -*Not on this list: `+y_not_cno+`.* It is not a "`concrete, closable -proof obligation`". The in-source rationale explains why: a rigorous -proof must rule out reaching the argument under _every_ interleaving of -`+beta_reduce+` (which permits reduction under binders and on either -side of an application), requiring an invariant closed under the full -reduction congruence, or a coinductive / step-indexed non-termination -argument. Genuinely out of scope, not merely tedious. - -=== Recommended Prover - -*Coq* — the existing proof infrastructure is in Coq. Aletheia (Rust) -verification would benefit from an *Idris2* ABI layer. - -=== Priority - -*MEDIUM* — the proof infrastructure is real and its trusted base is -honestly documented. The one genuinely urgent item is the three -*unsound* axioms: they are currently unused, so this is cheap to fix now -and expensive to discover later. - -=== Template ABI Cleanup (2026-03-29) - -Template ABI removed – was creating false impression of formal -verification. The removed files (Types.idr, Layout.idr, Foreign.idr) -contained only RSR template scaffolding with unresolved -\{\{PROJECT}}/\{\{AUTHOR}} placeholders and no domain-specific proofs. diff --git a/QUICKSTART-DEV.adoc b/QUICKSTART-DEV.adoc deleted file mode 100644 index 919b9fc..0000000 --- a/QUICKSTART-DEV.adoc +++ /dev/null @@ -1,113 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= QUICKSTART-DEV — maa-framework contributor setup -:toc: - -// What a working dev loop looks like here, in one page. End users start -// at QUICKSTART-USER.adoc, maintainers at QUICKSTART-MAINTAINER.adoc. - -== The stack - -* **Rust 1.98.1** (pinned in `mise.toml` / `.tool-versions`): the - `aletheia/` crate, edition 2021, MSRV 1.80, **zero dependencies** by - RSR Bronze rule (`just deps-check` enforces it). -* **Just** (any recent release; `cargo install just`): every task in - this file is a Just recipe. Run from the repo root. -* **GitHub Actions**: `just check` mirrors the CI gate exactly, same - recipes in the same order — if it passes locally, CI passes. -* **absolute-zero/** is a submodule (the Certified Null Operation - reference, developed upstream; bump the pointer deliberately, never - develop in place). Its `proofs/coq/` tree is where the Coq proofs - live — there is no in-tree `verification/` directory. - -== Option A: Guix (reproducible) - -[source,shell] ----- -guix shell # auto-discovers manifest.scm at the root -just check ----- - -`manifest.scm` provides rust + just + git (specs verified 2026-09-21). -It is new: if `guix shell` fails on a spec, file an issue rather than -working around it. There is no `flake.nix` — Guix is primary by design -(RSR 1.2.1), Nix was retired, so there is no Option B for it. - -== Option B: rustup (recommended for most) - -[source,shell] ----- -rustup toolchain install stable # 1.98.1 at time of writing; MSRV is 1.80 -cargo install just -just check ----- - -System rustc from your distro also works if it meets MSRV — the gate is -`just check`, not how the toolchain arrived. - -== Build, test, MUST - -[source,shell] ----- -just build # debug + release, locked -just test # full aletheia suite (unit + integration; green since #124) -just check # the whole CI gate: build test fmt lint deps-check ----- - -`Mustfile` is the MUST contract: `security` → `just lint`, -`tests` → `just test`, `format` → `just fmt`. The generated -`contractile.just` adds `must-check` (license/readme/SPDX/no-banned-files) -and `trust-verify` (license-content/no-secrets-committed/pinned-images). -Run `just must-check trust-verify` before pushing anything structural. - -Landmines (each bought with a real incident): - -* Workflows run **only** from `.github/workflows/` — a workflow file - anywhere else is silently dead (#98). -* Clippy denies **all warnings including dead code**; keep the tree - warning-free or CI fails (#125). -* A recipe that echoes and exits 0 is a fake gate. Recipes MUST fail - loudly (#99). -* `main` takes **squash-merges on PRs only**, commits signed - (Optimus-Branch ruleset, zero bypass actors) — direct pushes fail. - -== Recipes you will actually use - -`just --list` is authoritative; the daily set is `build`, `test`, -`check`, `lint`, `fmt` (`fmt-fix` applies), `deps-check`, -`self-verify` (runs aletheia against this repo), `doctor` (setup -self-diagnostic), `assail` (panic-attack pre-commit scan — needs the -external `panic-attack` binary), `tour`, and `help-me`. - -== Wiring a new agent / LLM session in - -Start it on `llm-warmup-dev.adoc` (repo root), then this file. For -deep background: `docs/usage.adoc`, `docs/architecture.adoc`, -`docs/troubleshooting.adoc`, `EXPLAINME.adoc`, and the normative -`STATE.a2ml` under `.machine_readable/6a2/`. - -== Layout (trimmed) - -[source] ----- -maa-framework/ -├── .github/ # workflows, hooks, agents, funding -├── .machine_readable/ # STATE, MUST schemas, gates, rsr-profile -├── .well-known/ # symlinks → www/.well-known (canonical bundle) -├── aletheia/ # the Rust crate: src/, tests/, benches/ -├── absolute-zero/ # submodule: CNO reference + Coq proofs -├── docs/ # usage, architecture, troubleshooting, decisions -├── tests/ # aspect/, e2e/, fuzz/ suites -├── www/ # the canonical .well-known/ bundle -├── manifest.scm # Guix dev environment (Option A) -├── mise.toml / .tool-versions # toolchain pins -├── Justfile / contractile.just / Mustfile -└── *.adoc # README, EXPLAINME, STATE pointers, this file ----- - -== Stuck? - -* `just doctor`, then `just help-me` (paste both into your issue). -* `docs/troubleshooting.adoc` for the known-good fixes. -* Issues: https://github.com/hyperpolymath/maa-framework/issues/new -* Wiki: https://github.com/hyperpolymath/maa-framework/wiki diff --git a/QUICKSTART-MAINTAINER.adoc b/QUICKSTART-MAINTAINER.adoc deleted file mode 100644 index 3367e30..0000000 --- a/QUICKSTART-MAINTAINER.adoc +++ /dev/null @@ -1,130 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -// Template: QUICKSTART-MAINTAINER.adoc — packaging, deploying, and maintaining -// Replace maa-framework, {{PACKAGE_NAME}}, {{DEPS}} with actuals -= maa-framework — Quick Start for Platform Maintainers -:toc: -:toclevels: 2 - -== Overview - -This guide covers packaging, deploying, and maintaining maa-framework for -distribution on your platform. - -== Runtime Dependencies - -{{DEPS}} - -== Build from Source - -[source,bash] ----- -git clone https://github.com/hyperpolymath/maa-framework.git -cd maa-framework -just build-release ----- - -Output: `{{BUILD_OUTPUT_PATH}}` - -== Packaging - -=== Guix - -[source,bash] ----- -guix build -f build/guix.scm ----- - -=== Nix - -[source,bash] ----- -nix build ----- - -=== Container (Stapeln) - -[source,bash] ----- -just stapeln-export # Generates Containerfile -podman build -t maa-framework . ----- - -=== Manual Package - -[source,bash] ----- -just install --prefix=/usr/local ----- - -Files installed: - -[cols="1,2"] -|=== -| Path | Contents - -| `$PREFIX/bin/` -| Executables - -| `$PREFIX/share/{{PACKAGE_NAME}}/` -| Data files, assets - -| `$PREFIX/share/doc/{{PACKAGE_NAME}}/` -| Documentation - -| `$PREFIX/share/applications/` -| .desktop file (Linux, if GUI) - -| `$PREFIX/share/man/man1/` -| Man pages -|=== - -== Configuration - -Default config location: `$XDG_CONFIG_HOME/{{PACKAGE_NAME}}/config.toml` - -Fallback: `$HOME/.config/{{PACKAGE_NAME}}/config.toml` - -== Health Checks - -[source,bash] ----- -just doctor # Full diagnostic -just run --version # Version check -just run --selftest # Built-in self-test ----- - -== Updating - -[source,bash] ----- -git pull -just build-release -just install --prefix=/usr/local ----- - -Or via OPSM: `opsm update {{PACKAGE_NAME}}` - -== Security Notes - -* License: MPL-2.0 (Palimpsest License) -* All dependencies SHA-pinned -* `panic-attacker` scan results: link:INSTALL-SECURITY-REPORT.adoc[] -* OpenSSF Scorecard: see badge in README - -== Multi-Instance Deployment - -For deploying multiple instances (e.g., different users or tenants): - -[source,bash] ----- -just install --prefix=/opt/{{PACKAGE_NAME}}-instance1 --config=/etc/{{PACKAGE_NAME}}/instance1.toml -just install --prefix=/opt/{{PACKAGE_NAME}}-instance2 --config=/etc/{{PACKAGE_NAME}}/instance2.toml ----- - -Each instance has isolated config, data, and logs. - -== Reporting Issues - -* Upstream: https://github.com/hyperpolymath/maa-framework/issues -* With diagnostic: `just help-me` (pre-fills context) diff --git a/QUICKSTART-USER.adoc b/QUICKSTART-USER.adoc deleted file mode 100644 index 3932e2a..0000000 --- a/QUICKSTART-USER.adoc +++ /dev/null @@ -1,125 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -// Template: QUICKSTART-USER.adoc — 5-minute path to working software -// Replace maa-framework, Maa Framework — See README.adoc for details., just run, Maa Framework started successfully. with actuals -= maa-framework — Quick Start for Users -:toc: -:toclevels: 2 - -== What is maa-framework? - -Maa Framework — See README.adoc for details. - -== Prerequisites - -Before you begin, ensure you have: - -* **just** — task runner (https://github.com/casey/just[install guide]) -* Platform-specific requirements listed below - -[cols="1,3"] -|=== -| Platform | Additional Requirements - -| Linux -| See README.adoc - -| macOS -| See README.adoc - -| Windows -| See README.adoc -|=== - -== Install - -=== Option 1: Standard Install (recommended) - -[source,bash] ----- -# Clone and set up -git clone https://github.com/hyperpolymath/maa-framework.git -cd maa-framework -just setup ----- - -The setup script will: - -* Detect your platform and shell -* Install missing dependencies (with your permission) -* Configure the application -* Offer install location choices -* Run a self-diagnostic to verify everything works - -=== Option 2: Container (via Stapeln) - -[source,bash] ----- -just stapeln-run ----- - -=== Option 3: Portable (no system changes) - -[source,bash] ----- -just install --portable --prefix=./maa-framework-portable ----- - -== First Run - -[source,bash] ----- -just run ----- - -Expected output: - -[source] ----- -Maa Framework started successfully. ----- - -== Self-Diagnostic - -If something isn't working: - -[source,bash] ----- -just doctor ----- - -This checks all dependencies, permissions, paths, and connectivity. -If it finds issues, it will suggest fixes. - -To attempt automatic repair: - -[source,bash] ----- -just heal ----- - -== Get Help - -* **In-app**: `just run --help` -* **Guided tour**: `just tour` -* **Report a problem**: `just help-me` (pre-fills diagnostic context) -* **Wiki**: https://github.com/hyperpolymath/maa-framework/wiki - -== Uninstall - -[source,bash] ----- -just uninstall ----- - -You will be asked: - -1. Which uninstall tier (Bennett reversible, parameter-based, standard, or secure) -2. Whether to include or exclude your data -3. Whether to clear caches and LLM models - -== Next Steps - -* Read the link:README.adoc[README] for full feature overview -* Read the link:EXPLAINME.adoc[EXPLAINME] for architecture and design decisions -* Try `just tour` for a guided walkthrough diff --git a/README.adoc b/README.adoc index 7fe4fb5..0bc1b3b 100644 --- a/README.adoc +++ b/README.adoc @@ -1,215 +1,112 @@ -// SPDX-License-Identifier: MPL-2.0 -= MAA Framework — Mutually Assured Accountability -:toc: preamble -:toc-title: Contents +// SPDX-License-Identifier: CC-BY-SA-4.0 += proofgateway +:toc: :icons: font -:doctype: article -image:https://img.shields.io/badge/OpenSSF-BestPractices-green[link="https://www.bestpractices.dev/projects/XXXX"] +____ +An RSR v2-compliant Rust/Creusot project. +____ -Governance hub and microkernel for the Mutually Assured Accountability paradigm: building verifiably-compliant, secure, and sustainable systems where accountability is symmetric and enforceable. +== Quick Start -== Overview - -Mutually Assured Accountability (MAA) is a paradigm where accountability between system participants is symmetric—each party can verify the other's compliance, and no party is above audit. This repository is the governance hub and implementation centre for the MAA ecosystem. - -The ecosystem has three components: - -[cols="1,2", options="header"] -|=== -| Component | Role - -| MAA Framework -| Governance hub, specifications, CI, and integration layer - -| Oblíbený -| Reference language designed for the framework (specification stage) - -| Aletheia -| Microkernel implementation (Rust, in-tree) -|=== - -The Certified Null Operation (CNO) formalisation is developed upstream in `link:https://github.com/hyperpolymath/absolute-zero[absolute-zero]` and pinned here as a git submodule. - -== What is built and what is planned - -[cols="1,2,2", options="header"] -|=== -| Artefact | Status | Evidence - -| Aletheia microkernel (Rust) -| Builds, 29 unit tests passing, zero dependencies -| `aletheia/`, CI gate `rust-ci.yml` - -| CRG Tier-C test suite -| Landed 2026-04-04 (unit, E2E, property, aspect, benchmarks) -| `tests/` - -| CI gates at repository root -| Green across every enabled workflow; each shown capable of failing -| `.github/workflows/` - -| Hub-and-spoke mirroring -| GitHub → GitLab, Codeberg, Bitbucket (automated) -| Mirror workflows - -| CLI surface for Aletheia -| **Unbuilt** — `main.rs` wires 3 checks; integration suite specifies more -| Issue #124 - -| Oblíbený reference language -| **Specification stage** -| Not yet in tree - -| Specification documents -| **Pending upload** (ROADMAP Phase 1) -| `docs/` (partial) -|=== - -== Known gaps - -[NOTE] -==== -**Aletheia CLI rebuilt 2026-09-21 (was: unbuilt, #124).** The CLI now implements the RSR v2 offline file-presence subset (26 checks: 13 Bronze, 12 Silver, 1 Gold) with human/JSON/SARIF/HTML/badge/quiet/verbose output; 68 unit + 47 integration tests pass. The hypatia `rsr-conformance` oracle stays normative — aletheia evaluates only the offline subset and says so in verbose output. -==== - -[NOTE] -==== -**Clippy clean and blocking since 2026-09-21 (was: 23 findings, #125).** The findings were wired into real code, not silenced; `cargo clippy --all-targets -- -D warnings` gates in `rust-ci.yml` and `just lint`. -==== - -[CAUTION] -==== -**`aletheia/.github/workflows/` is inert.** GitHub Actions reads `.github/workflows/` at the repository root only, and `aletheia/` is vendored as plain tracked files (not a submodule). Those 16 workflow files have never executed. Gates must be added at the root, not inside `aletheia/`. -==== - -[CAUTION] -==== -**Specification uploads are pending.** ROADMAP Phase 1 (specification publication) is not complete. The project scope is stated; the formal specifications backing it are not yet in-tree. -==== - -== What is standard and what is ours - -[cols="1,2,2", options="header"] -|=== -| Concept | Status | Home - -| Microkernel architecture (Rust) -| Standard -| `aletheia/` +[source,bash] +---- +# Build (offline, zero dependencies) +just build -| Hub-and-spoke repo mirroring -| Standard -| `.github/workflows/` (mirror sync) +# Test +just test -| SHA-pinned GitHub Actions -| Standard supply-chain hygiene -| `.github/workflows/` +# Verify RSR compliance +just verify +---- -| Mutually Assured Accountability paradigm -| **Novel governance concept** -| This repository +This project is *standalone by construction*: the scaffold fetches nothing. +`cargo build --offline` works on a machine with no network, because the +crate has zero dependencies and the licence texts ship in-tree under +`+LICENSES/+`. -| Symmetric accountability enforcement -| **Novel** (paradigm definition) -| Specifications (pending) +== RSR Compliance -| Oblíbený reference language -| **Novel** (specification stage) -| Not yet in tree +[cols="1,3"] |=== - -== Project scope - -The framework addresses these domains. Where an implementation exists, it is noted; where it does not, the domain is a stated intention: - -[cols="1,2", options="header"] +|Bronze |Documentation, security policy, SPDX headers, CI, licence classification +|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` +|Gold |No silent-skip recipes |=== -| Domain | Current status - -| Security & Formal Verification -| CNO submodule pinned; Aletheia builds - -| AI Ethics & Axiology -| Specification pending -| Dependability -| Specification pending +Verify with the estate's own checker: -| Language Design & Compilers -| Oblíbený at specification stage - -| Microkernel Architecture -| Aletheia: builds, 29 unit tests, zero dependencies - -| RISC-V -| Specification pending - -| Sustainability -| Specification pending - -| Economics-as-Code -| Specification pending - -| Distributed Computing -| Specification pending +[source,bash] +---- +aletheia . +---- -| Reversibility -| CNO submodule (upstream: `absolute-zero`) +== Language: Rust/Creusot -| Web Protocols -| Specification pending -|=== +Per the estate language policy, Rust in this estate is always *Rust/Creusot* +— Rust plus https://github.com/creusot-rs/creusot[Creusot], the deductive +verifier that translates annotated Rust to Why3 and discharges proof +obligations with SMT solvers. -== Repository Layout +The verification crate lives in `+verification/+` and is *deliberately +detached from the default Cargo workspace*, so the main crate stays +zero-dependency and air-gapped. Only `just proof` needs the Creusot +toolchain (nightly Rust + Why3 + SMT solvers), and only when you actually +run it. -[cols="1,3", options="header"] -|=== -| Path | Purpose +`+src/impl.rs+` is a single source of truth: both `+src/lib.rs+` and +`+verification/src/lib.rs+` `include!` it, so what Creusot verifies is the +code that ships. The specifications are gated behind `+cfg(creusot)+`, which +only `+creusot-rustc+` sets: -| `aletheia/` -| Microkernel implementation (Rust, vendored in-tree) +[source,rust] +---- +#[cfg_attr(creusot, requires(lo@ <= hi@))] +#[cfg_attr(creusot, ensures(lo@ <= result@ && result@ <= hi@))] +pub fn clamp(value: u32, lo: u32, hi: u32) -> u32 { ... } +---- -| `absolute-zero/` -| CNO formalisation (git submodule, developed upstream) +`+just proof+` translates and discharges both obligations; it exits non-zero +if any goal is unproved. -| `tests/` -| E2E, property, aspect tests (CRG Tier-C) +See link:verification/README.adoc[verification/README.adoc] for setup. -| `.github/workflows/` -| CI gates and mirror synchronization (root level only) +== Documentation -| `docs/` -| Specifications and state-of-play documents +* link:SECURITY.adoc[Security Policy] — vulnerability disclosure +* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute +* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards +* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions +* link:CHANGELOG.adoc[Changelog] — version history -| `.machine_readable/` -| 6a2 metadata, contractiles, bot directives -|=== +== Layout -== Build +.... +. +├── Justfile # build automation (capital J — v2 shape) +├── LICENSE # licence statement +├── LICENSES/ # full licence texts (REUSE style) +├── src/ # crate source +├── tests/ # integration tests +├── verification/ # Rust/Creusot proof crate (detached from workspace) +├── .github/workflows/ # CI + estate gates +├── .machine_readable/ # machine-readable metadata +└── .well-known/ # security.txt, ai.txt, humans.txt +.... -[source,bash] ----- -# Aletheia microkernel -cd aletheia/ -cargo build -cargo test +== Contributing -# Full CI (from repository root) -just verify ----- +See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. -== Documentation +== License -* link:EXPLAINME.adoc[EXPLAINME] — claim-by-claim receipts and known gaps -* link:Glossary.adoc[Glossary] — terminology reference -* `docs/STATE-OF-PLAY-2026-07-29.adoc` — CI status, gated checks, proof state, open questions -* `ROADMAP.adoc` — development phases -* `GOVERNANCE.adoc` — project governance -* link:https://github.com/hyperpolymath/absolute-zero[absolute-zero] — CNO formalisation (upstream) +Code is licensed under the Mozilla Public License, version 2.0 +(`+MPL-2.0+`). Documentation is licensed under Creative Commons +Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). -== License +See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. -SPDX-License-Identifier: MPL-2.0 — see link:LICENSE[LICENSE]. +''''' -Prose documentation is licensed under CC-BY-SA-4.0; see `LICENSES/`. +_Created from the aletheia v2 Bronze template._ diff --git a/ROADMAP.adoc b/ROADMAP.adoc deleted file mode 100644 index 19a0ba3..0000000 --- a/ROADMAP.adoc +++ /dev/null @@ -1,92 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= MAA Framework Roadmap -:toc: -:icons: font - -== Current Status - -[NOTE] -==== -*Phase 0: Foundation* — Complete. *Phase 1: Specification* — Open (uploads pending). - -Infrastructure and governance established. Implementation work has commenced ahead of the specification uploads: the Aletheia microkernel lives in-tree under `aletheia/`, the Certified Null Operation reference is pinned as the `absolute-zero/` git submodule (PR #89), and a CRG Tier-C test suite (unit, E2E, property, aspect, benchmarks) landed 2026-04-04. The 2026-06 estate standardization brought the governance layer (flat contractiles, bot directives, self-validation, Guix manifest) current. Specification document uploads remain the open Phase-1 work. -==== - -== Development Phases - -=== Phase 0: Foundation [Complete] - -* [x] Repository initialization -* [x] Multi-forge hub-and-spoke mirroring (GitHub → GitLab, Codeberg, Bitbucket) -* [x] Security hardening (SHA-pinned actions, SSH host verification) -* [x] Language policy definition (Hyperpolymath Standard) -* [x] Code ownership and governance structure - -=== Phase 1: Specification - -* [ ] Upload MAA Framework specification documents -* [ ] Define Oblíbený language grammar and semantics -* [ ] Document Aletheia microkernel architecture -* [ ] Establish formal verification requirements -* [ ] Define API boundaries and interfaces - -=== Phase 2: Toolchain Bootstrap - -* [ ] Oblíbený lexer/parser (OCaml or Rust) -* [ ] Initial type system implementation -* [ ] REPL for language exploration -* [ ] Build system integration (Guix/Nix) - -=== Phase 3: Core Runtime - -* [ ] Aletheia microkernel prototype -* [ ] Memory management subsystem -* [ ] IPC mechanisms -* [ ] RISC-V target support - -=== Phase 4: Framework Libraries - -* [ ] Standard library for Oblíbený -* [ ] Formal verification primitives -* [ ] Economics-as-code modules -* [ ] Distributed computing abstractions (BOINC compatibility) - -=== Phase 5: Ecosystem - -* [ ] Developer documentation -* [ ] Example applications -* [ ] Community contribution guidelines -* [ ] Package registry (if applicable) - -== Architecture Vision - -[source] ----- -┌─────────────────────────────────────────────────────┐ -│ Applications │ -├─────────────────────────────────────────────────────┤ -│ MAA Framework Libraries │ -│ ┌──────────┐ ┌──────────┐ ┌──────────────────────┐ │ -│ │ Formal │ │Economics │ │ Distributed │ │ -│ │Verificat.│ │ as Code │ │ Computing │ │ -│ └──────────┘ └──────────┘ └──────────────────────┘ │ -├─────────────────────────────────────────────────────┤ -│ Oblíbený │ -│ (Reference Language + Compiler) │ -├─────────────────────────────────────────────────────┤ -│ Aletheia │ -│ (Microkernel) │ -├─────────────────────────────────────────────────────┤ -│ RISC-V │ -│ (Hardware Target) │ -└─────────────────────────────────────────────────────┘ ----- - -== Timeline - -No fixed timeline. Development proceeds as specifications are finalized and resources become available. - -== Contributing - -Roadmap updates will be coordinated through the canonical GitHub repository. Major phase transitions require maintainer approval. diff --git a/SECURITY.adoc b/SECURITY.adoc index 75518d1..46af491 100644 --- a/SECURITY.adoc +++ b/SECURITY.adoc @@ -1,65 +1,33 @@ -== Security Policy +// SPDX-License-Identifier: CC-BY-SA-4.0 += Security Policy +:toc: -=== Supported Versions +== Reporting a Vulnerability -[cols=",",options="header",] -|=== -|Version |Supported -|main |:white_check_mark: -|=== - -=== Reporting a Vulnerability - -If you discover a security vulnerability in this project, please report -it responsibly: - -[arabic] -. *Do NOT* create a public GitHub issue for security vulnerabilities -. Send a private report to the repository maintainers via GitHub’s -private vulnerability reporting feature -. Include as much detail as possible: -* Description of the vulnerability -* Steps to reproduce -* Potential impact -* Suggested fix (if any) +Report vulnerabilities privately to **j.d.a.jewell@open.ac.uk**. -=== Security Measures +**Do not** open a public issue for a security vulnerability. -This repository implements the following security practices: +== Response Timeline -==== GitHub Actions Security - -* *SHA-pinned actions*: All GitHub Actions are pinned to specific commit -SHAs to prevent supply chain attacks -* *Minimal permissions*: Workflows use the least privilege principle -with `+contents: read+` permission -* *SSH host key verification*: Known hosts are verified to prevent MITM -attacks during mirroring -* *Concurrency controls*: Prevents race conditions during parallel -workflow runs -* *Timeout limits*: All jobs have timeout limits to prevent resource -exhaustion - -==== Secret Management - -* SSH keys for mirror targets are stored as GitHub encrypted secrets -* Mirror operations are conditionally enabled via repository variables -* No secrets are logged or exposed in workflow outputs +[cols="1,2"] +|=== +|Acknowledgment |within 48 hours +|Assessment |within 7 days +|Fix (critical) |within 30 days +|Fix (other) |within 90 days +|=== -==== Force Push Warning +== Scope -This repository uses `+--force+` push for mirroring operations. This is -intentional for maintaining exact mirrors but means: - History on mirror -targets will be overwritten - Tags on mirror targets will be -force-updated - Only trusted maintainers should have push access to the -main branch +This policy covers the source code in this repository and the artefacts it +publishes. It does not cover third-party dependencies, which are governed +by their own policies. -=== Dependency Updates +== Supported Versions -This project monitors for security updates in: - GitHub Actions -(checkout, ssh-agent) - SSH host keys for mirror targets +The latest release on the default branch receives security fixes. -=== Contact +== Machine-Readable Form -For security concerns, use GitHub’s private security advisory feature or -contact the repository maintainers directly. +An RFC 9116 `+security.txt+` is published at link:.well-known/security.txt[.well-known/security.txt]. diff --git a/TEST-NEEDS.adoc b/TEST-NEEDS.adoc deleted file mode 100644 index 9829a1c..0000000 --- a/TEST-NEEDS.adoc +++ /dev/null @@ -1,139 +0,0 @@ -== TEST-NEEDS.md — maa-framework - -____ -Generated 2026-03-29 by punishing audit. -____ - -=== CRG Grade: C — ACHIEVED 2026-04-04 - -All CRG C requirements met across the absolute-zero crate: - Unit tests: -47 total (*29* in aletheia src, 13 brainfuck, 5 whitespace) - Smoke -tests: build and self-verification pass - P2P/property-based: 11 -deterministic property tests in -`+absolute-zero/tests/property_based.rs+` (100% pass) - E2E/reflexive: -10 brainfuck interpreter E2E tests in -`+absolute-zero/tests/brainfuck_e2e.rs+` (100% pass) - Security aspect -tests: 11 tests in `+absolute-zero/tests/security_aspects.rs+` (100% -pass) - Criterion benchmarks: -`+absolute-zero/benches/cno_benchmarks.rs+` (compiles and runs) - -____ -*Updated 2026-07-29.* aletheia unit tests went 26 → *29*: three new -tests for SHA-pin detection (PR #144), added alongside a fix for a check -that could never fail. One tautological `+assert!(true)+` was replaced -with a real assertion at the same time. `+absolute-zero/+` is a -submodule — its tests run in the upstream repo, not in this repository’s -CI. -____ - -____ -*Updated 2026-09-21.* aletheia unit tests went 29 → *66* -and the integration suite went 2 pass / 27 fail → *45 pass / 0 fail* -(issues #124 and #125 closed). The root `+rust-ci.yml+` gate was -restored re-pointed at `+aletheia/+` with clippy blocking. `+absolute-zero/+` -tests still run in the upstream repo. -____ - -==== The 45 passing aletheia integration tests (was: 27 failing by design) - -*Resolved 2026-09-21 (issue #124).* The CLI the suite specified has been -written — against the upstream RSR criteria, not against the suite's -strings, exactly as the caution below demanded. `+tests/integration_tests.rs+` -(47 tests) runs the built binary end to end: 26 checks over the offline -file-presence subset, `+--help+`, `+--version+`, `+--verbose+`, -`+--badge+`, `+--init-hook+`, `+--format=+`, HTML output. The suite is in -the CI gate and in `+just test+` (full `+cargo test --locked+`). - -The historical note is preserved because the warning still applies to -future checks: - -____ -[!CAUTION] Every assertion in that suite is on a *stdout substring*. -That pins the _wording_ of the verdict and says nothing about what the -checks must verify — so the whole suite can be satisfied by checks that -verify nothing. New checks must cite their upstream criterion (see -`+SSOT_PROVENANCE+` in `+aletheia/src/checks.rs+`); never write a check -to match a string. -____ - -=== Current State - -[width="100%",cols="50%,25%,25%",options="header",] -|=== -|Category |Count |Notes -|Unit tests |0 |No inline tests in source - -|Integration |3 |absolute-zero FFI integration_test.zig, aletheia FFI -integration_test.zig, rhodibot integration_tests.rs - -|E2E |0 |None - -|Benchmarks |1 |aletheia/benches/verification_benchmark.rs — uses -std::time, not criterion (manual benchmark, not automated) -|=== - -*Source modules:* ~23 across 2 subsystems. absolute-zero: brainfuck -interpreter, whitespace interpreter, main + ABI/FFI. aletheia: checks, -config, main, output, types + rhodibot + rhodium-pipeline + ABI/FFI. - -=== What’s Missing - -==== P2P (Property-Based) Tests - -* [ ] absolute-zero: arbitrary brainfuck program fuzzing (already has -fuzz target, good) -* [ ] aletheia: arbitrary repo structure verification fuzzing -* [ ] Config parsing: property tests for all config formats - -==== E2E Tests - -* [ ] absolute-zero: compile -> execute -> verify program output -* [ ] aletheia: full RSR verification pipeline (scan repo -> check rules --> report) -* [ ] rhodibot: full bot operation cycle -* [ ] rhodium-pipeline: extraction pipeline end-to-end - -==== Aspect Tests - -* *Security:* No tests for aletheia bypass (can a repo trick the -verifier?), rhodibot credential handling -* *Performance:* Benchmark exists but is manual (std::time), not -integrated into CI, not criterion-based -* *Concurrency:* No tests for parallel verification of multiple repos -* *Error handling:* No tests for malformed repos, missing files, invalid -configurations - -==== Build & Execution - -* [ ] `+cargo test+` for all Rust crates -* [ ] `+zig build test+` for FFI tests -* [ ] `+cargo fuzz+` for absolute-zero fuzz targets - -==== Benchmarks Needed - -* [ ] Verification speed per repo size/complexity (aletheia) -* [ ] Brainfuck/whitespace interpreter throughput (absolute-zero) -* [ ] rhodibot processing rate -* [ ] Pipeline extraction throughput - -==== Self-Tests - -* [ ] aletheia: verify itself against RSR standards -* [ ] Config schema validation -* [ ] ABI version agreement - -=== Priority - -*HIGH.* An RSR compliance verification framework that cannot verify -itself is the definition of irony. 23 source modules with 0 unit tests. -The 3 integration tests are a start but cover only FFI seams. The -benchmark is manual and not CI-integrated. Fuzz targets for -absolute-zero are good but need complementary structured tests. - -=== FAKE-FUZZ ALERT - -* `+tests/fuzz/placeholder.txt+` is a scorecard placeholder inherited -from rsr-template-repo — it does NOT provide real fuzz testing -* Replace with an actual fuzz harness (see -rsr-template-repo/tests/fuzz/README.adoc) or remove the file -* Priority: P2 — creates false impression of fuzz coverage diff --git a/TOPOLOGY.adoc b/TOPOLOGY.adoc deleted file mode 100644 index 7c0fa37..0000000 --- a/TOPOLOGY.adoc +++ /dev/null @@ -1,87 +0,0 @@ -== MAA Framework — Project Topology - -=== System Architecture - -.... - ┌─────────────────────────────────────────┐ - │ MAA FRAMEWORK │ - │ (Full-Stack System Paradigm) │ - └───────────────────┬─────────────────────┘ - │ - ▼ - ┌─────────────────────────────────────────┐ - │ GOVERNANCE & POLICY │ - │ ┌───────────┐ ┌───────────────────┐ │ - │ │ AI Ethics │ │ RSR Standards │ │ - │ │ (Axiology)│ │ (Compliance) │ │ - │ └─────┬─────┘ └────────┬──────────┘ │ - └────────│─────────────────│──────────────┘ - │ │ - ▼ ▼ - ┌─────────────────────────────────────────┐ - │ LANGUAGE & KERNEL │ - │ ┌───────────┐ ┌───────────────────┐ │ - │ │ Oblíbený │ │ Aletheia │ │ - │ │ (Language)│ │ (Microkernel) │ │ - │ └─────┬─────┘ └────────┬──────────┘ │ - └────────│─────────────────│──────────────┘ - │ │ - ▼ ▼ - ┌─────────────────────────────────────────┐ - │ DISTRIBUTED RUNTIME │ - │ (BOINC, RISC-V, Sustainable) │ - └─────────────────────────────────────────┘ - - ┌─────────────────────────────────────────┐ - │ REPO INFRASTRUCTURE │ - │ Justfile / Mustfile .machine_readable/ │ - │ Multi-Forge Hub 0-AI-MANIFEST.a2ml │ - └─────────────────────────────────────────┘ -.... - -=== Completion Dashboard - -.... -COMPONENT STATUS NOTES -───────────────────────────────── ────────────────── ───────────────────────────────── -SPECIFICATIONS - Framework Paradigm ██████████ 100% Core scope defined - Oblíbený Reference Lang ██████░░░░ 60% Grammar & semantics refining - Aletheia Microkernel ████░░░░░░ 40% Initial architecture stubs - AI Ethics & Axiology ████████░░ 80% Value-alignment policies stable - -INFRASTRUCTURE - Multi-Forge Mirroring ██████████ 100% GH/GL/BB/CB sync stable - Supply Chain Security ██████████ 100% SHA-pinned actions verified - .machine_readable/ ██████████ 100% STATE tracking active - -REPO INFRASTRUCTURE - Justfile Automation ██████████ 100% Standard build/sync tasks - 0-AI-MANIFEST.a2ml ██████████ 100% AI entry point verified - Language Policy (CCCP) ██████████ 100% RSR stack verified - -───────────────────────────────────────────────────────────────────────────── -OVERALL: ██████░░░░ ~60% Governance stable, Core pending -.... - -=== Key Dependencies - -.... -Framework Spec ───► Oblíbený Lang ───► Aletheia Kernel ───► Runtime - │ │ │ │ - ▼ ▼ ▼ ▼ -RSR Standards ───► Infrastructure ───► Multi-Forge ──────► Compliance -.... - -=== Update Protocol - -This file is maintained by both humans and AI agents. When updating: - -[arabic] -. *After completing a component*: Change its bar and percentage -. *After adding a component*: Add a new row in the appropriate section -. *After architectural changes*: Update the ASCII diagram -. *Date*: Update the `+Last updated+` comment at the top of this file - -Progress bars use: `+█+` (filled) and `+░+` (empty), 10 characters wide. -Percentages: 0%, 10%, 20%, … 100% (in 10% increments). diff --git a/absolute-zero b/absolute-zero deleted file mode 160000 index 87902bb..0000000 --- a/absolute-zero +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 87902bb770e767c10e065d9ac75d111e80a01be1 diff --git a/aletheia/.claude/CLAUDE.md b/aletheia/.claude/CLAUDE.md deleted file mode 100644 index 4a78174..0000000 --- a/aletheia/.claude/CLAUDE.md +++ /dev/null @@ -1,87 +0,0 @@ - -## Machine-Readable Artefacts - -The following files in `.machine_readable/` contain structured project metadata: - -- `STATE.scm` - Current project state and progress -- `META.scm` - Architecture decisions and development practices -- `ECOSYSTEM.scm` - Position in the ecosystem and related projects -- `AGENTIC.scm` - AI agent interaction patterns -- `NEUROSYM.scm` - Neurosymbolic integration config -- `PLAYBOOK.scm` - Operational runbook - ---- - -# CLAUDE.md - AI Assistant Instructions - -## Language Policy (Hyperpolymath Standard) - -### ALLOWED Languages & Tools - -| Language/Tool | Use Case | Notes | -|---------------|----------|-------| -| **AffineScript** | Primary application code | Compiles to JS, type-safe | -| **Bun** | JS runtime & package management (tier 1) | Default for all new work. Runs compiled ESM/JS directly — no bundler step. Uses an npm-compatible `package.json` plus `bun.lock` — both are expected, not anti-patterns. | -| **Rust** | Performance-critical, systems, WASM | Preferred for CLI tools | -| **Tauri 2.0+** | Mobile apps (iOS/Android) | Rust backend + web UI | -| **Dioxus** | Mobile apps (native UI) | Pure Rust, React-like | -| **Gleam** | Backend services | Runs on BEAM or compiles to JS | -| **Bash/POSIX Shell** | Scripts, automation | Keep minimal | -| **JavaScript** | Only where AffineScript cannot | MCP protocol glue, Bun APIs | -| **Nickel** | Configuration language | For complex configs | -| **Guile Scheme** | State/meta files | STATE.scm, META.scm, ECOSYSTEM.scm | -| **Julia** | Batch scripts, data processing | Per RSR | -| **OCaml** | AffineScript compiler | Language-specific | -| **Ada** | Safety-critical systems | Where required | - -### BANNED - Do Not Use - -| Banned | Replacement | -|--------|-------------| -| TypeScript | AffineScript | -| Deno | Bun | -| Node.js | Bun | -| npm | Bun | -| pnpm/yarn | Bun | -| Go | Rust | -| Python | Julia/Rust/AffineScript | -| Java/Kotlin | Rust/Tauri/Dioxus | -| Swift | Tauri/Dioxus | -| React Native | Tauri/Dioxus | -| Flutter/Dart | Tauri/Dioxus | - -### Mobile Development - -**No exceptions for Kotlin/Swift** - use Rust-first approach: - -1. **Tauri 2.0+** - Web UI (AffineScript) + Rust backend, MIT/Apache-2.0 -2. **Dioxus** - Pure Rust native UI, MIT/Apache-2.0 - -Both are FOSS with independent governance (no Big Tech). - -### Enforcement Rules - -1. **No new TypeScript files** - Convert existing TS to AffineScript -2. **Use `package.json` + `bun.lock` for JS runtime deps** - Bun is npm-compatible; a manifest is REQUIRED -3. **`bun install --production` for production deps** - resolved from `package.json`, pinned via `bun.lock` -4. **No Go code** - Use Rust instead -5. **No Python anywhere** - Use Julia for data/batch, Rust for systems, AffineScript for apps -6. **No Kotlin/Swift for mobile** - Use Tauri 2.0+ or Dioxus - -### Package Management - -- **Primary**: Guix (guix.scm) -- **Fallback**: Nix (flake.nix) -- **JS deps**: Bun (`package.json` + `bun.lock`). Declare tooling as a devDependency and run `bunx --no-install --bun ` — a bare `bunx ` can fetch an unpinned package and may start Node via its shebang. - -### Security Requirements - -- No MD5/SHA1 for security (use SHA256+) -- HTTPS only (no HTTP URLs) -- No hardcoded secrets -- SHA-pinned dependencies -- SPDX license headers on all files - diff --git a/aletheia/.clippy.toml b/aletheia/.clippy.toml deleted file mode 100644 index 92d10aa..0000000 --- a/aletheia/.clippy.toml +++ /dev/null @@ -1,26 +0,0 @@ -# Clippy configuration for Aletheia -# This configures Rust's linter for our specific needs - -# Cognitive complexity threshold -cognitive-complexity-threshold = 30 - -# Array size threshold for passing by reference -array-size-threshold = 64 - -# Maximum number of lines in a function -too-large-for-stack = 200 - -# Maximum number of single char bindings in a scope -single-char-binding-names-threshold = 5 - -# Maximum number of bool parameters -max-fn-params-bools = 2 - -# Minimum number of lines for doc comments -doc-valid-idents = ["RSR", "TPCF", "CADRE", "Aletheia", "GitLab", "GitHub"] - -# Disallowed names (variable names to avoid) -disallowed-names = ["foo", "bar", "baz", "quux"] - -# Allowed identifiers in docs -# This prevents clippy from complaining about our Greek term and acronyms diff --git a/aletheia/.clusterfuzzlite/Containerfile b/aletheia/.clusterfuzzlite/Containerfile deleted file mode 100644 index 5d41892..0000000 --- a/aletheia/.clusterfuzzlite/Containerfile +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -FROM gcr.io/oss-fuzz-base/base-builder-rust@sha256:73c1d5648db54100639339d411a5d192cbc8bf413ee91e843a07cf6f0e319dc7 - -COPY . $SRC/aletheia -WORKDIR $SRC/aletheia - -COPY .clusterfuzzlite/build.sh $SRC/ diff --git a/aletheia/.clusterfuzzlite/build.sh b/aletheia/.clusterfuzzlite/build.sh deleted file mode 100755 index 8376964..0000000 --- a/aletheia/.clusterfuzzlite/build.sh +++ /dev/null @@ -1,7 +0,0 @@ -#!/bin/bash -eu -# SPDX-License-Identifier: MPL-2.0 -cd "$SRC"/aletheia -cargo +nightly fuzz build -for target in $(cargo +nightly fuzz list); do - cp ./target/x86_64-unknown-linux-gnu/release/$target $OUT/ -done diff --git a/aletheia/.clusterfuzzlite/project.yaml b/aletheia/.clusterfuzzlite/project.yaml deleted file mode 100644 index 311ed3d..0000000 --- a/aletheia/.clusterfuzzlite/project.yaml +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -language: rust diff --git a/aletheia/.dockerignore b/aletheia/.dockerignore deleted file mode 100644 index 925dfce..0000000 --- a/aletheia/.dockerignore +++ /dev/null @@ -1,46 +0,0 @@ -# Docker ignore file - exclude unnecessary files from Docker context - -# Git -.git/ -.gitignore - -# Build artifacts -target/ -*.rs.bk - -# IDE -.vscode/ -.idea/ -*.swp -*.swo - -# Documentation (not needed in container) -docs/ -examples/ -*.md -!README.md - -# CI/CD -.gitlab-ci.yml -.github/ - -# Development tools -justfile -flake.nix -.editorconfig -.rustfmt.toml -.clippy.toml - -# Tests and benchmarks -tests/ -benches/ - -# Temporary files -tmp/ -temp/ -*.tmp -*.log - -# OS files -.DS_Store -Thumbs.db diff --git a/aletheia/.editorconfig b/aletheia/.editorconfig deleted file mode 100644 index 34d29de..0000000 --- a/aletheia/.editorconfig +++ /dev/null @@ -1,57 +0,0 @@ -# EditorConfig - Consistent coding style across editors -# https://editorconfig.org - -root = true - -# All files -[*] -charset = utf-8 -end_of_line = lf -insert_final_newline = true -trim_trailing_whitespace = true - -# Rust source files -[*.rs] -indent_style = space -indent_size = 4 -max_line_length = 100 - -# TOML files (Cargo.toml, etc.) -[*.toml] -indent_style = space -indent_size = 2 - -# Markdown files -[*.md] -indent_style = space -indent_size = 2 -trim_trailing_whitespace = false # Preserve trailing spaces for line breaks - -# YAML files (.gitlab-ci.yml, etc.) -[*.yml] -indent_style = space -indent_size = 2 - -# Nix files -[*.nix] -indent_style = space -indent_size = 2 - -# Shell scripts -[*.sh] -indent_style = space -indent_size = 2 - -# Just files -[justfile] -indent_style = space -indent_size = 4 - -# JSON files -[*.json] -indent_style = space -indent_size = 2 - -# Makefiles (just in case) -[Makefile] -indent_style = tab diff --git a/aletheia/.gitattributes b/aletheia/.gitattributes deleted file mode 100644 index e860a85..0000000 --- a/aletheia/.gitattributes +++ /dev/null @@ -1,54 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR-compliant .gitattributes - -* text=auto eol=lf - -# Source -*.rs text eol=lf diff=rust -*.ex text eol=lf diff=elixir -*.exs text eol=lf diff=elixir -*.jl text eol=lf -*.res text eol=lf -*.resi text eol=lf -*.ada text eol=lf diff=ada -*.adb text eol=lf diff=ada -*.ads text eol=lf diff=ada -*.hs text eol=lf -*.chpl text eol=lf -*.scm text eol=lf -*.ncl text eol=lf -*.nix text eol=lf - -# Docs -*.md text eol=lf diff=markdown -*.adoc text eol=lf -*.txt text eol=lf - -# Data -*.json text eol=lf -*.yaml text eol=lf -*.yml text eol=lf -*.toml text eol=lf - -# Config -.gitignore text eol=lf -.gitattributes text eol=lf -justfile text eol=lf -Makefile text eol=lf -Containerfile text eol=lf - -# Scripts -*.sh text eol=lf - -# Binary -*.png binary -*.jpg binary -*.gif binary -*.pdf binary -*.woff2 binary -*.zip binary -*.gz binary - -# Lock files -Cargo.lock text eol=lf -diff -flake.lock text eol=lf -diff diff --git a/aletheia/.github/FUNDING.yml b/aletheia/.github/FUNDING.yml deleted file mode 100644 index 688a442..0000000 --- a/aletheia/.github/FUNDING.yml +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Funding platforms for hyperpolymath projects -# See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository - -github: hyperpolymath -ko_fi: hyperpolymath -liberapay: hyperpolymath diff --git a/aletheia/.github/ISSUE_TEMPLATE/bug_report.md b/aletheia/.github/ISSUE_TEMPLATE/bug_report.md deleted file mode 100644 index 917068f..0000000 --- a/aletheia/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,42 +0,0 @@ - ---- -name: Bug report -about: Create a report to help us improve -title: "[Bug]: " -labels: 'bug, priority: unset, triage' -assignees: '' - ---- - -**Describe the bug** -A clear and concise description of what the bug is. - -**To Reproduce** -Steps to reproduce the behavior: -1. Go to '...' -2. Click on '....' -3. Scroll down to '....' -4. See error - -**Expected behavior** -A clear and concise description of what you expected to happen. - -**Screenshots** -If applicable, add screenshots to help explain your problem. - -**Desktop (please complete the following information):** - - OS: [e.g. iOS] - - Browser [e.g. chrome, safari] - - Version [e.g. 22] - -**Smartphone (please complete the following information):** - - Device: [e.g. iPhone6] - - OS: [e.g. iOS8.1] - - Browser [e.g. stock browser, safari] - - Version [e.g. 22] - -**Additional context** -Add any other context about the problem here. diff --git a/aletheia/.github/ISSUE_TEMPLATE/custom.md b/aletheia/.github/ISSUE_TEMPLATE/custom.md deleted file mode 100644 index bfb2caf..0000000 --- a/aletheia/.github/ISSUE_TEMPLATE/custom.md +++ /dev/null @@ -1,14 +0,0 @@ - ---- -name: Custom issue template -about: Describe this issue template's purpose here. -title: '' -labels: '' -assignees: '' - ---- - - diff --git a/aletheia/.github/ISSUE_TEMPLATE/documentation.md b/aletheia/.github/ISSUE_TEMPLATE/documentation.md deleted file mode 100644 index b686e81..0000000 --- a/aletheia/.github/ISSUE_TEMPLATE/documentation.md +++ /dev/null @@ -1,70 +0,0 @@ - ---- -name: Documentation -about: Report unclear, missing, or incorrect documentation -title: "[DOCS]: " -labels: 'documentation, priority: unset, triage' -assignees: '' - ---- - -name: Documentation -description: Report unclear, missing, or incorrect documentation -title: "[Docs]: " -labels: ["documentation", "triage"] -body: - - type: markdown - attributes: - value: | - Help us improve our documentation by reporting issues or gaps. - - - type: dropdown - id: type - attributes: - label: Documentation issue type - options: - - Missing (documentation doesn't exist) - - Incorrect (information is wrong) - - Unclear (confusing or hard to follow) - - Outdated (no longer accurate) - - Typo or grammar - validations: - required: true - - - type: input - id: location - attributes: - label: Location - description: Where is this documentation? (URL, file path, or section name) - placeholder: README.adoc, section "Installation" - validations: - required: true - - - type: textarea - id: description - attributes: - label: Description - description: What's the problem with the current documentation? - placeholder: Describe what's wrong or missing - validations: - required: true - - - type: textarea - id: suggestion - attributes: - label: Suggested improvement - description: How should it be fixed or improved? - placeholder: The documentation should say... - validations: - required: false - - - type: checkboxes - id: contribution - attributes: - label: Contribution - options: - - label: I would be willing to submit a PR to fix this - required: false diff --git a/aletheia/.github/ISSUE_TEMPLATE/feature_request.md b/aletheia/.github/ISSUE_TEMPLATE/feature_request.md deleted file mode 100644 index fa0243f..0000000 --- a/aletheia/.github/ISSUE_TEMPLATE/feature_request.md +++ /dev/null @@ -1,24 +0,0 @@ - ---- -name: Feature request -about: Suggest an idea for this project -title: '' -labels: 'enhancement, priority: unset, triage' -assignees: '' - ---- - -**Is your feature request related to a problem? Please describe.** -A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] - -**Describe the solution you'd like** -A clear and concise description of what you want to happen. - -**Describe alternatives you've considered** -A clear and concise description of any alternative solutions or features you've considered. - -**Additional context** -Add any other context or screenshots about the feature request here. diff --git a/aletheia/.github/ISSUE_TEMPLATE/question.md b/aletheia/.github/ISSUE_TEMPLATE/question.md deleted file mode 100644 index ac505d4..0000000 --- a/aletheia/.github/ISSUE_TEMPLATE/question.md +++ /dev/null @@ -1,59 +0,0 @@ - ---- -name: Question -about: Ask a question about usage or behaviour -title: "[QUESTION]: " -labels: question, triage -assignees: '' - ---- - -name: Question -description: Ask a question about usage or behaviour -title: "[Question]: " -labels: ["question", "triage"] -body: - - type: markdown - attributes: - value: | - Have a question? You can also ask in [Discussions](../discussions) for broader conversations. - - - type: textarea - id: question - attributes: - label: Your question - description: What would you like to know? - placeholder: How do I...? - validations: - required: true - - - type: textarea - id: context - attributes: - label: Context - description: Any relevant context that helps us answer your question - placeholder: I'm trying to achieve X and I've tried Y... - validations: - required: false - - - type: textarea - id: research - attributes: - label: What I've already tried - description: What have you already looked at or attempted? - placeholder: I've read the README and searched issues but... - validations: - required: false - - - type: checkboxes - id: checked - attributes: - label: Pre-submission checklist - options: - - label: I have searched existing issues and discussions - required: true - - label: I have read the documentation - required: true diff --git a/aletheia/.github/dependabot.yml b/aletheia/.github/dependabot.yml deleted file mode 100644 index fd857bb..0000000 --- a/aletheia/.github/dependabot.yml +++ /dev/null @@ -1,22 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -version: 2 -updates: - - package-ecosystem: "cargo" - directory: "/" - schedule: - interval: "weekly" - ignore: - - dependency-name: "*" - update-types: ["version-update:semver-patch"] - - package-ecosystem: "github-actions" - directory: "/" - schedule: - interval: "weekly" - groups: - actions: - patterns: - - "*" - - package-ecosystem: "nix" - directory: "/" - schedule: - interval: "weekly" diff --git a/aletheia/.github/workflows/README.md b/aletheia/.github/workflows/README.md deleted file mode 100644 index b9727bc..0000000 --- a/aletheia/.github/workflows/README.md +++ /dev/null @@ -1,51 +0,0 @@ - - -# These 16 workflows do not run. They never have. - -GitHub Actions only reads workflow files from `.github/workflows/` **at the root of a -repository**. This directory is nested inside `maa-framework`, so every YAML file here -is inert — including `rust-ci.yml`, `codeql.yml`, `cflite_pr.yml`, `cflite_batch.yml`, -`generator-generic-ossf-slsa3-publish.yml`, `scorecard.yml`, and `ghcr-publish.yml`. - -## Why they are here - -`aletheia` began as the standalone repository `hyperpolymath/aletheia` (created -2025-12-11), where these workflows *did* run. That repository was removed from GitHub — -its mirrors on GitLab, Codeberg and Bitbucket all stop by early January 2026. On -2026-02-21, commit `639f389` left behind a dangling gitlink with no `.gitmodules` -entry; on 2026-03-02, commit `25cf219` ("Fix stale submodule pointers after repo -cleanup") replaced that pointer by vendoring 361 files — these workflows among them — -into `maa-framework` as ordinary tracked files. - -Nothing has executed them since. - -## What that cost - -Between 2026-06-17 and 2026-07-21, `aletheia` **did not compile**. Commit `b5322c2` -("security: remediate Track C and Track E findings") correctly added a 1 MiB read cap -to `Config::load_config`, but collapsed the block onto one line and dropped a closing -brace. A single `cargo build` would have caught it. Nothing ran one, so `main` stayed -broken for over a month. - -## Where the real gate lives now - -`/.github/workflows/rust-ci.yml`, at the repository root. (It went missing for a -while: the commit that moved the crate to `aletheia/` deleted the old root gate -without re-pointing it, so main had no Rust CI until the gate was restored on -2026-09-21.) It builds debug (`--all-targets`) and release, runs the full test -suite (66 unit + 45 integration and counting), checks formatting, runs clippy -with warnings denied (issue #125), and enforces the zero-dependency constraint -from `aletheia/CLAUDE.md`. Each job has a same-named recipe in the root Justfile -— `just check` runs the same steps locally. Read the workflow header comment for -what it deliberately does *not* gate yet. - -## If you are changing CI for aletheia - -Edit the root workflow. Editing anything in this directory has no effect. These files -are retained only as the source material for porting the capabilities that were lost — -ClusterFuzzLite fuzzing, SLSA3 provenance, GHCR publishing — back to root workflows. -Once a capability is ported, delete its file here so this directory shrinks toward -empty. diff --git a/aletheia/.github/workflows/aletheia.yml b/aletheia/.github/workflows/aletheia.yml deleted file mode 100644 index 1e5283c..0000000 --- a/aletheia/.github/workflows/aletheia.yml +++ /dev/null @@ -1,78 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Aletheia RSR Compliance Check -# This workflow verifies RSR Bronze-level compliance using Aletheia -# -# Usage: Copy this file to your repository's .github/workflows/ directory - -name: RSR Compliance - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -env: - CARGO_TERM_COLOR: always - -jobs: - rsr-compliance: - name: RSR Bronze Compliance Check - runs-on: ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout repository - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - with: - toolchain: stable - - - name: Cache Cargo registry - uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4 - with: - path: | - ~/.cargo/registry - ~/.cargo/git - target - key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }} - restore-keys: | - ${{ runner.os }}-cargo- - - - name: Install Aletheia - run: cargo install aletheia || cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - - - name: Run RSR Compliance Check - run: aletheia --format json > aletheia-report.json - - - name: Display Results - run: | - echo "## RSR Compliance Report" >> $GITHUB_STEP_SUMMARY - echo "" >> $GITHUB_STEP_SUMMARY - if jq -e '.bronze_compliant == true and .has_critical_warnings == false' aletheia-report.json > /dev/null; then - echo "✅ **Bronze-level RSR compliance: ACHIEVED**" >> $GITHUB_STEP_SUMMARY - else - echo "❌ **Bronze-level RSR compliance: NOT MET**" >> $GITHUB_STEP_SUMMARY - fi - echo "" >> $GITHUB_STEP_SUMMARY - echo "### Score" >> $GITHUB_STEP_SUMMARY - PASSED=$(jq '.score.passed' aletheia-report.json) - TOTAL=$(jq '.score.total' aletheia-report.json) - PCT=$(jq '.score.percentage' aletheia-report.json) - echo "$PASSED/$TOTAL checks passed ($PCT%)" >> $GITHUB_STEP_SUMMARY - - - name: Upload Report - uses: actions/upload-artifact@65c4c4a1ddee5b72f698fdd19549f0f0fb45cf08 # v4 - with: - name: aletheia-report - path: aletheia-report.json - - - name: Fail on Non-Compliance - run: | - if ! jq -e '.bronze_compliant == true and .has_critical_warnings == false' aletheia-report.json > /dev/null; then - echo "RSR Bronze compliance not met" - exit 1 - fi diff --git a/aletheia/.github/workflows/cflite_batch.yml b/aletheia/.github/workflows/cflite_batch.yml deleted file mode 100644 index e7248f2..0000000 --- a/aletheia/.github/workflows/cflite_batch.yml +++ /dev/null @@ -1,33 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: ClusterFuzzLite batch fuzzing -on: - schedule: - - cron: '0 3 * * 0' - workflow_dispatch: - -permissions: read-all - -jobs: - BatchFuzzing: - runs-on: ubuntu-latest - timeout-minutes: 15 - strategy: - fail-fast: false - matrix: - sanitizer: [address] - steps: - - name: Build Fuzzers (${{ matrix.sanitizer }}) - id: build - uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1 - with: - language: rust - sanitizer: ${{ matrix.sanitizer }} - - - name: Run Fuzzers (${{ matrix.sanitizer }}) - id: run - uses: google/clusterfuzzlite/actions/run_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - fuzz-seconds: 1800 - mode: batch - sanitizer: ${{ matrix.sanitizer }} diff --git a/aletheia/.github/workflows/cflite_pr.yml b/aletheia/.github/workflows/cflite_pr.yml deleted file mode 100644 index 9733d4c..0000000 --- a/aletheia/.github/workflows/cflite_pr.yml +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: ClusterFuzzLite PR fuzzing -on: - pull_request: - branches: [main] - -permissions: read-all - -jobs: - PR: - runs-on: ubuntu-latest - timeout-minutes: 15 - strategy: - fail-fast: false - matrix: - sanitizer: [address] - steps: - - name: Build Fuzzers (${{ matrix.sanitizer }}) - id: build - uses: google/clusterfuzzlite/actions/build_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1 - with: - language: rust - sanitizer: ${{ matrix.sanitizer }} - - - name: Run Fuzzers (${{ matrix.sanitizer }}) - id: run - uses: google/clusterfuzzlite/actions/run_fuzzers@884713a6c30a92e5e8544c39945cd7cb630abcd1 # v1 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - fuzz-seconds: 300 - mode: code-change - sanitizer: ${{ matrix.sanitizer }} diff --git a/aletheia/.github/workflows/codeql.yml b/aletheia/.github/workflows/codeql.yml deleted file mode 100644 index 741d0c1..0000000 --- a/aletheia/.github/workflows/codeql.yml +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: CodeQL Security Analysis - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - schedule: - - cron: '0 6 * * 1' - - -permissions: read-all - -jobs: - analyze: - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - contents: read - security-events: write - strategy: - fail-fast: false - matrix: - include: - - language: rust - build-mode: none - - steps: - - name: Checkout - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4.1.1 - - - name: Initialize CodeQL - uses: github/codeql-action/init@662472033e021d55d94146f66f6058822b0b39fd # v3.28.1 - with: - languages: ${{ matrix.language }} - build-mode: ${{ matrix.build-mode }} - - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@662472033e021d55d94146f66f6058822b0b39fd # v3.28.1 - with: - category: "/language:${{ matrix.language }}" diff --git a/aletheia/.github/workflows/generator-generic-ossf-slsa3-publish.yml b/aletheia/.github/workflows/generator-generic-ossf-slsa3-publish.yml deleted file mode 100644 index 2cdcdc2..0000000 --- a/aletheia/.github/workflows/generator-generic-ossf-slsa3-publish.yml +++ /dev/null @@ -1,68 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# This workflow uses actions that are not certified by GitHub. -# They are provided by a third-party and are governed by -# separate terms of service, privacy policy, and support -# documentation. - -# This workflow lets you generate SLSA provenance file for your project. -# The generation satisfies level 3 for the provenance requirements - see https://slsa.dev/spec/v0.1/requirements -# The project is an initiative of the OpenSSF (openssf.org) and is developed at -# https://github.com/slsa-framework/slsa-github-generator. -# The provenance file can be verified using https://github.com/slsa-framework/slsa-verifier. -# For more information about SLSA and how it improves the supply-chain, visit slsa.dev. - -name: SLSA generic generator -on: - workflow_dispatch: - release: - types: [created] - -jobs: - build: - runs-on: ubuntu-latest - timeout-minutes: 15 - outputs: - digests: ${{ steps.hash.outputs.digests }} - - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - # ======================================================== - # - # Step 1: Build your artifacts. - # - # ======================================================== - - name: Build artifacts - run: | - # These are some amazing artifacts. - echo "artifact1" > artifact1 - echo "artifact2" > artifact2 - - # ======================================================== - # - # Step 2: Add a step to generate the provenance subjects - # as shown below. Update the sha256 sum arguments - # to include all binaries that you generate - # provenance for. - # - # ======================================================== - - name: Generate subject for provenance - id: hash - run: | - set -euo pipefail - - # List the artifacts the provenance will refer to. - files=$(ls artifact*) - # Generate the subjects (base64 encoded). - echo "hashes=$(sha256sum $files | base64 -w0)" >> "${GITHUB_OUTPUT}" - - provenance: - needs: [build] - permissions: - actions: read # To read the workflow path. - id-token: write # To sign the provenance. - contents: write # To add assets to a release. - uses: slsa-framework/slsa-github-generator/.github/workflows/generator_generic_slsa3.yml@f7dd8c54c2067bafc12ca7a55595d5ee9b75204a # v2.1.0 - with: - base64-subjects: "${{ needs.build.outputs.digests }}" - upload-assets: true # Optional: Upload to a new release diff --git a/aletheia/.github/workflows/ghcr-publish.yml b/aletheia/.github/workflows/ghcr-publish.yml deleted file mode 100644 index bf7b778..0000000 --- a/aletheia/.github/workflows/ghcr-publish.yml +++ /dev/null @@ -1,61 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: Publish to GHCR - -permissions: read-all - -on: - release: - types: [published] - workflow_dispatch: - -env: - REGISTRY: ghcr.io - IMAGE_NAME: ${{ github.repository }} - -jobs: - build-and-push: - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - contents: read - packages: write - - steps: - - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - - name: Install nerdctl and containerd - run: | - sudo apt-get update - sudo apt-get install -y containerd - sudo systemctl start containerd - - NERDCTL_VERSION=2.2.1 - curl -fsSL "https://github.com/containerd/nerdctl/releases/download/v${NERDCTL_VERSION}/nerdctl-full-${NERDCTL_VERSION}-linux-amd64.tar.gz" -o /tmp/nerdctl.tar.gz - sudo tar -xzf /tmp/nerdctl.tar.gz -C /usr/local - sudo mkdir -p /opt/cni/bin - sudo cp /usr/local/libexec/cni/* /opt/cni/bin/ 2>/dev/null || true - - sudo /usr/local/bin/buildkitd & - sleep 3 - - - name: Log in to GHCR - run: | - echo "${{ secrets.GITHUB_TOKEN }}" | sudo nerdctl login ghcr.io -u ${{ github.actor }} --password-stdin - - - name: Build image - run: | - sudo nerdctl build -f Containerfile -t ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} . - sudo nerdctl tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - - name: Push image - run: | - sudo nerdctl push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} - sudo nerdctl push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:latest - - - name: Tag release version - if: github.event_name == 'release' - run: | - VERSION=${{ github.event.release.tag_name }} - sudo nerdctl tag ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ github.sha }} ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION} - sudo nerdctl push ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${VERSION} diff --git a/aletheia/.github/workflows/governance.yml b/aletheia/.github/workflows/governance.yml deleted file mode 100644 index b4062e0..0000000 --- a/aletheia/.github/workflows/governance.yml +++ /dev/null @@ -1,26 +0,0 @@ -# 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. -# -# Replaces the per-repo governance scaffolding removed in the same commit: -# quality.yml, guix-nix-policy.yml, npm-bun-blocker.yml, ts-blocker.yml, -# security-policy.yml, rsr-antipattern.yml, wellknown-enforcement.yml, -# workflow-linter.yml -# -# Load-bearing build/security workflows stay standalone in the repo -# (rust-ci, codeql, dependabot, release, scan/mirror/pages plumbing). - -name: Governance - -on: - push: - branches: [main, master] - pull_request: - workflow_dispatch: - -permissions: - contents: read - -jobs: - governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@861b5e911d9e5dcfb3c0ab3dd2a9a3c8fd0a1613 diff --git a/aletheia/.github/workflows/hypatia-scan.yml b/aletheia/.github/workflows/hypatia-scan.yml deleted file mode 100644 index 49e830d..0000000 --- a/aletheia/.github/workflows/hypatia-scan.yml +++ /dev/null @@ -1,180 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Hypatia Neurosymbolic CI/CD Security Scan -name: Hypatia Security Scan - -on: - push: - branches: [ main, master, develop ] - pull_request: - branches: [ main, master ] - schedule: - - cron: '0 0 * * 0' # Weekly on Sunday - workflow_dispatch: - -permissions: read-all - -jobs: - scan: - name: Hypatia Neurosymbolic Analysis - runs-on: ubuntu-latest - timeout-minutes: 15 - - steps: - - name: Checkout repository - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - with: - fetch-depth: 0 # Full history for better pattern analysis - - - name: Setup Elixir for Hypatia scanner - uses: erlef/setup-beam@2f0cc07b4b9bea248ae098aba9e1a8a1de5ec24c # v1.18.2 - with: - elixir-version: '1.19.4' - otp-version: '28.3' - - - 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) - working-directory: ${{ env.HOME }}/hypatia - run: | - if [ ! -f hypatia-v2 ]; then - echo "Building hypatia-v2 scanner..." - cd scanner - mix deps.get - mix escript.build - mv hypatia ../hypatia-v2 - fi - - - name: Run Hypatia scan - id: scan - run: | - echo "Scanning repository: ${{ github.repository }}" - - # Run scanner - HYPATIA_FORMAT=json "$HOME/hypatia/hypatia-cli.sh" scan . > hypatia-findings.json - - # Count findings - FINDING_COUNT=$(jq '. | length' hypatia-findings.json 2>/dev/null || echo 0) - echo "findings_count=$FINDING_COUNT" >> $GITHUB_OUTPUT - - # Extract severity counts - CRITICAL=$(jq '[.[] | select(.severity == "critical")] | length' hypatia-findings.json) - HIGH=$(jq '[.[] | select(.severity == "high")] | length' hypatia-findings.json) - MEDIUM=$(jq '[.[] | select(.severity == "medium")] | length' hypatia-findings.json) - - echo "critical=$CRITICAL" >> $GITHUB_OUTPUT - echo "high=$HIGH" >> $GITHUB_OUTPUT - echo "medium=$MEDIUM" >> $GITHUB_OUTPUT - - echo "## Hypatia Scan Results" >> $GITHUB_STEP_SUMMARY - echo "- Total findings: $FINDING_COUNT" >> $GITHUB_STEP_SUMMARY - echo "- Critical: $CRITICAL" >> $GITHUB_STEP_SUMMARY - echo "- High: $HIGH" >> $GITHUB_STEP_SUMMARY - echo "- Medium: $MEDIUM" >> $GITHUB_STEP_SUMMARY - - - name: Upload findings artifact - uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4 - with: - name: hypatia-findings - path: hypatia-findings.json - retention-days: 90 - - - name: Submit findings to gitbot-fleet (Phase 2) - if: steps.scan.outputs.findings_count > 0 - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - GITHUB_REPOSITORY: ${{ github.repository }} - GITHUB_SHA: ${{ github.sha }} - run: | - echo "📤 Submitting ${{ steps.scan.outputs.findings_count }} findings to gitbot-fleet..." - - # Clone gitbot-fleet to temp directory - FLEET_DIR="/tmp/gitbot-fleet-$$" - git clone https://github.com/hyperpolymath/gitbot-fleet.git "$FLEET_DIR" - - # Run submission script - bash "$FLEET_DIR/scripts/submit-finding.sh" hypatia-findings.json - - # Cleanup - rm -rf "$FLEET_DIR" - - echo "✅ Finding submission complete" - - - name: Check for critical issues - if: steps.scan.outputs.critical > 0 - run: | - echo "⚠️ Critical security issues found!" - echo "Review hypatia-findings.json for details" - # Don't fail the build yet - just warn - # exit 1 - - - 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. Review findings in the artifact: hypatia-findings.json - 2. Auto-fixable issues will be addressed by robot-repo-automaton (Phase 3) - 3. Manual review required for complex issues - - ## 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 - uses: actions/github-script@60a0d83039c74a4aee543508d2ffcb1c3799cdea # 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 - }); diff --git a/aletheia/.github/workflows/instant-sync.yml b/aletheia/.github/workflows/instant-sync.yml deleted file mode 100644 index 62a0f3e..0000000 --- a/aletheia/.github/workflows/instant-sync.yml +++ /dev/null @@ -1,34 +0,0 @@ -# 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 - timeout-minutes: 15 - steps: - - name: Trigger Propagation - uses: peter-evans/repository-dispatch@ff45666b9427631e3450c54a1bcbee4d9ff4d7c0 # v3 - with: - token: ${{ secrets.FARM_DISPATCH_TOKEN }} - repository: hyperpolymath/.git-private-farm - event-type: propagate - client-payload: |- - { - "repo": "${{ github.event.repository.name }}", - "ref": "${{ github.ref }}", - "sha": "${{ github.sha }}", - "forges": "" - } - - - name: Confirm - run: echo "::notice::Propagation triggered for ${{ github.event.repository.name }}" diff --git a/aletheia/.github/workflows/jekyll-gh-pages.yml b/aletheia/.github/workflows/jekyll-gh-pages.yml deleted file mode 100644 index d046132..0000000 --- a/aletheia/.github/workflows/jekyll-gh-pages.yml +++ /dev/null @@ -1,54 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Sample workflow for building and deploying a Jekyll site to GitHub Pages -name: Deploy Jekyll with GitHub Pages dependencies preinstalled - -on: - # Runs on pushes targeting the default branch - push: - branches: ["main"] - - # Allows you to run this workflow manually from the Actions tab - workflow_dispatch: - -# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages -permissions: - contents: read - pages: write - id-token: write - -# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued. -# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete. -concurrency: - group: "pages" - cancel-in-progress: false - -jobs: - # Build job - build: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - name: Checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - name: Setup Pages - uses: actions/configure-pages@983d7736d9b0ae728b81ab479565c72886d7745b # v5 - - name: Build with Jekyll - uses: actions/jekyll-build-pages@44a6e6beabd48582f863aeeb6cb2151cc1716697 # v1 - with: - source: ./ - destination: ./_site - - name: Upload artifact - uses: actions/upload-pages-artifact@56afc609e74202658d3ffba0e8f6dda462b719fa # v3 - - # Deployment job - deploy: - environment: - name: github-pages - url: ${{ steps.deployment.outputs.page_url }} - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: build - steps: - - name: Deploy to GitHub Pages - id: deployment - uses: actions/deploy-pages@d6db90164ac5ed86f2b6aed7e0febac5b3c0c03e # v4 diff --git a/aletheia/.github/workflows/mirror.yml b/aletheia/.github/workflows/mirror.yml deleted file mode 100644 index 6cee9bc..0000000 --- a/aletheia/.github/workflows/mirror.yml +++ /dev/null @@ -1,50 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: Mirror to GitLab and Bitbucket - -on: - push: - branches: [main, master] - tags: - - 'v*' - workflow_dispatch: - -jobs: - mirror-gitlab: - runs-on: ubuntu-latest - timeout-minutes: 15 - if: ${{ vars.GITLAB_MIRROR_ENABLED == 'true' }} - - steps: - - name: Checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - fetch-depth: 0 - - - name: Push to GitLab - env: - GITLAB_TOKEN: ${{ secrets.GITLAB_TOKEN }} - REPO_NAME: ${{ github.event.repository.name }} - run: | - git remote add gitlab https://oauth2:${GITLAB_TOKEN}@gitlab.com/hyperpolymath/${REPO_NAME}.git || true - git push gitlab HEAD:main --force || git push gitlab HEAD:master --force - git push gitlab --tags --force - - mirror-bitbucket: - runs-on: ubuntu-latest - timeout-minutes: 15 - if: ${{ vars.BITBUCKET_MIRROR_ENABLED == 'true' }} - - steps: - - name: Checkout - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - fetch-depth: 0 - - - name: Push to Bitbucket - env: - BITBUCKET_TOKEN: ${{ secrets.BITBUCKET_TOKEN }} - REPO_NAME: ${{ github.event.repository.name }} - run: | - git remote add bitbucket https://x-token-auth:${BITBUCKET_TOKEN}@bitbucket.org/hyperpolymath/${REPO_NAME}.git || true - git push bitbucket HEAD:main --force || git push bitbucket HEAD:master --force - git push bitbucket --tags --force diff --git a/aletheia/.github/workflows/publish-container.yml b/aletheia/.github/workflows/publish-container.yml deleted file mode 100644 index 546271e..0000000 --- a/aletheia/.github/workflows/publish-container.yml +++ /dev/null @@ -1,45 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: Publish Container - -on: - release: - types: [published] - workflow_dispatch: - -permissions: - contents: read - packages: write - -jobs: - publish: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@b4ffde65f46336ab88eb53be808477a3936bae11 # v4 - - - name: Log in to GitHub Container Registry - uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3 - with: - registry: ghcr.io - username: ${{ github.actor }} - password: ${{ secrets.GITHUB_TOKEN }} - - - name: Extract metadata - id: meta - uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5 - with: - images: ghcr.io/${{ github.repository }} - tags: | - type=semver,pattern={{version}} - type=semver,pattern={{major}}.{{minor}} - type=semver,pattern={{major}} - type=sha - - - name: Build and push - uses: docker/build-push-action@4f58ea79222b3b9dc2c8bbdd6debcef730109a75 # v6 - with: - context: . - file: ./Containerfile - push: true - tags: ${{ steps.meta.outputs.tags }} - labels: ${{ steps.meta.outputs.labels }} diff --git a/aletheia/.github/workflows/rust-ci.yml b/aletheia/.github/workflows/rust-ci.yml deleted file mode 100644 index 1db60f9..0000000 --- a/aletheia/.github/workflows/rust-ci.yml +++ /dev/null @@ -1,53 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: Rust CI -on: [push, pull_request] -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: -Dwarnings - -jobs: - test: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - with: - components: rustfmt, clippy - - uses: Swatinem/rust-cache@779680da715d629ac1d338a641029a2f4372abb5 # v2 - - - name: Check formatting - run: cargo fmt --all -- --check - - - name: Clippy lints - run: cargo clippy --all-targets --all-features -- -D warnings - - - name: Run tests - run: cargo test --all-features - - - name: Build release - run: cargo build --release - - security: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - - name: Install cargo-audit - run: cargo install cargo-audit - - name: Security audit - run: cargo audit - - name: Check for outdated deps - run: cargo install cargo-outdated && cargo outdated --exit-code 1 || true - - coverage: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - uses: dtolnay/rust-toolchain@4be9e76fd7c4901c61fb841f559994984270fce7 # stable - - name: Install tarpaulin - run: cargo install cargo-tarpaulin - - name: Generate coverage - run: cargo tarpaulin --out Xml diff --git a/aletheia/.github/workflows/scorecard-enforcer.yml b/aletheia/.github/workflows/scorecard-enforcer.yml deleted file mode 100644 index d5b414c..0000000 --- a/aletheia/.github/workflows/scorecard-enforcer.yml +++ /dev/null @@ -1,74 +0,0 @@ -# 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 - workflow_dispatch: - -permissions: read-all - -jobs: - scorecard: - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - security-events: write - id-token: write # For OIDC - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - persist-credentials: false - - - name: Run Scorecard - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 - with: - results_file: results.sarif - results_format: sarif - publish_results: true - - - name: Upload SARIF - uses: github/codeql-action/upload-sarif@b2f9ef845756500b97acbdaf5c1dd4e9c1d15734 # v3 - with: - sarif_file: results.sarif - - - name: Check minimum score - run: | - # Parse score from results - SCORE=$(jq -r '.runs[0].tool.driver.properties.score // 0' results.sarif 2>/dev/null || echo "0") - - echo "OpenSSF Scorecard Score: $SCORE" - - # Minimum acceptable score (0-10 scale) - MIN_SCORE=5 - - if [ "$(echo "$SCORE < $MIN_SCORE" | bc -l)" = "1" ]; then - 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@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - - 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 - unpinned=$(grep -r "uses:.*@v[0-9]" .github/workflows/*.yml 2>/dev/null | grep -v "#" | head -5 || true) - if [ -n "$unpinned" ]; then - echo "::warning::Found unpinned actions:" - echo "$unpinned" - fi diff --git a/aletheia/.github/workflows/scorecard.yml b/aletheia/.github/workflows/scorecard.yml deleted file mode 100644 index 58d0f9f..0000000 --- a/aletheia/.github/workflows/scorecard.yml +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -name: OSSF Scorecard -on: - push: - branches: [main, master] - schedule: - - cron: '0 4 * * 0' - -permissions: read-all - -jobs: - analysis: - runs-on: ubuntu-latest - timeout-minutes: 15 - permissions: - security-events: write - id-token: write - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - persist-credentials: false - - - name: Run Scorecard - uses: ossf/scorecard-action@62b2cac7ed8198b15735ed49ab1e5cf35480ba46 # v2.4.0 - with: - results_file: results.sarif - results_format: sarif - - - name: Upload results - uses: github/codeql-action/upload-sarif@b2f9ef845756500b97acbdaf5c1dd4e9c1d15734 # v3 - with: - sarif_file: results.sarif diff --git a/aletheia/.github/workflows/secret-scanner.yml b/aletheia/.github/workflows/secret-scanner.yml deleted file mode 100644 index 6e7d441..0000000 --- a/aletheia/.github/workflows/secret-scanner.yml +++ /dev/null @@ -1,70 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Prevention workflow - scans for hardcoded secrets before they reach main -name: Secret Scanner - -on: - pull_request: - push: - branches: [main] - -permissions: read-all - -jobs: - trufflehog: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - with: - fetch-depth: 0 # Full history for scanning - - - name: TruffleHog Secret Scan - uses: trufflesecurity/trufflehog@7ee2e0fdffec27d19ccbb8fb3dcf8a83b9d7f9e8 # main - with: - extra_args: --only-verified --fail - - gitleaks: - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # 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 - if: hashFiles('**/Cargo.toml') != '' - steps: - - uses: actions/checkout@34e114876b0b11c390a56381ad16ebd13914f8d5 # v4 - - - name: Check for hardcoded secrets in Rust - run: | - # Patterns that suggest hardcoded secrets - PATTERNS=( - 'const.*SECRET.*=.*"' - 'const.*KEY.*=.*"[a-zA-Z0-9]{16,}"' - 'const.*TOKEN.*=.*"' - 'let.*api_key.*=.*"' - 'HMAC.*"[a-fA-F0-9]{32,}"' - 'password.*=.*"[^"]+"' - ) - - found=0 - for pattern in "${PATTERNS[@]}"; do - if grep -rn --include="*.rs" -E "$pattern" src/; then - echo "WARNING: Potential hardcoded secret found matching: $pattern" - found=1 - fi - done - - if [ $found -eq 1 ]; then - echo "::error::Potential hardcoded secrets detected. Use environment variables instead." - exit 1 - fi diff --git a/aletheia/.gitignore b/aletheia/.gitignore deleted file mode 100644 index e19f7fb..0000000 --- a/aletheia/.gitignore +++ /dev/null @@ -1,89 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR-compliant .gitignore - -# OS & Editor -.DS_Store -Thumbs.db -*.swp -*.swo -*~ -.idea/ -.vscode/ - -# Build -target/ -/_build/ -/build/ -/dist/ -/out/ - -# Dependencies -/node_modules/ -/vendor/ -/deps/ -/.elixir_ls/ - -# Rust -# Cargo.lock # Keep for binaries - -# Elixir -/cover/ -/doc/ -*.ez -erl_crash.dump - -# Julia -*.jl.cov -*.jl.mem -/Manifest.toml - -# ReScript -/lib/bs/ -/.bsb.lock - -# Python (SaltStack only) -__pycache__/ -*.py[cod] -.venv/ - -# Ada/SPARK -*.ali -/obj/ -/bin/ - -# Haskell -/.stack-work/ -/dist-newstyle/ - -# Chapel -*.chpl.tmp.* - -# Secrets -.env -.env.* -*.pem -*.key -secrets/ - -# Test/Coverage -/coverage/ -htmlcov/ - -# Logs -*.log -/logs/ - -# Temp -/tmp/ -*.tmp -*.bak - -# Crash recovery artifacts -ai-cli-crash-capture/ -node_modules/ -_build/ -deps/ -.elixir_ls/ -.cache/ -build/ -dist/ diff --git a/aletheia/.gitlab-ci.yml b/aletheia/.gitlab-ci.yml deleted file mode 100644 index b44fb22..0000000 --- a/aletheia/.gitlab-ci.yml +++ /dev/null @@ -1,295 +0,0 @@ -# GitLab CI/CD Pipeline for Aletheia -# RSR Bronze-level compliance verification - -# Global variables -variables: - CARGO_HOME: $CI_PROJECT_DIR/.cargo - RUST_BACKTRACE: "1" - -# Cache Cargo dependencies -cache: - key: ${CI_COMMIT_REF_SLUG} - paths: - - .cargo/ - - target/ - -# Pipeline stages -stages: - - check - - test - - build - - verify - - deploy - -# Job templates -.rust_job: - image: rust:1.75 - before_script: - - rustc --version - - cargo --version - - rustup component add rustfmt clippy - -# ============================================================================ -# CHECK STAGE - Fast feedback on code quality -# ============================================================================ - -format:check: - extends: .rust_job - stage: check - script: - - cargo fmt -- --check - allow_failure: false - -clippy:check: - extends: .rust_job - stage: check - script: - - cargo clippy --all-targets -- -D warnings - allow_failure: false - -# Check that we maintain zero dependencies -dependencies:check: - extends: .rust_job - stage: check - script: - - echo "Verifying zero dependencies for RSR Bronze compliance..." - - cargo tree --depth 0 - - | - DEPS=$(cargo tree --depth 0 | grep -v "aletheia" | wc -l) - if [ "$DEPS" -ne "0" ]; then - echo "❌ ERROR: Dependencies detected! RSR Bronze requires zero dependencies." - exit 1 - fi - - echo "✅ Zero dependencies verified" - allow_failure: false - -# Check for unsafe code blocks -unsafe:check: - extends: .rust_job - stage: check - script: - - echo "Checking for unsafe code blocks..." - - | - if grep -r "unsafe" src/; then - echo "❌ ERROR: Unsafe code detected! RSR Bronze requires zero unsafe blocks." - exit 1 - fi - - echo "✅ No unsafe code found" - allow_failure: false - -# ============================================================================ -# TEST STAGE - Run all tests -# ============================================================================ - -test:unit: - extends: .rust_job - stage: test - script: - - cargo test --verbose - coverage: '/^\s*lines:\s*\d+\.\d+%/' - -test:release: - extends: .rust_job - stage: test - script: - - cargo test --release --verbose - -test:doc: - extends: .rust_job - stage: test - script: - - cargo test --doc - -# Security audit (requires Cargo.lock) -security:audit: - extends: .rust_job - stage: test - script: - - cargo install cargo-audit - - cargo audit - allow_failure: true # Don't fail on advisories for now - -# ============================================================================ -# BUILD STAGE - Build release binaries -# ============================================================================ - -build:debug: - extends: .rust_job - stage: build - script: - - cargo build --verbose - artifacts: - paths: - - target/debug/aletheia - expire_in: 1 week - -build:release: - extends: .rust_job - stage: build - script: - - cargo build --release --verbose - artifacts: - paths: - - target/release/aletheia - expire_in: 1 month - -build:linux-musl: - extends: .rust_job - stage: build - script: - - rustup target add x86_64-unknown-linux-musl - - cargo build --release --target x86_64-unknown-linux-musl - artifacts: - paths: - - target/x86_64-unknown-linux-musl/release/aletheia - expire_in: 1 month - only: - - tags - - main - -# ============================================================================ -# VERIFY STAGE - RSR compliance self-verification -# ============================================================================ - -verify:rsr-compliance: - extends: .rust_job - stage: verify - dependencies: - - build:release - script: - - echo "Running RSR self-verification..." - - cargo run --release - - | - if cargo run --release; then - echo "✅ RSR Bronze compliance verified" - else - echo "❌ RSR Bronze compliance failed" - exit 1 - fi - -verify:documentation: - image: alpine:latest - stage: verify - script: - - echo "Verifying required documentation files..." - - | - DOCS="README.md LICENSE.txt SECURITY.md CONTRIBUTING.md CODE_OF_CONDUCT.md MAINTAINERS.md CHANGELOG.md" - for doc in $DOCS; do - if [ ! -f "$doc" ]; then - echo "❌ Missing: $doc" - exit 1 - fi - echo "✅ Found: $doc" - done - - echo "Verifying .well-known directory..." - - | - WELL_KNOWN=".well-known/security.txt .well-known/ai.txt .well-known/humans.txt" - for file in $WELL_KNOWN; do - if [ ! -f "$file" ]; then - echo "❌ Missing: $file" - exit 1 - fi - echo "✅ Found: $file" - done - - echo "✅ All documentation verified" - -verify:build-system: - image: alpine:latest - stage: verify - script: - - echo "Verifying build system files..." - - | - BUILD_FILES="justfile flake.nix .gitlab-ci.yml Cargo.toml" - for file in $BUILD_FILES; do - if [ ! -f "$file" ]; then - echo "❌ Missing: $file" - exit 1 - fi - echo "✅ Found: $file" - done - - echo "✅ Build system verified" - -# ============================================================================ -# DEPLOY STAGE - Release artifacts -# ============================================================================ - -# Create GitLab release -release:gitlab: - extends: .rust_job - stage: deploy - dependencies: - - build:release - - build:linux-musl - script: - - echo "Preparing release artifacts..." - - mkdir -p release - - cp target/release/aletheia release/aletheia-x86_64-unknown-linux-gnu - - cp target/x86_64-unknown-linux-musl/release/aletheia release/aletheia-x86_64-unknown-linux-musl - - cd release && sha256sum * > SHA256SUMS - artifacts: - paths: - - release/ - expire_in: never - only: - - tags - -# Publish documentation -pages: - extends: .rust_job - stage: deploy - script: - - cargo doc --no-deps - - mv target/doc public - - echo '' > public/index.html - artifacts: - paths: - - public - only: - - main - -# ============================================================================ -# SCHEDULED JOBS - Periodic checks -# ============================================================================ - -# Weekly security audit -security:audit:scheduled: - extends: .rust_job - stage: test - script: - - cargo install cargo-audit - - cargo audit - only: - - schedules - -# ============================================================================ -# MERGE REQUEST PIPELINE - Fast feedback for MRs -# ============================================================================ - -# Fast checks for merge requests -mr:quick-check: - extends: .rust_job - stage: check - script: - - cargo fmt -- --check - - cargo clippy -- -D warnings - - cargo check - only: - - merge_requests - -# ============================================================================ -# RULES AND CONDITIONS -# ============================================================================ - -# Default pipeline runs on: -# - Pushes to any branch -# - Merge requests -# - Tags -# - Scheduled pipelines - -workflow: - rules: - - if: '$CI_PIPELINE_SOURCE == "merge_request_event"' - - if: '$CI_COMMIT_TAG' - - if: '$CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH' - - if: '$CI_PIPELINE_SOURCE == "schedule"' - - if: '$CI_COMMIT_BRANCH' diff --git a/aletheia/.machine_readable/6a2/AGENTIC.a2ml b/aletheia/.machine_readable/6a2/AGENTIC.a2ml deleted file mode 100644 index cd1fb1d..0000000 --- a/aletheia/.machine_readable/6a2/AGENTIC.a2ml +++ /dev/null @@ -1,34 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# AGENTIC.a2ml — AI agent constraints and capabilities -[metadata] -version = "0.1.0" -last-updated = "2026-04-11" - -[agent-permissions] -can-edit-source = true -can-edit-tests = true -can-edit-docs = true -can-edit-config = true -can-create-files = true - -[agent-constraints] -# What AI agents must NOT do: -# - Never use banned language patterns (believe_me, unsafeCoerce, etc.) -# - Never commit secrets or credentials -# - Never use banned languages (TypeScript, Python, Go, etc.) -# - Never place state files in repository root (must be in .machine_readable/) -# - Never use AGPL license (use MPL-2.0) - -[maintenance-integrity] -fail-closed = true -require-evidence-per-step = true -allow-silent-skip = false -require-rerun-after-fix = true -release-claim-requires-hard-pass = true - -[automation-hooks] -# on-enter: Read 0-AI-MANIFEST.a2ml, then STATE.a2ml -# on-exit: Update STATE.a2ml with session outcomes -# on-commit: Run just validate-rsr diff --git a/aletheia/.machine_readable/6a2/ECOSYSTEM.a2ml b/aletheia/.machine_readable/6a2/ECOSYSTEM.a2ml deleted file mode 100644 index 057c962..0000000 --- a/aletheia/.machine_readable/6a2/ECOSYSTEM.a2ml +++ /dev/null @@ -1,20 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# ECOSYSTEM.a2ml — Aletheia ecosystem position -[metadata] -version = "1.0" -last-updated = "2026-04-11" - -[project] -name = "Aletheia" -purpose = "" -role = "" - -[position-in-ecosystem] -category = "" - -[related-projects] -projects = [ - # No related projects recorded -] diff --git a/aletheia/.machine_readable/6a2/META.a2ml b/aletheia/.machine_readable/6a2/META.a2ml deleted file mode 100644 index 6612449..0000000 --- a/aletheia/.machine_readable/6a2/META.a2ml +++ /dev/null @@ -1,27 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# META.a2ml — Aletheia meta-level information -[metadata] -version = "0.1.0" -last-updated = "2026-04-11" - -[project-info] -license = "MPL-2.0" -author = "Jonathan D.A. Jewell (hyperpolymath)" - -[architecture-decisions] -decisions = [ - # No ADRs recorded -] - -[development-practices] -versioning = "SemVer" -documentation = "AsciiDoc" -build-tool = "just" - -[maintenance-axes] -scoping-first = true -axis-1 = "must > intend > like" -axis-2 = "corrective > adaptive > perfective" -axis-3 = "systems > compliance > effects" diff --git a/aletheia/.machine_readable/6a2/NEUROSYM.a2ml b/aletheia/.machine_readable/6a2/NEUROSYM.a2ml deleted file mode 100644 index e1d34c0..0000000 --- a/aletheia/.machine_readable/6a2/NEUROSYM.a2ml +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# NEUROSYM.a2ml — Neurosymbolic integration metadata -[metadata] -version = "0.1.0" -last-updated = "2026-04-11" - -[hypatia-config] -scan-enabled = true -scan-depth = "standard" # quick | standard | deep -report-format = "logtalk" - -[symbolic-rules] -# Custom symbolic rules for this project -# - { name = "no-unsafe-ffi", pattern = "believe_me|unsafeCoerce", severity = "critical" } - -[neural-config] -# Neural pattern detection settings -# confidence-threshold = 0.85 -# model = "hypatia-v2" diff --git a/aletheia/.machine_readable/6a2/PLAYBOOK.a2ml b/aletheia/.machine_readable/6a2/PLAYBOOK.a2ml deleted file mode 100644 index 5003fd0..0000000 --- a/aletheia/.machine_readable/6a2/PLAYBOOK.a2ml +++ /dev/null @@ -1,26 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# PLAYBOOK.a2ml — Operational playbook -[metadata] -version = "0.1.0" -last-updated = "2026-04-11" - -[deployment] -# method = "gitops" # gitops | manual | ci-triggered -# target = "container" # container | binary | library | wasm - -[incident-response] -# 1. Check .machine_readable/STATE.a2ml for current status -# 2. Review recent commits and CI results -# 3. Run `just validate` to check compliance -# 4. Run `just security` to audit for vulnerabilities - -[release-process] -# 1. Update version in STATE.a2ml, META.a2ml -# 2. Run `just release-preflight` (validate + quality + security + maint-hard-pass) -# 3. Tag and push - -[maintenance-operations] -# Baseline audit: just maint-audit -# Hard release gate: just maint-hard-pass diff --git a/aletheia/.machine_readable/6a2/STATE.a2ml b/aletheia/.machine_readable/6a2/STATE.a2ml deleted file mode 100644 index ae1d5c5..0000000 --- a/aletheia/.machine_readable/6a2/STATE.a2ml +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# STATE.a2ml — Aletheia project state -[metadata] -project = "aletheia" -version = "1.9.0" -last-updated = "2026-02-05" -status = "active" -session = "converted from scheme — 2026-04-11" - -[project-context] -name = "Aletheia" -purpose = """RSR compliance verification - truth in repository standards""" -completion-percentage = 100 - -[position] -phase = "stable" # design | implementation | testing | maintenance | archived -maturity = "experimental" # experimental | alpha | beta | production | lts - -[route-to-mvp] -milestones = [ - # No milestones recorded -] - -[blockers-and-issues] -issues = [ - # No blockers recorded -] - -[critical-next-actions] -actions = [ - "Publish v1.9.0 to crates.io", - "Plan v2.0.0 Silver-level RSR features", -] - -[maintenance-status] -last-run-utc = "2026-02-05T00:00:00Z" -last-result = "unknown" # unknown | pass | warn | fail diff --git a/aletheia/.nojekyll b/aletheia/.nojekyll deleted file mode 100644 index e69de29..0000000 diff --git a/aletheia/.rustfmt.toml b/aletheia/.rustfmt.toml deleted file mode 100644 index f6341ab..0000000 --- a/aletheia/.rustfmt.toml +++ /dev/null @@ -1,75 +0,0 @@ -# Rustfmt configuration for Aletheia -# This ensures consistent formatting across the codebase - -# Use Rust 2021 edition -edition = "2021" - -# Maximum line width -max_width = 100 - -# Use spaces for indentation -hard_tabs = false - -# Number of spaces per indentation level -tab_spaces = 4 - -# Newline style -newline_style = "Unix" - -# Use trailing commas in multi-line contexts -trailing_comma = "Vertical" - -# Put single-line function arguments on the same line -fn_single_line = false - -# Format code in doc comments -format_code_in_doc_comments = true - -# Format strings -format_strings = true - -# Import reordering -reorder_imports = true -reorder_modules = true - -# Group imports -group_imports = "StdExternalCrate" - -# Use field init shorthand -use_field_init_shorthand = true - -# Normalize doc comments -normalize_doc_attributes = true -normalize_comments = true - -# Control flow formatting -control_brace_style = "AlwaysSameLine" - -# Match arm formatting -match_block_trailing_comma = true - -# Blank lines -blank_lines_upper_bound = 2 -blank_lines_lower_bound = 0 - -# Remove trailing semicolons -remove_nested_parens = true - -# Space around operators -space_after_colon = true -space_before_colon = false -spaces_around_ranges = false - -# Function definitions -fn_args_layout = "Tall" -brace_style = "SameLineWhere" - -# Struct formatting -struct_field_align_threshold = 0 - -# Comments -comment_width = 100 -wrap_comments = true - -# Imports -imports_granularity = "Crate" diff --git a/aletheia/.well-known/ai.txt b/aletheia/.well-known/ai.txt deleted file mode 100644 index 41e14cc..0000000 --- a/aletheia/.well-known/ai.txt +++ /dev/null @@ -1,38 +0,0 @@ -# AI Training Policy for Aletheia -# Last Updated: 2025-11-22 - -# User-Agent Consent Policy -# This file indicates the project's position on AI training data usage. - -User-agent: * -# Consent: This repository is available under MIT OR AGPL-3.0-or-later licenses. -# AI training on this code requires adherence to the Palimpsest License v0.8 overlay. - -# Training Consent -Allow-training: conditional -License-required: MIT OR AGPL-3.0-or-later -Overlay: Palimpsest-0.8 - -# Attribution Requirements -Attribution: required -Attribution-url: https://github.com/hyperpolymath/maa-framework/tree/main/aletheia -Attribution-name: MAA Framework Contributors - -# Consent Framework -# Under the Palimpsest License v0.8: -# - Training is permitted with proper attribution -# - Derivative works must credit the original authors -# - Commercial use requires license compliance -# - Human creators' moral rights must be respected - -# Contact for AI-related inquiries -Contact: mailto:ai-policy@maa-framework.org - -# Opt-out for sensitive files -Disallow-training: /secrets/* -Disallow-training: /.env* -Disallow-training: /credentials/* - -# Philosophy -# Aletheia (truth) believes in transparent AI development. -# We encourage responsible AI training that respects human creators. diff --git a/aletheia/.well-known/humans.txt b/aletheia/.well-known/humans.txt deleted file mode 100644 index bec3c8d..0000000 --- a/aletheia/.well-known/humans.txt +++ /dev/null @@ -1,31 +0,0 @@ -/* TEAM */ -Project: Aletheia -Name: MAA Framework Contributors -Location: Global -Twitter: @maaframework - -/* CONTRIBUTORS */ -Role: Core Development -Location: Global -Contact: contributors@maa-framework.org - -/* THANKS */ -The Rust Community - For an amazing language -The FOSS Community - For inspiring security-first development -RFC 9116 Authors - For standardizing security.txt -All our contributors - For making Aletheia possible - -/* SITE */ -Last update: 2025-11-22 -Language: English -Standards: RFC 9116, RSR Bronze -Doctype: Rust -IDE: Any (Vim, Emacs, VS Code, Helix, etc.) - -/* PHILOSOPHY */ -Aletheia (Greek: truth, disclosure, unconcealment) -We believe in: - - Zero-dependency security - - Offline-first operations - - Complete auditability - - Truth in software diff --git a/aletheia/.well-known/security.txt b/aletheia/.well-known/security.txt deleted file mode 100644 index 56d2ed0..0000000 --- a/aletheia/.well-known/security.txt +++ /dev/null @@ -1,15 +0,0 @@ -# Aletheia Security Contact Information -# RFC 9116 Compliant (https://www.rfc-editor.org/rfc/rfc9116.html) -# Last Updated: 2026-09-21 (repointed from the dead GitLab mirror to GitHub) - -Contact: mailto:security@maa-framework.org -Contact: https://github.com/hyperpolymath/maa-framework/security/advisories/new -Expires: 2026-12-31T23:59:59.000Z -Preferred-Languages: en -Canonical: https://raw.githubusercontent.com/hyperpolymath/maa-framework/main/aletheia/.well-known/security.txt -Policy: https://github.com/hyperpolymath/maa-framework/blob/main/aletheia/SECURITY.md -Hiring: https://maa-framework.org/careers - -# Acknowledgments -# We recognize and thank security researchers who responsibly disclose vulnerabilities. -# See SECURITY.md for our Security Hall of Fame. diff --git a/aletheia/ABI-FFI-README.adoc b/aletheia/ABI-FFI-README.adoc deleted file mode 100644 index b2533a8..0000000 --- a/aletheia/ABI-FFI-README.adoc +++ /dev/null @@ -1,409 +0,0 @@ -\{\{~ Aditionally delete this line and fill out the template below ~}} - -== maa-framework ABI/FFI Documentation - -=== Overview - -This library follows the *Hyperpolymath RSR Standard* for ABI and FFI -design: - -* *ABI (Application Binary Interface)* defined in *Idris2* with formal -proofs -* *FFI (Foreign Function Interface)* implemented in *Zig* for C -compatibility -* *Generated C headers* bridge Idris2 ABI to Zig FFI -* *Any language* can call through standard C ABI - -=== Architecture - -.... -┌─────────────────────────────────────────────┐ -│ ABI Definitions (Idris2) │ -│ src/abi/ │ -│ - Types.idr (Type definitions) │ -│ - Layout.idr (Memory layout proofs) │ -│ - Foreign.idr (FFI declarations) │ -└─────────────────┬───────────────────────────┘ - │ - │ generates (at compile time) - ▼ -┌─────────────────────────────────────────────┐ -│ C Headers (auto-generated) │ -│ generated/abi/maa-framework.h │ -└─────────────────┬───────────────────────────┘ - │ - │ imported by - ▼ -┌─────────────────────────────────────────────┐ -│ FFI Implementation (Zig) │ -│ ffi/zig/src/main.zig │ -│ - Implements C-compatible functions │ -│ - Zero-cost abstractions │ -│ - Memory-safe by default │ -└─────────────────┬───────────────────────────┘ - │ - │ compiled to libmaa-framework.so/.a - ▼ -┌─────────────────────────────────────────────┐ -│ Any Language via C ABI │ -│ - Rust, ReScript, Julia, Python, etc. │ -└─────────────────────────────────────────────┘ -.... - -=== Directory Structure - -.... -maa-framework/ -├── src/ -│ ├── abi/ # ABI definitions (Idris2) -│ │ ├── Types.idr # Core type definitions with proofs -│ │ ├── Layout.idr # Memory layout verification -│ │ └── Foreign.idr # FFI function declarations -│ └── lib/ # Core library (any language) -│ -├── ffi/ -│ └── zig/ # FFI implementation (Zig) -│ ├── build.zig # Build configuration -│ ├── build.zig.zon # Dependencies -│ ├── src/ -│ │ └── main.zig # C-compatible FFI implementation -│ ├── test/ -│ │ └── integration_test.zig -│ └── include/ -│ └── maa-framework.h # C header (optional, can be generated) -│ -├── generated/ # Auto-generated files -│ └── abi/ -│ └── maa-framework.h # Generated from Idris2 ABI -│ -└── bindings/ # Language-specific wrappers (optional) - ├── rust/ - ├── rescript/ - └── julia/ -.... - -=== Why Idris2 for ABI? - -==== 1. *Formal Verification* - -Idris2’s dependent types allow proving properties about the ABI at -compile-time: - -[source,idris] ----- --- Prove struct size is correct -public export -exampleStructSize : HasSize ExampleStruct 16 - --- Prove field alignment is correct -public export -fieldAligned : Divides 8 (offsetOf ExampleStruct.field) - --- Prove ABI is platform-compatible -public export -abiCompatible : Compatible (ABI 1) (ABI 2) ----- - -==== 2. *Type Safety* - -Encode invariants that C/Zig cannot express: - -[source,idris] ----- --- Non-null pointer guaranteed at type level -data Handle : Type where - MkHandle : (ptr : Bits64) -> {auto 0 nonNull : So (ptr /= 0)} -> Handle - --- Array with length proof -data Buffer : (n : Nat) -> Type where - MkBuffer : Vect n Byte -> Buffer n ----- - -==== 3. *Platform Abstraction* - -Platform-specific types with compile-time selection: - -[source,idris] ----- -CInt : Platform -> Type -CInt Linux = Bits32 -CInt Windows = Bits32 - -CSize : Platform -> Type -CSize Linux = Bits64 -CSize Windows = Bits64 ----- - -==== 4. *Safe Evolution* - -Prove that new ABI versions are backward-compatible: - -[source,idris] ----- --- Compiler enforces compatibility -abiUpgrade : ABI 1 -> ABI 2 -abiUpgrade old = MkABI2 { - -- Must preserve all v1 fields - v1_compat = old, - -- Can add new fields - new_features = defaults -} ----- - -=== Why Zig for FFI? - -==== 1. *C ABI Compatibility* - -Zig exports C-compatible functions naturally: - -[source,zig] ----- -export fn library_function(param: i32) i32 { - return param * 2; -} ----- - -==== 2. *Memory Safety* - -Compile-time safety without runtime overhead: - -[source,zig] ----- -// Null check enforced at compile time -const handle = init() orelse return error.InitFailed; -defer free(handle); ----- - -==== 3. *Cross-Compilation* - -Built-in cross-compilation to any platform: - -[source,bash] ----- -zig build -Dtarget=x86_64-linux -zig build -Dtarget=aarch64-macos -zig build -Dtarget=x86_64-windows ----- - -==== 4. *Zero Dependencies* - -No runtime, no libc required (unless explicitly needed): - -[source,zig] ----- -// Minimal binary size -pub const lib = @import("std"); -// Only includes what you use ----- - -=== Building - -==== Build FFI Library - -[source,bash] ----- -cd ffi/zig -zig build # Build debug -zig build -Doptimize=ReleaseFast # Build optimized -zig build test # Run tests ----- - -==== Generate C Header from Idris2 ABI - -[source,bash] ----- -cd src/abi -idris2 --cg c-header Types.idr -o ../../generated/abi/maa-framework.h ----- - -==== Cross-Compile - -[source,bash] ----- -cd ffi/zig - -# Linux x86_64 -zig build -Dtarget=x86_64-linux - -# macOS ARM64 -zig build -Dtarget=aarch64-macos - -# Windows x86_64 -zig build -Dtarget=x86_64-windows ----- - -=== Usage - -==== From C - -[source,c] ----- -#include "maa-framework.h" - -int main() { - void* handle = maa-framework_init(); - if (!handle) return 1; - - int result = maa-framework_process(handle, 42); - if (result != 0) { - const char* err = maa-framework_last_error(); - fprintf(stderr, "Error: %s\n", err); - } - - maa-framework_free(handle); - return 0; -} ----- - -Compile with: - -[source,bash] ----- -gcc -o example example.c -lmaa-framework -L./zig-out/lib ----- - -==== From Idris2 - -[source,idris] ----- -import maa-framework.ABI.Foreign - -main : IO () -main = do - Just handle <- init - | Nothing => putStrLn "Failed to initialize" - - Right result <- process handle 42 - | Left err => putStrLn $ "Error: " ++ errorDescription err - - free handle - putStrLn "Success" ----- - -==== From Rust - -[source,rust] ----- -#[link(name = "maa-framework")] -extern "C" { - fn maa-framework_init() -> *mut std::ffi::c_void; - fn maa-framework_free(handle: *mut std::ffi::c_void); - fn maa-framework_process(handle: *mut std::ffi::c_void, input: u32) -> i32; -} - -fn main() { - unsafe { - let handle = maa-framework_init(); - assert!(!handle.is_null()); - - let result = maa-framework_process(handle, 42); - assert_eq!(result, 0); - - maa-framework_free(handle); - } -} ----- - -==== From Julia - -[source,julia] ----- -const libmaa-framework = "libmaa-framework" - -function init() - handle = ccall((:maa-framework_init, libmaa-framework), Ptr{Cvoid}, ()) - handle == C_NULL && error("Failed to initialize") - handle -end - -function process(handle, input) - result = ccall((:maa-framework_process, libmaa-framework), Cint, (Ptr{Cvoid}, UInt32), handle, input) - result -end - -function cleanup(handle) - ccall((:maa-framework_free, libmaa-framework), Cvoid, (Ptr{Cvoid},), handle) -end - -# Usage -handle = init() -try - result = process(handle, 42) - println("Result: $result") -finally - cleanup(handle) -end ----- - -=== Testing - -==== Unit Tests (Zig) - -[source,bash] ----- -cd ffi/zig -zig build test ----- - -==== Integration Tests - -[source,bash] ----- -cd ffi/zig -zig build test-integration ----- - -==== ABI Verification (Idris2) - -[source,idris] ----- --- Compile-time verification -%runElab verifyABI - --- Runtime checks -main : IO () -main = do - verifyLayoutsCorrect - verifyAlignmentsCorrect - putStrLn "ABI verification passed" ----- - -=== Contributing - -When modifying the ABI/FFI: - -[arabic] -. *Update ABI first* (`+src/abi/*.idr+`) -* Modify type definitions -* Update proofs -* Ensure backward compatibility -. *Generate C header* -+ -[source,bash] ----- -idris2 --cg c-header src/abi/Types.idr -o generated/abi/maa-framework.h ----- -. *Update FFI implementation* (`+ffi/zig/src/main.zig+`) -* Implement new functions -* Match ABI types exactly -. *Add tests* -* Unit tests in Zig -* Integration tests -* ABI verification tests -. *Update documentation* -* Function signatures -* Usage examples -* Migration guide (if breaking changes) - -=== License - -MPL-2.0 - -=== See Also - -* https://idris2.readthedocs.io[Idris2 Documentation] -* https://ziglang.org/documentation/master/[Zig Documentation] -* https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium -Standard Repositories] -* link:../ffi-migration-guide.md[FFI Migration Guide] -* link:../abi-migration-guide.md[ABI Migration Guide] diff --git a/aletheia/ALETHEIA-HANDOVER.adoc b/aletheia/ALETHEIA-HANDOVER.adoc deleted file mode 100644 index 86916b7..0000000 --- a/aletheia/ALETHEIA-HANDOVER.adoc +++ /dev/null @@ -1,203 +0,0 @@ -== Aletheia Project Handover - -*For*: AI assistants starting work on the Aletheia project *Updated*: -2026-02-05 - -=== Conformance Badges - -link:conformance/RSR-CONFORMANCE.md[image:https://img.shields.io/badge/RSR-Bronze-cd7f32[RSR -Bronze]] -link:conformance/PALIMPSEST-CONFORMANCE.md[image:https://img.shields.io/badge/License-Palimpsest%20v0.8-blue[Palimpsest -License]] -link:conformance/OIKOS-CONFORMANCE.md[image:https://img.shields.io/badge/Oikos-Pending-lightgrey[Oikos -Pending]] -link:conformance/ECHIDNA-CONFORMANCE.md[image:https://img.shields.io/badge/Echidna-Pending-lightgrey[Echidna -Pending]] -link:docs/VALUE-CHAIN-POLICY.md[image:https://img.shields.io/badge/Value%20Chain-Defined-green[Value -Chain]] - -=== What is Aletheia? - -*Aletheia* (ἀλήθεια - "`truth`", "`disclosure`", "`unconcealment`") is -the *precursor research project* for building a reversible operating -system based on Minix. - -==== Core Purpose - -Aletheia explores *reversible system operations* - the foundational -research required before undertaking a full rewrite of Minix into a -modern, reversible operating system (*r-Minix*). - -==== What Aletheia is NOT - -* ❌ NOT an RSR compliance checking tool (that’s -link:extraction/rhodibot/[rhodibot]) -* ❌ NOT a CI/CD pipeline generator (that’s -link:extraction/rhodium-pipeline/[rhodium-pipeline]) -* ❌ NOT just about repository standards - -==== What Aletheia IS - -* ✅ Research into reversible computing at the OS level -* ✅ Practical application of CNO (Certified Null Operation) theory -* ✅ Precursor work for r-Minix -* ✅ Connected to -https://gitlab.com/hyperpolymath/absolute-zero[Absolute Zero] formal -proofs - -=== Value Chain Position - -.... -┌────────────────────────────────────────────────────────────────┐ -│ ALETHEIA VALUE CHAIN │ -├────────────────────────────────────────────────────────────────┤ -│ │ -│ INBOUND OPERATIONS OUTBOUND │ -│ ════════ ══════════ ════════ │ -│ Absolute Zero Reversible CCCP Stack │ -│ • CNO proofs Minix research • Valence Shell │ -│ • Landauer • OS primitives • Future r-Minix │ -│ • Bennett • Undo/redo • Svalinn integration │ -│ • State capture │ -│ │ -└────────────────────────────────────────────────────────────────┘ -.... - -For the complete value chain model, see -link:docs/VALUE-CHAIN-POLICY.md[VALUE-CHAIN-POLICY.md]. - -=== Theoretical Foundation - -Aletheia builds on *Absolute Zero* - formal verification of Certified -Null Operations: - -[width="100%",cols="41%,59%",options="header",] -|=== -|Concept |Description -|*CNO* |Certified Null Operation: `+op ;; reverse(op) ≡ identity+` - -|*Landauer’s Principle* |Computation dissipates heat (kT ln 2 per bit -erased) - -|*Bennett’s Insight* |Reversible computation = zero heat dissipation - -|*Reversibility* |Every operation has an inverse -|=== - -=== Ecosystem Connections - -.... - ┌─────────────────────┐ - │ absolute-zero │ - │ (Formal Proofs) │ - └──────────┬──────────┘ - │ provides CNOs - ▼ -┌───────────────┐ ┌─────────────────────┐ ┌───────────────┐ -│ valence-shell │◀───│ ALETHEIA │───▶│ r-Minix │ -│ (Reversible │ │ │ │ (FUTURE) │ -│ Filesystem) │ │ Precursor research │ │ │ -└───────────────┘ └─────────────────────┘ └───────────────┘ -.... - -=== Project Setup - -==== Bots Present - -* *echidnabot* - Formal proof-based code validation -* *oikos bot* - Economic/ecological analysis -* *rhodibot* - RSR compliance checking - -==== AI Support Files (.scm - Guile Scheme) - -[cols=",",options="header",] -|=== -|File |Purpose -|`+META.scm+` |Project metadata -|`+ECOSYSTEM.scm+` |Ecosystem connections -|`+STATE.scm+` |Current project state -|`+PLAYBOOK.scm+` |Development workflows -|`+AGENTIC.scm+` |AI agent configuration -|`+NEUROSYM.scm+` |Neurosymbolic settings -|=== - -==== Build System - -* `+mustfile+` - Hyperpolymath build/task automation - -==== Licensing - -* *Primary*: link:LICENSE[Palimpsest License (MPL-2.0)] - -=== Quick Reference - -==== Language Policy - -[cols=",",options="header",] -|=== -|Allowed |Use Case -|Rust |Systems, performance-critical -|ReScript |Application code -|Deno |Runtime -|Gleam |Backend services -|=== - -[cols=",",options="header",] -|=== -|Banned |Use Instead -|TypeScript |ReScript -|Node.js/npm |Deno -|Go |Rust -|Python (general) |Rust/AffineScript -|=== - -==== Key Files - -[cols=",",options="header",] -|=== -|File |Purpose -|`+ALETHEIA-HANDOVER.md+` |This file - project handover -|`+CROSSREPO-HANDOVER.md+` |Full ecosystem documentation -|`+CLAUDE.md+` |AI assistant instructions -|`+docs/VALUE-CHAIN-POLICY.md+` |Value chain model -|`+conformance/+` |Conformance reports -|=== - -=== Conformance Reports - -All conformance reports are in the link:conformance/[`+conformance/+`] -folder: - -[width="100%",cols="29%,27%,44%",options="header",] -|=== -|Report |Status |Description -|link:conformance/RSR-CONFORMANCE.md[RSR-CONFORMANCE.md] |Bronze -|Repository standards - -|link:conformance/PALIMPSEST-CONFORMANCE.md[PALIMPSEST-CONFORMANCE.md] -|Active |License compliance - -|link:conformance/OIKOS-CONFORMANCE.md[OIKOS-CONFORMANCE.md] |Pending -|Economic/ecological - -|link:conformance/ECHIDNA-CONFORMANCE.md[ECHIDNA-CONFORMANCE.md] -|Pending |Formal verification -|=== - -=== Getting Started - -[arabic] -. *Read this document* to understand Aletheia’s purpose -. *Check CLAUDE.md* for development constraints -. *Review conformance/* for current compliance status -. *Start with the research* - focus on reversible OS primitives - -=== Contact - -*Jonathan D. A. Jewell* - GitLab: -https://gitlab.com/hyperpolymath[@hyperpolymath] - GitHub: -https://github.com/Hyperpolymath[@Hyperpolymath] - -''''' - -_Aletheia: Unconcealing the path to reversible operating systems._ diff --git a/aletheia/CHANGELOG.adoc b/aletheia/CHANGELOG.adoc deleted file mode 100644 index 913b4b6..0000000 --- a/aletheia/CHANGELOG.adoc +++ /dev/null @@ -1,204 +0,0 @@ -== Changelog - -All notable changes to this project will be documented in this file. - -The format is based on https://keepachangelog.com/en/1.0.0/[Keep a -Changelog], and this project adheres to -https://semver.org/spec/v2.0.0.html[Semantic Versioning]. - -=== [Unreleased] - -==== Added - -* *JSON output format*: `+--format json+` for CI/CD integration -* *Quiet mode*: `+-q+` / `+--quiet+` - outputs only PASS/FAIL -* *Verbose mode*: `+-v+` / `+--verbose+` - detailed output with -explanations -* *Distinct exit codes*: 0=success, 1=compliance failed, 2=security -warning, 3=invalid path, 4=invalid args -* *GitHub Actions workflow*: `+.github/workflows/aletheia.yml+` template -for GitHub users -* *Performance benchmarks*: -`+cargo run --release --bin verification_benchmark+` -* *Help text*: `+--help+` with usage, options, exit codes, and examples -* *Version flag*: `+--version+` displays version information -* *Security warning system*: Three-level warning system (Info, Warning, -Critical) -* *Symlink detection*: Detects symlinks and warns if they escape -repository bounds -* *Verification timestamps*: ISO 8601 UTC timestamp in output (TOCTOU -mitigation) -* *README.adoc support*: Accepts AsciiDoc README as alternative to -Markdown -* *18 integration tests*: Comprehensive test coverage for all CLI -features -* *ROADMAP.md*: Comprehensive roadmap from MVP to v10.0.0 -* *PRIORITIES.md*: MoSCoW prioritization document - -==== Changed - -* Consistent 16-check count regardless of .well-known directory -existence -* Critical symlink warnings now cause verification failure -* Updated SECURITY.md with accurate threat model -* Updated MAINTAINERS.md with actual maintainer information -* Codebase expanded from ~300 lines to ~810 lines (still zero -dependencies) - -==== Security - -* *Security Audit*: Conducted 2025-12-26, zero vulnerabilities found -* Removed false "`large files`" limitation from SECURITY.md (we don’t -read file contents) -* Added symlink escape detection to prevent directory traversal -* Exit code 2 reserved for security warnings - -==== Fixed - -* Self-verification now passes (was 76.9%, now 100%) -* Integration tests updated to match actual check count -* Removed unused code warnings - -=== [0.1.0] - 2025-11-22 - -==== Added - -* *Initial release* of Aletheia RSR compliance verification tool -* *Core verification engine* for RSR Bronze-level compliance -* *Documentation checks*: README.md, LICENSE.txt, SECURITY.md, -CONTRIBUTING.md, CODE_OF_CONDUCT.md, MAINTAINERS.md, CHANGELOG.md -* *Well-known directory checks*: `+.well-known/security.txt+`, -`+.well-known/ai.txt+`, `+.well-known/humans.txt+` -* *Build system checks*: Justfile, flake.nix, .gitlab-ci.yml -* *Source structure checks*: src/ directory, tests/ directory -* *Comprehensive test suite*: 5 unit tests with 100% pass rate -* *Zero dependencies*: Only uses Rust standard library -* *Offline-first*: No network calls, works completely air-gapped -* *Type safety*: Full Rust compile-time guarantees, zero unsafe blocks -* *Memory safety*: Rust ownership model, no manual memory management -* *Complete documentation*: -** README.md with quick start guide -** SECURITY.md with vulnerability disclosure policy -** CONTRIBUTING.md with contribution guidelines -** CODE_OF_CONDUCT.md with community standards -** MAINTAINERS.md with governance structure -** CHANGELOG.md (this file) -* *.well-known directory*: -** security.txt (RFC 9116 compliant) -** ai.txt (AI training policies) -** humans.txt (human attribution) -* *Build automation*: -** Justfile with 20+ recipes -** flake.nix for Nix reproducible builds -** .gitlab-ci.yml for CI/CD pipeline -* *Dual licensing*: MIT + Palimpsest v0.8 -* *TPCF Perimeter 3*: Community Sandbox - fully open contribution -* *RSR self-verification*: Aletheia verifies its own RSR compliance - -==== Design Decisions - -* *Single-file implementation*: All code in `+src/main.rs+` for easy -auditing (~300 lines) -* *Zero unsafe code*: No `+unsafe+` blocks anywhere in the codebase -* *Explicit error handling*: All errors handled with `+Result+` and -`+Option+` -* *Minimal attack surface*: No dependencies = no supply chain -vulnerabilities -* *Clear output*: Human-readable compliance report with emoji indicators - -==== Architecture - -.... -aletheia/ -├── src/ -│ └── main.rs # Single-file implementation -├── tests/ # Integration tests (future) -├── .well-known/ # Security and metadata -│ ├── security.txt # RFC 9116 security contact -│ ├── ai.txt # AI training policies -│ └── humans.txt # Human attribution -├── Cargo.toml # Zero dependencies -├── Justfile # Build automation -├── flake.nix # Nix reproducible builds -├── .gitlab-ci.yml # CI/CD pipeline -└── docs/ # Documentation -.... - -==== Known Limitations - -* *Bronze-level only*: Only checks Bronze-level compliance -(Silver/Gold/Platinum planned) -* *No custom checks*: Cannot define custom verification rules (planned) -* *Single repository*: Cannot batch-analyze multiple repositories -(planned) -* *No configuration file*: Settings must be passed as CLI arguments -(planned) - -=== Version History - -==== Version Numbering - -We follow https://semver.org/[Semantic Versioning]: - -* *MAJOR*: Incompatible API changes -* *MINOR*: Backwards-compatible functionality additions -* *PATCH*: Backwards-compatible bug fixes - -==== Release Cadence - -* *Patch releases*: As needed for bug fixes -* *Minor releases*: Monthly (if features are ready) -* *Major releases*: When breaking changes are necessary - -=== Migration Guides - -==== From Pre-1.0 to 1.0 - -_Not applicable - this is the initial release_ - -=== Security Advisories - -Security issues are tracked separately. See SECURITY.md for the -vulnerability disclosure process. - -==== Security Fixes - -_None yet - this is the initial release_ - -=== Deprecation Notices - -_None yet - this is the initial release_ - -=== Contributors - -Thank you to all contributors who made this release possible! - -* Initial design and implementation by MAA Framework team - -=== [Definition of Done] - -For a release to be considered complete, it must: - -[arabic] -. ✅ Pass all tests (`+cargo test+`) -. ✅ Pass all lints (`+cargo clippy+`) -. ✅ Be formatted (`+cargo fmt+`) -. ✅ Self-verify RSR compliance (`+cargo run+`) -. ✅ Update CHANGELOG.md -. ✅ Update version in Cargo.toml -. ✅ Tag release in Git -. ✅ Build release binary (`+cargo build --release+`) - -=== Links - -* *Repository*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia -* *Issues*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues -* *Merge Requests*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/merge_requests - -''''' - -*Maintained by*: MAA Framework *Contact*: maintainers@maa-framework.org -*License*: MIT OR Palimpsest-0.8 diff --git a/aletheia/CLAUDE.md b/aletheia/CLAUDE.md deleted file mode 100644 index c82f65d..0000000 --- a/aletheia/CLAUDE.md +++ /dev/null @@ -1,421 +0,0 @@ - -# Claude Development Documentation - -This document provides guidance for Claude (AI assistant) when working on the Aletheia project. - -## Project Overview - -**Aletheia** (ἀλήθεια - "truth", "disclosure", "unconcealment") is an RSR (Rhodium Standard Repository) compliance verification tool written in Rust with zero dependencies. - -### Core Purpose -- Verify repositories against RSR Bronze-level standards -- Promote security, documentation, and operational excellence -- Serve as a reference implementation of RSR principles - -## Critical Constraints - -### 🚫 NEVER Add Dependencies - -Aletheia maintains **zero dependencies** for RSR Bronze-level compliance. This is non-negotiable. - -**DO NOT**: -- Add crates to `Cargo.toml` `[dependencies]` -- Add dev-dependencies (except for testing tools if absolutely necessary) -- Import external libraries -- Use `extern crate` for third-party crates - -**DO**: -- Use Rust standard library (`std`) exclusively -- Implement functionality from scratch if needed -- Prefer simple, auditable code over complex abstractions - -### 🚫 NEVER Use Unsafe Code - -Aletheia maintains **zero unsafe blocks** for RSR compliance. - -**DO NOT**: -- Use `unsafe` keyword -- Use `#[unsafe(...)]` attributes -- Call FFI functions -- Use raw pointers in unsafe context - -**DO**: -- Use safe Rust abstractions -- Leverage Rust's type system for safety -- Use `Option` and `Result` for error handling - -## Architecture Principles - -### Module Layout (updated 2026-09-21 — re-measured after the CLI rebuild) - -> **This file used to say "all core logic lives in `src/main.rs` (~950 lines)" and -> "don't split into modules unless >1000 lines". Both were out of date.** The crate has -> been split for some time. Measured 2026-09-21 (`wc -l`): - -| File | Lines | Contents | -|---|---|---| -| `src/main.rs` | 422 | CLI entry, arg parsing, init-hook installer, exit policy | -| `src/checks.rs` | 1932 | 26-check inventory, `Scanner` walks, symlink sweep, pure predicates | -| `src/config.rs` | 538 | `.aletheia.toml` (level / checks / ignore), hand-rolled TOML | -| `src/output.rs` | 626 | human / JSON / SARIF / HTML / badge / quiet / verbose, exit codes | -| `src/types.rs` | 246 | `ComplianceLevel`, `CheckResult`, `ComplianceReport`, scoring | -| **total src** | **3764** | (+ 1236 lines in `tests/integration_tests.rs`) | - -The single-file rationale still applies *in spirit* — prefer few, auditable files over -deep abstraction — but do not "restore" the single-file layout, and do not treat 1000 -lines as a threshold that has not yet been crossed. - -**When to add more files**: -- Integration tests in `tests/` directory -- Examples in `examples/` directory -- Documentation in `docs/` directory - -**When NOT to add files**: -- Don't create abstractions prematurely -- Don't add utility files for one-off functions - -### Resolved 2026-09-21: the CLI rebuild (was: issues #124 / #125) - -The CLI now implements the RSR v2 offline file-presence subset: 26 checks -(13 Bronze, 12 Silver, 1 Gold) across `src/{types,config,checks,output,main}.rs`, -TOML config, and human/JSON/SARIF/HTML/badge/quiet/verbose output with exit -codes 0–4. **66 unit + 45 integration tests pass; clippy `-D warnings` is a -blocking gate** (`rust-ci.yml` + `just lint`). - -Two lessons from the rebuild, still binding: - -1. **The integration tests assert on stdout substrings** — a UI contract, not a - specification. Every check cites its upstream criterion (see `SSOT_PROVENANCE` - in `src/checks.rs`); never write a check to match a string. -2. **Hypatia's `rsr-conformance` oracle is normative.** Aletheia evaluates only - the offline subset and labels itself non-normative. Do not grow a second, - divergent definition of RSR here. - -The #125 findings were wired into real code, not silenced. **Do not silence -future ones with `#![allow(dead_code)]`** — the root Rust CI header forbids it. - -### Type Safety First - -Leverage Rust's type system: - -```rust -// GOOD: Use strong types -enum ComplianceLevel { - Bronze, - Silver, - Gold, - Platinum, -} - -// BAD: Use strings for enumerable values -let level = "bronze"; // Avoid this -``` - -### Explicit Error Handling - -```rust -// GOOD: Return Result, handle errors explicitly -fn check_file(path: &Path) -> Result { - let exists = path.exists(); - Ok(exists) -} - -// BAD: Unwrap or panic -fn check_file(path: &Path) -> bool { - path.exists().unwrap() // Never do this -} -``` - -### Offline-First - -**DO NOT**: -- Make network requests -- Access external APIs -- Download files -- Phone home for telemetry - -**DO**: -- Work entirely from local filesystem -- Be completely air-gapped compatible -- Function without internet access - -## Development Workflow - -### Making Changes - -1. **Read existing code first** - ```bash - # Understand the current implementation - cat src/main.rs - ``` - -2. **Write tests for new functionality** - ```rust - #[test] - fn test_new_feature() { - // Test code here - } - ``` - -3. **Implement the feature** - - Keep it simple - - Follow existing patterns - - Maintain zero dependencies - -4. **Run checks** - ```bash - cargo fmt # Format code - cargo clippy # Lint - cargo test # Run tests - cargo run # Self-verify RSR compliance - ``` - -5. **Update documentation** - - Update README.md if user-facing - - Update CHANGELOG.md - - Add doc comments for public APIs - -### Code Style - -**Follow Rust conventions**: -- Use `snake_case` for functions and variables -- Use `CamelCase` for types and enums -- Use `SCREAMING_SNAKE_CASE` for constants -- Max line length: 100 characters -- Use `cargo fmt` for formatting - -**Documentation**: -```rust -/// Check if a file exists at the given path. -/// -/// # Arguments -/// -/// * `base` - Base directory path -/// * `filename` - Name of file to check -/// -/// # Returns -/// -/// `true` if file exists, `false` otherwise -fn file_exists(base: &Path, filename: &str) -> bool { - base.join(filename).is_file() -} -``` - -### Testing Strategy - -**Unit tests**: Test individual functions -```rust -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_file_exists() { - // Test implementation - } -} -``` - -**Integration tests**: Test complete workflows -```rust -// tests/integration_test.rs -#[test] -fn test_rsr_verification_workflow() { - // Test complete verification process -} -``` - -**Manual testing**: Run on real repositories -```bash -cargo run -- /path/to/test/repository -``` - -## Common Tasks - -### Adding a New Compliance Check - -1. **Add check function**: - ```rust - fn check_new_requirement(report: &mut ComplianceReport, repo_path: &Path) { - let passes = /* check logic */; - report.add_check( - "Category", - "Requirement Name", - passes, - ComplianceLevel::Bronze, - ); - } - ``` - -2. **Call from `verify_repository()`**: - ```rust - fn verify_repository(repo_path: &Path) -> ComplianceReport { - let mut report = ComplianceReport::new(repo_path.to_path_buf()); - check_documentation(&mut report, repo_path); - check_new_requirement(&mut report, repo_path); // Add this - report - } - ``` - -3. **Add tests**: - ```rust - #[test] - fn test_new_requirement_check() { - // Test the new check - } - ``` - -### Updating RSR Standards - -When RSR standards change: - -1. Update checks in `src/main.rs` -2. Update documentation in `README.md` -3. Update `CHANGELOG.md` -4. Run self-verification: `cargo run` - -### Releasing New Version - -1. Update version in `Cargo.toml` -2. Update `CHANGELOG.md` -3. Run full checks: `just check` -4. Tag release: `git tag -a v0.x.0 -m "Release v0.x.0"` -5. Push: `git push && git push --tags` - -## RSR Compliance Checklist - -When making changes, ensure these remain true: - -- [ ] ✅ Zero dependencies (`cargo tree --depth 0`) -- [ ] ✅ No unsafe code (`! rg "unsafe" src/`) -- [ ] ✅ Tests pass (`cargo test`) -- [ ] ✅ Clippy clean (`cargo clippy -- -D warnings`) -- [ ] ✅ Formatted (`cargo fmt --check`) -- [ ] ✅ Self-verification passes (`cargo run`) -- [ ] ✅ Documentation updated -- [ ] ✅ CHANGELOG.md updated - -## File Structure Reference - -``` -aletheia/ -├── src/ # 5 modules, 995 lines total — see Module Layout above -│ ├── main.rs # CLI entry (121) -│ ├── checks.rs # compliance checks (316) -│ ├── config.rs # .aletheia.toml (243) -│ ├── output.rs # human/JSON/SARIF (226) -│ └── types.rs # core types (89) -├── tests/ -│ └── integration_tests.rs # 45 tests, all passing (#124 closed 2026-09-21) -├── benches/ # Performance benchmarks -├── examples/ # Usage examples -├── fuzz/ # Fuzzing infrastructure -├── .well-known/ -│ ├── security.txt # RFC 9116 security contact -│ ├── ai.txt # AI training policies -│ └── humans.txt # Human attribution -├── .github/workflows/ # 16 files — ⚠ ALL INERT, see below -├── Cargo.toml # Zero dependencies, MSRV 1.80 -├── Cargo.lock # Lock file (commit this) -├── Justfile # Build automation -├── .gitlab-ci.yml # CI/CD pipeline (GitLab mirror) -├── .gitignore # Git ignore patterns -├── README.adoc # User documentation (AsciiDoc) -├── SECURITY.md # Security policy -├── CONTRIBUTING.md # Contribution guidelines -├── CODE_OF_CONDUCT.md # Community standards -├── MAINTAINERS.md # Governance -├── CHANGELOG.md # Version history -├── CLAUDE.md # This file -├── LICENSE # Palimpsest License (MPL-2.0) -├── STATE.scm # Current project state -├── ECOSYSTEM.scm # Ecosystem connections -└── META.scm # Project metadata and ADRs -``` - -### ⚠ The 16 workflows in `aletheia/.github/workflows/` have NEVER run - -`aletheia/` is **vendored into `maa-framework` as plain tracked files** (mode 100644), -not a submodule, and GitHub Actions reads `.github/workflows/` **at the repository root -only**. There is no standalone `hyperpolymath/aletheia` repo running them either — it was -deleted around January 2026 and its content vendored here. - -Consequence: editing anything under `aletheia/.github/workflows/` has **no effect on -CI whatsoever**. This is not hypothetical — it is how commit `b5322c2` (2026-06-17) left -this crate **failing to compile for over a month** with nobody noticing. - -**The real gate is `/.github/workflows/rust-ci.yml` at the repository root.** It runs -`cargo build` (debug + release), `cargo test`, `cargo fmt --check` and a zero-dependency -assertion, with `working-directory: aletheia`. Add gates there, not here. See -`aletheia/.github/workflows/README.md`. - -## Troubleshooting - -### "Dependency detected" error -- Check `Cargo.toml` - should have no `[dependencies]` section with crates -- Run `cargo tree --depth 0` to verify - -### "Unsafe code detected" error -- Search for `unsafe` keyword: `rg "unsafe" src/` -- Remove all unsafe blocks - -### Tests failing -- Run with verbose output: `cargo test -- --nocapture` -- Check test logic and assertions -- Ensure tests are deterministic - -### RSR self-verification fails -- Run `cargo run` to see which checks fail -- Fix missing files or requirements -- Ensure all documentation is present - -## Best Practices for AI Assistants - -1. **Read before writing**: Always read existing code before making changes -2. **Maintain constraints**: Never add dependencies or unsafe code -3. **Test everything**: Write tests for new functionality -4. **Document changes**: Update docs and CHANGELOG.md -5. **Follow conventions**: Use existing patterns and style -6. **Keep it simple**: Prefer simple, clear code over clever abstractions -7. **Self-verify**: Run `cargo run` to verify RSR compliance - -## Philosophical Notes - -### Why Zero Dependencies? - -1. **Security**: No supply chain attacks -2. **Audibility**: Easy to review entire codebase -3. **Reliability**: No dependency breakage -4. **Simplicity**: Fewer moving parts -5. **Trust**: Users can verify everything - -### Why No Unsafe Code? - -1. **Safety**: Rust's guarantees apply everywhere -2. **Trust**: No hidden memory bugs -3. **Simplicity**: No manual memory management -4. **Audibility**: No special cases to review - -### Why Offline-First? - -1. **Privacy**: Cannot exfiltrate data -2. **Reliability**: Works without internet -3. **Speed**: No network latency -4. **Trust**: Users control all inputs - -## Contact - -For questions about this document or Aletheia development: - -- **GitHub**: https://github.com/hyperpolymath/aletheia -- **Author**: Jonathan D.A. Jewell - ---- - -**Last Updated**: 2026-09-21 -**Version**: 1.2 - -*"Alētheia is not just absence of falsehood, but active unconcealment of truth."* diff --git a/aletheia/CODE_OF_CONDUCT.adoc b/aletheia/CODE_OF_CONDUCT.adoc deleted file mode 100644 index 48b237a..0000000 --- a/aletheia/CODE_OF_CONDUCT.adoc +++ /dev/null @@ -1,204 +0,0 @@ -== Code of Conduct - -=== 🤝 Our Pledge - -We as members, contributors, and leaders pledge to make participation in -our community a harassment-free experience for everyone, regardless of -age, body size, visible or invisible disability, ethnicity, sex -characteristics, gender identity and expression, level of experience, -education, socio-economic status, nationality, personal appearance, -race, caste, color, religion, or sexual identity and orientation. - -We pledge to act and interact in ways that contribute to an open, -welcoming, diverse, inclusive, and healthy community. - -=== 🌟 Our Standards - -==== Positive Behavior - -Examples of behavior that contributes to a positive environment: - -* *Empathy and kindness* toward other people -* *Respect* for differing opinions, viewpoints, and experiences -* *Constructive feedback*, given and received gracefully -* *Accountability* for mistakes and learning from them -* *Focus* on what is best for the community -* *Collaboration* over competition - -==== Unacceptable Behavior - -Examples of unacceptable behavior include: - -* *Harassment*: Trolling, insulting/derogatory comments, personal or -political attacks -* *Privacy violations*: Publishing others’ private information without -explicit permission -* *Sexual attention*: Unwelcome sexual attention or advances -* *Professional misconduct*: Conduct inappropriate in a professional -setting -* *Dishonesty*: Plagiarism, misrepresentation, or intentional -misinformation - -=== 🛡️ Enforcement Responsibilities - -Community leaders are responsible for clarifying and enforcing our -standards of acceptable behavior and will take appropriate and fair -corrective action in response to any behavior that they deem -inappropriate, threatening, offensive, or harmful. - -Community leaders have the right and responsibility to remove, edit, or -reject comments, commits, code, wiki edits, issues, and other -contributions that are not aligned with this Code of Conduct, and will -communicate reasons for moderation decisions when appropriate. - -=== 🌍 Scope - -This Code of Conduct applies within all community spaces, and also -applies when an individual is officially representing the community in -public spaces. Examples of representing our community include: - -* Using an official project email address -* Posting via an official social media account -* Acting as an appointed representative at an online or offline event -* Participating in project-related discussions - -=== 📋 Enforcement - -==== Reporting - -Instances of abusive, harassing, or otherwise unacceptable behavior may -be reported to the community leaders responsible for enforcement at: - -* *Email*: conduct@maa-framework.org -* *GitLab*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues/new?issue%5Bconfidential%5D=true[Confidential -Issue] - -All complaints will be reviewed and investigated promptly and fairly. - -==== Confidentiality - -All community leaders are obligated to respect the privacy and security -of the reporter of any incident. - -==== Enforcement Guidelines - -Community leaders will follow these Community Impact Guidelines in -determining the consequences for any action they deem in violation of -this Code of Conduct: - -===== 1. Correction - -*Community Impact*: Use of inappropriate language or other behavior -deemed unprofessional or unwelcome. - -*Consequence*: A private, written warning from community leaders, -providing clarity around the nature of the violation and an explanation -of why the behavior was inappropriate. A public apology may be -requested. - -===== 2. Warning - -*Community Impact*: A violation through a single incident or series of -actions. - -*Consequence*: A warning with consequences for continued behavior. No -interaction with the people involved, including unsolicited interaction -with those enforcing the Code of Conduct, for a specified period of -time. This includes avoiding interactions in community spaces as well as -external channels like social media. Violating these terms may lead to a -temporary or permanent ban. - -===== 3. Temporary Ban - -*Community Impact*: A serious violation of community standards, -including sustained inappropriate behavior. - -*Consequence*: A temporary ban from any sort of interaction or public -communication with the community for a specified period of time. No -public or private interaction with the people involved, including -unsolicited interaction with those enforcing the Code of Conduct, is -allowed during this period. Violating these terms may lead to a -permanent ban. - -===== 4. Permanent Ban - -*Community Impact*: Demonstrating a pattern of violation of community -standards, including sustained inappropriate behavior, harassment of an -individual, or aggression toward or disparagement of classes of -individuals. - -*Consequence*: A permanent ban from any sort of public interaction -within the community. - -=== 💚 Emotional Safety Framework - -In addition to standard conduct guidelines, we recognize the importance -of *emotional safety* in open source: - -==== Psychological Safety - -* *Safe to experiment*: Contributors can try new ideas without fear of -humiliation -* *Safe to fail*: Mistakes are learning opportunities, not grounds for -punishment -* *Safe to dissent*: Disagreement is encouraged when done respectfully -* *Safe to be yourself*: Authentic expression is welcomed within -professional boundaries - -==== Reversibility Culture - -We embrace a culture where: - -* *Experiments are encouraged*: Git makes everything reversible -* *Early feedback is valued*: Share work-in-progress for collaborative -improvement -* *Iterations are normal*: First drafts are rarely perfect -* *Anxiety is reduced*: Knowing changes can be reverted reduces fear of -contribution - -==== Emotional Temperature Monitoring - -We encourage contributors to: - -* *Take breaks*: Step away when frustrated or overwhelmed -* *Ask for help*: Request support when stuck or uncertain -* *Set boundaries*: Decline work that exceeds capacity -* *Practice self-care*: Prioritize wellbeing over deadlines - -=== 🎯 TPCF Alignment - -This Code of Conduct aligns with the *Tri-Perimeter Contribution -Framework (TPCF)*: - -* *Perimeter 3 (Community Sandbox)*: Open contribution with quality -standards -* *Graduated Trust*: Build trust through consistent positive -contributions -* *Clear Boundaries*: Explicit guidelines for each perimeter level - -=== 📚 Attribution - -This Code of Conduct is adapted from the -https://www.contributor-covenant.org/[Contributor Covenant], version -2.1, with additions from the -https://gitlab.com/maa-framework[Comprehensive Contributor Code of -Practice (CCCP)] emphasizing emotional safety and psychological -wellbeing. - -=== 🔄 Updates - -This Code of Conduct may be updated periodically. Major changes will be -announced via: - -* GitLab announcements -* CHANGELOG.md entries -* Email to active contributors - -*Current Version*: 1.0 *Last Updated*: 2025-11-22 *Contact*: -conduct@maa-framework.org - -''''' - -_"`Be kind, for everyone you meet is fighting a hard battle.`" - Ian -Maclaren_ diff --git a/aletheia/CONTRIBUTING.adoc b/aletheia/CONTRIBUTING.adoc deleted file mode 100644 index a2ccc83..0000000 --- a/aletheia/CONTRIBUTING.adoc +++ /dev/null @@ -1,60 +0,0 @@ -== Contributing to Aletheia - -Thank you for your interest in contributing to Aletheia! - -=== Getting Started - -[arabic] -. Fork the repository on GitHub -. Clone your fork locally -. Create a feature branch from `+main+` -. Set up your development environment (see below) - -=== Development Setup - -Aletheia requires only the Rust toolchain. No external dependencies. - -[source,bash] ----- -# Clone and build -git clone https://github.com/hyperpolymath/aletheia.git -cd aletheia -cargo build -cargo test ----- - -=== How to Contribute - -==== Reporting Issues - -Open an issue on GitHub with a clear description of the problem or -suggestion. - -==== Submitting Changes - -[arabic] -. Create a feature branch: `+git checkout -b feat/my-feature+` -. Make your changes following the code style below -. Run `+cargo test+` and `+cargo clippy -- -D warnings+` -. Sign off your commits: `+git commit -s+` -. Submit a pull request against `+main+` - -=== Pull Request Process - -* Keep PRs focused and atomic -* Include tests for new functionality -* Ensure all existing tests pass -* Follow conventional commit format: `+type(scope): description+` -* All PRs require review before merge - -=== Code Style - -* Zero external dependencies (use std library only) -* Zero unsafe code -* Run `+cargo fmt+` before committing -* All public items must have doc comments - -=== License - -Contributions are licensed under MPL-2.0. See ../.github/CONTRIBUTING.md for full -details. diff --git a/aletheia/CROSSREPO-HANDOVER.adoc b/aletheia/CROSSREPO-HANDOVER.adoc deleted file mode 100644 index 8320c38..0000000 --- a/aletheia/CROSSREPO-HANDOVER.adoc +++ /dev/null @@ -1,440 +0,0 @@ -== Cross-Repository Handover Document - -*For*: Cross-repo Claude sessions managing the Hyperpolymath ecosystem -*Date*: 2026-02-05 *Author*: Generated during aletheia code review -session - -=== Overview - -This document provides context for AI assistants working across the -Hyperpolymath repository ecosystem. The ecosystem is designed so that -new projects start perfectly configured and maintain quality throughout -their lifecycle. - -=== The Vision - -____ -"`Every project should leave the user with a perfect repo that has -everything and avoids anything problematic, so that the project itself -is just fantastic. All of this should happen in the background.`" -____ - -=== Two Input Systems - -Every Hyperpolymath project receives inputs from two complementary -systems: - -==== RSR - Rhodium Standard Repositories - -*What*: Repository organization and compliance standards *Handles*: -Documentation, security.txt, CI/CD, build systems, project structure -*Tools*: rhodium-standard-repositories, rsr-template-repo, rhodibot, -rhodium-pipeline - -==== CCCP - Campaign for Cooling Coding and Programming - -*What*: Technology stack and code standards *Handles*: Language choices, -containers, integrations, efficient code practices *Tools*: -cccp-portfolio, svalinn (containers), corre-terro (images), scaffoldia - -*Core Infrastructure (almost always present):* | Tool | Purpose | -|——|———| | *Cerro Torre* | Provenance-verified container base images -(replaces Alpine/Wolfi) | | *Svalinn* | Edge shield (ReScript/Deno) + -Vörðr OCI runtime | | *Valence Shell* | Reversible shell scripting | | -*Echidna/echidnabot* | Formal proof-based code validation | - -*Application Layer (as needed):* | Tool | Purpose | |——|———| | -*rescript-tea* | The Elm Architecture for ReScript | | *cadre-router* | -Typed HTTP routing with CRDTs | | *casket-ssg* | Static site generator | -| **poly-*-mcp** | MCP tools (ssg, isc, container, etc.) | - -*Bot Pattern (from oikos):* Bots operate in multiple modes: consultant, -advisor, regulator, policy developer. They are *self-referential* - they -validate their own code. Polyglot: specialized languages for each task. - -*The Connection to Thermodynamics*: - Landauer’s Principle: Computation -dissipates heat (kT ln 2 per bit erased) - Reversible computing: Zero -heat dissipation (CNOs from Absolute Zero) - CCCP "`Cooling`": -Efficient, low-energy, well-structured code - -.... -┌─────────────────────────────────────────────────────────────────────────────┐ -│ ANY PROJECT │ -└─────────────────────────────────────────────────────────────────────────────┘ - ▲ ▲ - │ │ - ┌───────────┴───────────┐ ┌───────────┴───────────┐ - │ RSR │ │ CCCP │ - │ (Repository Layer) │ │ (Code/Tech Layer) │ - │ │ │ │ - │ • How repo organized │ │ • What code goes in │ - │ • Docs, CI/CD, badges │ │ • Languages, patterns │ - │ • Compliance checking │ │ • Containers, images │ - └───────────────────────┘ └───────────────────────┘ -.... - -=== Ecosystem Architecture - -.... -┌─────────────────────────────────────────────────────────────────────────────┐ -│ STANDARDS & TEMPLATES │ -│ │ -│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ -│ │ rhodium-standard-repositories│ │ rsr-template-repo │ │ -│ │ │ │ │ │ -│ │ The RSR Specification │───▶│ Template for new repos │ │ -│ │ Bronze/Silver/Gold/Platinum│ │ Scaffolding & structure │ │ -│ └─────────────────────────────┘ └──────────────┬──────────────┘ │ -└────────────────────────────────────────────────────┼────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────────┐ -│ CUSTOMIZATION LAYER │ -│ │ -│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ -│ │ repo-customiser │ │ slm-repo-automaton │ │ -│ │ │ │ robot-repo-automaton │ │ -│ │ C4 Control Point │◀──▶│ │ │ -│ │ Works with ANY .scm std │ │ Automation agents │ │ -│ └─────────────────────────────┘ └─────────────────────────────┘ │ -└────────────────────────────────────────────────────┬────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────────┐ -│ COMPLIANCE & CI/CD │ -│ │ -│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ -│ │ rhodibot │ │ rhodium-pipeline │ │ -│ │ │ │ │ │ -│ │ Compliance bot/advisor │◀──▶│ CI/CD generator │ │ -│ │ Consultant/Regulator │ │ Pipeline templates │ │ -│ └─────────────────────────────┘ └─────────────────────────────┘ │ -└────────────────────────────────────────────────────┬────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────────────────────┐ -│ VERIFICATION & VALIDATION │ -│ │ -│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ -│ │ oikos │ │ echidnabot │ │ -│ │ │ │ │ │ -│ │ Economic/Ecological eval │ │ Formal proof verification │ │ -│ │ Sustainability metrics │ │ Code validation │ │ -│ └─────────────────────────────┘ └─────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────────┘ - -┌─────────────────────────────────────────────────────────────────────────────┐ -│ PRESENTATION LAYER │ -│ │ -│ ┌─────────────────────────────┐ ┌─────────────────────────────┐ │ -│ │ *-ssg repos │ │ poly-ssg-mcp │ │ -│ │ │ │ │ │ -│ │ Static site generators │◀──▶│ MCP tool for SSG selection │ │ -│ │ Various frameworks │ │ Unified interface │ │ -│ └─────────────────────────────┘ └─────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────────┘ - -┌─────────────────────────────────────────────────────────────────────────────┐ -│ THEORETICAL FOUNDATIONS │ -│ │ -│ ┌─────────────────────────────┐ │ -│ │ absolute-zero │ │ -│ │ │ │ -│ │ Formal CNO verification │ │ -│ │ Coq/Lean/Z3/Agda/Isabelle │ │ -│ └──────────────┬──────────────┘ │ -│ │ │ -│ ┌─────────┴─────────┐ │ -│ ▼ ▼ │ -│ ┌────────────┐ ┌─────────────┐ ┌─────────────────────────┐ │ -│ │valence-shell│ │ aletheia │ │ r-Minix │ │ -│ │ │ │ │ │ (FUTURE) │ │ -│ │ Reversible │ │ Precursor │───▶│ │ │ -│ │ filesystem │ │ to r-Minix │ │ Full reversible Minix │ │ -│ └────────────┘ └─────────────┘ └─────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────────────┘ -.... - -=== Repository Descriptions - -==== Standards Layer - -[width="100%",cols="42%,31%,27%",options="header",] -|=== -|Repository |Purpose |Status -|`+rhodium-standard-repositories+` |RSR specification -(Bronze/Silver/Gold/Platinum) |Active - -|`+rsr-template-repo+` |Template for creating RSR-compliant repos -|Active -|=== - -==== Customization Layer - -[width="100%",cols="42%,31%,27%",options="header",] -|=== -|Repository |Purpose |Status -|`+repo-customiser+` |C4 control point for ANY .scm standard |Active -|`+slm-repo-automaton+` |Small Language Model automation |Check status -|`+robot-repo-automaton+` |Robot/automation agent |Check status -|=== - -==== Compliance Layer - -[width="100%",cols="42%,31%,27%",options="header",] -|=== -|Repository |Purpose |Status -|`+rhodibot+` |RSR compliance bot (like Dependabot for standards) -|Extraction in `+/aletheia/extraction/rhodibot/+` - -|`+rhodium-pipeline+` |CI/CD pipeline generator |Extraction in -`+/aletheia/extraction/rhodium-pipeline/+` -|=== - -==== Verification Layer - -[width="100%",cols="42%,31%,27%",options="header",] -|=== -|Repository |Purpose |Status -|`+oikos+` |Economic/ecological evaluation |Check status - -|`+echidnabot+` |Formal proof verification (Echidna integration) |Check -status -|=== - -==== Presentation Layer - -[cols=",,",options="header",] -|=== -|Repository |Purpose |Status -|`+*-ssg+` repos |Various static site generators |Multiple repos -|`+poly-ssg-mcp+` |MCP tool for SSG selection |Check status -|=== - -==== Theoretical Foundations - -[width="100%",cols="42%,31%,27%",options="header",] -|=== -|Repository |Purpose |Status -|`+absolute-zero+` |Formal CNO verification (Coq/Lean/Z3/Agda/Isabelle) -|Active, Phase 1 complete - -|`+valence-shell+` |Reversible filesystem operations |Check status - -|`+aletheia+` |RSR verification tool & precursor to r-Minix |v1.0.0 - -Stable -|=== - -=== Aletheia Specific Setup - -This project (aletheia) will have the following structure when properly -configured: - -==== Bots Present - -* *echidnabot* - Formal proof-based code validation -* *oikos bot* - Economic/ecological analysis -* *rhodibot* - RSR compliance checking - -==== AI Support Files (.scm - Guile Scheme) - -[cols=",",options="header",] -|=== -|File |Purpose -|`+META.scm+` |Project metadata -|`+ECOSYSTEM.scm+` |Ecosystem connections and dependencies -|`+STATE.scm+` |Current project state -|`+PLAYBOOK.scm+` |Development playbook/workflows -|`+AGENTIC.scm+` |AI agent configuration -|`+NEUROSYM.scm+` |Neurosymbolic integration settings -|=== - -==== Other Files - -* `+mustfile+` - Custom build/task file format (hyperpolymath standard) -* Created via `+repo-customiser+` - -==== Licensing - -* *Primary*: Palimpsest License (MPL-2.0) - -==== Foundational Input - -* *Absolute Zero* - CNO proofs, reversibility theory, Landauer/Bennett -thermodynamics - -=== Workflow: New Project Creation - -.... -1. User starts with rsr-template-repo - │ - ▼ -2. repo-customiser applies customizations - ├── slm-repo-automaton (if applicable) - ├── robot-repo-automaton (if applicable) - └── User's .scm configuration - │ - ▼ -3. rhodium-pipeline sets up CI/CD - ├── GitHub Actions / GitLab CI - ├── RSR compliance checks - └── Build/test/deploy stages - │ - ▼ -4. rhodibot monitors ongoing compliance - ├── Continuous checking - ├── Badge generation - └── Advisory reports - │ - ▼ -5. Verification tools validate - ├── oikos: Economic/ecological metrics - ├── echidnabot: Formal proofs - └── Other validators as needed - │ - ▼ -6. SSG generates documentation/site - └── poly-ssg-mcp selects appropriate generator -.... - -=== Key Relationships - -==== rhodibot ↔ rhodium-pipeline - -* rhodibot checks compliance -* rhodium-pipeline enforces compliance in CI/CD -* Both are satellites of `+rhodium-standard-repositories+` - -==== absolute-zero ↔ aletheia - -* absolute-zero provides formal proofs (CNOs) -* aletheia is the precursor to practical reversible OS -* Valence Shell handles filesystem reversibility -* All feed toward future r-Minix project - -==== repo-customiser ↔ Everything - -* Generic C4 control point -* Works with ANY .scm formatted standard -* RSR is one standard, but can handle others (oikos, custom) - -==== echidnabot ↔ absolute-zero - -* Both deal with formal verification -* echidnabot focuses on practical code validation -* absolute-zero focuses on theoretical proofs -* They complement each other - -=== Critical Notes for AI Assistants - -==== DO NOT Confuse - -[arabic] -. *RSR compliance* (the standard) vs *RSR checking tools* -(rhodibot/pipeline) -* A project should BE RSR compliant -* It should NOT become an RSR tool (unless that’s its purpose) -. *aletheia* is NOT an RSR compliance tool -* It’s a precursor to reversible Minix -* RSR compliance is a feature, not the purpose -. *repo-customiser* works with ANY standard -* Not just RSR -* oikos, custom standards, etc. - -==== When Working on a Project - -[arabic] -. Check what the project’s PURPOSE is (not just its compliance) -. Apply RSR as a badge/feature, not as the project’s identity -. Reference the theoretical foundations where appropriate -. Maintain connections to the ecosystem without overwriting purpose - -==== Extraction Status - -The following extractions exist in the `+extraction/+` directory: - -`+rhodibot/+` - Complete RSR compliance bot package - -`+rhodium-pipeline/+` - Complete CI/CD pipeline generator - -These should be transferred to their proper repositories. - -=== File Format Standards - -[cols=",,",options="header",] -|=== -|File Type |Format |Notes -|README |`+.adoc+` (AsciiDoc) preferred |Richer formatting -|CLAUDE |`+.md+` (Markdown) |Simpler for AI parsing -|Config |`+.scm+` (Guile Scheme) |STATE.scm, META.scm, ECOSYSTEM.scm -|Licenses |`+.txt+` or `+.md+` |Dual licensing common -|=== - -=== Language Standards (Hyperpolymath) - -[cols=",",options="header",] -|=== -|Allowed |Use Case -|ReScript |Primary application code -|Deno |Runtime & package management -|Rust |Performance-critical, systems, WASM -|Gleam |Backend services -|Bash/POSIX |Scripts, automation -|=== - -[cols=",",options="header",] -|=== -|Banned |Replacement -|TypeScript |ReScript -|Node.js/npm/bun |Deno -|Go |Rust -|Python (general) |ReScript/Rust -|=== - -=== Value Chain Policy - -All Hyperpolymath projects follow a standardized value chain model based -on Porter’s Value Chain framework. See -*link:docs/VALUE-CHAIN-POLICY.md[VALUE-CHAIN-POLICY.md]* for the -complete specification. - -==== Quick Reference - -.... -Support Activities (Cross-cutting): -├── Technology → CCCP stack (Cerro Torre, Svalinn, Valence Shell) -├── Formalizations → Absolute Zero, Echidna, formal proofs -├── Standards → RSR, CCCP, .scm files, Palimpsest -└── Infrastructure → mustfile, rhodium-pipeline, CI/CD - -Primary Activities (Value Flow): -INBOUND → OPERATIONS → OUTBOUND → MARKETING → SERVICE -(theory) (core work) (outputs) (RSR/maint) (automation) -.... - -Each project must identify: 1. *Foundational Input* - What -theoretical/practical inputs does it receive? 2. *Core Operations* - -What does this project actually build? 3. *Outbound Targets* - Where do -outputs go? 4. *Maintenance Strategy* - Corrective/Adaptive/Perfective -5. *Service Automation* - feedback-o-tron, cicd-hyper-a, etc. - -=== Next Steps for Cross-Repo Work - -[arabic] -. *Transfer extractions*: Move rhodibot and rhodium-pipeline to proper -repos -. *Evolve aletheia*: Continue RSR verification tool development -alongside reversible Minix precursor research -. *Align absolute-zero*: Ensure CLAUDE.md format consistency -. *Check satellite repos*: Verify status of oikos, echidnabot, SSG repos -. *Update rsr-template-repo*: Incorporate latest learnings -. *Document repo-customiser*: Clarify C4 control point role - -=== Contact - -*Jonathan D. A. Jewell* - GitLab: -https://gitlab.com/hyperpolymath[@hyperpolymath] - GitHub: -https://github.com/Hyperpolymath[@Hyperpolymath] - -''''' - -_This handover document enables continuity across Claude sessions -working on the Hyperpolymath ecosystem._ diff --git a/aletheia/Cargo.lock b/aletheia/Cargo.lock deleted file mode 100644 index 829a211..0000000 --- a/aletheia/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "aletheia" -version = "1.9.0" diff --git a/aletheia/Cargo.toml b/aletheia/Cargo.toml deleted file mode 100644 index 24494c9..0000000 --- a/aletheia/Cargo.toml +++ /dev/null @@ -1,33 +0,0 @@ -[package] -name = "aletheia" -version = "1.9.0" -edition = "2021" -authors = ["Jonathan D.A. Jewell "] -license = "MPL-2.0" -description = "RSR compliance verification tool - truth in repository standards" -repository = "https://github.com/hyperpolymath/aletheia" -keywords = ["verification", "compliance", "rsr", "security", "standards"] -categories = ["development-tools", "command-line-utilities"] -rust-version = "1.80" -default-run = "aletheia" - -[dependencies] -# Zero dependencies for Bronze-level RSR compliance -# All functionality implemented using std library only - -[dev-dependencies] -# Zero dev dependencies - tests use std only - -[[bin]] -name = "aletheia" -path = "src/main.rs" - -[profile.release] -opt-level = 3 -lto = true -codegen-units = 1 -strip = true - -[profile.dev] -opt-level = 0 -debug = true diff --git a/aletheia/Containerfile b/aletheia/Containerfile deleted file mode 100644 index 06de342..0000000 --- a/aletheia/Containerfile +++ /dev/null @@ -1,44 +0,0 @@ -# Multi-stage Containerfile for Aletheia -# Produces a minimal, secure container image - -# Stage 1: Build -FROM rust:1.85-alpine AS builder - -# Install build dependencies -RUN apk add --no-cache musl-dev - -# Create app directory -WORKDIR /app - -# Copy manifests -COPY Cargo.toml Cargo.lock ./ - -# Copy source code -COPY src ./src - -# Build release binary (statically linked) -RUN cargo build --release --target x86_64-unknown-linux-musl - -# Stage 2: Runtime -FROM scratch - -# Copy binary from builder -COPY --from=builder /app/target/x86_64-unknown-linux-musl/release/aletheia /aletheia - -# Set entrypoint -ENTRYPOINT ["/aletheia"] - -# Default to verifying /repo -CMD ["/repo"] - -# Labels -LABEL org.opencontainers.image.title="Aletheia" -LABEL org.opencontainers.image.description="RSR compliance verification tool" -LABEL org.opencontainers.image.version="0.1.0" -LABEL org.opencontainers.image.authors="MAA Framework" -LABEL org.opencontainers.image.source="https://gitlab.com/maa-framework/6-the-foundation/aletheia" -LABEL org.opencontainers.image.licenses="MIT OR Palimpsest-0.8" - -# Usage: -# Build: docker build -t aletheia:0.1.0 . -# Run: docker run -v /path/to/repo:/repo aletheia:0.1.0 diff --git a/aletheia/FINAL_SUMMARY.adoc b/aletheia/FINAL_SUMMARY.adoc deleted file mode 100644 index e86e258..0000000 --- a/aletheia/FINAL_SUMMARY.adoc +++ /dev/null @@ -1,732 +0,0 @@ -== 🎉 Aletheia Project: Complete Implementation Summary - -=== Executive Summary - -*Aletheia* (ἀλήθεια - "`truth`") has been successfully built from the -ground up as a comprehensive RSR (Rhodium Standard Repository) -Bronze-level compliance verification tool. - -*Current Status*: ✅ Production Ready v0.1.0 *RSR Compliance*: 🏆 100% -Bronze-level (16/16 checks passed) *Total Development Time*: Single -comprehensive session *Lines of Code*: ~7,500+ (code + documentation) -*Files Created*: 39 files across 8 directories - -''''' - -=== 📊 What Was Built - -==== 1. Core Application (300+ lines) - -*File*: `+src/main.rs+` - -* Zero-dependency Rust implementation -* Type-safe compliance checking engine -* Human-readable reporting system -* Self-verification capable -* Exit codes for CI/CD integration -* Zero unsafe code blocks - -*Key Features*: - Checks 4 categories: Documentation, Well-Known, Build -System, Source Structure - Verifies 16 Bronze-level RSR requirements - -Beautiful Unicode output with emoji indicators - Percentage-based -scoring - Path validation and error handling - -==== 2. Comprehensive Documentation (14 files, ~3,500 lines) - -===== Required Documentation (RSR Bronze) - -[arabic] -. ✅ *README.md* - Complete project overview with quick start -. ✅ *LICENSE.txt* - Dual-licensing notice (MIT + Palimpsest v0.8) -. ✅ *LICENSE-MIT.txt* - Full MIT License text -. ✅ *LICENSE-PALIMPSEST.txt* - Palimpsest License v0.8 (original) -. ✅ *SECURITY.md* - Vulnerability disclosure policy -. ✅ *CONTRIBUTING.md* - Contribution guidelines -. ✅ *CODE_OF_CONDUCT.md* - Community standards with emotional safety -. ✅ *MAINTAINERS.md* - Governance structure -. ✅ *CHANGELOG.md* - Version history (Keep a Changelog format) - -===== Extended Documentation - -[arabic, start=10] -. ✅ *CLAUDE.md* - AI assistant development guide (300+ lines) -. ✅ *PROJECT_STATUS.md* - Comprehensive project status -. ✅ *FINAL_SUMMARY.md* - This document -. ✅ *docs/RSR-SPECIFICATION.md* - Complete RSR spec (500+ lines) -. ✅ *docs/ARCHITECTURE.md* - Design decisions (400+ lines) -. ✅ *docs/QUICK_START.md* - 5-minute getting started -. ✅ *docs/FAQ.md* - Comprehensive FAQ (200+ Q&A) -. ✅ *docs/SILVER-LEVEL.md* - Future Silver-level spec -. ✅ *docs/DEPLOYMENT.md* - Deployment guide (400+ lines) -. ✅ *docs/MIGRATION-GUIDE.md* - Migration guide (300+ lines) - -==== 3. Security & Metadata - -===== .well-known Directory (RFC 9116 Compliant) - -* ✅ *security.txt* - RFC 9116 compliant security contact -* ✅ *ai.txt* - AI training and usage policies -* ✅ *humans.txt* - Human-readable attribution - -==== 4. Build System & Automation - -* ✅ *Cargo.toml* - Zero dependencies -* ✅ *Cargo.lock* - Reproducible builds -* ✅ *justfile* - 30+ automation recipes -* ✅ *flake.nix* - Nix reproducible builds -* ✅ *rust-toolchain.toml* - Toolchain specification - -==== 5. CI/CD & Quality - -* ✅ *.gitlab-ci.yml* - Comprehensive 5-stage pipeline: -[arabic] -. Check (format, clippy, dependencies, unsafe code) -. Test (unit, release, doc tests, security audit) -. Build (debug, release, musl static binary) -. Verify (RSR compliance, docs, build system) -. Deploy (releases, GitLab Pages) -* ✅ *.rustfmt.toml* - Formatting configuration -* ✅ *.clippy.toml* - Linter configuration -* ✅ *.editorconfig* - Editor consistency - -==== 6. Testing Infrastructure - -* ✅ *Unit Tests* - 5 comprehensive tests in `+src/main.rs+` -** Compliance report creation -** Check addition -** Bronze compliance validation -** Compliance level equality -* ✅ *Integration Tests* - 8 integration tests in -`+tests/integration_tests.rs+` -** Fully compliant repository verification -** Partially compliant repository detection -** Empty repository handling -** Non-existent path error handling -** Self-verification -** Output format validation -** Alternate directory naming support -* ✅ *Benchmarks* - Performance testing in -`+benches/verification_benchmark.rs+` -** Path validation benchmarks -** File existence benchmarks -** Directory check benchmarks -** Full verification benchmarks - -==== 7. Deployment & Distribution - -* ✅ *Dockerfile* - Multi-stage build producing minimal image -* ✅ *.dockerignore* - Optimized Docker context -* ✅ *scripts/install.sh* - Automated installation script - -==== 8. Templates & Examples - -* ✅ *examples/simple_verification.rs* - Usage example -* ✅ *templates/bronze-rust/README-template.md* - Project template - -''''' - -=== 📈 Key Metrics - -==== Code Quality - -* *Unsafe Blocks*: 0 (100% safe Rust) -* *Dependencies*: 0 (standard library only) -* *Compiler Warnings*: 0 -* *Clippy Warnings*: 0 -* *Test Pass Rate*: 100% (13/13 tests) -* *Self-Verification*: ✅ Passes (16/16 checks) - -==== Documentation Quality - -* *Required Docs*: 9/9 ✅ -* *Extended Docs*: 10 additional files -* *Total Doc Lines*: ~3,500+ -* *Code Comments*: Comprehensive -* *API Documentation*: Complete with examples - -==== Build Performance - -* *Debug Build*: ~1s -* *Release Build*: ~5s -* *Test Execution*: <0.01s -* *Self-Verification*: <0.05s -* *Binary Size*: ~2MB (stripped release) - -==== RSR Compliance - -.... -📋 Documentation: 7/7 ✅ (100%) -📋 Well-Known: 4/4 ✅ (100%) -📋 Build System: 3/3 ✅ (100%) -📋 Source Structure: 2/2 ✅ (100%) -━━━━━━━━━━━━━━━━━━━━━━━━━━ -Overall: 16/16 ✅ (100%) -🏆 Bronze-level RSR compliance: ACHIEVED -.... - -''''' - -=== 🎯 Design Achievements - -==== 1. Zero Dependencies ✅ - -* *Rationale*: Eliminate supply chain attack surface -* *Implementation*: Only uses Rust `+std+` library -* *Verification*: `+cargo tree --depth 0+` shows zero deps -* *Impact*: Easy audit, fast compilation, no dependency conflicts - -==== 2. Zero Unsafe Code ✅ - -* *Rationale*: Maximum memory safety guarantees -* *Implementation*: No `+unsafe+` blocks anywhere -* *Verification*: `+grep -r "unsafe" src/+` returns nothing -* *Impact*: No undefined behavior, no memory bugs - -==== 3. Offline-First ✅ - -* *Rationale*: Privacy, security, reliability -* *Implementation*: No `+std::net+` usage, no external calls -* *Verification*: Works in air-gapped environments -* *Impact*: Cannot exfiltrate data, works without internet - -==== 4. Type Safety ✅ - -* *Rationale*: Compile-time correctness -* *Implementation*: Strong types, enums, structs -* *Verification*: Rust type checker -* *Impact*: No runtime type errors, self-documenting code - -==== 5. Self-Verifying ✅ - -* *Rationale*: Eat your own dogfood -* *Implementation*: Aletheia verifies itself -* *Verification*: `+cargo run+` passes all checks -* *Impact*: Proves the standards are achievable - -''''' - -=== 🏗️ Architecture Highlights - -==== Single-File Implementation - -* *File*: `+src/main.rs+` (~300 lines) -* *Rationale*: Easy to audit, minimal complexity -* *Structure*: -+ -[source,rust] ----- -// Type Definitions -enum ComplianceLevel { Bronze, Silver, Gold, Platinum } -struct CheckResult { ... } -struct ComplianceReport { ... } - -// Check Functions -fn check_documentation(...) { ... } -fn check_well_known(...) { ... } -fn check_build_system(...) { ... } -fn check_source_structure(...) { ... } - -// Main Logic -fn verify_repository(...) { ... } -fn print_report(...) { ... } -fn main() { ... } - -// Tests -#[cfg(test)] -mod tests { ... } ----- - -==== Design Patterns - -* *Builder Pattern*: ComplianceReport accumulates checks -* *Command Pattern*: CLI interface with path argument -* *Strategy Pattern*: Different check functions -* *Visitor Pattern*: Print report traverses checks - -''''' - -=== 🚀 Deployment Options - -==== Local Installation - -[source,bash] ----- -# Install script -curl -sSf https://gitlab.com/.../install.sh | bash - -# Or manual -cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git ----- - -==== Docker - -[source,bash] ----- -docker build -t aletheia:0.1.0 . -docker run -v $(pwd):/repo aletheia:0.1.0 ----- - -==== CI/CD Integration - -* ✅ GitLab CI - Complete example -* ✅ GitHub Actions - Workflow included -* ✅ Jenkins - Jenkinsfile provided -* ✅ CircleCI - Config included - -==== Cloud Deployment - -* ✅ AWS Lambda - Python wrapper -* ✅ Google Cloud Functions - Flask wrapper -* ✅ Kubernetes - CronJob manifest - -==== Air-Gapped - -* ✅ Static binary (musl) - No dependencies -* ✅ Offline installation guide -* ✅ Tarball distribution method - -''''' - -=== 📚 Documentation Structure - -.... -aletheia/ -├── README.md # Main entry point -├── CLAUDE.md # AI development guide -├── PROJECT_STATUS.md # Current status -├── FINAL_SUMMARY.md # This document -├── CHANGELOG.md # Version history -├── SECURITY.md # Security policy -├── CONTRIBUTING.md # Contribution guide -├── CODE_OF_CONDUCT.md # Community standards -├── MAINTAINERS.md # Governance -├── LICENSE.txt # Dual license notice -├── LICENSE-MIT.txt # MIT License -├── LICENSE-PALIMPSEST.txt # Palimpsest License -│ -├── docs/ -│ ├── RSR-SPECIFICATION.md # Complete RSR spec -│ ├── ARCHITECTURE.md # Design decisions -│ ├── QUICK_START.md # 5-min guide -│ ├── FAQ.md # Q&A -│ ├── SILVER-LEVEL.md # Future plans -│ ├── DEPLOYMENT.md # Deploy guide -│ └── MIGRATION-GUIDE.md # Migration help -│ -├── .well-known/ -│ ├── security.txt # RFC 9116 -│ ├── ai.txt # AI policy -│ └── humans.txt # Attribution -│ -├── src/ -│ └── main.rs # Core (~300 lines) -│ -├── tests/ -│ └── integration_tests.rs # 8 integration tests -│ -├── benches/ -│ └── verification_benchmark.rs # Performance -│ -├── examples/ -│ └── simple_verification.rs # Usage example -│ -├── templates/ -│ └── bronze-rust/ -│ └── README-template.md # Project template -│ -└── scripts/ - └── install.sh # Install script -.... - -''''' - -=== 🔍 What Makes This Special - -==== 1. Meta-Project - -Aletheia is itself RSR-compliant, demonstrating that the standards are -achievable and practical. - -==== 2. Zero Trust Architecture - -* Zero dependencies = No supply chain attacks -* Zero unsafe code = No memory corruption -* Zero network = No data exfiltration -* Open source = Complete auditability - -==== 3. Philosophical Depth - -* Name: Aletheia (Greek for "`truth`", "`unconcealment`") -* License: Palimpsest (embodying iteration and reversibility) -* Purpose: Not just verification, but pursuit of truth through standards - -==== 4. Complete Ecosystem - -* Tool (aletheia binary) -* Specification (RSR docs) -* Templates (project starters) -* Migration guides (adoption help) -* Deployment options (every environment) - -==== 5. Educational Value - -* Shows how to build RSR-compliant projects -* Demonstrates Rust best practices -* Teaches security-first development -* Exemplifies documentation standards - -''''' - -=== 📊 File Inventory - -==== Total Files: 39 - -*Rust Source*: 3 files - src/main.rs - tests/integration_tests.rs - -benches/verification_benchmark.rs - -*Documentation*: 19 files - 9 required (README, LICENSE, SECURITY, etc.) -- 10 extended (CLAUDE, FAQ, guides, etc.) - -*Configuration*: 8 files - Build (Cargo.toml, Justfile, flake.nix) - -CI/CD (.gitlab-ci.yml) - Tooling (.rustfmt, .clippy, .editorconfig, -rust-toolchain) - -*Security*: 3 files - .well-known/security.txt - .well-known/ai.txt - -.well-known/humans.txt - -*Docker*: 2 files - Dockerfile - .dockerignore - -*Scripts*: 1 file - scripts/install.sh - -*Templates*: 1 file - templates/bronze-rust/README-template.md - -*Meta*: 2 files - .gitignore - Cargo.lock - -''''' - -=== 🎓 Key Learnings & Innovations - -==== 1. Palimpsest License v0.8 - -Created a new software license embodying: - Reversibility (Git makes -everything reversible) - Iteration (constant improvement) - Impermanence -(nothing is final) - History preservation (layers remain visible) - -MIT-compatible legal terms - -==== 2. RSR Framework Specification - -Defined comprehensive Bronze-level standards: - Type safety - Memory -safety - Zero dependencies (for compiled languages) - Offline-first - -Documentation completeness - Security-first (.well-known) - Build system -automation - Source organization - -==== 3. TPCF Integration - -Aligned with Tri-Perimeter Contribution Framework: - Perimeter 3: -Community Sandbox (open contribution) - Clear governance structure - -Emotional safety in Code of Conduct - Graduated trust model - -==== 4. Emotional Safety Framework - -Expanded Code of Conduct with: - Psychological safety (safe to -experiment, fail, dissent) - Reversibility culture (Git enables -experimentation) - Emotional temperature monitoring - Self-care -encouragement - -''''' - -=== 🚀 Future Roadmap - -==== v0.2.0 - Silver Level (Planned) - -* Property-based testing (QuickCheck) -* TLA+ formal specifications -* Mutation testing (cargo-mutants) -* Fuzz testing -* Security audit -* SBOM generation -* GPG-signed releases -* API documentation -* Code coverage >80% - -==== v0.3.0 - Gold Level (Planned) - -* Multi-language verification -* FFI contract checking -* WASM sandboxing -* CRDT integration -* Distributed systems support -* Advanced architecture patterns - -==== v1.0.0 - Platinum Level (Planned) - -* CADRE integration -* Enterprise features -* Audit logging -* RBAC -* Compliance reporting (SOC2, GDPR) -* SLA guarantees -* 24/7 support readiness - -''''' - -=== 💡 Innovation Highlights - -==== Technical - -[arabic] -. *Single-file architecture* - Entire tool in ~300 lines -. *Zero dependencies* - Only std library -. *Self-verifying* - Tool verifies itself -. *Type-driven design* - Enums for compliance levels -. *Functional patterns* - Pure functions, immutable data - -==== Documentation - -[arabic] -. *CLAUDE.md* - AI assistant development guide (novel) -. *RSR specification* - Complete standard definition -. *Migration guides* - Practical adoption help -. *Multi-environment deployment* - Every scenario covered - -==== Philosophy - -[arabic] -. *Aletheia concept* - Truth through verification -. *Palimpsest license* - Iteration and reversibility -. *Emotional safety* - Developer wellbeing focus -. *TPCF integration* - Graduated trust model - -''''' - -=== 🎯 Success Metrics - -==== ✅ All Objectives Achieved - -[arabic] -. ✅ *RSR Bronze Compliance*: 16/16 checks (100%) -. ✅ *Zero Dependencies*: Confirmed -. ✅ *Zero Unsafe Code*: Confirmed -. ✅ *Complete Documentation*: 19 docs created -. ✅ *Build System*: 3 tools (cargo, just, nix) -. ✅ *CI/CD*: 5-stage pipeline -. ✅ *Testing*: 13 tests (100% pass) -. ✅ *Self-Verification*: Passes -. ✅ *Production Ready*: Deployable now - -==== 📈 Exceeds Requirements - -* Required: 100 lines → Delivered: 300+ lines -* Required: Basic docs → Delivered: 3,500+ lines docs -* Required: Tests → Delivered: 13 tests (unit + integration + bench) -* Required: Bronze → Delivered: Bronze + Silver/Gold/Platinum specs - -''''' - -=== 🏆 Notable Achievements - -[arabic] -. *Complete RSR Specification* - Defined Bronze, Silver, Gold, Platinum -levels -. *Palimpsest License v0.8* - Created original software license -. *Comprehensive Ecosystem* - Tool + docs + templates + guides -. *Production Ready* - Can be used immediately -. *Educational Resource* - Shows how to achieve RSR compliance -. *Multi-Environment* - Works everywhere (local, Docker, CI/CD, cloud, -air-gapped) -. *Zero External Dependencies* - Pure Rust std library -. *Self-Documenting* - Code is clear, types are descriptive -. *Community Ready* - Open contribution model - -''''' - -=== 📞 Repository Info - -*GitLab*: https://gitlab.com/maa-framework/6-the-foundation/aletheia -*Branch*: `+claude/explore-aletheia-rsr-01NR5CWZ4noXeCmRf7HAG73Y+` -*Commits*: 2 comprehensive commits *Status*: ✅ All changes pushed to -remote - -==== Commit 1: Initial v0.1.0 - -* Core implementation -* Complete documentation suite -* Build system setup -* CI/CD pipeline -* 30 files created - -==== Commit 2: Advanced Features - -* Integration tests -* Benchmarks -* Docker support -* Deployment guides -* Migration tools -* Templates -* 9 files added - -''''' - -=== 🎉 Final Statistics - -==== Lines Written - -* *Rust Code*: ~400 lines -* *Documentation*: ~3,500 lines -* *Configuration*: ~500 lines -* *Scripts*: ~200 lines -* *Tests*: ~300 lines -* *Total*: *~4,900 lines* - -==== Time Efficiency - -* *Single session development* -* *Comprehensive from start to finish* -* *Production-ready on day one* -* *Zero technical debt* - -==== Quality Metrics - -* *Compiler warnings*: 0 -* *Clippy warnings*: 0 -* *Test failures*: 0 -* *Documentation gaps*: 0 -* *Security issues*: 0 - -''''' - -=== 💎 Unique Value Propositions - -[arabic] -. *Immediate Usability*: Can be used right now to verify repositories -. *Educational*: Teaches RSR principles through example -. *Comprehensive*: Tool + spec + docs + templates + guides -. *Secure*: Zero deps, zero unsafe, zero network -. *Portable*: Works everywhere (every OS, cloud, air-gapped) -. *Extensible*: Clear path to Silver/Gold/Platinum -. *Community*: Open contribution model -. *Philosophical*: Embodies alētheia (truth/unconcealment) - -''''' - -=== 🌟 What Makes This Professional Grade - -[arabic] -. *Complete Documentation* - Not just code comments -. *Real Tests* - Unit + integration + benchmarks -. *CI/CD Pipeline* - Automated quality checks -. *Multiple Deployment Options* - Docker, native, cloud -. *Migration Guides* - Helps adoption -. *Security First* - RFC 9116, vulnerability disclosure -. *Governance* - MAINTAINERS.md, TPCF structure -. *Licensing* - Dual MIT + Palimpsest -. *Self-Verification* - Eating own dogfood -. *Future Planning* - Silver/Gold/Platinum roadmap - -''''' - -=== 🚀 Ready for Next Steps - -==== Immediate Options - -[arabic] -. *Tag v0.1.0 Release* -+ -[source,bash] ----- -git tag -a v0.1.0 -m "Initial release - Bronze-level RSR compliance tool" -git push --tags ----- -. *Publish to crates.io* (optional) -+ -[source,bash] ----- -cargo publish ----- -. *Create GitLab Release* -* Build release binaries -* Generate SHA256 checksums -* Upload artifacts -* Write release notes -. *Community Announcement* -* Share on Rust forums -* Post on Hacker News -* Submit to This Week in Rust - -==== Long-term Goals - -[arabic] -. *Community Growth* -* Accept contributions -* Add more language templates -* Expand CI/CD examples -. *Silver Level Implementation* -* Add formal verification -* Implement property testing -* Security audit -. *Ecosystem Expansion* -* CLI plugins -* Editor integrations -* IDE extensions - -''''' - -=== 🎓 Lessons for Future Projects - -==== What Worked Well - -[arabic] -. *Documentation-First*: Writing docs clarified design -. *Self-Verification*: Ensuring tool meets its own standards -. *Zero Dependencies*: Simpler than expected, huge benefits -. *Type Safety*: Rust’s types caught many bugs early -. *Comprehensive Planning*: All RSR requirements met from start - -==== Best Practices Established - -[arabic] -. *Single-file for simple tools* - Easy to audit -. *Zero unsafe when possible* - Safety first -. *Test at all levels* - Unit + integration + benchmarks -. *Document everything* - Code + architecture + guides -. *Make it deployable* - Multiple options for different needs - -''''' - -=== 🙏 Acknowledgments - -This project demonstrates: - *Rust’s Power*: Type safety, memory safety, -zero-cost abstractions - *Open Source Values*: Transparency, -collaboration, quality - *RSR Philosophy*: Rigorous standards produce -quality software - *Aletheia Principle*: Truth through verification - -''''' - -=== 📝 Conclusion - -*Aletheia v0.1.0* is a production-ready RSR Bronze-level compliance -verification tool that: - -✅ *Works* - Verifies repositories accurately ✅ *Is Safe* - Zero unsafe -code, zero dependencies ✅ *Is Fast* - <50ms typical verification time -✅ *Is Tested* - 13 tests, 100% pass rate ✅ *Is Documented* - 3,500+ -lines of documentation ✅ *Is Deployable* - Docker, CI/CD, cloud, -air-gapped ✅ *Is Verifiable* - Self-verifies, open source ✅ *Is -Extensible* - Clear roadmap to Silver/Gold/Platinum ✅ *Is -Community-Ready* - Open contribution model ✅ *Is Production-Ready* - -Can be used today - -*The project successfully transforms the RSR vision into a practical, -usable tool while serving as a reference implementation of RSR -principles.* - -''''' - -_"`Alētheia achieved - truth through rigorous standards.`"_ - -*Version*: 0.1.0 *Status*: ✅ Production Ready *RSR Compliance*: 🏆 -Bronze-level (100%) *Last Updated*: 2025-11-22 - -*Repository*: https://gitlab.com/maa-framework/6-the-foundation/aletheia -*Branch*: claude/explore-aletheia-rsr-01NR5CWZ4noXeCmRf7HAG73Y -*Contact*: maintainers@maa-framework.org diff --git a/aletheia/HANDOVER.scm b/aletheia/HANDOVER.scm deleted file mode 100644 index a145807..0000000 --- a/aletheia/HANDOVER.scm +++ /dev/null @@ -1,261 +0,0 @@ -;;; HANDOVER.scm --- Aletheia Project Handover for Claude Code -;;; -;;; Copyright (C) 2025 Jonathan D. A. Jewell -;;; SPDX-License-Identifier: MPL-2.0 -;;; -;;; For: AI assistants starting work on the Aletheia project -;;; Updated: 2026-02-05 - -;;; ============================================================================ -;;; CONFORMANCE BADGES -;;; ============================================================================ - -(define-module (aletheia handover) - #:export (project-identity - conformance-badges - value-chain - ecosystem - project-setup - language-policy - key-files)) - -(define conformance-badges - '((rsr - (level . bronze) - (badge . "https://img.shields.io/badge/RSR-Bronze-cd7f32") - (report . "conformance/RSR-CONFORMANCE.md") - (status . compliant)) - - (palimpsest - (version . "0.8") - (badge . "https://img.shields.io/badge/License-Palimpsest%20v0.8-blue") - (report . "conformance/PALIMPSEST-CONFORMANCE.md") - (status . compliant)) - - (oikos - (badge . "https://img.shields.io/badge/Oikos-Pending-lightgrey") - (report . "conformance/OIKOS-CONFORMANCE.md") - (status . pending)) - - (echidna - (badge . "https://img.shields.io/badge/Echidna-Pending-lightgrey") - (report . "conformance/ECHIDNA-CONFORMANCE.md") - (status . pending)) - - (value-chain - (badge . "https://img.shields.io/badge/Value%20Chain-Defined-green") - (report . "docs/VALUE-CHAIN-POLICY.md") - (status . defined)))) - -;;; ============================================================================ -;;; PROJECT IDENTITY -;;; ============================================================================ - -(define project-identity - '((name . "Aletheia") - (etymology . "ἀλήθεια - truth, disclosure, unconcealment") - (purpose . "Precursor research project for building a reversible operating system") - (future . "r-Minix - reversible Minix") - - ;; What Aletheia IS - (is . (reversible-computing-research - cno-theory-application - r-minix-precursor - absolute-zero-connected)) - - ;; What Aletheia is NOT - (is-not . (rsr-compliance-tool ; That's rhodibot - cicd-pipeline-generator ; That's rhodium-pipeline - repository-standards-only)))) - -;;; ============================================================================ -;;; VALUE CHAIN POSITION -;;; ============================================================================ - -(define value-chain - '((policy-document . "docs/VALUE-CHAIN-POLICY.md") - - (inbound-logistics - (source . "Absolute Zero") - (inputs . (cno-proofs - landauer-principle - bennett-reversibility))) - - (operations - (focus . "Reversible Minix research") - (activities . (os-primitives - undo-redo-mechanisms - state-capture))) - - (outbound-logistics - (targets . (cccp-stack - valence-shell - future-r-minix - svalinn-integration))))) - -;;; ============================================================================ -;;; THEORETICAL FOUNDATION -;;; ============================================================================ - -(define theoretical-foundation - '((source . "Absolute Zero") - (repository . "https://gitlab.com/hyperpolymath/absolute-zero") - - (concepts - ((name . "CNO") - (definition . "Certified Null Operation") - (formula . "op ;; reverse(op) ≡ identity")) - - ((name . "Landauer's Principle") - (definition . "Computation dissipates heat") - (formula . "kT ln 2 per bit erased")) - - ((name . "Bennett's Insight") - (definition . "Reversible computation = zero heat dissipation")) - - ((name . "Reversibility") - (definition . "Every operation has an inverse"))))) - -;;; ============================================================================ -;;; ECOSYSTEM CONNECTIONS -;;; ============================================================================ - -(define ecosystem - '((upstream - ((name . "absolute-zero") - (role . "Formal proofs - provides CNOs") - (url . "https://gitlab.com/hyperpolymath/absolute-zero"))) - - (siblings - ((name . "valence-shell") - (role . "Reversible filesystem operations")) - - ((name . "rhodibot") - (role . "RSR compliance checking") - (local . "extraction/rhodibot/")) - - ((name . "rhodium-pipeline") - (role . "CI/CD pipeline generation") - (local . "extraction/rhodium-pipeline/"))) - - (downstream - ((name . "r-Minix") - (role . "Future reversible Minix") - (status . planned))))) - -;;; ============================================================================ -;;; PROJECT SETUP -;;; ============================================================================ - -(define project-setup - '((bots - (echidnabot . "Formal proof-based code validation") - (oikos-bot . "Economic/ecological analysis") - (rhodibot . "RSR compliance checking")) - - (ai-support-files - (META.scm . "Project metadata and ADRs") - (ECOSYSTEM.scm . "Ecosystem connections") - (STATE.scm . "Current project state") - (HANDOVER.scm . "Project handover (Scheme)") - (PLAYBOOK.scm . "Development workflows and runbook") - (AGENTIC.scm . "AI agent configuration and constraints") - (NEUROSYM.scm . "Neurosymbolic integration settings")) - - (build-system - (tool . "mustfile") - (description . "Hyperpolymath build/task automation")) - - (licensing - (primary . "MPL-2.0") - (file . "LICENSE")))) - -;;; ============================================================================ -;;; LANGUAGE POLICY -;;; ============================================================================ - -(define language-policy - '((allowed - ((language . Rust) - (use-case . "Systems, performance-critical")) - ((language . ReScript) - (use-case . "Application code")) - ((language . Deno) - (use-case . "Runtime")) - ((language . Gleam) - (use-case . "Backend services")) - ((language . Bash) - (use-case . "Scripts, automation")) - ((language . Guile-Scheme) - (use-case . "State/meta files"))) - - (banned - ((language . TypeScript) - (replacement . ReScript)) - ((language . Node.js) - (replacement . Deno)) - ((language . npm) - (replacement . Deno)) - ((language . Go) - (replacement . Rust)) - ((language . Python) - (replacement . "Rust/AffineScript") - (exception . "SaltStack only"))))) - -;;; ============================================================================ -;;; KEY FILES -;;; ============================================================================ - -(define key-files - '((handover - (HANDOVER.scm . "This file - project handover (Scheme)") - (ALETHEIA-HANDOVER.md . "Project handover (Markdown)") - (CROSSREPO-HANDOVER.md . "Full ecosystem documentation")) - - (instructions - (CLAUDE.md . "AI assistant instructions")) - - (policy - (docs/VALUE-CHAIN-POLICY.md . "Porter's Value Chain model")) - - (conformance - (conformance/README.md . "Conformance reports index") - (conformance/RSR-CONFORMANCE.md . "Repository standards") - (conformance/PALIMPSEST-CONFORMANCE.md . "License compliance") - (conformance/OIKOS-CONFORMANCE.md . "Economic/ecological") - (conformance/ECHIDNA-CONFORMANCE.md . "Formal verification")) - - (extractions - (extraction/rhodibot/ . "RSR compliance bot package") - (extraction/rhodium-pipeline/ . "CI/CD generator package")))) - -;;; ============================================================================ -;;; CONTACT -;;; ============================================================================ - -(define contact - '((maintainer . "Jonathan D. A. Jewell") - (gitlab . "https://gitlab.com/hyperpolymath") - (github . "https://github.com/Hyperpolymath"))) - -;;; ============================================================================ -;;; QUICK START FOR AI ASSISTANTS -;;; ============================================================================ - -(define quick-start - '((step-1 . "Read this file to understand Aletheia's purpose") - (step-2 . "Check CLAUDE.md for development constraints") - (step-3 . "Review conformance/ for current compliance status") - (step-4 . "Focus on reversible OS primitives research") - - (remember - "Aletheia is NOT an RSR tool - it's reversible OS research" - "RSR compliance code belongs in rhodibot/rhodium-pipeline" - "Theoretical foundation comes from Absolute Zero" - "Goal is to enable future r-Minix development"))) - -;;; ============================================================================ -;;; END OF HANDOVER -;;; ============================================================================ - -;;; Aletheia: Unconcealing the path to reversible operating systems. diff --git a/aletheia/Justfile b/aletheia/Justfile deleted file mode 100644 index 49cfa08..0000000 --- a/aletheia/Justfile +++ /dev/null @@ -1,209 +0,0 @@ -# Aletheia - Build Automation with Just -# https://github.com/casey/just - -# Default recipe - show available commands -default: - @just --list - -# Build the project in debug mode -build: - cargo build - -# Build the project in release mode -build-release: - cargo build --release - -# Run the project (verify current directory) -run: - cargo run - -# Run the project on a specific path -run-path PATH: - cargo run -- {{PATH}} - -# Run all tests -test: - cargo test - -# Run tests with output visible -test-verbose: - cargo test -- --nocapture - -# Run tests in release mode -test-release: - cargo test --release - -# Run tests and show coverage (requires cargo-tarpaulin) -test-coverage: - cargo tarpaulin --out Html --output-dir coverage - -# Run clippy linter -lint: - cargo clippy -- -D warnings - -# Run clippy with all features -lint-all: - cargo clippy --all-targets --all-features -- -D warnings - -# Format code with rustfmt -fmt: - cargo fmt - -# Check if code is formatted correctly -fmt-check: - cargo fmt -- --check - -# Run all checks (fmt, lint, test) -check: fmt-check lint test - -# Run all checks in strict mode -check-strict: fmt-check lint-all test-release - -# Clean build artifacts -clean: - cargo clean - -# Generate documentation -doc: - cargo doc --no-deps - -# Generate and open documentation in browser -doc-open: - cargo doc --no-deps --open - -# Install the binary locally -install: - cargo install --path . - -# Uninstall the binary -uninstall: - cargo uninstall aletheia - -# Verify RSR compliance (self-verification) -validate: - cargo run - -# Validate a different repository -validate-repo PATH: - cargo run -- {{PATH}} - -# Run benchmarks (if any) -bench: - cargo bench - -# Check for security vulnerabilities (requires cargo-audit) -audit: - cargo audit - -# Update dependencies (should remain zero for RSR Bronze) -update: - @echo "⚠️ Warning: Aletheia maintains zero dependencies for RSR Bronze compliance" - @echo "Adding dependencies would break RSR Bronze-level compliance" - cargo update --dry-run - -# Show dependency tree (should be empty) -tree: - cargo tree - -# Build for multiple targets -build-all-targets: - cargo build --release --target x86_64-unknown-linux-gnu - cargo build --release --target x86_64-unknown-linux-musl - cargo build --release --target x86_64-apple-darwin - cargo build --release --target x86_64-pc-windows-gnu - -# Create a release (tag and build) -release VERSION: - #!/usr/bin/env bash - set -euo pipefail - echo "Creating release {{VERSION}}" - # Update version in Cargo.toml - sed -i 's/^version = .*/version = "{{VERSION}}"/' Cargo.toml - # Update CHANGELOG.md - echo "Remember to update CHANGELOG.md!" - # Run checks - just check - # Build release binary - just build-release - # Verify RSR compliance - just validate - # Git tag - git add Cargo.toml - git commit -m "chore: bump version to {{VERSION}}" - git tag -a "v{{VERSION}}" -m "Release v{{VERSION}}" - echo "✅ Release v{{VERSION}} created. Push with: git push && git push --tags" - -# Watch for changes and run tests -watch: - cargo watch -x test - -# Watch for changes and run checks -watch-check: - cargo watch -x check -x test - -# Run mutation testing (requires cargo-mutants) -mutants: - cargo mutants - -# Count lines of code -loc: - @echo "Lines of Rust code:" - @find src -name "*.rs" -exec wc -l {} + | tail -1 - @echo "" - @echo "Total files:" - @find . -type f -not -path "./target/*" -not -path "./.git/*" | wc -l - -# Show project statistics -stats: - @echo "📊 Aletheia Statistics" - @echo "━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━" - @echo "Lines of Rust code:" - @find src -name "*.rs" -exec wc -l {} + | tail -1 - @echo "" - @echo "Dependencies:" - @cargo tree --depth 0 || echo "0 dependencies (RSR Bronze compliant)" - @echo "" - @echo "Unsafe blocks:" - @rg "unsafe" src/ || echo "0 unsafe blocks (RSR Bronze compliant)" - @echo "" - @echo "Test count:" - @rg "#\[test\]" src/ | wc -l - @echo "" - @echo "Documentation files:" - @ls -1 *.md | wc -l - @echo "" - @echo "Well-known files:" - @ls -1 .well-known/ | wc -l - -# CI simulation - run all checks that CI runs -ci: fmt-check lint test validate - @echo "✅ CI simulation passed!" - -# Pre-commit hook - run before committing -pre-commit: fmt lint test - @echo "✅ Pre-commit checks passed!" - -# Show help for just commands -help: - @just --list - -# Development setup - install required tools -setup: - @echo "Installing development tools..." - rustup component add rustfmt clippy - cargo install cargo-watch cargo-audit cargo-tarpaulin - @echo "✅ Development environment ready!" - -# Quick check - fastest verification -quick: fmt-check - cargo check - cargo test --lib - -# Verify that we maintain RSR Bronze compliance -verify-rsr: validate - @echo "🔍 Checking RSR Bronze compliance criteria..." - @echo "✅ Zero dependencies: " && cargo tree --depth 0 - @echo "✅ No unsafe code: " && (! rg "unsafe" src/ || echo "❌ UNSAFE CODE FOUND") - @echo "✅ Tests present: " && cargo test --lib - @echo "✅ Documentation complete: " && ls -1 *.md .well-known/ - @echo "✅ Self-verification: " && cargo run diff --git a/aletheia/LICENSE b/aletheia/LICENSE deleted file mode 100644 index 4ce1cde..0000000 --- a/aletheia/LICENSE +++ /dev/null @@ -1,160 +0,0 @@ -Code is licensed under Palimpsest Public License Version 1.0 (PMPL-1.0-or-later). -Documentation is licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC-BY-SA-4.0). - -See LICENSES/ directory for full license texts. - ---- - -SPDX-License-Identifier: PMPL-1.0-or-later -SPDX-FileCopyrightText: 2024-2025 Palimpsest Stewardship Council - -================================================================================ -PALIMPSEST-MPL LICENSE VERSION 1.0 -================================================================================ - -File-level copyleft with ethical use and quantum-safe provenance - -Based on Mozilla Public License 2.0 - --------------------------------------------------------------------------------- -PREAMBLE --------------------------------------------------------------------------------- - -This License extends the Mozilla Public License 2.0 (MPL-2.0) with provisions -for ethical use, post-quantum cryptographic provenance, and emotional lineage -protection. The base MPL-2.0 terms apply except where explicitly modified by -the Exhibits below. - -Like a palimpsest manuscript where each layer builds upon what came before, -this license recognizes that creative works carry history, context, and meaning -that transcend mere code or text. - --------------------------------------------------------------------------------- -SECTION 1: BASE LICENSE --------------------------------------------------------------------------------- - -This License incorporates the full text of Mozilla Public License 2.0 by -reference. The complete MPL-2.0 text is available at: -https://www.mozilla.org/en-US/MPL/2.0/ - -All terms, conditions, and definitions from MPL-2.0 apply except where -explicitly modified by the Exhibits in this License. - --------------------------------------------------------------------------------- -SECTION 2: ADDITIONAL DEFINITIONS --------------------------------------------------------------------------------- - -2.1. "Emotional Lineage" - means the narrative, cultural, symbolic, and contextual meaning embedded - in Covered Software, including but not limited to: protest traditions, - cultural heritage, trauma narratives, and community stories. - -2.2. "Provenance Metadata" - means cryptographically signed attribution information attached to or - associated with Covered Software, including author identities, timestamps, - modification history, and lineage references. - -2.3. "Non-Interpretive System" - means any automated system that processes Covered Software without - preserving or considering its Emotional Lineage, including but not - limited to: AI training pipelines, content aggregators, and automated - summarization tools. - -2.4. "Quantum-Safe Signature" - means a cryptographic signature using algorithms resistant to attacks - by quantum computers, as specified in Exhibit B. - --------------------------------------------------------------------------------- -SECTION 3: ETHICAL USE REQUIREMENTS --------------------------------------------------------------------------------- - -In addition to the rights and obligations under MPL-2.0: - -3.1. Emotional Lineage Preservation - You must make reasonable efforts to preserve and communicate the - Emotional Lineage of Covered Software when distributing or creating - derivative works. This includes maintaining narrative context, cultural - attributions, and symbolic meaning where documented. - -3.2. Non-Interpretive System Notice - If You use Covered Software as input to a Non-Interpretive System, You - must: - (a) document such use in a publicly accessible manner; and - (b) not claim that outputs of such systems carry the Emotional Lineage - of the original work without explicit permission from Contributors. - -3.3. Ethical Use Declaration - Commercial use of Covered Software requires acknowledgment that You have - read and understood Exhibit A (Ethical Use Guidelines) and agree to act - in good faith accordance with its principles. - -See Exhibit A for complete Ethical Use Guidelines. - --------------------------------------------------------------------------------- -SECTION 4: PROVENANCE REQUIREMENTS --------------------------------------------------------------------------------- - -4.1. Metadata Preservation - You must not strip, alter, or obscure Provenance Metadata from Covered - Software except where technically necessary and with clear documentation - of any changes. - -4.2. Quantum-Safe Provenance (Optional) - Contributors may sign their Contributions using Quantum-Safe Signatures. - If Quantum-Safe Signatures are present, You must preserve them in all - distributions. - -4.3. Lineage Chain - When creating derivative works, You should extend the provenance chain - to include Your own contributions, maintaining cryptographic linkage to - prior Contributors where feasible. - -See Exhibit B for Quantum-Safe Provenance specifications. - --------------------------------------------------------------------------------- -SECTION 5: GOVERNANCE --------------------------------------------------------------------------------- - -5.1. Stewardship Council - This License is maintained by the Palimpsest Stewardship Council, which - may issue clarifications, interpretive guidance, and future versions. - -5.2. Version Selection - You may use Covered Software under this version of the License or any - later version published by the Palimpsest Stewardship Council. - -5.3. Dispute Resolution - Disputes regarding interpretation of Ethical Use Requirements (Section 3) - should first be submitted to the Palimpsest Stewardship Council for - non-binding guidance before pursuing legal remedies. - --------------------------------------------------------------------------------- -SECTION 6: COMPATIBILITY --------------------------------------------------------------------------------- - -6.1. MPL-2.0 Compatibility - Covered Software under this License may be combined with software under - MPL-2.0. The combined work must comply with both licenses. - -6.2. Secondary Licenses - The Secondary License provisions of MPL-2.0 Section 3.3 apply to this - License. - --------------------------------------------------------------------------------- -EXHIBITS --------------------------------------------------------------------------------- - -Exhibit A - Ethical Use Guidelines -Exhibit B - Quantum-Safe Provenance Specification - -See separate files: -- EXHIBIT-A-ETHICAL-USE.txt -- EXHIBIT-B-QUANTUM-SAFE.txt - --------------------------------------------------------------------------------- -END OF PALIMPSEST-MPL LICENSE VERSION 1.0 --------------------------------------------------------------------------------- - -For questions about this License: -- Repository: https://github.com/hyperpolymath/palimpsest-license -- Council: contact via repository Issues diff --git a/aletheia/LICENSES/CC-BY-SA-4.0.txt b/aletheia/LICENSES/CC-BY-SA-4.0.txt deleted file mode 100644 index 2d58298..0000000 --- a/aletheia/LICENSES/CC-BY-SA-4.0.txt +++ /dev/null @@ -1,428 +0,0 @@ -Attribution-ShareAlike 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-ShareAlike 4.0 International Public -License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - l. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - m. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - including for purposes of Section 3(b); and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. - diff --git a/aletheia/LICENSES/PMPL-1.0-or-later.txt b/aletheia/LICENSES/PMPL-1.0-or-later.txt deleted file mode 100644 index f639385..0000000 --- a/aletheia/LICENSES/PMPL-1.0-or-later.txt +++ /dev/null @@ -1,162 +0,0 @@ -SPDX-License-Identifier: PMPL-1.0-or-later -SPDX-FileCopyrightText: 2025 Palimpsest Stewardship Council - -================================================================================ -PALIMPSEST-MPL LICENSE VERSION 1.0 -================================================================================ - -File-level copyleft with ethical use and quantum-safe provenance - -Based on Mozilla Public License 2.0 - --------------------------------------------------------------------------------- -PREAMBLE --------------------------------------------------------------------------------- - -This License extends the Mozilla Public License 2.0 (MPL-2.0) with provisions -for ethical use, post-quantum cryptographic provenance, and emotional lineage -protection. The base MPL-2.0 terms apply except where explicitly modified by -the Exhibits below. - -Like a palimpsest manuscript where each layer builds upon what came before, -this license recognizes that creative works carry history, context, and meaning -that transcend mere code or text. - --------------------------------------------------------------------------------- -SECTION 1: BASE LICENSE --------------------------------------------------------------------------------- - -This License incorporates the full text of Mozilla Public License 2.0 by -reference. The complete MPL-2.0 text is available at: -https://www.mozilla.org/en-US/MPL/2.0/ - -All terms, conditions, and definitions from MPL-2.0 apply except where -explicitly modified by the Exhibits in this License. - --------------------------------------------------------------------------------- -SECTION 2: ADDITIONAL DEFINITIONS --------------------------------------------------------------------------------- - -2.1. "Emotional Lineage" - means the narrative, cultural, symbolic, and contextual meaning embedded - in Covered Software, including but not limited to: protest traditions, - cultural heritage, trauma narratives, and community stories. - -2.2. "Provenance Metadata" - means cryptographically signed attribution information attached to or - associated with Covered Software, including author identities, timestamps, - modification history, and lineage references. - -2.3. "Non-Interpretive System" - means any automated system that processes Covered Software without - preserving or considering its Emotional Lineage, including but not - limited to: AI training pipelines, content aggregators, and automated - summarization tools. - -2.4. "Quantum-Safe Signature" - means a cryptographic signature using algorithms resistant to attacks - by quantum computers, as specified in Exhibit B. - --------------------------------------------------------------------------------- -SECTION 3: ETHICAL USE REQUIREMENTS --------------------------------------------------------------------------------- - -In addition to the rights and obligations under MPL-2.0: - -3.1. Emotional Lineage Preservation - You must make reasonable efforts to preserve and communicate the - Emotional Lineage of Covered Software when distributing or creating - derivative works. This includes maintaining narrative context, cultural - attributions, and symbolic meaning where documented. - -3.2. Non-Interpretive System Notice - If You use Covered Software as input to a Non-Interpretive System, You - must: - (a) document such use in a publicly accessible manner; and - (b) not claim that outputs of such systems carry the Emotional Lineage - of the original work without explicit permission from Contributors. - -3.3. Ethical Use Declaration - Commercial use of Covered Software requires acknowledgment that You have - read and understood Exhibit A (Ethical Use Guidelines) and agree to act - in good faith accordance with its principles. - -See Exhibit A for complete Ethical Use Guidelines. - --------------------------------------------------------------------------------- -SECTION 4: PROVENANCE REQUIREMENTS --------------------------------------------------------------------------------- - -4.1. Metadata Preservation - You must not strip, alter, or obscure Provenance Metadata from Covered - Software except where technically necessary and with clear documentation - of any changes. - -4.2. Quantum-Safe Provenance (Optional) - Contributors may sign their Contributions using Quantum-Safe Signatures. - If Quantum-Safe Signatures are present, You must preserve them in all - distributions. - -4.3. Lineage Chain - When creating derivative works, You should extend the provenance chain - to include Your own contributions, maintaining cryptographic linkage to - prior Contributors where feasible. - -See Exhibit B for Quantum-Safe Provenance specifications. - --------------------------------------------------------------------------------- -SECTION 5: GOVERNANCE --------------------------------------------------------------------------------- - -5.1. Stewardship Council - This License is maintained by the Palimpsest Stewardship Council, which - may issue clarifications, interpretive guidance, and future versions. - -5.2. Version Selection - You may use Covered Software under this version of the License or any - later version published by the Palimpsest Stewardship Council. - -5.3. Dispute Resolution - Disputes regarding interpretation of Ethical Use Requirements (Section 3) - should first be submitted to the Palimpsest Stewardship Council for - non-binding guidance before pursuing legal remedies. - --------------------------------------------------------------------------------- -SECTION 6: COMPATIBILITY --------------------------------------------------------------------------------- - -6.1. MPL-2.0 Compatibility - Covered Software under this License may be combined with software under - MPL-2.0. The combined work must comply with both licenses. - -6.2. Secondary Licenses - The Secondary License provisions of MPL-2.0 Section 3.3 apply to this - License. - --------------------------------------------------------------------------------- -EXHIBITS --------------------------------------------------------------------------------- - -Exhibit A - Ethical Use Guidelines -Exhibit B - Quantum-Safe Provenance Specification - -See separate files: -- EXHIBIT-A-ETHICAL-USE.txt -- EXHIBIT-B-QUANTUM-SAFE.txt - --------------------------------------------------------------------------------- -END OF PALIMPSEST-MPL-1.0 LICENSE TEXT --------------------------------------------------------------------------------- - -For exhibits, specifications, provenance rules, and governance: -https://github.com/hyperpolymath/palimpsest-license - -For legal frameworks and jurisdictional analysis: -See /legal/frameworks/ - -For provenance and audit tooling: -See /tools/ and /spec/PROVENANCE-SPEC.adoc - -For questions about this License: -- Repository: https://github.com/hyperpolymath/palimpsest-license -- Council: contact via repository Issues diff --git a/aletheia/MAINTAINERS.adoc b/aletheia/MAINTAINERS.adoc deleted file mode 100644 index e78e76a..0000000 --- a/aletheia/MAINTAINERS.adoc +++ /dev/null @@ -1,195 +0,0 @@ -== Maintainers - -This document lists the maintainers of the Aletheia project and -describes the governance structure. - -=== 🏛️ Governance Model - -Aletheia follows a *benevolent dictator governance model with maintainer -delegation*: - -* *Project Lead*: Makes final decisions on project direction -* *Core Maintainers*: Review and merge contributions -* *Contributors*: Submit improvements and feedback - -=== 👥 Current Maintainers - -==== Project Lead - -*hyperpolymath* - *Role*: Project vision, final decision authority - -*GitLab*: @hyperpolymath - *Email*: hyperpolymath@maa-framework.org - -*Timezone*: Global - *Focus Areas*: Architecture, RSR compliance, -community, Hyperpolymath Standard - -==== Core Maintainers - -*MAA Framework Contributors* - *Role*: Code review, merge authority - -*GitLab*: @maa-framework - *Email*: maintainers@maa-framework.org - -*Timezone*: Global - *Focus Areas*: Rust implementation, testing, -documentation - -_Contributors are welcome! See CONTRIBUTING.md for how to get involved._ - -=== 🎯 Maintainer Responsibilities - -==== Code Review - -* Review merge requests within 7 days -* Ensure RSR Bronze-level compliance -* Verify tests pass and code quality standards are met -* Provide constructive feedback - -==== Issue Triage - -* Label issues appropriately (`+bug+`, `+enhancement+`, -`+documentation+`, etc.) -* Assign priority levels (`+critical+`, `+high+`, `+medium+`, `+low+`) -* Close duplicate or resolved issues -* Link related issues and merge requests - -==== Release Management - -* Tag releases following semantic versioning -* Update CHANGELOG.md -* Build and verify release artifacts -* Announce releases to community - -==== Community Leadership - -* Welcome new contributors -* Enforce Code of Conduct -* Foster inclusive environment -* Mentor contributors - -=== 🌱 Becoming a Maintainer - -Maintainers are invited based on sustained, high-quality contributions. -Typical criteria: - -[arabic] -. *Sustained Contributions*: 10+ merged MRs over 3+ months -. *Code Quality*: Consistent adherence to standards -. *Community Engagement*: Helpful in issues and discussions -. *Alignment*: Understanding of RSR principles and project goals -. *Availability*: Able to commit 2-4 hours/week to maintenance - -==== Nomination Process - -[arabic] -. *Self-nomination or peer nomination*: Open an issue titled -"`Maintainer Nomination: [Name]`" -. *Discussion*: Existing maintainers discuss contribution history and -fit -. *Vote*: Maintainers vote (simple majority required) -. *Onboarding*: New maintainer added to this document and granted -repository access - -=== 🔐 Maintainer Permissions - -==== Repository Access - -* *Write access*: Push to non-protected branches -* *Merge access*: Merge approved merge requests -* *Release access*: Create tags and releases -* *Settings access*: Manage labels, milestones, CI/CD - -==== Communication Channels - -* Access to maintainer email list -* Private maintainer discussion forum (if established) -* Authority to speak on behalf of project (with coordination) - -=== 📋 Decision-Making Process - -==== Minor Decisions - -* *Scope*: Bug fixes, documentation updates, minor features -* *Process*: Single maintainer approval sufficient -* *Timeline*: Decide within 7 days - -==== Major Decisions - -* *Scope*: Breaking changes, architecture changes, new dependencies -* *Process*: Discussion among all maintainers, consensus preferred -* *Timeline*: Minimum 14-day discussion period -* *Fallback*: Project lead makes final decision if consensus cannot be -reached - -==== Emergency Decisions - -* *Scope*: Critical security fixes, severe bugs -* *Process*: Any maintainer can act immediately -* *Follow-up*: Notify other maintainers within 24 hours - -=== 🚪 Stepping Down - -Maintainers may step down at any time: - -[arabic] -. *Notification*: Email other maintainers with 30-day notice (if -possible) -. *Transition*: Hand off ongoing responsibilities -. *Emeritus Status*: Retain advisory role and recognition -. *Repository Access*: Access revoked, can be restored if returning - -==== Emeritus Maintainers - -Former maintainers who have stepped down with recognition: - -_None yet - Aletheia is a new project!_ - -=== 🔄 Inactive Maintainer Policy - -If a maintainer is unresponsive for 90+ days: - -[arabic] -. *Outreach*: Other maintainers attempt contact via email -. *Grace Period*: 30 additional days for response -. *Temporary Removal*: Repository access temporarily revoked -. *Reinstatement*: Access restored upon return and re-engagement - -=== 🎓 Mentorship - -Maintainers are encouraged to mentor potential future maintainers: - -* Review contributions with detailed feedback -* Suggest areas for contribution -* Invite to maintainer discussions (when appropriate) -* Share knowledge of project history and architecture - -=== 📊 Maintainer Activity - -We track maintainer activity to ensure the project remains -well-maintained: - -* Monthly review of open issues and merge requests -* Quarterly review of maintainer engagement -* Annual review of governance structure - -=== 🌐 TPCF Alignment - -Maintainers operate across all TPCF perimeters: - -* *Perimeter 1 (Inner Sanctum)*: Full access to all project resources -* *Perimeter 2 (Trusted Contributors)*: Ability to promote active -contributors -* *Perimeter 3 (Community Sandbox)*: Steward open contribution process - -=== 📞 Contact Maintainers - -* *General*: maintainers@maa-framework.org -* *Security*: security@maa-framework.org -* *Code of Conduct*: conduct@maa-framework.org -* *GitLab*: Mention @maintainers in issues/MRs - -=== 🙏 Acknowledgments - -Thank you to all maintainers for their dedication to Aletheia and the -pursuit of _alētheia_ - the unconcealment of truth. - -''''' - -*Last Updated*: 2025-11-22 *Version*: 1.0 - -_This document will be updated as the maintainer team grows and -governance evolves._ diff --git a/aletheia/Mustfile b/aletheia/Mustfile deleted file mode 100644 index 5f07541..0000000 --- a/aletheia/Mustfile +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Mustfile - hyperpolymath mandatory checks -# See: https://github.com/hyperpolymath/mustfile - -version: 1 - -checks: - - name: security - run: just lint - - name: tests - run: just test - - name: format - run: just fmt diff --git a/aletheia/PALIMPSEST.adoc b/aletheia/PALIMPSEST.adoc deleted file mode 100644 index fd219d0..0000000 --- a/aletheia/PALIMPSEST.adoc +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Palimpsest License -:toc: -:toc-placement!: - -image:https://img.shields.io/badge/License-MPL--2.0-blue.svg[License: PMPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] -image:https://img.shields.io/badge/Philosophy-Palimpsest-indigo.svg[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"] - -toc::[] - -== Legal Status - -This project is licensed under the **Palimpsest-MPL License 1.0 (PMPL-1.0)**. -For SPDX and tooling, use **MPL-2.0**. - -PMPL-1.0 incorporates the Mozilla Public License 2.0 by reference and adds -ethical-use, provenance, and lineage requirements. - -== What PMPL Adds - -* **Emotional Lineage** - preserve narrative intent and cultural context -* **Provenance Integrity** - retain attribution and lineage metadata -* **Ethical Use Constraints** - explicit consent for non-interpretive AI training -* **Quantum-Safe Provenance (optional)** - post-quantum signature support - -== How to Adopt - -1. Include the PMPL-1.0 license text in `LICENSE`. -2. Add SPDX headers to source files: - `SPDX-License-Identifier: CC-BY-SA-4.0` -3. Add a Palimpsest badge to your README (see `assets/badges/` and `embed/license-blocks/`). - -== Versioning - -See `VERSIONING.adoc` for the release process and the "-or-later" model. -The current legal text is PMPL-1.0. - -== References - -* `legal/README.adoc` -* `assets/badges/README.md` -* `embed/license-blocks/README.md` diff --git a/aletheia/PROJECT_STATUS.adoc b/aletheia/PROJECT_STATUS.adoc deleted file mode 100644 index 04759ec..0000000 --- a/aletheia/PROJECT_STATUS.adoc +++ /dev/null @@ -1,119 +0,0 @@ -== Aletheia Project Status - -*Version*: 1.9.0 *Status*: Stable / Maintenance *Last Updated*: -2026-09-21 - -=== Project Overview - -Aletheia is a zero-dependency Rust tool for verifying Rhodium Standard -Repository (RSR) compliance. Also serves as precursor research for -reversible operating systems (r-Minix). - -=== Completion Status - -==== Core Implementation (100% Complete) - -* *Main Application* (`+src/main.rs+`) -** ~3,800 lines of safe Rust code (measured 2026-09-21) -** Zero dependencies -** Zero unsafe blocks -** 66 unit tests + 45 integration tests (111 total, 100% pass) -** 100% test pass rate -** RSR v2 offline-subset verification (26 checks: 13 Bronze, 12 Silver, 1 Gold) -** CLI with human, JSON, SARIF, HTML, badge, quiet, verbose output + `.aletheia.toml` config -** Symlink detection and security warnings -** Verification timestamps - -==== Documentation (100% Complete) - -*Required Documentation*: - `+README.adoc+` - Project overview -(AsciiDoc) - `+LICENSE+` - Palimpsest License (MPL-2.0) - -`+SECURITY.md+` - Security policy and disclosure - `+CONTRIBUTING.md+` / -`+../.github/CONTRIBUTING.md+` - Contribution guidelines - `+CODE_OF_CONDUCT.md+` -- Community standards - `+MAINTAINERS.md+` / `+MAINTAINERS.adoc+` - -Governance structure - `+CHANGELOG.md+` / `+CHANGELOG.adoc+` - Version -history - -*Additional Documentation*: - `+CLAUDE.md+` - AI assistant development -guide - `+PROJECT_STATUS.md+` - This file - `+ALETHEIA-HANDOVER.md+` - -Project handover document - `+CROSSREPO-HANDOVER.md+` - Ecosystem -documentation - `+ROADMAP.adoc+` - Development roadmap - `+docs/+` - -Architecture, specifications, FAQ, quick start - -==== .well-known Directory (100% Complete) - -* `+.well-known/security.txt+` - RFC 9116 compliant -* `+.well-known/ai.txt+` - AI training policies -* `+.well-known/humans.txt+` - Human attribution - -==== Build System (100% Complete) - -* `+Cargo.toml+` - Zero dependencies, MSRV 1.80 -* `+Cargo.lock+` - Reproducible builds -* `+Justfile+` - Crate recipes (the root Justfile is canonical, wired to CI) -* `+.gitlab-ci.yml+` - Present for the GitLab mirror; the live gate is the root `+rust-ci.yml+` -* `+.github/workflows/+` - 16 files, ALL INERT (live gates live at the repo root) - -==== Source Structure (100% Complete) - -* `+src/+` - Source code -* `+tests/+` - Integration tests -* `+benches/+` - Performance benchmarks -* `+examples/+` - Usage examples -* `+docs/+` - Documentation -* `+fuzz/+` - Fuzzing infrastructure - -=== RSR Bronze Compliance - -*Self-Verification Result* (measured 2026-09-21): Bronze-level RSR -compliance ACHIEVED — 13/13 Bronze checks in the v2 offline subset pass -(23/26 overall; the 3 gaps are Silver: `+.tool-versions+`, -`+0-AI-MANIFEST.a2ml+`, `+rsr-profile.a2ml+`, which live at the repo -root, not in the vendored crate tree). - -=== Code Metrics - -[cols=",",options="header",] -|=== -|Metric |Value -|Lines of Rust (main, measured) |~3,800 -|Lines of Rust (tests, measured) |~1,240 -|Dependencies |0 -|Unsafe Blocks |0 -|Unit Tests |66 -|Integration Tests |45 -|Clippy Warnings |0 -|Format Issues |0 -|=== - -=== Security Posture - -* *Attack Surface*: Minimal (~3,800 lines, zero dependencies, `#![forbid(unsafe_code)]`) -* *Supply Chain Risk*: None (zero dependencies) -* *Memory Safety*: 100% (Rust ownership, zero unsafe) -* *Network Access*: None (offline-first) - -=== Next Steps - -==== Short-term - -[arabic] -. Tag a release from the current tree (crate is at 1.9.0, untagged) -. Publish to crates.io (optional) - -*Shipped 2026-09-21 (were medium-term):* SARIF output, `+.aletheia.toml+` -configuration, Silver-level RSR checks. - -==== Open - -[arabic] -. Custom check definitions - -''''' - -*Status Summary*: *Stable* - -Aletheia v1.9.0 is feature-complete, well-tested, fully documented, and -achieves Bronze-level RSR compliance on itself. - -_"`Aletheia: Unconcealing the truth in repository standards.`"_ diff --git a/aletheia/QUICK_REFERENCE.adoc b/aletheia/QUICK_REFERENCE.adoc deleted file mode 100644 index 12b53f7..0000000 --- a/aletheia/QUICK_REFERENCE.adoc +++ /dev/null @@ -1,230 +0,0 @@ -== Aletheia Quick Reference Card - -One-page reference for Aletheia RSR compliance verification (v1.9.0, -2026-09-21). Aletheia evaluates the *offline file-presence subset* of the -RSR v2 criteria (26 checks); the hypatia `rsr-conformance` oracle stays -normative. Criteria source: `hyperpolymath/standards` -`0-canon/rsr/rsr-criteria-v2.a2ml`. - -=== 🚀 Installation - -[source,bash] ----- -# Build from source (aletheia is vendored in maa-framework) -git clone https://github.com/hyperpolymath/maa-framework.git -cd maa-framework/aletheia && cargo build --release -# binary: target/release/aletheia (zero dependencies, MSRV 1.80) - -# Or run the installer (same steps, installs to ~/.local/bin) -bash scripts/install.sh ----- - -=== 💻 Usage - -[source,bash] ----- -# Verify current directory (human report, Bronze gate) -aletheia - -# Verify a specific repository -aletheia /path/to/repo - -# Machine-readable output -aletheia --format json /path/to/repo -aletheia --format sarif . > results.sarif -aletheia --badge . > badge.svg # SVG compliance badge -aletheia -q . # quiet: prints only PASS or FAIL -aletheia -v . # verbose: suggestions, tiers, SSOT note - -# Config file (default: /.aletheia.toml) -aletheia --config my.toml . - -# Install a pre-commit hook that runs aletheia -aletheia init-hook /path/to/repo ----- - -=== ✅ The 26 checks (RSR v2 offline subset) - -==== Bronze (13 — the gate) - -* [ ] `scm-github` — `.github/` directory -* [ ] `justfile` — Justfile with real recipes -* [ ] `no-makefile` — no Makefile / Dockerfile -* [ ] `readme` — README.adoc (README.md accepted) -* [ ] `license-file` — LICENSE file (not LICENSE.txt) -* [ ] `security-policy` — SECURITY policy (root or .github/) -* [ ] `gitignore` — .gitignore + .gitattributes -* [ ] `spdx-headers` — SPDX headers on source files -* [ ] `no-secrets` — no committed secrets / key material -* [ ] `language-policy` — no banned languages -* [ ] `no-node-runtime` — no package.json runtime deps (Bun lockfile carves out) -* [ ] `ci-present` — CI pipeline under .github/workflows/ -* [ ] `licence-class` — LICENSE names a recognized identifier - -==== Silver (12 — reported, non-fatal at the default gate) - -* [ ] `editorconfig`, `tool-versions` -* [ ] `coc` — CODE_OF_CONDUCT (root or .github/) -* [ ] `contributing` — CONTRIBUTING (root or .github/) -* [ ] `changelog` — CHANGELOG.adoc (or .md) -* [ ] `wellknown-core` — .well-known/{security.txt,ai.txt,humans.txt} -* [ ] `ai-manifest` — 0-AI-MANIFEST.a2ml -* [ ] `rsr-profile` — .machine_readable/rsr-profile.a2ml -* [ ] `sha-pinned` — actions pinned (full SHA, or tag covered by actions.lock) -* [ ] `hypatia-scan` — hypatia-scan.yml workflow -* [ ] `governance-wf` — governance.yml workflow -* [ ] `reuse` — LICENSES/ with full texts - -==== Gold (1) - -* [ ] `no-silent-skip` — no `|| echo SKIP` silent-green recipes - -Plus automatic critical warnings for symlinks escaping the repo root. - -=== 📊 Understanding Output - -.... -Aletheia - RSR Compliance Verification Report -Repository: /path/to/repo -Verified: 2026-09-21T20:05:37Z - -[Documentation] - ✅ README.adoc (or README.md) [Bronze] - ✅ LICENSE file (not LICENSE.txt) [Bronze] - ❌ SECURITY policy (root or .github/) [Bronze] - -Score: 25/26 checks passed (96.2%) -Bronze-level RSR compliance: NOT MET # Exit code 1 - -Fix Suggestions - [security-policy] Add SECURITY.md with disclosure contact + response timeline; v2 2.1.3. -.... - -*Exit Codes*: `0` — required tier achieved; `1` — tier not met; `2` — -critical warning (escaping symlink); `3` — usage/path/config error; -`4` — invalid arguments. Gate tier via `[aletheia] level` in config -(default `bronze`). - -=== 🛠️ Quick Fixes - -==== Missing Documentation - -[source,bash] ----- -# .adoc is primary, .md accepted; LICENSE (never LICENSE.txt) -touch README.adoc LICENSE SECURITY.md \ - CONTRIBUTING.md CODE_OF_CONDUCT.md CHANGELOG.adoc -touch .gitignore .gitattributes -mkdir -p LICENSES # full licence texts, REUSE style ----- - -==== Missing .well-known - -[source,bash] ----- -mkdir -p .well-known -cat > .well-known/security.txt << 'EOF' -Contact: mailto:security@example.org -Expires: 2027-12-31T23:59:59.000Z -EOF - -touch .well-known/ai.txt .well-known/humans.txt ----- - -==== Missing Build Files - -[source,bash] ----- -# Capital-J Justfile with real recipes (stubs fail the check) -cat > Justfile << 'EOF' -build: - cargo build --locked - -test: - cargo test --locked -EOF - -# CI lives at .github/workflows/ (repo root only) -mkdir -p .github/workflows ----- - -==== Missing Source/Machine-Readable - -[source,bash] ----- -mkdir -p src -touch 0-AI-MANIFEST.a2ml -mkdir -p .machine_readable && touch .machine_readable/rsr-profile.a2ml ----- - -=== 🔧 Config (.aletheia.toml) - -[source,toml] ----- -[aletheia] -level = "bronze" # gate tier: bronze | silver | gold - -[checks] -# Disable by check id, category, or tier alias: -# wellknown-core = false -# Machine-Readable = false -# silver = false - -[ignore] -files = ["CHANGELOG.adoc"] # glob patterns, repo-relative ----- - -=== 🔄 CI/CD Integration - -[source,yaml] ----- -# No published image or crate: build from the vendored tree. -- uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 -- run: cargo build --locked --release - working-directory: aletheia -- run: ./aletheia/target/release/aletheia -q . ----- - -=== 🆘 Troubleshooting - -[width="100%",cols="48%,52%",options="header",] -|=== -|Problem |Solution -|Path not found |Use an absolute path: `+aletheia /full/path+` - -|Permission denied |Check file permissions: `+ls -la+` - -|Wrong directory |Run from the repo root, or pass the path - -|Exit code 2 |An escaping symlink was found — inspect before overriding - -|Missing tool |Install Rust: -`+curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs \| sh+` -|=== - -=== 📚 More Information - -* *AI guide*: `+CLAUDE.md+` (setup, gates, module layout) -* *Status*: `+PROJECT_STATUS.adoc+` -* *Architecture*: `+docs/ARCHITECTURE.adoc+` -* *Quick Start*: `+docs/QUICK_START.adoc+` -* *FAQ*: `+docs/FAQ.adoc+` -* *Silver level*: `+docs/SILVER-LEVEL.adoc+` - -=== 🔗 Links - -* *Repository*: -https://github.com/hyperpolymath/maa-framework/tree/main/aletheia -* *Issues*: https://github.com/hyperpolymath/maa-framework/issues -* *Security*: See `+SECURITY.md+` and `+.well-known/security.txt+` - -=== 📞 Contact - -* *Security*: security@maa-framework.org - -''''' - -*Version*: 1.9.0 | *RSR Level*: Bronze (self-verified) + Silver checks | -*License*: PMPL-1.0-or-later (code) + CC-BY-SA-4.0 (docs), see LICENSE — -under review, see the `aletheia-licence` open question in the root -STATE.a2ml diff --git a/aletheia/README.adoc b/aletheia/README.adoc deleted file mode 100644 index 45e8a55..0000000 --- a/aletheia/README.adoc +++ /dev/null @@ -1,292 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Aletheia - -image:https://img.shields.io/badge/License-MPL--2.0-blue.svg[License: PMPL-1.0,link="https://github.com/hyperpolymath/palimpsest-license"] -image:https://img.shields.io/badge/Philosophy-Palimpsest-indigo.svg[Palimpsest,link="https://github.com/hyperpolymath/palimpsest-license"] - - -Jonathan D. A. Jewell -:toc: left -:toclevels: 3 -:sectnums: -:icons: font - -image::https://img.shields.io/badge/RSR-Bronze-cd7f32[Rhodium Standard Bronze,link=https://github.com/hyperpolymath/rhodium-standard-repositories] - -[quote, Heidegger on Aletheia] -____ -*Ἀλήθεια* (alētheia) - Greek: "truth", "disclosure", "unconcealment" - -The unconcealment of what was previously hidden; the bringing-forth of truth from concealment. -____ - -== What is Aletheia? - -*Aletheia* is a research project exploring *reversible system operations* - the precursor work required before undertaking a full rewrite of Minix into a modern, reversible operating system (*r-Minix*). - -=== The Central Question - -[quote] -____ -Can every system operation be undone? Can we prove that `operation ;; reverse(operation) ≡ nothing`? -____ - -This is not just about "undo" functionality. It's about *formal guarantees* that: - -* Every operation has a well-defined inverse -* The composition of an operation with its inverse is provably a null operation (CNO) -* System state can always be recovered -* No information is irreversibly destroyed - -=== Connection to Absolute Zero - -Aletheia builds on the theoretical foundations established in link:https://github.com/hyperpolymath/absolute-zero[Absolute Zero], which formally proves properties of *Certified Null Operations (CNOs)*: - -[source] ----- -∀ σ : State, ∀ op : Operation, - IsReversible(op) ↔ ( - ∃ op_inv : Operation, - (op ;; op_inv) ≡ CNO ∧ - (op_inv ;; op) ≡ CNO - ) ----- - -Where Absolute Zero proves that certain operations do *nothing*, Aletheia explores operations that *do something but can be undone*. - -== Ecosystem Architecture - -[source] ----- -┌─────────────────────────────────────────────────────────────────────┐ -│ ABSOLUTE ZERO │ -│ Formal proofs: op ;; reverse(op) ≡ CNO │ -│ │ -│ Coq │ Lean 4 │ Z3 │ Agda │ Isabelle │ -│ Phase 1: 100% │ Phase 2-4: 70% │ -└─────────────────────────────────────────────────────────────────────┘ - │ - │ proves - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ PRACTICAL IMPLEMENTATIONS │ -│ │ -│ ┌───────────────────┐ ┌───────────────────────────┐ │ -│ │ VALENCE SHELL │ │ ALETHEIA │ │ -│ │ │ │ (this project) │ │ -│ │ Reversible │ │ │ │ -│ │ Filesystem │ │ Reversible System Ops │ │ -│ │ │ │ Precursor to r-Minix │ │ -│ │ • mkdir/rmdir │ │ │ │ -│ │ • create/unlink │ │ • Process operations │ │ -│ │ • read/write │ │ • IPC mechanisms │ │ -│ │ │ │ • Memory management │ │ -│ └───────────────────┘ │ • Signal handling │ │ -│ └───────────────────────────┘ │ -└─────────────────────────────────────────────────────────────────────┘ - │ - │ enables - ▼ -┌─────────────────────────────────────────────────────────────────────┐ -│ r-MINIX (FUTURE) │ -│ │ -│ Full reversible Minix rewrite in modern stack │ -│ Rust │ ReScript │ Formally verified │ All syscalls reversible │ -└─────────────────────────────────────────────────────────────────────┘ ----- - -== Research Areas - -=== 1. Process Reversibility - -Can process creation and termination be made reversible? - -[source] ----- -fork() ;; wait() ≡ CNO ? -exec() ;; exit() ≡ CNO ? ----- - -*Challenges*: - -* Process state capture and restoration -* Resource cleanup verification -* Signal handling during reversal - -=== 2. IPC Reversibility - -Can inter-process communication be undone? - -[source] ----- -send(msg) ;; receive() ≡ CNO ? -signal(SIGTERM) ;; ??? ≡ CNO ? ----- - -*Challenges*: - -* Message ordering and causality -* Buffered vs unbuffered channels -* Broadcast/multicast reversal - -=== 3. Memory Reversibility - -Can memory operations be made reversible? - -[source] ----- -mmap() ;; munmap() ≡ CNO ? -brk(+n) ;; brk(-n) ≡ CNO ? ----- - -*Challenges*: - -* Copy-on-write semantics -* Shared memory across processes -* Memory-mapped I/O - -=== 4. System Call Abstraction - -Defining a reversible system call interface: - -[source,rust] ----- -trait ReversibleSyscall { - type State; - type Inverse: ReversibleSyscall; - - fn execute(&self, state: &mut State) -> Result<(), Error>; - fn inverse(&self) -> Self::Inverse; - - // Proof obligation: execute ;; inverse.execute ≡ identity - fn proof_reversible(&self) -> Proof; -} ----- - -== Design Principles - -1. *Formal First* - Every operation must have a formal reversibility proof -2. *Absolute Zero Compatible* - Uses CNO definitions from Absolute Zero -3. *Minix Inspired* - Microkernel architecture, minimal trusted base -4. *Modern Stack* - Rust, ReScript, Deno (per Hyperpolymath standards) -5. *Zero Unsafe* - Except where absolutely required for syscalls - -== Project Status - -[cols="1,2,1"] -|=== -|Phase |Description |Status - -|0. Research -|Literature review, Minix analysis, reversibility theory -|🔄 In Progress - -|1. Foundations -|Core reversibility types and proofs -|📋 Planned - -|2. Filesystem -|Integration with Valence Shell -|📋 Planned - -|3. Process -|Reversible process management -|📋 Planned - -|4. IPC -|Reversible inter-process communication -|📋 Planned - -|5. Integration -|Full system integration, r-Minix prototype -|📋 Future -|=== - -== Related Projects - -[cols="1,2,1"] -|=== -|Project |Purpose |Link - -|*absolute-zero* -|Formal CNO verification (Coq/Lean/Z3) -|link:https://github.com/hyperpolymath/absolute-zero[GitHub] - -|*valence-shell* -|Reversible filesystem operations -|TBD - -|*r-Minix* -|Full reversible Minix (future goal) -|TBD -|=== - -== Quick Start - -[source,bash] ----- -# Clone -git clone https://github.com/hyperpolymath/aletheia.git -cd aletheia - -# Build (Rust) -cargo build - -# Run tests -cargo test - -# Explore proofs (requires Coq) -cd proofs && coqc Reversibility.v ----- - -== Contributing - -This is research-stage software. Contributions welcome in: - -* Formal proofs of reversibility properties -* Minix syscall analysis -* Reversibility literature survey -* Rust/AffineScript implementation - -See link:../.github/CONTRIBUTING.md[CONTRIBUTING.md] for guidelines. - -== License - -Dual-licensed under MIT and Palimpsest v0.8. See link:LICENSE.txt[LICENSE.txt]. - -== References - -=== Theoretical Foundations - -* Landauer, R. (1961). "Irreversibility and Heat Generation in Computing" -* Bennett, C. (1973). "Logical Reversibility of Computation" -* Absolute Zero project - Formal CNO verification - -=== Operating Systems - -* Tanenbaum, A. - MINIX design and implementation -* seL4 - Formally verified microkernel -* Redox OS - Rust-based microkernel - -=== Reversible Computing - -* Thomsen, M. K. - Reversible computing languages -* Yokoyama, T. - Janus reversible programming language - -== Contact - -*Jonathan D. A. Jewell* - -* GitLab: link:https://gitlab.com/hyperpolymath[@hyperpolymath] -* GitHub: link:https://github.com/Hyperpolymath[@Hyperpolymath] -* Email: jonathan@metadatastician.art - ---- - -[quote, Parmenides] -____ -"For it is the same thing to think and to be." -____ - -_What can be computed can be unconcealed. What is unconcealed reveals its reversibility._ diff --git a/aletheia/ROADMAP.adoc b/aletheia/ROADMAP.adoc deleted file mode 100644 index 297744a..0000000 --- a/aletheia/ROADMAP.adoc +++ /dev/null @@ -1,309 +0,0 @@ -== Aletheia Roadmap: MVP to v10.0.0 - -This document outlines the complete development roadmap for Aletheia, -from the current MVP to the long-term vision of v10.0.0. - -=== Philosophy - -*Aletheia* (Greek: truth, disclosure, unconcealment) embodies the -principle that repository compliance should be: - *Verifiable*: -Automated, reproducible checks - *Transparent*: Clear pass/fail criteria -- *Auditable*: Zero dependencies, single-file implementation - -*Trustworthy*: No network access, no data exfiltration - -''''' - -=== Current State: v0.1.x (MVP+) - -==== Status: Production Ready - -[cols=",",options="header",] -|=== -|Metric |Value -|Self-Verification |16/16 checks (100%) -|Dependencies |0 (zero) -|Unsafe Blocks |0 (zero) -|Lines of Code |~810 -|Unit Tests |10 -|Integration Tests |18 -|Security Audit |2025-12-26 (0 vulnerabilities) -|=== - -==== Completed Features - -* Bronze-level RSR verification -* CLI interface with distinct exit codes (0-4) -* Human-readable reports -* JSON output format (`+--format json+`) -* Quiet mode (`+-q+` / `+--quiet+`) -* Verbose mode (`+-v+` / `+--verbose+`) -* Help text (`+--help+`) and version (`+--version+`) -* Self-verification capability -* RFC 9116 security.txt compliance -* Nix flake for reproducible builds -* GitHub Actions workflow template -* Performance benchmarks -* Symlink detection and security warnings -* Verification timestamps (TOCTOU mitigation) -* Comprehensive documentation - -''''' - -=== Short-Term: v0.2.0 - v0.9.0 - -==== v0.2.0: Output Formats - -* [x] JSON output format (`+--format json+`) ✅ Completed -* [ ] SARIF output for CI/CD integration -* [x] Machine-readable exit codes (0-4) ✅ Completed -* [x] Quiet mode (`+--quiet+`) ✅ Completed -* [x] Verbose mode (`+--verbose+`) ✅ Completed - -==== v0.3.0: Configuration - -* [ ] `+.aletheia.toml+` configuration file -* [ ] Custom check definitions -* [ ] Ignore patterns for files -* [ ] Severity levels (error, warning, info) -* [ ] Custom compliance levels - -==== v0.4.0: Silver-Level RSR - -* [ ] Formal verification hooks -* [ ] Proof artifact detection -* [ ] Property-based testing validation -* [ ] Mutation testing integration -* [ ] Coverage thresholds - -==== v0.5.0: Performance & Scale - -* [ ] Parallel file checking -* [ ] Incremental verification (cache) -* [ ] Batch repository analysis -* [ ] Large repository optimization -* [ ] Memory-mapped file access - -==== v0.6.0: Multi-Language Support - -* [ ] Language detection -* [ ] Language-specific checks (Rust, Python, Go, etc.) -* [ ] Build system detection -* [ ] Test framework detection -* [ ] Linter configuration validation - -==== v0.7.0: Gold-Level RSR - -* [ ] Multi-language repository support -* [ ] Polyglot build systems -* [ ] Cross-language dependency verification -* [ ] Interface contract checking -* [ ] API compatibility validation - -==== v0.8.0: Reporting & Visualization - -* [ ] HTML report generation -* [ ] Compliance dashboard -* [ ] Trend tracking -* [ ] Badge generation -* [ ] CI integration (GitHub Actions, GitLab CI) - -==== v0.9.0: Extensibility - -* [ ] Plugin architecture -* [ ] Custom check modules -* [ ] Language server protocol (LSP) support -* [ ] IDE integrations -* [ ] Pre-commit hooks - -''''' - -=== Medium-Term: v1.0.0 - v3.0.0 - -==== v1.0.0: Stable Release - -* [ ] Semantic versioning commitment -* [ ] API stability guarantee -* [x] Comprehensive documentation ✅ Completed -* [x] Performance benchmarks ✅ Completed -* [x] Security audit completed ✅ Completed (2025-12-26) -* [ ] crates.io publication - -==== v2.0.0: Platinum-Level RSR - -* [ ] CADRE integration -* [ ] Formal specification support -* [ ] Proof assistant integration (Lean, Coq) -* [ ] Property-based testing frameworks -* [ ] Mutation testing validation - -==== v3.0.0: Enterprise Features - -* [ ] SBOM (Software Bill of Materials) generation -* [ ] License compliance checking -* [ ] Vulnerability scanning (CVE database) -* [ ] SLSA provenance verification -* [ ] OpenSSF Scorecard integration - -''''' - -=== Long-Term: v4.0.0 - v10.0.0 - -==== v4.0.0: Distributed Verification - -* [ ] Remote repository verification -* [ ] Git-based verification (by commit hash) -* [ ] Distributed verification network -* [ ] Reproducible build verification -* [ ] Binary transparency - -==== v5.0.0: AI/ML Integration - -* [ ] Intelligent check suggestions -* [ ] Anomaly detection -* [ ] Code quality prediction -* [ ] Security vulnerability prediction -* [ ] Documentation completeness analysis - -==== v6.0.0: Ecosystem Integration - -* [ ] Package registry integration (crates.io, npm, PyPI) -* [ ] CI/CD platform integrations -* [ ] Issue tracker integration -* [ ] Pull request automation -* [ ] Dependency update automation - -==== v7.0.0: Governance & Community - -* [ ] Organization-wide policies -* [ ] Team compliance tracking -* [ ] Audit trail generation -* [ ] Compliance attestation -* [ ] Third-party audit support - -==== v8.0.0: Advanced Security - -* [ ] Supply chain attack detection -* [ ] Dependency confusion detection -* [ ] Typosquatting detection -* [ ] Malware signature scanning -* [ ] Behavioral analysis - -==== v9.0.0: Full TPCF Implementation - -* [ ] Perimeter 1: Inner Sanctum verification -* [ ] Perimeter 2: Trusted Contributors verification -* [ ] Perimeter 3: Community Sandbox verification -* [ ] Trust level propagation -* [ ] Reputation scoring - -==== v10.0.0: The Dream - -* [ ] Complete RSR compliance spectrum (Bronze to Diamond) -* [ ] Self-improving verification (ML-based) -* [ ] Global repository network -* [ ] Zero-knowledge compliance proofs -* [ ] Decentralized trust network -* [ ] Universal package verification -* [ ] Cross-ecosystem compatibility -* [ ] Real-time compliance monitoring -* [ ] Predictive compliance -* [ ] Full ecosystem health dashboard - -''''' - -=== Constraints (Non-Negotiable) - -These constraints apply to ALL versions: - -==== Zero Dependencies (Bronze Requirement) - -* *NEVER* add external crates -* Use only Rust standard library -* Implement functionality from scratch - -==== Zero Unsafe Code (Bronze Requirement) - -* *NEVER* use `+unsafe+` keyword -* No FFI calls -* No raw pointer operations - -==== Offline-First (Bronze Requirement) - -* *NEVER* make network requests -* Work entirely from local filesystem -* Air-gapped compatible - -==== Single Binary - -* *ALWAYS* produce a single, static binary -* No runtime dependencies -* Cross-compilation support - -''''' - -=== Contribution Opportunities - -==== Immediate (Good First Issues) - -[arabic] -. Add more unit tests for edge cases -. Improve error messages -. Add example repositories -. SARIF output format - -==== Intermediate - -[arabic] -. Configuration file support (`+.aletheia.toml+`) -. Language-specific checks -. HTML report generation -. Custom check definitions - -==== Advanced - -[arabic] -. Plugin architecture design -. Formal verification integration -. Silver-level RSR implementation -. Batch repository analysis - -''''' - -=== Success Metrics - -==== v1.0.0 Targets - -* 100+ repositories verified -* 10+ contributors -* Security audit completed -* Published on crates.io - -==== v5.0.0 Targets - -* 10,000+ repositories verified -* 50+ contributors -* Enterprise adoption -* Community ecosystem - -==== v10.0.0 Targets - -* 1M+ repositories verified -* Industry standard status -* Cross-ecosystem adoption -* Academic recognition - -''''' - -=== Resources - -* *Repository*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia -* *Documentation*: See `+docs/+` directory -* *Contributing*: See `+CONTRIBUTING.md+` -* *Security*: See `+SECURITY.md+` - -''''' - -*Version*: 1.1 *Last Updated*: 2025-12-26 - -_"`Truth in repository standards, one check at a time.`"_ diff --git a/aletheia/RSR-CONFORMITY.adoc b/aletheia/RSR-CONFORMITY.adoc deleted file mode 100644 index 18253da..0000000 --- a/aletheia/RSR-CONFORMITY.adoc +++ /dev/null @@ -1,45 +0,0 @@ -== RSR Conformity Statement - -*Project*: Aletheia *RSR Level*: Bronze *Standard*: -https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium -Standard Repository] *Last Verified*: 2025-12-26 - -=== Bronze Requirements Met - -[cols=",",options="header",] -|=== -|Requirement |Status -|Zero external dependencies |Yes -|Zero unsafe code |Yes -|Offline-first (no network) |Yes -|Documentation suite complete |Yes -|Security disclosure (RFC 9116) |Yes -|Build automation |Yes -|CI/CD pipeline |Yes -|Test suite |Yes -|=== - -=== Verification - -Run self-verification: - -[source,bash] ----- -cargo run ----- - -Expected output: `+16/16 checks passed (100.0%)+` - -=== Audits - -[cols=",,",options="header",] -|=== -|Date |Auditor |Result -|2025-12-26 |Security review |0 vulnerabilities -|=== - -''''' - -See the -https://github.com/hyperpolymath/rhodium-standard-repositories[RSR -specification] for full standard details. diff --git a/aletheia/RSR_OUTLINE.adoc b/aletheia/RSR_OUTLINE.adoc deleted file mode 100644 index cb8179d..0000000 --- a/aletheia/RSR_OUTLINE.adoc +++ /dev/null @@ -1,220 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.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"] -:toc: -:sectnums: - -// Badges -image:https://img.shields.io/badge/RSR-Infrastructure-cd7f32[RSR Infrastructure] -image:https://img.shields.io/badge/Phase-Maintenance-brightgreen[Phase] -image:https://img.shields.io/badge/Guix-Primary-purple?logo=gnu[Guix] - -== Overview - -**The canonical template for RSR (Rhodium Standard Repository) projects.** - -This repository provides the standardized structure, configuration, and tooling for all 139 repos in the hyperpolymath ecosystem. Use it to: - -* Bootstrap new projects with RSR compliance -* Reference the standard directory structure -* Copy configuration templates (Justfile, STATE.scm, etc.) - -== Quick Start - -[source,bash] ----- -# Clone the template -git clone https://github.com/hyperpolymath/RSR-template-repo my-project -cd my-project - -# Remove template git history -rm -rf .git -git init - -# Customize -sed -i 's/RSR-template-repo/my-project/g' Justfile guix.scm README.adoc - -# Enter development environment -guix shell -D -f build/guix.scm - -# Validate compliance -just validate-rsr ----- - -== What's Included - -[cols="1,3"] -|=== -|File/Directory |Purpose - -|`.editorconfig` -|Editor configuration (indent, charset) - -|`.gitignore` -|Standard ignore patterns - -|`.guix-channel` -|Guix channel definition - -|`.well-known/` -|RFC-compliant metadata (security.txt, ai.txt, humans.txt) - -|`docs/` -|Documentation directory - -|`guix.scm` -|Guix package definition - -|`justfile` -|Task runner with 50+ recipes - -|`LICENSE.txt` -|AGPL + Palimpsest dual license - -|`README.adoc` -|This file - -|`RSR_COMPLIANCE.adoc` -|Compliance tracking - -|`STATE.scm` -|Project state checkpoint -|=== - -== Justfile Features - -The template Justfile provides: - -* **~10 billion recipe combinations** via matrix recipes -* **Cookbook generation**: `just cookbook` → `docs/just-cookbook.adoc` -* **Man page generation**: `just man` → `docs/man/project.1` -* **RSR validation**: `just validate-rsr` -* **STATE.scm management**: `just state-touch`, `just state-phase` -* **Container support**: `just container-build`, `just container-push` -* **CI matrix**: `just ci-matrix [stage] [depth]` - -=== Key Recipes - -[source,bash] ----- -just # Show all recipes -just help # Detailed help -just info # Project info -just combinations # Show matrix options - -just build # Build (debug) -just test # Run tests -just quality # Format + lint + test -just ci # Full CI pipeline - -just validate # RSR + STATE validation -just docs # Generate all docs -just cookbook # Generate Justfile docs - -just guix-shell # Guix dev environment -just container-build # Build container ----- - -== Directory Structure - -[source] ----- -project/ -├── .editorconfig # Editor settings -├── .gitignore # Git ignore -├── .guix-channel # Guix channel -├── .well-known/ # RFC metadata -│ ├── ai.txt -│ ├── humans.txt -│ └── security.txt -├── config/ # Nickel configs (optional) -├── docs/ # Documentation -│ ├── generated/ -│ ├── man/ -│ └── just-cookbook.adoc -├── guix.scm # Guix package -├── Justfile # Task runner -├── LICENSE.txt # Dual license -├── README.adoc # Overview -├── RSR_COMPLIANCE.adoc # Compliance -├── src/ # Source code -├── STATE.scm # State checkpoint -└── tests/ # Tests ----- - -== RSR Compliance - -=== Language Tiers - -* **Tier 1** (Gold): Rust, Elixir, Zig, Ada, Haskell, ReScript -* **Tier 2** (Silver): Nickel, Racket, Guile Scheme, Nix -* **Infrastructure**: Guix channels, derivations - -=== Required Files - -* `.editorconfig` -* `.gitignore` -* `justfile` -* `README.adoc` -* `RSR_COMPLIANCE.adoc` -* `LICENSE.txt` (AGPL + Palimpsest) -* `.well-known/security.txt` -* `.well-known/ai.txt` -* `.well-known/humans.txt` -* `guix.scm` OR `flake.nix` - -=== Prohibited - -* Python outside `salt/` directory -* TypeScript/JavaScript (use ReScript) -* CUE (use Guile/Nickel) -* `Dockerfile` (use `Containerfile`) - -== STATE.scm - -The STATE.scm file tracks project state: - -[source,scheme] ----- -(define state - `((metadata - (project . "my-project") - (updated . "2025-12-10")) - (position - (phase . implementation) ; design|implementation|testing|maintenance|archived - (maturity . beta)) ; experimental|alpha|beta|production|lts - (ecosystem - (part-of . ("RSR Framework")) - (depends-on . ())))) ----- - -== Badge Schema - -Generate badges from STATE.scm: - -[source,bash] ----- -just badges standard ----- - -See `docs/BADGE_SCHEMA.adoc` for the full badge taxonomy. - -== Ecosystem Integration - -This template is part of: - -* **STATE.scm Ecosystem**: Conversation checkpoints -* **RSR Framework**: Repository standards -* **Consent-Aware-HTTP**: .well-known compliance - -== License - -SPDX-License-Identifier: CC-BY-SA-4.0 - -== Links - -* https://github.com/hyperpolymath/elegant-STATE[elegant-STATE] - STATE.scm tooling -* https://github.com/hyperpolymath/conative-gating[conative-gating] - Policy enforcement -* https://rhodium.sh[Rhodium Standard] - RSR documentation diff --git a/aletheia/SECURITY.adoc b/aletheia/SECURITY.adoc deleted file mode 100644 index 1c36341..0000000 --- a/aletheia/SECURITY.adoc +++ /dev/null @@ -1,212 +0,0 @@ -== Security Policy - -=== 🔒 Security Principles - -Aletheia is built with security as a foundational principle: - -[arabic] -. *Zero Dependencies*: No external crates = minimal supply chain attack -surface -. *No Unsafe Code*: Zero `+unsafe+` blocks in the entire codebase -. *Offline-First*: No network access = cannot exfiltrate data -. *Type Safety*: Rust’s ownership model prevents memory safety -vulnerabilities -. *Minimal Attack Surface*: ~300 lines of auditable code - -=== 🛡️ Supported Versions - -[cols=",",options="header",] -|=== -|Version |Supported -|0.1.x |:white_check_mark: -|=== - -=== 🚨 Reporting a Vulnerability - -We take security seriously. If you discover a security vulnerability, -please follow these steps: - -==== 1. *DO NOT* create a public issue - -Public disclosure of security vulnerabilities puts all users at risk. -Please report privately. - -==== 2. Report via Secure Channels - -Choose one of these methods: - -* *Email*: security@maa-framework.org (PGP key available at -`+.well-known/security.txt+`) -* *GitLab Confidential Issue*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues/new?issue%5Bconfidential%5D=true[Create -confidential issue] - -==== 3. Include Detailed Information - -Please provide: - -* Description of the vulnerability -* Steps to reproduce -* Potential impact -* Suggested fix (if available) -* Your contact information (for follow-up) - -==== 4. Response Timeline - -We aim to: - -* *Acknowledge* receipt within 48 hours -* *Assess* severity within 7 days -* *Provide updates* every 7 days until resolution -* *Release fix* within 30 days for critical issues, 90 days for others - -=== 🏆 Security Hall of Fame - -We recognize researchers who responsibly disclose vulnerabilities: - -_Be the first to help secure Aletheia!_ - -=== 🔍 Security Features - -==== Memory Safety - -Aletheia leverages Rust’s ownership model to prevent: - -* Buffer overflows -* Use-after-free -* Null pointer dereferences -* Data races -* Iterator invalidation - -==== Input Validation - -All file paths and inputs are validated: - -[source,rust] ----- -if !repo_path.exists() { - eprintln!("Error: Path does not exist: {}", repo_path.display()); - process::exit(1); -} - -if !repo_path.is_dir() { - eprintln!("Error: Path is not a directory: {}", repo_path.display()); - process::exit(1); -} ----- - -==== Error Handling - -All operations use Rust’s `+Result+` type for explicit error handling: - -* No panics in production code -* Graceful degradation on errors -* Clear error messages - -==== Supply Chain Security - -* *Zero dependencies*: No transitive dependency vulnerabilities -* *Cargo.lock committed*: Reproducible builds -* *Minimal build tools*: Only Rust toolchain required - -=== 🔐 Security Audit - -==== Last Audit: 2025-12-26 - -[cols=",",options="header",] -|=== -|Aspect |Result -|*Auditor* |Automated security review -|*Scope* |Full codebase (~586 lines) -|*Vulnerabilities Found* |0 -|*Unsafe Code Blocks* |0 -|*Dependencies* |0 -|=== - -*Audit Coverage*: - Symlink escape vulnerabilities → Mitigated -(detection + critical warnings) - Path traversal attacks → Mitigated -(canonicalization checks) - Memory safety → Guaranteed (Rust ownership -model) - Supply chain attacks → N/A (zero dependencies) - TOCTOU races → -Mitigated (verification timestamps) - -We welcome additional security audits! If you’re interested in auditing -Aletheia: - -[arabic] -. Review the source code in `+src/main.rs+` (~586 lines) -. Check for: -* Unsafe code blocks (should be zero) -* Unvalidated inputs -* Path traversal vulnerabilities -* Integer overflows -* Logic errors -. Report findings via security@maa-framework.org - -==== Known Limitations - -[arabic] -. *Symbolic Links*: Aletheia detects symlinks and warns if they point -outside the repository. Symlinks pointing outside the repository root -generate CRITICAL warnings and cause verification to fail. -. *Filesystem Races*: TOCTOU (time-of-check-time-of-use) gaps between -existence checks and file reads. Mitigated by including verification -timestamp in output. - -These are documented for transparency. Aletheia does NOT read file -contents - it only checks existence - so there is no memory exhaustion -risk from large files. - -=== 🎯 Threat Model - -==== In Scope - -* *Malicious repository contents*: Aletheia should safely analyze any -repository -* *Path traversal attacks*: Cannot escape intended directory -* *Resource exhaustion*: Reasonable limits on memory/CPU usage -* *Information disclosure*: No sensitive data leaked - -==== Out of Scope - -* *Physical access*: Attacker has physical access to the machine -* *Compromised OS/kernel*: Underlying system is already compromised -* *Side-channel attacks*: Timing attacks, cache attacks, etc. -* *Social engineering*: Tricking users into running malicious code - -=== 🔄 Security Updates - -Security updates are released as soon as possible: - -[arabic] -. *Critical* (CVSS 9.0-10.0): Immediate patch release -. *High* (CVSS 7.0-8.9): Patch within 7 days -. *Medium* (CVSS 4.0-6.9): Patch within 30 days -. *Low* (CVSS 0.1-3.9): Patch in next minor release - -=== 📜 Security.txt - -This project complies with RFC 9116. See .well-known/security.txt for -machine-readable security information. - -=== 🤝 Coordinated Disclosure - -We follow coordinated disclosure principles: - -[arabic] -. Reporter notifies us privately -. We acknowledge and investigate -. We develop and test a fix -. We coordinate public disclosure timing with reporter -. We release patch and advisory simultaneously -. We credit reporter (with permission) - -=== 📚 References - -* https://owasp.org/www-project-top-ten/[OWASP Top 10] -* https://cwe.mitre.org/top25/[CWE Top 25] -* https://www.rfc-editor.org/rfc/rfc9116.html[RFC 9116 - security.txt] -* https://anssi-fr.github.io/rust-guide/[Rust Security Guidelines] - -''''' - -*Last Updated*: 2025-12-26 *Contact*: security@maa-framework.org diff --git a/aletheia/benches/verification_benchmark.rs b/aletheia/benches/verification_benchmark.rs deleted file mode 100644 index 6b25a24..0000000 --- a/aletheia/benches/verification_benchmark.rs +++ /dev/null @@ -1,260 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Benchmarks for Aletheia RSR compliance verification -//! -//! These benchmarks measure the performance of verification operations. -//! -//! Run with: cargo build --release && cargo run --release --bin verification_benchmark -//! -//! Note: This is a simple benchmark implementation using std::time. -//! For more sophisticated benchmarking, consider using criterion.rs -//! (but that would add a dependency, breaking RSR Bronze compliance). - -use std::path::PathBuf; -use std::process::Command; -use std::time::{Duration, Instant}; - -/// Number of iterations for each benchmark -const ITERATIONS: u32 = 100; - -/// Number of warmup iterations -const WARMUP: u32 = 5; - -/// Benchmark a function and return statistics -struct BenchmarkResult { - name: String, - min: Duration, - max: Duration, - avg: Duration, - iterations: u32, -} - -impl BenchmarkResult { - fn print(&self) { - println!( - "{}: min={}μs, max={}μs, avg={}μs ({} iterations)", - self.name, - self.min.as_micros(), - self.max.as_micros(), - self.avg.as_micros(), - self.iterations - ); - } -} - -/// Run a benchmark with warmup and statistics -fn benchmark(name: &str, mut f: F) -> BenchmarkResult { - // Warmup phase - for _ in 0..WARMUP { - f(); - } - - let mut times = Vec::with_capacity(ITERATIONS as usize); - - // Measurement phase - for _ in 0..ITERATIONS { - let start = Instant::now(); - f(); - times.push(start.elapsed()); - } - - let min = *times.iter().min().unwrap(); - let max = *times.iter().max().unwrap(); - let total: Duration = times.iter().sum(); - let avg = total / ITERATIONS; - - BenchmarkResult { - name: name.to_string(), - min, - max, - avg, - iterations: ITERATIONS, - } -} - -/// Run a benchmark for command execution (fewer iterations) -fn benchmark_command(name: &str, binary_path: &str, args: &[&str]) -> BenchmarkResult { - const CMD_ITERATIONS: u32 = 10; - - // Warmup - for _ in 0..2 { - let _ = Command::new(binary_path).args(args).output(); - } - - let mut times = Vec::with_capacity(CMD_ITERATIONS as usize); - - for _ in 0..CMD_ITERATIONS { - let start = Instant::now(); - let _ = Command::new(binary_path).args(args).output(); - times.push(start.elapsed()); - } - - let min = *times.iter().min().unwrap(); - let max = *times.iter().max().unwrap(); - let total: Duration = times.iter().sum(); - let avg = total / CMD_ITERATIONS; - - BenchmarkResult { - name: name.to_string(), - min, - max, - avg, - iterations: CMD_ITERATIONS, - } -} - -fn main() { - println!("╔══════════════════════════════════════════════════════════════╗"); - println!("║ Aletheia Performance Benchmarks ║"); - println!("╚══════════════════════════════════════════════════════════════╝\n"); - - let current_dir = std::env::current_dir().expect("Cannot get current directory"); - - // Build release binary first - println!("Building release binary..."); - let build_result = Command::new("cargo") - .args(["build", "--release"]) - .current_dir(¤t_dir) - .output() - .expect("Failed to build release binary"); - - if !build_result.status.success() { - eprintln!("Failed to build release binary"); - std::process::exit(1); - } - println!("Build complete.\n"); - - let binary_path = current_dir.join("target/release/aletheia"); - let binary_str = binary_path.to_str().unwrap(); - - println!("┌─────────────────────────────────────────────────────────────┐"); - println!("│ Micro-benchmarks (filesystem operations) │"); - println!("└─────────────────────────────────────────────────────────────┘\n"); - - // Benchmark 1: Path validation - let path_validation = benchmark("Path validation", || { - let path = PathBuf::from(¤t_dir); - let _ = path.exists(); - let _ = path.is_dir(); - }); - path_validation.print(); - - // Benchmark 2: File existence checks - let file_checks = benchmark("File existence check (single)", || { - let _ = current_dir.join("README.md").is_file(); - }); - file_checks.print(); - - // Benchmark 3: Multiple file checks - let multi_file = benchmark("File existence checks (16 files)", || { - let files = [ - "README.md", - "LICENSE.txt", - "SECURITY.md", - "CONTRIBUTING.md", - "CODE_OF_CONDUCT.md", - "MAINTAINERS.md", - "CHANGELOG.md", - "Cargo.toml", - "justfile", - "flake.nix", - ".gitlab-ci.yml", - ".well-known/security.txt", - ".well-known/ai.txt", - ".well-known/humans.txt", - "src/main.rs", - "tests/integration_tests.rs", - ]; - for file in &files { - let _ = current_dir.join(file).exists(); - } - }); - multi_file.print(); - - // Benchmark 4: Directory checks - let dir_checks = benchmark("Directory existence checks", || { - let _ = current_dir.join("src").is_dir(); - let _ = current_dir.join("tests").is_dir(); - let _ = current_dir.join(".well-known").is_dir(); - }); - dir_checks.print(); - - // Benchmark 5: Symlink checks - let symlink_checks = benchmark("Symlink detection", || { - let _ = current_dir.join("README.md").symlink_metadata(); - }); - symlink_checks.print(); - - // Benchmark 6: Canonicalization - let canon = benchmark("Path canonicalization", || { - let _ = current_dir.canonicalize(); - }); - canon.print(); - - println!("\n┌─────────────────────────────────────────────────────────────┐"); - println!("│ End-to-end benchmarks (full verification) │"); - println!("└─────────────────────────────────────────────────────────────┘\n"); - - // Benchmark: Full verification (human format) - let human_format = benchmark_command("Full verification (human)", binary_str, &[]); - human_format.print(); - - // Benchmark: Full verification (JSON format) - let json_format = benchmark_command( - "Full verification (JSON)", - binary_str, - &["--format", "json"], - ); - json_format.print(); - - // Benchmark: Quiet mode - let quiet_mode = benchmark_command("Full verification (quiet)", binary_str, &["-q"]); - quiet_mode.print(); - - // Benchmark: Verbose mode - let verbose_mode = benchmark_command("Full verification (verbose)", binary_str, &["-v"]); - verbose_mode.print(); - - println!("\n┌─────────────────────────────────────────────────────────────┐"); - println!("│ Summary │"); - println!("└─────────────────────────────────────────────────────────────┘\n"); - - println!( - "Average full verification time: {}μs ({:.2}ms)", - human_format.avg.as_micros(), - human_format.avg.as_secs_f64() * 1000.0 - ); - - println!("\nPerformance Targets:"); - println!(" Target: <10ms per verification"); - println!(" Excellent: <5ms per verification"); - println!(" Outstanding: <2ms per verification"); - - let avg_ms = human_format.avg.as_secs_f64() * 1000.0; - if avg_ms < 2.0 { - println!("\n Status: ⭐ OUTSTANDING ({:.2}ms < 2ms)", avg_ms); - } else if avg_ms < 5.0 { - println!("\n Status: ✨ EXCELLENT ({:.2}ms < 5ms)", avg_ms); - } else if avg_ms < 10.0 { - println!("\n Status: ✅ TARGET MET ({:.2}ms < 10ms)", avg_ms); - } else { - println!( - "\n Status: ⚠️ NEEDS IMPROVEMENT ({:.2}ms >= 10ms)", - avg_ms - ); - } - - // Memory info (if available on Linux) - #[cfg(target_os = "linux")] - { - if let Ok(output) = Command::new("ls").args(["-lh", binary_str]).output() { - let stdout = String::from_utf8_lossy(&output.stdout); - if let Some(line) = stdout.lines().next() { - let parts: Vec<&str> = line.split_whitespace().collect(); - if parts.len() >= 5 { - println!("\nBinary size: {}", parts[4]); - } - } - } - } -} diff --git a/aletheia/conformance/ECHIDNA-CONFORMANCE.adoc b/aletheia/conformance/ECHIDNA-CONFORMANCE.adoc deleted file mode 100644 index baed329..0000000 --- a/aletheia/conformance/ECHIDNA-CONFORMANCE.adoc +++ /dev/null @@ -1,132 +0,0 @@ -== Echidna Conformance Report - -https://gitlab.com/hyperpolymath/echidnabot[image:https://img.shields.io/badge/Echidna-Pending-lightgrey[Echidna -Pending]] - -*Project*: Aletheia *Date*: 2025-12-26 *Status*: Pending Verification - -=== Overview - -https://gitlab.com/hyperpolymath/echidnabot[Echidna] provides formal -proof-based code validation. It verifies that code meets specified -properties using formal methods (Coq, Lean, Z3, Agda, Isabelle). - -=== Echidna Verification Levels - -[width="100%",cols="27%,25%,48%",options="header",] -|=== -|Level |Badge |Description -|Pending -|image:https://img.shields.io/badge/Echidna-Pending-lightgrey[Pending] -|Awaiting verification - -|Partial -|image:https://img.shields.io/badge/Echidna-Partial-yellow[Partial] -|Some proofs complete - -|Verified -|image:https://img.shields.io/badge/Echidna-Verified-green[Verified] -|Core properties proven - -|Certified -|image:https://img.shields.io/badge/Echidna-Certified-brightgreen[Certified] -|Full formal verification -|=== - -=== Connection to Absolute Zero - -Aletheia builds on -https://gitlab.com/hyperpolymath/absolute-zero[Absolute Zero] for its -theoretical foundation: - -.... -┌─────────────────────────────────────────────────────────────┐ -│ ABSOLUTE ZERO │ -│ Formal CNO Verification Framework │ -│ │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ PROOF SYSTEMS │ │ -│ │ Coq │ Lean │ Z3 │ Agda │ Isabelle │ │ -│ └─────────────────────────────────────────────────────┘ │ -│ │ │ -│ ▼ │ -│ ┌─────────────────────────────────────────────────────┐ │ -│ │ CERTIFIED NULL OPERATIONS │ │ -│ │ op ;; reverse(op) ≡ identity │ │ -│ └─────────────────────────────────────────────────────┘ │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ ALETHEIA │ -│ Practical Reversibility Research │ -│ │ -│ Applies CNO theory to operating system primitives │ -└─────────────────────────────────────────────────────────────┘ - │ - ▼ -┌─────────────────────────────────────────────────────────────┐ -│ r-MINIX │ -│ Reversible Minix (Future) │ -└─────────────────────────────────────────────────────────────┘ -.... - -=== Properties to Verify - -==== Core Reversibility Properties - -[width="100%",cols="28%,20%,35%,17%",options="header",] -|=== -|Property |Status |Proof System |Notes -|Operation reversibility |⏳ Pending |Coq |`+∀op: reverse(op) exists+` - -|CNO composition |⏳ Pending |Lean |`+CNO(a) ∧ CNO(b) → CNO(a;b)+` - -|State preservation |⏳ Pending |Z3 -|`+state' = state after op;reverse(op)+` -|=== - -==== Safety Properties - -[cols=",,",options="header",] -|=== -|Property |Status |Notes -|Memory safety |⏳ Pending |Rust provides baseline -|No undefined behavior |⏳ Pending |No unsafe blocks -|Type soundness |⏳ Pending |Rust type system -|=== - -==== Security Properties - -[cols=",,",options="header",] -|=== -|Property |Status |Notes -|No symlink attacks |⏳ Pending |Path validation -|No directory traversal |⏳ Pending |Input sanitization -|No data exfiltration |⏳ Pending |Offline-first design -|=== - -=== Verification Roadmap - -[arabic] -. *Phase 1*: Formalize CNO definitions (in Absolute Zero) -. *Phase 2*: Prove basic reversibility lemmas -. *Phase 3*: Apply proofs to Aletheia operations -. *Phase 4*: Achieve "`Verified`" status - -=== Current Status - -*Status*: Pending - Awaiting completion of Aletheia’s core reversibility -implementation and corresponding proofs in Absolute Zero. - -=== Learn More - -* https://gitlab.com/hyperpolymath/echidnabot[Echidnabot Repository] -* https://gitlab.com/hyperpolymath/absolute-zero[Absolute Zero -Repository] -* https://gitlab.com/hyperpolymath/absolute-zero/-/blob/main/VERIFICATION.md[Formal -Methods Overview] - -''''' - -_Awaiting formal verification via Echidna_ diff --git a/aletheia/conformance/OIKOS-CONFORMANCE.adoc b/aletheia/conformance/OIKOS-CONFORMANCE.adoc deleted file mode 100644 index 88b8880..0000000 --- a/aletheia/conformance/OIKOS-CONFORMANCE.adoc +++ /dev/null @@ -1,105 +0,0 @@ -== Oikos Conformance Report - -https://gitlab.com/hyperpolymath/oikos[image:https://img.shields.io/badge/Oikos-Pending-lightgrey[Oikos -Pending]] - -*Project*: Aletheia *Date*: 2025-12-26 *Status*: Pending Validation - -=== Overview - -https://gitlab.com/hyperpolymath/oikos[Oikos] provides economic and -ecological evaluation for software projects. It assesses sustainability, -resource efficiency, and long-term viability. - -=== Oikos Validation Levels - -[width="100%",cols="27%,25%,48%",options="header",] -|=== -|Level |Badge |Description -|Pending -|image:https://img.shields.io/badge/Oikos-Pending-lightgrey[Pending] -|Awaiting validation - -|Evaluated -|image:https://img.shields.io/badge/Oikos-Evaluated-yellow[Evaluated] -|Under review - -|Validated -|image:https://img.shields.io/badge/Oikos-Validated-green[Validated] -|Meets criteria - -|Exemplary -|image:https://img.shields.io/badge/Oikos-Exemplary-brightgreen[Exemplary] -|Best practices -|=== - -=== Evaluation Criteria - -==== Resource Efficiency - -[cols=",,,",options="header",] -|=== -|Metric |Status |Target |Current -|Zero dependencies |⏳ Pending |Yes |Yes (Rust std only) -|Binary size |⏳ Pending |< 1MB |TBD -|Memory usage |⏳ Pending |< 10MB |TBD -|Startup time |⏳ Pending |< 100ms |TBD -|=== - -==== Sustainability - -[cols=",,",options="header",] -|=== -|Metric |Status |Notes -|Maintenance burden |⏳ Pending |Simple codebase, low burden -|Dependency updates |⏳ Pending |N/A (zero dependencies) -|Bus factor |⏳ Pending |Single maintainer (risk) -|Documentation coverage |⏳ Pending |Good, needs expansion -|=== - -==== Ecological Impact - -[cols=",,",options="header",] -|=== -|Metric |Status |Notes -|Energy efficiency |⏳ Pending |Reversible computing reduces waste -|Carbon footprint |⏳ Pending |Minimal - local processing only -|E-waste consideration |⏳ Pending |N/A for software -|=== - -=== Aletheia-Specific Considerations - -==== Positive Factors - -[arabic] -. *Zero dependencies* - No supply chain complexity -. *Offline-first* - No network overhead -. *Reversibility focus* - Core mission aligns with efficiency -. *Simple architecture* - Low maintenance burden - -==== Areas for Improvement - -[arabic] -. *Bus factor* - Single maintainer risk -. *Test coverage* - Needs expansion -. *Contributor documentation* - Could be improved - -=== Next Steps - -[arabic] -. Complete initial codebase -. Run oikos bot validation -. Address any identified issues -. Achieve "`Validated`" status - -=== Learn More - -* https://gitlab.com/hyperpolymath/oikos[Oikos Repository] -* https://gitlab.com/hyperpolymath/oikos/-/blob/main/CRITERIA.md[Oikos -Evaluation Criteria] -* https://gitlab.com/hyperpolymath/oikos/-/blob/main/BOT-PATTERN.md[Bot -Pattern Documentation] - -''''' - -_Awaiting Oikos validation_ diff --git a/aletheia/conformance/PALIMPSEST-CONFORMANCE.adoc b/aletheia/conformance/PALIMPSEST-CONFORMANCE.adoc deleted file mode 100644 index 3313a52..0000000 --- a/aletheia/conformance/PALIMPSEST-CONFORMANCE.adoc +++ /dev/null @@ -1,98 +0,0 @@ -== Palimpsest License Conformance Report - -https://gitlab.com/hyperpolymath/palimpsest-license[image:https://img.shields.io/badge/License-Palimpsest%20v0.8-blue[Palimpsest -License]] - -*Project*: Aletheia *Date*: 2025-12-26 *Version*: Palimpsest v0.8 -*Status*: Compliant - -=== Overview - -The Palimpsest License is an overlay license designed to work alongside -standard open-source licenses (MIT, Apache-2.0, AGPL). It adds -attribution and provenance requirements while maintaining full -open-source compatibility. - -=== License Structure - -.... -┌─────────────────────────────────────────┐ -│ PALIMPSEST OVERLAY │ -│ • Attribution requirements │ -│ • Provenance tracking │ -│ • Contribution acknowledgment │ -├─────────────────────────────────────────┤ -│ BASE LICENSE │ -│ • MIT (permissive) │ -│ • OR Apache-2.0 (permissive) │ -│ • OR AGPL (copyleft) │ -└─────────────────────────────────────────┘ -.... - -=== Aletheia License Configuration - -[cols=",",options="header",] -|=== -|Component |License -|Base License |MIT -|Overlay |Palimpsest v0.8 -|License Files |`+LICENSE-MIT.txt+`, `+LICENSE-PALIMPSEST.txt+` -|=== - -=== Palimpsest Requirements - -==== Attribution - -[cols=",,",options="header",] -|=== -|Requirement |Status |Notes -|Original author credited |✅ Pass |Jonathan D. A. Jewell -|Contribution history preserved |✅ Pass |Git history maintained -|License notice in files |⚠️ Partial |Adding to source files -|=== - -==== Provenance - -[cols=",,",options="header",] -|=== -|Requirement |Status |Notes -|Origin clearly stated |✅ Pass |In README and LICENSE -|Modifications documented |✅ Pass |CHANGELOG.md -|Fork lineage tracked |N/A |Original project -|=== - -==== Contribution Acknowledgment - -[cols=",,",options="header",] -|=== -|Requirement |Status |Notes -|Contributors listed |✅ Pass |MAINTAINERS.md -|CONTRIBUTING.md present |✅ Pass |Guidelines documented -|DCO/CLA specified |⚠️ Pending |DCO recommended -|=== - -=== Verification Checklist - -* [x] LICENSE-MIT.txt present -* [x] LICENSE-PALIMPSEST.txt present -* [x] LICENSE.txt references both -* [x] README includes license badges -* [x] Source files have headers (in progress) - -=== Why Palimpsest? - -The Palimpsest License: 1. *Preserves attribution* - Ensures original -creators are credited 2. *Tracks provenance* - Documents where code came -from 3. *Remains open source* - Compatible with OSI-approved licenses 4. -*Supports collaboration* - Clear contribution guidelines - -=== Learn More - -* https://gitlab.com/hyperpolymath/palimpsest-license[Palimpsest License -Repository] -* https://gitlab.com/hyperpolymath/palimpsest-license/-/blob/main/FAQ.md[Palimpsest -FAQ] - -''''' - -_Licensed under MIT with Palimpsest v0.8 overlay_ diff --git a/aletheia/conformance/README.adoc b/aletheia/conformance/README.adoc deleted file mode 100644 index 38a3f06..0000000 --- a/aletheia/conformance/README.adoc +++ /dev/null @@ -1,88 +0,0 @@ -== Conformance Reports - -This folder contains conformance reports for Aletheia’s compliance with -various standards and verification systems. - -=== Reports - -[width="100%",cols="29%,27%,44%",options="header",] -|=== -|Report |Status |Description -|RSR-CONFORMANCE.md -|image:https://img.shields.io/badge/RSR-Bronze-cd7f32[Bronze] |Rhodium -Standard Repository compliance -|=== - -image:https://img.shields.io/badge/License-MPL–2.0-blue.svg[License: -PMPL-1.0,link="`https://github.com/hyperpolymath/palimpsest-license`"] | -OIKOS-CONFORMANCE.md | -image:https://img.shields.io/badge/Oikos-Pending-lightgrey[Pending] | -Economic/ecological validation | | ECHIDNA-CONFORMANCE.md | -image:https://img.shields.io/badge/Echidna-Pending-lightgrey[Pending] | -Formal proof verification | - -=== Understanding Badges - -==== RSR (Rhodium Standard Repositories) - -Repository organization and documentation standards. - -[cols=",",options="header",] -|=== -|Level |Meaning -|Bronze |Basic compliance - documentation and structure -|Silver |Enhanced quality - testing and coverage -|Gold |Production ready - multi-platform builds -|Platinum |Enterprise grade - full formal verification -|=== - -==== Palimpsest License - -Overlay license for attribution and provenance. - -[cols=",",options="header",] -|=== -|Status |Meaning -|Active |License properly applied -|Partial |Some requirements pending -|=== - -==== Oikos - -Economic and ecological evaluation. - -[cols=",",options="header",] -|=== -|Level |Meaning -|Pending |Awaiting validation -|Evaluated |Under review -|Validated |Meets sustainability criteria -|Exemplary |Best practices -|=== - -==== Echidna - -Formal proof-based code validation. - -[cols=",",options="header",] -|=== -|Level |Meaning -|Pending |Awaiting verification -|Partial |Some proofs complete -|Verified |Core properties proven -|Certified |Full formal verification -|=== - -=== Learn More - -* link:../docs/VALUE-CHAIN-POLICY.md[Value Chain Policy] - How -conformance fits into project value chain -* link:../ALETHEIA-HANDOVER.md[ALETHEIA-HANDOVER.md] - Project handover -with all badges -* link:../CROSSREPO-HANDOVER.md[CROSSREPO-HANDOVER.md] - Full ecosystem -documentation - -''''' - -_Conformance is verified by automated bots: rhodibot, oikos bot, -echidnabot_ diff --git a/aletheia/conformance/RSR-CONFORMANCE.adoc b/aletheia/conformance/RSR-CONFORMANCE.adoc deleted file mode 100644 index 0488f35..0000000 --- a/aletheia/conformance/RSR-CONFORMANCE.adoc +++ /dev/null @@ -1,118 +0,0 @@ -[NOTE] -==== -2026-09-21: the record below dates from 2025-12-26 and describes the *v1* -check shape (16 checks: LICENSE.txt, lowercase justfile, flake.nix), -which the estate has since retired. Current state: aletheia implements -the RSR v2 offline file-presence subset (26 checks: 13 Bronze, 12 Silver, -1 Gold — see `SSOT_PROVENANCE` in `src/checks.rs`) and achieves -Bronze-level compliance on itself. The hypatia `rsr-conformance` oracle -is normative. This file is retained as a historical record. -==== - -== RSR Conformance Report - -https://github.com/hyperpolymath/rhodium-standard-repositories[image:https://img.shields.io/badge/RSR-Bronze-cd7f32[RSR -Bronze]] - -*Project*: Aletheia *Date*: 2025-12-26 *Level*: Bronze *Status*: -Compliant - -=== Overview - -This document records Aletheia’s conformance to the -https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium -Standard Repositories (RSR)] specification. - -=== RSR Levels - -[width="100%",cols="27%,25%,48%",options="header",] -|=== -|Level |Badge |Description -|Bronze |image:https://img.shields.io/badge/RSR-Bronze-cd7f32[Bronze] -|Basic compliance - -|Silver |image:https://img.shields.io/badge/RSR-Silver-c0c0c0[Silver] -|Enhanced quality - -|Gold |image:https://img.shields.io/badge/RSR-Gold-ffd700[Gold] -|Production ready - -|Platinum -|image:https://img.shields.io/badge/RSR-Platinum-e5e4e2[Platinum] -|Enterprise grade -|=== - -=== Bronze Requirements - -==== Documentation - -[cols=",,",options="header",] -|=== -|Requirement |Status |Notes -|README.md/README.adoc |✅ Pass |README.adoc present -|LICENSE.txt |✅ Pass |Dual MIT + Palimpsest -|SECURITY.md |✅ Pass |Security policy defined -|CONTRIBUTING.md |✅ Pass |Contribution guidelines -|CODE_OF_CONDUCT.md |✅ Pass |Community standards -|MAINTAINERS.md |✅ Pass |Governance documented -|CHANGELOG.md |✅ Pass |Version history -|=== - -==== .well-known Directory - -[cols=",,",options="header",] -|=== -|File |Status |Notes -|security.txt |✅ Pass |RFC 9116 compliant -|ai.txt |✅ Pass |AI training policies -|humans.txt |✅ Pass |Human attribution -|=== - -==== Build System - -[cols=",,",options="header",] -|=== -|Requirement |Status |Notes -|Justfile |✅ Pass |Task automation -|flake.nix |✅ Pass |Reproducible builds -|CI/CD config |✅ Pass |.gitlab-ci.yml -|=== - -==== Source Structure - -[cols=",,",options="header",] -|=== -|Requirement |Status |Notes -|src/ directory |✅ Pass |Source code present -|tests/ directory |⚠️ Pending |Tests to be added -|=== - -=== Silver Requirements (Future) - -[cols=",",options="header",] -|=== -|Requirement |Status -|Property-based tests |⏳ Not started -|Coverage threshold |⏳ Not started -|Mutation testing |⏳ Not started -|Formal verification hooks |⏳ Not started -|=== - -=== Verification - -This conformance was verified by: - *Tool*: rhodibot v0.1.0 - *Date*: -2025-12-26 - *Method*: Automated scan - -=== Learn More - -* https://github.com/hyperpolymath/rhodium-standard-repositories[RSR -Specification] -* link:../extraction/rhodibot/README.md[rhodibot Documentation] -* link:../extraction/rhodium-pipeline/README.md[rhodium-pipeline -Documentation] - -''''' - -_Part of the -https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium -Standard] ecosystem_ diff --git a/aletheia/contractiles/README.adoc b/aletheia/contractiles/README.adoc deleted file mode 100644 index 9f94acc..0000000 --- a/aletheia/contractiles/README.adoc +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Contractiles Template Set -:toc: -:sectnums: - -This directory contains the generalized contractiles templates. Copy the `contractiles/` directory into a new repo to establish a consistent operational, validation, trust, recovery, and intent framework. - -== Fill-In Instructions - -1. Update the Mustfile to reflect your real invariants (paths, schema versions, ports). -2. Replace Trustfile.hs placeholders with your actual key paths and verification commands. -3. Adjust Dustfile handlers to match your rollback and recovery tooling. -4. Update Intentfile to mirror the roadmap you want the system to evolve toward. - -== Contents - -* `must/Mustfile` - required invariants and validations. -* `trust/Trustfile.hs` - cryptographic verification steps. -* `dust/Dustfile` - rollback and recovery semantics. -* `lust/Intentfile` - future intent and roadmap direction. diff --git a/aletheia/contractiles/dust/Dustfile b/aletheia/contractiles/dust/Dustfile deleted file mode 100644 index 314903c..0000000 --- a/aletheia/contractiles/dust/Dustfile +++ /dev/null @@ -1,29 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Dustfile template - recovery and rollback semantics - -version: 1 - -recovery: - logs: - - name: decision-log - path: logs/decisions.json - reversible: true - handler: "log-replay --reverse logs/decisions.json" - - policy: - - name: policy-rollback - path: policy/policy.ncl - rollback: "git checkout HEAD~1 -- policy/policy.ncl" - notes: "Rollback policy to the previous known-good revision." - - gateway: - - name: bad-deployment - event: "deploy.failure" - undo: "kubectl rollout undo deployment/gateway" - notes: "Undo a failed deployment while preserving audit logs." - - dust-events: - - name: decision-log-to-dust - source: logs/decisions.json - transform: "dustify --input logs/decisions.json --output logs/dust-events.json" - notes: "Map gateway decision logs into reversible dust events." diff --git a/aletheia/contractiles/must/Mustfile b/aletheia/contractiles/must/Mustfile deleted file mode 100644 index dc7b3be..0000000 --- a/aletheia/contractiles/must/Mustfile +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Mustfile - declarative state contract (template) -# See: https://github.com/hyperpolymath/mustfile - -version: 1 - -metadata: - name: project-state-contract - spec: v0.0.1 - description: "Invariant checks for config, policy, gateway, logs, and schema." - -parameters: - gateway_port: "8080" - schema_version: "v0.0.1" - -checks: - - name: config-valid - description: "config/service.yaml must be valid." - run: "yq -e '.' config/service.yaml >/dev/null" - - - name: policy-compiles - description: "policy/policy.ncl must compile." - run: "nickel check policy/policy.ncl" - - - name: gateway-exposes-port - description: "Service must expose the configured port." - run: "bash -uc 'ss -lnt | rg \":${GATEWAY_PORT:-8080}\"'" - - - name: logs-are-json - description: "Logs must be JSON." - run: "bash -uc 'rg --files -g \"*.json\" logs | xargs -r jq -e .'" - - - name: schema-version-matches - description: "Schema must match version spec." - run: "bash -uc 'rg -n \"${SCHEMA_VERSION:-v0.0.1}\" schema'" diff --git a/aletheia/docs/ARCHITECTURE.adoc b/aletheia/docs/ARCHITECTURE.adoc deleted file mode 100644 index cd62465..0000000 --- a/aletheia/docs/ARCHITECTURE.adoc +++ /dev/null @@ -1,410 +0,0 @@ -== Aletheia Architecture - -=== Overview - -Aletheia is designed as a *simple, auditable, single-file tool* for RSR -compliance verification. This document explains the architectural -decisions and design principles. - -=== Design Principles - -==== 1. Simplicity Over Complexity - -*Decision*: Single-file implementation (~300 lines) - -*Rationale*: - Easy to audit - one file to review - Minimal cognitive -overhead - Clear code flow without jumping between modules - Reduces -attack surface - -*Trade-offs*: - Limited to ~1000 lines before needing modularization - -All code must be general-purpose (no domain-specific modules) - -==== 2. Zero Dependencies - -*Decision*: Only use Rust standard library - -*Rationale*: - No supply chain attacks - Easy security review - Faster -compilation - Long-term stability - Works offline - -*Trade-offs*: - Must implement features from scratch - Cannot use -ecosystem tools (clap, serde, etc.) - More code to maintain - -==== 3. Type Safety First - -*Decision*: Leverage Rust’s type system maximally - -*Rationale*: - Compile-time correctness guarantees - Self-documenting -code - Prevents entire classes of bugs - No runtime type errors - -*Implementation*: - -[source,rust] ----- -enum ComplianceLevel { - Bronze, - Silver, - Gold, - Platinum, -} - -struct CheckResult { - category: String, - item: String, - passed: bool, - required_for: ComplianceLevel, -} ----- - -==== 4. Offline-First - -*Decision*: No network access whatsoever - -*Rationale*: - Works air-gapped - Cannot exfiltrate data - No privacy -concerns - Faster execution - More reliable - -*Implementation*: - All checks are filesystem-based - No `+std::net+` -usage - No external API calls - -==== 5. Explicit Error Handling - -*Decision*: No panics, all errors handled explicitly - -*Rationale*: - Predictable behavior - Graceful degradation - Clear error -messages - No crashes on invalid input - -*Implementation*: - -[source,rust] ----- -let repo_path = if args.len() > 1 { - PathBuf::from(&args[1]) -} else { - std::env::current_dir().unwrap_or_else(|_| { - eprintln!("Error: Cannot determine current directory"); - process::exit(1); - }) -}; ----- - -=== Code Structure - -==== Module Organization - -.... -src/main.rs -├── Type Definitions -│ ├── ComplianceLevel (enum) -│ ├── CheckResult (struct) -│ └── ComplianceReport (struct) -│ -├── Core Verification Functions -│ ├── file_exists() -│ ├── dir_exists() -│ ├── check_documentation() -│ ├── check_well_known() -│ ├── check_build_system() -│ ├── check_source_structure() -│ └── verify_repository() -│ -├── Reporting -│ └── print_report() -│ -├── Entry Point -│ └── main() -│ -└── Tests - └── #[cfg(test)] mod tests -.... - -==== Data Flow - -.... -Command Line Args - ↓ - Parse Path - ↓ -Verify Repository - ↓ - ┌─────────────┐ - │ Create │ - │ Report │ - └─────────────┘ - ↓ - ┌─────────────┐ - │ Check │ - │ Documentation │ - └─────────────┘ - ↓ - ┌─────────────┐ - │ Check │ - │ Well-Known │ - └─────────────┘ - ↓ - ┌─────────────┐ - │ Check │ - │ Build System│ - └─────────────┘ - ↓ - ┌─────────────┐ - │ Check │ - │ Source │ - └─────────────┘ - ↓ - Print Report - ↓ - Exit Code -.... - -=== Key Components - -==== ComplianceReport - -*Purpose*: Accumulate all check results - -*Design*: - -[source,rust] ----- -struct ComplianceReport { - checks: Vec, - repository_path: PathBuf, -} ----- - -*Methods*: - `+new()+` - Create empty report - `+add_check()+` - Add a -check result - `+bronze_compliance()+` - Check if all Bronze -requirements pass - `+passed_count()+` - Count passing checks - -`+total_count()+` - Count total checks - -==== Check Functions - -*Pattern*: All check functions follow the same signature - -[source,rust] ----- -fn check_category(report: &mut ComplianceReport, repo_path: &Path) { - // Perform checks - // Add results to report -} ----- - -*Benefits*: - Consistent interface - Easy to add new checks - Clear -separation of concerns - -==== Verification Flow - -*Strategy*: Sequential checks with accumulation - -[arabic] -. Create empty report -. Run each check function -. Each function adds results to report -. Return completed report - -*Benefits*: - All checks run (don’t stop on first failure) - Complete -picture of compliance status - Easy to parallelize in future (if needed) - -=== Security Architecture - -==== Threat Model - -*In Scope*: - Malicious repository contents - Path traversal attacks - -Resource exhaustion - Information disclosure - -*Out of Scope*: - Physical access attacks - Compromised OS/kernel - -Side-channel attacks - Social engineering - -==== Security Measures - -[arabic] -. *Input Validation* -+ -[source,rust] ----- -if !repo_path.exists() { - eprintln!("Error: Path does not exist"); - process::exit(1); -} ----- -. *No Unsafe Code* -* Zero `+unsafe+` blocks -* All code memory-safe by construction -. *No Dependencies* -* No supply chain vulnerabilities -* No transitive dependencies -. *Offline Operation* -* Cannot exfiltrate data -* No network attack surface - -==== Known Limitations - -[arabic] -. *Symbolic Links*: Follows symlinks (potential path traversal) -. *Large Files*: Could consume excessive memory -. *TOCTOU*: Time-of-check-time-of-use races between existence checks and -reads - -=== Performance Characteristics - -==== Time Complexity - -* *File Checks*: O(n) where n = number of required files -* *Directory Checks*: O(1) per directory -* *Overall*: O(n) where n = total checks (~20 checks) - -==== Space Complexity - -* *Report Storage*: O(n) where n = number of checks -* *Stack Usage*: Minimal (no recursion) -* *Heap Usage*: Small (only storing check results) - -==== Typical Performance - -* *Small repos*: <10ms -* *Large repos*: <50ms -* *Bottleneck*: Filesystem I/O (stat calls) - -=== Extensibility - -==== Adding New Checks - -[arabic] -. Create check function: -+ -[source,rust] ----- -fn check_new_category(report: &mut ComplianceReport, repo_path: &Path) { - let passes = /* check logic */; - report.add_check("Category", "Item", passes, ComplianceLevel::Bronze); -} ----- -. Call from `+verify_repository()+`: -+ -[source,rust] ----- -check_new_category(&mut report, repo_path); ----- -. Add tests: -+ -[source,rust] ----- -#[test] -fn test_new_category_check() { /* ... */ } ----- - -==== Supporting New Compliance Levels - -Currently: Bronze only - -*To add Silver/Gold/Platinum*: - -[arabic] -. Add checks with appropriate `+ComplianceLevel+` enum value -. Add level-specific verification methods to `+ComplianceReport+` -. Update output to show multi-level status - -==== Future Modularization (>1000 lines) - -*Suggested structure*: - -.... -src/ -├── main.rs # Entry point -├── types.rs # Type definitions -├── checks/ -│ ├── mod.rs # Check functions -│ ├── docs.rs # Documentation checks -│ ├── security.rs # Security checks -│ └── build.rs # Build system checks -└── report.rs # Reporting -.... - -=== Testing Strategy - -==== Unit Tests - -Test individual functions: - -[source,rust] ----- -#[test] -fn test_file_exists() { - // Test file existence checking -} ----- - -==== Integration Tests (Future) - -Test complete workflows: - -[source,rust] ----- -#[test] -fn test_complete_verification() { - // Test end-to-end verification -} ----- - -==== Manual Testing - -Test on real repositories: - RSR-compliant repos (should pass) - -Non-compliant repos (should fail) - Edge cases (empty dirs, symlinks, -etc.) - -=== Build System - -==== Justfile - -*Purpose*: Common development tasks - -*Key Recipes*: - `+build+` - Compile project - `+test+` - Run tests - -`+check+` - Run all quality checks - `+validate+` - Self-verification - -==== Nix Flake - -*Purpose*: Reproducible builds - -*Benefits*: - Exact dependency versions - Cross-platform consistency - -Isolated build environment - -==== GitLab CI - -*Purpose*: Automated testing - -*Stages*: 1. Check (format, clippy, dependencies, unsafe code) 2. Test -(unit, release, doc tests) 3. Build (debug, release, musl) 4. Verify -(RSR compliance, docs, build system) 5. Deploy (releases, pages) - -=== Maintenance Philosophy - -==== Stability Over Features - -* Keep core simple -* Avoid feature creep -* Maintain zero dependencies -* Preserve auditability - -==== Backwards Compatibility - -* Follow semantic versioning -* Maintain API stability -* Document breaking changes - -==== Evolution Strategy - -[arabic] -. *Bronze* (current): Foundation -. *Silver*: Add verification without breaking Bronze -. *Gold*: Multi-language support -. *Platinum*: Enterprise features - -=== References - -* link:RSR-SPECIFICATION.md[RSR Specification] -* https://rust-lang.github.io/api-guidelines/[Rust API Guidelines] -* https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html[Clean -Architecture] - -''''' - -*Last Updated*: 2025-11-22 *Version*: 1.0 diff --git a/aletheia/docs/BADGES.adoc b/aletheia/docs/BADGES.adoc deleted file mode 100644 index 286f6b0..0000000 --- a/aletheia/docs/BADGES.adoc +++ /dev/null @@ -1,253 +0,0 @@ -== RSR Compliance Badges - -Display your RSR compliance status with badges in your README. - -=== Available Badges - -==== Bronze Level - -*Achieved*: - -[source,markdown] ----- -[![RSR Bronze](https://img.shields.io/badge/RSR-Bronze%20Compliant-green?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) ----- - -https://gitlab.com/maa-framework/6-the-foundation/aletheia[image:https://img.shields.io/badge/RSR-Bronze%20Compliant-green?style=flat-square&logo=rust[RSR -Bronze]] - -*In Progress*: - -[source,markdown] ----- -[![RSR Bronze](https://img.shields.io/badge/RSR-Bronze%20In%20Progress-yellow?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) ----- - -https://gitlab.com/maa-framework/6-the-foundation/aletheia[image:https://img.shields.io/badge/RSR-Bronze%20In%20Progress-yellow?style=flat-square&logo=rust[RSR -Bronze]] - -*Not Compliant*: - -[source,markdown] ----- -[![RSR Bronze](https://img.shields.io/badge/RSR-Not%20Compliant-red?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) ----- - -https://gitlab.com/maa-framework/6-the-foundation/aletheia[image:https://img.shields.io/badge/RSR-Not%20Compliant-red?style=flat-square&logo=rust[RSR -Bronze]] - -==== Silver Level (Future) - -[source,markdown] ----- -[![RSR Silver](https://img.shields.io/badge/RSR-Silver%20Compliant-blue?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) ----- - -==== Gold Level (Future) - -[source,markdown] ----- -[![RSR Gold](https://img.shields.io/badge/RSR-Gold%20Compliant-gold?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) ----- - -==== Platinum Level (Future) - -[source,markdown] ----- -[![RSR Platinum](https://img.shields.io/badge/RSR-Platinum%20Compliant-platinum?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) ----- - -=== Dynamic Badges (Future Feature) - -In the future, Aletheia may support dynamic badges that automatically -update: - -[source,markdown] ----- -[![RSR Compliance](https://rsr-badges.example.com/compliance/owner/repo)](https://gitlab.com/owner/repo) ----- - -This would: 1. Run Aletheia verification 2. Generate badge with current -status 3. Update automatically on push - -=== Badge Styles - -==== Flat Square (Recommended) - -[source,markdown] ----- -![RSR](https://img.shields.io/badge/RSR-Bronze-green?style=flat-square) ----- - -==== Flat - -[source,markdown] ----- -![RSR](https://img.shields.io/badge/RSR-Bronze-green?style=flat) ----- - -==== Plastic - -[source,markdown] ----- -![RSR](https://img.shields.io/badge/RSR-Bronze-green?style=plastic) ----- - -==== For the Badge - -[source,markdown] ----- -![RSR](https://img.shields.io/badge/RSR-Bronze-green?style=for-the-badge) ----- - -==== Social - -[source,markdown] ----- -![RSR](https://img.shields.io/badge/RSR-Bronze-green?style=social) ----- - -=== Badge Verification - -Users can verify your badge claim by: - -[arabic] -. *Clone repository*: -+ -[source,bash] ----- -git clone https://your-repo-url.git -cd your-repo ----- -. *Run Aletheia*: -+ -[source,bash] ----- -aletheia . ----- -. *Check output*: -+ -.... -🏆 Bronze-level RSR compliance: ACHIEVED -.... - -=== README Example - -[source,markdown] ----- -# My Amazing Project - -[![RSR Bronze](https://img.shields.io/badge/RSR-Bronze%20Compliant-green?style=flat-square&logo=rust)](https://gitlab.com/maa-framework/6-the-foundation/aletheia) -[![License](https://img.shields.io/badge/License-MIT-blue.svg)](LICENSE-MIT.txt) -[![Build Status](https://gitlab.com/your/repo/badges/main/pipeline.svg)](https://gitlab.com/your/repo/-/commits/main) - -> RSR Bronze-level compliant project demonstrating best practices - -## Features - -- Feature 1 -- Feature 2 -- Feature 3 - -## RSR Compliance - -This project maintains RSR Bronze-level compliance. Verify with: - -\`\`\`bash -aletheia . -\`\`\` - -## Installation - -\`\`\`bash -cargo install my-project -\`\`\` - -## License - -Code is under MPL-2.0 and docs are under CC-BY-SA-4.0. ----- - -=== Custom Badges - -You can create custom badges with specific scores: - -[source,markdown] ----- - -![RSR](https://img.shields.io/badge/RSR-16%2F16%20Checks-green) - - -![RSR](https://img.shields.io/badge/RSR-87.5%25%20Compliant-yellow) ----- - -=== Badge in CI/CD - -Generate badge URL based on CI results: - -==== GitLab CI - -[source,yaml] ----- -# .gitlab-ci.yml -rsr-verify: - script: - - | - if aletheia .; then - echo "BADGE_STATUS=compliant" >> build.env - echo "BADGE_COLOR=green" >> build.env - else - echo "BADGE_STATUS=not_compliant" >> build.env - echo "BADGE_COLOR=red" >> build.env - fi - artifacts: - reports: - dotenv: build.env ----- - -=== Badge Guidelines - -==== Do’s ✅ - -* ✅ Update badge when compliance changes -* ✅ Link badge to Aletheia repo or RSR docs -* ✅ Keep badge current with latest verification -* ✅ Use appropriate color (green/yellow/red) - -==== Don’ts ❌ - -* ❌ Don’t claim compliance without verification -* ❌ Don’t use outdated badge status -* ❌ Don’t modify badge colors misleadingly -* ❌ Don’t use higher-level badges prematurely - -=== Verification Required - -To use a compliance badge: - -[arabic] -. *Run Aletheia*: `+aletheia .+` -. *Verify output*: Ensure 16/16 checks pass -. *Add badge*: Use appropriate badge code -. *Keep updated*: Re-verify after changes - -=== Badge Hosting - -Badges use shields.io service: - *Service*: https://shields.io - -*Format*: `+https://img.shields.io/badge/{subject}-{status}-{color}+` - -*Customization*: See https://shields.io for options - -=== Future: Automated Badge Service - -Planned features: - Real-time verification API - Automatic badge -generation - Webhook integration - Historical compliance tracking - -Multi-repo dashboards - -=== Contributing - -Help improve RSR badges: - Suggest new badge designs - Propose dynamic -badge service - Contribute to Aletheia - Share badge usage examples - -''''' - -*Displaying your RSR compliance shows commitment to quality!* diff --git a/aletheia/docs/CITATIONS.adoc b/aletheia/docs/CITATIONS.adoc deleted file mode 100644 index f23302d..0000000 --- a/aletheia/docs/CITATIONS.adoc +++ /dev/null @@ -1,38 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= aletheia - Citation Guide -:toc: - -== BibTeX - -[source,bibtex] ----- -@software{aletheia_2025, - author = {Jewell, Jonathan D.A.}, - title = {aletheia}, - year = {2025}, - url = {https://github.com/hyperpolymath/maa-framework}, - license = {MPL-2.0} -} ----- - -== Harvard Style - -Jewell, J.D.A. (2025) _aletheia_ [Computer software]. Available at: https://github.com/hyperpolymath/maa-framework - -== OSCOLA - -Jonathan D.A. Jewell, 'aletheia' (2025) - -== MLA - -Jewell, Jonathan D.A. "aletheia." 2025, github.com/hyperpolymath/maa-framework. - -== APA 7 - -Jewell, J.D.A. (2025). _aletheia_ [Computer software]. GitHub. https://github.com/hyperpolymath/maa-framework - -== See Also - -* link:../CITATION.cff[CITATION.cff] -* link:../codemeta.json[codemeta.json] diff --git a/aletheia/docs/DEPLOYMENT.adoc b/aletheia/docs/DEPLOYMENT.adoc deleted file mode 100644 index 118ee0a..0000000 --- a/aletheia/docs/DEPLOYMENT.adoc +++ /dev/null @@ -1,583 +0,0 @@ -== Deployment Guide - -This document describes various ways to deploy and use Aletheia in -different environments. - -=== Table of Contents - -[arabic] -. link:#local-installation[Local Installation] -. link:#docker-deployment[Docker Deployment] -. link:#cicd-integration[CI/CD Integration] -. link:#system-wide-installation[System-Wide Installation] -. link:#cloud-deployment[Cloud Deployment] -. link:#air-gapped-environments[Air-Gapped Environments] - -=== Local Installation - -==== Quick Install (Recommended) - -[source,bash] ----- -# Using the install script -curl -sSf https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/raw/main/scripts/install.sh | bash - -# Or download and inspect first -curl -O https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/raw/main/scripts/install.sh -chmod +x install.sh -./install.sh ----- - -==== Manual Build - -[source,bash] ----- -# Clone repository -git clone https://gitlab.com/maa-framework/6-the-foundation/aletheia.git -cd aletheia - -# Build release binary -cargo build --release - -# Binary is at: target/release/aletheia -# Copy to PATH location: -cp target/release/aletheia ~/.local/bin/ ----- - -==== Using Cargo Install - -[source,bash] ----- -# Install directly from Git -cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - -# Or from crates.io (when published) -cargo install aletheia ----- - -=== Docker Deployment - -==== Build Docker Image - -[source,bash] ----- -# Build the image -docker build -t aletheia:0.1.0 . - -# Or build with specific target -docker build -t aletheia:latest --target=runtime . ----- - -==== Run with Docker - -[source,bash] ----- -# Verify current directory -docker run -v $(pwd):/repo aletheia:0.1.0 - -# Verify specific repository -docker run -v /path/to/repo:/repo aletheia:0.1.0 - -# Save results to file -docker run -v $(pwd):/repo aletheia:0.1.0 > report.txt ----- - -==== Docker Compose - -[source,yaml] ----- -# docker-compose.yml -version: '3.8' - -services: - aletheia: - image: aletheia:0.1.0 - volumes: - - ./:/repo:ro - command: ["/repo"] ----- - -[source,bash] ----- -# Run with docker-compose -docker-compose run aletheia ----- - -==== Multi-Repository Verification - -[source,bash] ----- -# Script to verify multiple repositories -#!/bin/bash -for repo in /path/to/repos/*; do - echo "Verifying: $repo" - docker run -v "$repo:/repo" aletheia:0.1.0 - echo "---" -done ----- - -=== CI/CD Integration - -==== GitLab CI - -===== Simple Integration - -[source,yaml] ----- -# .gitlab-ci.yml -rsr-compliance: - stage: test - image: rust:1.75 - before_script: - - cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - script: - - aletheia - allow_failure: false ----- - -===== With Caching - -[source,yaml] ----- -# .gitlab-ci.yml -variables: - CARGO_HOME: $CI_PROJECT_DIR/.cargo - -rsr-compliance: - stage: test - image: rust:1.75 - cache: - key: aletheia - paths: - - .cargo/ - before_script: - - | - if [ ! -f .cargo/bin/aletheia ]; then - cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - fi - script: - - .cargo/bin/aletheia ----- - -===== Using Docker - -[source,yaml] ----- -# .gitlab-ci.yml -rsr-compliance: - stage: test - image: aletheia:0.1.0 - script: - - /aletheia . ----- - -==== GitHub Actions - -[source,yaml] ----- -# .github/workflows/rsr-compliance.yml -name: RSR Compliance - -on: [push, pull_request] - -jobs: - verify: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v3 - - - name: Install Rust - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - override: true - - - name: Cache Aletheia - uses: actions/cache@v3 - with: - path: ~/.cargo/bin/aletheia - key: aletheia-${{ hashFiles('**/Cargo.lock') }} - - - name: Install Aletheia - run: cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - - - name: Verify RSR Compliance - run: aletheia ----- - -==== Jenkins - -[source,groovy] ----- -// Jenkinsfile -pipeline { - agent { - docker { - image 'rust:1.75' - } - } - - stages { - stage('Install Aletheia') { - steps { - sh 'cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git' - } - } - - stage('Verify RSR Compliance') { - steps { - sh 'aletheia' - } - } - } - - post { - always { - archiveArtifacts artifacts: 'rsr-report.txt', allowEmptyArchive: true - } - } -} ----- - -==== CircleCI - -[source,yaml] ----- -# .circleci/config.yml -version: 2.1 - -jobs: - rsr-compliance: - docker: - - image: rust:1.75 - steps: - - checkout - - restore_cache: - keys: - - aletheia-{{ .Branch }} - - run: - name: Install Aletheia - command: cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - - save_cache: - key: aletheia-{{ .Branch }} - paths: - - ~/.cargo/bin/aletheia - - run: - name: Verify RSR Compliance - command: aletheia - -workflows: - version: 2 - build: - jobs: - - rsr-compliance ----- - -=== System-Wide Installation - -==== Linux (systemd) - -[source,bash] ----- -# Install binary -sudo cp target/release/aletheia /usr/local/bin/ - -# Create systemd service for scheduled checks -cat < ~/Library/LaunchAgents/org.maa-framework.aletheia.plist - - - - - Label - org.maa-framework.aletheia - ProgramArguments - - /usr/local/bin/aletheia - /path/to/repositories - - StartCalendarInterval - - Hour - 9 - Minute - 0 - - - -EOF - -# Load LaunchAgent -launchctl load ~/Library/LaunchAgents/org.maa-framework.aletheia.plist ----- - -=== Cloud Deployment - -==== AWS Lambda - -[source,python] ----- -# lambda_function.py -import subprocess -import json - -def lambda_handler(event, context): - """ - AWS Lambda function to run Aletheia verification - """ - repo_path = event.get('repo_path', '/tmp/repo') - - # Run aletheia - result = subprocess.run( - ['/opt/aletheia', repo_path], - capture_output=True, - text=True - ) - - return { - 'statusCode': 200 if result.returncode == 0 else 400, - 'body': json.dumps({ - 'compliant': result.returncode == 0, - 'output': result.stdout, - 'error': result.stderr if result.returncode != 0 else None - }) - } ----- - -==== Google Cloud Functions - -[source,python] ----- -# main.py -import subprocess -from flask import jsonify - -def verify_rsr(request): - """ - Google Cloud Function to run Aletheia verification - """ - request_json = request.get_json() - repo_path = request_json.get('repo_path', '/tmp/repo') - - result = subprocess.run( - ['/usr/local/bin/aletheia', repo_path], - capture_output=True, - text=True - ) - - return jsonify({ - 'compliant': result.returncode == 0, - 'output': result.stdout, - 'error': result.stderr if result.returncode != 0 else None - }) ----- - -==== Kubernetes - -[source,yaml] ----- -# kubernetes/deployment.yaml -apiVersion: batch/v1 -kind: CronJob -metadata: - name: aletheia-rsr-check -spec: - schedule: "0 9 * * *" # Daily at 9 AM - jobTemplate: - spec: - template: - spec: - containers: - - name: aletheia - image: aletheia:0.1.0 - volumeMounts: - - name: repo - mountPath: /repo - readOnly: true - volumes: - - name: repo - hostPath: - path: /path/to/repositories - restartPolicy: OnFailure ----- - -=== Air-Gapped Environments - -==== Offline Installation - -[source,bash] ----- -# On a machine with internet access: - -# 1. Clone repository -git clone https://gitlab.com/maa-framework/6-the-foundation/aletheia.git -cd aletheia - -# 2. Download Rust toolchain -rustup toolchain install 1.75 --offline - -# 3. Build binary -cargo build --release --target x86_64-unknown-linux-musl - -# 4. Create tarball -tar -czf aletheia-offline.tar.gz \ - target/x86_64-unknown-linux-musl/release/aletheia \ - README.md \ - LICENSE.txt \ - docs/ - -# Transfer aletheia-offline.tar.gz to air-gapped environment - -# On air-gapped machine: -tar -xzf aletheia-offline.tar.gz -sudo cp aletheia /usr/local/bin/ ----- - -==== Vendored Dependencies (Zero deps = already done!) - -[source,bash] ----- -# Aletheia has ZERO dependencies, so it works perfectly in air-gapped environments -# No cargo vendor needed! - -# Just copy the binary: -scp target/release/aletheia airgapped-machine:/usr/local/bin/ ----- - -=== Best Practices - -==== Security - -[arabic] -. *Verify checksums*: -+ -[source,bash] ----- -sha256sum aletheia > aletheia.sha256 -sha256sum -c aletheia.sha256 ----- -. *Use specific versions*: -+ -[source,bash] ----- -# Don't use :latest in production -docker pull aletheia:0.1.0 ----- -. *Run as non-root*: -+ -[source,dockerfile] ----- -USER nobody:nobody ----- - -==== Performance - -[arabic] -. *Cache installations*: -* Use Docker layer caching -* Cache cargo installations in CI/CD -. *Parallel verification*: -+ -[source,bash] ----- -find /repos -type d -maxdepth 1 | \ - parallel -j4 'aletheia {}' ----- - -==== Monitoring - -[arabic] -. *Log results*: -+ -[source,bash] ----- -aletheia | tee -a /var/log/aletheia.log ----- -. *Alert on failures*: -+ -[source,bash] ----- -aletheia || notify-send "RSR compliance failed" ----- - -=== Troubleshooting - -==== Issue: Binary not found - -[source,bash] ----- -# Check installation -which aletheia - -# Add to PATH -export PATH="$PATH:$HOME/.cargo/bin" ----- - -==== Issue: Permission denied - -[source,bash] ----- -# Make binary executable -chmod +x /path/to/aletheia ----- - -==== Issue: Old version - -[source,bash] ----- -# Force reinstall -cargo install --force --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git ----- - -=== Support - -* *Issues*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues -* *Documentation*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia -* *Email*: maintainers@maa-framework.org - -''''' - -_Deploy Aletheia everywhere - verify truth everywhere!_ diff --git a/aletheia/docs/FAQ.adoc b/aletheia/docs/FAQ.adoc deleted file mode 100644 index bc4c58f..0000000 --- a/aletheia/docs/FAQ.adoc +++ /dev/null @@ -1,348 +0,0 @@ -== Frequently Asked Questions (FAQ) - -=== General Questions - -==== What is Aletheia? - -Aletheia (Greek: ἀλήθεια - "`truth`", "`disclosure`", "`unconcealment`") -is a zero-dependency Rust tool for verifying Rhodium Standard Repository -(RSR) compliance. It checks repositories against rigorous standards for -security, documentation, and operational excellence. - -==== What is RSR? - -RSR (Rhodium Standard Repository) is a framework defining graduated -standards for software repositories. It covers type safety, memory -safety, security, documentation, build systems, and testing. See -RSR-SPECIFICATION.md for details. - -==== Why "`Aletheia`"? - -"`Aletheia`" is ancient Greek for "`truth`" or "`unconcealment`" - not -merely factual correctness, but the revealing of reality. In software, -this means transparent processes, verifiable standards, and honest -documentation. - -==== Why "`Rhodium`"? - -Rhodium is a rare, valuable, durable precious metal. Like rhodium, -high-quality software repositories are rare, valuable, and built to -last. - -=== Installation & Usage - -==== How do I install Aletheia? - -[source,bash] ----- -# From source (recommended) -git clone https://gitlab.com/maa-framework/6-the-foundation/aletheia.git -cd aletheia -cargo build --release - -# Or install directly -cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git ----- - -==== How do I use Aletheia? - -[source,bash] ----- -# Verify current directory -cargo run - -# Verify specific repository -cargo run -- /path/to/repository ----- - -==== What languages does Aletheia support? - -Aletheia is language-agnostic. It checks documentation, structure, and -build systems - not code itself. Works with: - Rust - Python - -JavaScript/TypeScript - Go - Any language with proper documentation - -==== Can I use Aletheia in CI/CD? - -Yes! Aletheia exits with code 0 on success, 1 on failure: - -[source,yaml] ----- -# GitLab CI -rsr-compliance: - script: - - aletheia ----- - -=== Technical Questions - -==== Why zero dependencies? - -Zero dependencies provides: 1. *Security*: No supply chain attacks 2. -*Auditability*: Easy to review entire codebase 3. *Reliability*: No -dependency breakage 4. *Simplicity*: Fewer moving parts 5. *Trust*: -Users can verify everything - -==== Why no unsafe code? - -No unsafe code means: 1. *Safety*: Rust’s guarantees apply everywhere 2. -*Trust*: No hidden memory bugs 3. *Simplicity*: No manual memory -management 4. *Auditability*: No special cases to review - -==== Why offline-first? - -Offline-first ensures: 1. *Privacy*: Cannot exfiltrate data 2. -*Reliability*: Works without internet 3. *Speed*: No network latency 4. -*Security*: No remote code execution 5. *Trust*: Users control all -inputs - -==== How fast is Aletheia? - -Very fast - typically <50ms for most repositories. Bottleneck is -filesystem I/O (stat calls). - -==== How much memory does Aletheia use? - -Minimal - typically <5MB RAM. Only stores check results in memory. - -=== Compliance Questions - -==== What compliance levels exist? - -* *Bronze* (current): Foundation - docs, security, build system -* *Silver* (planned): Formal verification, advanced security -* *Gold* (planned): Multi-language, distributed systems -* *Platinum* (planned): Enterprise, CADRE integration - -==== What does Bronze compliance require? - -Bronze requires: - ✅ 7 documentation files (README, LICENSE, SECURITY, -etc.) - ✅ .well-known directory (security.txt, ai.txt, humans.txt) - ✅ -Build system (Justfile, flake.nix, CI/CD) - ✅ Source structure (src/, -tests/) - -See RSR-SPECIFICATION.md for details. - -==== How do I make my repository compliant? - -[arabic] -. Run `+aletheia+` to see what’s missing -. Create missing files (see examples in Aletheia repo) -. Re-run `+aletheia+` to verify -. See QUICK_START.md for step-by-step guide - -==== Can I skip some requirements? - -No - all Bronze requirements are mandatory. However, you can: - Use -alternative build tools (alongside required ones) - Add additional -documentation - Exceed minimum standards - -==== What if I disagree with a requirement? - -The RSR specification is open for discussion: - Open an issue on the -specification repository - Propose changes via merge request - Join -community discussions - -=== Project Questions - -==== Who maintains Aletheia? - -Aletheia is maintained by the MAA Framework team. See -link:../MAINTAINERS.md[MAINTAINERS.md] for details. - -==== How can I contribute? - -See link:../../.github/CONTRIBUTING.md[CONTRIBUTING.md] for contribution -guidelines. We welcome: - Bug reports - Feature requests - Documentation -improvements - Code contributions - -==== What license is Aletheia under? - -Dual-licensed under your choice of: - MIT License - Palimpsest License -v0.8 - -See link:../LICENSE.txt[LICENSE.txt] for details. - -==== Is Aletheia production-ready? - -Yes, for Bronze-level verification. It’s: - Well-tested (100% test pass -rate) - Zero unsafe code - Zero dependencies - Self-verified (Aletheia -verifies itself) - -Silver/Gold/Platinum levels are planned for future releases. - -=== Security Questions - -==== How do I report a vulnerability? - -See link:../SECURITY.md[SECURITY.md] for: - Security contact email - -Confidential issue reporting - Response timeline - Disclosure process - -==== Has Aletheia been audited? - -Not yet. We welcome security audits! The codebase is: - ~300 lines of -Rust - Zero unsafe code - Zero dependencies - Easy to audit - -==== What’s the threat model? - -*In Scope*: - Malicious repository contents - Path traversal attacks - -Resource exhaustion - -*Out of Scope*: - Physical access - Compromised OS/kernel - Side-channel -attacks - -See link:../SECURITY.md[SECURITY.md] for full threat model. - -==== Can Aletheia be tricked? - -Known limitations: 1. Follows symbolic links (potential path traversal) -2. Could consume memory on very large files 3. TOCTOU races between -checks and file reads - -These are documented for transparency but not considered security -vulnerabilities in the current threat model. - -=== Development Questions - -==== Can I use Aletheia as a library? - -Currently, Aletheia is binary-only. Library API may be added in future -versions. - -==== How do I run tests? - -[source,bash] ----- -cargo test # Run all tests -cargo test -- --nocapture # See output -cargo test --release # Test optimized build ----- - -==== How do I build for different platforms? - -[source,bash] ----- -# Linux (glibc) -cargo build --release --target x86_64-unknown-linux-gnu - -# Linux (musl - static binary) -cargo build --release --target x86_64-unknown-linux-musl - -# macOS -cargo build --release --target x86_64-apple-darwin - -# Windows -cargo build --release --target x86_64-pc-windows-gnu ----- - -==== How do I add a new check? - -See link:../CLAUDE.md[CLAUDE.md] for development guide. Basic steps: - -[arabic] -. Add check function -. Call from `+verify_repository()+` -. Add tests -. Update documentation - -=== Philosophy Questions - -==== What is the TPCF? - -TPCF (Tri-Perimeter Contribution Framework) is a graduated trust model: -- *Perimeter 1*: Core maintainers (full access) - *Perimeter 2*: Trusted -contributors (review/merge rights) - *Perimeter 3*: Community sandbox -(open contribution) - -See link:../CODE_OF_CONDUCT.md[CODE_OF_CONDUCT.md] for details. - -==== What is the Palimpsest License? - -The Palimpsest License v0.8 is a permissive license embodying principles -of: - Reversibility (Git makes everything reversible) - Iteration -(constant improvement) - Impermanence (nothing is final) - History -preservation (layers remain visible) - -See link:../LICENSE-PALIMPSEST.txt[LICENSE-PALIMPSEST.txt] for full -text. - -==== Why focus on emotional safety? - -We believe healthy open source requires: - Psychological safety to -experiment - Safe to fail (mistakes are learning) - Safe to dissent -(respectful disagreement) - Reduced anxiety (reversibility helps) - -See link:../CODE_OF_CONDUCT.md[CODE_OF_CONDUCT.md] for our emotional -safety framework. - -=== Roadmap Questions - -==== What’s next for Aletheia? - -Planned features: - *v0.2.0*: Silver-level compliance checks - *v0.3.0*: -Gold-level compliance checks - *v0.4.0*: JSON output format - *v0.5.0*: -Configurable checks - *v1.0.0*: Platinum-level compliance - -==== When will Silver/Gold/Platinum be ready? - -No fixed timeline. We prioritize quality over speed. Follow: - -link:../CHANGELOG.md[CHANGELOG.md] for updates - -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues[Issues] -for progress - -==== Can I request features? - -Yes! Open an issue: - Describe the feature - Explain the use case - -Suggest implementation (optional) - -=== Troubleshooting - -==== Aletheia won’t compile - -Check: - -[source,bash] ----- -rustc --version # Should be 1.75+ -cargo --version ----- - -Update Rust: - -[source,bash] ----- -rustup update ----- - -==== Tests fail - -Run with verbose output: - -[source,bash] ----- -cargo test -- --nocapture ----- - -Check for: - Filesystem permissions - Correct working directory - -Updated Rust version - -==== Self-verification fails - -This shouldn’t happen! If it does: 1. Check which files are missing 2. -Verify you’re in Aletheia directory 3. Open an issue (this is a bug) - -==== CI/CD integration doesn’t work - -Check: - Aletheia installed correctly - Running in repository root - -Exit code checked (0 = success, 1 = failure) - -=== Still Have Questions? - -* *Documentation*: Browse link:.[docs/] directory -* *Issues*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues -* *Email*: maintainers@maa-framework.org - -''''' - -_"`The unexamined repository is not worth maintaining.`" - Adapted from -Socrates_ diff --git a/aletheia/docs/MIGRATION-GUIDE.adoc b/aletheia/docs/MIGRATION-GUIDE.adoc deleted file mode 100644 index 211c0ba..0000000 --- a/aletheia/docs/MIGRATION-GUIDE.adoc +++ /dev/null @@ -1,677 +0,0 @@ -== Migration Guide: Making Your Repository RSR-Compliant - -This guide helps you migrate an existing repository to RSR Bronze-level -compliance. - -=== Table of Contents - -[arabic] -. link:#assessment[Assessment] -. link:#documentation-migration[Documentation Migration] -. link:#security-setup[Security Setup] -. link:#build-system[Build System] -. link:#source-organization[Source Organization] -. link:#testing[Testing] -. link:#verification[Verification] - -=== Assessment - -==== Step 1: Run Initial Assessment - -[source,bash] ----- -# Clone and install Aletheia -git clone https://gitlab.com/maa-framework/6-the-foundation/aletheia.git -cd aletheia -cargo install --path . - -# Assess your repository -cd /path/to/your/repository -aletheia . ----- - -You’ll see output like: - -.... -🔍 Aletheia - RSR Compliance Verification Report -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Repository: /path/to/your/repository - -📋 Documentation - ✅ README.md [Bronze] - ❌ LICENSE.txt [Bronze] - ❌ SECURITY.md [Bronze] - ❌ CONTRIBUTING.md [Bronze] - ❌ CODE_OF_CONDUCT.md [Bronze] - ❌ MAINTAINERS.md [Bronze] - ❌ CHANGELOG.md [Bronze] - -... - -Score: 3/16 checks passed (18.8%) -⚠️ Bronze-level RSR compliance: NOT MET -.... - -==== Step 2: Create Checklist - -Based on the output, create a checklist of missing items: - -[source,markdown] ----- -## Migration Checklist - -### Documentation -- [ ] LICENSE.txt -- [ ] SECURITY.md -- [ ] CONTRIBUTING.md -- [ ] CODE_OF_CONDUCT.md -- [ ] MAINTAINERS.md -- [ ] CHANGELOG.md - -### .well-known -- [ ] .well-known/security.txt -- [ ] .well-known/ai.txt -- [ ] .well-known/humans.txt - -### Build System -- [ ] Justfile -- [ ] flake.nix -- [ ] .gitlab-ci.yml (or GitHub Actions) - -### Source Structure -- [ ] Organize into src/ -- [ ] Create tests/ directory ----- - -=== Documentation Migration - -==== LICENSE.txt - -*If you already have a license:* - -[source,bash] ----- -# Rename existing license -mv LICENSE LICENSE.txt - -# Or create dual-license -cat > LICENSE.txt << 'EOF' -# Dual License - -This project is dual-licensed under: -- MIT License (see LICENSE-MIT.txt) -- Apache License 2.0 (see LICENSE-APACHE.txt) - -Choose the license that best fits your needs. -EOF ----- - -*If you need to choose a license:* - -[source,bash] ----- -# MIT License (recommended for maximum compatibility) -curl -o LICENSE-MIT.txt https://opensource.org/licenses/MIT - -# Or Apache 2.0 -curl -o LICENSE-APACHE.txt https://www.apache.org/licenses/LICENSE-2.0.txt ----- - -==== SECURITY.md - -[source,bash] ----- -# Create from template -cat > SECURITY.md << 'EOF' -# Security Policy - -## Supported Versions - -| Version | Supported | -| ------- | ------------------ | -| 1.x.x | :white_check_mark: | -| < 1.0 | :x: | - -## Reporting a Vulnerability - -Please report security vulnerabilities to: security@example.org - -**DO NOT** create public issues for security vulnerabilities. - -### Response Timeline - -- Acknowledgment: Within 48 hours -- Assessment: Within 7 days -- Fix: 30 days for critical, 90 days for others - -See [.well-known/security.txt](.well-known/security.txt) for more details. -EOF ----- - -==== CONTRIBUTING.md - -[source,bash] ----- -# Create from template -cat > CONTRIBUTING.md << 'EOF' -# Contributing - -Thank you for your interest in contributing! - -## Quick Start - -1. Fork the repository -2. Create a feature branch: `git checkout -b feature/my-feature` -3. Make your changes -4. Test your changes -5. Commit with clear messages -6. Push and create a pull request - -## Code Style - -- Follow existing code style -- Write tests for new features -- Update documentation - -## Pull Request Process - -1. Ensure all tests pass -2. Update documentation -3. Add entry to CHANGELOG.md -4. Request review from maintainers - -## Code of Conduct - -See [CODE_OF_CONDUCT.md](CODE_OF_CONDUCT.md) -EOF ----- - -==== CODE_OF_CONDUCT.md - -[source,bash] ----- -# Use Contributor Covenant -curl -o CODE_OF_CONDUCT.md https://www.contributor-covenant.org/version/2/1/code_of_conduct/code_of_conduct.md ----- - -==== MAINTAINERS.md - -[source,bash] ----- -cat > MAINTAINERS.md << 'EOF' -# Maintainers - -## Current Maintainers - -**[Your Name]** -- Role: Project Lead -- Email: you@example.org -- GitHub: @yourhandle - -## Becoming a Maintainer - -Maintainers are invited based on sustained contributions. - -Criteria: -- 10+ merged PRs -- 3+ months of engagement -- Alignment with project values - -## Decision Making - -- Minor changes: Single maintainer approval -- Major changes: Consensus among maintainers -- Emergency: Any maintainer can act, notify others within 24h -EOF ----- - -==== CHANGELOG.md - -[source,bash] ----- -cat > CHANGELOG.md << 'EOF' -# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added -- RSR Bronze-level compliance - -## [1.0.0] - YYYY-MM-DD - -### Added -- Initial release -EOF ----- - -=== Security Setup - -==== Create .well-known Directory - -[source,bash] ----- -mkdir -p .well-known ----- - -==== security.txt (RFC 9116) - -[source,bash] ----- -cat > .well-known/security.txt << 'EOF' -Contact: mailto:security@example.org -Expires: 2026-12-31T23:59:59.000Z -Preferred-Languages: en -Canonical: https://example.org/.well-known/security.txt -Policy: https://example.org/security-policy -EOF ----- - -*Important*: Update expiration date and contact info! - -==== ai.txt - -[source,bash] ----- -cat > .well-known/ai.txt << 'EOF' -# AI Training and Usage Policy - -License: MIT -Training: Allowed with attribution -Usage: Commercial and non-commercial use permitted -Attribution: Please credit the project - -Contact: ai-policy@example.org -EOF ----- - -==== humans.txt - -[source,bash] ----- -cat > .well-known/humans.txt << 'EOF' -/* TEAM */ - -Project: Your Project Name -Purpose: Your project purpose -Team: Your team members -Contact: contact@example.org - -/* THANKS */ - -Contributors: See GitHub contributors page -Tools: Rust, Cargo, Just, Nix - -/* SITE */ - -Repository: https://github.com/yourorg/yourproject -License: MIT -Last Updated: YYYY-MM-DD -EOF ----- - -=== Build System - -==== Justfile - -[source,bash] ----- -cat > Justfile << 'EOF' -# Build automation with Just - -default: - @just --list - -build: - cargo build - -build-release: - cargo build --release - -test: - cargo test - -check: - cargo fmt --check - cargo clippy -- -D warnings - cargo test - -run: - cargo run - -clean: - cargo clean -EOF ----- - -==== flake.nix (for Nix users) - -[source,bash] ----- -cat > flake.nix << 'EOF' -{ - description = "Your project description"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - rust-overlay.url = "github:oxalica/rust-overlay"; - }; - - outputs = { self, nixpkgs, rust-overlay }: - let - system = "x86_64-linux"; - pkgs = import nixpkgs { - inherit system; - overlays = [ (import rust-overlay) ]; - }; - in - { - devShells.${system}.default = pkgs.mkShell { - buildInputs = with pkgs; [ - rust-bin.stable.latest.default - just - ]; - }; - }; -} -EOF ----- - -==== CI/CD (.gitlab-ci.yml or GitHub Actions) - -*GitLab CI:* - -[source,bash] ----- -cat > .gitlab-ci.yml << 'EOF' -stages: - - check - - test - - build - -format:check: - stage: check - image: rust:latest - script: - - cargo fmt --check - -clippy:check: - stage: check - image: rust:latest - script: - - cargo clippy -- -D warnings - -test: - stage: test - image: rust:latest - script: - - cargo test - -build: - stage: build - image: rust:latest - script: - - cargo build --release - artifacts: - paths: - - target/release/ -EOF ----- - -*GitHub Actions:* - -[source,bash] ----- -mkdir -p .github/workflows -cat > .github/workflows/ci.yml << 'EOF' -name: CI - -on: [push, pull_request] - -jobs: - check: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - run: cargo fmt --check - - run: cargo clippy -- -D warnings - - test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - run: cargo test - - build: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v3 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - run: cargo build --release -EOF ----- - -=== Source Organization - -==== Reorganize Source Files - -[source,bash] ----- -# Create directories -mkdir -p src tests - -# Move source files (example for Rust) -mv *.rs src/ 2>/dev/null || true - -# Create a basic main.rs if needed -cat > src/main.rs << 'EOF' -fn main() { - println!("Hello, RSR!"); -} -EOF - -# Create a basic test -cat > tests/integration_test.rs << 'EOF' -#[test] -fn test_basic() { - assert_eq!(2 + 2, 4); -} -EOF ----- - -=== Testing - -==== Add Tests - -[source,bash] ----- -# For Rust -cat >> src/lib.rs << 'EOF' -#[cfg(test)] -mod tests { - #[test] - fn test_something() { - assert!(true); - } -} -EOF - -# Run tests -cargo test ----- - -=== Verification - -==== Final Verification - -[source,bash] ----- -# Run Aletheia -aletheia . - -# Should see: -# 16/16 checks passed (100.0%) -# 🏆 Bronze-level RSR compliance: ACHIEVED ----- - -==== Commit Changes - -[source,bash] ----- -git add . -git commit -m "feat: achieve RSR Bronze-level compliance - -- Add complete documentation suite -- Create .well-known directory with security.txt -- Set up build automation (Justfile, flake.nix) -- Add CI/CD pipeline -- Organize source structure -- Add comprehensive tests - -Verified with Aletheia - 16/16 checks passed" ----- - -=== Common Issues - -==== Issue: Multiple license files - -*Problem*: You have `+LICENSE+`, `+LICENSE.md+`, and `+LICENSE.txt+` - -*Solution*: - -[source,bash] ----- -# Choose one format, use LICENSE.txt -mv LICENSE LICENSE.txt -rm LICENSE.md # If redundant ----- - -==== Issue: Tests in wrong location - -*Problem*: Tests are in `+test/+` but Aletheia expects `+tests/+` - -*Solution*: - -[source,bash] ----- -mv test tests ----- - -==== Issue: Missing Cargo.toml - -*Problem*: Rust project without Cargo.toml - -*Solution*: - -[source,bash] ----- -cargo init --name your-project-name ----- - -=== Language-Specific Guides - -==== Python Projects - -[source,bash] ----- -# Create src/ -mkdir -p src tests - -# Move Python files -mv *.py src/ - -# Create __init__.py -touch src/__init__.py - -# Create basic test -cat > tests/test_basic.py << 'EOF' -def test_example(): - assert True -EOF - -# Create Justfile for Python -cat > Justfile << 'EOF' -test: - pytest - -lint: - flake8 src/ - mypy src/ - -format: - black src/ tests/ -EOF ----- - -==== JavaScript/TypeScript - -[source,bash] ----- -# Create directories -mkdir -p src tests - -# Move source files -mv *.ts src/ 2>/dev/null || true -mv *.js src/ 2>/dev/null || true - -# Create Justfile for Node -cat > Justfile << 'EOF' -build: - npm run build - -test: - npm test - -lint: - npm run lint - -format: - npm run format -EOF ----- - -=== Timeline - -Typical migration timeline: - -* *Day 1*: Assessment and planning (1-2 hours) -* *Day 2*: Documentation (2-3 hours) -* *Day 3*: Security and .well-known (1 hour) -* *Day 4*: Build system and CI/CD (2-3 hours) -* *Day 5*: Source organization and testing (2-4 hours) -* *Day 6*: Verification and cleanup (1 hour) - -*Total*: 10-15 hours for most projects - -=== Resources - -* link:RSR-SPECIFICATION.md[RSR Specification] -* https://gitlab.com/maa-framework/6-the-foundation/aletheia[Aletheia -Documentation] -* https://keepachangelog.com/[Keep a Changelog] -* https://www.contributor-covenant.org/[Contributor Covenant] -* https://www.rfc-editor.org/rfc/rfc9116.html[RFC 9116 (security.txt)] - -=== Support - -Need help with migration? - -* *Issues*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues -* *Email*: maintainers@maa-framework.org - -''''' - -_Make your repository RSR-compliant - pursue alētheia!_ diff --git a/aletheia/docs/PRIORITIES.adoc b/aletheia/docs/PRIORITIES.adoc deleted file mode 100644 index aa0d743..0000000 --- a/aletheia/docs/PRIORITIES.adoc +++ /dev/null @@ -1,258 +0,0 @@ -== Aletheia Project Priorities - -*Snapshot Date*: 2025-12-26 (Updated) *Current Version*: 0.1.x -*Compliance Status*: 16/16 Bronze RSR (100%) *Codebase Size*: ~810 lines -(main.rs) + ~480 lines (tests) - -''''' - -=== Current State Assessment - -==== Strengths - -[width="100%",cols="29%,38%,33%",options="header",] -|=== -|Area |Status |Notes -|Zero Dependencies |Achieved |Only std library -|Zero Unsafe Code |Achieved |100% safe Rust -|Self-Verification |Passing |16/16 checks -|Test Coverage |Excellent |28 tests (10 unit + 18 integration) -|Security Features |Implemented |Symlink detection, timestamps, warnings -|Documentation |Complete |All required docs present -|Build Systems |Complete |Cargo, Just, Nix, CI/CD -|CLI Features |Complete |JSON, quiet, verbose, exit codes -|Security Audit |Complete |2025-12-26, 0 vulnerabilities -|=== - -==== Technical Debt - -[width="100%",cols="24%,38%,38%",options="header",] -|=== -|Item |Severity |Location -|Timestamp impl is verbose |Low |`+format_timestamp()+` - 50 lines for -date math - -|Some `+#[allow(dead_code)]+` |Low |Reserved for future use -|=== - -''''' - -=== MUST (Critical - Do First) - -==== Immediate (Before v0.1.0 Release) - COMPLETED - -[arabic] -. [line-through]#*Tag and Release v0.1.0*# ✅ COMPLETED -* Current state is release-ready -* Tag: `+git tag -a v0.1.0 -m "Initial release"+` -* Create release notes from CHANGELOG.md -. *Verify CI/CD Pipeline Works* - PENDING -* `+.gitlab-ci.yml+` exists but untested in production -* Run full pipeline before announcing release -* Fix any blocking issues -. [line-through]#*Update CHANGELOG.md*# ✅ COMPLETED -* Document security improvements from this audit -* Add symlink detection feature -* Add timestamp feature -. [line-through]#*Security Audit Documentation*# ✅ COMPLETED -* Update SECURITY.md "`Last Audit`" section -* Document that audit was performed 2025-12-26 -* Note zero vulnerabilities found - -==== Before v0.2.0 - COMPLETED - -[arabic, start=5] -. [line-through]#*Add JSON Output Format*# ✅ COMPLETED -* `+--format json+` flag implemented -* Machine-parseable results -* CI/CD ready -. [line-through]#*Exit Codes for Categories*# ✅ COMPLETED -* 0 = success (all checks passed) -* 1 = compliance failure -* 2 = security warning (critical) -* 3 = invalid path -* 4 = invalid arguments - -''''' - -=== SHOULD (Important - Do Soon) - -==== v0.2.0 - v0.3.0 Timeframe - -[arabic, start=7] -. *Configuration File Support* - PENDING -* `+.aletheia.toml+` or `+.aletheia.yaml+` -* Allow ignoring specific checks -* Custom severity levels -* Per-project overrides -. *SARIF Output* - PENDING -* Static Analysis Results Interchange Format -* GitHub/GitLab security dashboard integration -* Industry standard for security tools -. [line-through]#*Quiet and Verbose Modes*# ✅ COMPLETED -* `+--quiet+` - Only show pass/fail -* `+--verbose+` - Show all details including explanations -* Help text: `+--help+` -. *Better Error Messages* - PENDING -* Current: "`Path does not exist`" -* Better: "`Path '`/foo/bar`' does not exist. Did you mean -'`/foo/baz`'?`" -* Suggest fixes for common issues -. *README.md Generation* - PENDING -* `+aletheia init+` command -* Generate missing Bronze-level files -* Template-based scaffolding -. [line-through]#*GitHub Actions Workflow*# ✅ COMPLETED -* `+.github/workflows/aletheia.yml+` template provided -* Easy adoption for GitHub users -* Multi-platform support -. [line-through]#*Performance Benchmarks*# ✅ COMPLETED -* `+benches/verification_benchmark.rs+` fully implemented -* Measures verification speed (~12ms avg) -* Tracks min/max/avg with warmup -. [line-through]#*More Integration Tests*# ✅ COMPLETED -* 18 integration tests total -* Tests: JSON output, quiet/verbose modes, exit codes -* Tests: timestamp format, README.adoc alternative -* Tests: invalid args, invalid paths, format syntax - -''''' - -=== COULD (Nice to Have - Do Later) - -==== v0.4.0 - v0.6.0 Timeframe - -[arabic, start=15] -. *Silver-Level RSR Checks* -* Formal verification hooks -* Property-based testing detection -* Coverage thresholds -* Mutation testing validation -. *Multi-Language Detection* -* Detect project language (Rust, Python, Go, etc.) -* Language-specific checks -* Build system detection -. *HTML Report Generation* -* Visual compliance report -* Shareable dashboard -* Badge generation -. *Watch Mode* -* `+aletheia watch+` -* Re-verify on file changes -* Developer feedback loop -. *Library API* -* Currently binary-only -* Expose as library crate -* Programmatic verification -. *Incremental Verification* -* Cache previous results -* Only re-check changed files -* Faster CI runs -. *Batch Verification* -* `+aletheia scan /path/to/repos/*+` -* Verify multiple repos at once -* Summary report - -==== v0.7.0+ (Long-term) - -[arabic, start=22] -. *Gold-Level RSR* -* Multi-language support -* Polyglot build systems -* Cross-language dependencies -. *Platinum-Level RSR* -* CADRE integration -* Formal proofs -* Enterprise features -. *Plugin Architecture* -* Custom check modules -* Third-party extensions -* Language-specific plugins -. *LSP Integration* -* IDE feedback -* Real-time compliance hints -* Editor extensions - -''''' - -=== Anti-Priorities (MUST NOT) - -These violate RSR Bronze principles and must NEVER be done: - -[cols=",",options="header",] -|=== -|Anti-Priority |Reason -|Add external dependencies |Violates zero-dependency principle -|Use `+unsafe+` code |Violates memory safety guarantee -|Make network requests |Violates offline-first principle -|Phone home / telemetry |Privacy violation -|Break single-binary |Deployment complexity -|Remove existing tests |Quality regression -|=== - -''''' - -=== Recommended Next Actions - -==== This Week - -[arabic] -. [line-through]#Update CHANGELOG.md with security audit results# ✅ -DONE -. Tag v0.1.0 release -. Verify GitLab CI/CD pipeline - -==== This Month - -[arabic, start=4] -. [line-through]#Implement `+--format json+`# ✅ DONE -. [line-through]#Add distinct exit codes# ✅ DONE -. [line-through]#Write more integration tests# ✅ DONE (18 total) -. Configuration file support (`+.aletheia.toml+`) -. SARIF output format - -==== This Quarter - -[arabic, start=9] -. Silver-level RSR planning -. `+aletheia init+` scaffolding command -. Better error messages with suggestions -. Library API (programmatic usage) - -''''' - -=== Metrics to Track - -[cols=",,",options="header",] -|=== -|Metric |Current |Target (v1.0) -|Lines of Code |~810 |<1000 -|Unit Tests |10 |25+ -|Integration Tests |18 |20+ -|Dependencies |0 |0 -|Unsafe Blocks |0 |0 -|Bronze Compliance |100% |100% -|Clippy Warnings |0 |0 -|Security Audit |Complete |Annual -|=== - -''''' - -=== Decision Log - -[width="100%",cols="23%,37%,40%",options="header",] -|=== -|Date |Decision |Rationale -|2025-12-26 |Add symlink detection |Security: prevent repo escape - -|2025-12-26 |Add timestamps |TOCTOU mitigation - -|2025-12-26 |Accept README.adoc |Flexibility for AsciiDoc users - -|2025-12-26 |Critical warnings fail verification |Security-first -approach -|=== - -''''' - -*Last Updated*: 2025-12-26 *Next Review*: After v0.1.0 release diff --git a/aletheia/docs/QUICK_START.adoc b/aletheia/docs/QUICK_START.adoc deleted file mode 100644 index 1cbdcba..0000000 --- a/aletheia/docs/QUICK_START.adoc +++ /dev/null @@ -1,353 +0,0 @@ -== Quick Start Guide - -Get started with Aletheia in 5 minutes. - -=== Installation - -==== Option 1: Build from Source (Recommended) - -[source,bash] ----- -# Clone the repository -git clone https://gitlab.com/maa-framework/6-the-foundation/aletheia.git -cd aletheia - -# Build release binary -cargo build --release - -# Run verification -cargo run ----- - -==== Option 2: Using Nix (Reproducible Build) - -[source,bash] ----- -# Clone the repository -git clone https://gitlab.com/maa-framework/6-the-foundation/aletheia.git -cd aletheia - -# Enter development environment -nix develop - -# Build and run -just build -just run ----- - -==== Option 3: Direct Installation - -[source,bash] ----- -# Install directly from repository -cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git ----- - -=== First Verification - -==== Verify Current Directory - -[source,bash] ----- -cargo run ----- - -This verifies the current directory against RSR Bronze-level standards. - -==== Verify Specific Repository - -[source,bash] ----- -cargo run -- /path/to/your/repository ----- - -=== Understanding the Output - -==== Passing Example - -.... -🔍 Aletheia - RSR Compliance Verification Report -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Repository: /home/user/my-project - -📋 Documentation - ✅ README.md [Bronze] - ✅ LICENSE.txt [Bronze] - ✅ SECURITY.md [Bronze] - ✅ CONTRIBUTING.md [Bronze] - ✅ CODE_OF_CONDUCT.md [Bronze] - ✅ MAINTAINERS.md [Bronze] - ✅ CHANGELOG.md [Bronze] - -📋 Well-Known - ✅ .well-known/ directory [Bronze] - ✅ security.txt [Bronze] - ✅ ai.txt [Bronze] - ✅ humans.txt [Bronze] - -📋 Build System - ✅ Justfile [Bronze] - ✅ flake.nix [Bronze] - ✅ .gitlab-ci.yml [Bronze] - -📋 Source Structure - ✅ src/ directory [Bronze] - ✅ tests/ directory [Bronze] - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Score: 16/16 checks passed (100.0%) -🏆 Bronze-level RSR compliance: ACHIEVED -.... - -*Exit code*: 0 (success) - -==== Failing Example - -.... -🔍 Aletheia - RSR Compliance Verification Report -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Repository: /home/user/incomplete-project - -📋 Documentation - ✅ README.md [Bronze] - ❌ LICENSE.txt [Bronze] - ❌ SECURITY.md [Bronze] - ... - -━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ -Score: 8/16 checks passed (50.0%) -⚠️ Bronze-level RSR compliance: NOT MET -.... - -*Exit code*: 1 (failure) - -=== Making Your Repository Compliant - -If your repository fails verification, follow these steps: - -==== 1. Create Missing Documentation - -[source,bash] ----- -# Required files -touch README.md -touch LICENSE.txt -touch SECURITY.md -touch CONTRIBUTING.md -touch CODE_OF_CONDUCT.md -touch MAINTAINERS.md -touch CHANGELOG.md ----- - -See link:../[examples in Aletheia repository] for content templates. - -==== 2. Create .well-known Directory - -[source,bash] ----- -mkdir -p .well-known -touch .well-known/security.txt -touch .well-known/ai.txt -touch .well-known/humans.txt ----- - -*security.txt* (RFC 9116 format): - -.... -Contact: mailto:security@example.org -Expires: 2026-01-01T00:00:00.000Z -Preferred-Languages: en -Canonical: https://example.org/.well-known/security.txt -.... - -*ai.txt* (AI training policy): - -.... -# AI Training Policy -License: MIT -Training: Allowed with attribution -.... - -*humans.txt* (attribution): - -.... -/* TEAM */ -Project: Your Project -Maintainers: Your Team -.... - -==== 3. Create Build System Files - -[source,bash] ----- -# Create Justfile -touch Justfile - -# Create flake.nix (for Nix users) -touch flake.nix - -# Create CI/CD -touch .gitlab-ci.yml # or .github/workflows/ci.yml ----- - -==== 4. Organize Source Structure - -[source,bash] ----- -# Create required directories -mkdir -p src -mkdir -p tests - -# Move source files to src/ -mv *.rs src/ # (or your language) ----- - -==== 5. Re-verify - -[source,bash] ----- -cargo run ----- - -=== Using with CI/CD - -==== GitLab CI - -[source,yaml] ----- -# .gitlab-ci.yml -rsr-compliance: - stage: test - image: rust:1.75 - script: - - cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - - aletheia - allow_failure: false ----- - -==== GitHub Actions - -[source,yaml] ----- -# .github/workflows/rsr.yml -name: RSR Compliance -on: [push, pull_request] -jobs: - verify: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v2 - - uses: actions-rs/toolchain@v1 - with: - toolchain: stable - - run: cargo install --git https://gitlab.com/maa-framework/6-the-foundation/aletheia.git - - run: aletheia ----- - -=== Development Workflow - -==== Using Just (Recommended) - -[source,bash] ----- -# List all commands -just - -# Build -just build - -# Run tests -just test - -# Run all checks -just check - -# Verify RSR compliance -just validate ----- - -==== Using Cargo Directly - -[source,bash] ----- -# Build -cargo build --release - -# Run tests -cargo test - -# Check formatting -cargo fmt --check - -# Run linter -cargo clippy - -# Verify -cargo run ----- - -=== Common Issues - -==== Issue: "`Path does not exist`" - -*Problem*: Specified path doesn’t exist - -*Solution*: - -[source,bash] ----- -# Check path -ls /path/to/repository - -# Use absolute path -cargo run -- /absolute/path/to/repository ----- - -==== Issue: "`Not a directory`" - -*Problem*: Path is a file, not a directory - -*Solution*: - -[source,bash] ----- -# Verify directory -cargo run -- /path/to/directory/ ----- - -==== Issue: Low compliance score - -*Problem*: Missing required files - -*Solution*: 1. Check which files are missing (marked with ❌) 2. Create -missing files 3. Re-run verification - -==== Issue: Tests not found - -*Problem*: No `+tests/+` directory - -*Solution*: - -[source,bash] ----- -mkdir tests -# Add test files ----- - -=== Next Steps - -* Read ARCHITECTURE.md - Understand how Aletheia works -* Read RSR-SPECIFICATION.md - Learn RSR standards -* Read link:../../.github/CONTRIBUTING.md[CONTRIBUTING.md] - Contribute to Aletheia - -=== Support - -* *Issues*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia/-/issues -* *Documentation*: -https://gitlab.com/maa-framework/6-the-foundation/aletheia -* *Email*: maintainers@maa-framework.org - -''''' - -_Start pursuing alētheia (truth) through rigorous standards!_ diff --git a/aletheia/docs/RSR-SPECIFICATION.adoc b/aletheia/docs/RSR-SPECIFICATION.adoc deleted file mode 100644 index 55b2e5b..0000000 --- a/aletheia/docs/RSR-SPECIFICATION.adoc +++ /dev/null @@ -1,352 +0,0 @@ -[WARNING] -==== -Superseded. This v0.1.0 specification predates the estate's RSR v2 -criteria and no longer defines anything: the normative criteria text is -`hyperpolymath/standards` `0-canon/rsr/rsr-criteria-v2.a2ml`, the -normative evaluator is the hypatia `rsr-conformance` oracle, and -aletheia's implemented subset is defined by the inventory table in -`src/checks.rs` (see `SSOT_PROVENANCE`). Do not extend this document — -it is retained for archaeology only. -==== - -== RSR (Rhodium Standard Repository) Specification - -=== Version 0.1.0 - -This document specifies the Rhodium Standard Repository (RSR) framework -compliance levels and requirements. - -=== Table of Contents - -[arabic] -. link:#overview[Overview] -. link:#compliance-levels[Compliance Levels] -. link:#bronze-level-requirements[Bronze Level Requirements] -. link:#silver-level-requirements[Silver Level Requirements] -. link:#gold-level-requirements[Gold Level Requirements] -. link:#platinum-level-requirements[Platinum Level Requirements] -. link:#tpcf-integration[TPCF Integration] - -=== Overview - -The Rhodium Standard Repository (RSR) framework defines a graduated set -of standards for software repositories, covering: - -* *Type Safety*: Compile-time correctness guarantees -* *Memory Safety*: Protection against memory vulnerabilities -* *Security*: Vulnerability disclosure and secure development -* *Documentation*: Comprehensive project documentation -* *Build System*: Reproducible, automated builds -* *Testing*: Comprehensive test coverage -* *Offline-First*: Air-gapped operation capability -* *Community*: Governance and contribution guidelines - -The name "`Rhodium`" references the precious metal’s properties: - -*Rare*: High standards are uncommon - *Valuable*: Quality software is -precious - *Durable*: Well-built software lasts - *Reflective*: -Standards help us see clearly - -=== Compliance Levels - -==== Level Hierarchy - -.... -Platinum (Highest) - ↑ - Gold - ↑ - Silver - ↑ - Bronze (Entry Level) -.... - -Each level builds upon the requirements of the previous level. - -=== Bronze Level Requirements - -*Goal*: Establish foundational quality, security, and documentation -standards. - -==== 1. Type Safety - -*Required*: Compile-time type checking - -* *Rust*: Use Rust 2021 edition or later (built-in type safety) -* *Other Languages*: Must have static type checking enabled -** TypeScript: `+strict: true+` in tsconfig.json -** Python: Type hints + mypy strict mode -** Go: Standard compiler (built-in) -** Haskell: GHC (built-in) - -==== 2. Memory Safety - -*Required*: Protection against memory vulnerabilities - -* *Rust*: Ownership model, zero `+unsafe+` blocks -* *Other Languages*: Memory-safe by design (GC languages) or formal -verification - -==== 3. Zero Dependencies (Language-Specific) - -*Required*: Minimal dependency footprint - -* *Interpreted Languages* (Python, JavaScript, Ruby): Use only standard -library -* *Compiled Languages* (Rust, Go): Zero external dependencies -* *Exceptions*: Build tools (cargo, npm) and dev dependencies for -testing are allowed - -==== 4. Offline-First - -*Required*: Works completely air-gapped - -* No network calls in core functionality -* No external API dependencies -* No analytics or telemetry -* All resources bundled or locally available - -==== 5. Documentation - -*Required Files*: - -* ✅ `+README.md+` - Project overview, quick start, usage -* ✅ `+LICENSE.txt+` - Open source license (MIT, Apache, GPL, etc.) -* ✅ `+SECURITY.md+` - Security policy and vulnerability disclosure -* ✅ `+CONTRIBUTING.md+` - Contribution guidelines -* ✅ `+CODE_OF_CONDUCT.md+` - Community standards -* ✅ `+MAINTAINERS.md+` - Project governance -* ✅ `+CHANGELOG.md+` - Version history (Keep a Changelog format) - -*Minimum Content*: - -* *README.md*: Purpose, quick start, installation, basic usage -* *LICENSE.txt*: Valid OSI-approved license -* *SECURITY.md*: Contact info, disclosure policy, response timeline -* *CONTRIBUTING.md*: How to contribute, code style, PR process -* *CODE_OF_CONDUCT.md*: Community standards (Contributor Covenant or -similar) -* *MAINTAINERS.md*: Who maintains the project, decision process -* *CHANGELOG.md*: Version history following Keep a Changelog - -==== 6. .well-known Directory - -*Required*: RFC 9116 compliance and metadata - -* ✅ `+.well-known/security.txt+` - RFC 9116 compliant security contact -* ✅ `+.well-known/ai.txt+` - AI training and usage policies -* ✅ `+.well-known/humans.txt+` - Human-readable attribution - -*security.txt Format*: - -.... -Contact: mailto:security@example.org -Expires: 2026-01-01T00:00:00.000Z -Preferred-Languages: en -Canonical: https://example.org/.well-known/security.txt -Policy: https://example.org/security-policy -.... - -==== 7. Build System - -*Required*: Automated, reproducible builds - -* ✅ `+justfile+` - Build automation (using Just) -* ✅ `+flake.nix+` - Nix reproducible builds -* ✅ `+.gitlab-ci.yml+` or `+.github/workflows/+` - CI/CD pipeline - -*Minimum Recipes*: - `+build+` - Build the project - `+test+` - Run all -tests - `+lint+` - Run linters - `+fmt+` - Format code - `+check+` - Run -all checks - -==== 8. Source Structure - -*Required*: Organized source code - -* ✅ `+src/+` directory - Source code -* ✅ `+tests/+` directory - Test files -* Clear separation of concerns -* Logical file organization - -==== 9. Testing - -*Required*: Comprehensive test suite - -* Unit tests for core functionality -* Integration tests for workflows -* 100% test pass rate (no skipped tests in default run) -* Tests run in CI/CD - -==== 10. Version Control - -*Required*: Git best practices - -* `+.gitignore+` - Ignore build artifacts -* Clear commit messages -* Semantic versioning (semver) -* Tagged releases - -==== 11. License Compliance - -*Required*: Clear, OSI-approved licensing - -* Valid open source license -* License file in root -* Copyright notices -* Dual licensing allowed (e.g., MIT OR Apache-2.0) - -=== Silver Level Requirements - -*Goal*: Add formal verification and advanced security. - -_(All Bronze requirements PLUS):_ - -==== 1. Formal Verification - -* Formal proofs of key algorithms -* Property-based testing (QuickCheck, PropTest) -* SPARK proofs (for Ada) -* TLA+ specifications (for distributed systems) - -==== 2. Security Hardening - -* Security audit completed -* Dependency scanning (if dependencies exist) -* SBOM (Software Bill of Materials) generation -* Signed releases - -==== 3. Advanced Documentation - -* Architecture Decision Records (ADRs) -* API documentation (rustdoc, JSDoc, etc.) -* Usage examples -* Performance benchmarks - -==== 4. Enhanced Testing - -* Mutation testing (cargo-mutants) -* Fuzzing tests -* Coverage >80% -* Benchmark suite - -=== Gold Level Requirements - -*Goal*: Multi-language verification and distributed systems support. - -_(All Silver requirements PLUS):_ - -==== 1. Multi-Language Support - -* FFI contracts for language boundaries -* WASM sandboxing for untrusted code -* Type-safe language interop - -==== 2. Distributed Systems - -* CRDT-based state management -* Offline-first data sync -* Conflict-free merging -* TLA+ formal specifications - -==== 3. Advanced Architecture - -* Modular plugin system -* Clean architecture boundaries -* Dependency injection -* Testable design - -=== Platinum Level Requirements - -*Goal*: Production-grade enterprise systems with full CADRE integration. - -_(All Gold requirements PLUS):_ - -==== 1. CADRE Integration - -* Conflict-free Asynchronous Data Replication Engine -* Production-tested at scale -* Multi-datacenter support -* Disaster recovery tested - -==== 2. Enterprise Features - -* Audit logging -* Role-based access control -* Compliance reporting (SOC2, GDPR, etc.) -* SLA guarantees - -==== 3. Operational Excellence - -* Monitoring and observability -* Incident response playbooks -* Disaster recovery procedures -* 24/7 support capability - -=== TPCF Integration - -RSR compliant repositories should operate under the Tri-Perimeter -Contribution Framework (TPCF): - -==== Perimeter 1: Inner Sanctum - -* Core maintainers -* Full repository access -* Decision-making authority - -==== Perimeter 2: Trusted Contributors - -* Regular contributors -* Review and merge permissions for specific areas -* Elevated trust level - -==== Perimeter 3: Community Sandbox - -* Open contribution -* Anyone can submit PRs -* All contributions reviewed - -=== Verification - -Projects can verify RSR compliance using: - -[source,bash] ----- -# Using Aletheia -aletheia /path/to/repository - -# Manual checklist -- Check all documentation files exist -- Verify .well-known directory -- Run build system -- Run tests -- Check for unsafe code -- Verify zero dependencies ----- - -=== Roadmap - -* *v0.1.0*: Bronze level specification (current) -* *v0.2.0*: Silver level specification -* *v0.3.0*: Gold level specification -* *v1.0.0*: Platinum level specification -* *v2.0.0*: Language-specific extensions - -=== References - -* https://www.rfc-editor.org/rfc/rfc9116.html[RFC 9116 - security.txt] -* https://keepachangelog.com/[Keep a Changelog] -* https://semver.org/[Semantic Versioning] -* https://www.contributor-covenant.org/[Contributor Covenant] -* https://gitlab.com/maa-framework/tpcf[TPCF Specification] - -=== Contributing to RSR - -The RSR specification itself is open for community input: - -* *Issues*: Suggest improvements -* *Discussions*: Debate requirements -* *Pull Requests*: Propose changes - -''''' - -*Version*: 0.1.0 *Last Updated*: 2025-11-22 *License*: CC-BY-4.0 -*Contact*: rsr@maa-framework.org diff --git a/aletheia/docs/SILVER-LEVEL.adoc b/aletheia/docs/SILVER-LEVEL.adoc deleted file mode 100644 index ff3590b..0000000 --- a/aletheia/docs/SILVER-LEVEL.adoc +++ /dev/null @@ -1,423 +0,0 @@ -== RSR Silver-Level Compliance (Future) - -*Status*: 🔄 Planned for v0.2.0 - -This document outlines the planned Silver-level RSR compliance -requirements. These extend Bronze-level requirements with formal -verification and advanced security. - -=== Overview - -Silver-level compliance builds upon Bronze by adding: - Formal -verification of critical code paths - Property-based testing - Advanced -security measures - Enhanced documentation - Performance guarantees - -=== Requirements - -==== 1. Formal Verification ⏳ - -===== SPARK Proofs (For Ada) - -[source,ada] ----- --- Example: Formally verified bounds checking -procedure Check_Bounds(Index : Natural; Max : Natural) - with Pre => Index <= Max, - Post => True -is -begin - -- Proof: Index is always within bounds - null; -end Check_Bounds; ----- - -===== TLA+ Specifications (For Distributed Systems) - -[source,tla] ----- ----- MODULE AletheiVerification ---- -EXTENDS Integers, Sequences - -VARIABLES repository, checks, status - -TypeInvariant == - /\ repository \in STRING - /\ checks \in Seq(CheckResult) - /\ status \in {"pending", "running", "complete"} - -Init == - /\ repository = "" - /\ checks = << >> - /\ status = "pending" - -RunCheck(check) == - /\ status = "running" - /\ checks' = Append(checks, check) - /\ UNCHANGED <> - -Complete == - /\ status' = "complete" - /\ UNCHANGED <> - -Next == - \/ \E check \in CheckResult : RunCheck(check) - \/ Complete - -Spec == Init /\ [][Next]_<> -==== ----- - -===== Property-Based Testing (QuickCheck/PropTest) - -[source,rust] ----- -// Example: Property-based test for check result accumulation -#[cfg(test)] -mod property_tests { - use quickcheck::{quickcheck, TestResult}; - - fn prop_check_count_never_decreases( - initial_count: usize, - added_checks: Vec - ) -> TestResult { - let mut report = ComplianceReport::new(PathBuf::from("/tmp")); - - for (i, passed) in added_checks.iter().enumerate() { - report.add_check( - "Test", - &format!("Check {}", i), - *passed, - ComplianceLevel::Bronze - ); - } - - TestResult::from_bool( - report.total_count() == added_checks.len() - ) - } - - #[test] - fn quickcheck_tests() { - quickcheck(prop_check_count_never_decreases as fn(usize, Vec) -> TestResult); - } -} ----- - -==== 2. Advanced Security ⏳ - -===== Security Audit - -* *Requirement*: Professional third-party security audit -* *Scope*: Full codebase review -* *Report*: Public audit report published -* *Remediation*: All findings addressed - -===== Dependency Scanning - -[source,toml] ----- -# cargo-audit configuration -[audit] -deny = ["unmaintained", "unsound", "yanked"] - -[advisories] -vulnerability = "deny" -unmaintained = "warn" -unsound = "warn" -yanked = "deny" ----- - -===== SBOM Generation - -[source,yaml] ----- -# Software Bill of Materials (SBOM) -# Generated automatically in CI/CD - -sbom: - stage: security - script: - - cargo install cargo-sbom - - cargo sbom > sbom.json - artifacts: - paths: - - sbom.json ----- - -===== Signed Releases - -[source,bash] ----- -# GPG-signed releases -git tag -s v0.2.0 -m "Release v0.2.0 (Silver-level)" -git push --tags - -# Verify signature -git tag -v v0.2.0 ----- - -==== 3. Enhanced Documentation ⏳ - -===== Architecture Decision Records (ADRs) - -[source,markdown] ----- -# ADR 001: Use Rust for Implementation - -## Status -Accepted - -## Context -Need a language with strong type safety and memory safety guarantees. - -## Decision -Use Rust for Aletheia implementation. - -## Consequences -- **Positive**: Memory safety, type safety, zero-cost abstractions -- **Negative**: Steeper learning curve for contributors -- **Neutral**: Requires Rust toolchain ----- - -===== API Documentation - -[source,rust] ----- -/// Verify repository against RSR Bronze-level standards. -/// -/// # Arguments -/// -/// * `repo_path` - Path to the repository to verify -/// -/// # Returns -/// -/// A `ComplianceReport` containing all check results. -/// -/// # Examples -/// -/// ``` -/// use std::path::Path; -/// let report = verify_repository(Path::new("/path/to/repo")); -/// assert!(report.bronze_compliance()); -/// ``` -/// -/// # Panics -/// -/// This function does not panic. -/// -/// # Errors -/// -/// Returns error if path does not exist or is not accessible. -pub fn verify_repository(repo_path: &Path) -> Result { - // Implementation -} ----- - -==== 4. Enhanced Testing ⏳ - -===== Mutation Testing - -[source,bash] ----- -# Using cargo-mutants -cargo install cargo-mutants -cargo mutants - -# Expected: High mutation kill rate (>80%) ----- - -===== Fuzzing - -[source,rust] ----- -// Fuzz testing for path handling -#[cfg(fuzzing)] -use libfuzzer_sys::fuzz_target; - -fuzz_target!(|data: &[u8]| { - if let Ok(path_str) = std::str::from_utf8(data) { - let path = PathBuf::from(path_str); - // Should never panic, even on malicious input - let _ = verify_repository(&path); - } -}); ----- - -===== Coverage Targets - -[source,yaml] ----- -# Minimum coverage: 80% -coverage: - stage: test - script: - - cargo tarpaulin --out Xml - - | - COVERAGE=$(grep -oP 'line-rate="\K[0-9.]+' cobertura.xml | head -1) - if (( $(echo "$COVERAGE < 0.8" | bc -l) )); then - echo "Coverage $COVERAGE < 80%" - exit 1 - fi ----- - -==== 5. Performance Guarantees ⏳ - -===== Benchmarking Suite - -[source,rust] ----- -// Criterion benchmarks (if dependencies allowed) -// For now, custom benchmarking - -const PERFORMANCE_TARGETS: &[(&str, u128)] = &[ - ("File existence check", 10), // 10μs - ("Directory check", 10), // 10μs - ("Single compliance check", 50), // 50μs - ("Full verification", 1000), // 1ms -]; ----- - -===== Memory Limits - -[source,rust] ----- -// Maximum memory usage: 10MB for typical repository -const MAX_MEMORY_BYTES: usize = 10 * 1024 * 1024; - -#[test] -fn test_memory_usage() { - // Track memory usage during verification - // Fail if exceeds limit -} ----- - -=== Implementation Plan - -==== Phase 1: Verification Foundation (v0.2.0) - -* [ ] Add property-based testing framework -* [ ] Implement TLA+ specification for verification logic -* [ ] Create formal proofs for critical functions -* [ ] Document all algorithms with invariants - -==== Phase 2: Security Enhancement (v0.2.1) - -* [ ] Complete professional security audit -* [ ] Implement SBOM generation -* [ ] Set up GPG signing for releases -* [ ] Add dependency scanning to CI/CD - -==== Phase 3: Documentation & Testing (v0.2.2) - -* [ ] Create ADRs for all major decisions -* [ ] Generate comprehensive API docs -* [ ] Implement mutation testing -* [ ] Add fuzz testing -* [ ] Achieve 80%+ code coverage - -==== Phase 4: Performance & Polish (v0.2.3) - -* [ ] Comprehensive benchmark suite -* [ ] Memory profiling -* [ ] Performance regression tests -* [ ] Optimization based on profiling - -=== Verification Checklist - -Silver-level compliance requires: - -* ✅ All Bronze-level requirements met -* ⏳ Formal verification of critical code -* ⏳ Property-based tests for all public APIs -* ⏳ Professional security audit completed -* ⏳ SBOM generated and published -* ⏳ Releases GPG-signed -* ⏳ ADRs for all major decisions -* ⏳ API documentation complete -* ⏳ Mutation testing implemented -* ⏳ Fuzz testing added -* ⏳ Code coverage >80% -* ⏳ Performance benchmarks established -* ⏳ Memory usage profiled and limited - -=== Migration from Bronze - -Existing Bronze-level repositories can upgrade to Silver by: - -[arabic] -. Adding property-based tests -. Creating formal specifications -. Completing security audit -. Generating SBOM -. Setting up signed releases -. Writing ADRs -. Expanding documentation -. Adding mutation/fuzz tests -. Achieving coverage targets -. Establishing performance baselines - -=== Tools Required - -==== Formal Verification - -* TLA+ Toolbox -* SPARK Pro (for Ada) -* Coq or Isabelle (for proof assistants) - -==== Testing - -* cargo-mutants (mutation testing) -* cargo-fuzz (fuzz testing) -* cargo-tarpaulin (coverage) - -==== Security - -* cargo-audit (dependency scanning) -* cargo-sbom (SBOM generation) -* GPG (release signing) - -==== Performance - -* cargo-bench (benchmarking) -* valgrind (memory profiling) -* perf (CPU profiling) - -=== Example Silver-Level Repository - -.... -silver-example/ -├── docs/ -│ ├── adr/ # Architecture Decision Records -│ │ ├── 001-use-rust.md -│ │ ├── 002-zero-deps.md -│ │ └── ... -│ ├── api/ # Generated API docs -│ └── proofs/ # Formal proofs -│ └── verification.tla -├── src/ -│ └── main.rs # With API docs -├── tests/ -│ ├── property_tests.rs # Property-based tests -│ └── fuzz_tests.rs # Fuzz tests -├── benches/ -│ └── benchmarks.rs # Performance benchmarks -├── security/ -│ ├── audit-2025.pdf # Security audit report -│ └── sbom.json # Software Bill of Materials -├── .cargo/ -│ └── audit.toml # cargo-audit config -└── (All Bronze-level files) -.... - -=== Resources - -* https://lamport.azurewebsites.net/tla/tla.html[TLA+ Homepage] -* https://www.adacore.com/about-spark[SPARK Ada] -* https://github.com/BurntSushi/quickcheck[QuickCheck for Rust] -* https://github.com/sourcefrog/cargo-mutants[Mutation Testing] -* https://www.fuzzingbook.org/[Fuzzing Book] - -''''' - -*Status*: Planning phase *Target Release*: v0.2.0 *Timeline*: TBD based -on community feedback diff --git a/aletheia/docs/VALUE-CHAIN-POLICY.adoc b/aletheia/docs/VALUE-CHAIN-POLICY.adoc deleted file mode 100644 index 03661ca..0000000 --- a/aletheia/docs/VALUE-CHAIN-POLICY.adoc +++ /dev/null @@ -1,204 +0,0 @@ -== Hyperpolymath Project Value Chain Policy - -This document defines the standard value chain model for all -Hyperpolymath projects. It is based on Porter’s Value Chain framework, -adapted for software development. - -=== Overview - -Every Hyperpolymath project has two types of activities: - -[arabic] -. *Support Activities* - Cross-cutting concerns that apply at all stages -. *Primary Activities* - The value flow from inputs to outputs - -=== Support Activities (Cross-Cutting) - -These apply horizontally across all primary activities: - -[width="100%",cols="34%,43%,23%",options="header",] -|=== -|Activity |Description |Tools -|*Technology* |CCCP stack (containers, runtime, shell) |Cerro Torre, -Svalinn, Valence Shell - -|*Formalizations* |Proofs, validation, verification |Absolute Zero, -Echidna, Coq/Lean/Z3 - -|*Standards* |Repository and code standards |RSR, CCCP, .scm files, -Palimpsest - -|*Infrastructure* |Build, CI/CD, deployment |mustfile, rhodium-pipeline, -GitLab CI -|=== - -=== Primary Activities (Value Flow) - -.... -┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ -│ INBOUND │ │ │ │ OUTBOUND │ │ MARKETING │ │ │ -│ LOGISTICS │──▶│ OPERATIONS │──▶│ LOGISTICS │──▶│ & SALES │──▶│ SERVICE │ -│ │ │ │ │ │ │ │ │ │ -│ Theoretical │ │ Core │ │ Outputs │ │ Standards │ │ Maintenance │ -│ foundations │ │ project │ │ & exports │ │ & business │ │ & ops │ -└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ -.... - -==== 1. Inbound Logistics - -*What*: Foundational inputs specific to the project’s domain - -Examples: - For Aletheia: Absolute Zero (CNO proofs, Landauer, Bennett) -- For rhodibot: RSR specification - For oikos: Economic/ecological -theory - -==== 2. Operations - -*What*: The core project work - what this repository actually builds - -Examples: - For Aletheia: Reversible Minix research (r-Minix precursor) -- For rhodibot: Compliance checking engine - For oikos: -Economic/ecological analyzer - -==== 3. Outbound Logistics - -*What*: Where outputs go - integration with CCCP stack or other projects - -Examples: - To CCCP technology stack (containers, runtime) - To -downstream projects - To future implementations (e.g., Aletheia → -r-Minix) - -==== 4. Marketing & Sales - -*What*: RSR ecosystem, maintenance strategies, business extensions - -Components: - *Corrective maintenance* - Bug fixes, issue resolution - -*Adaptive maintenance* - Platform/environment changes - *Perfective -maintenance* - Improvements, optimizations - -==== 5. Service - -*What*: Ongoing operational support via automation - -Tools: - *feedback-o-tron* - Feedback collection and processing - -*cicd-hyper-a* - CI/CD automation - *robot-repo-automaton* - Repository -automation - -=== Two Input Systems - -All projects receive inputs from two complementary systems: - -==== RSR - Rhodium Standard Repositories - -* *Layer*: Repository organization -* *Handles*: Documentation, security.txt, CI/CD, build systems -* *Tools*: rhodium-standard-repositories, rsr-template-repo, rhodibot, -rhodium-pipeline - -==== CCCP - Campaign for Cooling Coding and Programming - -* *Layer*: Technology stack and code -* *Handles*: Languages, containers, integrations, efficiency -* *Tools*: Cerro Torre, Svalinn, Valence Shell, rescript-tea, -cadre-router - -=== Project-Specific Foundations - -Each project may have domain-specific foundational inputs: - -[cols=",",options="header",] -|=== -|Project |Foundational Input -|Aletheia |Absolute Zero (CNO proofs, reversibility theory) -|Valence Shell |Absolute Zero (filesystem CNO proofs) -|Oikos |Economic/ecological theory -|Echidnabot |Formal methods, SAT/SMT solving -|=== - -=== Standard Files - -All properly configured projects include: - -==== AI Support Files (.scm - Guile Scheme) - -* `+META.scm+` - Project metadata -* `+ECOSYSTEM.scm+` - Ecosystem connections -* `+STATE.scm+` - Current project state -* `+PLAYBOOK.scm+` - Development workflows -* `+AGENTIC.scm+` - AI agent configuration -* `+NEUROSYM.scm+` - Neurosymbolic settings - -==== Build & Standards - -* `+mustfile+` - Build/task automation -* RSR compliance files (README, LICENSE, SECURITY.md, etc.) -* `+.well-known/+` directory - -==== Licensing - -* *Base*: MIT or AGPL (user choice) -* *Overlay*: Palimpsest License (optional but encouraged) - -=== Bot Ecosystem - -Projects are supported by bots operating in multiple modes: - -[cols=",",options="header",] -|=== -|Bot |Role -|*rhodibot* |RSR compliance (consultant, advisor, regulator) -|*echidnabot* |Formal proof validation -|*oikos bot* |Economic/ecological analysis -|=== - -Bots are *self-referential* - they validate their own code. - -=== Applying This Policy - -When setting up a new project: - -[arabic] -. Start with `+rsr-template-repo+` -. Apply customizations via `+repo-customiser+` -. Identify the project’s *foundational input* (inbound logistics) -. Define the *core operations* (what this project builds) -. Specify *outbound targets* (where outputs go) -. Configure *maintenance strategy* (corrective/adaptive/perfective) -. Set up *service automation* (feedback-o-tron, cicd-hyper-a, etc.) - -=== Diagram - -.... -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ SUPPORT ACTIVITIES (Cross-cutting) │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ TECHNOLOGY │ CCCP: Cerro Torre, Svalinn, Valence Shell, rescript-tea... │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ FORMALIZATIONS │ Absolute Zero, Echidna, Coq/Lean/Z3, formal proofs │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ STANDARDS │ RSR (repo), CCCP (code), .scm files, Palimpsest licensing │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ INFRASTRUCTURE │ mustfile, rhodium-pipeline, GitLab CI, GitHub Actions │ -└──────────────────┴──────────────────────────────────────────────────────────────────┘ - │ -┌───────────────────────────────────────────┼─────────────────────────────────────────┐ -│ PRIMARY ACTIVITIES (Value Flow) │ -│ │ │ -│ ┌───────────┐ ┌───────────┐ ┌────────┴──┐ ┌───────────┐ ┌───────────┐ │ -│ │ INBOUND │ │ │ │ OUTBOUND │ │ MARKETING │ │ │ │ -│ │ LOGISTICS │──▶│ OPERATIONS│──▶│ LOGISTICS │──▶│ & SALES │──▶│ SERVICE │ │ -│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ -│ │ -│ Foundational Core project To CCCP/ RSR system feedback-o-tron │ -│ theory/proofs development other projects Maintenance cicd-hyper-a │ -│ strategies robot-repo-auto │ -│ │ -│ ═══════════════════════════════════════════════════════════════════════════════▶ │ -│ VALUE CREATION MARGIN │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -.... - -''''' - -_This policy applies to all Hyperpolymath projects and their satellite -repositories._ diff --git a/aletheia/eclexiaiser.toml b/aletheia/eclexiaiser.toml deleted file mode 100644 index 0f662ff..0000000 --- a/aletheia/eclexiaiser.toml +++ /dev/null @@ -1,26 +0,0 @@ -# eclexiaiser manifest — energy/carbon resource budgets -# SPDX-License-Identifier: MPL-2.0 - -[project] -name = "aletheia" - -[[functions]] -name = "check_spdx_headers" -source = "src/checks.rs" -energy-budget-mj = 25.0 -carbon-budget-mg = 5.0 - -[[functions]] -name = "check_documentation" -source = "src/checks.rs" -energy-budget-mj = 15.0 -carbon-budget-mg = 3.0 - -[carbon] -provider = "static" -region = "GB" -static-intensity = 200.0 - -[report] -format = "text" -include-recommendations = true diff --git a/aletheia/examples/simple_verification.rs b/aletheia/examples/simple_verification.rs deleted file mode 100644 index 928a36b..0000000 --- a/aletheia/examples/simple_verification.rs +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Simple example of using Aletheia as a library -//! -//! This example shows how to programmatically verify RSR compliance -//! Note: Aletheia is currently a binary-only tool, but this demonstrates -//! the API design if library usage is added in the future. - -fn main() { - println!("Aletheia RSR Compliance Verification Example"); - println!("============================================\n"); - - // Example 1: Verify current directory - println!("Example 1: Verify current directory"); - let current_dir = std::env::current_dir().expect("Cannot get current directory"); - println!("Checking: {}", current_dir.display()); - println!("Run: cargo run\n"); - - // Example 2: Verify specific path - println!("Example 2: Verify specific repository"); - println!("Run: cargo run -- /path/to/repository\n"); - - // Example 3: Expected output (RSR v2 shape — README.adoc primary, - // LICENSE not LICENSE.txt, 26 checks in the offline subset) - println!("Example 3: Expected output format"); - println!( - " -Aletheia - RSR Compliance Verification Report -Repository: /path/to/repository -Verified: 2026-09-21T20:05:37Z - -[Documentation] - ✅ README.adoc (or README.md) [Bronze] - ✅ LICENSE file (not LICENSE.txt) [Bronze] - ✅ SECURITY policy (root or .github/) [Bronze] - ❌ CONTRIBUTING (root or .github/) [Silver] - ... - -Score: 25/26 checks passed (96.2%) -Bronze-level RSR compliance: ACHIEVED -Silver-level RSR compliance: NOT MET - " - ); - - println!("\nNote: To use Aletheia, run the binary:"); - println!(" cargo run # Verify current directory"); - println!(" cargo run -- /path/to/repo # Verify specific repository"); -} diff --git a/aletheia/examples/web-project-deno.json b/aletheia/examples/web-project-deno.json deleted file mode 100644 index 5ddd3bd..0000000 --- a/aletheia/examples/web-project-deno.json +++ /dev/null @@ -1,20 +0,0 @@ -{ - "// NOTE": "Example deno.json for ReScript web projects", - "tasks": { - "build": "deno run -A npm:rescript", - "clean": "deno run -A npm:rescript clean", - "watch": "deno run -A npm:rescript -w", - "serve": "deno run -A jsr:@std/http/file-server .", - "test": "deno test --allow-all" - }, - "imports": { - "rescript": "^12.0.0", - "@rescript/core": "npm:@rescript/core@^1.6.0", - "safe-dom/": "https://raw.githubusercontent.com/hyperpolymath/rescript-dom-mounter/main/src/", - "proven/": "../proven/bindings/rescript/src/" - }, - "compilerOptions": { - "allowJs": true, - "checkJs": false - } -} diff --git a/aletheia/extraction/rhodibot/.github/workflows/ci.yml b/aletheia/extraction/rhodibot/.github/workflows/ci.yml deleted file mode 100644 index 6a873a3..0000000 --- a/aletheia/extraction/rhodibot/.github/workflows/ci.yml +++ /dev/null @@ -1,105 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Rhodibot CI/CD Pipeline -name: CI - -on: - push: - branches: [main] - pull_request: - branches: [main] - schedule: - - cron: '0 0 * * 1' # Weekly on Monday - -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: -Dwarnings - -jobs: - check: - name: Check - runs-on: ubuntu-latest - timeout-minutes: 15 - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: dtolnay/rust-action@stable - - - name: Check formatting - run: cargo fmt --check - - - name: Clippy - run: cargo clippy -- -D warnings - - - name: Check for unsafe code - run: | - if grep -r "unsafe" src/; then - echo "Unsafe code detected!" - exit 1 - fi - - - name: Check for dependencies - run: | - deps=$(cargo tree --depth 0 | grep -c "^") - if [ "$deps" -gt 1 ]; then - echo "External dependencies detected!" - cargo tree - exit 1 - fi - - test: - name: Test - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: check - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: dtolnay/rust-action@stable - - - name: Run tests - run: cargo test --verbose - - - name: Run tests (release) - run: cargo test --release --verbose - - build: - name: Build - runs-on: ${{ matrix.os }} - timeout-minutes: 15 - needs: test - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: dtolnay/rust-action@stable - - - name: Build release - run: cargo build --release - - - name: Upload binary - uses: actions/upload-artifact@ea165f8d65b6db9a8b71b5c2d1a090c0daf9c8bb # v4 - with: - name: rhodibot-${{ matrix.os }} - path: | - target/release/rhodibot - target/release/rhodibot.exe - - self-verify: - name: Self-Verification - runs-on: ubuntu-latest - timeout-minutes: 15 - needs: build - steps: - - uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4 - - uses: dtolnay/rust-action@stable - - - name: Build - run: cargo build --release - - - name: Self-verify RSR compliance - run: ./target/release/rhodibot check . - - - name: Generate badge - run: ./target/release/rhodibot badge - - - name: Generate conformity document - run: ./target/release/rhodibot conformity diff --git a/aletheia/extraction/rhodibot/.gitlab-ci.yml b/aletheia/extraction/rhodibot/.gitlab-ci.yml deleted file mode 100644 index 1507325..0000000 --- a/aletheia/extraction/rhodibot/.gitlab-ci.yml +++ /dev/null @@ -1,104 +0,0 @@ -# Rhodibot GitLab CI/CD Pipeline -# RSR Bronze compliant: zero dependencies, zero unsafe code - -stages: - - check - - test - - build - - verify - -variables: - CARGO_HOME: ${CI_PROJECT_DIR}/.cargo - RUSTFLAGS: "-Dwarnings" - -.rust-template: - image: rust:latest - cache: - key: ${CI_COMMIT_REF_SLUG} - paths: - - .cargo/ - - target/ - -# Check stage -fmt: - extends: .rust-template - stage: check - script: - - cargo fmt --check - -clippy: - extends: .rust-template - stage: check - script: - - rustup component add clippy - - cargo clippy -- -D warnings - -unsafe-check: - extends: .rust-template - stage: check - script: - - | - if grep -r "unsafe" src/; then - echo "Unsafe code detected!" - exit 1 - fi - -deps-check: - extends: .rust-template - stage: check - script: - - | - deps=$(cargo tree --depth 0 | grep -c "^") - if [ "$deps" -gt 1 ]; then - echo "External dependencies detected!" - exit 1 - fi - -# Test stage -test: - extends: .rust-template - stage: test - script: - - cargo test --verbose - -test-release: - extends: .rust-template - stage: test - script: - - cargo test --release --verbose - -# Build stage -build-debug: - extends: .rust-template - stage: build - script: - - cargo build - artifacts: - paths: - - target/debug/rhodibot - expire_in: 1 week - -build-release: - extends: .rust-template - stage: build - script: - - cargo build --release - artifacts: - paths: - - target/release/rhodibot - expire_in: 1 month - -# Verify stage -self-verify: - extends: .rust-template - stage: verify - dependencies: - - build-release - script: - - ./target/release/rhodibot check . - - ./target/release/rhodibot badge - - ./target/release/rhodibot conformity > RSR-CONFORMITY.md - artifacts: - paths: - - RSR-CONFORMITY.md - expire_in: 1 month diff --git a/aletheia/extraction/rhodibot/.well-known/ai.txt b/aletheia/extraction/rhodibot/.well-known/ai.txt deleted file mode 100644 index 15f49fe..0000000 --- a/aletheia/extraction/rhodibot/.well-known/ai.txt +++ /dev/null @@ -1,18 +0,0 @@ -# AI Training Policy for Rhodibot -# https://site.spawning.ai/spawning-ai-txt - -User-Agent: * - -# Training Policy -# This code may be used for AI training with attribution -ai-training: allowed-with-attribution - -# Data Usage -ai-data-usage: allowed-for-research, allowed-for-training - -# Attribution Required -attribution-required: yes -attribution-format: "Rhodibot by Hyperpolymath - https://github.com/hyperpolymath/rhodibot" - -# License -license: MIT OR Apache-2.0 diff --git a/aletheia/extraction/rhodibot/.well-known/humans.txt b/aletheia/extraction/rhodibot/.well-known/humans.txt deleted file mode 100644 index 97554c9..0000000 --- a/aletheia/extraction/rhodibot/.well-known/humans.txt +++ /dev/null @@ -1,17 +0,0 @@ -/* TEAM */ -Project: Rhodibot -Role: RSR Compliance Bot -Organization: Hyperpolymath -Repository: https://github.com/hyperpolymath/rhodibot - -/* THANKS */ -Rust Community - For an exceptional language -RSR Standard Authors - For the compliance framework -Dependabot Team - For the inspiration - -/* SITE */ -Last update: 2025-12-26 -Standards: RSR Bronze -Language: Rust -Dependencies: Zero (std only) -Unsafe Code: Zero diff --git a/aletheia/extraction/rhodibot/.well-known/security.txt b/aletheia/extraction/rhodibot/.well-known/security.txt deleted file mode 100644 index 34463a9..0000000 --- a/aletheia/extraction/rhodibot/.well-known/security.txt +++ /dev/null @@ -1,13 +0,0 @@ -# RFC 9116 Security Contact -# https://www.rfc-editor.org/rfc/rfc9116 - -Contact: mailto:security@hyperpolymath.org -Expires: 2026-12-31T23:59:59.000Z -Preferred-Languages: en -Canonical: https://github.com/hyperpolymath/rhodibot/.well-known/security.txt - -# Security Policy -Policy: https://github.com/hyperpolymath/rhodibot/blob/main/SECURITY.md - -# Acknowledgments -Acknowledgments: https://github.com/hyperpolymath/rhodibot/blob/main/SECURITY.md#acknowledgments diff --git a/aletheia/extraction/rhodibot/Cargo.lock b/aletheia/extraction/rhodibot/Cargo.lock deleted file mode 100644 index 782e522..0000000 --- a/aletheia/extraction/rhodibot/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "rhodibot" -version = "0.1.0" diff --git a/aletheia/extraction/rhodibot/Cargo.toml b/aletheia/extraction/rhodibot/Cargo.toml deleted file mode 100644 index dc303ac..0000000 --- a/aletheia/extraction/rhodibot/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "rhodibot" -version = "0.1.0" -edition = "2021" -rust-version = "1.70" -description = "RSR compliance bot - like Dependabot but for Rhodium Standard Repository compliance" -license = "MIT OR Apache-2.0" -repository = "https://github.com/hyperpolymath/rhodibot" -keywords = ["rsr", "compliance", "bot", "ci-cd", "security"] -categories = ["development-tools", "command-line-utilities"] - -[lib] -name = "rhodibot" -path = "src/lib.rs" - -[[bin]] -name = "rhodibot" -path = "src/main.rs" - -[dependencies] -# Zero dependencies - RSR Bronze compliant - -[dev-dependencies] -# Testing only - -[profile.release] -lto = true -codegen-units = 1 -strip = true -opt-level = "z" diff --git a/aletheia/extraction/rhodibot/Justfile b/aletheia/extraction/rhodibot/Justfile deleted file mode 100644 index 8490a54..0000000 --- a/aletheia/extraction/rhodibot/Justfile +++ /dev/null @@ -1,85 +0,0 @@ -# Rhodibot - RSR Compliance Bot -# Build automation with just (https://just.systems) - -# Default recipe -default: check - -# Build in debug mode -build: - cargo build - -# Build in release mode -release: - cargo build --release - -# Run all checks -check: fmt-check clippy test - @echo "All checks passed!" - -# Run tests -test: - cargo test - -# Run clippy linter -clippy: - cargo clippy -- -D warnings - -# Check formatting -fmt-check: - cargo fmt --check - -# Format code -fmt: - cargo fmt - -# Run rhodibot on itself (self-verification) -self-check: - cargo run -- check . - -# Generate badge -badge: - cargo run -- badge - -# Generate conformity document -conformity: - cargo run -- conformity - -# Clean build artifacts -clean: - cargo clean - -# Install locally -install: - cargo install --path . - -# Run with JSON output -json: - cargo run -- check . --format json - -# Run in quiet mode -quiet: - cargo run -- check . --quiet - -# Run in verbose mode -verbose: - cargo run -- check . --verbose - -# Show help -help: - cargo run -- --help - -# Generate documentation -docs: - cargo doc --no-deps --open - -# Check for unsafe code -unsafe-check: - @! grep -r "unsafe" src/ || echo "No unsafe code found" - -# Check for dependencies -deps-check: - @cargo tree --depth 0 | grep -c "^" | xargs -I {} test {} -eq 1 && echo "Zero dependencies verified" - -# Full CI pipeline -ci: check self-check - @echo "CI pipeline complete" diff --git a/aletheia/extraction/rhodibot/README.adoc b/aletheia/extraction/rhodibot/README.adoc deleted file mode 100644 index 04ec73a..0000000 --- a/aletheia/extraction/rhodibot/README.adoc +++ /dev/null @@ -1,198 +0,0 @@ -== Rhodibot - -https://github.com/hyperpolymath/rhodium-standard-repositories[image:https://img.shields.io/badge/RSR-Bronze-cd7f32[RSR -Bronze]] - -____ -**Rho**dium Stan**d**ard Repos**i**tory *Bot* -____ - -Rhodibot is like Dependabot, but for repository standards compliance -instead of dependency updates. It acts as a consultant, regulator, -advisor, and policy manager for RSR (Rhodium Standard Repository) -compliance. - -=== What Rhodibot Does - -* *Checks* repositories for RSR compliance (Bronze, Silver, Gold, -Platinum levels) -* *Reports* issues via CI/CD annotations (GitHub Actions, GitLab CI) -* *Generates* badges and conformity documents -* *Advises* on compliance gaps and how to fix them - -=== Ecosystem Architecture - -.... - ┌─────────────────────────────────────┐ - │ rhodium-standard-repositories │ - │ (The RSR Specification) │ - └─────────────────┬───────────────────┘ - │ defines - ┌──────────────────────────┼──────────────────────────┐ - │ │ │ - ▼ ▼ ▼ -┌─────────────────────┐ ╔═══════════════════════╗ ┌─────────────────────┐ -│ rsr-template-repo │ ║ RHODIBOT ║ │ rhodium-pipeline │ -│ (Project Start) │ ║ ================== ║ │ (CI/CD Tools) │ -│ │ ║ Consultant/Advisor ║ │ │ -│ • Template files │◀──║ Regulator/Policy ║──▶│ • Pipeline gen │ -│ • Initial setup │ ║ Compliance checker ║ │ • Stage configs │ -│ • Scaffolding │ ╚═══════════════════════╝ │ • Platform support │ -└─────────────────────┘ │ └─────────────────────┘ - │ reports to - ▼ - ┌─────────────────────────────────────┐ - │ repo-customiser │ - │ (C4 Control Point - Generic) │ - │ │ - │ Works with ANY .scm standard: │ - │ • RSR (Rhodium Standard) │ - │ • oikos (Economic/Ecological) │ - │ • Custom organization standards │ - └─────────────────────────────────────┘ -.... - -*Satellite of:* -https://github.com/hyperpolymath/rhodium-standard-repositories[rhodium-standard-repositories] - -Rhodibot sits at the center of RSR compliance enforcement, connecting -templates, pipelines, and the standard. It can be invoked by CI/CD -systems, used interactively, or integrated via the repo-customiser C4 -control point. - -=== Quick Start - -[source,bash] ----- -# Install -cargo install rhodibot - -# Check current directory -rhodibot check . - -# Generate badge markdown -rhodibot badge - -# Generate conformity document -rhodibot conformity ----- - -=== CI/CD Integration - -==== GitHub Actions - -[source,yaml] ----- -name: RSR Compliance -on: [push, pull_request] - -jobs: - rhodibot: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: hyperpolymath/rhodibot@v1 - with: - path: '.' - fail-on-warning: true ----- - -==== GitLab CI - -[source,yaml] ----- -rhodibot: - stage: test - image: hyperpolymath/rhodibot:latest - script: - - rhodibot check . ----- - -=== CLI Usage - -.... -rhodibot [COMMAND] [OPTIONS] [PATH] - -COMMANDS: - check Check RSR compliance (default) - badge Generate RSR badge markdown - conformity Generate RSR conformity document - -OPTIONS: - -f, --format Output format: human, json - -q, --quiet Quiet mode: only show pass/fail - -v, --verbose Verbose mode: show all details - -h, --help Print help information - -EXIT CODES: - 0 Success - Bronze compliance achieved - 1 Failure - Bronze compliance not met - 2 Security - Critical security warnings detected - 3 Error - Invalid path provided - 4 Error - Invalid arguments -.... - -=== Design Principles - -[arabic] -. *Zero Dependencies* - Only Rust standard library (RSR Bronze -compliant) -. *Zero Unsafe Code* - 100% safe Rust -. *Offline-First* - Works without network access -. *Security-Aware* - Detects symlink attacks, validates paths -. *CI/CD Native* - First-class GitHub Actions and GitLab CI support - -=== Bronze Compliance Checks - -Rhodibot checks for these Bronze-level requirements: - -==== Documentation - -* README.md (or README.adoc) -* LICENSE.txt -* SECURITY.md -* CONTRIBUTING.md -* CODE_OF_CONDUCT.md -* MAINTAINERS.md -* CHANGELOG.md - -==== .well-known Directory - -* .well-known/security.txt (RFC 9116) -* .well-known/ai.txt -* .well-known/humans.txt - -==== Build System - -* Justfile -* flake.nix -* .gitlab-ci.yml - -==== Source Structure - -* src/ directory -* tests/ directory - -=== Security - -Rhodibot includes security features: - -* *Symlink Detection*: Warns about symlinks that point outside the -repository -* *Path Validation*: Prevents directory traversal attacks -* *No Network*: Cannot exfiltrate data (offline-first design) -* *Zero Dependencies*: No supply chain attack surface - -=== License - -MIT OR Apache-2.0 - -=== Contributing - -See CONTRIBUTING.md for guidelines. - -''''' - -_Part of the -https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium -Standard] ecosystem_ diff --git a/aletheia/extraction/rhodibot/docs/VALUE-CHAIN-POLICY.adoc b/aletheia/extraction/rhodibot/docs/VALUE-CHAIN-POLICY.adoc deleted file mode 100644 index 03661ca..0000000 --- a/aletheia/extraction/rhodibot/docs/VALUE-CHAIN-POLICY.adoc +++ /dev/null @@ -1,204 +0,0 @@ -== Hyperpolymath Project Value Chain Policy - -This document defines the standard value chain model for all -Hyperpolymath projects. It is based on Porter’s Value Chain framework, -adapted for software development. - -=== Overview - -Every Hyperpolymath project has two types of activities: - -[arabic] -. *Support Activities* - Cross-cutting concerns that apply at all stages -. *Primary Activities* - The value flow from inputs to outputs - -=== Support Activities (Cross-Cutting) - -These apply horizontally across all primary activities: - -[width="100%",cols="34%,43%,23%",options="header",] -|=== -|Activity |Description |Tools -|*Technology* |CCCP stack (containers, runtime, shell) |Cerro Torre, -Svalinn, Valence Shell - -|*Formalizations* |Proofs, validation, verification |Absolute Zero, -Echidna, Coq/Lean/Z3 - -|*Standards* |Repository and code standards |RSR, CCCP, .scm files, -Palimpsest - -|*Infrastructure* |Build, CI/CD, deployment |mustfile, rhodium-pipeline, -GitLab CI -|=== - -=== Primary Activities (Value Flow) - -.... -┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ -│ INBOUND │ │ │ │ OUTBOUND │ │ MARKETING │ │ │ -│ LOGISTICS │──▶│ OPERATIONS │──▶│ LOGISTICS │──▶│ & SALES │──▶│ SERVICE │ -│ │ │ │ │ │ │ │ │ │ -│ Theoretical │ │ Core │ │ Outputs │ │ Standards │ │ Maintenance │ -│ foundations │ │ project │ │ & exports │ │ & business │ │ & ops │ -└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ -.... - -==== 1. Inbound Logistics - -*What*: Foundational inputs specific to the project’s domain - -Examples: - For Aletheia: Absolute Zero (CNO proofs, Landauer, Bennett) -- For rhodibot: RSR specification - For oikos: Economic/ecological -theory - -==== 2. Operations - -*What*: The core project work - what this repository actually builds - -Examples: - For Aletheia: Reversible Minix research (r-Minix precursor) -- For rhodibot: Compliance checking engine - For oikos: -Economic/ecological analyzer - -==== 3. Outbound Logistics - -*What*: Where outputs go - integration with CCCP stack or other projects - -Examples: - To CCCP technology stack (containers, runtime) - To -downstream projects - To future implementations (e.g., Aletheia → -r-Minix) - -==== 4. Marketing & Sales - -*What*: RSR ecosystem, maintenance strategies, business extensions - -Components: - *Corrective maintenance* - Bug fixes, issue resolution - -*Adaptive maintenance* - Platform/environment changes - *Perfective -maintenance* - Improvements, optimizations - -==== 5. Service - -*What*: Ongoing operational support via automation - -Tools: - *feedback-o-tron* - Feedback collection and processing - -*cicd-hyper-a* - CI/CD automation - *robot-repo-automaton* - Repository -automation - -=== Two Input Systems - -All projects receive inputs from two complementary systems: - -==== RSR - Rhodium Standard Repositories - -* *Layer*: Repository organization -* *Handles*: Documentation, security.txt, CI/CD, build systems -* *Tools*: rhodium-standard-repositories, rsr-template-repo, rhodibot, -rhodium-pipeline - -==== CCCP - Campaign for Cooling Coding and Programming - -* *Layer*: Technology stack and code -* *Handles*: Languages, containers, integrations, efficiency -* *Tools*: Cerro Torre, Svalinn, Valence Shell, rescript-tea, -cadre-router - -=== Project-Specific Foundations - -Each project may have domain-specific foundational inputs: - -[cols=",",options="header",] -|=== -|Project |Foundational Input -|Aletheia |Absolute Zero (CNO proofs, reversibility theory) -|Valence Shell |Absolute Zero (filesystem CNO proofs) -|Oikos |Economic/ecological theory -|Echidnabot |Formal methods, SAT/SMT solving -|=== - -=== Standard Files - -All properly configured projects include: - -==== AI Support Files (.scm - Guile Scheme) - -* `+META.scm+` - Project metadata -* `+ECOSYSTEM.scm+` - Ecosystem connections -* `+STATE.scm+` - Current project state -* `+PLAYBOOK.scm+` - Development workflows -* `+AGENTIC.scm+` - AI agent configuration -* `+NEUROSYM.scm+` - Neurosymbolic settings - -==== Build & Standards - -* `+mustfile+` - Build/task automation -* RSR compliance files (README, LICENSE, SECURITY.md, etc.) -* `+.well-known/+` directory - -==== Licensing - -* *Base*: MIT or AGPL (user choice) -* *Overlay*: Palimpsest License (optional but encouraged) - -=== Bot Ecosystem - -Projects are supported by bots operating in multiple modes: - -[cols=",",options="header",] -|=== -|Bot |Role -|*rhodibot* |RSR compliance (consultant, advisor, regulator) -|*echidnabot* |Formal proof validation -|*oikos bot* |Economic/ecological analysis -|=== - -Bots are *self-referential* - they validate their own code. - -=== Applying This Policy - -When setting up a new project: - -[arabic] -. Start with `+rsr-template-repo+` -. Apply customizations via `+repo-customiser+` -. Identify the project’s *foundational input* (inbound logistics) -. Define the *core operations* (what this project builds) -. Specify *outbound targets* (where outputs go) -. Configure *maintenance strategy* (corrective/adaptive/perfective) -. Set up *service automation* (feedback-o-tron, cicd-hyper-a, etc.) - -=== Diagram - -.... -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ SUPPORT ACTIVITIES (Cross-cutting) │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ TECHNOLOGY │ CCCP: Cerro Torre, Svalinn, Valence Shell, rescript-tea... │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ FORMALIZATIONS │ Absolute Zero, Echidna, Coq/Lean/Z3, formal proofs │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ STANDARDS │ RSR (repo), CCCP (code), .scm files, Palimpsest licensing │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ INFRASTRUCTURE │ mustfile, rhodium-pipeline, GitLab CI, GitHub Actions │ -└──────────────────┴──────────────────────────────────────────────────────────────────┘ - │ -┌───────────────────────────────────────────┼─────────────────────────────────────────┐ -│ PRIMARY ACTIVITIES (Value Flow) │ -│ │ │ -│ ┌───────────┐ ┌───────────┐ ┌────────┴──┐ ┌───────────┐ ┌───────────┐ │ -│ │ INBOUND │ │ │ │ OUTBOUND │ │ MARKETING │ │ │ │ -│ │ LOGISTICS │──▶│ OPERATIONS│──▶│ LOGISTICS │──▶│ & SALES │──▶│ SERVICE │ │ -│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ -│ │ -│ Foundational Core project To CCCP/ RSR system feedback-o-tron │ -│ theory/proofs development other projects Maintenance cicd-hyper-a │ -│ strategies robot-repo-auto │ -│ │ -│ ═══════════════════════════════════════════════════════════════════════════════▶ │ -│ VALUE CREATION MARGIN │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -.... - -''''' - -_This policy applies to all Hyperpolymath projects and their satellite -repositories._ diff --git a/aletheia/extraction/rhodibot/manifest.scm b/aletheia/extraction/rhodibot/manifest.scm deleted file mode 100644 index dd942c7..0000000 --- a/aletheia/extraction/rhodibot/manifest.scm +++ /dev/null @@ -1,24 +0,0 @@ -;;; SPDX-License-Identifier: MPL-2.0 -;;; manifest.scm — Generic Guix manifest for RSR-compliant projects -;;; -;;; Usage: -;;; guix shell -m manifest.scm -;;; - -(specifications->manifest - '(;; Core development tools - "git" - "just" - "nickel" - "curl" - "bash" - "coreutils" - - ;; Documentation - "asciidoctor" - "pandoc" - - ;; Common build dependencies - "openssl" - "zlib" - "pkg-config")) diff --git a/aletheia/extraction/rhodibot/src/bot.rs b/aletheia/extraction/rhodibot/src/bot.rs deleted file mode 100644 index 236ddf8..0000000 --- a/aletheia/extraction/rhodibot/src/bot.rs +++ /dev/null @@ -1,349 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Bot integration module for CI/CD platforms -//! -//! This module provides integration with various CI/CD platforms: -//! - GitHub Actions -//! - GitLab CI -//! - Generic CI environments - -use crate::{ComplianceReport, WarningLevel}; -use std::env; - -/// Detected CI/CD platform -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum CIPlatform { - GitHubActions, - GitLabCI, - CircleCI, - Travis, - Jenkins, - Unknown, -} - -impl CIPlatform { - /// Detect the current CI/CD platform from environment variables - pub fn detect() -> Self { - if env::var("GITHUB_ACTIONS").is_ok() { - CIPlatform::GitHubActions - } else if env::var("GITLAB_CI").is_ok() { - CIPlatform::GitLabCI - } else if env::var("CIRCLECI").is_ok() { - CIPlatform::CircleCI - } else if env::var("TRAVIS").is_ok() { - CIPlatform::Travis - } else if env::var("JENKINS_URL").is_ok() { - CIPlatform::Jenkins - } else { - CIPlatform::Unknown - } - } - - /// Get a human-readable name for the platform - pub fn name(&self) -> &'static str { - match self { - CIPlatform::GitHubActions => "GitHub Actions", - CIPlatform::GitLabCI => "GitLab CI", - CIPlatform::CircleCI => "CircleCI", - CIPlatform::Travis => "Travis CI", - CIPlatform::Jenkins => "Jenkins", - CIPlatform::Unknown => "Unknown", - } - } -} - -/// GitHub Actions specific output commands -pub mod github_actions { - use super::*; - - /// Set an output variable for GitHub Actions - pub fn set_output(name: &str, value: &str) { - // GitHub Actions uses GITHUB_OUTPUT file since Oct 2022 - if let Ok(output_file) = env::var("GITHUB_OUTPUT") { - if let Ok(mut file) = std::fs::OpenOptions::new().append(true).open(output_file) { - use std::io::Write; - let _ = writeln!(file, "{}={}", name, value); - } - } else { - // Fallback to deprecated set-output command - println!("::set-output name={}::{}", name, value); - } - } - - /// Add a warning annotation - pub fn warning(message: &str, file: Option<&str>, line: Option) { - let mut cmd = "::warning".to_string(); - if let Some(f) = file { - cmd.push_str(&format!(" file={}", f)); - if let Some(l) = line { - cmd.push_str(&format!(",line={}", l)); - } - } - cmd.push_str(&format!("::{}", message)); - println!("{}", cmd); - } - - /// Add an error annotation - pub fn error(message: &str, file: Option<&str>, line: Option) { - let mut cmd = "::error".to_string(); - if let Some(f) = file { - cmd.push_str(&format!(" file={}", f)); - if let Some(l) = line { - cmd.push_str(&format!(",line={}", l)); - } - } - cmd.push_str(&format!("::{}", message)); - println!("{}", cmd); - } - - /// Start a log group - pub fn group(title: &str) { - println!("::group::{}", title); - } - - /// End a log group - pub fn endgroup() { - println!("::endgroup::"); - } - - /// Create a job summary entry - pub fn summary(markdown: &str) { - if let Ok(summary_file) = env::var("GITHUB_STEP_SUMMARY") { - if let Ok(mut file) = std::fs::OpenOptions::new() - .append(true) - .create(true) - .open(summary_file) - { - use std::io::Write; - let _ = writeln!(file, "{}", markdown); - } - } - } - - /// Output report as GitHub Actions annotations and summary - pub fn output_report(report: &ComplianceReport) { - // Set outputs - set_output("passed", &report.passed_count().to_string()); - set_output("total", &report.total_count().to_string()); - set_output("percentage", &format!("{:.1}", report.percentage())); - set_output("bronze_compliant", &report.bronze_compliance().to_string()); - set_output("has_warnings", &report.has_critical_warnings().to_string()); - - // Output annotations for failed checks - for check in &report.checks { - if !check.passed { - warning( - &format!("RSR check failed: {} - {}", check.category, check.item), - None, - None, - ); - } - } - - // Output annotations for security warnings - for warning_item in &report.warnings { - let file = warning_item.path.as_ref().map(|p| p.to_string_lossy()); - match warning_item.level { - WarningLevel::Critical => { - error(&warning_item.message, file.as_deref(), None); - }, - _ => { - warning(&warning_item.message, file.as_deref(), None); - }, - } - } - - // Generate job summary - let mut md = String::new(); - md.push_str("## 🤖 Rhodibot RSR Compliance Report\n\n"); - - if report.bronze_compliance() && !report.has_critical_warnings() { - md.push_str("✅ **Bronze-level RSR compliance: ACHIEVED**\n\n"); - } else { - md.push_str("❌ **Bronze-level RSR compliance: NOT MET**\n\n"); - } - - md.push_str(&format!( - "**Score**: {}/{} checks passed ({:.1}%)\n\n", - report.passed_count(), - report.total_count(), - report.percentage() - )); - - md.push_str("### Checks\n\n"); - md.push_str("| Category | Item | Status |\n"); - md.push_str("|----------|------|--------|\n"); - for check in &report.checks { - let status = if check.passed { "✅" } else { "❌" }; - md.push_str(&format!( - "| {} | {} | {} |\n", - check.category, check.item, status - )); - } - - if !report.warnings.is_empty() { - md.push_str("\n### Security Warnings\n\n"); - for warning_item in &report.warnings { - let icon = match warning_item.level { - WarningLevel::Info => "ℹ️", - WarningLevel::Warning => "⚠️", - WarningLevel::Critical => "🚨", - }; - md.push_str(&format!("- {} {}\n", icon, warning_item.message)); - } - } - - summary(&md); - } -} - -/// GitLab CI specific output -pub mod gitlab_ci { - use super::*; - - /// Output report in GitLab CI compatible format - pub fn output_report(report: &ComplianceReport) { - // GitLab uses dotenv artifacts for passing variables - // Output to console in a parseable format - println!("RHODIBOT_PASSED={}", report.passed_count()); - println!("RHODIBOT_TOTAL={}", report.total_count()); - println!("RHODIBOT_PERCENTAGE={:.1}", report.percentage()); - println!("RHODIBOT_BRONZE_COMPLIANT={}", report.bronze_compliance()); - println!("RHODIBOT_HAS_WARNINGS={}", report.has_critical_warnings()); - - // Output sections - println!("\n\\e[0Ksection_start:{}:rhodibot_report[collapsed=false]\\r\\e[0K\x1b[36mRhodibot Report\x1b[0m", - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() - ); - - for check in &report.checks { - let status = if check.passed { "✓" } else { "✗" }; - let color = if check.passed { "32" } else { "31" }; - println!( - "\x1b[{}m[{}]\x1b[0m {} - {}", - color, status, check.category, check.item - ); - } - - println!( - "section_end:{}:rhodibot_report\\r\\e[0K", - std::time::SystemTime::now() - .duration_since(std::time::UNIX_EPOCH) - .unwrap_or_default() - .as_secs() - ); - } -} - -/// Generate GitHub Actions workflow file -pub fn generate_github_actions_workflow() -> String { - r#"# Rhodibot RSR Compliance Check -# This workflow checks your repository for Rhodium Standard Repository compliance - -name: RSR Compliance - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - schedule: - # Run weekly on Mondays at 00:00 UTC - - cron: '0 0 * * 1' - -jobs: - rhodibot: - name: RSR Compliance Check - runs-on: ubuntu-latest - steps: - - name: Checkout repository - uses: actions/checkout@v4 - - - name: Install Rust - uses: dtolnay/rust-action@stable - - - name: Install Rhodibot - run: cargo install rhodibot - - - name: Run RSR compliance check - id: check - run: | - rhodibot check . --format json > rhodibot-report.json - rhodibot check . - continue-on-error: true - - - name: Generate badge - run: rhodibot badge > RSR_BADGE.md - - - name: Upload report - uses: actions/upload-artifact@v4 - with: - name: rhodibot-report - path: rhodibot-report.json - - - name: Check result - if: steps.check.outcome == 'failure' - run: | - echo "RSR compliance check failed!" - exit 1 -"# - .to_string() -} - -/// Generate GitLab CI configuration -pub fn generate_gitlab_ci_config() -> String { - r#"# Rhodibot RSR Compliance Check -# Add this to your .gitlab-ci.yml - -rhodibot: - stage: test - image: rust:latest - before_script: - - cargo install rhodibot - script: - - rhodibot check . --format json > rhodibot-report.json - - rhodibot check . - artifacts: - reports: - dotenv: rhodibot.env - paths: - - rhodibot-report.json - when: always - allow_failure: false - rules: - - if: $CI_PIPELINE_SOURCE == "merge_request_event" - - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - - if: $CI_PIPELINE_SOURCE == "schedule" -"# - .to_string() -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_ci_platform_detection() { - // In test environment, should be Unknown unless in CI - let platform = CIPlatform::detect(); - // Can't guarantee which platform we're on, just test it doesn't panic - let _ = platform.name(); - } - - #[test] - fn test_generate_github_workflow() { - let workflow = generate_github_actions_workflow(); - assert!(workflow.contains("rhodibot")); - assert!(workflow.contains("actions/checkout")); - } - - #[test] - fn test_generate_gitlab_config() { - let config = generate_gitlab_ci_config(); - assert!(config.contains("rhodibot")); - assert!(config.contains("stage: test")); - } -} diff --git a/aletheia/extraction/rhodibot/src/lib.rs b/aletheia/extraction/rhodibot/src/lib.rs deleted file mode 100644 index 50e88c8..0000000 --- a/aletheia/extraction/rhodibot/src/lib.rs +++ /dev/null @@ -1,1055 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Rhodibot - RSR Compliance Bot Library -//! -//! This library provides RSR (Rhodium Standard Repository) compliance verification -//! capabilities for use in CI/CD pipelines, bots, and automation tools. -//! -//! Rhodibot is like Dependabot but for repository standards compliance instead -//! of dependency updates. -//! -//! # Features -//! -//! - Zero dependencies (uses only Rust std library) -//! - Zero unsafe code -//! - Offline-first (no network access required) -//! - Bronze-level RSR compliance checking -//! - JSON output for CI/CD integration -//! - Security-aware (symlink detection) -//! -//! # Example -//! -//! ```rust,no_run -//! use rhodibot::{verify_repository, OutputFormat, Verbosity}; -//! use std::path::Path; -//! -//! let report = verify_repository(Path::new("/path/to/repo")); -//! println!("Bronze compliant: {}", report.bronze_compliance()); -//! ``` - -pub mod bot; - -use std::fs; -use std::path::{Path, PathBuf}; -use std::time::SystemTime; - -/// Library version -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); - -/// Exit codes for different failure modes -pub mod exit_codes { - pub const SUCCESS: i32 = 0; - pub const COMPLIANCE_FAILED: i32 = 1; - pub const SECURITY_WARNING: i32 = 2; - pub const INVALID_PATH: i32 = 3; - pub const INVALID_ARGS: i32 = 4; -} - -/// Output format options -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum OutputFormat { - Human, - Json, - /// Static Analysis Results Interchange Format (SARIF 2.1.0) - /// Supported by GitHub Security tab, GitLab, Azure DevOps - Sarif, -} - -/// Verbosity level -#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)] -pub enum Verbosity { - Quiet, // Only pass/fail - Normal, // Standard output - Verbose, // Include all details -} - -/// RSR Compliance levels -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum ComplianceLevel { - Bronze, - Silver, - Gold, - Platinum, -} - -impl ComplianceLevel { - /// Get the badge color for this compliance level - pub fn badge_color(&self) -> &'static str { - match self { - ComplianceLevel::Bronze => "cd7f32", - ComplianceLevel::Silver => "c0c0c0", - ComplianceLevel::Gold => "ffd700", - ComplianceLevel::Platinum => "e5e4e2", - } - } - - /// Get the display name for this compliance level - pub fn display_name(&self) -> &'static str { - match self { - ComplianceLevel::Bronze => "Bronze", - ComplianceLevel::Silver => "Silver", - ComplianceLevel::Gold => "Gold", - ComplianceLevel::Platinum => "Platinum", - } - } -} - -/// Individual compliance check result -#[derive(Debug, Clone)] -pub struct CheckResult { - pub category: String, - pub item: String, - pub passed: bool, - pub required_for: ComplianceLevel, - pub description: Option, -} - -/// Security warning levels -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum WarningLevel { - Info, - Warning, - Critical, -} - -/// Security warning -#[derive(Debug, Clone)] -pub struct SecurityWarning { - pub level: WarningLevel, - pub message: String, - pub path: Option, -} - -/// Overall compliance report -#[derive(Debug)] -pub struct ComplianceReport { - pub checks: Vec, - pub warnings: Vec, - pub repository_path: PathBuf, - pub verified_at: SystemTime, -} - -impl ComplianceReport { - /// Create a new empty compliance report - pub fn new(path: PathBuf) -> Self { - Self { - checks: Vec::new(), - warnings: Vec::new(), - repository_path: path, - verified_at: SystemTime::now(), - } - } - - /// Add a compliance check result - pub fn add_check(&mut self, category: &str, item: &str, passed: bool, level: ComplianceLevel) { - self.checks.push(CheckResult { - category: category.to_string(), - item: item.to_string(), - passed, - required_for: level, - description: None, - }); - } - - /// Add a compliance check with description - pub fn add_check_with_desc( - &mut self, - category: &str, - item: &str, - passed: bool, - level: ComplianceLevel, - description: &str, - ) { - self.checks.push(CheckResult { - category: category.to_string(), - item: item.to_string(), - passed, - required_for: level, - description: Some(description.to_string()), - }); - } - - /// Add a security warning - pub fn add_warning(&mut self, level: WarningLevel, message: &str, path: Option) { - self.warnings.push(SecurityWarning { - level, - message: message.to_string(), - path, - }); - } - - /// Check if Bronze-level compliance is met - pub fn bronze_compliance(&self) -> bool { - self.checks - .iter() - .filter(|c| c.required_for == ComplianceLevel::Bronze) - .all(|c| c.passed) - } - - /// Check if Silver-level compliance is met - pub fn silver_compliance(&self) -> bool { - self.bronze_compliance() - && self - .checks - .iter() - .filter(|c| c.required_for == ComplianceLevel::Silver) - .all(|c| c.passed) - } - - /// Get the highest compliance level achieved - pub fn highest_level(&self) -> Option { - if !self.bronze_compliance() || self.has_critical_warnings() { - return None; - } - if self.silver_compliance() { - // Check for gold and platinum when implemented - Some(ComplianceLevel::Silver) - } else { - Some(ComplianceLevel::Bronze) - } - } - - /// Count of passed checks - pub fn passed_count(&self) -> usize { - self.checks.iter().filter(|c| c.passed).count() - } - - /// Total number of checks - pub fn total_count(&self) -> usize { - self.checks.len() - } - - /// Check if there are any critical warnings - pub fn has_critical_warnings(&self) -> bool { - self.warnings - .iter() - .any(|w| w.level == WarningLevel::Critical) - } - - /// Get pass percentage - pub fn percentage(&self) -> f64 { - if self.total_count() == 0 { - 0.0 - } else { - (self.passed_count() as f64 / self.total_count() as f64) * 100.0 - } - } - - /// Get checks by category - pub fn checks_by_category(&self) -> std::collections::HashMap> { - let mut map = std::collections::HashMap::new(); - for check in &self.checks { - map.entry(check.category.clone()) - .or_insert_with(Vec::new) - .push(check); - } - map - } -} - -/// Result of checking a path for existence and symlink status -struct PathCheckResult { - exists: bool, - is_symlink: bool, - escapes_repo: bool, - target: Option, -} - -/// Check if a path is a symlink and if it escapes the repository root -fn check_path_security(path: &Path, repo_root: &Path) -> PathCheckResult { - let metadata = match fs::symlink_metadata(path) { - Ok(m) => m, - Err(_) => { - return PathCheckResult { - exists: false, - is_symlink: false, - escapes_repo: false, - target: None, - } - }, - }; - - let is_symlink = metadata.file_type().is_symlink(); - - if !is_symlink { - return PathCheckResult { - exists: true, - is_symlink: false, - escapes_repo: false, - target: None, - }; - } - - let target = match fs::read_link(path) { - Ok(t) => t, - Err(_) => { - return PathCheckResult { - exists: true, - is_symlink: true, - escapes_repo: false, - target: None, - }; - }, - }; - - let resolved_target = if target.is_absolute() { - target.clone() - } else { - path.parent() - .map(|p| p.join(&target)) - .unwrap_or(target.clone()) - }; - - let canonical_root = repo_root - .canonicalize() - .unwrap_or_else(|_| repo_root.to_path_buf()); - let canonical_target = resolved_target - .canonicalize() - .unwrap_or_else(|_| resolved_target.clone()); - - let escapes_repo = !canonical_target.starts_with(canonical_root); - - PathCheckResult { - exists: true, - is_symlink: true, - escapes_repo, - target: Some(resolved_target), - } -} - -/// Check if a file exists at the given path (with symlink detection) -fn check_file(base: &Path, filename: &str, report: &mut ComplianceReport) -> bool { - let path = base.join(filename); - let security = check_path_security(&path, &report.repository_path); - - if security.is_symlink { - if security.escapes_repo { - report.add_warning( - WarningLevel::Critical, - &format!( - "Symlink '{}' points outside repository to '{}'", - filename, - security - .target - .as_ref() - .map(|p| p.display().to_string()) - .unwrap_or_default() - ), - Some(path.clone()), - ); - } else { - report.add_warning( - WarningLevel::Info, - &format!("'{}' is a symlink (within repository bounds)", filename), - Some(path.clone()), - ); - } - } - - security.exists && path.is_file() -} - -/// Check if a directory exists at the given path (with symlink detection) -fn check_dir(base: &Path, dirname: &str, report: &mut ComplianceReport) -> bool { - let path = base.join(dirname); - let security = check_path_security(&path, &report.repository_path); - - if security.is_symlink { - if security.escapes_repo { - report.add_warning( - WarningLevel::Critical, - &format!( - "Symlink directory '{}' points outside repository to '{}'", - dirname, - security - .target - .as_ref() - .map(|p| p.display().to_string()) - .unwrap_or_default() - ), - Some(path.clone()), - ); - } else { - report.add_warning( - WarningLevel::Info, - &format!( - "'{}' is a symlink directory (within repository bounds)", - dirname - ), - Some(path.clone()), - ); - } - } - - security.exists && path.is_dir() -} - -/// Verify documentation files exist -fn check_documentation(report: &mut ComplianceReport, repo_path: &Path) { - // README can be either .md or .adoc (AsciiDoc is acceptable alternative) - let readme_md = check_file(repo_path, "README.md", report); - let readme_adoc = if !readme_md { - check_file(repo_path, "README.adoc", report) - } else { - false - }; - report.add_check( - "Documentation", - "README.md", - readme_md || readme_adoc, - ComplianceLevel::Bronze, - ); - - // Documents that can be either .md or .adoc format - let docs_with_adoc_alternative = vec![ - "SECURITY.md", - "CONTRIBUTING.md", - "CODE_OF_CONDUCT.md", - "MAINTAINERS.md", - "CHANGELOG.md", - ]; - - for doc in docs_with_adoc_alternative { - let exists_md = check_file(repo_path, doc, report); - let adoc_name = doc.replace(".md", ".adoc"); - let exists_adoc = if !exists_md { - check_file(repo_path, &adoc_name, report) - } else { - false - }; - report.add_check( - "Documentation", - doc, - exists_md || exists_adoc, - ComplianceLevel::Bronze, - ); - } - - // LICENSE.txt has no alternative format - let license_exists = check_file(repo_path, "LICENSE.txt", report); - report.add_check( - "Documentation", - "LICENSE.txt", - license_exists, - ComplianceLevel::Bronze, - ); -} - -/// Verify .well-known directory and required files -fn check_well_known(report: &mut ComplianceReport, repo_path: &Path) { - let has_dir = check_dir(repo_path, ".well-known", report); - - report.add_check( - "Well-Known", - ".well-known/ directory", - has_dir, - ComplianceLevel::Bronze, - ); - - let well_known_path = repo_path.join(".well-known"); - let required_files = vec!["security.txt", "ai.txt", "humans.txt"]; - for file in required_files { - let exists = if has_dir { - check_file(&well_known_path, file, report) - } else { - false - }; - report.add_check("Well-Known", file, exists, ComplianceLevel::Bronze); - } -} - -/// Verify build system files -fn check_build_system(report: &mut ComplianceReport, repo_path: &Path) { - // justfile can be either lowercase or Justfile (capitalized) - let justfile_lower = check_file(repo_path, "justfile", report); - let justfile_cap = if !justfile_lower { - check_file(repo_path, "Justfile", report) - } else { - false - }; - report.add_check( - "Build System", - "justfile", - justfile_lower || justfile_cap, - ComplianceLevel::Bronze, - ); - - let other_build_files = vec![ - ("flake.nix", ComplianceLevel::Bronze), - (".gitlab-ci.yml", ComplianceLevel::Bronze), - ]; - - for (file, level) in other_build_files { - let exists = check_file(repo_path, file, report); - report.add_check("Build System", file, exists, level); - } -} - -/// Verify source code structure -fn check_source_structure(report: &mut ComplianceReport, repo_path: &Path) { - let has_src = check_dir(repo_path, "src", report); - let has_tests = check_dir(repo_path, "tests", report) || check_dir(repo_path, "test", report); - - report.add_check( - "Source Structure", - "src/ directory", - has_src, - ComplianceLevel::Bronze, - ); - - report.add_check( - "Source Structure", - "tests/ directory", - has_tests, - ComplianceLevel::Bronze, - ); -} - -/// Run all compliance checks on a repository -pub fn verify_repository(repo_path: &Path) -> ComplianceReport { - let mut report = ComplianceReport::new(repo_path.to_path_buf()); - - check_documentation(&mut report, repo_path); - check_well_known(&mut report, repo_path); - check_build_system(&mut report, repo_path); - check_source_structure(&mut report, repo_path); - - report -} - -/// Format a SystemTime as a human-readable timestamp (ISO 8601) -pub fn format_timestamp(time: SystemTime) -> String { - match time.duration_since(SystemTime::UNIX_EPOCH) { - Ok(duration) => { - let secs = duration.as_secs(); - let days = secs / 86400; - let time_secs = secs % 86400; - let hours = time_secs / 3600; - let minutes = (time_secs % 3600) / 60; - let seconds = time_secs % 60; - - let mut year = 1970; - let mut remaining_days = days; - - loop { - let days_in_year = if year % 4 == 0 && (year % 100 != 0 || year % 400 == 0) { - 366 - } else { - 365 - }; - if remaining_days < days_in_year { - break; - } - remaining_days -= days_in_year; - year += 1; - } - - let is_leap = year % 4 == 0 && (year % 100 != 0 || year % 400 == 0); - let days_in_months: [u64; 12] = if is_leap { - [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - } else { - [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - }; - - let mut month = 1; - for days_in_month in days_in_months.iter() { - if remaining_days < *days_in_month { - break; - } - remaining_days -= days_in_month; - month += 1; - } - let day = remaining_days + 1; - - format!( - "{:04}-{:02}-{:02}T{:02}:{:02}:{:02}Z", - year, month, day, hours, minutes, seconds - ) - }, - Err(_) => "unknown".to_string(), - } -} - -/// Escape a string for JSON output -pub fn json_escape(s: &str) -> String { - let mut result = String::with_capacity(s.len()); - for c in s.chars() { - match c { - '"' => result.push_str("\\\""), - '\\' => result.push_str("\\\\"), - '\n' => result.push_str("\\n"), - '\r' => result.push_str("\\r"), - '\t' => result.push_str("\\t"), - c if c.is_control() => { - result.push_str(&format!("\\u{:04x}", c as u32)); - }, - c => result.push(c), - } - } - result -} - -/// Generate SARIF (Static Analysis Results Interchange Format) output -/// -/// SARIF is a standard JSON format for static analysis tools, supported by -/// GitHub Security tab, GitLab, Azure DevOps, and other platforms. -pub fn generate_sarif(report: &ComplianceReport) -> String { - let timestamp = format_timestamp(report.verified_at); - let repo_path = json_escape(&report.repository_path.display().to_string()); - - let mut sarif = String::new(); - sarif.push_str("{\n"); - sarif.push_str(" \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\",\n"); - sarif.push_str(" \"version\": \"2.1.0\",\n"); - sarif.push_str(" \"runs\": [\n"); - sarif.push_str(" {\n"); - sarif.push_str(" \"tool\": {\n"); - sarif.push_str(" \"driver\": {\n"); - sarif.push_str(" \"name\": \"rhodibot\",\n"); - sarif.push_str(&format!(" \"version\": \"{}\",\n", VERSION)); - sarif.push_str(" \"informationUri\": \"https://github.com/hyperpolymath/rhodium-standard-repositories\",\n"); - sarif.push_str(" \"rules\": [\n"); - - // Generate rules from unique check categories and items - let mut rules: Vec<(&str, &str, &ComplianceLevel)> = Vec::new(); - for check in &report.checks { - let rule_id = format!("{}/{}", check.category, check.item); - if !rules - .iter() - .any(|(cat, item, _)| format!("{}/{}", cat, item) == rule_id) - { - rules.push((&check.category, &check.item, &check.required_for)); - } - } - - for (i, (category, item, level)) in rules.iter().enumerate() { - let rule_id = format!("{}/{}", category, item); - let comma = if i < rules.len() - 1 { "," } else { "" }; - sarif.push_str(" {\n"); - sarif.push_str(&format!( - " \"id\": \"{}\",\n", - json_escape(&rule_id) - )); - sarif.push_str(&format!( - " \"name\": \"{}\",\n", - json_escape(item) - )); - sarif.push_str(" \"shortDescription\": {\n"); - sarif.push_str(&format!( - " \"text\": \"RSR {:?} requirement: {}\"\n", - level, - json_escape(item) - )); - sarif.push_str(" },\n"); - sarif.push_str(&format!( - " \"defaultConfiguration\": {{\n \"level\": \"{}\"\n }}\n", - match level { - ComplianceLevel::Bronze => "error", - ComplianceLevel::Silver => "warning", - ComplianceLevel::Gold => "note", - ComplianceLevel::Platinum => "note", - } - )); - sarif.push_str(&format!(" }}{}\n", comma)); - } - - sarif.push_str(" ]\n"); - sarif.push_str(" }\n"); - sarif.push_str(" },\n"); - - // Invocation info - sarif.push_str(" \"invocations\": [\n"); - sarif.push_str(" {\n"); - sarif.push_str(&format!( - " \"executionSuccessful\": {},\n", - !report.has_critical_warnings() && report.bronze_compliance() - )); - sarif.push_str(&format!(" \"endTimeUtc\": \"{}\"\n", timestamp)); - sarif.push_str(" }\n"); - sarif.push_str(" ],\n"); - - // Results (failed checks and warnings) - sarif.push_str(" \"results\": [\n"); - - let mut result_count = 0; - let total_results = report.checks.iter().filter(|c| !c.passed).count() + report.warnings.len(); - - // Add failed checks - for check in &report.checks { - if !check.passed { - let rule_id = format!("{}/{}", check.category, check.item); - let comma = if result_count < total_results - 1 { - "," - } else { - "" - }; - sarif.push_str(" {\n"); - sarif.push_str(&format!( - " \"ruleId\": \"{}\",\n", - json_escape(&rule_id) - )); - sarif.push_str(&format!( - " \"level\": \"{}\",\n", - match check.required_for { - ComplianceLevel::Bronze => "error", - ComplianceLevel::Silver => "warning", - ComplianceLevel::Gold => "note", - ComplianceLevel::Platinum => "note", - } - )); - sarif.push_str(" \"message\": {\n"); - sarif.push_str(&format!( - " \"text\": \"Missing required file or directory: {}\"\n", - json_escape(&check.item) - )); - sarif.push_str(" },\n"); - sarif.push_str(" \"locations\": [\n"); - sarif.push_str(" {\n"); - sarif.push_str(" \"physicalLocation\": {\n"); - sarif.push_str(" \"artifactLocation\": {\n"); - sarif.push_str(&format!( - " \"uri\": \"{}\"\n", - json_escape(&check.item) - )); - sarif.push_str(" }\n"); - sarif.push_str(" }\n"); - sarif.push_str(" }\n"); - sarif.push_str(" ]\n"); - sarif.push_str(&format!(" }}{}\n", comma)); - result_count += 1; - } - } - - // Add warnings - for warning in &report.warnings { - let comma = if result_count < total_results - 1 { - "," - } else { - "" - }; - sarif.push_str(" {\n"); - sarif.push_str(" \"ruleId\": \"security/warning\",\n"); - sarif.push_str(&format!( - " \"level\": \"{}\",\n", - match warning.level { - WarningLevel::Info => "note", - WarningLevel::Warning => "warning", - WarningLevel::Critical => "error", - } - )); - sarif.push_str(" \"message\": {\n"); - sarif.push_str(&format!( - " \"text\": \"{}\"\n", - json_escape(&warning.message) - )); - sarif.push_str(" }"); - - if let Some(ref path) = warning.path { - sarif.push_str(",\n"); - sarif.push_str(" \"locations\": [\n"); - sarif.push_str(" {\n"); - sarif.push_str(" \"physicalLocation\": {\n"); - sarif.push_str(" \"artifactLocation\": {\n"); - sarif.push_str(&format!( - " \"uri\": \"{}\"\n", - json_escape(&path.display().to_string()) - )); - sarif.push_str(" }\n"); - sarif.push_str(" }\n"); - sarif.push_str(" }\n"); - sarif.push_str(" ]\n"); - } else { - sarif.push('\n'); - } - - sarif.push_str(&format!(" }}{}\n", comma)); - result_count += 1; - } - - sarif.push_str(" ],\n"); - - // Artifact (repository being analyzed) - sarif.push_str(" \"artifacts\": [\n"); - sarif.push_str(" {\n"); - sarif.push_str(" \"location\": {\n"); - sarif.push_str(&format!(" \"uri\": \"{}\"\n", repo_path)); - sarif.push_str(" },\n"); - sarif.push_str(" \"roles\": [\"analysisTarget\"]\n"); - sarif.push_str(" }\n"); - sarif.push_str(" ]\n"); - sarif.push_str(" }\n"); - sarif.push_str(" ]\n"); - sarif.push_str("}\n"); - - sarif -} - -/// Bot action types for CI/CD integration -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum BotAction { - /// Check compliance and report - Check, - /// Check compliance and create PR with fixes - Fix, - /// Generate badge for README - Badge, - /// Generate conformity document - Conformity, -} - -/// Bot configuration -#[derive(Debug, Clone)] -pub struct BotConfig { - pub action: BotAction, - pub create_pr: bool, - pub fail_on_warning: bool, - pub target_level: ComplianceLevel, -} - -impl Default for BotConfig { - fn default() -> Self { - Self { - action: BotAction::Check, - create_pr: false, - fail_on_warning: false, - target_level: ComplianceLevel::Bronze, - } - } -} - -/// Generate RSR badge markdown -pub fn generate_badge(level: ComplianceLevel) -> String { - format!( - "[![Rhodium Standard {}](https://img.shields.io/badge/RSR-{}-{})](https://github.com/hyperpolymath/rhodium-standard-repositories)", - level.display_name(), - level.display_name(), - level.badge_color() - ) -} - -/// Generate RSR conformity document -pub fn generate_conformity_doc(report: &ComplianceReport) -> String { - let level = report.highest_level(); - let level_str = level.map(|l| l.display_name()).unwrap_or("Not Met"); - let timestamp = format_timestamp(report.verified_at); - - let mut doc = String::new(); - doc.push_str("# RSR Conformity Statement\n\n"); - doc.push_str(&format!( - "**Project**: {}\n", - report - .repository_path - .file_name() - .map(|n| n.to_string_lossy().to_string()) - .unwrap_or_else(|| "Unknown".to_string()) - )); - doc.push_str(&format!("**RSR Level**: {}\n", level_str)); - doc.push_str("**Standard**: [Rhodium Standard Repository](https://github.com/hyperpolymath/rhodium-standard-repositories)\n"); - doc.push_str(&format!( - "**Last Verified**: {}\n\n", - timestamp.split('T').next().unwrap_or(×tamp) - )); - - if let Some(l) = level { - doc.push_str(&format!("## {} Requirements Met\n\n", l.display_name())); - doc.push_str("| Requirement | Status |\n"); - doc.push_str("|-------------|--------|\n"); - for check in &report.checks { - if check.required_for == l { - let status = if check.passed { "Yes" } else { "No" }; - doc.push_str(&format!("| {} | {} |\n", check.item, status)); - } - } - } - - doc.push_str("\n## Verification\n\n"); - doc.push_str("Run self-verification:\n"); - doc.push_str("```bash\n"); - doc.push_str("rhodibot check .\n"); - doc.push_str("```\n\n"); - doc.push_str(&format!( - "Expected output: `{}/{} checks passed ({:.1}%)`\n", - report.passed_count(), - report.total_count(), - report.percentage() - )); - - doc -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_compliance_report_creation() { - let path = PathBuf::from("/tmp/test"); - let report = ComplianceReport::new(path.clone()); - assert_eq!(report.repository_path, path); - assert_eq!(report.checks.len(), 0); - } - - #[test] - fn test_add_check() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Test", "Item", true, ComplianceLevel::Bronze); - assert_eq!(report.checks.len(), 1); - assert!(report.checks[0].passed); - } - - #[test] - fn test_bronze_compliance_all_passing() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Test", "Item1", true, ComplianceLevel::Bronze); - report.add_check("Test", "Item2", true, ComplianceLevel::Bronze); - assert!(report.bronze_compliance()); - } - - #[test] - fn test_bronze_compliance_one_failing() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Test", "Item1", true, ComplianceLevel::Bronze); - report.add_check("Test", "Item2", false, ComplianceLevel::Bronze); - assert!(!report.bronze_compliance()); - } - - #[test] - fn test_compliance_level_badge_colors() { - assert_eq!(ComplianceLevel::Bronze.badge_color(), "cd7f32"); - assert_eq!(ComplianceLevel::Silver.badge_color(), "c0c0c0"); - assert_eq!(ComplianceLevel::Gold.badge_color(), "ffd700"); - } - - #[test] - fn test_add_warning() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_warning(WarningLevel::Info, "Test warning", None); - assert_eq!(report.warnings.len(), 1); - assert_eq!(report.warnings[0].level, WarningLevel::Info); - } - - #[test] - fn test_critical_warnings_detection() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_warning(WarningLevel::Info, "Info warning", None); - assert!(!report.has_critical_warnings()); - - report.add_warning(WarningLevel::Critical, "Critical warning", None); - assert!(report.has_critical_warnings()); - } - - #[test] - fn test_generate_badge() { - let badge = generate_badge(ComplianceLevel::Bronze); - assert!(badge.contains("RSR-Bronze")); - assert!(badge.contains("cd7f32")); - } - - #[test] - fn test_format_timestamp() { - use std::time::Duration; - let time = SystemTime::UNIX_EPOCH + Duration::from_secs(1705322445); - let formatted = format_timestamp(time); - assert!(formatted.contains("2024")); - assert!(formatted.ends_with("Z")); - } - - #[test] - fn test_json_escape() { - assert_eq!(json_escape("hello"), "hello"); - assert_eq!(json_escape("he\"llo"), "he\\\"llo"); - assert_eq!(json_escape("he\\llo"), "he\\\\llo"); - assert_eq!(json_escape("he\nllo"), "he\\nllo"); - } - - #[test] - fn test_generate_sarif_basic_structure() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Documentation", "README.md", true, ComplianceLevel::Bronze); - report.add_check( - "Documentation", - "LICENSE.txt", - false, - ComplianceLevel::Bronze, - ); - - let sarif = generate_sarif(&report); - - // Verify SARIF structure - assert!(sarif.contains("\"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\"")); - assert!(sarif.contains("\"version\": \"2.1.0\"")); - assert!(sarif.contains("\"name\": \"rhodibot\"")); - assert!(sarif.contains("\"runs\":")); - assert!(sarif.contains("\"tool\":")); - assert!(sarif.contains("\"results\":")); - } - - #[test] - fn test_generate_sarif_with_failed_checks() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Documentation", "README.md", false, ComplianceLevel::Bronze); - - let sarif = generate_sarif(&report); - - // Should contain a result for the failed check - assert!(sarif.contains("\"ruleId\": \"Documentation/README.md\"")); - assert!(sarif.contains("Missing required file or directory: README.md")); - } - - #[test] - fn test_generate_sarif_with_warnings() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Documentation", "README.md", true, ComplianceLevel::Bronze); - report.add_warning( - WarningLevel::Critical, - "Symlink points outside repository", - Some(PathBuf::from("/tmp/test/link")), - ); - - let sarif = generate_sarif(&report); - - // Should contain the warning - assert!(sarif.contains("security/warning")); - assert!(sarif.contains("Symlink points outside repository")); - } - - #[test] - fn test_generate_sarif_compliant_repo() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Documentation", "README.md", true, ComplianceLevel::Bronze); - report.add_check( - "Documentation", - "LICENSE.txt", - true, - ComplianceLevel::Bronze, - ); - - let sarif = generate_sarif(&report); - - // executionSuccessful should be true for compliant repos - assert!(sarif.contains("\"executionSuccessful\": true")); - } - - #[test] - fn test_generate_sarif_non_compliant_repo() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test")); - report.add_check("Documentation", "README.md", false, ComplianceLevel::Bronze); - - let sarif = generate_sarif(&report); - - // executionSuccessful should be false for non-compliant repos - assert!(sarif.contains("\"executionSuccessful\": false")); - } - - #[test] - fn test_generate_conformity_doc() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/test-project")); - report.add_check("Documentation", "README.md", true, ComplianceLevel::Bronze); - - let doc = generate_conformity_doc(&report); - - assert!(doc.contains("# RSR Conformity Statement")); - assert!(doc.contains("**RSR Level**:")); - assert!(doc.contains("rhodibot check .")); - } -} diff --git a/aletheia/extraction/rhodibot/src/main.rs b/aletheia/extraction/rhodibot/src/main.rs deleted file mode 100644 index 3bed156..0000000 --- a/aletheia/extraction/rhodibot/src/main.rs +++ /dev/null @@ -1,904 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Rhodibot CLI - RSR Compliance Bot -//! -//! A command-line tool for verifying Rhodium Standard Repository compliance. -//! Like Dependabot but for repository standards instead of dependencies. - -use rhodibot::{ - exit_codes, format_timestamp, generate_badge, generate_conformity_doc, generate_sarif, - json_escape, verify_repository, BotAction, ComplianceLevel, ComplianceReport, OutputFormat, - Verbosity, WarningLevel, VERSION, -}; -use std::fs; -use std::path::{Path, PathBuf}; -use std::process; - -/// CLI options -struct CliOptions { - repo_path: PathBuf, - format: OutputFormat, - verbosity: Verbosity, - action: BotAction, -} - -/// Print help message -fn print_help() { - println!( - r#"Rhodibot - RSR Compliance Bot - -Like Dependabot but for Rhodium Standard Repository compliance. - -USAGE: - rhodibot [COMMAND] [OPTIONS] [PATH] - -COMMANDS: - check Check RSR compliance (default) - badge Generate RSR badge markdown - conformity Generate RSR conformity document - -ARGS: - [PATH] Repository path to verify (default: current directory) - -OPTIONS: - -f, --format Output format: human, json (default: human) - -q, --quiet Quiet mode: only show pass/fail result - -v, --verbose Verbose mode: show all details - -h, --help Print help information - -V, --version Print version information - -EXIT CODES: - 0 Success - Bronze compliance achieved - 1 Failure - Bronze compliance not met - 2 Security - Critical security warnings detected - 3 Error - Invalid path provided - 4 Error - Invalid arguments - -EXAMPLES: - rhodibot # Check current directory - rhodibot check /path/to/repo # Check specific repository - rhodibot badge # Generate badge for current directory - rhodibot conformity # Generate conformity document - rhodibot --format json # Output as JSON - -CI/CD INTEGRATION: - # GitHub Actions - - uses: hyperpolymath/rhodibot@v1 - with: - path: '.' - fail-on-warning: true - - # GitLab CI - rhodibot: - image: hyperpolymath/rhodibot:latest - script: - - rhodibot check . -"# - ); -} - -/// Print version information -fn print_version() { - println!("rhodibot {}", VERSION); -} - -/// Parse command line arguments -fn parse_args() -> Result { - let args: Vec = std::env::args().collect(); - let mut format = OutputFormat::Human; - let mut verbosity = Verbosity::Normal; - let mut repo_path: Option = None; - let mut action = BotAction::Check; - - let mut i = 1; - while i < args.len() { - let arg = &args[i]; - match arg.as_str() { - "-h" | "--help" => { - print_help(); - process::exit(exit_codes::SUCCESS); - }, - "-V" | "--version" => { - print_version(); - process::exit(exit_codes::SUCCESS); - }, - "-q" | "--quiet" => { - verbosity = Verbosity::Quiet; - }, - "-v" | "--verbose" => { - verbosity = Verbosity::Verbose; - }, - "-f" | "--format" => { - i += 1; - if i >= args.len() { - return Err("--format requires an argument".to_string()); - } - format = match args[i].as_str() { - "human" => OutputFormat::Human, - "json" => OutputFormat::Json, - other => { - return Err(format!("Unknown format: {}. Use 'human' or 'json'", other)) - }, - }; - }, - "check" => action = BotAction::Check, - "badge" => action = BotAction::Badge, - "conformity" => action = BotAction::Conformity, - "fix" => action = BotAction::Fix, - arg if arg.starts_with('-') => { - if let Some(value) = arg.strip_prefix("--format=") { - format = match value { - "human" => OutputFormat::Human, - "json" => OutputFormat::Json, - other => { - return Err(format!("Unknown format: {}. Use 'human' or 'json'", other)) - }, - }; - } else { - return Err(format!("Unknown option: {}", arg)); - } - }, - path => { - if repo_path.is_some() { - return Err("Multiple paths provided. Only one path is allowed.".to_string()); - } - repo_path = Some(PathBuf::from(path)); - }, - } - i += 1; - } - - let repo_path = - repo_path.unwrap_or_else(|| std::env::current_dir().unwrap_or_else(|_| PathBuf::from("."))); - - Ok(CliOptions { - repo_path, - format, - verbosity, - action, - }) -} - -/// Print the compliance report (human format) -fn print_report(report: &ComplianceReport) { - println!("🤖 Rhodibot - RSR Compliance Report"); - println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); - println!("Repository: {}", report.repository_path.display()); - println!("Verified: {}", format_timestamp(report.verified_at)); - println!(); - - let mut current_category = String::new(); - for check in &report.checks { - if check.category != current_category { - println!("\n📋 {}", check.category); - current_category = check.category.clone(); - } - - let icon = if check.passed { "✅" } else { "❌" }; - let level = format!("{:?}", check.required_for); - println!(" {} {} [{}]", icon, check.item, level); - } - - if !report.warnings.is_empty() { - println!("\n🛡️ Security Warnings"); - for warning in &report.warnings { - let icon = match warning.level { - WarningLevel::Info => "ℹ️ ", - WarningLevel::Warning => "⚠️ ", - WarningLevel::Critical => "🚨", - }; - println!(" {} {}", icon, warning.message); - } - } - - println!(); - println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); - println!( - "Score: {}/{} checks passed ({:.1}%)", - report.passed_count(), - report.total_count(), - report.percentage() - ); - - if report.has_critical_warnings() { - println!("🚨 CRITICAL: Security warnings detected - review required"); - } - - if report.bronze_compliance() && !report.has_critical_warnings() { - println!("🏆 Bronze-level RSR compliance: ACHIEVED"); - } else if report.bronze_compliance() && report.has_critical_warnings() { - println!("⚠️ Bronze-level RSR compliance: ACHIEVED (with warnings)"); - } else { - println!("⚠️ Bronze-level RSR compliance: NOT MET"); - } - println!(); -} - -/// Print report as JSON -fn print_json_report(report: &ComplianceReport) { - let timestamp = format_timestamp(report.verified_at); - let passed = report.passed_count(); - let total = report.total_count(); - let percentage = report.percentage(); - let bronze_compliant = report.bronze_compliance(); - let has_critical = report.has_critical_warnings(); - - println!("{{"); - println!(" \"tool\": \"rhodibot\","); - println!(" \"version\": \"{}\",", VERSION); - println!( - " \"repository\": \"{}\",", - json_escape(&report.repository_path.display().to_string()) - ); - println!(" \"verified_at\": \"{}\",", timestamp); - println!(" \"score\": {{"); - println!(" \"passed\": {},", passed); - println!(" \"total\": {},", total); - println!(" \"percentage\": {:.1}", percentage); - println!(" }},"); - println!(" \"bronze_compliant\": {},", bronze_compliant); - println!(" \"has_critical_warnings\": {},", has_critical); - - println!(" \"checks\": ["); - for (i, check) in report.checks.iter().enumerate() { - let comma = if i < report.checks.len() - 1 { "," } else { "" }; - println!(" {{"); - println!(" \"category\": \"{}\",", json_escape(&check.category)); - println!(" \"item\": \"{}\",", json_escape(&check.item)); - println!(" \"passed\": {},", check.passed); - println!(" \"level\": \"{:?}\"", check.required_for); - println!(" }}{}", comma); - } - println!(" ],"); - - println!(" \"warnings\": ["); - for (i, warning) in report.warnings.iter().enumerate() { - let comma = if i < report.warnings.len() - 1 { - "," - } else { - "" - }; - let level = match warning.level { - WarningLevel::Info => "info", - WarningLevel::Warning => "warning", - WarningLevel::Critical => "critical", - }; - println!(" {{"); - println!(" \"level\": \"{}\",", level); - println!(" \"message\": \"{}\"", json_escape(&warning.message)); - println!(" }}{}", comma); - } - println!(" ]"); - println!("}}"); -} - -/// Print quiet mode output -fn print_quiet_report(report: &ComplianceReport) { - let bronze_compliant = report.bronze_compliance(); - let has_critical = report.has_critical_warnings(); - - if bronze_compliant && !has_critical { - println!("PASS"); - } else if has_critical { - println!("FAIL (security)"); - } else { - println!("FAIL"); - } -} - -/// Print verbose report -fn print_verbose_report(report: &ComplianceReport) { - println!("🤖 Rhodibot - RSR Compliance Report (Verbose)"); - println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); - println!("Repository: {}", report.repository_path.display()); - println!("Verified: {}", format_timestamp(report.verified_at)); - println!("Version: {}", VERSION); - println!(); - - let mut current_category = String::new(); - for check in &report.checks { - if check.category != current_category { - println!("\n📋 {}", check.category); - current_category = check.category.clone(); - } - - let icon = if check.passed { "✅" } else { "❌" }; - let level = format!("{:?}", check.required_for); - println!(" {} {} [{}]", icon, check.item, level); - } - - if !report.warnings.is_empty() { - println!("\n🛡️ Security Warnings ({} total)", report.warnings.len()); - for warning in &report.warnings { - let icon = match warning.level { - WarningLevel::Info => "ℹ️ ", - WarningLevel::Warning => "⚠️ ", - WarningLevel::Critical => "🚨", - }; - let level_str = match warning.level { - WarningLevel::Info => "[INFO]", - WarningLevel::Warning => "[WARN]", - WarningLevel::Critical => "[CRITICAL]", - }; - println!(" {} {} {}", icon, level_str, warning.message); - if let Some(ref path) = warning.path { - println!(" Path: {}", path.display()); - } - } - } - - println!(); - println!("━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━"); - println!( - "Score: {}/{} checks passed ({:.1}%)", - report.passed_count(), - report.total_count(), - report.percentage() - ); - - if report.has_critical_warnings() { - println!("🚨 CRITICAL: Security warnings detected - review required"); - println!( - " Exit code: {} (SECURITY_WARNING)", - exit_codes::SECURITY_WARNING - ); - } - - if report.bronze_compliance() && !report.has_critical_warnings() { - println!("🏆 Bronze-level RSR compliance: ACHIEVED"); - println!(" Exit code: {} (SUCCESS)", exit_codes::SUCCESS); - } else if report.bronze_compliance() && report.has_critical_warnings() { - println!("⚠️ Bronze-level RSR compliance: ACHIEVED (with warnings)"); - println!( - " Exit code: {} (SECURITY_WARNING)", - exit_codes::SECURITY_WARNING - ); - } else { - println!("⚠️ Bronze-level RSR compliance: NOT MET"); - println!( - " Exit code: {} (COMPLIANCE_FAILED)", - exit_codes::COMPLIANCE_FAILED - ); - } - println!(); -} - -/// Apply fixes to create missing RSR-required files -fn apply_fixes(repo_path: &Path, report: &ComplianceReport) -> usize { - let mut fixes_applied = 0; - - for check in &report.checks { - if check.passed { - continue; - } - - // Generate appropriate content based on the missing item - let (relative_path, content) = match (check.category.as_str(), check.item.as_str()) { - ("Documentation", "README.md") => { - let project_name = repo_path - .file_name() - .map(|n| n.to_string_lossy().to_string()) - .unwrap_or_else(|| "Project".to_string()); - ( - "README.md", - format!( - r#"# {} - -## Overview - -A brief description of this project. - -## Installation - -```bash -# Installation instructions here -``` - -## Usage - -```bash -# Usage examples here -``` - -## License - -See [LICENSE.txt](LICENSE.txt) for details. - -## Contributing - -See [CONTRIBUTING.md](../../../../.github/CONTRIBUTING.md) for contribution guidelines. - -## Security - -See [SECURITY.md](SECURITY.md) for security policy. -"#, - project_name - ), - ) - } - ("Documentation", "LICENSE.txt") => ( - "LICENSE.txt", - r#"MIT License - -Copyright (c) [year] [copyright holder] - -Permission is hereby granted, free of charge, to any person obtaining a copy -of this software and associated documentation files (the "Software"), to deal -in the Software without restriction, including without limitation the rights -to use, copy, modify, merge, publish, distribute, sublicense, and/or sell -copies of the Software, and to permit persons to whom the Software is -furnished to do so, subject to the following conditions: - -The above copyright notice and this permission notice shall be included in all -copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER -LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, -OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE -SOFTWARE. -"# - .to_string(), - ), - ("Documentation", "SECURITY.md") => ( - "SECURITY.md", - r#"# Security Policy - -## Supported Versions - -| Version | Supported | -| ------- | ------------------ | -| latest | :white_check_mark: | - -## Reporting a Vulnerability - -Please report security vulnerabilities by emailing security@example.org. - -Do NOT open public issues for security vulnerabilities. - -### What to Include - -- Description of the vulnerability -- Steps to reproduce -- Potential impact -- Suggested fix (if any) - -### Response Timeline - -- Initial response: Within 48 hours -- Status update: Within 7 days -- Resolution target: Within 30 days (critical), 90 days (others) -"# - .to_string(), - ), - ("Documentation", "CONTRIBUTING.md") => ( - "CONTRIBUTING.md", - r#"# Contributing - -Thank you for your interest in contributing! - -## How to Contribute - -1. Fork the repository -2. Create a feature branch (`git checkout -b feature/amazing-feature`) -3. Commit your changes (`git commit -m 'Add amazing feature'`) -4. Push to the branch (`git push origin feature/amazing-feature`) -5. Open a Pull Request - -## Code Style - -- Follow the existing code style -- Write clear commit messages -- Add tests for new features - -## Reporting Issues - -Use the issue tracker to report bugs or request features. - -## Code of Conduct - -Please read and follow our [Code of Conduct](CODE_OF_CONDUCT.md). -"# - .to_string(), - ), - ("Documentation", "CODE_OF_CONDUCT.md") => ( - "CODE_OF_CONDUCT.md", - r#"# Contributor Covenant Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in our -community a harassment-free experience for everyone. - -## Our Standards - -Examples of behavior that contributes to a positive environment: - -* Using welcoming and inclusive language -* Being respectful of differing viewpoints and experiences -* Gracefully accepting constructive criticism -* Focusing on what is best for the community - -Examples of unacceptable behavior: - -* Trolling, insulting/derogatory comments, and personal attacks -* Public or private harassment -* Publishing others' private information without permission - -## Enforcement - -Instances of abusive, harassing, or otherwise unacceptable behavior may be -reported to the project maintainers. All complaints will be reviewed and -investigated promptly and fairly. - -## Attribution - -This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org). -"# - .to_string(), - ), - ("Documentation", "MAINTAINERS.md") => ( - "MAINTAINERS.md", - r#"# Maintainers - -## Current Maintainers - -| Name | Role | Contact | -|------|------|---------| -| Your Name | Lead Maintainer | email@example.org | - -## Becoming a Maintainer - -Contributors who have made significant contributions may be invited to -become maintainers. - -## Responsibilities - -- Review and merge pull requests -- Triage issues -- Release management -- Community support -"# - .to_string(), - ), - ("Documentation", "CHANGELOG.md") => ( - "CHANGELOG.md", - r#"# Changelog - -All notable changes to this project will be documented in this file. - -The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - -## [Unreleased] - -### Added -- Initial project setup - -### Changed -- None - -### Deprecated -- None - -### Removed -- None - -### Fixed -- None - -### Security -- None -"# - .to_string(), - ), - ("Well-Known", ".well-known/ directory") => { - // Create directory - let well_known_path = repo_path.join(".well-known"); - if fs::create_dir_all(&well_known_path).is_ok() { - fixes_applied += 1; - println!(" Created: .well-known/"); - } - continue; - } - ("Well-Known", "security.txt") => ( - ".well-known/security.txt", - r#"# Security contact information -# See https://securitytxt.org/ for format specification - -Contact: mailto:security@example.org -Expires: 2025-12-31T23:59:59.000Z -Preferred-Languages: en -Canonical: https://example.org/.well-known/security.txt -"# - .to_string(), - ), - ("Well-Known", "ai.txt") => ( - ".well-known/ai.txt", - r#"# AI Training Policy -# See proposed standard at https://example.org/ai-txt - -User-agent: * -Disallow: Training - -# This project does not consent to use for AI/ML training without explicit permission. -# Contact: ai-policy@example.org -"# - .to_string(), - ), - ("Well-Known", "humans.txt") => ( - ".well-known/humans.txt", - r#"/* TEAM */ -Developer: Your Name -Contact: email@example.org -Location: Your Location - -/* THANKS */ -Name: Contributors - -/* SITE */ -Last update: 2024/01/01 -Language: English -Standards: RSR Bronze -"# - .to_string(), - ), - ("Build System", "justfile") => ( - "justfile", - r#"# Justfile for project automation -# See https://github.com/casey/just - -# Default recipe -default: - @just --list - -# Build the project -build: - cargo build - -# Build release version -release: - cargo build --release - -# Run tests -test: - cargo test - -# Run clippy lints -lint: - cargo clippy -- -D warnings - -# Format code -fmt: - cargo fmt - -# Check formatting -fmt-check: - cargo fmt --check - -# Run all checks -check: fmt-check lint test - @echo "All checks passed!" - -# Clean build artifacts -clean: - cargo clean -"# - .to_string(), - ), - ("Build System", "flake.nix") => ( - "flake.nix", - r#"{ - description = "Project flake"; - - inputs = { - nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable"; - flake-utils.url = "github:numtide/flake-utils"; - }; - - outputs = { self, nixpkgs, flake-utils }: - flake-utils.lib.eachDefaultSystem (system: - let - pkgs = nixpkgs.legacyPackages.${system}; - in { - devShells.default = pkgs.mkShell { - buildInputs = with pkgs; [ - rustc - cargo - rust-analyzer - clippy - rustfmt - ]; - }; - } - ); -} -"# - .to_string(), - ), - ("Build System", ".gitlab-ci.yml") => ( - ".gitlab-ci.yml", - r#"# GitLab CI/CD Configuration - -stages: - - check - - test - - build - -variables: - CARGO_HOME: ${CI_PROJECT_DIR}/.cargo - -cache: - key: ${CI_COMMIT_REF_SLUG} - paths: - - .cargo/ - - target/ - -check: - stage: check - image: rust:latest - script: - - cargo fmt --check - - cargo clippy -- -D warnings - -test: - stage: test - image: rust:latest - script: - - cargo test --verbose - -build: - stage: build - image: rust:latest - script: - - cargo build --release - artifacts: - paths: - - target/release/ - expire_in: 1 week -"# - .to_string(), - ), - ("Source Structure", "src/ directory") => { - let src_path = repo_path.join("src"); - if fs::create_dir_all(&src_path).is_ok() { - // Create a minimal main.rs - let main_path = src_path.join("main.rs"); - if !main_path.exists() { - let content = r#"fn main() { - println!("Hello, world!"); -} -"#; - if fs::write(&main_path, content).is_ok() { - fixes_applied += 1; - println!(" Created: src/main.rs"); - } - } else { - fixes_applied += 1; - println!(" Created: src/"); - } - } - continue; - } - ("Source Structure", "tests/ directory") => { - let tests_path = repo_path.join("tests"); - if fs::create_dir_all(&tests_path).is_ok() { - // Create a minimal test file - let test_path = tests_path.join("integration_tests.rs"); - if !test_path.exists() { - let content = r#"#[test] -fn test_example() { - assert!(true); -} -"#; - if fs::write(&test_path, content).is_ok() { - fixes_applied += 1; - println!(" Created: tests/integration_tests.rs"); - } - } else { - fixes_applied += 1; - println!(" Created: tests/"); - } - } - continue; - } - _ => continue, - }; - - // Create the file - let file_path = repo_path.join(relative_path); - - // Create parent directories if needed - if let Some(parent) = file_path.parent() { - let _ = fs::create_dir_all(parent); - } - - if !file_path.exists() && fs::write(&file_path, content).is_ok() { - fixes_applied += 1; - println!(" Created: {}", relative_path); - } - } - - fixes_applied -} - -fn main() { - let options = match parse_args() { - Ok(opts) => opts, - Err(e) => { - eprintln!("Error: {}", e); - eprintln!("Use --help for usage information."); - process::exit(exit_codes::INVALID_ARGS); - }, - }; - - if !options.repo_path.exists() { - eprintln!( - "Error: Path does not exist: {}", - options.repo_path.display() - ); - process::exit(exit_codes::INVALID_PATH); - } - - if !options.repo_path.is_dir() { - eprintln!( - "Error: Path is not a directory: {}", - options.repo_path.display() - ); - process::exit(exit_codes::INVALID_PATH); - } - - let report = verify_repository(&options.repo_path); - - // Handle different actions - match options.action { - BotAction::Badge => { - let level = report.highest_level().unwrap_or(ComplianceLevel::Bronze); - println!("{}", generate_badge(level)); - process::exit(exit_codes::SUCCESS); - }, - BotAction::Conformity => { - println!("{}", generate_conformity_doc(&report)); - process::exit(exit_codes::SUCCESS); - }, - BotAction::Fix => { - let fixes_applied = apply_fixes(&options.repo_path, &report); - if fixes_applied > 0 { - println!("Applied {} fixes to the repository.", fixes_applied); - println!("Run 'rhodibot check' to verify compliance."); - } else { - println!("No fixes needed - repository is already compliant."); - } - process::exit(exit_codes::SUCCESS); - }, - BotAction::Check => { - // Continue with normal output - }, - } - - // Output based on format and verbosity - match options.format { - OutputFormat::Json => print_json_report(&report), - OutputFormat::Human => match options.verbosity { - Verbosity::Quiet => print_quiet_report(&report), - Verbosity::Normal => print_report(&report), - Verbosity::Verbose => print_verbose_report(&report), - }, - OutputFormat::Sarif => { - println!("{}", generate_sarif(&report)); - }, - } - - // Exit with appropriate code - let exit_code = if report.has_critical_warnings() { - exit_codes::SECURITY_WARNING - } else if !report.bronze_compliance() { - exit_codes::COMPLIANCE_FAILED - } else { - exit_codes::SUCCESS - }; - - process::exit(exit_code); -} diff --git a/aletheia/extraction/rhodibot/tests/integration_tests.rs b/aletheia/extraction/rhodibot/tests/integration_tests.rs deleted file mode 100644 index ebb15f8..0000000 --- a/aletheia/extraction/rhodibot/tests/integration_tests.rs +++ /dev/null @@ -1,141 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Integration tests for Rhodibot - -use std::path::PathBuf; -use std::process::Command; - -/// Get path to the rhodibot binary -fn rhodibot_binary() -> PathBuf { - let mut path = std::env::current_exe().unwrap(); - path.pop(); // Remove test binary name - path.pop(); // Remove deps - path.push("rhodibot"); - path -} - -#[test] -fn test_help_flag() { - // Build first - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .arg("--help") - .output() - .expect("Failed to execute rhodibot"); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("Rhodibot")); - assert!(stdout.contains("USAGE")); -} - -#[test] -fn test_version_flag() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .arg("--version") - .output() - .expect("Failed to execute rhodibot"); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("rhodibot")); -} - -#[test] -fn test_check_command() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["check", "."]) - .output() - .expect("Failed to execute rhodibot"); - - // May pass or fail depending on repo state, but should not error - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("Rhodibot") || stdout.contains("PASS") || stdout.contains("FAIL")); -} - -#[test] -fn test_badge_command() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["badge"]) - .output() - .expect("Failed to execute rhodibot"); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("RSR")); - assert!(stdout.contains("img.shields.io")); -} - -#[test] -fn test_conformity_command() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["conformity"]) - .output() - .expect("Failed to execute rhodibot"); - - assert!(output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("RSR Conformity Statement")); -} - -#[test] -fn test_json_output() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["check", ".", "--format", "json"]) - .output() - .expect("Failed to execute rhodibot"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("\"tool\": \"rhodibot\"")); - assert!(stdout.contains("\"checks\"")); -} - -#[test] -fn test_quiet_mode() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["check", ".", "--quiet"]) - .output() - .expect("Failed to execute rhodibot"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("PASS") || stdout.contains("FAIL")); -} - -#[test] -fn test_invalid_path() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["check", "/nonexistent/path/12345"]) - .output() - .expect("Failed to execute rhodibot"); - - assert!(!output.status.success()); - assert_eq!(output.status.code(), Some(3)); // INVALID_PATH -} - -#[test] -fn test_invalid_format() { - let _ = Command::new("cargo").args(["build"]).output(); - - let output = Command::new(rhodibot_binary()) - .args(["check", ".", "--format", "invalid"]) - .output() - .expect("Failed to execute rhodibot"); - - assert!(!output.status.success()); - assert_eq!(output.status.code(), Some(4)); // INVALID_ARGS -} diff --git a/aletheia/extraction/rhodium-pipeline/Cargo.lock b/aletheia/extraction/rhodium-pipeline/Cargo.lock deleted file mode 100644 index fb713fc..0000000 --- a/aletheia/extraction/rhodium-pipeline/Cargo.lock +++ /dev/null @@ -1,7 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "rhodium-pipeline" -version = "0.1.0" diff --git a/aletheia/extraction/rhodium-pipeline/Cargo.toml b/aletheia/extraction/rhodium-pipeline/Cargo.toml deleted file mode 100644 index a8f86d6..0000000 --- a/aletheia/extraction/rhodium-pipeline/Cargo.toml +++ /dev/null @@ -1,30 +0,0 @@ -[package] -name = "rhodium-pipeline" -version = "0.1.0" -edition = "2021" -rust-version = "1.70" -description = "RSR-compliant CI/CD pipeline generator and templates" -license = "MIT OR Apache-2.0" -repository = "https://github.com/hyperpolymath/rhodium-pipeline" -keywords = ["rsr", "ci-cd", "pipeline", "devops", "security"] -categories = ["development-tools", "command-line-utilities"] - -[lib] -name = "rhodium_pipeline" -path = "src/lib.rs" - -[[bin]] -name = "rhodium-pipeline" -path = "src/main.rs" - -[dependencies] -# Zero dependencies - RSR Bronze compliant - -[dev-dependencies] -# Testing only - -[profile.release] -lto = true -codegen-units = 1 -strip = true -opt-level = "z" diff --git a/aletheia/extraction/rhodium-pipeline/README.adoc b/aletheia/extraction/rhodium-pipeline/README.adoc deleted file mode 100644 index a2a4820..0000000 --- a/aletheia/extraction/rhodium-pipeline/README.adoc +++ /dev/null @@ -1,236 +0,0 @@ -== Rhodium Pipeline - -https://github.com/hyperpolymath/rhodium-standard-repositories[image:https://img.shields.io/badge/RSR-Bronze-cd7f32[RSR -Bronze]] - -CI/CD pipeline generator and templates for RSR-compliant projects. - -=== What Rhodium Pipeline Does - -* *Generates* CI/CD configuration files (GitHub Actions, GitLab CI) -* *Templates* for RSR-compliant pipelines -* *Validates* existing pipeline configurations -* *Enforces* RSR build requirements (zero dependencies, zero unsafe, -etc.) - -=== Ecosystem Architecture - -.... - ┌─────────────────────────────────────┐ - │ rhodium-standard-repositories │ - │ (The RSR Specification) │ - └─────────────────┬───────────────────┘ - │ defines - ┌──────────────────────────┼──────────────────────────┐ - │ │ │ - ▼ ▼ ▼ -┌─────────────────────┐ ┌─────────────────────┐ ╔═══════════════════════╗ -│ rsr-template-repo │ │ rhodibot │ ║ RHODIUM-PIPELINE ║ -│ (Project Start) │ │ (Compliance Bot) │ ║ ================= ║ -│ │ │ │ ║ CI/CD Generator ║ -│ • Template files │ │ • Check repos │──▶║ Pipeline Templates ║ -│ • Initial setup │ │ • Report issues │ ║ Platform Support ║ -│ • Scaffolding │ │ • Generate badges │ ╚═══════════════════════╝ -└─────────────────────┘ └─────────────────────┘ │ - │ │ │ generates - │ │ ▼ - │ │ ┌─────────────────────┐ - │ │ │ CI/CD Platforms │ - │ │ │ • GitHub Actions │ - │ │ │ • GitLab CI │ - │ │ │ • CircleCI │ - │ │ │ • Jenkins │ - │ │ └─────────────────────┘ - │ │ - └──────────────────────────┴──────────────────────────┐ - │ │ - ▼ │ - ┌─────────────────────────────────────┐ │ - │ repo-customiser │◀─────┘ - │ (C4 Control Point - Generic) │ - │ Works with ANY .scm standard │ - └─────────────────────────────────────┘ -.... - -*Satellite of:* -https://github.com/hyperpolymath/rhodium-standard-repositories[rhodium-standard-repositories] - -Rhodium Pipeline generates CI/CD configurations that enforce RSR -compliance automatically. It works with rhodibot to verify compliance -during pipeline runs. - -=== Quick Start - -[source,bash] ----- -# Install -cargo install rhodium-pipeline - -# Generate GitHub Actions workflow -rhodium-pipeline generate github - -# Generate GitLab CI configuration -rhodium-pipeline generate gitlab - -# Validate existing pipeline -rhodium-pipeline validate . ----- - -=== Pipeline Stages - -Rhodium Pipeline generates pipelines with these stages: - -==== 1. Check Stage - -* Format verification (`+cargo fmt --check+`) -* Linting (`+cargo clippy+`) -* Unsafe code detection -* Dependency audit (verify zero deps) - -==== 2. Test Stage - -* Unit tests -* Integration tests -* Documentation tests -* Release mode tests - -==== 3. Build Stage - -* Debug build -* Release build -* Cross-platform builds (Linux, macOS, Windows) -* MUSL static builds - -==== 4. Verify Stage - -* RSR compliance check (via rhodibot) -* Self-verification -* Badge generation -* Conformity document generation - -==== 5. Deploy Stage (optional) - -* Binary releases -* Container images -* Documentation deployment - -=== CLI Usage - -.... -rhodium-pipeline [COMMAND] [OPTIONS] - -COMMANDS: - generate Generate CI/CD configuration - validate [path] Validate existing pipeline - list List available templates - -PLATFORMS: - github GitHub Actions (.github/workflows/) - gitlab GitLab CI (.gitlab-ci.yml) - circle CircleCI (.circleci/config.yml) - jenkins Jenkinsfile - -OPTIONS: - -o, --output Output path (default: current directory) - -f, --force Overwrite existing files - -h, --help Print help information -.... - -=== Templates - -==== Bronze Pipeline (Default) - -[source,yaml] ----- -# Minimum viable RSR-compliant pipeline -stages: [check, test, build, verify] -features: - - fmt-check - - clippy - - unsafe-detection - - dependency-audit - - unit-tests - - release-build - - rsr-compliance ----- - -==== Silver Pipeline - -[source,yaml] ----- -# Extended pipeline with advanced checks -stages: [check, test, security, build, verify] -features: - - all bronze features - - property-based-tests - - coverage-threshold - - mutation-testing - - formal-verification-hooks ----- - -==== Gold Pipeline - -[source,yaml] ----- -# Multi-language, multi-platform pipeline -stages: [check, test, security, build, verify, deploy] -features: - - all silver features - - cross-platform-builds - - container-builds - - documentation-deploy - - release-automation ----- - -=== Design Principles - -[arabic] -. *Zero Dependencies* - Only Rust standard library -. *Zero Unsafe Code* - 100% safe Rust -. *Template-Based* - Easy customization -. *Platform-Agnostic* - Works with any CI/CD system -. *RSR-First* - Enforces RSR requirements by default - -=== Generated Files - -==== GitHub Actions - -.... -.github/ - workflows/ - ci.yml # Main CI pipeline - release.yml # Release automation - pages.yml # Documentation deployment -.... - -==== GitLab CI - -.... -.gitlab-ci.yml # Full pipeline configuration -.... - -=== Validation - -Rhodium Pipeline can validate existing configurations: - -[source,bash] ----- -rhodium-pipeline validate . ----- - -Checks: - Required stages present - RSR checks configured - Security -scans enabled - No unsafe operations - -=== License - -MIT OR Apache-2.0 - -=== Contributing - -See CONTRIBUTING.md for guidelines. - -''''' - -_Part of the -https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium -Standard] ecosystem_ diff --git a/aletheia/extraction/rhodium-pipeline/docs/VALUE-CHAIN-POLICY.adoc b/aletheia/extraction/rhodium-pipeline/docs/VALUE-CHAIN-POLICY.adoc deleted file mode 100644 index 03661ca..0000000 --- a/aletheia/extraction/rhodium-pipeline/docs/VALUE-CHAIN-POLICY.adoc +++ /dev/null @@ -1,204 +0,0 @@ -== Hyperpolymath Project Value Chain Policy - -This document defines the standard value chain model for all -Hyperpolymath projects. It is based on Porter’s Value Chain framework, -adapted for software development. - -=== Overview - -Every Hyperpolymath project has two types of activities: - -[arabic] -. *Support Activities* - Cross-cutting concerns that apply at all stages -. *Primary Activities* - The value flow from inputs to outputs - -=== Support Activities (Cross-Cutting) - -These apply horizontally across all primary activities: - -[width="100%",cols="34%,43%,23%",options="header",] -|=== -|Activity |Description |Tools -|*Technology* |CCCP stack (containers, runtime, shell) |Cerro Torre, -Svalinn, Valence Shell - -|*Formalizations* |Proofs, validation, verification |Absolute Zero, -Echidna, Coq/Lean/Z3 - -|*Standards* |Repository and code standards |RSR, CCCP, .scm files, -Palimpsest - -|*Infrastructure* |Build, CI/CD, deployment |mustfile, rhodium-pipeline, -GitLab CI -|=== - -=== Primary Activities (Value Flow) - -.... -┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ -│ INBOUND │ │ │ │ OUTBOUND │ │ MARKETING │ │ │ -│ LOGISTICS │──▶│ OPERATIONS │──▶│ LOGISTICS │──▶│ & SALES │──▶│ SERVICE │ -│ │ │ │ │ │ │ │ │ │ -│ Theoretical │ │ Core │ │ Outputs │ │ Standards │ │ Maintenance │ -│ foundations │ │ project │ │ & exports │ │ & business │ │ & ops │ -└─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ └─────────────┘ -.... - -==== 1. Inbound Logistics - -*What*: Foundational inputs specific to the project’s domain - -Examples: - For Aletheia: Absolute Zero (CNO proofs, Landauer, Bennett) -- For rhodibot: RSR specification - For oikos: Economic/ecological -theory - -==== 2. Operations - -*What*: The core project work - what this repository actually builds - -Examples: - For Aletheia: Reversible Minix research (r-Minix precursor) -- For rhodibot: Compliance checking engine - For oikos: -Economic/ecological analyzer - -==== 3. Outbound Logistics - -*What*: Where outputs go - integration with CCCP stack or other projects - -Examples: - To CCCP technology stack (containers, runtime) - To -downstream projects - To future implementations (e.g., Aletheia → -r-Minix) - -==== 4. Marketing & Sales - -*What*: RSR ecosystem, maintenance strategies, business extensions - -Components: - *Corrective maintenance* - Bug fixes, issue resolution - -*Adaptive maintenance* - Platform/environment changes - *Perfective -maintenance* - Improvements, optimizations - -==== 5. Service - -*What*: Ongoing operational support via automation - -Tools: - *feedback-o-tron* - Feedback collection and processing - -*cicd-hyper-a* - CI/CD automation - *robot-repo-automaton* - Repository -automation - -=== Two Input Systems - -All projects receive inputs from two complementary systems: - -==== RSR - Rhodium Standard Repositories - -* *Layer*: Repository organization -* *Handles*: Documentation, security.txt, CI/CD, build systems -* *Tools*: rhodium-standard-repositories, rsr-template-repo, rhodibot, -rhodium-pipeline - -==== CCCP - Campaign for Cooling Coding and Programming - -* *Layer*: Technology stack and code -* *Handles*: Languages, containers, integrations, efficiency -* *Tools*: Cerro Torre, Svalinn, Valence Shell, rescript-tea, -cadre-router - -=== Project-Specific Foundations - -Each project may have domain-specific foundational inputs: - -[cols=",",options="header",] -|=== -|Project |Foundational Input -|Aletheia |Absolute Zero (CNO proofs, reversibility theory) -|Valence Shell |Absolute Zero (filesystem CNO proofs) -|Oikos |Economic/ecological theory -|Echidnabot |Formal methods, SAT/SMT solving -|=== - -=== Standard Files - -All properly configured projects include: - -==== AI Support Files (.scm - Guile Scheme) - -* `+META.scm+` - Project metadata -* `+ECOSYSTEM.scm+` - Ecosystem connections -* `+STATE.scm+` - Current project state -* `+PLAYBOOK.scm+` - Development workflows -* `+AGENTIC.scm+` - AI agent configuration -* `+NEUROSYM.scm+` - Neurosymbolic settings - -==== Build & Standards - -* `+mustfile+` - Build/task automation -* RSR compliance files (README, LICENSE, SECURITY.md, etc.) -* `+.well-known/+` directory - -==== Licensing - -* *Base*: MIT or AGPL (user choice) -* *Overlay*: Palimpsest License (optional but encouraged) - -=== Bot Ecosystem - -Projects are supported by bots operating in multiple modes: - -[cols=",",options="header",] -|=== -|Bot |Role -|*rhodibot* |RSR compliance (consultant, advisor, regulator) -|*echidnabot* |Formal proof validation -|*oikos bot* |Economic/ecological analysis -|=== - -Bots are *self-referential* - they validate their own code. - -=== Applying This Policy - -When setting up a new project: - -[arabic] -. Start with `+rsr-template-repo+` -. Apply customizations via `+repo-customiser+` -. Identify the project’s *foundational input* (inbound logistics) -. Define the *core operations* (what this project builds) -. Specify *outbound targets* (where outputs go) -. Configure *maintenance strategy* (corrective/adaptive/perfective) -. Set up *service automation* (feedback-o-tron, cicd-hyper-a, etc.) - -=== Diagram - -.... -┌─────────────────────────────────────────────────────────────────────────────────────┐ -│ SUPPORT ACTIVITIES (Cross-cutting) │ -├─────────────────────────────────────────────────────────────────────────────────────┤ -│ TECHNOLOGY │ CCCP: Cerro Torre, Svalinn, Valence Shell, rescript-tea... │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ FORMALIZATIONS │ Absolute Zero, Echidna, Coq/Lean/Z3, formal proofs │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ STANDARDS │ RSR (repo), CCCP (code), .scm files, Palimpsest licensing │ -├──────────────────┼──────────────────────────────────────────────────────────────────┤ -│ INFRASTRUCTURE │ mustfile, rhodium-pipeline, GitLab CI, GitHub Actions │ -└──────────────────┴──────────────────────────────────────────────────────────────────┘ - │ -┌───────────────────────────────────────────┼─────────────────────────────────────────┐ -│ PRIMARY ACTIVITIES (Value Flow) │ -│ │ │ -│ ┌───────────┐ ┌───────────┐ ┌────────┴──┐ ┌───────────┐ ┌───────────┐ │ -│ │ INBOUND │ │ │ │ OUTBOUND │ │ MARKETING │ │ │ │ -│ │ LOGISTICS │──▶│ OPERATIONS│──▶│ LOGISTICS │──▶│ & SALES │──▶│ SERVICE │ │ -│ └───────────┘ └───────────┘ └───────────┘ └───────────┘ └───────────┘ │ -│ │ -│ Foundational Core project To CCCP/ RSR system feedback-o-tron │ -│ theory/proofs development other projects Maintenance cicd-hyper-a │ -│ strategies robot-repo-auto │ -│ │ -│ ═══════════════════════════════════════════════════════════════════════════════▶ │ -│ VALUE CREATION MARGIN │ -└─────────────────────────────────────────────────────────────────────────────────────┘ -.... - -''''' - -_This policy applies to all Hyperpolymath projects and their satellite -repositories._ diff --git a/aletheia/extraction/rhodium-pipeline/src/lib.rs b/aletheia/extraction/rhodium-pipeline/src/lib.rs deleted file mode 100644 index 594a9e5..0000000 --- a/aletheia/extraction/rhodium-pipeline/src/lib.rs +++ /dev/null @@ -1,563 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Rhodium Pipeline - CI/CD Pipeline Generator -//! -//! Generates RSR-compliant CI/CD configurations for various platforms. -//! -//! # Features -//! -//! - Zero dependencies (uses only Rust std library) -//! - Template-based pipeline generation -//! - Multi-platform support (GitHub, GitLab, CircleCI, Jenkins) -//! - RSR compliance enforcement - -use std::path::Path; - -/// Library version -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); - -/// Supported CI/CD platforms -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum Platform { - GitHub, - GitLab, - CircleCI, - Jenkins, -} - -impl Platform { - /// Parse platform from string - pub fn parse(s: &str) -> Option { - match s.to_lowercase().as_str() { - "github" | "gh" => Some(Platform::GitHub), - "gitlab" | "gl" => Some(Platform::GitLab), - "circleci" | "circle" => Some(Platform::CircleCI), - "jenkins" => Some(Platform::Jenkins), - _ => None, - } - } - - /// Get the default output path for this platform - pub fn default_path(&self) -> &'static str { - match self { - Platform::GitHub => ".github/workflows/ci.yml", - Platform::GitLab => ".gitlab-ci.yml", - Platform::CircleCI => ".circleci/config.yml", - Platform::Jenkins => "Jenkinsfile", - } - } -} - -/// Pipeline compliance level -#[derive(Debug, Clone, Copy, PartialEq, Eq)] -pub enum PipelineLevel { - Bronze, - Silver, - Gold, - Platinum, -} - -/// Pipeline generation options -#[derive(Debug, Clone)] -pub struct PipelineOptions { - pub platform: Platform, - pub level: PipelineLevel, - pub include_deploy: bool, - pub project_name: String, - pub rust_version: String, -} - -impl Default for PipelineOptions { - fn default() -> Self { - Self { - platform: Platform::GitHub, - level: PipelineLevel::Bronze, - include_deploy: false, - project_name: String::from("project"), - rust_version: String::from("stable"), - } - } -} - -/// Generate GitHub Actions workflow -pub fn generate_github_actions(options: &PipelineOptions) -> String { - format!( - r#"# RSR-Compliant CI/CD Pipeline -# Generated by Rhodium Pipeline v{version} -# Level: {level:?} - -name: CI - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - schedule: - - cron: '0 0 * * 1' # Weekly - -env: - CARGO_TERM_COLOR: always - RUSTFLAGS: -Dwarnings - -jobs: - # Stage 1: Check - check: - name: Check - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-action@{rust_version} - - - name: Check formatting - run: cargo fmt --check - - - name: Clippy - run: cargo clippy -- -D warnings - - - name: Check for unsafe code - run: | - if grep -r "unsafe" src/; then - echo "::error::Unsafe code detected!" - exit 1 - fi - - - name: Check for dependencies - run: | - deps=$(cargo tree --depth 0 | grep -c "^") - if [ "$deps" -gt 1 ]; then - echo "::error::External dependencies detected!" - cargo tree - exit 1 - fi - - # Stage 2: Test - test: - name: Test - runs-on: ubuntu-latest - needs: check - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-action@{rust_version} - - - name: Run tests - run: cargo test --verbose - - - name: Run tests (release) - run: cargo test --release --verbose - - - name: Doc tests - run: cargo test --doc - - # Stage 3: Build - build: - name: Build - runs-on: ${{{{ matrix.os }}}} - needs: test - strategy: - matrix: - os: [ubuntu-latest, macos-latest, windows-latest] - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-action@{rust_version} - - - name: Build release - run: cargo build --release - - - name: Upload binary - uses: actions/upload-artifact@v4 - with: - name: {project_name}-${{{{ matrix.os }}}} - path: | - target/release/{project_name} - target/release/{project_name}.exe - - # Stage 4: Verify RSR Compliance - verify: - name: RSR Compliance - runs-on: ubuntu-latest - needs: build - steps: - - uses: actions/checkout@v4 - - uses: dtolnay/rust-action@{rust_version} - - - name: Build - run: cargo build --release - - - name: Self-verify - run: cargo run -- check . || true - - - name: Generate badge - run: | - echo "![RSR Bronze](https://img.shields.io/badge/RSR-Bronze-cd7f32)" > RSR_BADGE.md -"#, - version = VERSION, - level = options.level, - rust_version = options.rust_version, - project_name = options.project_name, - ) -} - -/// Generate GitLab CI configuration -pub fn generate_gitlab_ci(options: &PipelineOptions) -> String { - format!( - r#"# RSR-Compliant CI/CD Pipeline -# Generated by Rhodium Pipeline v{version} -# Level: {level:?} - -stages: - - check - - test - - build - - verify - -variables: - CARGO_HOME: ${{CI_PROJECT_DIR}}/.cargo - RUSTFLAGS: "-Dwarnings" - -.rust-template: - image: rust:{rust_version} - cache: - key: ${{CI_COMMIT_REF_SLUG}} - paths: - - .cargo/ - - target/ - -# Stage 1: Check -fmt: - extends: .rust-template - stage: check - script: - - cargo fmt --check - -clippy: - extends: .rust-template - stage: check - script: - - rustup component add clippy - - cargo clippy -- -D warnings - -unsafe-check: - extends: .rust-template - stage: check - script: - - | - if grep -r "unsafe" src/; then - echo "Unsafe code detected!" - exit 1 - fi - -deps-check: - extends: .rust-template - stage: check - script: - - | - deps=$(cargo tree --depth 0 | grep -c "^") - if [ "$deps" -gt 1 ]; then - echo "External dependencies detected!" - exit 1 - fi - -# Stage 2: Test -test: - extends: .rust-template - stage: test - script: - - cargo test --verbose - -test-release: - extends: .rust-template - stage: test - script: - - cargo test --release --verbose - -# Stage 3: Build -build-debug: - extends: .rust-template - stage: build - script: - - cargo build - artifacts: - paths: - - target/debug/{project_name} - expire_in: 1 week - -build-release: - extends: .rust-template - stage: build - script: - - cargo build --release - artifacts: - paths: - - target/release/{project_name} - expire_in: 1 month - -# Stage 4: Verify -verify: - extends: .rust-template - stage: verify - dependencies: - - build-release - script: - - ./target/release/{project_name} check . || true -"#, - version = VERSION, - level = options.level, - rust_version = options.rust_version, - project_name = options.project_name, - ) -} - -/// Generate CircleCI configuration -pub fn generate_circleci(options: &PipelineOptions) -> String { - format!( - r#"# RSR-Compliant CI/CD Pipeline -# Generated by Rhodium Pipeline v{version} -# Level: {level:?} - -version: 2.1 - -executors: - rust: - docker: - - image: rust:{rust_version} - -jobs: - check: - executor: rust - steps: - - checkout - - run: - name: Check formatting - command: cargo fmt --check - - run: - name: Clippy - command: cargo clippy -- -D warnings - - run: - name: Check for unsafe code - command: | - if grep -r "unsafe" src/; then - echo "Unsafe code detected!" - exit 1 - fi - - test: - executor: rust - steps: - - checkout - - run: - name: Run tests - command: cargo test --verbose - - run: - name: Run release tests - command: cargo test --release --verbose - - build: - executor: rust - steps: - - checkout - - run: - name: Build release - command: cargo build --release - - store_artifacts: - path: target/release/{project_name} - - verify: - executor: rust - steps: - - checkout - - run: - name: Build and verify - command: | - cargo build --release - ./target/release/{project_name} check . || true - -workflows: - rsr-pipeline: - jobs: - - check - - test: - requires: - - check - - build: - requires: - - test - - verify: - requires: - - build -"#, - version = VERSION, - level = options.level, - rust_version = options.rust_version, - project_name = options.project_name, - ) -} - -/// Generate Jenkinsfile -pub fn generate_jenkinsfile(options: &PipelineOptions) -> String { - format!( - r#"// RSR-Compliant CI/CD Pipeline -// Generated by Rhodium Pipeline v{version} -// Level: {level:?} - -pipeline {{ - agent any - - environment {{ - CARGO_HOME = "${{WORKSPACE}}/.cargo" - RUSTFLAGS = '-Dwarnings' - }} - - stages {{ - stage('Check') {{ - steps {{ - sh 'cargo fmt --check' - sh 'cargo clippy -- -D warnings' - sh ''' - if grep -r "unsafe" src/; then - echo "Unsafe code detected!" - exit 1 - fi - ''' - }} - }} - - stage('Test') {{ - steps {{ - sh 'cargo test --verbose' - sh 'cargo test --release --verbose' - }} - }} - - stage('Build') {{ - steps {{ - sh 'cargo build --release' - }} - post {{ - success {{ - archiveArtifacts artifacts: 'target/release/{project_name}', fingerprint: true - }} - }} - }} - - stage('Verify') {{ - steps {{ - sh './target/release/{project_name} check . || true' - }} - }} - }} - - post {{ - always {{ - cleanWs() - }} - }} -}} -"#, - version = VERSION, - level = options.level, - project_name = options.project_name, - ) -} - -/// Generate pipeline configuration for the specified platform -pub fn generate_pipeline(options: &PipelineOptions) -> String { - match options.platform { - Platform::GitHub => generate_github_actions(options), - Platform::GitLab => generate_gitlab_ci(options), - Platform::CircleCI => generate_circleci(options), - Platform::Jenkins => generate_jenkinsfile(options), - } -} - -/// Validation result -#[derive(Debug)] -pub struct ValidationResult { - pub valid: bool, - pub errors: Vec, - pub warnings: Vec, -} - -/// Validate an existing pipeline configuration -pub fn validate_pipeline(path: &Path) -> ValidationResult { - let mut result = ValidationResult { - valid: true, - errors: Vec::new(), - warnings: Vec::new(), - }; - - // Check for GitHub Actions - let github_path = path.join(".github/workflows"); - let gitlab_path = path.join(".gitlab-ci.yml"); - let circleci_path = path.join(".circleci/config.yml"); - let jenkins_path = path.join("Jenkinsfile"); - - let has_ci = github_path.exists() - || gitlab_path.exists() - || circleci_path.exists() - || jenkins_path.exists(); - - if !has_ci { - result - .errors - .push("No CI/CD configuration found".to_string()); - result.valid = false; - } - - // Check for required elements (basic validation) - if github_path.exists() { - if let Ok(entries) = std::fs::read_dir(&github_path) { - let has_workflow = entries.filter_map(|e| e.ok()).any(|e| { - e.path() - .extension() - .map(|ext| ext == "yml") - .unwrap_or(false) - }); - if !has_workflow { - result - .warnings - .push("No workflow files in .github/workflows/".to_string()); - } - } - } - - result -} - -#[cfg(test)] -mod tests { - use super::*; - - #[test] - fn test_platform_parsing() { - assert_eq!(Platform::parse("github"), Some(Platform::GitHub)); - assert_eq!(Platform::parse("gitlab"), Some(Platform::GitLab)); - assert_eq!(Platform::parse("invalid"), None); - } - - #[test] - fn test_default_paths() { - assert_eq!(Platform::GitHub.default_path(), ".github/workflows/ci.yml"); - assert_eq!(Platform::GitLab.default_path(), ".gitlab-ci.yml"); - } - - #[test] - fn test_github_generation() { - let options = PipelineOptions::default(); - let result = generate_github_actions(&options); - assert!(result.contains("cargo fmt --check")); - assert!(result.contains("cargo clippy")); - assert!(result.contains("unsafe")); - } - - #[test] - fn test_gitlab_generation() { - let options = PipelineOptions { - platform: Platform::GitLab, - ..Default::default() - }; - let result = generate_gitlab_ci(&options); - assert!(result.contains("stages:")); - assert!(result.contains("cargo test")); - } -} diff --git a/aletheia/extraction/rhodium-pipeline/src/main.rs b/aletheia/extraction/rhodium-pipeline/src/main.rs deleted file mode 100644 index 430dc73..0000000 --- a/aletheia/extraction/rhodium-pipeline/src/main.rs +++ /dev/null @@ -1,222 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Rhodium Pipeline CLI -//! -//! Generate RSR-compliant CI/CD configurations. - -use rhodium_pipeline::{ - generate_pipeline, validate_pipeline, PipelineLevel, PipelineOptions, Platform, VERSION, -}; -use std::fs; -use std::path::PathBuf; -use std::process; - -fn print_help() { - println!( - r#"Rhodium Pipeline - RSR CI/CD Pipeline Generator - -USAGE: - rhodium-pipeline [COMMAND] [OPTIONS] - -COMMANDS: - generate Generate CI/CD configuration - validate [path] Validate existing pipeline - list List available templates - -PLATFORMS: - github GitHub Actions (.github/workflows/) - gitlab GitLab CI (.gitlab-ci.yml) - circle CircleCI (.circleci/config.yml) - jenkins Jenkinsfile - -OPTIONS: - -o, --output Output path (default: stdout) - -n, --name Project name (default: project) - -l, --level RSR level: bronze, silver, gold (default: bronze) - -f, --force Overwrite existing files - -h, --help Print help information - -V, --version Print version information - -EXAMPLES: - rhodium-pipeline generate github - rhodium-pipeline generate gitlab -o .gitlab-ci.yml - rhodium-pipeline validate . - rhodium-pipeline list -"# - ); -} - -fn print_version() { - println!("rhodium-pipeline {}", VERSION); -} - -fn list_templates() { - println!("Available Templates:"); - println!(); - println!(" Platforms:"); - println!(" github - GitHub Actions workflow"); - println!(" gitlab - GitLab CI configuration"); - println!(" circle - CircleCI configuration"); - println!(" jenkins - Jenkinsfile"); - println!(); - println!(" Levels:"); - println!(" bronze - Basic RSR compliance (default)"); - println!(" silver - Extended checks and testing"); - println!(" gold - Multi-platform builds"); - println!(" platinum - Full enterprise pipeline"); -} - -fn main() { - let args: Vec = std::env::args().collect(); - - if args.len() < 2 { - print_help(); - process::exit(0); - } - - let mut output_path: Option = None; - let mut project_name = String::from("project"); - let mut level = PipelineLevel::Bronze; - let mut force = false; - - // Parse global options first - let mut i = 1; - while i < args.len() { - match args[i].as_str() { - "-h" | "--help" => { - print_help(); - process::exit(0); - }, - "-V" | "--version" => { - print_version(); - process::exit(0); - }, - "-o" | "--output" => { - i += 1; - if i < args.len() { - output_path = Some(PathBuf::from(&args[i])); - } - }, - "-n" | "--name" => { - i += 1; - if i < args.len() { - project_name = args[i].clone(); - } - }, - "-l" | "--level" => { - i += 1; - if i < args.len() { - level = match args[i].as_str() { - "bronze" => PipelineLevel::Bronze, - "silver" => PipelineLevel::Silver, - "gold" => PipelineLevel::Gold, - "platinum" => PipelineLevel::Platinum, - _ => { - eprintln!("Unknown level: {}", args[i]); - process::exit(1); - }, - }; - } - }, - "-f" | "--force" => force = true, - _ => break, - } - i += 1; - } - - if i >= args.len() { - print_help(); - process::exit(0); - } - - match args[i].as_str() { - "generate" => { - i += 1; - if i >= args.len() { - eprintln!("Error: Platform required. Use: github, gitlab, circle, jenkins"); - process::exit(1); - } - - let platform = match Platform::parse(&args[i]) { - Some(p) => p, - None => { - eprintln!("Unknown platform: {}", args[i]); - process::exit(1); - }, - }; - - let options = PipelineOptions { - platform, - level, - include_deploy: false, - project_name, - rust_version: String::from("stable"), - }; - - let config = generate_pipeline(&options); - - if let Some(path) = output_path { - if path.exists() && !force { - eprintln!( - "Error: {} already exists. Use --force to overwrite.", - path.display() - ); - process::exit(1); - } - - // Create parent directories if needed - if let Some(parent) = path.parent() { - let _ = fs::create_dir_all(parent); - } - - if let Err(e) = fs::write(&path, &config) { - eprintln!("Error writing {}: {}", path.display(), e); - process::exit(1); - } - println!("Generated: {}", path.display()); - } else { - println!("{}", config); - } - }, - "validate" => { - i += 1; - let path = if i < args.len() { - PathBuf::from(&args[i]) - } else { - PathBuf::from(".") - }; - - let result = validate_pipeline(&path); - - if !result.errors.is_empty() { - println!("Errors:"); - for error in &result.errors { - println!(" - {}", error); - } - } - - if !result.warnings.is_empty() { - println!("Warnings:"); - for warning in &result.warnings { - println!(" - {}", warning); - } - } - - if result.valid { - println!("Pipeline configuration is valid."); - process::exit(0); - } else { - println!("Pipeline configuration has issues."); - process::exit(1); - } - }, - "list" => { - list_templates(); - }, - cmd => { - eprintln!("Unknown command: {}", cmd); - print_help(); - process::exit(1); - }, - } -} diff --git a/aletheia/ffi/zig/build.zig b/aletheia/ffi/zig/build.zig deleted file mode 100644 index c02617f..0000000 --- a/aletheia/ffi/zig/build.zig +++ /dev/null @@ -1,95 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// {{PROJECT}} FFI Build Configuration - -const std = @import("std"); - -pub fn build(b: *std.Build) void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - - // Shared library (.so, .dylib, .dll) - const lib = b.addSharedLibrary(.{ - .name = "{{project}}", - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); - - // Set version - lib.version = .{ .major = 0, .minor = 1, .patch = 0 }; - - // Static library (.a) - const lib_static = b.addStaticLibrary(.{ - .name = "{{project}}", - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); - - // Install artifacts - b.installArtifact(lib); - b.installArtifact(lib_static); - - // Generate header file for C compatibility - const header = b.addInstallHeader( - b.path("include/{{project}}.h"), - "{{project}}.h", - ); - b.getInstallStep().dependOn(&header.step); - - // Unit tests - const lib_tests = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - }); - - const run_lib_tests = b.addRunArtifact(lib_tests); - - const test_step = b.step("test", "Run library tests"); - test_step.dependOn(&run_lib_tests.step); - - // Integration tests - const integration_tests = b.addTest(.{ - .root_source_file = b.path("test/integration_test.zig"), - .target = target, - .optimize = optimize, - }); - - integration_tests.linkLibrary(lib); - - const run_integration_tests = b.addRunArtifact(integration_tests); - - const integration_test_step = b.step("test-integration", "Run integration tests"); - integration_test_step.dependOn(&run_integration_tests.step); - - // Documentation - const docs = b.addTest(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = .Debug, - }); - - const docs_step = b.step("docs", "Generate documentation"); - docs_step.dependOn(&b.addInstallDirectory(.{ - .source_dir = docs.getEmittedDocs(), - .install_dir = .prefix, - .install_subdir = "docs", - }).step); - - // Benchmark (if needed) - const bench = b.addExecutable(.{ - .name = "{{project}}-bench", - .root_source_file = b.path("bench/bench.zig"), - .target = target, - .optimize = .ReleaseFast, - }); - - bench.linkLibrary(lib); - - const run_bench = b.addRunArtifact(bench); - - const bench_step = b.step("bench", "Run benchmarks"); - bench_step.dependOn(&run_bench.step); -} diff --git a/aletheia/ffi/zig/src/main.zig b/aletheia/ffi/zig/src/main.zig deleted file mode 100644 index f1b2633..0000000 --- a/aletheia/ffi/zig/src/main.zig +++ /dev/null @@ -1,275 +0,0 @@ -// 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. -// - -const std = @import("std"); - -// Version information (keep in sync with project) -const VERSION = "0.1.0"; -const BUILD_INFO = "{{PROJECT}} built with Zig " ++ @import("builtin").zig_version_string; - -/// Thread-local error storage -threadlocal var last_error: ?[]const u8 = null; - -/// Set the last error message -fn setError(msg: []const u8) void { - last_error = msg; -} - -/// Clear the last error -fn clearError() void { - last_error = null; -} - -//============================================================================== -// Core Types (must match src/abi/Types.idr) -//============================================================================== - -/// Result codes (must match Idris2 Result type) -pub const Result = enum(c_int) { - ok = 0, - @"error" = 1, - invalid_param = 2, - out_of_memory = 3, - null_pointer = 4, -}; - -/// Library handle (opaque to prevent direct access) -pub const Handle = opaque { - // Internal state hidden from C - allocator: std.mem.Allocator, - initialized: bool, - // Add your fields here -}; - -//============================================================================== -// Library Lifecycle -//============================================================================== - -/// Initialize the library -/// Returns a handle, or null on failure -export fn {{project}}_init() ?*Handle { - const allocator = std.heap.c_allocator; - - const handle = allocator.create(Handle) catch { - setError("Failed to allocate handle"); - return null; - }; - - // Initialize handle - handle.* = .{ - .allocator = allocator, - .initialized = true, - }; - - clearError(); - return handle; -} - -/// Free the library handle -export fn {{project}}_free(handle: ?*Handle) void { - const h = handle orelse return; - const allocator = h.allocator; - - // Clean up resources - h.initialized = false; - - allocator.destroy(h); - clearError(); -} - -//============================================================================== -// Core Operations -//============================================================================== - -/// Process data (example operation) -export fn {{project}}_process(handle: ?*Handle, input: u32) Result { - const h = handle orelse { - setError("Null handle"); - return .null_pointer; - }; - - if (!h.initialized) { - setError("Handle not initialized"); - return .@"error"; - } - - // Example processing logic - _ = input; - - clearError(); - return .ok; -} - -//============================================================================== -// String Operations -//============================================================================== - -/// Get a string result (example) -/// Caller must free the returned string -export fn {{project}}_get_string(handle: ?*Handle) ?[*:0]const u8 { - const h = handle orelse { - setError("Null handle"); - return null; - }; - - if (!h.initialized) { - setError("Handle not initialized"); - return null; - } - - // Example: allocate and return a string - const result = h.allocator.dupeZ(u8, "Example result") catch { - setError("Failed to allocate string"); - return null; - }; - - clearError(); - return result.ptr; -} - -/// Free a string allocated by the library -export fn {{project}}_free_string(str: ?[*:0]const u8) void { - const s = str orelse return; - const allocator = std.heap.c_allocator; - - const slice = std.mem.span(s); - allocator.free(slice); -} - -//============================================================================== -// Array/Buffer Operations -//============================================================================== - -/// Process an array of data -export fn {{project}}_process_array( - handle: ?*Handle, - buffer: ?[*]const u8, - len: u32, -) Result { - const h = handle orelse { - setError("Null handle"); - return .null_pointer; - }; - - const buf = buffer orelse { - setError("Null buffer"); - return .null_pointer; - }; - - if (!h.initialized) { - setError("Handle not initialized"); - return .@"error"; - } - - // Access the buffer - const data = buf[0..len]; - _ = data; - - // Process data here - - clearError(); - return .ok; -} - -//============================================================================== -// Error Handling -//============================================================================== - -/// Get the last error message -/// Returns null if no error -export fn {{project}}_last_error() ?[*:0]const u8 { - const err = last_error orelse return null; - - // Return C string (static storage, no need to free) - const allocator = std.heap.c_allocator; - const c_str = allocator.dupeZ(u8, err) catch return null; - return c_str.ptr; -} - -//============================================================================== -// Version Information -//============================================================================== - -/// Get the library version -export fn {{project}}_version() [*:0]const u8 { - return VERSION.ptr; -} - -/// Get build information -export fn {{project}}_build_info() [*:0]const u8 { - return BUILD_INFO.ptr; -} - -//============================================================================== -// Callback Support -//============================================================================== - -/// Callback function type (C ABI) -pub const Callback = *const fn (u64, u32) callconv(.C) u32; - -/// Register a callback -export fn {{project}}_register_callback( - handle: ?*Handle, - callback: ?Callback, -) Result { - const h = handle orelse { - setError("Null handle"); - return .null_pointer; - }; - - const cb = callback orelse { - setError("Null callback"); - return .null_pointer; - }; - - if (!h.initialized) { - setError("Handle not initialized"); - return .@"error"; - } - - // Store callback for later use - _ = cb; - - clearError(); - return .ok; -} - -//============================================================================== -// Utility Functions -//============================================================================== - -/// Check if handle is initialized -export fn {{project}}_is_initialized(handle: ?*Handle) u32 { - const h = handle orelse return 0; - return if (h.initialized) 1 else 0; -} - -//============================================================================== -// Tests -//============================================================================== - -test "lifecycle" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - try std.testing.expect({{project}}_is_initialized(handle) == 1); -} - -test "error handling" { - const result = {{project}}_process(null, 0); - try std.testing.expectEqual(Result.null_pointer, result); - - const err = {{project}}_last_error(); - try std.testing.expect(err != null); -} - -test "version" { - const ver = {{project}}_version(); - const ver_str = std.mem.span(ver); - try std.testing.expectEqualStrings(VERSION, ver_str); -} diff --git a/aletheia/ffi/zig/test/integration_test.zig b/aletheia/ffi/zig/test/integration_test.zig deleted file mode 100644 index e481508..0000000 --- a/aletheia/ffi/zig/test/integration_test.zig +++ /dev/null @@ -1,183 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -// {{PROJECT}} Integration Tests -// -// These tests verify that the Zig FFI correctly implements the Idris2 ABI - -const std = @import("std"); -const testing = std.testing; - -// Import FFI functions -extern fn {{project}}_init() ?*opaque {}; -extern fn {{project}}_free(?*opaque {}) void; -extern fn {{project}}_process(?*opaque {}, u32) c_int; -extern fn {{project}}_get_string(?*opaque {}) ?[*:0]const u8; -extern fn {{project}}_free_string(?[*:0]const u8) void; -extern fn {{project}}_last_error() ?[*:0]const u8; -extern fn {{project}}_version() [*:0]const u8; -extern fn {{project}}_is_initialized(?*opaque {}) u32; - -//============================================================================== -// Lifecycle Tests -//============================================================================== - -test "create and destroy handle" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - try testing.expect(handle != null); -} - -test "handle is initialized" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - const initialized = {{project}}_is_initialized(handle); - try testing.expectEqual(@as(u32, 1), initialized); -} - -test "null handle is not initialized" { - const initialized = {{project}}_is_initialized(null); - try testing.expectEqual(@as(u32, 0), initialized); -} - -//============================================================================== -// Operation Tests -//============================================================================== - -test "process with valid handle" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - const result = {{project}}_process(handle, 42); - try testing.expectEqual(@as(c_int, 0), result); // 0 = ok -} - -test "process with null handle returns error" { - const result = {{project}}_process(null, 42); - try testing.expectEqual(@as(c_int, 4), result); // 4 = null_pointer -} - -//============================================================================== -// String Tests -//============================================================================== - -test "get string result" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - const str = {{project}}_get_string(handle); - defer if (str) |s| {{project}}_free_string(s); - - try testing.expect(str != null); -} - -test "get string with null handle" { - const str = {{project}}_get_string(null); - try testing.expect(str == null); -} - -//============================================================================== -// Error Handling Tests -//============================================================================== - -test "last error after null handle operation" { - _ = {{project}}_process(null, 0); - - const err = {{project}}_last_error(); - try testing.expect(err != null); - - if (err) |e| { - const err_str = std.mem.span(e); - try testing.expect(err_str.len > 0); - } -} - -test "no error after successful operation" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - _ = {{project}}_process(handle, 0); - - // Error should be cleared after successful operation - // (This depends on implementation) -} - -//============================================================================== -// Version Tests -//============================================================================== - -test "version string is not empty" { - const ver = {{project}}_version(); - const ver_str = std.mem.span(ver); - - try testing.expect(ver_str.len > 0); -} - -test "version string is semantic version format" { - const ver = {{project}}_version(); - const ver_str = std.mem.span(ver); - - // Should be in format X.Y.Z - try testing.expect(std.mem.count(u8, ver_str, ".") >= 1); -} - -//============================================================================== -// Memory Safety Tests -//============================================================================== - -test "multiple handles are independent" { - const h1 = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(h1); - - const h2 = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(h2); - - try testing.expect(h1 != h2); - - // Operations on h1 should not affect h2 - _ = {{project}}_process(h1, 1); - _ = {{project}}_process(h2, 2); -} - -test "double free is safe" { - const handle = {{project}}_init() orelse return error.InitFailed; - - {{project}}_free(handle); - {{project}}_free(handle); // Should not crash -} - -test "free null is safe" { - {{project}}_free(null); // Should not crash -} - -//============================================================================== -// Thread Safety Tests (if applicable) -//============================================================================== - -test "concurrent operations" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); - - const ThreadContext = struct { - h: *opaque {}, - id: u32, - }; - - const thread_fn = struct { - fn run(ctx: ThreadContext) void { - _ = {{project}}_process(ctx.h, ctx.id); - } - }.run; - - var threads: [4]std.Thread = undefined; - for (&threads, 0..) |*thread, i| { - thread.* = try std.Thread.spawn(.{}, thread_fn, .{ - ThreadContext{ .h = handle, .id = @intCast(i) }, - }); - } - - for (threads) |thread| { - thread.join(); - } -} diff --git a/aletheia/fuzz/Cargo.toml b/aletheia/fuzz/Cargo.toml deleted file mode 100644 index 8a474f0..0000000 --- a/aletheia/fuzz/Cargo.toml +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -[package] -name = "aletheia-fuzz" -version = "0.0.0" -authors = ["Jonathan D.A. Jewell "] -publish = false -edition = "2021" - -[package.metadata] -cargo-fuzz = true - -[dependencies] -libfuzzer-sys = "0.4" -arbitrary = { version = "1", features = ["derive"] } - -[dependencies.aletheia] -path = ".." - -[[bin]] -name = "fuzz_input" -path = "fuzz_targets/fuzz_input.rs" -test = false -doc = false -bench = false diff --git a/aletheia/fuzz/fuzz_targets/fuzz_input.rs b/aletheia/fuzz/fuzz_targets/fuzz_input.rs deleted file mode 100644 index 34dcbd9..0000000 --- a/aletheia/fuzz/fuzz_targets/fuzz_input.rs +++ /dev/null @@ -1,21 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Generic fuzz target for arbitrary input processing - -#![no_main] - -use libfuzzer_sys::fuzz_target; - -fuzz_target!(|data: &[u8]| { - // Fuzz with arbitrary byte input - // This exercises any parsing/processing functions with random data - if let Ok(input) = std::str::from_utf8(data) { - // Try to process the input as text - let _ = input.trim(); - let _ = input.lines().count(); - } - - // Exercise the data directly as bytes - let _ = data.len(); - let _ = data.is_empty(); -}); diff --git a/aletheia/manifest.scm b/aletheia/manifest.scm deleted file mode 100644 index dd942c7..0000000 --- a/aletheia/manifest.scm +++ /dev/null @@ -1,24 +0,0 @@ -;;; SPDX-License-Identifier: MPL-2.0 -;;; manifest.scm — Generic Guix manifest for RSR-compliant projects -;;; -;;; Usage: -;;; guix shell -m manifest.scm -;;; - -(specifications->manifest - '(;; Core development tools - "git" - "just" - "nickel" - "curl" - "bash" - "coreutils" - - ;; Documentation - "asciidoctor" - "pandoc" - - ;; Common build dependencies - "openssl" - "zlib" - "pkg-config")) diff --git a/aletheia/rust-toolchain.toml b/aletheia/rust-toolchain.toml deleted file mode 100644 index 32f1502..0000000 --- a/aletheia/rust-toolchain.toml +++ /dev/null @@ -1,6 +0,0 @@ -[toolchain] -# Specify the Rust toolchain version for consistency -channel = "stable" -components = ["rustfmt", "clippy", "rust-src"] -targets = ["x86_64-unknown-linux-gnu", "x86_64-unknown-linux-musl"] -profile = "minimal" diff --git a/aletheia/scripts/create-template.sh b/aletheia/scripts/create-template.sh deleted file mode 100755 index 5579558..0000000 --- a/aletheia/scripts/create-template.sh +++ /dev/null @@ -1,492 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) Jonathan D.A. Jewell -# -# create-template.sh — scaffold an RSR v2 project for a Tier-1 estate language. -# -# STANDALONE BY CONSTRUCTION: this generator reads only the template tree -# that ships beside it and writes only into the target directory. It makes -# no network calls, runs no package manager, and downloads nothing. A -# scaffolded project consequently passes `aletheia` Bronze AND Silver on -# day one with no hand edits, for every language it supports. -# -# Retired v1 shape this script no longer produces (see issue #186): -# LICENSE.txt / lowercase justfile / flake.nix / .gitlab-ci.yml / -# Python + flake8 / remote `curl` of licence texts. - -set -euo pipefail - -# Colours (suppressed when not a terminal, so CI logs stay clean) -if [ -t 1 ]; then - RED='\033[0;31m'; GREEN='\033[0;32m'; YELLOW='\033[1;33m' - BLUE='\033[0;34m'; NC='\033[0m' -else - RED=''; GREEN=''; YELLOW=''; BLUE=''; NC='' -fi - -log_info() { printf '%b\n' "${GREEN}[INFO]${NC} $1"; } -log_warn() { printf '%b\n' "${YELLOW}[WARN]${NC} $1"; } -log_error() { printf '%b\n' "${RED}[ERROR]${NC} $1" >&2; } -log_step() { printf '%b\n' "${BLUE}[STEP]${NC} $1"; } - -SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)" -ALETHEIA_DIR="$(dirname "$SCRIPT_DIR")" -TEMPLATE_ROOT="$ALETHEIA_DIR/templates" - -# --------------------------------------------------------------------------- -# Language table -# -# Every language shares templates/common/ (docs, licence texts, .well-known, -# the estate CI gates) and adds templates// on top. The values below -# are the only things that differ; keeping them here means the estate's -# language policy is stated once, not six times. -# -# Tier-1 languages per hyperpolymath/standards (RSR_OUTLINE: "Tier 1 (Gold): -# Rust(+SPARK), Elixir, Zig, Ada, Haskell, AffineScript, Agda"). -# --------------------------------------------------------------------------- -LANGS="rust zig elixir haskell ada agda" - -lang_display() { - case "$1" in - rust) echo "Rust/Creusot" ;; - zig) echo "Zig" ;; - elixir) echo "Elixir" ;; - haskell) echo "Haskell" ;; - ada) echo "Ada/SPARK" ;; - agda) echo "Agda" ;; - esac -} - -lang_policy() { - case "$1" in - rust) echo 'Rust here is always *Rust/Creusot*: Rust plus the Creusot deductive verifier. `just proof` translates `+src/impl.rs+` and discharges every obligation with Why3/Z3/CVC5, exiting non-zero on any unproved goal; the main crate stays zero-dependency because the specifications are gated behind `+cfg(creusot)+`.' ;; - zig) echo 'Zig is a Tier-1 estate language. The build is dependency-free: `zig build` compiles from this tree alone, and the Zig compiler ships its own libc, so there is nothing else to install.' ;; - elixir) echo 'Elixir is a Tier-1 estate language (BEAM/OTP). The project carries no Hex dependencies, so `mix compile` and `mix test` run with no network and nothing to fetch.' ;; - haskell) echo 'Haskell is a Tier-1 estate language. The package depends only on `base`, which ships with GHC, so `cabal build --offline` resolves with no package index and no network.' ;; - ada) echo 'Ada here is *Ada/SPARK*: the core package declares `+pragma SPARK_Mode (On);+` and its contracts are statically proved by `gnatprove` at proof level 2, not merely checked at run time. The project builds with GNAT and plain GPR projects — no Alire, no crate index, nothing to fetch.' ;; - agda) echo 'Agda is a Tier-1 estate language, and the estate formal-methods emphasis (Coq, Agda, SPARK) makes it a first-class target. Typechecking *is* the verification: these modules import only `Agda.Builtin`, so there is no stdlib to resolve and `agda` proves them offline.' ;; - esac -} - -lang_invariant() { - case "$1" in - rust) echo 'Rust here means Rust/Creusot — a specification that is not discharged by `just proof` is a bug, never a claim. The verified source is the shipped source: both crates `include!` `src/impl.rs`.' ;; - zig) echo 'Zig here means the Zig compiler toolchain: `zig fmt` and the built-in test runner are the gates, and no package manager sits in the build path.' ;; - elixir) echo 'Elixir here means the standard toolchain: `mix format` and ExUnit are the gates, and `deps` stays empty.' ;; - haskell) echo 'Haskell here means GHC/Cabal, with `-Wall -Werror` as the static-analysis gate rather than extra linters to install.' ;; - ada) echo 'Ada here means GNAT + GPR projects, with `-gnatwa -gnatwe` (all warnings, warnings as errors) as the build gate and `gnatprove --level=2 --checks-as-errors` as the proof gate. `--checks-as-errors` matters: without it gnatprove exits 0 on an unproved check.' ;; - agda) echo 'Agda here means machine-checked proofs, not tests with a proof-shaped comment: a proof that does not typecheck must fail the gate.' ;; - esac -} - -lang_dep_invariant() { - case "$1" in - rust) echo 'the crate depends only on `std`. Adding a dependency breaks the air-gapped guarantee and RSR Bronze.' ;; - zig) echo 'there is no package manager in the build path and no `build.zig.zon`. Adding a dependency means creating one with `zig fetch --save` — a deliberate decision, not a default.' ;; - elixir) echo '`mix.exs` declares `deps: []`. Adding a Hex dependency makes the build require the network.' ;; - haskell) echo 'the package depends only on `base`, which ships with GHC. Any further `build-depends` makes `--offline` fail.' ;; - ada) echo 'the GPR projects reference no external crates and do not use Alire, so nothing is fetched at build time.' ;; - agda) echo 'the modules import only `Agda.Builtin`. Adding a `depend:` line to the `.agda-lib` makes the check require that library to be installed.' ;; - esac -} - -lang_gitattr() { - case "$1" in - rust) echo '*.rs text eol=lf diff=rust' ;; - zig) echo '*.zig text eol=lf' ;; - elixir) echo '*.ex *.exs text eol=lf' ;; - haskell) echo '*.hs text eol=lf' ;; - ada) echo '*.adb *.ads text eol=lf' ;; - agda) echo '*.agda text eol=lf' ;; - esac -} - -# --------------------------------------------------------------------------- -# Defaults -# --------------------------------------------------------------------------- -PROJECT_NAME="" -LANGUAGE="rust" -DESCRIPTION="" -AUTHOR_NAME="Jonathan D.A. Jewell" -AUTHOR_EMAIL="j.d.a.jewell@open.ac.uk" -REPO_URL="" -SECURITY_CONTACT="" -CONDUCT_CONTACT="" -INIT_GIT=1 -FORCE=0 -RUN_VERIFY=0 - -usage() { - cat <<'EOF' -Usage: create-template.sh [options] - -Scaffold an RSR v2-compliant project for a Tier-1 estate language. The -generated tree passes `aletheia` Bronze AND Silver with no hand edits, and -needs no network: the scaffold embeds every licence text and downloads -nothing. - -Arguments: - project-name Name of the new project (required) - -Options: - -l, --lang Template language (default: rust) - --list-languages List supported languages and exit - -d, --description One-line project description - --author Copyright holder / maintainer name - --email Maintainer email - --repo-url Canonical repository URL - --security-contact Vulnerability disclosure contact - --conduct-contact Code-of-conduct contact - --no-git Do not initialise a git repository - --verify Run `aletheia` on the result (must be on PATH) - --force Write into a directory that already exists - -h, --help Show this message - -Supported languages (Tier-1 per hyperpolymath/standards): - rust Rust/Creusot — zero-dependency crate + Creusot proof crate - zig Zig 0.16 — build.zig, no package manager in the build path - elixir Elixir 1.18 / OTP 27 — mix, empty deps - haskell GHC 9.6 — cabal, `base` only - ada Ada — GNAT + plain GPR projects (no Alire) - agda Agda — machine-checked proofs, Agda.Builtin only - -Every template provides (v2 shape): - LICENSE + LICENSES/ MPL-2.0 (+ CC-BY-SA-4.0 for docs), full texts - Justfile capital J, real recipes, failing loudly - source + tests working code and a real test gate - .github/workflows/ CI, hypatia-scan, governance (actions.lock) - .machine_readable/ rsr-profile.a2ml capability declaration - .well-known/ security.txt, ai.txt, humans.txt - 0-AI-MANIFEST.a2ml agent front door - Documentation README.adoc, SECURITY, CONTRIBUTING, CoC, - CHANGELOG, MAINTAINERS - -Every template deliberately does NOT provide (retired v1 shape): - LICENSE.txt, lowercase justfile, flake.nix, .gitlab-ci.yml, - Makefile/Dockerfile, remote licence downloads - -NOT SUPPORTED, deliberately: - AffineScript — the estate successor to ReScript (`.res` -> `.affine`). - It has no verifiable toolchain yet, so a scaffold could not pass its own - `just check`; shipping one would be exactly the fake gate this estate - bans. Add it here once its compiler is installable and pinned. - -Examples: - create-template.sh my-service - create-template.sh my-service -l zig -d "A small service" --verify - create-template.sh my-service --no-git --repo-url https://codeberg.org/me/my-service -EOF - exit "${1:-1}" -} - -list_languages() { - printf 'Supported languages:\n\n' - for l in $LANGS; do - printf ' %-8s %s\n' "$l" "$(lang_display "$l")" - done - printf '\nUnsupported, deliberately: affinescript (no verifiable toolchain yet)\n' -} - -# --------------------------------------------------------------------------- -# Argument parsing -# --------------------------------------------------------------------------- -parse_args() { - while [ $# -gt 0 ]; do - case "$1" in - -h|--help|help) usage 0 ;; - --list-languages|languages) list_languages; exit 0 ;; - -l|--lang|--language) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - LANGUAGE="$2"; shift 2 ;; - -d|--description) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - DESCRIPTION="$2"; shift 2 ;; - --author) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - AUTHOR_NAME="$2"; shift 2 ;; - --email) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - AUTHOR_EMAIL="$2"; shift 2 ;; - --repo-url) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - REPO_URL="$2"; shift 2 ;; - --security-contact) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - SECURITY_CONTACT="$2"; shift 2 ;; - --conduct-contact) - [ $# -ge 2 ] || { log_error "$1 requires a value"; exit 2; } - CONDUCT_CONTACT="$2"; shift 2 ;; - --no-git) INIT_GIT=0; shift ;; - --verify) RUN_VERIFY=1; shift ;; - --force) FORCE=1; shift ;; - -*) log_error "unknown option: $1"; usage 2 ;; - *) - if [ -z "$PROJECT_NAME" ]; then - PROJECT_NAME="$1" - else - log_error "unexpected extra argument: $1"; usage 2 - fi - shift ;; - esac - done - - [ -n "$PROJECT_NAME" ] || { log_error "project name is required"; usage 2; } -} - -# --------------------------------------------------------------------------- -# Validation -# --------------------------------------------------------------------------- -lang_supported() { - for l in $LANGS; do [ "$l" = "$1" ] && return 0; done - return 1 -} - -validate() { - case "$PROJECT_NAME" in - *[!a-zA-Z0-9._-]*|"") - log_error "invalid project name: '$PROJECT_NAME'" - log_error "use letters, digits, dot, underscore or hyphen" - exit 2 ;; - -*) - log_error "project name may not start with a hyphen: '$PROJECT_NAME'" - exit 2 ;; - esac - - # Identifiers derived from the name must be valid for the target language: - # a leading digit is not, so reject it here rather than emit code that - # cannot compile. - case "$PROJECT_NAME" in - [0-9]*) log_error "project name may not start with a digit: '$PROJECT_NAME'"; exit 2 ;; - esac - - if ! lang_supported "$LANGUAGE"; then - log_error "unsupported language: '$LANGUAGE'" - case "$LANGUAGE" in - python|py|typescript|ts|go|golang|rescript|res) - log_error "Note: .py/.ts/.go/.res sources are BANNED by the v2" - log_error "estate language policy, so this template never passed" - log_error "Bronze. That v1 path was removed, not ported." ;; - affinescript|affine) - log_error "Note: AffineScript is the estate's intended successor," - log_error "but it has no verifiable toolchain yet, so a scaffold" - log_error "could not pass its own 'just check'." ;; - esac - printf '\n' - list_languages - exit 2 - fi - - if [ -e "$PROJECT_NAME" ] && [ "$FORCE" -ne 1 ]; then - log_error "directory '$PROJECT_NAME' already exists (use --force to reuse)" - exit 1 - fi - - for dir in "$TEMPLATE_ROOT/common" "$TEMPLATE_ROOT/$LANGUAGE"; do - if [ ! -d "$dir" ]; then - log_error "template not found: $dir" - log_error "is this script running from an intact aletheia checkout?" - exit 1 - fi - done -} - -# --------------------------------------------------------------------------- -# Rendering -# --------------------------------------------------------------------------- -# Escape the characters sed treats specially on the right-hand side, so -# values containing '&', '|' or '\' cannot corrupt the output. -sed_escape() { printf '%s' "$1" | sed -e 's/[\\&|]/\\&/g'; } - -# Substitute every placeholder in stdin -> stdout. -subst() { - sed \ - -e "s|@@PROJECT_NAME@@|$E_PROJECT_NAME|g" \ - -e "s|@@MOD_NAME@@|$E_MOD_NAME|g" \ - -e "s|@@CRATE_NAME@@|$E_MOD_NAME|g" \ - -e "s|@@MOD_CAMEL@@|$E_MOD_CAMEL|g" \ - -e "s|@@MOD_ADA@@|$E_MOD_ADA|g" \ - -e "s|@@VERSION@@|0.1.0|g" \ - -e "s|@@PROJECT_DESCRIPTION@@|$E_DESCRIPTION|g" \ - -e "s|@@REPO_URL@@|$E_REPO_URL|g" \ - -e "s|@@AUTHOR_NAME@@|$E_AUTHOR_NAME|g" \ - -e "s|@@AUTHOR_EMAIL@@|$E_AUTHOR_EMAIL|g" \ - -e "s|@@SECURITY_CONTACT@@|$E_SECURITY_CONTACT|g" \ - -e "s|@@CONDUCT_CONTACT@@|$E_CONDUCT_CONTACT|g" \ - -e "s|@@DATE@@|$E_DATE|g" \ - -e "s|@@SECURITY_EXPIRES@@|$E_SECURITY_EXPIRES|g" \ - -e "s|@@LANG_DISPLAY@@|$E_LANG_DISPLAY|g" \ - -e "s|@@LANG_POLICY@@|$E_LANG_POLICY|g" \ - -e "s|@@LANG_INVARIANT@@|$E_LANG_INVARIANT|g" \ - -e "s|@@DEP_INVARIANT@@|$E_DEP_INVARIANT|g" \ - -e "s|@@STANDALONE_INVARIANT@@|$E_STANDALONE|g" \ - -e "s|@@LANG_GITATTR_LINE@@|$E_LANG_GITATTR|g" -} - -# Copy one template layer into the target, then render every file. Called -# once for templates/common and once for templates/; the language -# layer is copied second so it wins where both define a path. -copy_layer() { - local layer="$1" target="$2" - local src rel - while IFS= read -r src; do - rel="${src#"$layer"/}" - # Recreate the directory skeleton (mkdir -p handles nesting). - mkdir -p "$target/$(dirname "$rel")" - cp "$src" "$target/$rel" - # Preserve the executable bit. Written as an `if`, not - # `[ -x ] && chmod`, because under `set -e` a failing test as the - # last command of a loop body would abort the whole render. - if [ -x "$src" ]; then - chmod +x "$target/$rel" - fi - done < <(find "$layer" -type f) -} - -render_tree() { - local target="$1" - - # File contents. - local f - while IFS= read -r f; do - subst < "$f" > "$f.tmp" - mv "$f.tmp" "$f" - done < <(find "$target" -type f) - - # Path names, deepest first, so renamed directories stay consistent. - local p new - while IFS= read -r p; do - new="$(printf '%s' "$p" | subst)" - if [ "$p" != "$new" ]; then - mv "$p" "$new" - fi - done < <(find "$target" -depth -name '*@@*') -} - -finish() { - local target="$1" - - if [ "$INIT_GIT" -eq 1 ]; then - log_step "Initialising git repository..." - ( cd "$target" - git init -q 2>/dev/null || true - # Only set local identity when the user has none, so the initial - # commit cannot fail on a fresh machine. - git config user.email >/dev/null 2>&1 || git config user.email "$AUTHOR_EMAIL" - git config user.name >/dev/null 2>&1 || git config user.name "$AUTHOR_NAME" - git add -A - git commit -q -m "chore: initial commit from aletheia v2 Bronze template" \ - || log_warn "initial commit skipped" - ) - log_info "Git repository initialised" - fi - - if [ "$RUN_VERIFY" -eq 1 ]; then - log_step "Verifying RSR compliance..." - if command -v aletheia >/dev/null 2>&1; then - if aletheia "$target"; then - log_info "Compliance check passed" - else - log_warn "Compliance check reported failures (see output above)" - fi - else - log_warn "aletheia not on PATH — skipping verification" - log_warn "build it with: just build (from the maa-framework root)" - fi - fi -} - -main() { - parse_args "$@" - validate - - # Derived values - MOD_NAME="$(printf '%s' "$PROJECT_NAME" | tr '[:upper:]' '[:lower:]' | tr '-' '_')" - MOD_CAMEL="$(printf '%s' "$PROJECT_NAME" | sed -E 's/[^a-zA-Z0-9]+/ /g' \ - | awk '{ for (i = 1; i <= NF; i++) printf toupper(substr($i,1,1)) substr($i,2) }')" - # Ada unit names are underscore-joined capitalised segments. Deriving this - # from MOD_CAMEL by inserting underscores at case boundaries is wrong for - # single-letter segments ("g-ada" would give "GAda", not "G_Ada"), which - # then makes GNAT look for gada.ads while the template ships g_ada.ads. - MOD_ADA="$(printf '%s' "$PROJECT_NAME" | sed -E 's/[^a-zA-Z0-9]+/ /g' \ - | awk '{ for (i = 1; i <= NF; i++) printf "%s%s", (i > 1 ? "_" : ""), toupper(substr($i,1,1)) substr($i,2) }')" - - if [ -z "$DESCRIPTION" ]; then - DESCRIPTION="An RSR v2-compliant $(lang_display "$LANGUAGE") project." - fi - if [ -z "$REPO_URL" ]; then - REPO_URL="https://github.com/hyperpolymath/$PROJECT_NAME" - fi - if [ -z "$SECURITY_CONTACT" ]; then - SECURITY_CONTACT="$AUTHOR_EMAIL" - fi - if [ -z "$CONDUCT_CONTACT" ]; then - CONDUCT_CONTACT="$AUTHOR_EMAIL" - fi - DATE="$(date -u +%Y-%m-%d)" - SECURITY_EXPIRES="$(date -u -d '+1 year' +%Y-%m-%dT%H:%M:%S.000Z 2>/dev/null \ - || date -u -v+1y +%Y-%m-%dT%H:%M:%S.000Z)" - - E_PROJECT_NAME="$(sed_escape "$PROJECT_NAME")" - E_MOD_NAME="$(sed_escape "$MOD_NAME")" - E_MOD_CAMEL="$(sed_escape "$MOD_CAMEL")" - E_MOD_ADA="$(sed_escape "$MOD_ADA")" - E_DESCRIPTION="$(sed_escape "$DESCRIPTION")" - E_REPO_URL="$(sed_escape "$REPO_URL")" - E_AUTHOR_NAME="$(sed_escape "$AUTHOR_NAME")" - E_AUTHOR_EMAIL="$(sed_escape "$AUTHOR_EMAIL")" - E_SECURITY_CONTACT="$(sed_escape "$SECURITY_CONTACT")" - E_CONDUCT_CONTACT="$(sed_escape "$CONDUCT_CONTACT")" - E_DATE="$(sed_escape "$DATE")" - E_SECURITY_EXPIRES="$(sed_escape "$SECURITY_EXPIRES")" - E_LANG_DISPLAY="$(sed_escape "$(lang_display "$LANGUAGE")")" - E_LANG_POLICY="$(sed_escape "$(lang_policy "$LANGUAGE")")" - E_LANG_INVARIANT="$(sed_escape "$(lang_invariant "$LANGUAGE")")" - E_DEP_INVARIANT="$(sed_escape "$(lang_dep_invariant "$LANGUAGE")")" - E_STANDALONE="$(sed_escape 'the build fetches nothing. Do not add network calls to the build, test, or scaffolding path.')" - E_LANG_GITATTR="$(sed_escape "$(lang_gitattr "$LANGUAGE")")" - - log_info "Creating RSR v2 project: $PROJECT_NAME ($LANGUAGE — $(lang_display "$LANGUAGE"))" - log_info "Template: v2 Bronze (standalone — no downloads)" - printf '\n' - - if [ -e "$PROJECT_NAME" ]; then - rm -rf "$PROJECT_NAME" - fi - mkdir -p "$PROJECT_NAME" - - log_step "Rendering template tree..." - copy_layer "$TEMPLATE_ROOT/common" "$PROJECT_NAME" - copy_layer "$TEMPLATE_ROOT/$LANGUAGE" "$PROJECT_NAME" - render_tree "$PROJECT_NAME" - - # A leftover placeholder means a template file references a token the - # generator does not know about. Fail loudly rather than ship it. - if grep -rl '@@' "$PROJECT_NAME" >/dev/null 2>&1; then - log_error "unresolved template placeholder(s) in:" - grep -rl '@@' "$PROJECT_NAME" | sed 's/^/ /' >&2 - log_error "the generator and the template tree are out of sync" - exit 1 - fi - log_info "Rendered $(find "$PROJECT_NAME" -type f | wc -l | tr -d ' ') files" - - finish "$PROJECT_NAME" - - printf '\n' - log_info "Project created: $PROJECT_NAME" - printf '\n' - echo "Next steps:" - echo " cd $PROJECT_NAME" - echo " just check # build, test, lint (offline)" - echo " just verify # RSR compliance with aletheia" - echo "" - echo "Language: $(lang_display "$LANGUAGE") — see README.adoc for the" - echo "toolchain and the offline guarantees." - echo "" - echo "Before publishing, review:" - echo " .well-known/security.txt disclosure contact and expiry" - echo " .machine_readable/rsr-profile.a2ml declared capabilities" - echo " MAINTAINERS.adoc ownership" - echo "" -} - -main "$@" diff --git a/aletheia/scripts/install.sh b/aletheia/scripts/install.sh deleted file mode 100755 index 129b232..0000000 --- a/aletheia/scripts/install.sh +++ /dev/null @@ -1,135 +0,0 @@ -#!/usr/bin/env bash -# SPDX-License-Identifier: MPL-2.0 -# Aletheia installation script -# This script installs Aletheia on Unix-like systems - -set -euo pipefail - -# Colors for output -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -# Configuration -REPO_URL="https://github.com/hyperpolymath/maa-framework.git" -INSTALL_DIR="${HOME}/.local/bin" -TEMP_DIR=$(mktemp -d) - -# Functions -log_info() { - echo -e "${GREEN}[INFO]${NC} $1" -} - -log_warn() { - echo -e "${YELLOW}[WARN]${NC} $1" -} - -log_error() { - echo -e "${RED}[ERROR]${NC} $1" -} - -check_dependencies() { - log_info "Checking dependencies..." - - if ! command -v git &> /dev/null; then - log_error "git is not installed. Please install git first." - exit 1 - fi - - if ! command -v cargo &> /dev/null; then - log_error "cargo is not installed. Please install Rust first." - log_info "Visit: https://rustup.rs/" - exit 1 - fi - - log_info "All dependencies satisfied." -} - -clone_repository() { - log_info "Cloning Aletheia repository..." - cd "$TEMP_DIR" - git clone "$REPO_URL" maa-framework - cd maa-framework/aletheia -} - -build_binary() { - log_info "Building Aletheia (release mode)..." - cargo build --release - - if [ ! -f "target/release/aletheia" ]; then - log_error "Build failed - binary not found" - exit 1 - fi - - log_info "Build successful." -} - -install_binary() { - log_info "Installing binary to ${INSTALL_DIR}..." - - # Create install directory if it doesn't exist - mkdir -p "$INSTALL_DIR" - - # Copy binary - cp target/release/aletheia "$INSTALL_DIR/" - chmod +x "$INSTALL_DIR/aletheia" - - log_info "Binary installed to ${INSTALL_DIR}/aletheia" -} - -check_path() { - if ! echo "$PATH" | grep -q "$INSTALL_DIR"; then - log_warn "${INSTALL_DIR} is not in your PATH." - log_warn "Add this to your shell profile:" - echo "" - echo " export PATH=\"\$PATH:${INSTALL_DIR}\"" - echo "" - else - log_info "${INSTALL_DIR} is in your PATH." - fi -} - -cleanup() { - log_info "Cleaning up temporary files..." - rm -rf "$TEMP_DIR" -} - -verify_installation() { - log_info "Verifying installation..." - - if command -v aletheia &> /dev/null; then - log_info "Installation verified successfully!" - log_info "Run 'aletheia' to verify a repository." - else - log_warn "Binary installed but not in PATH." - log_warn "You can run it directly: ${INSTALL_DIR}/aletheia" - fi -} - -main() { - echo "Aletheia Installation Script" - echo "============================" - echo "" - - check_dependencies - clone_repository - build_binary - install_binary - cleanup - check_path - verify_installation - - echo "" - log_info "Installation complete!" - echo "" - echo "Next steps:" - echo " 1. Run 'aletheia' in any repository to verify RSR compliance" - echo " 2. Run 'aletheia /path/to/repo' to verify a specific repository" - echo " 3. Read the documentation at:" - echo " https://github.com/hyperpolymath/maa-framework/tree/main/aletheia" - echo "" -} - -# Run main function -main diff --git a/aletheia/src/checks.rs b/aletheia/src/checks.rs deleted file mode 100644 index 69f0925..0000000 --- a/aletheia/src/checks.rs +++ /dev/null @@ -1,2105 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! RSR Compliance Verification Kernel. -//! -//! This module implements the deterministic checks used by Aletheia to -//! audit repository state. It performs physical filesystem analysis to -//! validate documentation, build system files, and security configurations. -//! -//! SOURCE OF TRUTH: every check below cites the upstream RSR criterion -//! it evaluates (see [`SSOT_PROVENANCE`]). Aletheia covers the *offline -//! file-presence subset* — criteria whose verdict can be computed from -//! the working tree with zero dependencies. Everything else (Scorecard, -//! secret-scanner depth, content carve-outs, containers, proofs, …) is -//! explicitly out of scope and deferred to the hypatia oracle; see -//! [`LOCAL_SUBSET_NOTE`]. Aletheia is non-normative by design. - -use std::cell::{Cell, OnceCell}; -use std::fs; -use std::path::{Path, PathBuf}; - -use crate::config::{Config, GitIgnore, IgnoreConfig}; -use crate::types::*; - -/// Provenance of the check inventory: the upstream single source of -/// truth this file is aligned to. When the criteria rev, update this -/// block and the inventory together — never one without the other. -pub const SSOT_PROVENANCE: &str = "RSR criteria v2.1.0-draft (2026-09-19), \ - hyperpolymath/standards 0-canon/rsr/rsr-criteria-v2.a2ml \ - (sha256 6a5aa885…1694d82a); normative oracle hypatia:rsr-conformance"; - -/// Honest scope statement, printed in verbose output so nobody mistakes -/// the local subset for the normative tier. -pub const LOCAL_SUBSET_NOTE: &str = "Local subset: offline file-presence checks only. \ - Scorecard, SBOM, containers, Guix, git hooks, signed commits, formal proofs, \ - dependency audit and content carve-outs (https-only, weak hashes, deep secret \ - scanning) are evaluated by the hypatia rsr-conformance oracle, not here."; - -/// Bound on files examined per walk. Repos beyond this get a `warning` -/// (results partial) rather than a silent pass. -const MAX_SCAN_FILES: usize = 50_000; -/// Maximum recursion depth for filesystem walks. -const MAX_SCAN_DEPTH: u32 = 16; -/// Maximum depth for the symlink security sweep. Kept equal to -/// `MAX_SCAN_DEPTH` so the sweep covers every directory the file walk -/// reaches. -const MAX_SYMLINK_DEPTH: u32 = MAX_SCAN_DEPTH; -/// Maximum entries examined by the symlink security sweep. -const MAX_SYMLINK_ENTRIES: usize = 20_000; -/// Content reads are capped at 64 KiB per file. -const MAX_CONTENT_BYTES: u64 = 64 * 1024; -/// SPDX detection reads the first 8 KiB (headers live in lines 1–10). -const SPDX_HEAD_BYTES: u64 = 8 * 1024; - -/// Directory names never descended into (build outputs, caches, VCS). -const SKIP_DIR_NAMES: &[&str] = &[ - ".git", - "target", - "node_modules", - "_build", - ".zig-cache", - "zig-out", - "zig-cache", - "deps", - "vendor", - "dist", - "build", - "out", - ".cache", - ".venv", - "__pycache__", - ".hypatia", - ".idea", - ".vscode", - ".tox", - ".nox", - "coverage", - ".dart_tool", - ".gradle", - "DerivedData", - "Pods", -]; - -/// Source-code extensions examined for SPDX headers. -const SPDX_EXTENSIONS: &[&str] = &[ - "rs", "sh", "bash", "zsh", "ksh", "py", "pyi", "js", "mjs", "cjs", "jsx", "ts", "mts", "cts", - "tsx", "ex", "exs", "erl", "hrl", "gleam", "res", "resi", "go", "java", "kt", "kts", "swift", - "c", "h", "cc", "hh", "cpp", "hpp", "cxx", "hxx", "cs", "fs", "fsi", "hs", "lhs", "ml", "mli", - "idr", "adb", "ads", "pl", "pm", "rb", "php", "lua", "r", "jl", "scala", "zig", "zon", "nix", - "scm", "rkt", "v", "el", "ps1", -]; - -/// Config extensions additionally scanned for committed secrets. -/// Documentation formats (md/adoc/txt) are deliberately excluded: they -/// routinely show redacted key *examples*, which a naive scan would flag. -const SECRET_SCAN_EXTENSIONS: &[&str] = &[ - "rs", "sh", "bash", "zsh", "toml", "yaml", "yml", "json", "env", "ini", "cfg", "conf", "py", - "js", "ts", "go", "java", "kt", "ex", "exs", "c", "h", "cpp", "zig", "nix", "pem", "key", - "p12", "pfx", "keystore", "jks", -]; - -/// Filenames that must never be committed (v2 4.1.2, file half). -const SECRET_FILENAMES: &[&str] = &[".env", ".env.local", "credentials.json"]; - -/// Fragment pairs concatenating into the committed-secret markers -/// (v2 4.1.2, content half): private-key block headers and unmistakable -/// token prefixes. Deliberately narrow — anything fuzzier belongs to the -/// oracle's secret scanner. -/// -/// WHY FRAGMENTS: if a full marker appeared here as one literal, this -/// scanner would flag its own source file — the definition would contain -/// the pattern it detects (self-hosting paradox). Each half is innocuous -/// alone; only their concatenation is ever matched, and that full string -/// appears nowhere in this crate. Keep it that way: never write a whole -/// marker in any scanned source file, including comments and tests (build -/// test fixtures from halves too). -const SECRET_MARKER_FRAGMENTS: &[(&str, &str)] = &[ - ("-----BEGIN RSA ", "PRIVATE KEY-----"), - ("-----BEGIN OPENSSH ", "PRIVATE KEY-----"), - ("-----BEGIN EC ", "PRIVATE KEY-----"), - ("-----BEGIN DSA ", "PRIVATE KEY-----"), - ("-----BEGIN ENCRYPTED ", "PRIVATE KEY-----"), - ("-----BEGIN ", "PRIVATE KEY-----"), - ("aws_secret_access", "_key"), - ("AK", "IA"), - ("xo", "xb-"), - ("xo", "xp-"), - ("gh", "p_"), - ("github_pa", "t_"), -]; - -/// Assemble the full matchable markers from their fragments. -fn secret_markers() -> Vec { - SECRET_MARKER_FRAGMENTS - .iter() - .map(|(head, tail)| format!("{head}{tail}")) - .collect() -} - -/// Banned build-system files (v2 1.1.3 + the Mustfile contractile, -/// which additionally bans Dockerfiles). -const BANNED_BUILD_FILES: &[&str] = &[ - "Makefile", - "makefile", - "GNUmakefile", - "Dockerfile", - "dockerfile", -]; - -/// Estate-banned language extensions (v2 5.1.1–5.1.5). `.v` is -/// content-sniffed (Coq vs V-lang) rather than blanket-banned — see -/// [`v_file_is_suspect`]. -const BANNED_LANGUAGE_EXTENSIONS: &[&str] = &[ - "py", "pyi", "ts", "tsx", "mts", "cts", "res", "resi", "go", "v", -]; - -/// Markers identifying Coq sources (which share `.v` with V-lang). -const COQ_MARKERS: &[&str] = &[ - "Definition ", - "Lemma ", - "Theorem ", - "Axiom ", - "Require ", - "Inductive ", - "Fixpoint ", - "Proposition ", - "Corollary ", - "Record ", - "Class ", - "Instance ", - "Scheme ", - "Ltac ", - "Proof.", - "Qed.", - "Admitted.", - "Section ", - "Variable ", - "Notation ", -]; - -/// Markers identifying V-lang sources. -const V_MARKERS: &[&str] = &["fn main", "\nfn ", "module main"]; - -/// Recognised licence-identifier anchors for the structural 7.1.1 check. -/// Real classification is the oracle's job (`cicd_rules/license_finding`); -/// this only asserts the LICENSE file names *something* known. Both SPDX -/// ids and spelled-out names are accepted: real LICENSE files often carry -/// only the full name (e.g. "Mozilla Public License Version 2.0" with no -/// "MPL-2.0" string anywhere). -const KNOWN_LICENSE_IDS: &[&str] = &[ - "Mozilla Public License", - "MPL-2.0", - "MIT License", - "Permission is hereby granted", - "Apache License", - "Apache-2.0", - "General Public License", - "Lesser General Public License", - "Affero General Public License", - "GPL-", - "LGPL-", - "AGPL-", - "Palimpsest", - "PMPL-1.0", - "Creative Commons", - "CC-BY-SA", - "CC0", - "BSD-2-Clause", - "BSD-3-Clause", - "Redistribution and use", - "ISC License", - "Unlicense", - "European Union Public Licence", - "EUPL-", - "Blue Oak", - "BlueOak", - "0BSD", - "zlib/libpng", -]; - -/// Outcome of one check: pass/fail plus an optional remediation hint. -/// `ignored` marks "missing but covered by an `[ignore]` pattern", which -/// passes and is labelled `(ignored)` in reports. -struct Outcome { - passed: bool, - suggestion: Option, - ignored: bool, -} - -impl Outcome { - fn pass() -> Self { - Outcome { - passed: true, - suggestion: None, - ignored: false, - } - } - - fn pass_ignored() -> Self { - Outcome { - passed: true, - suggestion: None, - ignored: true, - } - } - - fn fail(suggestion: String) -> Self { - Outcome { - passed: false, - suggestion: Some(suggestion), - ignored: false, - } - } -} - -/// Presence of a file looked up under several candidate paths. -enum Presence { - Found, - MissingIgnored, - Missing, -} - -/// ALGORITHM: Implements a glob pattern matcher for path filtering. -/// Supports `*` (zero or more chars, crossing `/`) and `?` (exactly one -/// char). Used for `[ignore]` patterns against repo-relative paths. -pub fn glob_match(pattern: &str, text: &str) -> bool { - let pat: Vec = pattern.chars().collect(); - let txt: Vec = text.chars().collect(); - glob_match_recursive(&pat, &txt, 0, 0) -} - -/// SECURITY: Validates that a path does not contain malicious symlinks. -/// Specifically checks if a symlink "escapes" the repository root, which -/// is a critical safety invariant for air-gapped or verified builds. -pub fn check_path_security(path: &Path, repo_root: &Path) -> PathCheckResult { - let metadata = match fs::symlink_metadata(path) { - Ok(m) => m, - Err(_) => return PathCheckResult::default(), - }; - - if !metadata.file_type().is_symlink() { - return PathCheckResult { - exists: true, - ..Default::default() - }; - } - - // RESOLUTION: Determine the absolute target of the symlink. - let target = match fs::read_link(path) { - Ok(t) => t, - Err(_) => { - return PathCheckResult { - exists: true, - is_symlink: true, - ..Default::default() - } - }, - }; - - // ESCAPE DETECTION: Canonicalize and verify prefix. - let canonical_root = repo_root.canonicalize().unwrap_or(repo_root.to_path_buf()); - let joined = if target.is_absolute() { - target - } else { - match path.parent() { - Some(parent) => parent.join(target), - None => { - return PathCheckResult { - exists: true, - is_symlink: true, - ..Default::default() - } - }, - } - }; - // A dangling link cannot canonicalize; judge the joined path as-is. - // Best-effort by construction — documented, not silent. - let canonical_target = joined.canonicalize().unwrap_or(joined); - - PathCheckResult { - exists: true, - is_symlink: true, - escapes_repo: !canonical_target.starts_with(&canonical_root), - target: Some(canonical_target), - } -} - -/// Helper: Check if a file exists at repo_path/filename. -fn file_exists(repo_path: &Path, filename: &str) -> bool { - repo_path.join(filename).is_file() -} - -/// Parse `.gitmodules` content into submodule paths. Submodule contents -/// belong to their upstream repo; scanning them here would attribute -/// foreign failures to this repository. -fn parse_gitmodules_content(content: &str) -> Vec { - content - .lines() - .filter_map(|line| { - let trimmed = line.trim(); - let rest = trimmed.strip_prefix("path")?.trim(); - let value = rest.strip_prefix('=')?.trim(); - if value.is_empty() { - None - } else { - Some(value.to_string()) - } - }) - .collect() -} - -/// Read submodule paths from `.gitmodules` (absent file: no submodules). -fn submodule_paths(repo_path: &Path) -> Vec { - let path = repo_path.join(".gitmodules"); - match fs::read_to_string(&path) { - Ok(content) => parse_gitmodules_content(&content), - Err(_) => Vec::new(), - } -} - -/// Bounded file read: the first `max_bytes` bytes, lossy-decoded. -/// Returns `None` on I/O error so callers treat unreadable files as -/// "cannot verify" rather than crashing the scan. -fn read_head(path: &Path, max_bytes: u64) -> Option { - use std::io::Read; - let file = fs::File::open(path).ok()?; - let mut content = String::new(); - file.take(max_bytes).read_to_string(&mut content).ok()?; - Some(content) -} - -/// One traversal's results, bucketed by the extension filters the checks -/// need (issue #197). -/// -/// WHY BUCKETS: each check used to run its own `walk_files`, so a single -/// `verify` performed seven full directory traversals. All seven walked the -/// same tree in the same order and differed only in which files they -/// collected, so a single traversal can fill every bucket at once. The -/// saving is in the traversal itself — `read_dir` plus `file_type` per -/// entry — not in the cheap extension filter applied afterwards. -/// -/// BUDGET SEMANTICS ARE UNCHANGED. A bucket accepts at most -/// `MAX_SCAN_FILES` *matches of its own*, exactly as -/// `walk_files(Some(exts))` counted only files passing its filter rather -/// than every file seen. When a bucket is full it stops growing, and the -/// traversal continues so the remaining buckets still receive their own -/// first `MAX_SCAN_FILES` matches — which is what the separate walks gave -/// them. -#[derive(Default)] -struct ScanSet { - /// Every file (checks with no extension filter). - all: Vec, - /// `SPDX_EXTENSIONS` matches. - spdx: Vec, - /// `SECRET_SCAN_EXTENSIONS` matches. - secret: Vec, - /// `BANNED_LANGUAGE_EXTENSIONS` matches. - banned: Vec, - /// Set once a file was refused because its bucket was full — i.e. the - /// results really are partial. Drives the truncation warning. - capped: bool, - /// `.gitignore` rules covering the directories walked so far. Maintained - /// as a stack: rules are pushed when the walk enters a directory and - /// truncated on the way out, so a nested file only governs its own - /// subtree. Filled during the single traversal, which is why this lives - /// here rather than in a second pass over the tree (issue #197). - ignores: GitIgnore, -} - -impl ScanSet { - /// Offer one file to every bucket whose filter accepts it. - /// - /// Extensionless files (empty `ext`) land only in `all`, matching the - /// old filtered walks, which skipped them. - fn offer(&mut self, path: &Path, ext: &str) { - Self::push(&mut self.all, path, &mut self.capped); - if SPDX_EXTENSIONS.contains(&ext) { - Self::push(&mut self.spdx, path, &mut self.capped); - } - if SECRET_SCAN_EXTENSIONS.contains(&ext) { - Self::push(&mut self.secret, path, &mut self.capped); - } - if BANNED_LANGUAGE_EXTENSIONS.contains(&ext) { - Self::push(&mut self.banned, path, &mut self.capped); - } - } - - /// Push into one bucket unless it has reached its per-check budget. - fn push(bucket: &mut Vec, path: &Path, capped: &mut bool) { - if bucket.len() < MAX_SCAN_FILES { - bucket.push(path.to_path_buf()); - } else { - *capped = true; - } - } -} - -/// Filesystem scanner: bounded recursive walks honouring skip dirs, -/// submodule boundaries and `[ignore]` globs. Never follows symlinks. -struct Scanner<'a> { - root: &'a Path, - ignore: &'a IgnoreConfig, - submodules: &'a [String], - truncated: Cell, - /// Memoised single-traversal file buckets (issue #197). Filled on first - /// use; every check then reads from it instead of re-walking the tree. - files: OnceCell, -} - -impl<'a> Scanner<'a> { - /// Repo-relative path with `/` separators ("" for the root itself). - fn rel(&self, path: &Path) -> String { - path.strip_prefix(self.root) - .map(|p| p.to_string_lossy().replace('\\', "/")) - .unwrap_or_default() - } - - fn under_submodule(&self, rel: &str) -> bool { - self.submodules - .iter() - .any(|s| rel == s || (rel.starts_with(s) && rel.as_bytes().get(s.len()) == Some(&b'/'))) - } - - fn skipped(&self, rel: &str) -> bool { - rel.is_empty() || self.under_submodule(rel) || self.ignore.is_ignored(rel) - } - - /// Recursive walk filling every bucket in one pass. Depth, skip-dir, - /// submodule and ignore rules are identical to the former per-check - /// walks, so each bucket receives exactly the files its own walk saw. - fn walk_into_set(&self, dir: &Path, depth: u32, set: &mut ScanSet) { - if depth > MAX_SCAN_DEPTH { - return; - } - let entries = match fs::read_dir(dir) { - Ok(entries) => entries, - Err(_) => return, - }; - // Rules from this directory's `.gitignore` apply to everything at or - // below it, so load them before visiting any entry. Popping on the way - // out keeps a nested file scoped to its own subtree. - let mark = set.ignores.len(); - if let Ok(text) = fs::read_to_string(dir.join(".gitignore")) { - let base = self.rel(dir); - set.ignores.push_file(&base, &text); - } - for entry in entries.flatten() { - let path = entry.path(); - let rel = self.rel(&path); - if self.skipped(&rel) { - continue; - } - let file_type = match entry.file_type() { - Ok(t) => t, - Err(_) => continue, - }; - // Never follow symlinks; the security sweep covers them. - if file_type.is_symlink() { - continue; - } - // Ask the type-aware question: a directory-only rule such as - // `obj/` must match the directory `obj` but not a file of the - // same name. - let ignored = if file_type.is_dir() { - set.ignores.is_ignored_dir(&rel) - } else { - set.ignores.is_ignored(&rel) - }; - if ignored { - continue; - } - if file_type.is_dir() { - let skip = path - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| SKIP_DIR_NAMES.contains(&name)); - if !skip { - self.walk_into_set(&path, depth + 1, set); - } - } else if file_type.is_file() { - let ext = path - .extension() - .and_then(|e| e.to_str()) - .unwrap_or_default() - .to_ascii_lowercase(); - set.offer(&path, &ext); - } - } - set.ignores.truncate(mark); - } - - /// The repository's files, bucketed. Computed once per `Scanner`, so - /// the seven checks that need file lists share one traversal. - fn files(&self) -> &ScanSet { - self.files.get_or_init(|| { - let mut set = ScanSet::default(); - self.walk_into_set(self.root, 0, &mut set); - if set.capped { - self.truncated.set(true); - } - set - }) - } - - /// Every file (checks with no extension filter). - fn all_files(&self) -> &[PathBuf] { - &self.files().all - } - - /// Files with an extension scanned for SPDX headers. - fn spdx_files(&self) -> &[PathBuf] { - &self.files().spdx - } - - /// Files with an extension additionally scanned for secrets. - fn secret_files(&self) -> &[PathBuf] { - &self.files().secret - } - - /// Files with an estate-banned language extension. - fn banned_files(&self) -> &[PathBuf] { - &self.files().banned - } - - /// Look up a file under several candidate relative paths. - fn presence(&self, candidates: &[&str]) -> Presence { - // Forces the (memoised) traversal so the `.gitignore` rules are loaded; - // this is a no-op once the scan has run. - let ignores = &self.files().ignores; - let mut saw_ignored = false; - for candidate in candidates { - if file_exists(self.root, candidate) { - return Presence::Found; - } - if self.ignore.is_ignored(candidate) || ignores.is_ignored(candidate) { - saw_ignored = true; - } - } - if saw_ignored { - Presence::MissingIgnored - } else { - Presence::Missing - } - } - - /// Sweep for symlinks escaping the repository root. Returns - /// `(message, path)` pairs, all critical. - fn scan_symlinks(&self) -> Vec<(String, Option)> { - let mut findings = Vec::new(); - let mut seen = 0usize; - self.symlink_into(self.root, 0, &mut seen, &mut findings); - findings - } - - fn symlink_into( - &self, - dir: &Path, - depth: u32, - seen: &mut usize, - findings: &mut Vec<(String, Option)>, - ) { - if depth > MAX_SYMLINK_DEPTH || *seen >= MAX_SYMLINK_ENTRIES { - self.truncated.set(true); - return; - } - let entries = match fs::read_dir(dir) { - Ok(entries) => entries, - Err(_) => return, - }; - for entry in entries.flatten() { - if *seen >= MAX_SYMLINK_ENTRIES { - self.truncated.set(true); - return; - } - *seen += 1; - let path = entry.path(); - let rel = self.rel(&path); - if self.skipped(&rel) { - continue; - } - let result = check_path_security(&path, self.root); - if !result.exists { - // TOCTOU: vanished between read_dir and stat. Skip it. - continue; - } - if result.is_symlink && result.escapes_repo { - findings.push(( - format!( - "Symlink escapes repository: {} -> {}", - rel, - result - .target - .as_ref() - .map(|t| t.display().to_string()) - .unwrap_or_else(|| "?".to_string()) - ), - Some(path.clone()), - )); - continue; - } - // Recurse into real dirs only — never through a symlink. - if !result.is_symlink && path.is_dir() { - let skip = path - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| SKIP_DIR_NAMES.contains(&name)); - if !skip { - self.symlink_into(&path, depth + 1, seen, findings); - } - } - } - } -} - -// --------------------------------------------------------------------------- -// Pure content predicates (unit-tested below). -// --------------------------------------------------------------------------- - -/// A Justfile is "real" when it defines at least one recipe and is not -/// the estate stub. Recipe lines start at column 0 with a target name -/// and contain a `:`. (v2 1.1.2: "Justfile task runner present with -/// real recipes".) -fn justfile_is_real(content: &str) -> bool { - if content.contains("not configured yet") { - return false; - } - content.lines().any(|line| { - let mut chars = line.chars(); - matches!(chars.next(), Some(c) if c.is_ascii_alphanumeric() || c == '_' || c == '-') - && line.contains(':') - }) -} - -/// Suspect V-lang iff V markers are present and no Coq markers are. -/// `.v` is shared by Coq and V; a blanket ban would false-positive every -/// proof file, so this heuristic stays narrow by design. -fn v_file_is_suspect(content: &str) -> bool { - let has_v = V_MARKERS.iter().any(|m| content.contains(m)); - let has_coq = COQ_MARKERS.iter().any(|m| content.contains(m)); - has_v && !has_coq -} - -/// `package.json` carries runtime deps iff it has a non-empty -/// `"dependencies"` object. (v2 5.1.6. `devDependencies` alone is fine.) -fn package_json_has_runtime_deps(content: &str) -> bool { - let Some(start) = content.find("\"dependencies\"") else { - return false; - }; - let rest = &content[start + "\"dependencies\"".len()..]; - let mut chars = rest.chars(); - // Expect `:`, then `{`, then something other than `}`. - for ch in chars.by_ref() { - if ch == ':' { - break; - } - if !ch.is_whitespace() { - return false; - } - } - for ch in chars.by_ref() { - if ch == '{' { - break; - } - if !ch.is_whitespace() { - return false; - } - } - for ch in chars { - if ch == '}' { - return false; - } - if !ch.is_whitespace() { - return true; - } - } - false -} - -/// A recipe line is silent-skip iff it chains `|| echo` with a skip -/// message — the literal `|| echo SKIP` shape v2 6.1.5 names. Plain -/// `|| true` (common in cleanup recipes) is out of scope. -fn silent_skip_line(line: &str) -> bool { - line.contains("|| echo") && (line.contains("SKIP") || line.contains("skip")) -} - -/// Structural licence check: the text names a known identifier. -fn license_text_ok(content: &str) -> bool { - KNOWN_LICENSE_IDS.iter().any(|id| content.contains(id)) -} - -// --------------------------------------------------------------------------- -// Checks. Each returns an Outcome; the inventory table in -// `verify_repository` binds ids, categories, items and tiers. -// Criterion refs point at rsr-criteria-v2.a2ml. -// --------------------------------------------------------------------------- - -/// 1.1.1 scm-github: repository canonical on GitHub (`.github/` present). -fn check_scm_github(scanner: &Scanner) -> Outcome { - if scanner.root.join(".github").is_dir() { - Outcome::pass() - } else { - Outcome::fail("Create .github/ (workflows live there; v2 1.1.1).".to_string()) - } -} - -/// 1.1.2 justfile: Justfile with real recipes. -fn check_justfile(scanner: &Scanner) -> Outcome { - match scanner.presence(&["Justfile", "justfile"]) { - Presence::Found => { - let content = ["Justfile", "justfile"] - .iter() - .find_map(|name| read_head(&scanner.root.join(name), MAX_CONTENT_BYTES)) - .unwrap_or_default(); - if justfile_is_real(&content) { - Outcome::pass() - } else { - Outcome::fail( - "Justfile has no real recipes (stub text or no targets); v2 1.1.2.".to_string(), - ) - } - }, - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail( - "Add a Justfile with real recipes (build/test/lint at minimum); v2 1.1.2.".to_string(), - ), - } -} - -/// 1.1.3 no-makefile (+ Mustfile: no Dockerfiles). -fn check_no_makefile(scanner: &Scanner) -> Outcome { - let mut offenders = Vec::new(); - for path in scanner.all_files() { - if path - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| BANNED_BUILD_FILES.contains(&name)) - { - offenders.push(scanner.rel(path)); - } - } - if offenders.is_empty() { - Outcome::pass() - } else { - offenders.sort(); - offenders.truncate(5); - Outcome::fail(format!( - "Remove banned build files ({}); use Justfile/Mustfile + Containerfile (v2 1.1.3).", - offenders.join(", ") - )) - } -} - -/// 2.1.1 readme-adoc: README.adoc (`.md` accepted; `.adoc` primary). -fn check_readme(scanner: &Scanner) -> Outcome { - match scanner.presence(&["README.adoc", "README.md"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail( - "Add README.adoc (README.md accepted; .adoc is primary per v2 2.1.1).".to_string(), - ), - } -} - -/// 2.1.2 license-file: LICENSE present (NOT LICENSE.txt — retired v1 shape). -fn check_license_file(scanner: &Scanner) -> Outcome { - match scanner.presence(&["LICENSE", "LICENSE.md", "LICENSE.adoc"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => { - if file_exists(scanner.root, "LICENSE.txt") { - Outcome::fail( - "LICENSE.txt is the retired v1 shape: rename to LICENSE (+ LICENSES/ full texts); v2 2.1.2." - .to_string(), - ) - } else { - Outcome::fail("Add a LICENSE file (+ LICENSES/ full texts); v2 2.1.2.".to_string()) - } - }, - } -} - -/// 2.1.3 security-md: vulnerability-disclosure policy, root or .github/. -fn check_security_policy(scanner: &Scanner) -> Outcome { - match scanner.presence(&[ - "SECURITY.md", - "SECURITY.adoc", - ".github/SECURITY.md", - ".github/SECURITY.adoc", - ]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail( - "Add SECURITY.md with disclosure contact + response timeline; v2 2.1.3.".to_string(), - ), - } -} - -/// 2.1.10 gitignore: .gitignore and .gitattributes present. -fn check_gitignore(scanner: &Scanner) -> Outcome { - let has_ignore = file_exists(scanner.root, ".gitignore"); - let has_attributes = file_exists(scanner.root, ".gitattributes"); - if has_ignore && has_attributes { - Outcome::pass() - } else if scanner.ignore.is_ignored(".gitignore") && scanner.ignore.is_ignored(".gitattributes") - { - Outcome::pass_ignored() - } else { - let mut missing = Vec::new(); - if !has_ignore { - missing.push(".gitignore"); - } - if !has_attributes { - missing.push(".gitattributes"); - } - Outcome::fail(format!("Add {}; v2 2.1.10.", missing.join(" and "))) - } -} - -/// 4.1.1 spdx-headers: SPDX headers on all scanned source files. -fn check_spdx_headers(scanner: &Scanner) -> Outcome { - let mut missing = Vec::new(); - for path in scanner.spdx_files() { - let headed = read_head(path, SPDX_HEAD_BYTES) - .map(|content| { - content - .lines() - .take(10) - .any(|line| line.contains("SPDX-License-Identifier")) - }) - .unwrap_or(false); - if !headed { - missing.push(scanner.rel(path)); - } - } - if missing.is_empty() { - Outcome::pass() - } else { - missing.sort(); - let shown: Vec<&str> = missing.iter().take(5).map(String::as_str).collect(); - let more = if missing.len() > 5 { - format!(" (+{} more)", missing.len() - 5) - } else { - String::new() - }; - Outcome::fail(format!( - "Add SPDX-License-Identifier headers (first 10 lines) to: {}{}; v2 4.1.1.", - shown.join(", "), - more - )) - } -} - -/// 4.1.2 no-secrets: no committed secret files or key material. -fn check_no_secrets(scanner: &Scanner) -> Outcome { - let mut offenders = Vec::new(); - for path in scanner.all_files() { - if path - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| SECRET_FILENAMES.contains(&name)) - { - offenders.push(scanner.rel(path)); - } - } - let markers = secret_markers(); - for path in scanner.secret_files() { - if let Some(content) = read_head(path, MAX_CONTENT_BYTES) { - if markers.iter().any(|m| content.contains(m)) { - offenders.push(scanner.rel(path)); - } - } - } - if offenders.is_empty() { - Outcome::pass() - } else { - offenders.sort(); - offenders.dedup(); - offenders.truncate(5); - Outcome::fail(format!( - "Possible committed secrets in: {}. Remove + rotate; v2 4.1.2.", - offenders.join(", ") - )) - } -} - -/// 5.1.1–5.1.5 language bans: no Python/TS/ReScript/Go/V sources. -fn check_language_policy(scanner: &Scanner) -> Outcome { - let mut offenders = Vec::new(); - for path in scanner.banned_files() { - let ext = path - .extension() - .and_then(|e| e.to_str()) - .unwrap_or_default() - .to_ascii_lowercase(); - if ext == "v" { - // `.v` is shared with Coq: only flag likely V-lang. - let suspect = read_head(path, MAX_CONTENT_BYTES) - .is_some_and(|content| v_file_is_suspect(&content)); - if suspect { - offenders.push(scanner.rel(path)); - } - continue; - } - offenders.push(scanner.rel(path)); - } - if offenders.is_empty() { - Outcome::pass() - } else { - offenders.sort(); - offenders.truncate(5); - Outcome::fail(format!( - "Banned-language sources present: {}. See estate language policy (v2 5.1.x); carve-outs are granted via hypatia, not here.", - offenders.join(", ") - )) - } -} - -/// 5.1.6 no-node-runtime: no npm-style runtime dependencies. -/// -/// Tier-1 Bun carve-out (estate LANGUAGE-POLICY §1, enforced by -/// governance): runtime deps accompanied by a Bun lockfile pass. -fn check_no_node_runtime(scanner: &Scanner) -> Outcome { - let mut offenders = Vec::new(); - for path in scanner.all_files() { - if path - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| name == "package.json") - { - if let Some(content) = read_head(path, MAX_CONTENT_BYTES) { - if package_json_has_runtime_deps(&content) && !has_bun_lockfile(path) { - offenders.push(scanner.rel(path)); - } - } - } - } - if offenders.is_empty() { - Outcome::pass() - } else { - Outcome::fail(format!( - "package.json with runtime dependencies and no Bun lockfile: {}. Use the estate runtime policy (v2 5.1.6).", - offenders.join(", ") - )) - } -} - -/// A Bun lockfile next to package.json (either generation: `bun.lock` -/// text or legacy `bun.lockb` binary). -fn has_bun_lockfile(package_json: &Path) -> bool { - package_json - .parent() - .is_some_and(|dir| dir.join("bun.lock").is_file() || dir.join("bun.lockb").is_file()) -} - -/// 6.1.1 ci-present: CI pipeline with at least one workflow. -fn check_ci_present(scanner: &Scanner) -> Outcome { - let workflows = scanner.root.join(".github/workflows"); - if workflows.is_dir() { - let has_workflow = fs::read_dir(&workflows).is_ok_and(|entries| { - entries.flatten().any(|entry| { - entry - .path() - .extension() - .is_some_and(|ext| ext == "yml" || ext == "yaml") - }) - }); - if has_workflow { - return Outcome::pass(); - } - } - if scanner.ignore.is_ignored(".github/workflows") { - Outcome::pass_ignored() - } else { - Outcome::fail("Add at least one workflow under .github/workflows/; v2 6.1.1.".to_string()) - } -} - -/// 7.1.1 licence-classified (structural half): LICENSE names a known id. -fn check_licence_class(scanner: &Scanner) -> Outcome { - let content = ["LICENSE", "LICENSE.md", "LICENSE.adoc", "LICENSE.txt"] - .iter() - .find_map(|name| read_head(&scanner.root.join(name), MAX_CONTENT_BYTES)); - match content { - None => Outcome::fail("No LICENSE file to classify; v2 7.1.1.".to_string()), - Some(text) if license_text_ok(&text) => Outcome::pass(), - Some(_) => Outcome::fail( - "LICENSE names no recognised identifier; use an estate-classified licence (v2 7.1.1)." - .to_string(), - ), - } -} - -/// 1.1.4 editorconfig. -fn check_editorconfig(scanner: &Scanner) -> Outcome { - match scanner.presence(&[".editorconfig"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail("Add .editorconfig; v2 1.1.4.".to_string()), - } -} - -/// 1.2.4 tool-versions. -fn check_tool_versions(scanner: &Scanner) -> Outcome { - match scanner.presence(&[".tool-versions"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => { - Outcome::fail("Add .tool-versions pinning toolchain versions; v2 1.2.4.".to_string()) - }, - } -} - -/// 2.1.4 coc-md, root or .github/. -fn check_coc(scanner: &Scanner) -> Outcome { - match scanner.presence(&[ - "CODE_OF_CONDUCT.md", - "CODE_OF_CONDUCT.adoc", - ".github/CODE_OF_CONDUCT.md", - ".github/CODE_OF_CONDUCT.adoc", - ]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail("Add CODE_OF_CONDUCT.md; v2 2.1.4.".to_string()), - } -} - -/// 2.1.5 contributing-md, root or .github/. -fn check_contributing(scanner: &Scanner) -> Outcome { - match scanner.presence(&[ - "CONTRIBUTING.md", - "CONTRIBUTING.adoc", - ".github/CONTRIBUTING.md", - ".github/CONTRIBUTING.adoc", - ]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail("Add CONTRIBUTING.md; v2 2.1.5.".to_string()), - } -} - -/// 2.1.6 changelog: CHANGELOG.adoc or .md. -fn check_changelog(scanner: &Scanner) -> Outcome { - match scanner.presence(&["CHANGELOG.adoc", "CHANGELOG.md"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => { - Outcome::fail("Add CHANGELOG.adoc (Keep a Changelog); v2 2.1.6.".to_string()) - }, - } -} - -/// 2.2.1 wellknown-core: security.txt + ai.txt + humans.txt. -fn check_wellknown_core(scanner: &Scanner) -> Outcome { - let files = ["security.txt", "ai.txt", "humans.txt"]; - let missing: Vec<&str> = files - .iter() - .filter(|name| !file_exists(scanner.root, &format!(".well-known/{name}"))) - .copied() - .collect(); - if missing.is_empty() { - Outcome::pass() - } else if scanner.ignore.is_ignored(".well-known") { - Outcome::pass_ignored() - } else { - Outcome::fail(format!( - "Add .well-known/{}; v2 2.2.1.", - missing.join(", .well-known/") - )) - } -} - -/// 2.3.1 ai-manifest: agent front door (`.deed` accepted mid-migration). -fn check_ai_manifest(scanner: &Scanner) -> Outcome { - match scanner.presence(&["0-AI-MANIFEST.a2ml", "0-AI-MANIFEST.deed"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => { - Outcome::fail("Add 0-AI-MANIFEST.a2ml agent front door; v2 2.3.1.".to_string()) - }, - } -} - -/// 3.2.2 rsr-profile: capability declaration driving the applicable set. -fn check_rsr_profile(scanner: &Scanner) -> Outcome { - match scanner.presence(&[ - ".machine_readable/rsr-profile.a2ml", - ".machine_readable/rsr-profile.deed", - ]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail( - "Add .machine_readable/rsr-profile.a2ml declaring capabilities; v2 3.2.2.".to_string(), - ), - } -} - -/// SECURITY: Extract the normalized `uses:` value from one workflow line. -/// -/// Returns `None` for non-`uses:` lines and empty values (nothing to -/// judge — callers treat those as pinned). Strips trailing provenance -/// comments (`# v7.0.1`) and surrounding quotes. -fn parse_uses_value(line: &str) -> Option { - let trimmed = line.trim(); - // Accept both `uses:` and list form `- uses:`. - let rest = trimmed - .strip_prefix("uses:") - .or_else(|| trimmed.strip_prefix("- uses:"))?; - let value = rest.split('#').next().unwrap_or("").trim(); - let value = value.trim_matches(|c| c == '"' || c == '\''); - if value.is_empty() { - None - } else { - Some(value.to_string()) - } -} - -/// SECURITY: Decide whether a `uses:` value is pinned. -/// -/// A value is pinned when the ref after the final `@` is exactly 40 -/// hexadecimal characters (a full-length Git SHA-1) — or when it is -/// covered by the repo's `actions.lock` (`locked`: the locked refs for -/// this workflow file; empty when there is no lockfile, in which case -/// only full SHAs pass). -/// -/// Lock matching follows the estate convention (governance-reusable: -/// tags in YAML plus a verified lockfile are the authoritative -/// resolution; inline SHAs alongside a lock are forbidden because they -/// break the lock tooling). A lock entry covers the exact `repo@ref` and -/// any sub-path action under it (`github/codeql-action@vX` covers -/// `github/codeql-action/init@vX`). -/// -/// Exempt (treated as pinned): -/// - local actions and reusable workflows — `./…` -/// - `docker://` image references (different digest syntax) -/// - `actions/github-script` (governance parity exemption) -fn uses_value_is_pinned(value: &str, locked: &[String]) -> bool { - if value.starts_with("./") || value.starts_with(".\\") || value.starts_with("docker://") { - return true; - } - if value == "actions/github-script" || value.starts_with("actions/github-script@") { - return true; - } - let Some((repo, git_ref)) = value.rsplit_once('@') else { - return false; // no ref at all — unpinned - }; - if git_ref.len() == 40 && git_ref.chars().all(|c| c.is_ascii_hexdigit()) { - return true; - } - // Lock coverage: same ref on the same repo (or a sub-path of it). - locked.iter().any(|entry| { - let Some((locked_repo, locked_ref)) = entry.rsplit_once('@') else { - return false; - }; - locked_ref == git_ref - && (repo == locked_repo - || (repo.starts_with(locked_repo) - && repo.as_bytes().get(locked_repo.len()) == Some(&b'/'))) - }) -} - -/// SECURITY: Decide whether one workflow line satisfies SHA pinning. -/// -/// Strict form (no lockfile): only full 40-hex SHAs pass. Unit-test -/// entry point — production uses the lock-aware verdict in -/// [`uses_value_is_pinned`]. -#[cfg(test)] -fn uses_line_is_pinned(line: &str) -> bool { - match parse_uses_value(line) { - None => true, // not a uses: line — nothing to judge - Some(value) => uses_value_is_pinned(&value, &[]), - } -} - -/// Extract the locked action refs for one workflow file from an -/// `actions.lock` document. Minimal line parser for the known shape -/// (`workflows:` map of file → ref list). Unknown shapes yield no refs — -/// a lockfile this parser cannot read falls back to the strict SHA -/// test rather than silently passing everything. -fn locked_refs_for(lock_content: &str, rel_path: &str) -> Vec { - let mut refs = Vec::new(); - let mut in_workflows = false; - let mut current: Option<&str> = None; - for line in lock_content.lines() { - let trimmed = line.trim(); - if trimmed.is_empty() { - continue; - } - if !line.starts_with([' ', '\t']) { - // Top-level key: entering or leaving the workflows map. - in_workflows = trimmed == "workflows:"; - current = None; - continue; - } - if !in_workflows { - continue; - } - // File entries look like `'.github/workflows/ci.yml':`. - if let Some(path) = trimmed - .strip_suffix(':') - .map(str::trim) - .and_then(|quoted| quoted.strip_prefix('\'')) - .and_then(|quoted| quoted.strip_suffix('\'')) - { - current = Some(path); - continue; - } - // Ref entries look like `- 'actions/checkout@v7.0.1'`. - if current == Some(rel_path) { - if let Some(entry) = trimmed - .strip_prefix('-') - .map(str::trim) - .and_then(|quoted| quoted.strip_prefix('\'')) - .and_then(|quoted| quoted.strip_suffix('\'')) - { - refs.push(entry.to_string()); - } - } - } - refs -} - -/// 4.1.3 sha-pinned: GitHub Actions SHA pinning. -/// -/// A `uses:` ref passes with a full 40-char SHA, or with a tag covered -/// by `.github/workflows/actions.lock` for that file (the estate -/// mechanism: tags in YAML plus a verified lockfile; governance forbids -/// inline SHAs alongside a lock because they break the lock tooling). -/// Repos without a lockfile are held to strict SHAs — mirroring the -/// governance-reusable no-lock branch. -fn check_workflow_pins(scanner: &Scanner) -> Outcome { - let workflows_path = scanner.root.join(".github/workflows"); - if !workflows_path.is_dir() { - // No workflows: ci-present already fails at Bronze; stay silent - // here rather than double-reporting the same gap. - return Outcome::pass(); - } - let lock = read_head( - &scanner.root.join(".github/workflows/actions.lock"), - MAX_CONTENT_BYTES, - ); - let entries = match fs::read_dir(&workflows_path) { - Ok(entries) => entries, - Err(_) => return Outcome::pass(), - }; - let mut unpinned_files = Vec::new(); - for entry in entries.flatten() { - let path = entry.path(); - if !path - .extension() - .is_some_and(|ext| ext == "yml" || ext == "yaml") - { - continue; - } - let rel = scanner.rel(&path); - let locked = lock - .as_ref() - .map(|content| locked_refs_for(content, &rel)) - .unwrap_or_default(); - if let Some(content) = read_head(&path, MAX_CONTENT_BYTES) { - let unpinned = content.lines().any(|line| match parse_uses_value(line) { - None => false, - Some(value) => !uses_value_is_pinned(&value, &locked), - }); - if unpinned { - unpinned_files.push(rel); - } - } - } - if unpinned_files.is_empty() { - Outcome::pass() - } else { - unpinned_files.sort(); - unpinned_files.truncate(5); - Outcome::fail(format!( - "Pin actions to full 40-char SHAs (or cover the tag in actions.lock) in: {}; v2 4.1.3.", - unpinned_files.join(", ") - )) - } -} - -/// 6.1.2 hypatia-scan: self-scan workflow wired. -fn check_hypatia_scan(scanner: &Scanner) -> Outcome { - match scanner.presence(&[".github/workflows/hypatia-scan.yml"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail( - "Wire .github/workflows/hypatia-scan.yml self-scan; v2 6.1.2.".to_string(), - ), - } -} - -/// 6.1.3 governance-wf: estate-policy enforcement workflow. -fn check_governance_wf(scanner: &Scanner) -> Outcome { - match scanner.presence(&[".github/workflows/governance.yml"]) { - Presence::Found => Outcome::pass(), - Presence::MissingIgnored => Outcome::pass_ignored(), - Presence::Missing => Outcome::fail( - "Wire .github/workflows/governance.yml estate-policy enforcement; v2 6.1.3." - .to_string(), - ), - } -} - -/// 7.1.2 reuse-compliant: LICENSES/ dir with full texts. -fn check_reuse(scanner: &Scanner) -> Outcome { - let dir = scanner.root.join("LICENSES"); - let has_texts = - dir.is_dir() && fs::read_dir(&dir).is_ok_and(|entries| entries.flatten().next().is_some()); - if has_texts { - Outcome::pass() - } else if scanner.ignore.is_ignored("LICENSES") { - Outcome::pass_ignored() - } else { - Outcome::fail("Add LICENSES/ with full licence texts (REUSE style); v2 7.1.2.".to_string()) - } -} - -/// 6.1.5 no-silent-skip (Gold): no `|| echo SKIP` silent-green recipes. -fn check_no_silent_skip(scanner: &Scanner) -> Outcome { - let mut offenders = Vec::new(); - for path in scanner.all_files() { - let is_recipe = path - .file_name() - .and_then(|name| name.to_str()) - .is_some_and(|name| name == "Justfile" || name == "justfile"); - let is_script = path.extension().is_some_and(|ext| { - ext == "just" || ext == "sh" || ext == "bash" || ext == "yml" || ext == "yaml" - }); - if !(is_recipe || is_script) { - continue; - } - if let Some(content) = read_head(path, MAX_CONTENT_BYTES) { - if content.lines().any(silent_skip_line) { - offenders.push(scanner.rel(path)); - } - } - } - if offenders.is_empty() { - Outcome::pass() - } else { - offenders.sort(); - Outcome::fail(format!( - "Silent-skip pattern (|| echo SKIP) in: {}. Fail loudly instead; v2 6.1.5.", - offenders.join(", ") - )) - } -} - -/// Helper: Recursive implementation of glob_match. -fn glob_match_recursive(pattern: &[char], text: &[char], pi: usize, ti: usize) -> bool { - if pi >= pattern.len() && ti >= text.len() { - true - } else if pi >= pattern.len() || ti >= text.len() { - // A trailing `*` also matches the empty remainder ("a*" ~ "a"). - if pi < pattern.len() && ti >= text.len() && pattern[pi..].iter().all(|c| *c == '*') { - return true; - } - false - } else if pattern[pi] == '*' { - // '*' matches zero or more characters (crossing `/`). - glob_match_recursive(pattern, text, pi + 1, ti) - || glob_match_recursive(pattern, text, pi, ti + 1) - } else if pattern[pi] == '?' || pattern[pi] == text[ti] { - // '?' matches any single character, or literal match - glob_match_recursive(pattern, text, pi + 1, ti + 1) - } else { - false - } -} - -/// One inventory row: stable id, category, item label, required tier, check. -type InventoryRow = ( - &'static str, - &'static str, - &'static str, - ComplianceLevel, - fn(&Scanner) -> Outcome, -); - -/// Record one evaluated check on the report, labelling `(ignored)` when -/// the pass comes from an `[ignore]` pattern rather than presence. -fn emit( - report: &mut ComplianceReport, - id: &str, - category: &str, - item: &str, - level: ComplianceLevel, - outcome: Outcome, -) { - let item = if outcome.ignored { - format!("{item} (ignored)") - } else { - item.to_string() - }; - report.add_check( - id, - category, - &item, - outcome.passed, - level, - outcome.suggestion, - ); -} - -/// VERIFY: run the local file-presence subset against a repository. -/// -/// Checks disabled via `[checks]` are *skipped* (not recorded), so the -/// score denominator is always "checks actually evaluated". Symlink -/// escapes become `critical` warnings; scan truncation becomes a -/// `warning` — partial results are labelled, never silent. -pub fn verify_repository(repo_path: &Path, config: &Config) -> ComplianceReport { - let mut report = ComplianceReport::new(repo_path.to_path_buf()); - let submodules = submodule_paths(repo_path); - let scanner = Scanner { - root: repo_path, - ignore: &config.ignore, - submodules: &submodules, - truncated: Cell::new(false), - files: OnceCell::new(), - }; - - // (id, category, item, tier, check). Display order follows this table. - let inventory: &[InventoryRow] = &[ - ( - "scm-github", - "Infrastructure", - ".github/ directory", - ComplianceLevel::Bronze, - check_scm_github, - ), - ( - "justfile", - "Build System", - "Justfile with real recipes", - ComplianceLevel::Bronze, - check_justfile, - ), - ( - "no-makefile", - "Build System", - "No Makefile / Dockerfile", - ComplianceLevel::Bronze, - check_no_makefile, - ), - ( - "readme", - "Documentation", - "README.adoc (or README.md)", - ComplianceLevel::Bronze, - check_readme, - ), - ( - "license-file", - "Documentation", - "LICENSE file (not LICENSE.txt)", - ComplianceLevel::Bronze, - check_license_file, - ), - ( - "security-policy", - "Documentation", - "SECURITY policy (root or .github/)", - ComplianceLevel::Bronze, - check_security_policy, - ), - ( - "gitignore", - "Documentation", - ".gitignore + .gitattributes", - ComplianceLevel::Bronze, - check_gitignore, - ), - ( - "spdx-headers", - "Security", - "SPDX license headers", - ComplianceLevel::Bronze, - check_spdx_headers, - ), - ( - "no-secrets", - "Security", - "No secrets committed", - ComplianceLevel::Bronze, - check_no_secrets, - ), - ( - "language-policy", - "Language Policy", - "No banned languages", - ComplianceLevel::Bronze, - check_language_policy, - ), - ( - "no-node-runtime", - "Language Policy", - "No Node/npm runtime deps", - ComplianceLevel::Bronze, - check_no_node_runtime, - ), - ( - "ci-present", - "CI/CD", - "CI pipeline (.github/workflows/)", - ComplianceLevel::Bronze, - check_ci_present, - ), - ( - "licence-class", - "Licensing", - "LICENSE carries recognized identifier", - ComplianceLevel::Bronze, - check_licence_class, - ), - ( - "editorconfig", - "Build System", - ".editorconfig", - ComplianceLevel::Silver, - check_editorconfig, - ), - ( - "tool-versions", - "Build System", - ".tool-versions", - ComplianceLevel::Silver, - check_tool_versions, - ), - ( - "coc", - "Documentation", - "CODE_OF_CONDUCT (root or .github/)", - ComplianceLevel::Silver, - check_coc, - ), - ( - "contributing", - "Documentation", - "CONTRIBUTING (root or .github/)", - ComplianceLevel::Silver, - check_contributing, - ), - ( - "changelog", - "Documentation", - "CHANGELOG.adoc (or .md)", - ComplianceLevel::Silver, - check_changelog, - ), - ( - "wellknown-core", - "Well-Known", - ".well-known core files", - ComplianceLevel::Silver, - check_wellknown_core, - ), - ( - "ai-manifest", - "Machine-Readable", - "0-AI-MANIFEST.a2ml", - ComplianceLevel::Silver, - check_ai_manifest, - ), - ( - "rsr-profile", - "Machine-Readable", - "rsr-profile.a2ml", - ComplianceLevel::Silver, - check_rsr_profile, - ), - ( - "sha-pinned", - "Security", - "GitHub Actions SHA pinning", - ComplianceLevel::Silver, - check_workflow_pins, - ), - ( - "hypatia-scan", - "CI/CD", - "hypatia-scan.yml workflow", - ComplianceLevel::Silver, - check_hypatia_scan, - ), - ( - "governance-wf", - "CI/CD", - "governance.yml workflow", - ComplianceLevel::Silver, - check_governance_wf, - ), - ( - "reuse", - "Licensing", - "LICENSES/ with full texts", - ComplianceLevel::Silver, - check_reuse, - ), - ( - "no-silent-skip", - "CI/CD", - "No silent-skip in recipes", - ComplianceLevel::Gold, - check_no_silent_skip, - ), - ]; - - for (id, category, item, level, run) in inventory { - if config.checks.enabled(id) { - let outcome = run(&scanner); - emit(&mut report, id, category, item, *level, outcome); - } - } - - for (message, path) in scanner.scan_symlinks() { - report.add_warning("critical", message, path); - } - - if scanner.truncated.get() { - report.add_warning( - "warning", - format!("Scan truncated at {MAX_SCAN_FILES} files; results are partial."), - None, - ); - } - - report -} - -#[cfg(test)] -mod tests { - use super::*; - use std::path::PathBuf; - - #[test] - fn test_glob_match_literal() { - assert!(glob_match("main.rs", "main.rs")); - assert!(!glob_match("main.rs", "lib.rs")); - } - - #[test] - fn test_glob_match_star() { - assert!(glob_match("*.rs", "main.rs")); - assert!(glob_match("*.rs", "lib.rs")); - assert!(!glob_match("*.rs", "main.toml")); - } - - #[test] - fn test_glob_match_star_crosses_dirs_and_trailing_star() { - assert!(glob_match("*.log", "nested/debug.log")); - assert!(glob_match("fixtures/**", "fixtures/input/data.bin")); - assert!(glob_match("prefix*", "prefix")); - assert!(glob_match("src/*", "src/main.rs")); - } - - #[test] - fn test_glob_match_question() { - assert!(glob_match("file?.rs", "file1.rs")); - assert!(glob_match("file?.rs", "filex.rs")); - assert!(!glob_match("file?.rs", "file.rs")); - } - - #[test] - fn test_glob_match_complex() { - assert!(glob_match("*.rs", "test.rs")); - assert!(glob_match("src/*.rs", "src/main.rs")); - } - - #[test] - fn test_path_check_result_default() { - let result: PathCheckResult = Default::default(); - assert!(!result.exists); - assert!(!result.is_symlink); - assert!(!result.escapes_repo); - assert!(result.target.is_none()); - } - - #[test] - fn test_check_result_creation() { - let check = CheckResult { - id: "readme".to_string(), - category: "Documentation".to_string(), - item: "README.md".to_string(), - passed: true, - required_for: ComplianceLevel::Bronze, - suggestion: None, - }; - - assert_eq!(check.id, "readme"); - assert_eq!(check.category, "Documentation"); - assert_eq!(check.item, "README.md"); - assert!(check.passed); - assert_eq!(check.required_for, ComplianceLevel::Bronze); - } - - #[test] - fn test_security_warning_creation() { - let warning = SecurityWarning { - level: "critical".to_string(), - message: "Symlink escapes repository".to_string(), - path: None, - }; - - assert_eq!(warning.level, "critical"); - assert!(!warning.message.is_empty()); - } - - #[test] - fn test_compliance_report_new() { - let path = PathBuf::from("/tmp/test-repo"); - let report = ComplianceReport::new(path.clone()); - - assert_eq!(report.repository_path, path); - assert!(report.checks.is_empty()); - assert!(report.warnings.is_empty()); - } - - #[test] - fn test_compliance_report_add_check() { - let path = PathBuf::from("/tmp/test-repo"); - let mut report = ComplianceReport::new(path); - - report.add_check( - "readme", - "Documentation", - "README.md", - true, - ComplianceLevel::Bronze, - None, - ); - - assert_eq!(report.checks.len(), 1); - assert_eq!(report.checks[0].id, "readme"); - assert_eq!(report.checks[0].category, "Documentation"); - assert_eq!(report.checks[0].item, "README.md"); - assert!(report.checks[0].passed); - } - - #[test] - fn test_compliance_report_add_warning() { - let path = PathBuf::from("/tmp/test-repo"); - let mut report = ComplianceReport::new(path); - - report.add_warning("warning", "Test warning".to_string(), None); - - assert_eq!(report.warnings.len(), 1); - assert_eq!(report.warnings[0].level, "warning"); - } - - #[test] - fn test_compliant_at_builds_upward() { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/x")); - report.add_check("a", "C", "a", true, ComplianceLevel::Bronze, None); - report.add_check("b", "C", "b", false, ComplianceLevel::Silver, None); - assert!(report.compliant_at(ComplianceLevel::Bronze)); - assert!(!report.compliant_at(ComplianceLevel::Silver)); - assert_eq!(report.score_pct(), 50.0); - } - - #[test] - fn test_tier_counts_covers_all_levels() { - let report = ComplianceReport::new(PathBuf::from("/tmp/x")); - let counts = report.tier_counts(); - assert_eq!(counts.len(), 4); - assert_eq!(counts[3].0, ComplianceLevel::Platinum); - assert_eq!(report.score_pct(), 100.0); - } - - #[test] - fn test_compliance_level_vocabulary() { - assert_eq!( - ComplianceLevel::from_v2_tier("bronze"), - Some(ComplianceLevel::Bronze) - ); - assert_eq!( - ComplianceLevel::from_v2_tier("SILVER"), - Some(ComplianceLevel::Silver) - ); - assert_eq!( - ComplianceLevel::from_v2_tier("gold"), - Some(ComplianceLevel::Gold) - ); - assert_eq!( - ComplianceLevel::from_v2_tier("rhodium"), - Some(ComplianceLevel::Platinum) - ); - assert_eq!( - ComplianceLevel::from_v2_tier("platinum"), - Some(ComplianceLevel::Platinum) - ); - assert_eq!(ComplianceLevel::from_v2_tier("copper"), None); - assert_eq!(ComplianceLevel::Bronze.name(), "Bronze"); - assert!(ComplianceLevel::Bronze.rank() < ComplianceLevel::Platinum.rank()); - } - - #[test] - fn test_file_exists() { - // Anchor on CARGO_MANIFEST_DIR rather than the process working directory: - // the crate root is fixed at compile time, so this is deterministic no - // matter where the test binary is invoked from. - let root = std::path::Path::new(env!("CARGO_MANIFEST_DIR")); - - assert!( - file_exists(root, "Cargo.toml"), - "Cargo.toml exists at the crate root" - ); - assert!(!file_exists(root, "no-such-file.does-not-exist")); - // `is_file()`, not `exists()` — a directory must not count as a file. - assert!(!file_exists(root, "src"), "a directory is not a file"); - } - - #[test] - fn test_uses_line_is_pinned_accepts_full_sha() { - // Real pins taken from this repository's own workflows. - assert!(uses_line_is_pinned( - " - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1" - )); - // A trailing provenance comment must not defeat the check. - assert!(uses_line_is_pinned( - " uses: actions/deploy-pages@cd2ce8fcbc39b97be8ca5fce6e763baed58fa128 # v5.0.0" - )); - } - - #[test] - fn test_uses_line_is_pinned_rejects_tags_and_branches() { - // REGRESSION: the previous implementation was `line.contains("@v") - // && !line.contains("@")`, which is unsatisfiable — every one of these - // was silently reported as pinned. - assert!(!uses_line_is_pinned(" uses: actions/checkout@v4")); - assert!(!uses_line_is_pinned( - " - uses: actions/checkout@v7.0.1" - )); - assert!(!uses_line_is_pinned(" uses: some/action@main")); - // The exact line that broke Governance and CodeQL on this repo. - assert!(!uses_line_is_pinned( - " uses: SonarSource/sonarqube-scan-action@master" - )); - // A short/abbreviated SHA is not a full-length pin. - assert!(!uses_line_is_pinned(" uses: foo/bar@3d3c42e")); - // No ref at all. - assert!(!uses_line_is_pinned(" uses: foo/bar")); - } - - #[test] - fn test_uses_line_is_pinned_ignores_non_uses_and_exempt_forms() { - assert!(uses_line_is_pinned(" - name: Checkout")); - assert!(uses_line_is_pinned(" run: cargo test")); - assert!(uses_line_is_pinned("")); - // Local actions and local reusable workflows cannot be SHA-pinned. - assert!(uses_line_is_pinned(" - uses: ./.github/actions/setup")); - assert!(uses_line_is_pinned( - " uses: ./.github/workflows/reusable.yml" - )); - // Docker refs use a different digest syntax; out of scope. - assert!(uses_line_is_pinned(" uses: docker://alpine:3.20")); - } - - #[test] - fn test_secret_markers_assemble() { - let markers = secret_markers(); - assert_eq!(markers.len(), SECRET_MARKER_FRAGMENTS.len()); - // Expectations assembled from halves too: a whole marker - // literal here would trip the scanner on its own source. - let rsa_block = format!("{}{}", "-----BEGIN RSA ", "PRIVATE KEY-----"); - assert!(markers.contains(&rsa_block)); - let aws_prefix = format!("{}{}", "AK", "IA"); - assert!(markers.contains(&aws_prefix)); - assert!(markers.iter().all(|m| !m.is_empty())); - } - - #[test] - fn test_parse_uses_value() { - assert_eq!( - parse_uses_value(" - uses: actions/checkout@v4 # v4"), - Some("actions/checkout@v4".to_string()) - ); - assert_eq!( - parse_uses_value("uses: \"./local/action\""), - Some("./local/action".to_string()) - ); - assert_eq!(parse_uses_value(" - name: Checkout"), None); - assert_eq!(parse_uses_value(""), None); - assert_eq!(parse_uses_value(" uses: "), None); - } - - #[test] - fn test_uses_value_is_pinned_with_lock() { - let locked = vec![ - "actions/checkout@v7.0.1".to_string(), - "github/codeql-action@v4.38.0".to_string(), - ]; - // Full SHA passes with or without a lock. - assert!(uses_value_is_pinned( - "actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1", - &[] - )); - // Locked tag passes; unlocked tag fails. - assert!(uses_value_is_pinned("actions/checkout@v7.0.1", &locked)); - assert!(!uses_value_is_pinned("actions/checkout@v7.0.1", &[])); - assert!(!uses_value_is_pinned("actions/checkout@v4", &locked)); - // Repo-level lock entry covers sub-path actions at the same ref. - assert!(uses_value_is_pinned( - "github/codeql-action/init@v4.38.0", - &locked - )); - assert!(!uses_value_is_pinned( - "github/codeql-action/init@v4.37.0", - &locked - )); - // A different repo sharing the prefix must not match. - assert!(!uses_value_is_pinned( - "github/codeql-action-evil@v4.38.0", - &locked - )); - // No ref at all is unpinned even with a lock present. - assert!(!uses_value_is_pinned("actions/checkout", &locked)); - // Exemptions hold regardless of lock state. - assert!(uses_value_is_pinned("./.github/actions/setup", &[])); - assert!(uses_value_is_pinned("docker://alpine:3.20", &[])); - assert!(uses_value_is_pinned("actions/github-script@v7", &[])); - } - - #[test] - fn test_locked_refs_for() { - let lock = "version: 'v0.0.2'\nworkflows:\n '.github/workflows/ci.yml':\n - 'actions/checkout@v7.0.1'\n - 'actions/cache@v6.1.0'\n '.github/workflows/empty.yml': []\ndependencies:\n 'actions/checkout@v7.0.1':\n ref: 'v7.0.1'\n"; - assert_eq!( - locked_refs_for(lock, ".github/workflows/ci.yml"), - vec!["actions/checkout@v7.0.1", "actions/cache@v6.1.0"] - ); - assert!(locked_refs_for(lock, ".github/workflows/empty.yml").is_empty()); - assert!(locked_refs_for(lock, ".github/workflows/other.yml").is_empty()); - assert!(locked_refs_for("not a lockfile\n", ".github/workflows/ci.yml").is_empty()); - assert!(locked_refs_for("", ".github/workflows/ci.yml").is_empty()); - } - - #[test] - fn test_justfile_is_real() { - assert!(justfile_is_real("build:\n cargo build\n")); - assert!(justfile_is_real("# comment\n\ntest target:\n echo ok\n")); - assert!(!justfile_is_real("")); - assert!(!justfile_is_real("# only a comment\n")); - assert!(!justfile_is_real( - "build:\n @echo \"Build not configured yet\"\n" - )); - // Indented lines alone are not recipes. - assert!(!justfile_is_real(" cargo build --release\n")); - } - - #[test] - fn test_v_file_is_suspect() { - let coq = "Require Import List.\nDefinition ident (x : nat) := x.\n"; - assert!(!v_file_is_suspect(coq)); - let vlang = "module main\n\nfn main() {\n\tprintln('hi')\n}\n"; - assert!(v_file_is_suspect(vlang)); - // No markers either way: not evidence of V. - assert!(!v_file_is_suspect("// empty\n")); - } - - #[test] - fn test_package_json_has_runtime_deps() { - assert!(package_json_has_runtime_deps( - r#"{"dependencies": {"left-pad": "^1.0.0"}}"# - )); - assert!(package_json_has_runtime_deps( - "{\"dependencies\" :\n{\n\"x\": \"1\"\n}\n}" - )); - assert!(!package_json_has_runtime_deps( - r#"{"devDependencies": {"vitest": "^1.0.0"}}"# - )); - assert!(!package_json_has_runtime_deps(r#"{"dependencies": {}}"#)); - assert!(!package_json_has_runtime_deps(r#"{"name": "x"}"#)); - } - - #[test] - fn test_silent_skip_line() { - assert!("test -f x || echo SKIP".lines().any(silent_skip_line)); - assert!("run || echo skipping optional step" - .lines() - .any(silent_skip_line)); - assert!(!"rm -rf tmp || true".lines().any(silent_skip_line)); - assert!(!"echo done".lines().any(silent_skip_line)); - } - - #[test] - fn test_license_text_ok() { - assert!(license_text_ok("Mozilla Public License Version 2.0")); - assert!(license_text_ok( - "SPDX-License-Identifier: PMPL-1.0-or-later" - )); - assert!(!license_text_ok("All rights reserved. No licence given.")); - } - - #[test] - fn test_parse_gitmodules_content() { - let content = "[submodule \"absolute-zero\"]\n\tpath = absolute-zero\n\turl = https://example.test/x.git\n"; - assert_eq!(parse_gitmodules_content(content), vec!["absolute-zero"]); - assert!(parse_gitmodules_content("").is_empty()); - assert!(parse_gitmodules_content("path =\n").is_empty()); - } - - #[test] - fn test_scan_set_cap_is_per_bucket() { - // Filling `all` to its cap must not consume the budget of the - // extension-filtered buckets: each check keeps its own allowance, - // exactly as the per-check walks did (issue #197). - let mut set = ScanSet::default(); - for _ in 0..(MAX_SCAN_FILES + 25) { - set.offer(Path::new("/repo/extensionless"), ""); - } - assert_eq!(set.all.len(), MAX_SCAN_FILES); - assert_eq!(set.spdx.len(), 0); - assert_eq!(set.secret.len(), 0); - assert_eq!(set.banned.len(), 0); - assert!(set.capped, "refusing a file must flag truncation"); - } - - #[test] - fn test_scan_set_filtered_buckets_cap_independently() { - // `.rs` matches the SPDX and secret buckets; `.go` matches only the - // banned bucket. Each fills to its own cap, and one reaching the - // limit does not shorten another's list. - let mut set = ScanSet::default(); - for _ in 0..(MAX_SCAN_FILES + 25) { - set.offer(Path::new("/repo/main.rs"), "rs"); - set.offer(Path::new("/repo/app.go"), "go"); - } - assert_eq!(set.all.len(), MAX_SCAN_FILES); - assert_eq!(set.spdx.len(), MAX_SCAN_FILES); - assert_eq!(set.secret.len(), MAX_SCAN_FILES); - assert_eq!(set.banned.len(), MAX_SCAN_FILES); - assert!(set.capped); - } - - #[test] - fn test_scan_set_extensionless_files_only_reach_all() { - let mut set = ScanSet::default(); - set.offer(Path::new("/repo/Makefile"), ""); - set.offer(Path::new("/repo/Justfile"), ""); - assert_eq!(set.all.len(), 2); - assert!(set.spdx.is_empty() && set.secret.is_empty() && set.banned.is_empty()); - } - - #[test] - fn test_scan_set_routes_each_extension_to_its_buckets() { - // One file can serve several buckets. `py` is an SPDX-header, - // secret-scan *and* banned extension; `rs` is SPDX + secret; - // `txt` is in no filtered set, so it reaches `all` alone. This is - // the sharing that makes one traversal cheaper than three. - let mut set = ScanSet::default(); - set.offer(Path::new("/repo/main.rs"), "rs"); - set.offer(Path::new("/repo/app.py"), "py"); - set.offer(Path::new("/repo/data.txt"), "txt"); - let rs = PathBuf::from("/repo/main.rs"); - let py = PathBuf::from("/repo/app.py"); - assert_eq!(set.all.len(), 3); - assert_eq!(set.spdx, vec![rs.clone(), py.clone()]); - assert_eq!(set.secret, vec![rs, py.clone()]); - assert_eq!(set.banned, vec![py]); - } - - #[test] - fn test_compliance_level_equality() { - assert_eq!(ComplianceLevel::Bronze, ComplianceLevel::Bronze); - assert_ne!(ComplianceLevel::Bronze, ComplianceLevel::Silver); - } -} diff --git a/aletheia/src/config.rs b/aletheia/src/config.rs deleted file mode 100644 index 923bdc4..0000000 --- a/aletheia/src/config.rs +++ /dev/null @@ -1,848 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Aletheia Configuration Kernel — Zero-Dependency TOML Parser. -//! -//! This module implements a safe, minimal TOML parser to ingest -//! the `.aletheia.toml` policy file. -//! -//! DESIGN MANDATE: To satisfy RSR Bronze compliance (Air-Gapped/Self-Contained), -//! this parser avoids external crates like `serde` or `toml-rs`. -//! -//! SUPPORTED SHAPE (all sections optional; missing file means defaults): -//! -//! ```toml -//! [aletheia] -//! level = "bronze" # bronze | silver | gold | platinum -//! -//! [checks] -//! readme = true # per-check toggles, keyed by check id -//! changelog = false # (see checks.rs inventory for ids) -//! -//! [ignore] -//! files = ["fixtures/**", "*.log"] # glob patterns, matched against -//! # repo-relative paths (`*`, `?`) -//! ``` -//! -//! For backwards compatibility, top-level `level = "..."` and flat -//! `documentation` / `spdx_headers` keys are still honoured. - -use std::collections::HashMap; -use std::fs; -use std::path::Path; - -/// Maximum `.aletheia.toml` size ingested (1 MiB). A hostile config must -/// not be able to exhaust memory. -const MAX_CONFIG_BYTES: u64 = 1024 * 1024; - -/// TOML value types supported by the minimal parser. -#[derive(Debug, Clone, PartialEq)] -pub enum TomlValue { - String(String), - Boolean(bool), - Integer(i64), - Array(Vec), -} - -impl TomlValue { - /// Interpret the value as a boolean toggle. Strings accept the - /// `true`/`false` spellings; anything else falls back to `default`. - pub fn as_bool(&self, default: bool) -> bool { - match self { - TomlValue::Boolean(b) => *b, - TomlValue::String(s) if s.eq_ignore_ascii_case("true") => true, - TomlValue::String(s) if s.eq_ignore_ascii_case("false") => false, - TomlValue::Integer(i) => *i != 0, - _ => default, - } - } - - /// Interpret the value as a string. - pub fn as_string(&self) -> Option<&str> { - match self { - TomlValue::String(s) => Some(s), - _ => None, - } - } - - /// Interpret the value as a string array (for `[ignore] files`). - /// A lone string is treated as a single-element array. - pub fn as_array(&self) -> Vec { - match self { - TomlValue::Array(items) => items.clone(), - TomlValue::String(s) => vec![s.clone()], - _ => Vec::new(), - } - } -} - -/// IGNORE PATTERNS: glob patterns for paths to exclude from the audit. -/// Matched against repo-relative paths with `/` separators (see -/// `checks::glob_match`). `*` crosses directory boundaries. -#[derive(Debug, Clone, Default)] -pub struct IgnoreConfig { - pub patterns: Vec, -} - -impl IgnoreConfig { - /// Whether a repo-relative path is ignored by any pattern. - pub(crate) fn is_ignored(&self, rel_path: &str) -> bool { - self.patterns - .iter() - .any(|pat| crate::checks::glob_match(pat, rel_path)) - } -} - -/// GITIGNORE SUPPORT: the repository's own `.gitignore` rules, honoured by -/// the scanner so that build output (`target/`, `obj/`, `_build/`, …) does -/// not pollute the audit. -/// -/// Deliberately separate from [`IgnoreConfig`]: `[ignore]` patterns come from -/// aletheia's own configuration and are a *choice*, whereas `.gitignore` is -/// the repository's own declaration of what is not part of the published -/// artefact. Auditing a tree that has just been built should produce the same -/// verdict as auditing a clean checkout. -/// -/// Implemented (a documented subset of git's behaviour): -/// * `#` comments and blank lines are skipped; -/// * `!pattern` re-includes, and the *last* matching rule wins; -/// * a trailing `/` restricts the rule to directories and their contents; -/// * a pattern containing `/` is anchored to the directory holding the -/// `.gitignore`; otherwise it matches at any depth below that directory; -/// * `*` crosses directory boundaries, matching this crate's `glob_match`. -/// -/// Not implemented, and not claimed: character classes (`[a-z]`), backslash -/// escapes, and re-inclusion of a file *inside* an ignored directory (git -/// itself forbids the last one). -#[derive(Debug, Clone, Default)] -pub struct GitIgnore { - rules: Vec, -} - -#[derive(Debug, Clone)] -struct GitIgnoreRule { - pattern: String, - negated: bool, - /// Rule carried a trailing `/`: matches directories, so it also covers - /// everything beneath them. - dir_only: bool, - /// Rule contained a `/`, making it relative to `base` rather than - /// matching at any depth. - anchored: bool, - /// Repo-relative directory holding the `.gitignore` that declared the - /// rule ("" for the repository root). - base: String, -} - -impl GitIgnore { - /// Add the rules from one `.gitignore` file. - /// - /// `base` is the repo-relative directory containing it. Rules are stored - /// in load order, and [`GitIgnore::is_ignored`] resolves conflicts by - /// last-match-wins, so a nested file overrides the root one. - pub(crate) fn push_file(&mut self, base: &str, contents: &str) { - for raw in contents.lines() { - // Trailing whitespace is not significant in git; leading whitespace - // is (it is part of the pattern), so only trim the end. - let line = raw.trim_end(); - if line.is_empty() || line.starts_with('#') { - continue; - } - let (negated, body) = match line.strip_prefix('!') { - Some(rest) => (true, rest), - None => (false, line), - }; - let body = body.trim_end(); - if body.is_empty() { - continue; - } - let (dir_only, body) = match body.strip_suffix('/') { - Some(rest) => (true, rest), - None => (false, body), - }; - if body.is_empty() { - continue; - } - // A leading `/` anchors without appearing in the pattern; a `/` - // anywhere else does the same thing by virtue of being present. - let stripped = body.strip_prefix('/').unwrap_or(body); - let anchored = body.starts_with('/') || stripped.contains('/'); - self.rules.push(GitIgnoreRule { - pattern: stripped.to_string(), - negated, - dir_only, - anchored, - base: base.to_string(), - }); - } - } - - /// Whether a repo-relative *file* path is ignored. Last matching rule - /// wins, so a later `!rule` can re-include something an earlier rule - /// excluded. - pub fn is_ignored(&self, rel_path: &str) -> bool { - self.decide(rel_path, false) - } - - /// Whether a repo-relative *directory* path is ignored. - /// - /// Separate from [`GitIgnore::is_ignored`] because a directory-only rule - /// (`obj/`) matches a directory named `obj` but not a file of that name, - /// and a path string alone cannot tell the two apart. The scanner knows - /// the entry's file type, so it can ask the precise question. - pub(crate) fn is_ignored_dir(&self, rel_path: &str) -> bool { - self.decide(rel_path, true) - } - - fn decide(&self, rel_path: &str, is_dir: bool) -> bool { - if rel_path.is_empty() { - return false; - } - let mut verdict = false; - let mut matched = false; - for rule in &self.rules { - if rule.matches(rel_path, is_dir) { - verdict = !rule.negated; - matched = true; - } - } - matched && verdict - } - - /// Drop rules back to an earlier [`GitIgnore::len`]. The scanner uses this - /// to pop a directory's rules when the walk leaves that directory, so a - /// nested `.gitignore` cannot leak into sibling subtrees. - pub(crate) fn truncate(&mut self, len: usize) { - self.rules.truncate(len); - } - - /// Number of rules loaded. Used by tests and diagnostics. - pub(crate) fn len(&self) -> usize { - self.rules.len() - } -} - -impl GitIgnoreRule { - fn matches(&self, path: &str, is_dir: bool) -> bool { - // A rule only governs paths at or below the directory that declared it. - let sub = match self.base.as_str() { - "" => path, - base => match path.strip_prefix(base) { - Some(rest) => match rest.strip_prefix('/') { - Some(rest) => rest, - None => return false, - }, - None => return false, - }, - }; - if sub.is_empty() { - return false; - } - if self.anchored { - return self.test(sub, is_dir); - } - // Unanchored: try at every depth below `base`, i.e. at every component - // boundary of the remaining path. - let mut candidate = sub; - loop { - if self.test(candidate, is_dir) { - return true; - } - match candidate.find('/') { - Some(i) => candidate = &candidate[i + 1..], - None => return false, - } - } - } - - /// Match one candidate path. - /// - /// A pattern that matches a *directory* excludes everything beneath it, so - /// every ancestor directory is a match candidate too — that is how `obj/` - /// comes to ignore `obj/x.o`. A directory-only rule may only match a real - /// directory: a proper ancestor always is one, but the path itself counts - /// only when the caller says so. - fn test(&self, candidate: &str, is_dir: bool) -> bool { - if (is_dir || !self.dir_only) && crate::checks::glob_match(&self.pattern, candidate) { - return true; - } - let mut node = candidate; - while let Some(i) = node.rfind('/') { - node = &node[..i]; - if crate::checks::glob_match(&self.pattern, node) { - return true; - } - } - false - } -} - -/// COMPLIANCE CONFIG: toggles for specific verification checks. -/// -/// The five named fields are the historical category toggles; `extra` -/// carries per-check-id toggles (`readme = false`, …). [`ChecksConfig::enabled`] -/// resolves a check id through both, defaulting to enabled. -#[derive(Debug, Clone)] -pub struct ChecksConfig { - pub documentation: bool, - pub well_known: bool, - pub build_system: bool, - pub spdx_headers: bool, - pub workflow_pins: bool, - pub extra: HashMap, -} - -impl Default for ChecksConfig { - fn default() -> Self { - ChecksConfig { - documentation: true, - well_known: true, - build_system: true, - spdx_headers: true, - workflow_pins: true, - extra: HashMap::new(), - } - } -} - -impl ChecksConfig { - /// Resolve whether the check with this stable id is enabled. - /// - /// A per-id entry in `[checks]` wins; otherwise the owning category - /// toggle applies; unknown ids default to enabled (a typo must not - /// silently disable a check — the id simply never matches). - pub fn enabled(&self, check_id: &str) -> bool { - if let Some(toggle) = self.extra.get(check_id) { - return *toggle; - } - match check_id { - "readme" | "license-file" | "security-policy" | "gitignore" | "coc" - | "contributing" | "changelog" => self.documentation, - "wellknown-core" => self.well_known, - "justfile" | "no-makefile" | "editorconfig" | "tool-versions" => self.build_system, - "spdx-headers" => self.spdx_headers, - "sha-pinned" => self.workflow_pins, - _ => true, - } - } - - /// Set a toggle from a `[checks]` key. Known category aliases update - /// the named field; anything else becomes a per-id entry. - fn set(&mut self, key: &str, value: bool) { - match key { - "documentation" => self.documentation = value, - "well_known" | "well-known" | "wellknown" => self.well_known = value, - "build_system" | "build-system" | "buildsystem" => self.build_system = value, - "spdx_headers" | "spdx-headers" | "spdx" => self.spdx_headers = value, - "workflow_pins" | "workflow-pins" | "workflowpins" => self.workflow_pins = value, - other => { - self.extra.insert(other.to_string(), value); - }, - } - } -} - -/// CONFIGURATION: the top-level policy record. -#[derive(Debug, Clone)] -pub struct Config { - pub level: String, // Target RSR tier (bronze, silver, gold, platinum) - pub checks: ChecksConfig, - pub ignore: IgnoreConfig, // Path patterns to exclude from audit -} - -impl Default for Config { - fn default() -> Self { - Config { - level: "bronze".to_string(), - checks: ChecksConfig::default(), - ignore: IgnoreConfig::default(), - } - } -} - -impl Config { - /// LOADER: reconciles the physical `.aletheia.toml` file with - /// the hardcoded system defaults. Missing or unreadable file means - /// defaults — a policy file must never be load-bearing for a scan. - pub fn load_config(repo_path: &Path) -> Config { - Self::load_from_file(&repo_path.join(".aletheia.toml")) - } - - /// Load policy from an explicit path (`--config`). Same fallback - /// semantics as [`Config::load_config`]. - pub fn load_from_file(config_path: &Path) -> Config { - if config_path.is_file() { - if let Ok(file) = fs::File::open(config_path) { - use std::io::Read; - let mut content = String::new(); - // Cap the read so a hostile config cannot exhaust memory. - if file - .take(MAX_CONFIG_BYTES) - .read_to_string(&mut content) - .is_ok() - { - return Self::parse_from_string(&content); - } - } - } - Config::default() - } - - /// Parse configuration from a TOML string. - /// - /// Section-aware keys (`[aletheia]`, `[checks]`, `[ignore]`) are read - /// via [`parse_toml`]; the historical flat keys (`level`, - /// `documentation`, `spdx_headers` at top level) are honoured too. - fn parse_from_string(content: &str) -> Config { - let mut config = Config::default(); - let sections = parse_toml(content); - - // Top-level (flat) keys, for backwards compatibility. - if let Some(top) = sections.get("") { - if let Some(level) = top.get("level").and_then(TomlValue::as_string) { - config.level = level.to_string(); - } - for key in ["documentation", "spdx_headers"] { - if let Some(value) = top.get(key) { - config.checks.set(key, value.as_bool(true)); - } - } - } - - // [aletheia] section. - if let Some(section) = sections.get("aletheia") { - if let Some(level) = section.get("level").and_then(TomlValue::as_string) { - config.level = level.to_string(); - } - } - - // [checks] section: every key is a toggle. - if let Some(section) = sections.get("checks") { - for (key, value) in section { - config.checks.set(key, value.as_bool(true)); - } - } - - // [ignore] section: `files = [...]` (or a lone string). - if let Some(section) = sections.get("ignore") { - if let Some(files) = section.get("files") { - config.ignore.patterns = files.as_array(); - } - } - - config - } -} - -/// Parse a single scalar value (string, bool or integer). -fn parse_scalar(value_str: &str) -> TomlValue { - let value_str = value_str.trim(); - let quoted = |quote: char| { - value_str.len() >= 2 && value_str.starts_with(quote) && value_str.ends_with(quote) - }; - if quoted('"') || quoted('\'') { - TomlValue::String(value_str[1..value_str.len() - 1].to_string()) - } else if let Ok(b) = value_str.parse::() { - TomlValue::Boolean(b) - } else if let Ok(i) = value_str.parse::() { - TomlValue::Integer(i) - } else { - TomlValue::String(value_str.to_string()) - } -} - -/// Parse an inline string array: `["a", "b"]`. Elements must be quoted; -/// unquoted elements are taken literally (TOML-strictness is deliberately -/// not the goal — resilience is). -fn parse_inline_array(value_str: &str) -> Vec { - let inner = value_str.trim(); - // Only a complete single-line array is understood; an unterminated - // (multi-line) array yields no patterns rather than a bogus one. - let Some(inner) = inner.strip_prefix('[').and_then(|s| s.strip_suffix(']')) else { - return Vec::new(); - }; - inner - .split(',') - .map(|item| { - let item = item.trim().trim_matches('"').trim_matches('\''); - item.to_string() - }) - .filter(|item| !item.is_empty()) - .collect() -} - -/// PARSER: a line-based state machine for TOML key-value pairs. -/// -/// Understands `[section]` headers, `key = value` pairs, `#` comments, -/// quoted strings, booleans, integers and single-line string arrays. -/// Keys before any section header land in the `""` section. A `#` inside -/// a quoted string does not start a comment. -pub fn parse_toml(content: &str) -> HashMap> { - let mut sections: HashMap> = HashMap::new(); - sections.insert(String::new(), HashMap::new()); - let mut current_section = String::new(); - - for line in content.lines() { - let trimmed = strip_comment(line).trim(); - if trimmed.is_empty() { - continue; - } - - if trimmed.starts_with('[') && trimmed.ends_with(']') { - current_section = trimmed[1..trimmed.len() - 1].trim().to_string(); - sections.entry(current_section.clone()).or_default(); - } else if let Some(eq_idx) = trimmed.find('=') { - let key = trimmed[..eq_idx].trim().to_string(); - let value_str = trimmed[eq_idx + 1..].trim(); - if key.is_empty() || value_str.is_empty() { - continue; - } - let value = if value_str.starts_with('[') { - TomlValue::Array(parse_inline_array(value_str)) - } else { - parse_scalar(value_str) - }; - if let Some(section) = sections.get_mut(¤t_section) { - section.insert(key, value); - } - } - } - - sections -} - -/// Strip a trailing `#` comment, honouring single/double quotes. -fn strip_comment(line: &str) -> &str { - let mut in_single = false; - let mut in_double = false; - for (idx, ch) in line.char_indices() { - match ch { - '\'' if !in_double => in_single = !in_single, - '"' if !in_single => in_double = !in_double, - '#' if !in_single && !in_double => return &line[..idx], - _ => {}, - } - } - line -} - -#[cfg(test)] -mod tests { - use super::*; - - // --- .gitignore support ------------------------------------------------- - // The scanner honours the repository's own `.gitignore`, so auditing a - // freshly built tree gives the same verdict as auditing a clean checkout. - - /// Build a rule set from one root-level `.gitignore`. - fn gi(contents: &str) -> GitIgnore { - let mut ig = GitIgnore::default(); - ig.push_file("", contents); - ig - } - - #[test] - fn gitignore_matches_build_output_directories() { - let ig = gi("target/\nobj/\ndist-newstyle/\n"); - // Files beneath an ignored directory are ignored. - assert!(ig.is_ignored("target/debug/app")); - assert!(ig.is_ignored("crate/obj/b__main.ads"), "nested obj/"); - assert!(ig.is_ignored("dist-newstyle/build/x/y")); - // And the directory itself is ignored — asked as a directory, because - // `target/` does not match a *file* called `target`. - assert!(ig.is_ignored_dir("target")); - assert!(ig.is_ignored_dir("crate/obj")); - // Nothing else is touched. - assert!(!ig.is_ignored("src/main.adb")); - assert!(!ig.is_ignored_dir("src")); - } - - #[test] - fn gitignore_plain_pattern_that_matches_a_directory_covers_its_subtree() { - // git ignores everything under a directory any rule matches, even - // without a trailing slash. - let ig = gi("/build\n"); - assert!(ig.is_ignored_dir("build")); - assert!(ig.is_ignored("build/x.coma")); - assert!(!ig.is_ignored("src/build/x.coma"), "anchored to the root"); - } - - #[test] - fn gitignore_dir_only_rule_does_not_match_a_file_of_that_name() { - // `obj/` ignores the directory; a *file* called `obj` is untouched. - let ig = gi("obj/\n"); - assert!(ig.is_ignored("obj/x.o")); - assert!(!ig.is_ignored("obj")); - } - - #[test] - fn gitignore_skips_comments_and_blank_lines() { - let ig = gi("# a comment\n\n \n/build/\n"); - assert_eq!(ig.len(), 1); - assert!(ig.is_ignored("build/x")); - } - - #[test] - fn gitignore_leading_slash_anchors_to_the_root() { - let ig = gi("/build\n"); - assert!(ig.is_ignored("build/x")); - assert!(!ig.is_ignored("src/build/x"), "anchored, so not at depth"); - } - - #[test] - fn gitignore_unanchored_pattern_matches_at_any_depth() { - let ig = gi("*.coma\n"); - assert!(ig.is_ignored("a.coma")); - assert!(ig.is_ignored("deep/nested/b.coma")); - assert!(!ig.is_ignored("a.rs")); - } - - #[test] - fn gitignore_wildcard_crosses_directories() { - let ig = gi("verification/verif/\n"); - assert!(ig.is_ignored("verification/verif/x/y.coma")); - } - - #[test] - fn gitignore_negation_reincludes_and_last_rule_wins() { - let ig = gi("*.log\n!keep.log\n"); - assert!(ig.is_ignored("debug.log")); - assert!(!ig.is_ignored("keep.log"), "negated by the later rule"); - - // Order matters: a later ignore beats an earlier negation. - let ig2 = gi("!keep.log\n*.log\n"); - assert!(ig2.is_ignored("keep.log")); - } - - #[test] - fn gitignore_nested_file_is_scoped_to_its_own_subtree() { - let mut ig = GitIgnore::default(); - ig.push_file("", ""); - ig.push_file("vendor", "*.md\n"); - assert!(ig.is_ignored("vendor/README.md")); - assert!( - !ig.is_ignored("docs/README.md"), - "nested rule must not escape" - ); - assert!( - !ig.is_ignored("vendor"), - "the directory itself is not matched" - ); - } - - #[test] - fn gitignore_empty_and_root_paths_are_never_ignored() { - let ig = gi("*\n"); - assert!(!ig.is_ignored(""), "the repo root is not a file"); - assert!(ig.is_ignored("anything.txt")); - } - - #[test] - fn gitignore_with_only_comments_ignores_nothing() { - let ig = gi("# nothing here\n\n"); - assert_eq!(ig.len(), 0); - assert!(!ig.is_ignored("target/x")); - } - - #[test] - fn test_config_default() { - let config = Config::default(); - assert_eq!(config.level, "bronze"); - assert!(config.checks.documentation); - assert!(config.checks.spdx_headers); - } - - #[test] - fn test_config_parse_simple() { - let toml = r#" -level = "silver" -documentation = true -spdx_headers = false -"#; - let config = Config::parse_from_string(toml); - assert_eq!(config.level, "silver"); - assert!(config.checks.documentation); - assert!(!config.checks.spdx_headers); - } - - #[test] - fn test_config_parse_with_comments() { - let toml = r#" -# This is a comment -level = "bronze" -# Another comment -documentation = true -"#; - let config = Config::parse_from_string(toml); - assert_eq!(config.level, "bronze"); - assert!(config.checks.documentation); - } - - #[test] - fn test_config_sections() { - let toml = r#" -[aletheia] -level = "silver" - -[checks] -readme = false -spdx_headers = false - -[ignore] -files = ["fixtures/**", "*.log"] -"#; - let config = Config::parse_from_string(toml); - assert_eq!(config.level, "silver"); - assert!(!config.checks.enabled("readme")); - assert!(config.checks.enabled("license-file")); - assert!(!config.checks.enabled("spdx-headers")); - assert_eq!(config.ignore.patterns, vec!["fixtures/**", "*.log"]); - } - - #[test] - fn test_config_category_toggle_disables_members() { - let toml = "[checks]\ndocumentation = false\n"; - let config = Config::parse_from_string(toml); - assert!(!config.checks.enabled("readme")); - assert!(!config.checks.enabled("changelog")); - assert!(config.checks.enabled("spdx-headers")); - } - - #[test] - fn test_config_per_id_overrides_category() { - let toml = "[checks]\ndocumentation = false\nreadme = true\n"; - let config = Config::parse_from_string(toml); - assert!(config.checks.enabled("readme")); - assert!(!config.checks.enabled("changelog")); - } - - #[test] - fn test_config_unknown_check_id_defaults_enabled() { - let config = Config::default(); - assert!(config.checks.enabled("no-such-check")); - } - - #[test] - fn test_config_hash_inside_string_is_not_comment() { - let toml = "[ignore]\nfiles = [\"releases/#42/**\"]\n"; - let config = Config::parse_from_string(toml); - assert_eq!(config.ignore.patterns, vec!["releases/#42/**"]); - } - - #[test] - fn test_ignore_config_default() { - let ignore = IgnoreConfig::default(); - assert!(ignore.patterns.is_empty()); - } - - #[test] - fn test_ignore_is_ignored() { - let ignore = IgnoreConfig { - patterns: vec!["*.log".to_string(), "fixtures/**".to_string()], - }; - assert!(ignore.is_ignored("debug.log")); - assert!(ignore.is_ignored("nested/debug.log")); - assert!(ignore.is_ignored("fixtures/input/data.bin")); - assert!(!ignore.is_ignored("src/main.rs")); - } - - #[test] - fn test_checks_config_default() { - let checks = ChecksConfig::default(); - assert!(checks.documentation); - assert!(checks.well_known); - assert!(checks.build_system); - assert!(checks.spdx_headers); - assert!(checks.workflow_pins); - } - - #[test] - fn test_toml_value_string() { - match TomlValue::String("test".to_string()) { - TomlValue::String(s) => assert_eq!(s, "test"), - _ => panic!("Expected String variant"), - } - } - - #[test] - fn test_toml_value_boolean() { - match TomlValue::Boolean(true) { - TomlValue::Boolean(b) => assert!(b), - _ => panic!("Expected Boolean variant"), - } - } - - #[test] - fn test_toml_value_integer() { - match TomlValue::Integer(42) { - TomlValue::Integer(i) => assert_eq!(i, 42), - _ => panic!("Expected Integer variant"), - } - } - - #[test] - fn test_toml_value_array() { - let value = TomlValue::Array(vec!["a".to_string(), "b".to_string()]); - assert_eq!(value.as_array(), vec!["a".to_string(), "b".to_string()]); - assert_eq!( - TomlValue::String("solo".to_string()).as_array(), - vec!["solo"] - ); - assert!(TomlValue::Boolean(true).as_array().is_empty()); - } - - #[test] - fn test_toml_value_as_bool() { - assert!(TomlValue::Boolean(true).as_bool(false)); - assert!(!TomlValue::Boolean(false).as_bool(true)); - assert!(TomlValue::String("true".to_string()).as_bool(false)); - assert!(!TomlValue::String("FALSE".to_string()).as_bool(true)); - assert!(TomlValue::Integer(1).as_bool(false)); - assert!(!TomlValue::Integer(0).as_bool(true)); - assert!(TomlValue::Array(vec![]).as_bool(true)); - } - - #[test] - fn test_parse_toml_basic() { - let toml = r#" -[project] -name = "test" -version = "1.0" -enabled = true -"#; - let parsed = parse_toml(toml); - assert!(parsed.contains_key("project")); - } - - #[test] - fn test_parse_toml_types_and_arrays() { - let toml = "[s]\ncount = 7\nname = \"x\"\nflag = false\nfiles = [\"a\", \"b\"]\n"; - let parsed = parse_toml(toml); - let section = &parsed["s"]; - assert_eq!(section["count"], TomlValue::Integer(7)); - assert_eq!(section["name"], TomlValue::String("x".to_string())); - assert_eq!(section["flag"], TomlValue::Boolean(false)); - assert_eq!( - section["files"], - TomlValue::Array(vec!["a".to_string(), "b".to_string()]) - ); - } - - #[test] - fn test_parse_toml_empty_array_and_skipped_lines() { - let toml = "[s]\nfiles = []\n= oops\nlonely\nkey =\n"; - let parsed = parse_toml(toml); - assert_eq!(parsed["s"]["files"], TomlValue::Array(vec![])); - assert_eq!(parsed["s"].len(), 1); - } - - #[test] - fn test_parse_inline_array_unterminated_yields_empty() { - // Review T5: `files = [` must not become a literal "[" pattern. - assert!(parse_inline_array("[").is_empty()); - assert!(parse_inline_array("").is_empty()); - assert_eq!( - parse_inline_array("[\"a\", \"b\"]"), - vec!["a".to_string(), "b".to_string()] - ); - } -} diff --git a/aletheia/src/main.rs b/aletheia/src/main.rs deleted file mode 100644 index 85cb275..0000000 --- a/aletheia/src/main.rs +++ /dev/null @@ -1,446 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Aletheia — Authoritative RSR Compliance Verification. -//! -//! Named after the Greek concept of "unconcealment," Aletheia is the -//! gatekeeper for the Rhodium Standard Repository (RSR) ecosystem. -//! It provides automated, deterministic audits of repository state to -//! ensure adherence to safety, security, and documentation standards. -//! -//! COMPLIANCE DIMENSIONS: -//! 1. Memory Safety: Verifies `unsafe_code = "deny"` in Rust crates. -//! 2. Totality: Checks for Idris totality markers. -//! 3. Air-Gapped Readiness: Ensures no network dependencies in core logic. -//! 4. Provenance: Validates SPDX headers and license compliance. -//! -//! SCOPE HONESTY: the checks wired here are the offline file-presence -//! subset of the upstream RSR criteria (see `checks::SSOT_PROVENANCE`). -//! The normative tier verdict always comes from the hypatia -//! `rsr-conformance` oracle; Aletheia is the fast local pre-check. - -#![forbid(unsafe_code)] -mod checks; -mod config; -mod output; -mod types; - -use std::path::{Path, PathBuf}; -use std::process; - -use output::exit_codes; -use types::*; - -/// CLI options. -#[derive(Debug)] -struct Options { - repo_path: PathBuf, - format: OutputFormat, - verbose: bool, - quiet: bool, - config_path: Option, - init_hook: bool, -} - -/// Output format selection. -#[derive(Debug, PartialEq, Eq, Clone, Copy)] -enum OutputFormat { - Human, - Json, - Sarif, - Html, - Badge, -} - -impl OutputFormat { - fn from_name(name: &str) -> Option { - match name.to_ascii_lowercase().as_str() { - "human" | "text" => Some(OutputFormat::Human), - "json" => Some(OutputFormat::Json), - "sarif" => Some(OutputFormat::Sarif), - "html" => Some(OutputFormat::Html), - "badge" | "svg" => Some(OutputFormat::Badge), - _ => None, - } - } -} - -/// Parse command-line arguments (pure: testable without the process). -/// -/// Accepted shape: -/// `aletheia [repo-path] [--format X | --format=X | --json | --sarif | -/// --html | --badge] [-v|--verbose] [-q|--quiet] [--config PATH] -/// [--init-hook] [init-hook [path]] [--help] [--version]` -/// The positional path defaults to `.`; `--` ends flag parsing. -fn parse_args_from(argv: &[String]) -> Result { - let mut repo_path: Option = None; - let mut format = OutputFormat::Human; - let mut verbose = false; - let mut quiet = false; - let mut config_path: Option = None; - let mut init_hook = false; - let mut help = false; - let mut version = false; - let mut end_of_flags = false; - - let mut args = argv.iter().peekable(); - // Skip argv[0]. - args.next(); - - while let Some(arg) = args.next() { - if !end_of_flags && arg == "--" { - end_of_flags = true; - continue; - } - if !end_of_flags && arg.starts_with('-') && arg.len() > 1 { - if arg == "--help" || arg == "-h" { - help = true; - } else if arg == "--version" || arg == "-V" { - version = true; - } else if arg == "--verbose" || arg == "-v" { - verbose = true; - } else if arg == "--quiet" || arg == "-q" { - quiet = true; - } else if arg == "--json" { - format = OutputFormat::Json; - } else if arg == "--sarif" { - format = OutputFormat::Sarif; - } else if arg == "--html" { - format = OutputFormat::Html; - } else if arg == "--badge" { - format = OutputFormat::Badge; - } else if arg == "--init-hook" { - init_hook = true; - } else if arg == "--format" { - let value = args.next().ok_or_else(|| { - "Missing value for --format (expected human|json|sarif|html|badge)".to_string() - })?; - format = OutputFormat::from_name(value) - .ok_or_else(|| format!("Unknown --format '{value}'"))?; - } else if let Some(value) = arg.strip_prefix("--format=") { - if value.is_empty() { - return Err("Missing value for --format=X".to_string()); - } - format = OutputFormat::from_name(value) - .ok_or_else(|| format!("Unknown --format '{value}'"))?; - } else if arg == "--config" { - let value = args.next().ok_or_else(|| { - "Missing value for --config (expected a file path)".to_string() - })?; - config_path = Some(PathBuf::from(value)); - } else if let Some(value) = arg.strip_prefix("--config=") { - if value.is_empty() { - return Err("Missing value for --config=X".to_string()); - } - config_path = Some(PathBuf::from(value)); - } else { - return Err(format!( - "Unknown option '{arg}'. Run `aletheia --help` for usage." - )); - } - continue; - } - if !end_of_flags && arg == "init-hook" && repo_path.is_none() && !init_hook { - init_hook = true; - continue; - } - if repo_path.is_some() { - return Err(format!("Unexpected extra argument '{arg}'.")); - } - repo_path = Some(PathBuf::from(arg)); - } - - if help { - print_help(); - process::exit(exit_codes::SUCCESS); - } - if version { - println!("aletheia {}", output::VERSION); - process::exit(exit_codes::SUCCESS); - } - - Ok(Options { - repo_path: repo_path.unwrap_or_else(|| PathBuf::from(".")), - format, - verbose, - quiet, - config_path, - init_hook, - }) -} - -/// Parse command-line arguments from the process environment. -fn parse_args() -> Result { - let argv: Vec = std::env::args().collect(); - parse_args_from(&argv) -} - -/// USAGE text: the CLI contract. -fn print_help() { - println!("aletheia {} - RSR compliance verification", output::VERSION); - println!(); - println!("USAGE:"); - println!(" aletheia [OPTIONS] [repo-path]"); - println!(" aletheia init-hook [repo-path]"); - println!(); - println!("ARGS:"); - println!(" [repo-path] Repository to verify (default: current directory)"); - println!(); - println!("OPTIONS:"); - println!(" -h, --help Print this help and exit"); - println!(" -V, --version Print version and exit"); - println!(" --format FORMAT Output format: human, json, sarif, html, badge"); - println!(" --format=FORMAT Same, equals syntax (e.g. --format=json)"); - println!(" --json Shorthand for --format json"); - println!(" --sarif Shorthand for --format sarif"); - println!(" --html Shorthand for --format html"); - println!(" --badge Print an SVG compliance badge and exit"); - println!(" -v, --verbose Verbose human output (suggestions, tiers, exit reason)"); - println!(" -q, --quiet Print only PASS or FAIL"); - println!(" --config PATH Use PATH instead of /.aletheia.toml"); - println!(" --init-hook Install a pre-commit hook instead of verifying"); - println!(); - println!("EXIT CODES:"); - println!(" 0 Required tier achieved, no critical warnings"); - println!(" 1 Required-tier checks failed (see Fix Suggestions)"); - println!(" 2 Critical security warnings (e.g. symlink escapes repo)"); - println!(" 3 Invalid repository path"); - println!(" 4 Invalid arguments"); - println!(); - println!("EXAMPLES:"); - println!(" aletheia Verify the current directory"); - println!(" aletheia /path/to/repo Verify a specific repository"); - println!(" aletheia --format json . Machine-readable report"); - println!(" aletheia --format=sarif . SARIF for GitHub code scanning"); - println!(" aletheia -q . && echo shipped Quiet gate for scripts"); - println!(" aletheia init-hook . Install the pre-commit hook"); - println!(); - println!("CONFIG:"); - println!(" Reads /.aletheia.toml ([aletheia] level, [checks] toggles,"); - println!(" [ignore] files globs). Absent file means defaults (tier: bronze)."); -} - -/// Install a pre-commit hook that gates commits on Bronze compliance. -/// Returns the exit code for the process. -fn run_init_hook(repo_path: &Path) -> i32 { - if !repo_path.is_dir() { - eprintln!("Error: Invalid repository path."); - return exit_codes::INVALID_PATH; - } - let git_dir = repo_path.join(".git"); - if !git_dir.is_dir() { - eprintln!( - "Error: {} is not a git repository (no .git/).", - repo_path.display() - ); - return exit_codes::INVALID_PATH; - } - let hooks_dir = git_dir.join("hooks"); - if let Err(err) = std::fs::create_dir_all(&hooks_dir) { - eprintln!("Error: cannot create hooks dir: {err}"); - return exit_codes::INVALID_PATH; - } - let hook_path = hooks_dir.join("pre-commit"); - let hook_body = r#"#!/bin/sh -# Installed by `aletheia init-hook`: gate commits on RSR Bronze. -command -v aletheia >/dev/null 2>&1 || { - echo "aletheia: binary not found on PATH - commit blocked" >&2 - exit 1 -} -aletheia --quiet . -status=$? -if [ "$status" -eq 0 ]; then - exit 0 -fi -if [ "$status" -eq 1 ]; then - echo "aletheia: Bronze compliance NOT MET - commit blocked" >&2 -else - echo "aletheia: verification error (exit $status) - commit blocked" >&2 -fi -exit 1 -"#; - if let Err(err) = std::fs::write(&hook_path, hook_body) { - eprintln!("Error: cannot write pre-commit hook: {err}"); - return exit_codes::INVALID_PATH; - } - #[cfg(unix)] - { - use std::os::unix::fs::PermissionsExt; - let perms = std::fs::Permissions::from_mode(0o755); - if let Err(err) = std::fs::set_permissions(&hook_path, perms) { - eprintln!("Error: cannot chmod pre-commit hook: {err}"); - return exit_codes::INVALID_PATH; - } - } - println!("Installed pre-commit hook at {}", hook_path.display()); - exit_codes::SUCCESS -} - -/// ENTRY POINT: Handles CLI orchestration and reporting. -fn main() { - // 1. ARGUMENT PARSING - let options = match parse_args() { - Ok(opts) => opts, - Err(message) => { - eprintln!("Error: {message}"); - process::exit(exit_codes::INVALID_ARGS); - }, - }; - - // 2a. INIT-HOOK MODE (verifies nothing; installs the git hook). - if options.init_hook { - process::exit(run_init_hook(&options.repo_path)); - } - - // 2b. ENVIRONMENT VALIDATION - if !options.repo_path.is_dir() { - eprintln!( - "Error: repository path '{}' does not exist or is not a directory.", - options.repo_path.display() - ); - process::exit(exit_codes::INVALID_PATH); - } - - // 3. AUDIT EXECUTION - let config = match &options.config_path { - Some(path) => config::Config::load_from_file(path), - None => config::Config::load_config(&options.repo_path), - }; - let level = match ComplianceLevel::from_v2_tier(&config.level) { - Some(level) => level, - None => { - eprintln!( - "Warning: unknown level '{}' in config; falling back to bronze.", - config.level - ); - ComplianceLevel::Bronze - }, - }; - let report = checks::verify_repository(&options.repo_path, &config); - - // 4. RESULT DISPATCH - if options.quiet { - output::print_quiet(&report, level); - } else { - match options.format { - OutputFormat::Human => output::print_report(&report, level, options.verbose), - OutputFormat::Json => output::print_json_report(&report, level), - OutputFormat::Sarif => output::print_sarif_report(&report), - OutputFormat::Html => output::print_html_report(&report, level), - OutputFormat::Badge => output::print_badge(&report, level), - } - } - - // 5. EXIT POLICY (shared with the verbose explainer). - process::exit(output::exit_code_for(&report, level)); -} - -#[cfg(test)] -mod cli_tests { - use super::*; - - fn argv(words: &[&str]) -> Vec { - words.iter().map(ToString::to_string).collect() - } - - #[test] - fn test_parse_defaults_to_human_and_cwd() { - let options = parse_args_from(&argv(&["aletheia"])).expect("bare invocation parses"); - assert_eq!(options.repo_path, PathBuf::from(".")); - assert_eq!(options.format, OutputFormat::Human); - assert!(!options.verbose); - assert!(!options.quiet); - assert!(options.config_path.is_none()); - assert!(!options.init_hook); - } - - #[test] - fn test_parse_positional_path() { - let options = - parse_args_from(&argv(&["aletheia", "/tmp/repo"])).expect("positional parses"); - assert_eq!(options.repo_path, PathBuf::from("/tmp/repo")); - } - - #[test] - fn test_parse_format_forms() { - for words in [ - vec!["aletheia", "--format", "json"], - vec!["aletheia", "--format=json"], - vec!["aletheia", "--json"], - ] { - let options = parse_args_from(&argv(&words)).expect("json form parses"); - assert_eq!(options.format, OutputFormat::Json); - } - let options = - parse_args_from(&argv(&["aletheia", "--format", "sarif"])).expect("sarif parses"); - assert_eq!(options.format, OutputFormat::Sarif); - let options = parse_args_from(&argv(&["aletheia", "--format=html"])).expect("html parses"); - assert_eq!(options.format, OutputFormat::Html); - let options = parse_args_from(&argv(&["aletheia", "--badge"])).expect("badge parses"); - assert_eq!(options.format, OutputFormat::Badge); - } - - #[test] - fn test_parse_flags_and_config() { - let options = parse_args_from(&argv(&[ - "aletheia", - "-v", - "--config", - "custom.toml", - "/tmp/repo", - ])) - .expect("flags parse"); - assert!(options.verbose); - assert_eq!(options.config_path, Some(PathBuf::from("custom.toml"))); - assert_eq!(options.repo_path, PathBuf::from("/tmp/repo")); - - let options = parse_args_from(&argv(&["aletheia", "-q"])).expect("quiet parses"); - assert!(options.quiet); - let options = parse_args_from(&argv(&["aletheia", "--config=other.toml"])) - .expect("equals config parses"); - assert_eq!(options.config_path, Some(PathBuf::from("other.toml"))); - } - - #[test] - fn test_parse_init_hook_forms() { - let options = - parse_args_from(&argv(&["aletheia", "init-hook", "/tmp/repo"])).expect("subcommand"); - assert!(options.init_hook); - assert_eq!(options.repo_path, PathBuf::from("/tmp/repo")); - let options = parse_args_from(&argv(&["aletheia", "--init-hook"])).expect("flag form"); - assert!(options.init_hook); - } - - #[test] - fn test_parse_rejects_unknown_options() { - assert!(parse_args_from(&argv(&["aletheia", "--invalid-option"])).is_err()); - assert!(parse_args_from(&argv(&["aletheia", "--format", "yaml"])).is_err()); - assert!(parse_args_from(&argv(&["aletheia", "--format="])).is_err()); - assert!(parse_args_from(&argv(&["aletheia", "--format"])).is_err()); - assert!(parse_args_from(&argv(&["aletheia", "--config"])).is_err()); - assert!(parse_args_from(&argv(&["aletheia", "a", "b"])).is_err()); - } - - #[test] - fn test_parse_double_dash_ends_flags() { - let options = - parse_args_from(&argv(&["aletheia", "--", "--not-a-flag"])).expect("separator works"); - assert_eq!(options.repo_path, PathBuf::from("--not-a-flag")); - } - - #[test] - fn test_output_format_names() { - assert_eq!(OutputFormat::from_name("JSON"), Some(OutputFormat::Json)); - assert_eq!(OutputFormat::from_name("text"), Some(OutputFormat::Human)); - assert_eq!(OutputFormat::from_name("svg"), Some(OutputFormat::Badge)); - assert_eq!(OutputFormat::from_name("yaml"), None); - } - - #[test] - fn test_parse_flags_after_positional() { - // Review T6: options must stay valid after the positional path. - let options = parse_args_from(&argv(&["aletheia", "/tmp/repo", "--json"])) - .expect("flag after positional parses"); - assert_eq!(options.repo_path, PathBuf::from("/tmp/repo")); - assert_eq!(options.format, OutputFormat::Json); - } -} diff --git a/aletheia/src/output.rs b/aletheia/src/output.rs deleted file mode 100644 index 727752c..0000000 --- a/aletheia/src/output.rs +++ /dev/null @@ -1,629 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Aletheia Output and Reporting Engine. -//! -//! This module implements the presentation layer for compliance audits. -//! It provides multiple serialization formats (JSON, SARIF, HTML, badge) -//! and a high-fidelity human-readable CLI report. -//! -//! ZERO-DEPENDENCY DESIGN: To maintain RSR Bronze compliance, this module -//! implements its own timestamp formatting and string escaping rather than -//! pulling in external crates like `chrono` or `serde_json`. - -use crate::checks::{LOCAL_SUBSET_NOTE, SSOT_PROVENANCE}; -use crate::types::*; -use std::time::SystemTime; - -/// The current version of the Aletheia tool. -pub const VERSION: &str = env!("CARGO_PKG_VERSION"); - -/// EXIT STRATEGY: Standardized exit codes for CI/CD integration. -pub mod exit_codes { - pub const SUCCESS: i32 = 0; // Required tier achieved, no critical warnings. - pub const COMPLIANCE_FAILED: i32 = 1; // Required checks failed. - pub const SECURITY_WARNING: i32 = 2; // Critical security issues (e.g. symlink escape). - pub const INVALID_PATH: i32 = 3; // Repository path missing or not a directory. - pub const INVALID_ARGS: i32 = 4; // Unrecognised flags or malformed arguments. -} - -/// ALGORITHM: Manual timestamp formatter. -/// Converts `SystemTime` to an ISO 8601 string (e.g., 2026-02-21T12:34:56Z). -/// Implemented manually to avoid the `chrono` dependency. -pub fn format_timestamp(time: SystemTime) -> String { - match time.duration_since(SystemTime::UNIX_EPOCH) { - Ok(duration) => { - let secs = duration.as_secs(); - let days_since_epoch = secs / 86400; - let seconds_today = secs % 86400; - - let (year, month, day) = calculate_date(days_since_epoch); - let (hour, minute, second) = calculate_time(seconds_today); - - format!("{year:04}-{month:02}-{day:02}T{hour:02}:{minute:02}:{second:02}Z") - }, - Err(_) => "2026-02-21T00:00:00Z".to_string(), - } -} - -/// Helper: Calculate date from days since Unix epoch. -fn calculate_date(days_since_epoch: u64) -> (u32, u32, u32) { - let mut remaining_days = days_since_epoch; - let mut year = 1970; - - loop { - let days_in_year = if is_leap_year(year) { 366 } else { 365 }; - if remaining_days < days_in_year as u64 { - break; - } - remaining_days -= days_in_year as u64; - year += 1; - } - - let is_leap = is_leap_year(year); - let days_in_months = if is_leap { - [31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - } else { - [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31] - }; - - let mut month = 1; - let mut day = remaining_days as u32 + 1; - - for &days_in_month in &days_in_months { - if day <= days_in_month { - break; - } - day -= days_in_month; - month += 1; - } - - (year, month, day) -} - -/// Helper: Calculate time from seconds since midnight. -fn calculate_time(seconds_today: u64) -> (u32, u32, u32) { - let hour = (seconds_today / 3600) as u32; - let minute = ((seconds_today % 3600) / 60) as u32; - let second = (seconds_today % 60) as u32; - (hour, minute, second) -} - -/// Helper: Check if a year is a leap year. -fn is_leap_year(year: u32) -> bool { - (year % 4 == 0 && year % 100 != 0) || (year % 400 == 0) -} - -/// Escape a string for JSON embedding (minimal, hand-rolled). -fn json_escape(text: &str) -> String { - let mut out = String::with_capacity(text.len() + 2); - for ch in text.chars() { - match ch { - '"' => out.push_str("\\\""), - '\\' => out.push_str("\\\\"), - '\n' => out.push_str("\\n"), - '\r' => out.push_str("\\r"), - '\t' => out.push_str("\\t"), - c if c.is_control() => out.push_str(&format!("\\u{:04x}", c as u32)), - c => out.push(c), - } - } - out -} - -/// Escape a string for HTML embedding (minimal, hand-rolled). -fn html_escape(text: &str) -> String { - text.replace('&', "&") - .replace('<', "<") - .replace('>', ">") - .replace('"', """) -} - -/// Group checks by category, preserving first-seen category order so -/// reports are deterministic across runs and platforms. -fn group_by_category(report: &ComplianceReport) -> Vec<(String, Vec<&CheckResult>)> { - let mut groups: Vec<(String, Vec<&CheckResult>)> = Vec::new(); - for check in &report.checks { - match groups.iter_mut().find(|(cat, _)| *cat == check.category) { - Some((_, items)) => items.push(check), - None => groups.push((check.category.clone(), vec![check])), - } - } - groups -} - -/// REPORTING: quiet mode. A single machine-greppable word. -pub fn print_quiet(report: &ComplianceReport, level: ComplianceLevel) { - if report.compliant_at(level) && !report.has_critical_warnings() { - println!("PASS"); - } else { - println!("FAIL"); - } -} - -/// REPORTING: Standard CLI output. -/// Prints a formatted summary using ✅/❌ markers and per-tier verdicts. -/// Includes categorized check results, fix suggestions for failed items, -/// prominent security warnings, score and verification timestamp. -/// Verbose mode adds version, per-tier counts, inline suggestions, -/// exit-code explanation and the local-subset honesty note. -pub fn print_report(report: &ComplianceReport, level: ComplianceLevel, verbose: bool) { - if verbose { - println!("Aletheia - RSR Compliance Verification Report (Verbose)"); - } else { - println!("Aletheia - RSR Compliance Verification Report"); - } - println!("Repository: {}", report.repository_path.display()); - println!("Verified: {}", format_timestamp(report.verified_at)); - if verbose { - println!("Version: {VERSION}"); - println!("Required tier: {}", level.name()); - } - println!(); - - for (category, checks) in group_by_category(report) { - println!("[{category}]"); - for check in checks { - let status = if check.passed { "✅" } else { "❌" }; - println!(" {status} {} [{}]", check.item, check.required_for.name()); - if verbose { - if let Some(suggestion) = &check.suggestion { - println!(" 💡 {suggestion}"); - } - } - } - println!(); - } - - if !report.warnings.is_empty() { - println!("Warnings:"); - for warning in &report.warnings { - match &warning.path { - Some(path) => println!( - " [{}] {} ({})", - warning.level, - warning.message, - path.display() - ), - None => println!(" [{}] {}", warning.level, warning.message), - } - } - println!(); - } - - let passed = report.passed_count(); - let total = report.total_count(); - println!( - "Score: {passed}/{total} checks passed ({:.1}%)", - report.score_pct() - ); - - let bronze = if report.compliant_at(ComplianceLevel::Bronze) { - "ACHIEVED" - } else { - "NOT MET" - }; - println!("Bronze-level RSR compliance: {bronze}"); - let silver = if report.compliant_at(ComplianceLevel::Silver) { - "ACHIEVED" - } else { - "NOT MET" - }; - println!("Silver-level RSR compliance: {silver}"); - - if verbose { - println!(); - println!("Per-tier results:"); - for (tier, tier_passed, tier_total) in report.tier_counts() { - println!(" {}: {tier_passed}/{tier_total}", tier.name()); - } - println!(); - println!( - "Exit code: {} ({})", - exit_code_for(report, level), - exit_reason(report, level) - ); - println!(); - println!("Aligned to: {SSOT_PROVENANCE}"); - println!("Note: {LOCAL_SUBSET_NOTE}"); - } else { - let failing = report.failing_checks(); - if !failing.is_empty() { - println!(); - println!("Fix Suggestions:"); - for check in failing { - if let Some(suggestion) = &check.suggestion { - println!(" - {}: {suggestion}", check.item); - } - } - } - } -} - -/// EXIT POLICY shared by the CLI and the verbose explainer: critical -/// security warnings outrank compliance failures (both are non-zero). -pub fn exit_code_for(report: &ComplianceReport, level: ComplianceLevel) -> i32 { - if report.has_critical_warnings() { - exit_codes::SECURITY_WARNING - } else if !report.compliant_at(level) { - exit_codes::COMPLIANCE_FAILED - } else { - exit_codes::SUCCESS - } -} - -/// Human-readable reason for [`exit_code_for`]. -fn exit_reason(report: &ComplianceReport, level: ComplianceLevel) -> &'static str { - if report.has_critical_warnings() { - "critical security warnings present" - } else if !report.compliant_at(level) { - "required-tier checks failed" - } else { - "required tier achieved" - } -} - -/// SERIALIZATION: JSON Output. -/// Machine-readable object representing the audit, hand-rolled to keep -/// zero-dependency builds. -pub fn print_json_report(report: &ComplianceReport, level: ComplianceLevel) { - println!("{{"); - println!(" \"version\": \"{VERSION}\","); - println!( - " \"repository\": \"{}\",", - json_escape(&report.repository_path.display().to_string()) - ); - println!( - " \"verified_at\": \"{}\",", - format_timestamp(report.verified_at) - ); - println!(" \"required_tier\": \"{}\",", level.name().to_lowercase()); - println!( - " \"score\": {{\"passed\": {}, \"total\": {}, \"percent\": {:.1}}},", - report.passed_count(), - report.total_count(), - report.score_pct() - ); - println!( - " \"bronze_compliant\": {},", - report.compliant_at(ComplianceLevel::Bronze) - ); - println!( - " \"silver_compliant\": {},", - report.compliant_at(ComplianceLevel::Silver) - ); - println!(" \"tiers\": ["); - let tiers = report.tier_counts(); - for (i, (tier, passed, total)) in tiers.iter().enumerate() { - println!( - " {{\"tier\": \"{}\", \"passed\": {passed}, \"total\": {total}}}{}", - tier.name().to_lowercase(), - if i + 1 < tiers.len() { "," } else { "" } - ); - } - println!(" ],"); - println!(" \"checks\": ["); - for (i, check) in report.checks.iter().enumerate() { - println!(" {{"); - println!(" \"id\": \"{}\",", json_escape(&check.id)); - println!(" \"category\": \"{}\",", json_escape(&check.category)); - println!(" \"item\": \"{}\",", json_escape(&check.item)); - println!(" \"passed\": {},", check.passed); - println!( - " \"required_for\": \"{}\"{}", - check.required_for.name().to_lowercase(), - match &check.suggestion { - Some(suggestion) => - format!(",\n \"suggestion\": \"{}\"", json_escape(suggestion)), - None => String::new(), - } - ); - println!( - " }}{}", - if i + 1 < report.checks.len() { "," } else { "" } - ); - } - println!(" ],"); - println!(" \"warnings\": ["); - for (i, warning) in report.warnings.iter().enumerate() { - println!(" {{"); - println!(" \"level\": \"{}\",", json_escape(&warning.level)); - println!( - " \"message\": \"{}\"{}", - json_escape(&warning.message), - match &warning.path { - Some(path) => format!( - ",\n \"path\": \"{}\"", - json_escape(&path.display().to_string()) - ), - None => String::new(), - } - ); - println!( - " }}{}", - if i + 1 < report.warnings.len() { - "," - } else { - "" - } - ); - } - println!(" ]"); - println!("}}"); -} - -/// SERIALIZATION: SARIF (Static Analysis Results Interchange Format). -/// Enables native integration with GitHub Code Scanning and other tools. -/// Every check becomes a rule (`rsr/`) with a pass/fail result. -pub fn print_sarif_report(report: &ComplianceReport) { - println!("{{"); - println!(" \"$schema\": \"https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json\","); - println!(" \"version\": \"2.1.0\","); - println!(" \"runs\": [{{"); - println!(" \"tool\": {{"); - println!(" \"driver\": {{"); - println!(" \"name\": \"aletheia\","); - println!(" \"version\": \"{VERSION}\","); - println!(" \"informationUri\": \"https://github.com/hyperpolymath/aletheia\","); - println!(" \"rules\": ["); - for (i, check) in report.checks.iter().enumerate() { - println!(" {{"); - println!(" \"id\": \"rsr/{}\",", json_escape(&check.id)); - println!( - " \"name\": \"{}\",", - json_escape( - &check - .item - .replace(|c: char| !c.is_ascii_alphanumeric(), "_") - ) - ); - println!( - " \"shortDescription\": {{\"text\": \"{}\"}},", - json_escape(&format!("{}: {}", check.category, check.item)) - ); - println!( - " \"properties\": {{\"requiredFor\": \"{}\"}}", - check.required_for.name().to_lowercase() - ); - println!( - " }}{}", - if i + 1 < report.checks.len() { "," } else { "" } - ); - } - println!(" ]"); - println!(" }}"); - println!(" }},"); - println!(" \"results\": ["); - for (i, check) in report.checks.iter().enumerate() { - let (kind, level) = if check.passed { - ("pass", "none") - } else { - ("fail", "error") - }; - println!(" {{"); - println!(" \"ruleId\": \"rsr/{}\",", json_escape(&check.id)); - println!(" \"kind\": \"{kind}\","); - println!(" \"level\": \"{level}\","); - println!( - " \"message\": {{\"text\": \"{}\"}}", - json_escape(&match &check.suggestion { - Some(suggestion) if !check.passed => suggestion.clone(), - _ => format!("{}: {}", check.category, check.item), - }) - ); - println!( - " }}{}", - if i + 1 < report.checks.len() { "," } else { "" } - ); - } - println!(" ]"); - println!(" }}]"); - println!("}}"); -} - -/// SERIALIZATION: HTML report with embedded CSS (no external assets — -/// the report must render identically offline and air-gapped). -pub fn print_html_report(report: &ComplianceReport, level: ComplianceLevel) { - let compliant = report.compliant_at(level); - let verdict = if compliant { "ACHIEVED" } else { "NOT MET" }; - let verdict_class = if compliant { "pass" } else { "fail" }; - println!(""); - println!(""); - println!(""); - println!(""); - println!("Aletheia Compliance Report"); - println!(""); - println!(""); - println!(""); - println!("

Aletheia Compliance Report

"); - println!( - "

Repository: {}

", - html_escape(&report.repository_path.display().to_string()) - ); - println!("

Verified: {}

", format_timestamp(report.verified_at)); - println!( - "

Score: {}/{} checks passed ({:.1}%)

", - report.passed_count(), - report.total_count(), - report.score_pct() - ); - println!( - "

{}-level RSR compliance: {verdict}

", - level.name() - ); - for (category, checks) in group_by_category(report) { - println!("

{}

", html_escape(&category)); - println!(""); - for check in checks { - let (mark, class) = if check.passed { - ("✅", "pass") - } else { - ("❌", "fail") - }; - println!( - "", - html_escape(&check.item), - check.required_for.name() - ); - } - println!("
StatusCheckTier
{mark}{}{}
"); - } - if !report.warnings.is_empty() { - println!("

Warnings

"); - println!("
    "); - for warning in &report.warnings { - println!( - "
  • [{}] {}
  • ", - html_escape(&warning.level), - html_escape(&warning.message) - ); - } - println!("
"); - } - println!(""); - println!(""); -} - -/// SVG BADGE: shields-style `RSR compliance | passing/failing` badge. -pub fn print_badge(report: &ComplianceReport, level: ComplianceLevel) { - let passing = report.compliant_at(level) && !report.has_critical_warnings(); - let (status, color) = if passing { - ("passing", "#97ca00") - } else { - ("failing", "#e05d44") - }; - println!(""); - println!(" "); - println!(" "); - println!(" "); - println!(" "); - println!(" "); - println!(" "); - println!(" "); - println!( - " " - ); - println!(" RSR compliance"); - println!(" {status}"); - println!(" "); - println!(""); -} - -#[cfg(test)] -mod tests { - use super::*; - use std::path::PathBuf; - - fn sample_report() -> ComplianceReport { - let mut report = ComplianceReport::new(PathBuf::from("/tmp/sample")); - report.add_check( - "readme", - "Documentation", - "README.adoc (or README.md)", - true, - ComplianceLevel::Bronze, - None, - ); - report.add_check( - "changelog", - "Documentation", - "CHANGELOG.adoc (or .md)", - false, - ComplianceLevel::Silver, - Some("Add CHANGELOG.adoc; v2 2.1.6.".to_string()), - ); - report - } - - #[test] - fn test_is_leap_year() { - assert!(is_leap_year(2000)); - assert!(is_leap_year(2004)); - assert!(!is_leap_year(1900)); - assert!(!is_leap_year(2001)); - } - - #[test] - fn test_calculate_time() { - let (h, m, s) = calculate_time(0); - assert_eq!(h, 0); - assert_eq!(m, 0); - assert_eq!(s, 0); - - let (h, m, s) = calculate_time(3661); - assert_eq!(h, 1); - assert_eq!(m, 1); - assert_eq!(s, 1); - } - - #[test] - fn test_format_timestamp() { - let timestamp = format_timestamp(SystemTime::UNIX_EPOCH); - assert!(timestamp.contains("1970")); - } - - #[test] - fn test_format_timestamp_shape() { - // 2026-01-01T00:00:00Z == 1767225600. - let time = SystemTime::UNIX_EPOCH + std::time::Duration::from_secs(1767225600); - assert_eq!(format_timestamp(time), "2026-01-01T00:00:00Z"); - } - - #[test] - fn test_version_constant() { - assert!(!VERSION.is_empty()); - } - - #[test] - fn test_exit_codes() { - assert_eq!(exit_codes::SUCCESS, 0); - assert_eq!(exit_codes::COMPLIANCE_FAILED, 1); - assert_eq!(exit_codes::SECURITY_WARNING, 2); - assert_eq!(exit_codes::INVALID_PATH, 3); - assert_eq!(exit_codes::INVALID_ARGS, 4); - } - - #[test] - fn test_exit_code_for_policy() { - let report = sample_report(); - assert_eq!( - exit_code_for(&report, ComplianceLevel::Bronze), - exit_codes::SUCCESS - ); - assert_eq!( - exit_code_for(&report, ComplianceLevel::Silver), - exit_codes::COMPLIANCE_FAILED - ); - let mut critical = sample_report(); - critical.add_warning("critical", "escape".to_string(), None); - // Critical warnings outrank compliance failures. - assert_eq!( - exit_code_for(&critical, ComplianceLevel::Bronze), - exit_codes::SECURITY_WARNING - ); - } - - #[test] - fn test_group_by_category_is_stable() { - let report = sample_report(); - let groups = group_by_category(&report); - assert_eq!(groups.len(), 1); - assert_eq!(groups[0].0, "Documentation"); - assert_eq!(groups[0].1.len(), 2); - } - - #[test] - fn test_json_escape() { - assert_eq!(json_escape("a\"b\\c"), "a\\\"b\\\\c"); - assert_eq!(json_escape("line\ntab\t"), "line\\ntab\\t"); - } - - #[test] - fn test_html_escape() { - assert_eq!(html_escape("&\""), "<a>&""); - } -} diff --git a/aletheia/src/types.rs b/aletheia/src/types.rs deleted file mode 100644 index ac1825b..0000000 --- a/aletheia/src/types.rs +++ /dev/null @@ -1,246 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Aletheia — Core Domain Types and Models. -//! -//! This module defines the formal data structures used throughout the -//! compliance verification engine. It establishes the schema for -//! audit results, security warnings, and RSR compliance tiers. -//! -//! TIER VOCABULARY: [`ComplianceLevel`] follows the estate-wide RSR tier -//! ladder (Bronze → Silver → Gold → Platinum/Rhodium). The *normative* -//! definition of what each tier requires lives upstream in -//! `hyperpolymath/standards` (`0-canon/rsr/rsr-criteria-v2.a2ml`) and is -//! scored by the hypatia `rsr-conformance` oracle. Aletheia evaluates a -//! documented *local file-presence subset* of those criteria — see -//! `checks::SSOT_PROVENANCE`. It is a non-normative convenience checker -//! in the same class as the rhodium-pipeline rsr-certifier (criteria -//! file `[oracle]` section: "MAY consume this file but is not normative"). - -use std::path::PathBuf; -use std::time::SystemTime; - -/// COMPLIANCE TIERS: RSR assurance levels, lowest to highest. -/// -/// - **Bronze**: foundational documentation, security and build baselines. -/// - **Silver**: enhanced quality (provenance, pinning, machine-readable substrate). -/// - **Gold**: production readiness (release hygiene, hardened enforcement). -/// - **Platinum**: estate-rhodium exemplary tier (proofs, succession, signed history). -/// -/// All four variants are constructed: [`ComplianceLevel::all`] feeds the -/// per-tier summary, and [`ComplianceLevel::from_v2_tier`] maps the -/// upstream tier vocabulary (including `rhodium`, the v2 name for this -/// tier) onto it. -#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)] -pub enum ComplianceLevel { - Bronze, - Silver, - Gold, - Platinum, -} - -impl ComplianceLevel { - /// All levels, lowest to highest. Used by the per-tier score summary - /// so every tier is always reported, even with zero local checks. - pub fn all() -> [ComplianceLevel; 4] { - [ - ComplianceLevel::Bronze, - ComplianceLevel::Silver, - ComplianceLevel::Gold, - ComplianceLevel::Platinum, - ] - } - - /// Severity rank: higher tiers build on lower ones. - pub fn rank(self) -> u8 { - match self { - ComplianceLevel::Bronze => 0, - ComplianceLevel::Silver => 1, - ComplianceLevel::Gold => 2, - ComplianceLevel::Platinum => 3, - } - } - - /// Short display name, matching the RSR badge vocabulary. - pub fn name(self) -> &'static str { - match self { - ComplianceLevel::Bronze => "Bronze", - ComplianceLevel::Silver => "Silver", - ComplianceLevel::Gold => "Gold", - ComplianceLevel::Platinum => "Platinum", - } - } - - /// Map the upstream criteria-file tier vocabulary onto this enum. - /// - /// Accepts `bronze`, `silver`, `gold`, `platinum` and `rhodium` (the - /// v2 name for the exemplary tier). Case-insensitive. Returns `None` - /// for anything else so callers can fall back honestly instead of - /// guessing. - pub fn from_v2_tier(tier: &str) -> Option { - if tier.eq_ignore_ascii_case("bronze") { - Some(ComplianceLevel::Bronze) - } else if tier.eq_ignore_ascii_case("silver") { - Some(ComplianceLevel::Silver) - } else if tier.eq_ignore_ascii_case("gold") { - Some(ComplianceLevel::Gold) - } else if tier.eq_ignore_ascii_case("platinum") || tier.eq_ignore_ascii_case("rhodium") { - Some(ComplianceLevel::Platinum) - } else { - None - } - } -} - -/// CHECK RESULT: the outcome of a single deterministic verification item. -/// -/// `id` is a stable machine key (e.g. `readme`, `sha-pinned`) used by -/// `[checks]` config toggles, JSON output and SARIF `rsr/` rule ids. -/// `suggestion` carries the remediation hint shown in verbose output and -/// the "Fix Suggestions" section; it is `Some` exactly when `passed` is -/// false (a passing check has nothing to remediate). -#[derive(Debug, Clone)] -pub struct CheckResult { - pub id: String, - pub category: String, // e.g. "Documentation", "Security" - pub item: String, // e.g. "README.adoc (or README.md)" - pub passed: bool, - pub required_for: ComplianceLevel, - pub suggestion: Option, -} - -/// PATH SECURITY CHECK RESULT: validates symlink safety. -#[derive(Debug, Clone, Default)] -pub struct PathCheckResult { - pub exists: bool, - pub is_symlink: bool, - pub escapes_repo: bool, - pub target: Option, -} - -/// SECURITY WARNING: detailed information about a security concern. -/// -/// `path` is `Some` whenever the warning concerns a specific filesystem -/// entry (e.g. an escaping symlink) so reports can point at it. -#[derive(Debug, Clone)] -pub struct SecurityWarning { - pub level: String, - pub message: String, - pub path: Option, -} - -/// AUDIT REPORT: the consolidated results of a repository audit. -pub struct ComplianceReport { - pub repository_path: PathBuf, - pub verified_at: SystemTime, - pub checks: Vec, - pub warnings: Vec, -} - -impl ComplianceReport { - /// Create a new compliance report for a given repository path. - pub fn new(repo_path: PathBuf) -> Self { - ComplianceReport { - repository_path: repo_path, - verified_at: SystemTime::now(), - checks: Vec::new(), - warnings: Vec::new(), - } - } - - /// Add a check result to the report. - /// - /// `suggestion` should be `Some` when (and only when) `passed` is - /// false; see [`CheckResult::suggestion`]. - pub fn add_check( - &mut self, - id: &str, - category: &str, - item: &str, - passed: bool, - level: ComplianceLevel, - suggestion: Option, - ) { - self.checks.push(CheckResult { - id: id.to_string(), - category: category.to_string(), - item: item.to_string(), - passed, - required_for: level, - suggestion, - }); - } - - /// Add a security warning to the report. - pub fn add_warning(&mut self, level: &str, message: String, path: Option) { - self.warnings.push(SecurityWarning { - level: level.to_string(), - message, - path, - }); - } - - /// Number of passing checks. - pub fn passed_count(&self) -> usize { - self.checks.iter().filter(|c| c.passed).count() - } - - /// Total number of checks evaluated. - pub fn total_count(&self) -> usize { - self.checks.len() - } - - /// Score as a percentage of evaluated checks passed. - /// - /// Informational only: the exit policy is strict per-tier (see - /// [`ComplianceReport::compliant_at`]), not score-based, because the - /// local subset cannot reproduce the oracle's capability-gated - /// weighting. An empty report scores 100.0 (nothing failed). - pub fn score_pct(&self) -> f64 { - if self.checks.is_empty() { - 100.0 - } else { - self.passed_count() as f64 / self.checks.len() as f64 * 100.0 - } - } - - /// Per-tier `(level, passed, total)` triples, lowest tier first. - pub fn tier_counts(&self) -> Vec<(ComplianceLevel, usize, usize)> { - ComplianceLevel::all() - .iter() - .map(|level| { - let total = self - .checks - .iter() - .filter(|c| c.required_for == *level) - .count(); - let passed = self - .checks - .iter() - .filter(|c| c.required_for == *level && c.passed) - .count(); - (*level, passed, total) - }) - .collect() - } - - /// Strict tier compliance: every check required at or below `level` - /// must pass. Tiers build on each other, so Silver compliance implies - /// Bronze compliance. - pub fn compliant_at(&self, level: ComplianceLevel) -> bool { - let max_rank = level.rank(); - !self - .checks - .iter() - .any(|c| c.required_for.rank() <= max_rank && !c.passed) - } - - /// Whether any `critical`-level security warning was recorded. - pub fn has_critical_warnings(&self) -> bool { - self.warnings.iter().any(|w| w.level == "critical") - } - - /// Failing checks, for suggestions and SARIF results. - pub fn failing_checks(&self) -> Vec<&CheckResult> { - self.checks.iter().filter(|c| !c.passed).collect() - } -} diff --git a/aletheia/templates/ada/.editorconfig b/aletheia/templates/ada/.editorconfig deleted file mode 100644 index 8718995..0000000 --- a/aletheia/templates/ada/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# @@PROJECT_NAME@@ - Editor Configuration -# https://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 3 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.adoc] -trim_trailing_whitespace = false - -[Justfile] -indent_style = space -indent_size = 4 diff --git a/aletheia/templates/ada/.github/workflows/ci.yml b/aletheia/templates/ada/.github/workflows/ci.yml deleted file mode 100644 index 1cca4ca..0000000 --- a/aletheia/templates/ada/.github/workflows/ci.yml +++ /dev/null @@ -1,40 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -name: CI - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - check: - name: Build, test, lint (offline) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Install GNAT and gprbuild - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends gnat gprbuild - - - name: Build - run: gprbuild -p -P @@MOD_NAME@@.gpr - - - name: Test - run: | - gprbuild -p -P tests/tests.gpr - ./obj-tests/run_tests diff --git a/aletheia/templates/ada/.github/workflows/proof.yml b/aletheia/templates/ada/.github/workflows/proof.yml deleted file mode 100644 index eb09412..0000000 --- a/aletheia/templates/ada/.github/workflows/proof.yml +++ /dev/null @@ -1,92 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# SPARK proof gate. Separate from ci.yml on purpose: the offline Bronze job -# must stay fast and dependency-free, while proving needs gnatprove. -# -# This workflow is a real gate — `gnatprove` runs with --checks-as-errors (set -# in the project's Prove package), so an unproved check fails the job instead -# of exiting 0. It is deliberately *not* part of `just check`. -name: Proof (SPARK) - -on: - push: - branches: [main, master] - paths: - - 'src/**' - - 'tests/**' - - '*.gpr' - - 'Justfile' - - '.github/workflows/proof.yml' - pull_request: - branches: [main, master] - paths: - - 'src/**' - - 'tests/**' - - '*.gpr' - - 'Justfile' - - '.github/workflows/proof.yml' - workflow_dispatch: - -concurrency: - group: proof-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - spark: - name: Prove SPARK units (gnatprove) - runs-on: ubuntu-24.04 - timeout-minutes: 30 - steps: - # Pinned to a full SHA rather than relying on actions.lock: only two of - # the six templates ship this opt-in workflow, and a lock entry for a - # file the other four do not have would be noise in a shared file. - - name: Checkout - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1 - - # gnatprove is a frontend, not a toolchain: the archive below contains - # one binary, no compiler and no gprbuild. It needs GNAT and gprbuild to - # be present, exactly as ci.yml installs them - without this step the job - # dies at `gprbuild --version` in the next step. - - name: Install GNAT and gprbuild - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends gnat gprbuild - - # gnatprove ships its own Why3 and versions of Alt-Ergo/CVC5, so there is - # no solver version to drift. Pinned by URL and checksum: this artefact is - # a release asset, not a mutable tag. - - name: Install gnatprove 13.2.0 - run: | - set -euo pipefail - url="https://github.com/alire-project/GNAT-FSF-builds/releases/download/gnatprove-13.2.0-1/gnatprove-x86_64-linux-13.2.0-1.tar.gz" - curl -fsSL -o /tmp/gnatprove.tar.gz "$url" - echo "28fc3583d2364c1e10790fe258c408faffa42d7ff77bb81dc18d4907608f4017 /tmp/gnatprove.tar.gz" | sha256sum -c - - sudo mkdir -p /opt/gnatprove - sudo tar xzf /tmp/gnatprove.tar.gz -C /opt/gnatprove --strip-components=1 - echo "/opt/gnatprove/bin" >> "$GITHUB_PATH" - - - name: Show toolchain - run: | - gnatprove --version - gprbuild --version | head -1 - - # The GPR's Prove package carries --level=2 and --checks-as-errors, so - # this fails on any unproved check. `just proof` runs gnatprove on the - # same project; the explicit gprbuild first builds the object directory - # the prover reads. - - name: Prove - run: | - gprbuild -p -P @@MOD_NAME@@.gpr - gnatprove -P @@MOD_NAME@@.gpr - - - name: Proof summary - if: always() - run: | - if [ -f obj/gnatprove/gnatprove.out ]; then - tail -25 obj/gnatprove/gnatprove.out - else - echo "no proof summary produced" - fi diff --git a/aletheia/templates/ada/.gitignore b/aletheia/templates/ada/.gitignore deleted file mode 100644 index 48b1f25..0000000 --- a/aletheia/templates/ada/.gitignore +++ /dev/null @@ -1,24 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Build artefacts -/obj/ -/obj-tests/ -*.ali -*.o -*.bexch - -# gnatprove / SPARK proof artefacts -*.siv -*.mlw -*.spark -obj/gnatprove/ - -# Editors and OS -.DS_Store -.idea/ -.vscode/ -*.swp -*~ - -# Local environment -.env -.env.local diff --git a/aletheia/templates/ada/.machine_readable/rsr-profile.a2ml b/aletheia/templates/ada/.machine_readable/rsr-profile.a2ml deleted file mode 100644 index 111f25f..0000000 --- a/aletheia/templates/ada/.machine_readable/rsr-profile.a2ml +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for @@PROJECT_NAME@@. Declares what this repo -# carries so the capability gates compute the applicable criterion set. -[profile] -capabilities = ["ada", "cli", "docs"] - -[rationale] -ada = "true: GPR project, GNAT 14.2 / gprbuild" -cli = "true: src/main.adb produces an executable" -docs = "true: README + SECURITY + CONTRIBUTING + CODE_OF_CONDUCT + CHANGELOG" -no-library = "shared: the library units are part of the same GPR project" -no-container = "true: no Containerfile in the scaffold" diff --git a/aletheia/templates/ada/.tool-versions b/aletheia/templates/ada/.tool-versions deleted file mode 100644 index dbf45d2..0000000 --- a/aletheia/templates/ada/.tool-versions +++ /dev/null @@ -1,3 +0,0 @@ -# Toolchain pins, asdf/mise compatible. -gnat 14.2.0 -gprbuild 2025.0.0 diff --git a/aletheia/templates/ada/@@MOD_NAME@@.gpr b/aletheia/templates/ada/@@MOD_NAME@@.gpr deleted file mode 100644 index e6e837c..0000000 --- a/aletheia/templates/ada/@@MOD_NAME@@.gpr +++ /dev/null @@ -1,37 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- GPR project for @@PROJECT_NAME@@. --- --- Plain GPR rather than Alire: no crate index, nothing to fetch, so the --- build works with no network at all. --- --- The switches are the static-analysis gate for this language: --- -gnatwa all warnings on --- -gnatwe warnings are errors (a warning fails the build) --- -gnata assertions and preconditions checked at run time -project @@MOD_ADA@@ is - for Source_Dirs use ("src"); - for Object_Dir use "obj"; - for Exec_Dir use "obj"; - for Main use ("main.adb"); - - -- -gnat2022 Big_Integers (used by the contracts) is an Ada 2022 unit - package Compiler is - for Default_Switches ("Ada") use ("-gnat2022", "-gnatwa", "-gnatwe", "-gnata"); - end Compiler; - - package Builder is - -- Name the artefact after the project, not after main.adb. - for Executable ("main.adb") use "@@PROJECT_NAME@@"; - end Builder; - - -- Default proof settings, so a bare `gnatprove -P @@MOD_NAME@@.gpr` - -- already means "prove everything, and treat unproved checks as - -- failure". `just proof` relies on this. - package Prove is - -- --level=2 prove absence of run-time errors as well - -- --checks-as-errors without this gnatprove still exits 0 when a - -- check is unproved, which would make the gate - -- decorative. It is what makes `just proof` fail. - for Proof_Switches ("Ada") use ("--level=2", "--checks-as-errors"); - end Prove; -end @@MOD_ADA@@; diff --git a/aletheia/templates/ada/Justfile b/aletheia/templates/ada/Justfile deleted file mode 100644 index c534c2f..0000000 --- a/aletheia/templates/ada/Justfile +++ /dev/null @@ -1,50 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Justfile — build automation for @@PROJECT_NAME@@. -# See: https://github.com/casey/just -# -# Every recipe here is offline: this project has no external dependencies, -# so nothing is fetched at build time. Recipes fail loudly — a recipe that -# echoes a message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). - -default: - @just --list - -# Build the executable into obj/ -build: - gprbuild -p -P @@MOD_NAME@@.gpr - -# Run the program; pass arguments after the recipe name -run *ARGS: - ./obj/@@PROJECT_NAME@@ {{ARGS}} - -# Build and run the test executable -test: - gprbuild -p -P tests/tests.gpr - ./obj-tests/run_tests - -# The static-analysis gate for this language. The switches live in the GPR -# files (`-gnatwa -gnatwe`: all warnings on, warnings as errors), so a -# warning fails the build rather than scrolling past. -lint: - gprbuild -p -P @@MOD_NAME@@.gpr - gprbuild -p -P tests/tests.gpr - -# --- SPARK deductive verification (opt-in) ---------------------------- -# Needs gnatprove. The default build never requires it — `gnatprove` only -# reads the sources and the GPR's Prove package (--level=2), so `just -# check` stays a plain GNAT build. See README.adoc. - -# Statically prove every SPARK unit. Exits non-zero on any unproved check. -proof: - gnatprove -P @@MOD_NAME@@.gpr - -# Remove gnatprove artefacts (obj/gnatprove, *.siv/*.mlw) -proof-clean: - gnatprove -P @@MOD_NAME@@.gpr --clean - -# Verify RSR compliance using the estate checker -verify: - aletheia . - -# Everything the CI gate runs, in the same order -check: build test lint diff --git a/aletheia/templates/ada/README.adoc b/aletheia/templates/ada/README.adoc deleted file mode 100644 index d3d40cb..0000000 --- a/aletheia/templates/ada/README.adoc +++ /dev/null @@ -1,118 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= @@PROJECT_NAME@@ -:toc: -:icons: font - -____ -@@PROJECT_DESCRIPTION@@ -____ - -== Quick Start - -[source,bash] ----- -# Build (offline — nothing is downloaded) -just build - -# Test -just test - -# Verify RSR compliance -just verify ----- - -This project is *standalone by construction*: the scaffold fetches nothing, -the build has no external dependencies, and the licence texts ship in-tree -under `+LICENSES/+`. - -== RSR Compliance - -[cols="1,3"] -|=== -|Bronze |Documentation, security policy, SPDX headers, CI, licence classification -|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` -|Gold |No silent-skip recipes -|=== - -Verify with the estate's own checker: - -[source,bash] ----- -aletheia . ----- - -== Language: @@LANG_DISPLAY@@ - -@@LANG_POLICY@@ - -== Verification: SPARK - -The core package (`+src/@@MOD_NAME@@.ads+`, `+src/@@MOD_NAME@@.adb+`) is in the -SPARK subset — it declares `+pragma SPARK_Mode (On);+` — and its contracts are -*statically proved*, not merely checked at run time: - -[source,ada] ----- -function Clamp (Value, Lo, Hi : U32) return U32 - with Pre => Lo <= Hi, - Post => Clamp'Result in Lo .. Hi; - -function Midpoint (A, B : U32) return U32 - with Pre => A <= B, - Post => Midpoint'Result in A .. B - and then BI (Midpoint'Result) = (BI (A) + BI (B)) / 2; ----- - -`+just proof+` runs `gnatprove` at proof level 2 (contracts *and* absence of -run-time errors) and passes `--checks-as-errors`, so an unproved check fails -the recipe. Without that switch `gnatprove` still exits `0` on an unproved -check, which would make the gate decorative. - -[source,bash] ----- -just proof # prove every SPARK unit; non-zero exit on anything unproved -just proof-clean # remove gnatprove artefacts ----- - -The command-line entry point (`+src/main.adb+`) is deliberately -`+pragma SPARK_Mode (Off);+`: `Ada.Text_IO`, exceptions and `'Value`/`'Image` -are outside the SPARK subset. gnatprove skips it rather than pretending to -verify it. The logic it calls is the part that is proved. - -== Documentation -== Documentation - -* link:SECURITY.adoc[Security Policy] — vulnerability disclosure -* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute -* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards -* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions -* link:CHANGELOG.adoc[Changelog] — version history - -== Layout - -.... -. -├── Justfile # build automation (capital J — v2 shape) -├── LICENSE # licence statement -├── LICENSES/ # full licence texts (REUSE style) -├── src/ # source (layout follows the language's conventions) -├── .github/workflows/ # CI + estate gates -├── .machine_readable/ # machine-readable metadata -└── .well-known/ # security.txt, ai.txt, humans.txt -.... - -== Contributing - -See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. - -== License - -Code is licensed under the Mozilla Public License, version 2.0 -(`+MPL-2.0+`). Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). - -See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. - -''''' - -_Created from the aletheia v2 Bronze template._ diff --git a/aletheia/templates/ada/src/@@MOD_NAME@@.adb b/aletheia/templates/ada/src/@@MOD_NAME@@.adb deleted file mode 100644 index f01d409..0000000 --- a/aletheia/templates/ada/src/@@MOD_NAME@@.adb +++ /dev/null @@ -1,31 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 -pragma SPARK_Mode (On); - -package body @@MOD_ADA@@ is - - function Clamp (Value, Lo, Hi : U32) return U32 is - Result : U32 := Value; - begin - if Result < Lo then - Result := Lo; - end if; - if Result > Hi then - Result := Hi; - end if; - return Result; - end Clamp; - - function Midpoint (A, B : U32) return U32 is - D : constant U32 := B - A; - begin - -- Stepping stones for the provers: modular subtraction and division - -- agree with their exact-integer counterparts on this domain, and - -- the final addition cannot wrap because the result is at most B. - pragma Assert (BI (D) = BI (B) - BI (A)); - pragma Assert (BI (D / 2) = BI (D) / 2); - pragma Assert (BI (A + D / 2) = BI (A) + BI (D) / 2); - pragma Assert (BI (A) + (BI (B) - BI (A)) / 2 = (BI (A) + BI (B)) / 2); - return A + D / 2; - end Midpoint; - -end @@MOD_ADA@@; diff --git a/aletheia/templates/ada/src/@@MOD_NAME@@.ads b/aletheia/templates/ada/src/@@MOD_NAME@@.ads deleted file mode 100644 index 03c577d..0000000 --- a/aletheia/templates/ada/src/@@MOD_NAME@@.ads +++ /dev/null @@ -1,50 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- Core library for @@PROJECT_NAME@@. --- --- This package is in the SPARK subset: `SPARK_Mode (On)` below means --- `gnatprove` analyses it, and every contract here is *statically proved*, --- not merely checked at run time. See README.adoc for the proof recipe. --- --- Replace these sample subprograms with your own. Adding a subprogram here --- adds it to gnatprove's remit automatically. - -pragma SPARK_Mode (On); - -with Ada.Numerics.Big_Numbers.Big_Integers; -use Ada.Numerics.Big_Numbers.Big_Integers; - -package @@MOD_ADA@@ is - - -- Unsigned 32-bit. Modular arithmetic wraps rather than raising, which - -- makes the shift/divide forms below total. - type U32 is mod 2 ** 32; - - -- Exact-integer view of U32. Contracts must reason about the - -- *mathematical* half-sum; U32 arithmetic would wrap. This is the - -- SPARK idiom for that, and the generated functions are ghost. - package U32_Big is new Unsigned_Conversions (U32); - - -- Shorthand so the contracts below read like specifications. - function BI (X : U32) return Big_Integer is (U32_Big.To_Big_Integer (X)) - with Ghost; - - -- Clamp Value into the inclusive range Lo .. Hi. - -- - -- Proved: given Lo <= Hi, the result is always inside Lo .. Hi. - function Clamp (Value, Lo, Hi : U32) return U32 - with Pre => Lo <= Hi, - Post => Clamp'Result in Lo .. Hi; - - -- Overflow-free midpoint of A and B, rounded towards zero. - -- - -- The naive (A + B) / 2 wraps for large inputs; this form cannot, - -- because it never materialises the sum. - -- - -- Proved: given A <= B, the result lies in A .. B and equals the exact - -- half-sum (A + B) / 2 as a mathematical integer. - function Midpoint (A, B : U32) return U32 - with Pre => A <= B, - Post => Midpoint'Result in A .. B - and then BI (Midpoint'Result) = (BI (A) + BI (B)) / 2; - -end @@MOD_ADA@@; diff --git a/aletheia/templates/ada/src/main.adb b/aletheia/templates/ada/src/main.adb deleted file mode 100644 index b639a37..0000000 --- a/aletheia/templates/ada/src/main.adb +++ /dev/null @@ -1,82 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- @@PROJECT_NAME@@ — command-line entry point. --- --- SPARK_Mode is Off here on purpose: this unit is the I/O boundary, and --- Ada.Text_IO, exceptions and 'Value/'Image are all outside the SPARK --- subset. The logic it calls lives in @@MOD_NAME@@.ads, which is SPARK and --- fully proved. gnatprove skips this file rather than pretending to verify --- it — see README.adoc. -pragma SPARK_Mode (Off); - -with Ada.Command_Line; -with Ada.Text_IO; -with @@MOD_ADA@@; - -procedure Main is - use Ada.Command_Line; - use Ada.Text_IO; - use @@MOD_ADA@@; - - Usage : constant String := - "@@PROJECT_NAME@@ @@VERSION@@" & ASCII.LF & - "" & ASCII.LF & - "usage:" & ASCII.LF & - " @@PROJECT_NAME@@ clamp clamp a value into a range" & ASCII.LF & - " @@PROJECT_NAME@@ mid midpoint, rounded down (a <= b)" & ASCII.LF & - " @@PROJECT_NAME@@ --help show this message" & ASCII.LF & - "" & ASCII.LF & - "All arguments are unsigned 32-bit integers."; - - procedure Unrecognised is - begin - Put_Line (Standard_Error, "error: unrecognised arguments"); - New_Line (Standard_Error); - Put_Line (Standard_Error, Usage); - Set_Exit_Status (Failure); - end Unrecognised; - -begin - if Argument_Count = 0 or else Argument (1) = "--help" or else Argument (1) = "-h" then - Put_Line (Usage); - return; - end if; - - if Argument_Count = 4 and then Argument (1) = "clamp" then - declare - Value : constant U32 := U32'Value (Argument (2)); - Lo : constant U32 := U32'Value (Argument (3)); - Hi : constant U32 := U32'Value (Argument (4)); - begin - if Lo > Hi then - Unrecognised; - return; - end if; - Put_Line (U32'Image (Clamp (Value, Lo, Hi))); - return; - exception - when Constraint_Error => - Unrecognised; - return; - end; - end if; - - if Argument_Count = 3 and then Argument (1) = "mid" then - declare - A : constant U32 := U32'Value (Argument (2)); - B : constant U32 := U32'Value (Argument (3)); - begin - if A > B then - Unrecognised; - return; - end if; - Put_Line (U32'Image (Midpoint (A, B))); - return; - exception - when Constraint_Error => - Unrecognised; - return; - end; - end if; - - Unrecognised; -end Main; diff --git a/aletheia/templates/ada/tests/run_tests.adb b/aletheia/templates/ada/tests/run_tests.adb deleted file mode 100644 index da1913a..0000000 --- a/aletheia/templates/ada/tests/run_tests.adb +++ /dev/null @@ -1,64 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- Test runner for @@PROJECT_NAME@@. --- --- Dependency-free by design: no AUnit, just a counter and a non-zero exit --- status on failure, so the suite needs nothing beyond the GNAT runtime. --- --- These are *runtime* tests. They complement, and do not replace, the --- static proof in @@MOD_NAME@@.ads — see README.adoc. -with Ada.Command_Line; -with Ada.Text_IO; -with @@MOD_ADA@@; - -procedure Run_Tests is - use Ada.Text_IO; - use @@MOD_ADA@@; - - Failures : Natural := 0; - - procedure Check (Label : String; Condition : Boolean) is - begin - if not Condition then - Put_Line ("FAIL: " & Label); - Failures := Failures + 1; - end if; - end Check; - -begin - -- Clamp: below, inside and above the range - Check ("clamp keeps an in-range value", Clamp (5, 0, 10) = 5); - Check ("clamp lifts a low value", Clamp (0, 1, 10) = 1); - Check ("clamp drops a high value", Clamp (99, 0, 10) = 10); - Check ("clamp handles a degenerate range", Clamp (7, 7, 7) = 7); - - -- Clamp: idempotent, and always inside the range - for Value in U32 range 0 .. 128 loop - declare - Once : constant U32 := Clamp (Value, 10, 100); - begin - Check ("clamp is idempotent", Clamp (Once, 10, 100) = Once); - Check ("clamp result is in range", Once >= 10 and then Once <= 100); - end; - end loop; - - -- Midpoint: agrees with the naive form wherever that form is safe - for A in U32 range 0 .. 63 loop - for B in U32 range A .. 63 loop - Check ("midpoint matches naive", Midpoint (A, B) = (A + B) / 2); - end loop; - end loop; - - -- Midpoint: stays inside the inputs, and cannot overflow - Check ("midpoint bounded (0, max)", Midpoint (0, U32'Last) = U32'Last / 2); - Check ("midpoint bounded (max, max)", Midpoint (U32'Last, U32'Last) = U32'Last); - Check ("midpoint (8, 11)", Midpoint (8, 11) = 9); - Check ("midpoint (7, 9)", Midpoint (7, 9) = 8); - Check ("midpoint (0, 0)", Midpoint (0, 0) = 0); - - if Failures = 0 then - Put_Line ("All tests passed."); - else - Put_Line (Natural'Image (Failures) & " test(s) failed."); - Ada.Command_Line.Set_Exit_Status (Ada.Command_Line.Failure); - end if; -end Run_Tests; diff --git a/aletheia/templates/ada/tests/tests.gpr b/aletheia/templates/ada/tests/tests.gpr deleted file mode 100644 index 2c2fcc9..0000000 --- a/aletheia/templates/ada/tests/tests.gpr +++ /dev/null @@ -1,13 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- Test project for @@PROJECT_NAME@@. Compiles the library sources --- alongside the test runner, so the tests exercise the real units. -project Tests is - for Source_Dirs use ("../src", "."); - for Object_Dir use "../obj-tests"; - for Exec_Dir use "../obj-tests"; - for Main use ("run_tests.adb"); - - package Compiler is - for Default_Switches ("Ada") use ("-gnat2022", "-gnatwa", "-gnatwe", "-gnata"); - end Compiler; -end Tests; diff --git a/aletheia/templates/agda/.editorconfig b/aletheia/templates/agda/.editorconfig deleted file mode 100644 index 7520e0f..0000000 --- a/aletheia/templates/agda/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# @@PROJECT_NAME@@ - Editor Configuration -# https://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.adoc] -trim_trailing_whitespace = false - -[Justfile] -indent_style = space -indent_size = 4 diff --git a/aletheia/templates/agda/.github/workflows/ci.yml b/aletheia/templates/agda/.github/workflows/ci.yml deleted file mode 100644 index 134fb0a..0000000 --- a/aletheia/templates/agda/.github/workflows/ci.yml +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -name: CI - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - check: - name: Build, test, lint (offline) - runs-on: ubuntu-latest - timeout-minutes: 20 - env: - # Agda source is Unicode; pin the locale so the gate is deterministic. - LC_ALL: C.UTF-8 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Install Agda - run: | - sudo apt-get update - sudo apt-get install -y --no-install-recommends agda - - - name: Typecheck (this is the build) - run: agda src/@@MOD_CAMEL@@.agda - - - name: Typecheck the proofs - run: agda src/Properties.agda diff --git a/aletheia/templates/agda/.gitignore b/aletheia/templates/agda/.gitignore deleted file mode 100644 index 88e6819..0000000 --- a/aletheia/templates/agda/.gitignore +++ /dev/null @@ -1,4 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -/_build/ -/MAlonzo/ -*.agdai diff --git a/aletheia/templates/agda/.machine_readable/rsr-profile.a2ml b/aletheia/templates/agda/.machine_readable/rsr-profile.a2ml deleted file mode 100644 index a08296f..0000000 --- a/aletheia/templates/agda/.machine_readable/rsr-profile.a2ml +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for @@PROJECT_NAME@@. Declares what this repo -# carries so the capability gates compute the applicable criterion set. -[profile] -capabilities = ["agda", "proofs", "docs"] - -[rationale] -agda = "true: .agda-lib project, Agda 2.6.4.3" -proofs = "true: src/ contains machine-checked proofs, not tests" -docs = "true: README + SECURITY + CONTRIBUTING + CODE_OF_CONDUCT + CHANGELOG" -no-library = "shared: modules are proof library, not published as a package" -no-container = "true: no Containerfile in the scaffold" diff --git a/aletheia/templates/agda/.tool-versions b/aletheia/templates/agda/.tool-versions deleted file mode 100644 index f509ae3..0000000 --- a/aletheia/templates/agda/.tool-versions +++ /dev/null @@ -1,2 +0,0 @@ -# Toolchain pins, asdf/mise compatible. -agda 2.6.4.3 diff --git a/aletheia/templates/agda/@@PROJECT_NAME@@.agda-lib b/aletheia/templates/agda/@@PROJECT_NAME@@.agda-lib deleted file mode 100644 index d947beb..0000000 --- a/aletheia/templates/agda/@@PROJECT_NAME@@.agda-lib +++ /dev/null @@ -1,2 +0,0 @@ -name: @@PROJECT_NAME@@ -include: src diff --git a/aletheia/templates/agda/Justfile b/aletheia/templates/agda/Justfile deleted file mode 100644 index 6a5b299..0000000 --- a/aletheia/templates/agda/Justfile +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Justfile — build automation for @@PROJECT_NAME@@. -# See: https://github.com/casey/just -# -# Every recipe here is offline: this project has no external dependencies, -# so nothing is fetched at build time. Recipes fail loudly — a recipe that -# echoes a message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). - -# Agda source is written in Unicode (≡, ∀, ×, ˡ). Without a UTF-8 locale -# the checker cannot read its own files and fails with a locale error -# rather than a type error, so pin it here rather than leave it to the -# ambient environment. -export LC_ALL := "C.UTF-8" - -default: - @just --list - -# Typecheck the main module. In Agda, typechecking IS the build. -build: - agda src/@@MOD_CAMEL@@.agda - -# NOTE: there is no `run` recipe. This is a proof library, not a program: -# there is no executable to run, and inventing one would be a fake gate. -# Add a `main : IO ⊤` module and a compile recipe if you need one. - -# Typecheck the proof suite. There is no separate test runner: a proof -# that does not typecheck fails, which is the strongest form of "test". -test: - agda src/Properties.agda - -# Verify RSR compliance using the estate checker -verify: - aletheia . - -# Everything the CI gate runs, in the same order -check: build test diff --git a/aletheia/templates/agda/README.adoc b/aletheia/templates/agda/README.adoc deleted file mode 100644 index 1e89576..0000000 --- a/aletheia/templates/agda/README.adoc +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= @@PROJECT_NAME@@ -:toc: -:icons: font - -____ -@@PROJECT_DESCRIPTION@@ -____ - -== Quick Start - -[source,bash] ----- -# Build (offline — nothing is downloaded) -just build - -# Test -just test - -# Verify RSR compliance -just verify ----- - -This project is *standalone by construction*: the scaffold fetches nothing, -the build has no external dependencies, and the licence texts ship in-tree -under `+LICENSES/+`. - -== RSR Compliance - -[cols="1,3"] -|=== -|Bronze |Documentation, security policy, SPDX headers, CI, licence classification -|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` -|Gold |No silent-skip recipes -|=== - -Verify with the estate's own checker: - -[source,bash] ----- -aletheia . ----- - -== Language: @@LANG_DISPLAY@@ - -@@LANG_POLICY@@ - -== Documentation - -* link:SECURITY.adoc[Security Policy] — vulnerability disclosure -* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute -* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards -* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions -* link:CHANGELOG.adoc[Changelog] — version history - -== Layout - -.... -. -├── Justfile # build automation (capital J — v2 shape) -├── LICENSE # licence statement -├── LICENSES/ # full licence texts (REUSE style) -├── src/ # source (layout follows the language's conventions) -├── .github/workflows/ # CI + estate gates -├── .machine_readable/ # machine-readable metadata -└── .well-known/ # security.txt, ai.txt, humans.txt -.... - -== Contributing - -See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. - -== License - -Code is licensed under the Mozilla Public License, version 2.0 -(`+MPL-2.0+`). Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). - -See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. - -''''' - -_Created from the aletheia v2 Bronze template._ diff --git a/aletheia/templates/agda/src/@@MOD_CAMEL@@.agda b/aletheia/templates/agda/src/@@MOD_CAMEL@@.agda deleted file mode 100644 index 5e81fda..0000000 --- a/aletheia/templates/agda/src/@@MOD_CAMEL@@.agda +++ /dev/null @@ -1,52 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- Core proofs for @@PROJECT_NAME@@. --- --- Self-contained by design: only Agda.Builtin is imported, so there is no --- standard-library dependency to fetch. Replace these with your own --- definitions and theorems. -module @@MOD_CAMEL@@ where - -open import Agda.Builtin.Nat using (Nat; zero; suc; _+_) -open import Agda.Builtin.Equality using (_≡_; refl) - ------------------------------------------------------------------------- --- Equality helpers --- --- Agda.Builtin.Equality ships only _≡_ and refl, and we do not want a --- stdlib dependency just for these two. Every argument is annotated with --- its type: `m ≡ n` with untyped `m`/`n` leaves the type index of _≡_ --- ambiguous, and Agda reports unsolved metas rather than guessing. ------------------------------------------------------------------------- - -sym : ∀ {m n : Nat} → m ≡ n → n ≡ m -sym refl = refl - -trans : ∀ {l m n : Nat} → l ≡ m → m ≡ n → l ≡ n -trans refl refl = refl - -cong-suc : ∀ {m n : Nat} → m ≡ n → suc m ≡ suc n -cong-suc refl = refl - ------------------------------------------------------------------------- --- Theorems about addition ------------------------------------------------------------------------- - --- zero is a left identity for _+_. Holds by computation — no induction --- needed — so `refl` is already a complete proof. -+-identityˡ : ∀ (n : Nat) → zero + n ≡ n -+-identityˡ n = refl - --- suc commutes with _+_ on the right. This needs induction, because _+_ --- recurses on its *first* argument. -suc-+ : ∀ (m n : Nat) → suc (m + n) ≡ m + suc n -suc-+ zero n = refl -suc-+ (suc m) n = cong-suc (suc-+ m n) - --- zero is a right identity for _+_. Also inductive, for the same reason. -+-identityʳ : ∀ (n : Nat) → n + zero ≡ n -+-identityʳ zero = refl -+-identityʳ (suc n) = cong-suc (+-identityʳ n) - --- A worked use of all three: zero commutes through addition. -+-zero-comm : ∀ (n : Nat) → n + zero ≡ zero + n -+-zero-comm n = trans (+-identityʳ n) (sym (+-identityˡ n)) diff --git a/aletheia/templates/agda/src/Properties.agda b/aletheia/templates/agda/src/Properties.agda deleted file mode 100644 index 2f2f290..0000000 --- a/aletheia/templates/agda/src/Properties.agda +++ /dev/null @@ -1,29 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- Derived results for @@PROJECT_NAME@@. --- --- This module is a *consumer* of the core library: it proves new facts --- from the exported lemmas, so a regression in the core shows up here as --- a typecheck failure rather than passing unnoticed. -module Properties where - -open import Agda.Builtin.Nat using (Nat; zero; suc; _+_) -open import Agda.Builtin.Equality using (_≡_) - --- Pairs. Agda.Builtin does not export _×_, so declare it here rather than --- pull in the standard library for one constructor. -data _×_ (A B : Set) : Set where - _,_ : A → B → A × B - -open import @@MOD_CAMEL@@ using (sym; trans; +-identityˡ; +-identityʳ; suc-+) - --- zero is an identity for _+_ on both sides at once. -+-zero-identity : ∀ (n : Nat) → ((n + zero) ≡ n) × ((zero + n) ≡ n) -+-zero-identity n = (+-identityʳ n , +-identityˡ n) - --- Adding zero on the right, twice, is still adding zero once. -+-zero-twice : ∀ (n : Nat) → (n + zero) + zero ≡ n -+-zero-twice n = trans (+-identityʳ (n + zero)) (+-identityʳ n) - --- The general suc-+ lemma, instantiated at m = suc zero. -suc-+-concrete : ∀ (n : Nat) → suc (suc zero + n) ≡ suc zero + suc n -suc-+-concrete n = suc-+ (suc zero) n diff --git a/aletheia/templates/common/.gitattributes b/aletheia/templates/common/.gitattributes deleted file mode 100644 index c74ab88..0000000 --- a/aletheia/templates/common/.gitattributes +++ /dev/null @@ -1,11 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -* text=auto eol=lf - -@@LANG_GITATTR_LINE@@ -*.adoc text eol=lf -*.a2ml text eol=lf -*.yml text eol=lf -*.yaml text eol=lf -*.toml text eol=lf - -LICENSES/* text eol=lf diff --git a/aletheia/templates/common/.github/workflows/actions.lock b/aletheia/templates/common/.github/workflows/actions.lock deleted file mode 100644 index 523511c..0000000 --- a/aletheia/templates/common/.github/workflows/actions.lock +++ /dev/null @@ -1,9 +0,0 @@ -# This file is machine-generated by `gh actions-lock`. -# Do not edit by hand; run `gh actions-lock` to update. -# Docs: https://gh.io/actions-lockfile -version: 'v0.0.2' -workflows: - '.github/workflows/ci.yml': - - 'actions/checkout@v7.0.1' - '.github/workflows/governance.yml': [] - '.github/workflows/hypatia-scan.yml': [] diff --git a/aletheia/templates/common/.github/workflows/governance.yml b/aletheia/templates/common/.github/workflows/governance.yml deleted file mode 100644 index 5c808fe..0000000 --- a/aletheia/templates/common/.github/workflows/governance.yml +++ /dev/null @@ -1,18 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -name: Governance - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -permissions: - actions: read - contents: read - -jobs: - governance: - uses: hyperpolymath/standards/.github/workflows/governance-reusable.yml@6b38eb50104901e2fec80f9455a972bc3eced813 diff --git a/aletheia/templates/common/.github/workflows/hypatia-scan.yml b/aletheia/templates/common/.github/workflows/hypatia-scan.yml deleted file mode 100644 index f839298..0000000 --- a/aletheia/templates/common/.github/workflows/hypatia-scan.yml +++ /dev/null @@ -1,21 +0,0 @@ -# This workflow is managed by gh actions-lock. -# SPDX-License-Identifier: MPL-2.0 -name: Hypatia Security Scan - -on: - push: - branches: [main, master, develop] - pull_request: - branches: [main, master] - schedule: - - cron: '0 0 * * 0' - workflow_dispatch: - -permissions: - actions: read - contents: read - security-events: write - -jobs: - hypatia: - uses: hyperpolymath/standards/.github/workflows/hypatia-scan-reusable.yml@84355587cb2a1f86e6882de83514a32db2646e7a diff --git a/aletheia/templates/common/.well-known/ai.txt b/aletheia/templates/common/.well-known/ai.txt deleted file mode 100644 index d30fbd9..0000000 --- a/aletheia/templates/common/.well-known/ai.txt +++ /dev/null @@ -1,15 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# ai.txt - AI interaction policy - -User-Agent: * -Disallow-Training: yes -Disallow-Summarization: no -Disallow-Generation: yes - -# This project's code is licensed under MPL-2.0. -# AI agents may read and analyse this code to assist contributors. -# AI agents must NOT use this code for model training without explicit consent. -# -# Agent integration instructions: -# 0-AI-MANIFEST.a2ml (universal AI entry point) -# .machine_readable/ (structured project state) diff --git a/aletheia/templates/common/.well-known/humans.txt b/aletheia/templates/common/.well-known/humans.txt deleted file mode 100644 index 75d2bc2..0000000 --- a/aletheia/templates/common/.well-known/humans.txt +++ /dev/null @@ -1,13 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# humanstxt.org - -/* TEAM */ -Maintainer: @@AUTHOR_NAME@@ -Contact: @@AUTHOR_EMAIL@@ - -/* SITE */ -Last update: @@DATE@@ -Standards: RSR (Rhodium Standard Repository) -Language: Rust/Creusot -License: MPL-2.0 -Tools: just, cargo diff --git a/aletheia/templates/common/.well-known/security.txt b/aletheia/templates/common/.well-known/security.txt deleted file mode 100644 index 8ce5343..0000000 --- a/aletheia/templates/common/.well-known/security.txt +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RFC 9116 - security.txt -# https://securitytxt.org/ - -Contact: mailto:@@SECURITY_CONTACT@@ -Expires: @@SECURITY_EXPIRES@@ -Preferred-Languages: en -Canonical: @@REPO_URL@@/blob/main/.well-known/security.txt -Policy: @@REPO_URL@@/blob/main/SECURITY.adoc diff --git a/aletheia/templates/common/0-AI-MANIFEST.a2ml b/aletheia/templates/common/0-AI-MANIFEST.a2ml deleted file mode 100644 index f0a203c..0000000 --- a/aletheia/templates/common/0-AI-MANIFEST.a2ml +++ /dev/null @@ -1,52 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# @@PROJECT_NAME@@ — universal AI agent entry point. - -# THIS FILE MUST BE READ FIRST BY ALL AI AGENTS - -## What Is This? - -The AI manifest for **@@PROJECT_NAME@@**. It declares canonical file -locations and the invariants an agent must not violate. - -## Canonical Locations - -### Machine-Readable Metadata: `.machine_readable/` ONLY - -* `.machine_readable/rsr-profile.a2ml` — capability declaration driving the - applicable RSR criterion set - -If any machine-readable metadata appears in the repository root, that is an -error: the root must contain only the agent front door -(`0-AI-MANIFEST.a2ml`). - -### Agent Instructions - -* `0-AI-MANIFEST.a2ml` — THIS FILE (universal entry point) -* `.claude/CLAUDE.md` — Claude-specific patterns (if present) - -## Core Invariants - -1. *No metadata duplication* — `.machine_readable/` is the single source of truth. -2. *Standalone by construction* — @@STANDALONE_INVARIANT@@ -3. *Dependency budget* — @@DEP_INVARIANT@@ -4. *Language policy* — @@LANG_INVARIANT@@ -5. *No fake gates* — a recipe that echoes a message and exits 0 is a - violation. Fail loudly. -6. *SPDX headers* — every source file carries an `SPDX-License-Identifier` - within its first ten lines. Code is `MPL-2.0`; docs are `CC-BY-SA-4.0`. -7. *Licence consistency* — MPL-2.0 across the repository. - -## Session Startup Checklist - -* Read THIS file first. -* Read `.machine_readable/rsr-profile.a2ml` for declared capabilities. -* Run `just check` to confirm the tree is green before changing anything. -* State understanding of canonical locations before writing files. - -## Attestation - -After reading this file, state: - -**"I have read the AI manifest. Machine-readable metadata lives in -`.machine_readable/` only, the build is standalone, and @@LANG_DISPLAY@@ -means what the estate language policy says it means."** diff --git a/aletheia/templates/common/CHANGELOG.adoc b/aletheia/templates/common/CHANGELOG.adoc deleted file mode 100644 index ae8a126..0000000 --- a/aletheia/templates/common/CHANGELOG.adoc +++ /dev/null @@ -1,19 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= Changelog - -All notable changes to this project are documented in this file. - -The format is based on https://keepachangelog.com/[Keep a Changelog], and -this project adheres to https://semver.org/[Semantic Versioning]. - -== [Unreleased] - -=== Added - -* Initial project structure. - -== [0.1.0] - @@DATE@@ - -=== Added - -* Initial release. diff --git a/aletheia/templates/common/CODE_OF_CONDUCT.adoc b/aletheia/templates/common/CODE_OF_CONDUCT.adoc deleted file mode 100644 index bd0ca64..0000000 --- a/aletheia/templates/common/CODE_OF_CONDUCT.adoc +++ /dev/null @@ -1,36 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= Code of Conduct -:toc: - -== Our Pledge - -We pledge to make participation in this project a harassment-free -experience for everyone, regardless of age, body size, disability, -ethnicity, gender identity and expression, level of experience, -nationality, personal appearance, race, religion, or sexual identity and -orientation. - -== Our Standards - -Examples of behaviour that creates a positive environment: - -* Being respectful of differing viewpoints and experiences -* Giving and accepting constructive feedback -* Focusing on what is best for the community -* Showing empathy towards other community members - -Examples of unacceptable behaviour: - -* Harassment, trolling, or insulting comments -* Publishing others' private information without permission -*Other conduct which could reasonably be considered inappropriate - -== Enforcement - -Report violations to **@@CONDUCT_CONTACT@@**. All complaints will be -reviewed and investigated promptly and fairly. Maintainers are obligated to -respect the privacy and security of the reporter. - -== Attribution - -Adapted from the Contributor Covenant, version 2.1. diff --git a/aletheia/templates/common/CONTRIBUTING.adoc b/aletheia/templates/common/CONTRIBUTING.adoc deleted file mode 100644 index 2609bcc..0000000 --- a/aletheia/templates/common/CONTRIBUTING.adoc +++ /dev/null @@ -1,43 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= Contributing -:toc: - -== Getting Started - -[source,bash] ----- -git clone @@REPO_URL@@ -cd @@PROJECT_NAME@@ -just check ----- - -`just check` is the same gate CI runs. It must pass before you open a pull -request. - -== Workflow - -. Fork the repository. -. Create a branch: `+git checkout -b feat/my-feature+`. -. Make your change, with tests. -. Run `+just check+`. -. Commit using Conventional Commits (`+feat:+`, `+fix:+`, `+docs:+`, `+chore:+`). -. Open a pull request. - -== Standards - -This project follows the RSR (Rhodium Standard Repository) criteria. Two -rules bite most often: - -* *No silent skips.* A recipe that echoes a message and exits 0 is a fake - gate. Fail loudly. -* *SPDX headers.* Every source file carries an `+SPDX-License-Identifier+` - in its first ten lines. - -== Language Policy - -@@LANG_POLICY@@ - -== Review - -Pull requests require review before merge. See link:MAINTAINERS.adoc[MAINTAINERS.adoc] -for decision-making. diff --git a/aletheia/templates/common/LICENSE b/aletheia/templates/common/LICENSE deleted file mode 100644 index b306f89..0000000 --- a/aletheia/templates/common/LICENSE +++ /dev/null @@ -1,9 +0,0 @@ -Mozilla Public License Version 2.0 (MPL-2.0) - -Code in this repository is licensed under the Mozilla Public License, -version 2.0. Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (CC-BY-SA-4.0). - -See the LICENSES/ directory for the full license texts. - -SPDX-License-Identifier: MPL-2.0 diff --git a/aletheia/templates/common/LICENSES/CC-BY-SA-4.0.txt b/aletheia/templates/common/LICENSES/CC-BY-SA-4.0.txt deleted file mode 100644 index 2d58298..0000000 --- a/aletheia/templates/common/LICENSES/CC-BY-SA-4.0.txt +++ /dev/null @@ -1,428 +0,0 @@ -Attribution-ShareAlike 4.0 International - -======================================================================= - -Creative Commons Corporation ("Creative Commons") is not a law firm and -does not provide legal services or legal advice. Distribution of -Creative Commons public licenses does not create a lawyer-client or -other relationship. Creative Commons makes its licenses and related -information available on an "as-is" basis. Creative Commons gives no -warranties regarding its licenses, any material licensed under their -terms and conditions, or any related information. Creative Commons -disclaims all liability for damages resulting from their use to the -fullest extent possible. - -Using Creative Commons Public Licenses - -Creative Commons public licenses provide a standard set of terms and -conditions that creators and other rights holders may use to share -original works of authorship and other material subject to copyright -and certain other rights specified in the public license below. The -following considerations are for informational purposes only, are not -exhaustive, and do not form part of our licenses. - - Considerations for licensors: Our public licenses are - intended for use by those authorized to give the public - permission to use material in ways otherwise restricted by - copyright and certain other rights. Our licenses are - irrevocable. Licensors should read and understand the terms - and conditions of the license they choose before applying it. - Licensors should also secure all rights necessary before - applying our licenses so that the public can reuse the - material as expected. Licensors should clearly mark any - material not subject to the license. This includes other CC- - licensed material, or material used under an exception or - limitation to copyright. More considerations for licensors: - wiki.creativecommons.org/Considerations_for_licensors - - Considerations for the public: By using one of our public - licenses, a licensor grants the public permission to use the - licensed material under specified terms and conditions. If - the licensor's permission is not necessary for any reason--for - example, because of any applicable exception or limitation to - copyright--then that use is not regulated by the license. Our - licenses grant only permissions under copyright and certain - other rights that a licensor has authority to grant. Use of - the licensed material may still be restricted for other - reasons, including because others have copyright or other - rights in the material. A licensor may make special requests, - such as asking that all changes be marked or described. - Although not required by our licenses, you are encouraged to - respect those requests where reasonable. More considerations - for the public: - wiki.creativecommons.org/Considerations_for_licensees - -======================================================================= - -Creative Commons Attribution-ShareAlike 4.0 International Public -License - -By exercising the Licensed Rights (defined below), You accept and agree -to be bound by the terms and conditions of this Creative Commons -Attribution-ShareAlike 4.0 International Public License ("Public -License"). To the extent this Public License may be interpreted as a -contract, You are granted the Licensed Rights in consideration of Your -acceptance of these terms and conditions, and the Licensor grants You -such rights in consideration of benefits the Licensor receives from -making the Licensed Material available under these terms and -conditions. - - -Section 1 -- Definitions. - - a. Adapted Material means material subject to Copyright and Similar - Rights that is derived from or based upon the Licensed Material - and in which the Licensed Material is translated, altered, - arranged, transformed, or otherwise modified in a manner requiring - permission under the Copyright and Similar Rights held by the - Licensor. For purposes of this Public License, where the Licensed - Material is a musical work, performance, or sound recording, - Adapted Material is always produced where the Licensed Material is - synched in timed relation with a moving image. - - b. Adapter's License means the license You apply to Your Copyright - and Similar Rights in Your contributions to Adapted Material in - accordance with the terms and conditions of this Public License. - - c. BY-SA Compatible License means a license listed at - creativecommons.org/compatiblelicenses, approved by Creative - Commons as essentially the equivalent of this Public License. - - d. Copyright and Similar Rights means copyright and/or similar rights - closely related to copyright including, without limitation, - performance, broadcast, sound recording, and Sui Generis Database - Rights, without regard to how the rights are labeled or - categorized. For purposes of this Public License, the rights - specified in Section 2(b)(1)-(2) are not Copyright and Similar - Rights. - - e. Effective Technological Measures means those measures that, in the - absence of proper authority, may not be circumvented under laws - fulfilling obligations under Article 11 of the WIPO Copyright - Treaty adopted on December 20, 1996, and/or similar international - agreements. - - f. Exceptions and Limitations means fair use, fair dealing, and/or - any other exception or limitation to Copyright and Similar Rights - that applies to Your use of the Licensed Material. - - g. License Elements means the license attributes listed in the name - of a Creative Commons Public License. The License Elements of this - Public License are Attribution and ShareAlike. - - h. Licensed Material means the artistic or literary work, database, - or other material to which the Licensor applied this Public - License. - - i. Licensed Rights means the rights granted to You subject to the - terms and conditions of this Public License, which are limited to - all Copyright and Similar Rights that apply to Your use of the - Licensed Material and that the Licensor has authority to license. - - j. Licensor means the individual(s) or entity(ies) granting rights - under this Public License. - - k. Share means to provide material to the public by any means or - process that requires permission under the Licensed Rights, such - as reproduction, public display, public performance, distribution, - dissemination, communication, or importation, and to make material - available to the public including in ways that members of the - public may access the material from a place and at a time - individually chosen by them. - - l. Sui Generis Database Rights means rights other than copyright - resulting from Directive 96/9/EC of the European Parliament and of - the Council of 11 March 1996 on the legal protection of databases, - as amended and/or succeeded, as well as other essentially - equivalent rights anywhere in the world. - - m. You means the individual or entity exercising the Licensed Rights - under this Public License. Your has a corresponding meaning. - - -Section 2 -- Scope. - - a. License grant. - - 1. Subject to the terms and conditions of this Public License, - the Licensor hereby grants You a worldwide, royalty-free, - non-sublicensable, non-exclusive, irrevocable license to - exercise the Licensed Rights in the Licensed Material to: - - a. reproduce and Share the Licensed Material, in whole or - in part; and - - b. produce, reproduce, and Share Adapted Material. - - 2. Exceptions and Limitations. For the avoidance of doubt, where - Exceptions and Limitations apply to Your use, this Public - License does not apply, and You do not need to comply with - its terms and conditions. - - 3. Term. The term of this Public License is specified in Section - 6(a). - - 4. Media and formats; technical modifications allowed. The - Licensor authorizes You to exercise the Licensed Rights in - all media and formats whether now known or hereafter created, - and to make technical modifications necessary to do so. The - Licensor waives and/or agrees not to assert any right or - authority to forbid You from making technical modifications - necessary to exercise the Licensed Rights, including - technical modifications necessary to circumvent Effective - Technological Measures. For purposes of this Public License, - simply making modifications authorized by this Section 2(a) - (4) never produces Adapted Material. - - 5. Downstream recipients. - - a. Offer from the Licensor -- Licensed Material. Every - recipient of the Licensed Material automatically - receives an offer from the Licensor to exercise the - Licensed Rights under the terms and conditions of this - Public License. - - b. Additional offer from the Licensor -- Adapted Material. - Every recipient of Adapted Material from You - automatically receives an offer from the Licensor to - exercise the Licensed Rights in the Adapted Material - under the conditions of the Adapter's License You apply. - - c. No downstream restrictions. You may not offer or impose - any additional or different terms or conditions on, or - apply any Effective Technological Measures to, the - Licensed Material if doing so restricts exercise of the - Licensed Rights by any recipient of the Licensed - Material. - - 6. No endorsement. Nothing in this Public License constitutes or - may be construed as permission to assert or imply that You - are, or that Your use of the Licensed Material is, connected - with, or sponsored, endorsed, or granted official status by, - the Licensor or others designated to receive attribution as - provided in Section 3(a)(1)(A)(i). - - b. Other rights. - - 1. Moral rights, such as the right of integrity, are not - licensed under this Public License, nor are publicity, - privacy, and/or other similar personality rights; however, to - the extent possible, the Licensor waives and/or agrees not to - assert any such rights held by the Licensor to the limited - extent necessary to allow You to exercise the Licensed - Rights, but not otherwise. - - 2. Patent and trademark rights are not licensed under this - Public License. - - 3. To the extent possible, the Licensor waives any right to - collect royalties from You for the exercise of the Licensed - Rights, whether directly or through a collecting society - under any voluntary or waivable statutory or compulsory - licensing scheme. In all other cases the Licensor expressly - reserves any right to collect such royalties. - - -Section 3 -- License Conditions. - -Your exercise of the Licensed Rights is expressly made subject to the -following conditions. - - a. Attribution. - - 1. If You Share the Licensed Material (including in modified - form), You must: - - a. retain the following if it is supplied by the Licensor - with the Licensed Material: - - i. identification of the creator(s) of the Licensed - Material and any others designated to receive - attribution, in any reasonable manner requested by - the Licensor (including by pseudonym if - designated); - - ii. a copyright notice; - - iii. a notice that refers to this Public License; - - iv. a notice that refers to the disclaimer of - warranties; - - v. a URI or hyperlink to the Licensed Material to the - extent reasonably practicable; - - b. indicate if You modified the Licensed Material and - retain an indication of any previous modifications; and - - c. indicate the Licensed Material is licensed under this - Public License, and include the text of, or the URI or - hyperlink to, this Public License. - - 2. You may satisfy the conditions in Section 3(a)(1) in any - reasonable manner based on the medium, means, and context in - which You Share the Licensed Material. For example, it may be - reasonable to satisfy the conditions by providing a URI or - hyperlink to a resource that includes the required - information. - - 3. If requested by the Licensor, You must remove any of the - information required by Section 3(a)(1)(A) to the extent - reasonably practicable. - - b. ShareAlike. - - In addition to the conditions in Section 3(a), if You Share - Adapted Material You produce, the following conditions also apply. - - 1. The Adapter's License You apply must be a Creative Commons - license with the same License Elements, this version or - later, or a BY-SA Compatible License. - - 2. You must include the text of, or the URI or hyperlink to, the - Adapter's License You apply. You may satisfy this condition - in any reasonable manner based on the medium, means, and - context in which You Share Adapted Material. - - 3. You may not offer or impose any additional or different terms - or conditions on, or apply any Effective Technological - Measures to, Adapted Material that restrict exercise of the - rights granted under the Adapter's License You apply. - - -Section 4 -- Sui Generis Database Rights. - -Where the Licensed Rights include Sui Generis Database Rights that -apply to Your use of the Licensed Material: - - a. for the avoidance of doubt, Section 2(a)(1) grants You the right - to extract, reuse, reproduce, and Share all or a substantial - portion of the contents of the database; - - b. if You include all or a substantial portion of the database - contents in a database in which You have Sui Generis Database - Rights, then the database in which You have Sui Generis Database - Rights (but not its individual contents) is Adapted Material, - including for purposes of Section 3(b); and - - c. You must comply with the conditions in Section 3(a) if You Share - all or a substantial portion of the contents of the database. - -For the avoidance of doubt, this Section 4 supplements and does not -replace Your obligations under this Public License where the Licensed -Rights include other Copyright and Similar Rights. - - -Section 5 -- Disclaimer of Warranties and Limitation of Liability. - - a. UNLESS OTHERWISE SEPARATELY UNDERTAKEN BY THE LICENSOR, TO THE - EXTENT POSSIBLE, THE LICENSOR OFFERS THE LICENSED MATERIAL AS-IS - AND AS-AVAILABLE, AND MAKES NO REPRESENTATIONS OR WARRANTIES OF - ANY KIND CONCERNING THE LICENSED MATERIAL, WHETHER EXPRESS, - IMPLIED, STATUTORY, OR OTHER. THIS INCLUDES, WITHOUT LIMITATION, - WARRANTIES OF TITLE, MERCHANTABILITY, FITNESS FOR A PARTICULAR - PURPOSE, NON-INFRINGEMENT, ABSENCE OF LATENT OR OTHER DEFECTS, - ACCURACY, OR THE PRESENCE OR ABSENCE OF ERRORS, WHETHER OR NOT - KNOWN OR DISCOVERABLE. WHERE DISCLAIMERS OF WARRANTIES ARE NOT - ALLOWED IN FULL OR IN PART, THIS DISCLAIMER MAY NOT APPLY TO YOU. - - b. TO THE EXTENT POSSIBLE, IN NO EVENT WILL THE LICENSOR BE LIABLE - TO YOU ON ANY LEGAL THEORY (INCLUDING, WITHOUT LIMITATION, - NEGLIGENCE) OR OTHERWISE FOR ANY DIRECT, SPECIAL, INDIRECT, - INCIDENTAL, CONSEQUENTIAL, PUNITIVE, EXEMPLARY, OR OTHER LOSSES, - COSTS, EXPENSES, OR DAMAGES ARISING OUT OF THIS PUBLIC LICENSE OR - USE OF THE LICENSED MATERIAL, EVEN IF THE LICENSOR HAS BEEN - ADVISED OF THE POSSIBILITY OF SUCH LOSSES, COSTS, EXPENSES, OR - DAMAGES. WHERE A LIMITATION OF LIABILITY IS NOT ALLOWED IN FULL OR - IN PART, THIS LIMITATION MAY NOT APPLY TO YOU. - - c. The disclaimer of warranties and limitation of liability provided - above shall be interpreted in a manner that, to the extent - possible, most closely approximates an absolute disclaimer and - waiver of all liability. - - -Section 6 -- Term and Termination. - - a. This Public License applies for the term of the Copyright and - Similar Rights licensed here. However, if You fail to comply with - this Public License, then Your rights under this Public License - terminate automatically. - - b. Where Your right to use the Licensed Material has terminated under - Section 6(a), it reinstates: - - 1. automatically as of the date the violation is cured, provided - it is cured within 30 days of Your discovery of the - violation; or - - 2. upon express reinstatement by the Licensor. - - For the avoidance of doubt, this Section 6(b) does not affect any - right the Licensor may have to seek remedies for Your violations - of this Public License. - - c. For the avoidance of doubt, the Licensor may also offer the - Licensed Material under separate terms or conditions or stop - distributing the Licensed Material at any time; however, doing so - will not terminate this Public License. - - d. Sections 1, 5, 6, 7, and 8 survive termination of this Public - License. - - -Section 7 -- Other Terms and Conditions. - - a. The Licensor shall not be bound by any additional or different - terms or conditions communicated by You unless expressly agreed. - - b. Any arrangements, understandings, or agreements regarding the - Licensed Material not stated herein are separate from and - independent of the terms and conditions of this Public License. - - -Section 8 -- Interpretation. - - a. For the avoidance of doubt, this Public License does not, and - shall not be interpreted to, reduce, limit, restrict, or impose - conditions on any use of the Licensed Material that could lawfully - be made without permission under this Public License. - - b. To the extent possible, if any provision of this Public License is - deemed unenforceable, it shall be automatically reformed to the - minimum extent necessary to make it enforceable. If the provision - cannot be reformed, it shall be severed from this Public License - without affecting the enforceability of the remaining terms and - conditions. - - c. No term or condition of this Public License will be waived and no - failure to comply consented to unless expressly agreed to by the - Licensor. - - d. Nothing in this Public License constitutes or may be interpreted - as a limitation upon, or waiver of, any privileges and immunities - that apply to the Licensor or You, including from the legal - processes of any jurisdiction or authority. - - -======================================================================= - -Creative Commons is not a party to its public -licenses. Notwithstanding, Creative Commons may elect to apply one of -its public licenses to material it publishes and in those instances -will be considered the “Licensor.” The text of the Creative Commons -public licenses is dedicated to the public domain under the CC0 Public -Domain Dedication. Except for the limited purpose of indicating that -material is shared under a Creative Commons public license or as -otherwise permitted by the Creative Commons policies published at -creativecommons.org/policies, Creative Commons does not authorize the -use of the trademark "Creative Commons" or any other trademark or logo -of Creative Commons without its prior written consent including, -without limitation, in connection with any unauthorized modifications -to any of its public licenses or any other arrangements, -understandings, or agreements concerning use of licensed material. For -the avoidance of doubt, this paragraph does not form part of the -public licenses. - -Creative Commons may be contacted at creativecommons.org. - diff --git a/aletheia/templates/common/LICENSES/MPL-2.0.txt b/aletheia/templates/common/LICENSES/MPL-2.0.txt deleted file mode 100644 index d0a1fa1..0000000 --- a/aletheia/templates/common/LICENSES/MPL-2.0.txt +++ /dev/null @@ -1,373 +0,0 @@ -Mozilla Public License Version 2.0 -================================== - -1. Definitions --------------- - -1.1. "Contributor" - means each individual or legal entity that creates, contributes to - the creation of, or owns Covered Software. - -1.2. "Contributor Version" - means the combination of the Contributions of others (if any) used - by a Contributor and that particular Contributor's Contribution. - -1.3. "Contribution" - means Covered Software of a particular Contributor. - -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 - - (a) that the initial Contributor has attached the notice described - in Exhibit B to the Covered Software; or - - (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. - -1.6. "Executable Form" - means any form of the work other than Source Code Form. - -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/aletheia/templates/common/MAINTAINERS.adoc b/aletheia/templates/common/MAINTAINERS.adoc deleted file mode 100644 index 7d3fa72..0000000 --- a/aletheia/templates/common/MAINTAINERS.adoc +++ /dev/null @@ -1,29 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= Maintainers - -== Current Maintainers - -* *@@AUTHOR_NAME@@* — Project Lead — @@AUTHOR_EMAIL@@ - -== Responsibilities - -Maintainers review pull requests, triage issues, cut releases, and uphold -the project's security and conduct policies. - -== Becoming a Maintainer - -Maintainers are invited based on sustained, constructive contribution. - -== Decision Making - -[cols="1,2"] -|=== -|Minor change |one maintainer approval -|Major change |consensus among maintainers -|Security fix |one maintainer approval, expedited -|=== - -== Contact - -Use the repository's issue tracker for project questions, and -@@SECURITY_CONTACT@@ for security matters. diff --git a/aletheia/templates/common/SECURITY.adoc b/aletheia/templates/common/SECURITY.adoc deleted file mode 100644 index f346b3d..0000000 --- a/aletheia/templates/common/SECURITY.adoc +++ /dev/null @@ -1,33 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= Security Policy -:toc: - -== Reporting a Vulnerability - -Report vulnerabilities privately to **@@SECURITY_CONTACT@@**. - -**Do not** open a public issue for a security vulnerability. - -== Response Timeline - -[cols="1,2"] -|=== -|Acknowledgment |within 48 hours -|Assessment |within 7 days -|Fix (critical) |within 30 days -|Fix (other) |within 90 days -|=== - -== Scope - -This policy covers the source code in this repository and the artefacts it -publishes. It does not cover third-party dependencies, which are governed -by their own policies. - -== Supported Versions - -The latest release on the default branch receives security fixes. - -== Machine-Readable Form - -An RFC 9116 `+security.txt+` is published at link:.well-known/security.txt[.well-known/security.txt]. diff --git a/aletheia/templates/elixir/.editorconfig b/aletheia/templates/elixir/.editorconfig deleted file mode 100644 index 7520e0f..0000000 --- a/aletheia/templates/elixir/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# @@PROJECT_NAME@@ - Editor Configuration -# https://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.adoc] -trim_trailing_whitespace = false - -[Justfile] -indent_style = space -indent_size = 4 diff --git a/aletheia/templates/elixir/.formatter.exs b/aletheia/templates/elixir/.formatter.exs deleted file mode 100644 index 8769554..0000000 --- a/aletheia/templates/elixir/.formatter.exs +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Used by `mix format`. -[ - inputs: ["{mix,.formatter}.exs", "{config,lib,test}/**/*.{ex,exs}"] -] diff --git a/aletheia/templates/elixir/.github/workflows/ci.yml b/aletheia/templates/elixir/.github/workflows/ci.yml deleted file mode 100644 index 20e1465..0000000 --- a/aletheia/templates/elixir/.github/workflows/ci.yml +++ /dev/null @@ -1,42 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -name: CI - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - check: - name: Build, test, lint (offline) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Install Erlang and Elixir - uses: erlef/setup-beam@54075bcc5e249e4758d363f27d099f55d843f124 # v1 - with: - otp-version: '27.3' - elixir-version: '1.18.3' - - - name: Compile (no deps to fetch) - run: mix compile --warnings-as-errors - - - name: Test - run: mix test - - - name: Check formatting - run: mix format --check-formatted diff --git a/aletheia/templates/elixir/.gitignore b/aletheia/templates/elixir/.gitignore deleted file mode 100644 index f9b9e3f..0000000 --- a/aletheia/templates/elixir/.gitignore +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -/_build/ -/cover/ -/deps/ -/doc/ -/.fetch -erl_crash.dump -*.ez -*.beam diff --git a/aletheia/templates/elixir/.machine_readable/rsr-profile.a2ml b/aletheia/templates/elixir/.machine_readable/rsr-profile.a2ml deleted file mode 100644 index 33b2fd5..0000000 --- a/aletheia/templates/elixir/.machine_readable/rsr-profile.a2ml +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for @@PROJECT_NAME@@. Declares what this repo -# carries so the capability gates compute the applicable criterion set. -[profile] -capabilities = ["elixir", "cli", "docs"] - -[rationale] -elixir = "true: mix project, Elixir 1.18 / OTP 27" -cli = "true: lib//cli.ex exposes a main/1 entry point" -docs = "true: README + SECURITY + CONTRIBUTING + CODE_OF_CONDUCT + CHANGELOG" -no-library = "shared: the app is a library plus a CLI wrapper, not published to Hex" -no-container = "true: no Containerfile in the scaffold" diff --git a/aletheia/templates/elixir/.tool-versions b/aletheia/templates/elixir/.tool-versions deleted file mode 100644 index 40ad142..0000000 --- a/aletheia/templates/elixir/.tool-versions +++ /dev/null @@ -1,3 +0,0 @@ -# Toolchain pins, asdf/mise compatible. -erlang 27.3 -gelixir 1.18.3 diff --git a/aletheia/templates/elixir/Justfile b/aletheia/templates/elixir/Justfile deleted file mode 100644 index a09faf1..0000000 --- a/aletheia/templates/elixir/Justfile +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Justfile — build automation for @@PROJECT_NAME@@. -# See: https://github.com/casey/just -# -# Every recipe here is offline: this project has no external dependencies, -# so nothing is fetched at build time. Recipes fail loudly — a recipe that -# echoes a message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). - -default: - @just --list - -# Compile the project, treating warnings as errors -build: - mix compile --warnings-as-errors - -# Run the program; pass arguments after the recipe name -run *ARGS: - mix run -e '@@MOD_CAMEL@@.CLI.main(System.argv())' -- {{ARGS}} - -# Run the test suite -test: - mix test - -# Check formatting (does not modify files) -fmt: - mix format --check-formatted - -# Apply formatting -fmt-fix: - mix format - -# Verify RSR compliance using the estate checker -verify: - aletheia . - -# Everything the CI gate runs, in the same order -check: build test fmt diff --git a/aletheia/templates/elixir/README.adoc b/aletheia/templates/elixir/README.adoc deleted file mode 100644 index 1e89576..0000000 --- a/aletheia/templates/elixir/README.adoc +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= @@PROJECT_NAME@@ -:toc: -:icons: font - -____ -@@PROJECT_DESCRIPTION@@ -____ - -== Quick Start - -[source,bash] ----- -# Build (offline — nothing is downloaded) -just build - -# Test -just test - -# Verify RSR compliance -just verify ----- - -This project is *standalone by construction*: the scaffold fetches nothing, -the build has no external dependencies, and the licence texts ship in-tree -under `+LICENSES/+`. - -== RSR Compliance - -[cols="1,3"] -|=== -|Bronze |Documentation, security policy, SPDX headers, CI, licence classification -|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` -|Gold |No silent-skip recipes -|=== - -Verify with the estate's own checker: - -[source,bash] ----- -aletheia . ----- - -== Language: @@LANG_DISPLAY@@ - -@@LANG_POLICY@@ - -== Documentation - -* link:SECURITY.adoc[Security Policy] — vulnerability disclosure -* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute -* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards -* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions -* link:CHANGELOG.adoc[Changelog] — version history - -== Layout - -.... -. -├── Justfile # build automation (capital J — v2 shape) -├── LICENSE # licence statement -├── LICENSES/ # full licence texts (REUSE style) -├── src/ # source (layout follows the language's conventions) -├── .github/workflows/ # CI + estate gates -├── .machine_readable/ # machine-readable metadata -└── .well-known/ # security.txt, ai.txt, humans.txt -.... - -== Contributing - -See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. - -== License - -Code is licensed under the Mozilla Public License, version 2.0 -(`+MPL-2.0+`). Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). - -See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. - -''''' - -_Created from the aletheia v2 Bronze template._ diff --git a/aletheia/templates/elixir/lib/@@MOD_NAME@@.ex b/aletheia/templates/elixir/lib/@@MOD_NAME@@.ex deleted file mode 100644 index 62a12ce..0000000 --- a/aletheia/templates/elixir/lib/@@MOD_NAME@@.ex +++ /dev/null @@ -1,47 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -defmodule @@MOD_CAMEL@@ do - @moduledoc """ - Core library for @@PROJECT_NAME@@. - - Replace these sample functions with your own. - """ - - @doc """ - Clamp `value` into the inclusive range `lo..hi`. - - Raises if `lo > hi`, because an inverted range is a programming error - rather than a silent no-op. - - ## Examples - - iex> @@MOD_CAMEL@@.clamp(5, 0, 10) - 5 - iex> @@MOD_CAMEL@@.clamp(99, 0, 10) - 10 - """ - @spec clamp(non_neg_integer(), non_neg_integer(), non_neg_integer()) :: non_neg_integer() - def clamp(value, lo, hi) when lo <= hi do - value |> max(lo) |> min(hi) - end - - @doc """ - Integer mean of two non-negative integers, rounded towards zero. - - The naive `div(a + b, 2)` is fine on the BEAM, where integers are - arbitrary precision; this form is kept because it is explicit about - intent and mirrors the other templates in this estate. - - ## Examples - - iex> @@MOD_CAMEL@@.mean_floor(8, 11) - 9 - """ - @spec mean_floor(non_neg_integer(), non_neg_integer()) :: non_neg_integer() - def mean_floor(a, b) do - Bitwise.band(a, b) + Bitwise.bsr(Bitwise.bxor(a, b), 1) - end - - @doc "Returns the project version." - @spec version() :: String.t() - def version, do: "0.1.0" -end diff --git a/aletheia/templates/elixir/lib/@@MOD_NAME@@/cli.ex b/aletheia/templates/elixir/lib/@@MOD_NAME@@/cli.ex deleted file mode 100644 index e3864d5..0000000 --- a/aletheia/templates/elixir/lib/@@MOD_NAME@@/cli.ex +++ /dev/null @@ -1,62 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -defmodule @@MOD_CAMEL@@.CLI do - @moduledoc """ - Command-line entry point for @@PROJECT_NAME@@. - """ - - @usage """ - @@PROJECT_NAME@@ 0.1.0 - - usage: - @@PROJECT_NAME@@ clamp clamp a value into a range - @@PROJECT_NAME@@ mean integer mean, rounded down - @@PROJECT_NAME@@ --help show this message - """ - - @doc """ - Runs the CLI with the given argument list. - - Returns an exit status. The Justfile's `run` recipe wires this up via - `mix run -e '@@MOD_CAMEL@@.CLI.main(System.argv())'`, which exits with - the status this returns. - """ - @spec main([String.t()]) :: non_neg_integer() - def main([]) do - IO.puts(@usage) - 0 - end - - def main([flag]) when flag in ["--help", "-h"] do - IO.puts(@usage) - 0 - end - - def main(["clamp", value, lo, hi]) do - with {value, ""} <- Integer.parse(value), - {lo, ""} <- Integer.parse(lo), - {hi, ""} <- Integer.parse(hi), - true <- lo <= hi do - IO.puts(@@MOD_CAMEL@@.clamp(value, lo, hi)) - 0 - else - _ -> fail() - end - end - - def main(["mean", a, b]) do - with {a, ""} <- Integer.parse(a), - {b, ""} <- Integer.parse(b) do - IO.puts(@@MOD_CAMEL@@.mean_floor(a, b)) - 0 - else - _ -> fail() - end - end - - def main(_), do: fail() - - defp fail do - IO.puts(:stderr, "error: unrecognised arguments\n\n#{@usage}") - 1 - end -end diff --git a/aletheia/templates/elixir/mix.exs b/aletheia/templates/elixir/mix.exs deleted file mode 100644 index c226942..0000000 --- a/aletheia/templates/elixir/mix.exs +++ /dev/null @@ -1,21 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -defmodule @@MOD_CAMEL@@.MixProject do - use Mix.Project - - def project do - [ - app: :@@MOD_NAME@@, - version: "0.1.0", - elixir: "~> 1.18", - start_permanent: Mix.env() == :prod, - # EMPTY BY DESIGN: no Hex dependencies, so nothing is fetched at - # build time and `mix compile` works with no network access. - # See 0-AI-MANIFEST.a2ml, invariant 2. - deps: [] - ] - end - - def application do - [extra_applications: [:logger]] - end -end diff --git a/aletheia/templates/elixir/test/@@MOD_NAME@@_test.exs b/aletheia/templates/elixir/test/@@MOD_NAME@@_test.exs deleted file mode 100644 index 469dd07..0000000 --- a/aletheia/templates/elixir/test/@@MOD_NAME@@_test.exs +++ /dev/null @@ -1,45 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -defmodule @@MOD_CAMEL@@Test do - use ExUnit.Case, async: true - - doctest @@MOD_CAMEL@@ - - describe "clamp/3" do - test "keeps a value already inside the range" do - assert @@MOD_CAMEL@@.clamp(5, 0, 10) == 5 - end - - test "lifts a value below the range to the lower bound" do - assert @@MOD_CAMEL@@.clamp(0, 1, 10) == 1 - end - - test "drops a value above the range to the upper bound" do - assert @@MOD_CAMEL@@.clamp(99, 0, 10) == 10 - end - - test "handles a degenerate range" do - assert @@MOD_CAMEL@@.clamp(7, 7, 7) == 7 - end - - test "is idempotent" do - for value <- [0, 1, 5, 42, 10_000] do - once = @@MOD_CAMEL@@.clamp(value, 10, 100) - assert @@MOD_CAMEL@@.clamp(once, 10, 100) == once - end - end - end - - describe "mean_floor/2" do - test "matches the naive form on small inputs" do - for a <- 0..63, b <- 0..63 do - assert @@MOD_CAMEL@@.mean_floor(a, b) == div(a + b, 2) - end - end - - test "never exceeds either input" do - for {a, b} <- [{0, 0}, {1, 2}, {7, 9}, {10_000, 0}] do - assert @@MOD_CAMEL@@.mean_floor(a, b) <= max(a, b) - end - end - end -end diff --git a/aletheia/templates/elixir/test/test_helper.exs b/aletheia/templates/elixir/test/test_helper.exs deleted file mode 100644 index 5a57034..0000000 --- a/aletheia/templates/elixir/test/test_helper.exs +++ /dev/null @@ -1,2 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -ExUnit.start() diff --git a/aletheia/templates/haskell/.editorconfig b/aletheia/templates/haskell/.editorconfig deleted file mode 100644 index 7520e0f..0000000 --- a/aletheia/templates/haskell/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# @@PROJECT_NAME@@ - Editor Configuration -# https://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.adoc] -trim_trailing_whitespace = false - -[Justfile] -indent_style = space -indent_size = 4 diff --git a/aletheia/templates/haskell/.github/workflows/ci.yml b/aletheia/templates/haskell/.github/workflows/ci.yml deleted file mode 100644 index 7a2d2e0..0000000 --- a/aletheia/templates/haskell/.github/workflows/ci.yml +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -name: CI - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - check: - name: Build, test, lint (offline) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Install GHC and Cabal - uses: haskell-actions/setup@0f8e8c99d88aeb3fbfd523f1ef2c6f762d10d64d # v2 - with: - ghc-version: '9.6.6' - cabal-version: '3.10.3.0' - - - name: Build (offline, base only) - run: cabal build --offline - - - name: Test - run: cabal test --offline --test-show-details=direct diff --git a/aletheia/templates/haskell/.gitignore b/aletheia/templates/haskell/.gitignore deleted file mode 100644 index b4a1619..0000000 --- a/aletheia/templates/haskell/.gitignore +++ /dev/null @@ -1,7 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -/dist-newstyle/ -dist-newstyle/ -*.hi -*.o -*.hie -.ghc.environment.* diff --git a/aletheia/templates/haskell/.machine_readable/rsr-profile.a2ml b/aletheia/templates/haskell/.machine_readable/rsr-profile.a2ml deleted file mode 100644 index 15107b4..0000000 --- a/aletheia/templates/haskell/.machine_readable/rsr-profile.a2ml +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for @@PROJECT_NAME@@. Declares what this repo -# carries so the capability gates compute the applicable criterion set. -[profile] -capabilities = ["haskell", "cli", "docs"] - -[rationale] -haskell = "true: cabal package, GHC 9.6.6" -cli = "true: app/Main.hs produces an executable" -docs = "true: README + SECURITY + CONTRIBUTING + CODE_OF_CONDUCT + CHANGELOG" -no-library = "shared: src/ is a library component of the same package, not published to Hackage" -no-container = "true: no Containerfile in the scaffold" diff --git a/aletheia/templates/haskell/.tool-versions b/aletheia/templates/haskell/.tool-versions deleted file mode 100644 index 66b7d5d..0000000 --- a/aletheia/templates/haskell/.tool-versions +++ /dev/null @@ -1,3 +0,0 @@ -# Toolchain pins, asdf/mise compatible. -ghc 9.6.6 -cabal 3.10.3.0 diff --git a/aletheia/templates/haskell/@@PROJECT_NAME@@.cabal b/aletheia/templates/haskell/@@PROJECT_NAME@@.cabal deleted file mode 100644 index 15bafdc..0000000 --- a/aletheia/templates/haskell/@@PROJECT_NAME@@.cabal +++ /dev/null @@ -1,44 +0,0 @@ -cabal-version: 2.4 --- SPDX-License-Identifier: MPL-2.0 -name: @@PROJECT_NAME@@ -version: 0.1.0 -synopsis: @@PROJECT_DESCRIPTION@@ -license: MPL-2.0 -license-file: LICENSE -build-type: Simple - --- Zero external dependencies: only `base`, which ships with GHC. That is --- what lets `cabal build --offline` resolve with no package index and no --- network. See 0-AI-MANIFEST.a2ml, invariant 2. - -common warnings - ghc-options: -Wall - -Wcompat - -Widentities - -Wincomplete-record-updates - -Wincomplete-uni-patterns - -Wredundant-constraints - -library - import: warnings - exposed-modules: Core - hs-source-dirs: src - build-depends: base >=4.14 && <5 - default-language: Haskell2010 - -executable @@PROJECT_NAME@@ - import: warnings - main-is: Main.hs - hs-source-dirs: app - build-depends: base, - @@PROJECT_NAME@@ - default-language: Haskell2010 - -test-suite @@PROJECT_NAME@@-test - import: warnings - type: exitcode-stdio-1.0 - main-is: Main.hs - hs-source-dirs: test - build-depends: base, - @@PROJECT_NAME@@ - default-language: Haskell2010 diff --git a/aletheia/templates/haskell/Justfile b/aletheia/templates/haskell/Justfile deleted file mode 100644 index adcc632..0000000 --- a/aletheia/templates/haskell/Justfile +++ /dev/null @@ -1,35 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Justfile — build automation for @@PROJECT_NAME@@. -# See: https://github.com/casey/just -# -# Every recipe here is offline: this project has no external dependencies, -# so nothing is fetched at build time. Recipes fail loudly — a recipe that -# echoes a message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). - -default: - @just --list - -# Build the package (offline: only `base` from GHC is needed) -build: - cabal build --offline - -# Run the program; pass arguments after the recipe name -run *ARGS: - cabal run --offline @@PROJECT_NAME@@ -- {{ARGS}} - -# Run the test suite -test: - cabal test --offline --test-show-details=direct - -# Build with all warnings enabled and promoted to errors. This is the -# static-analysis gate for this language: GHC's own warning set, no extra -# tooling to install. -lint: - cabal build --offline --ghc-options="-Wall -Wcompat -Werror" - -# Verify RSR compliance using the estate checker -verify: - aletheia . - -# Everything the CI gate runs, in the same order -check: build test diff --git a/aletheia/templates/haskell/README.adoc b/aletheia/templates/haskell/README.adoc deleted file mode 100644 index 1e89576..0000000 --- a/aletheia/templates/haskell/README.adoc +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= @@PROJECT_NAME@@ -:toc: -:icons: font - -____ -@@PROJECT_DESCRIPTION@@ -____ - -== Quick Start - -[source,bash] ----- -# Build (offline — nothing is downloaded) -just build - -# Test -just test - -# Verify RSR compliance -just verify ----- - -This project is *standalone by construction*: the scaffold fetches nothing, -the build has no external dependencies, and the licence texts ship in-tree -under `+LICENSES/+`. - -== RSR Compliance - -[cols="1,3"] -|=== -|Bronze |Documentation, security policy, SPDX headers, CI, licence classification -|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` -|Gold |No silent-skip recipes -|=== - -Verify with the estate's own checker: - -[source,bash] ----- -aletheia . ----- - -== Language: @@LANG_DISPLAY@@ - -@@LANG_POLICY@@ - -== Documentation - -* link:SECURITY.adoc[Security Policy] — vulnerability disclosure -* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute -* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards -* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions -* link:CHANGELOG.adoc[Changelog] — version history - -== Layout - -.... -. -├── Justfile # build automation (capital J — v2 shape) -├── LICENSE # licence statement -├── LICENSES/ # full licence texts (REUSE style) -├── src/ # source (layout follows the language's conventions) -├── .github/workflows/ # CI + estate gates -├── .machine_readable/ # machine-readable metadata -└── .well-known/ # security.txt, ai.txt, humans.txt -.... - -== Contributing - -See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. - -== License - -Code is licensed under the Mozilla Public License, version 2.0 -(`+MPL-2.0+`). Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). - -See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. - -''''' - -_Created from the aletheia v2 Bronze template._ diff --git a/aletheia/templates/haskell/app/Main.hs b/aletheia/templates/haskell/app/Main.hs deleted file mode 100644 index 86c375d..0000000 --- a/aletheia/templates/haskell/app/Main.hs +++ /dev/null @@ -1,51 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- | @@PROJECT_NAME@@ — command-line entry point. -module Main (main) where - -import Core (clamp, meanFloor) -import System.IO (hPutStrLn, stderr) -import System.Environment (getArgs) -import System.Exit (exitFailure, exitSuccess) -import Text.Read (readMaybe) - -usage :: String -usage = - unlines - [ "@@PROJECT_NAME@@ 0.1.0" - , "" - , "usage:" - , " @@PROJECT_NAME@@ clamp clamp a value into a range" - , " @@PROJECT_NAME@@ mean integer mean, rounded down" - , " @@PROJECT_NAME@@ --help show this message" - , "" - , "All arguments are non-negative integers." - ] - -parseWord :: String -> Maybe Word -parseWord raw = case readMaybe raw of - Just n | n >= 0 -> Just n - _ -> Nothing - -main :: IO () -main = do - args <- getArgs - case args of - [] -> putStr usage >> exitSuccess - ["--help"] -> putStr usage >> exitSuccess - ["-h"] -> putStr usage >> exitSuccess - ["clamp", value, lo, hi] -> - case (parseWord value, parseWord lo, parseWord hi) of - (Just v, Just l, Just h) | l <= h -> print (clamp v l h) >> exitSuccess - _ -> unrecognised - ["mean", a, b] -> - case (parseWord a, parseWord b) of - (Just x, Just y) -> print (meanFloor x y) >> exitSuccess - _ -> unrecognised - _ -> unrecognised - -unrecognised :: IO a -unrecognised = do - hPutStrLn stderr "error: unrecognised arguments" - hPutStrLn stderr "" - hPutStrLn stderr usage - exitFailure diff --git a/aletheia/templates/haskell/cabal.project b/aletheia/templates/haskell/cabal.project deleted file mode 100644 index f63a681..0000000 --- a/aletheia/templates/haskell/cabal.project +++ /dev/null @@ -1,2 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 -packages: . diff --git a/aletheia/templates/haskell/src/Core.hs b/aletheia/templates/haskell/src/Core.hs deleted file mode 100644 index d339dc2..0000000 --- a/aletheia/templates/haskell/src/Core.hs +++ /dev/null @@ -1,24 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- | Core library for @@PROJECT_NAME@@. --- --- Replace these sample functions with your own. -module Core - ( clamp - , meanFloor - ) where - -import Data.Bits (shiftR, xor, (.&.)) - --- | Clamp @value@ into the inclusive range @[lo, hi]@. --- --- If @lo > hi@ the range is empty; the upper bound wins, so the result is --- @hi@. Callers that care should check their range first. -clamp :: Ord a => a -> a -> a -> a -clamp value lo hi = min hi (max lo value) - --- | Integer mean of two 'Word's, rounded towards zero. --- --- The naive @(a + b) \`div\` 2@ overflows for large inputs; this form --- cannot, because it never materialises the sum. -meanFloor :: Word -> Word -> Word -meanFloor a b = (a .&. b) + ((a `xor` b) `shiftR` 1) diff --git a/aletheia/templates/haskell/test/Main.hs b/aletheia/templates/haskell/test/Main.hs deleted file mode 100644 index c49d7a6..0000000 --- a/aletheia/templates/haskell/test/Main.hs +++ /dev/null @@ -1,45 +0,0 @@ --- SPDX-License-Identifier: MPL-2.0 --- | Test suite for @@PROJECT_NAME@@. --- --- Deliberately dependency-free: a plain exitcode-stdio runner rather than --- a framework, so the package still needs only `base`. -module Main (main) where - -import Control.Monad (forM_, unless) -import Core (clamp, meanFloor) -import Data.IORef (modifyIORef', newIORef, readIORef) -import System.Exit (exitFailure, exitSuccess) - -main :: IO () -main = do - failures <- newIORef (0 :: Int) - let check label condition = - unless condition $ do - putStrLn ("FAIL: " ++ label) - modifyIORef' failures (+ 1) - - -- clamp: values inside, below and above the range - check "clamp keeps an in-range value" (clamp (5 :: Int) 0 10 == 5) - check "clamp lifts a low value" (clamp (0 :: Int) 1 10 == 1) - check "clamp drops a high value" (clamp (99 :: Int) 0 10 == 10) - check "clamp handles a degenerate range" (clamp (7 :: Int) 7 7 == 7) - - -- clamp: idempotent and always in range - forM_ [0, 1, 5, 42, 10000 :: Int] $ \value -> do - let once = clamp value 10 100 - check "clamp is idempotent" (clamp once 10 100 == once) - check "clamp result is in range" (once >= 10 && once <= 100) - - -- meanFloor: agrees with the naive form where the naive form is safe - forM_ [0 .. 63 :: Word] $ \a -> - forM_ [0 .. 63 :: Word] $ \b -> - check "meanFloor matches naive" (meanFloor a b == (a + b) `div` 2) - - -- meanFloor: never exceeds either input, and cannot overflow - forM_ [(0, 0), (1, 2), (7, 9), (maxBound, 0), (maxBound, maxBound)] $ - \(a, b) -> check "meanFloor bounded" (meanFloor a b <= max a b) - - total <- readIORef failures - if total == 0 - then putStrLn "All tests passed." >> exitSuccess - else putStrLn (show total ++ " test(s) failed.") >> exitFailure diff --git a/aletheia/templates/rust/.editorconfig b/aletheia/templates/rust/.editorconfig deleted file mode 100644 index 32de1c9..0000000 --- a/aletheia/templates/rust/.editorconfig +++ /dev/null @@ -1,22 +0,0 @@ -# @@PROJECT_NAME@@ - Editor Configuration -# https://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 2 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.adoc] -trim_trailing_whitespace = false - -[*.rs] -indent_size = 4 - -[Justfile] -indent_style = space -indent_size = 4 diff --git a/aletheia/templates/rust/.gitignore b/aletheia/templates/rust/.gitignore deleted file mode 100644 index 469d74f..0000000 --- a/aletheia/templates/rust/.gitignore +++ /dev/null @@ -1,23 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Build artefacts -/target/ -**/target/ -Cargo.lock - -# Creusot/Why3 proof artefacts -*.coma -*.mlcfg -verification/verif/ -verification/target/ -.why3find/ - -# Editors and OS -.DS_Store -.idea/ -.vscode/ -*.swp -*~ - -# Local environment -.env -.env.local diff --git a/aletheia/templates/rust/.machine_readable/rsr-profile.a2ml b/aletheia/templates/rust/.machine_readable/rsr-profile.a2ml deleted file mode 100644 index 60c1323..0000000 --- a/aletheia/templates/rust/.machine_readable/rsr-profile.a2ml +++ /dev/null @@ -1,16 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for @@PROJECT_NAME@@. Declares what this repo -# carries so the capability gates compute the applicable criterion set. -[profile] -capabilities = ["rust", "cli", "docs"] - -[rationale] -rust = "true: a Rust 2021 crate (MSRV 1.80) with zero dependencies" -cli = "true: src/main.rs produces a binary" -docs = "true: README.adoc + SECURITY.adoc + CONTRIBUTING.adoc + CODE_OF_CONDUCT.adoc + CHANGELOG.adoc" -no-library = "DECLINED unless a lib target is added; src/lib.rs currently backs the binary's tests" -no-bash = "true: no tracked *.sh; all automation is in the Justfile" -no-container = "true: no Containerfile in the scaffold" -no-reproducible-build = "true: no guix.scm; the zero-dependency crate is offline-buildable via `cargo build --offline`" -no-formal-proofs = "PARTIAL: verification/ carries Creusot proof obligations, but they are not wired into CI until the Creusot toolchain is pinned (see verification/README.adoc)" -no-docs-site = "true: no pages workflow" diff --git a/aletheia/templates/rust/.tool-versions b/aletheia/templates/rust/.tool-versions deleted file mode 100644 index a87d31a..0000000 --- a/aletheia/templates/rust/.tool-versions +++ /dev/null @@ -1,5 +0,0 @@ -# Toolchain pins, asdf/mise compatible. -# The main crate builds on stable with zero dependencies; verification/ -# additionally needs the Creusot toolchain (nightly Rust + Why3), which is -# pinned separately in verification/README.adoc. -rust 1.98.1 diff --git a/aletheia/templates/rust/Justfile b/aletheia/templates/rust/Justfile deleted file mode 100644 index c77b416..0000000 --- a/aletheia/templates/rust/Justfile +++ /dev/null @@ -1,69 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Justfile — build automation for @@PROJECT_NAME@@. -# See: https://github.com/casey/just -# -# Every recipe here is offline: the crate has zero dependencies, so -# `--offline` always succeeds. Recipes fail loudly — a recipe that echoes a -# message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). - -default: - @just --list - -# Build the crate (debug) -build: - cargo build --offline - -# Build the crate in release mode -build-release: - cargo build --offline --release - -# Run the binary; pass arguments after the recipe name -run *ARGS: - cargo run --offline --quiet -- {{ARGS}} - -# Run the full test suite (unit + integration) -test: - cargo test --offline - -# Check formatting without modifying files -fmt: - cargo fmt --check - -# Apply formatting -fmt-fix: - cargo fmt - -# Lint with warnings denied -lint: - cargo clippy --offline --all-targets -- -D warnings - -# Enforce the zero-dependency guarantee (RSR Bronze, air-gapped build) -deps-check: - #!/usr/bin/env bash - set -euo pipefail - if cargo tree --offline --depth 1 | tail -n +2 | grep -q '[a-z]'; then - echo "ERROR: dependencies detected — this crate must stay zero-dependency." - cargo tree --offline --depth 1 - exit 1 - fi - echo "OK: zero dependencies" - -# Verify RSR compliance using the estate checker -verify: - aletheia . - -# --- Rust/Creusot deductive verification (opt-in) --------------------- -# These recipes need the Creusot toolchain (nightly Rust + Why3 + SMT -# solvers). The default build never needs it — see verification/README.adoc. - -# Translate the annotated source to Coma and discharge every obligation -# with Why3. Fails loudly on any unproved goal — this is a real gate. -proof: - cd verification && cargo creusot - -# Remove generated Creusot/Why3 artefacts -proof-clean: - cd verification && cargo creusot clean - -# Everything the CI gate runs, in the same order -check: build test fmt lint deps-check diff --git a/aletheia/templates/rust/README.adoc b/aletheia/templates/rust/README.adoc deleted file mode 100644 index 4fdd4e8..0000000 --- a/aletheia/templates/rust/README.adoc +++ /dev/null @@ -1,112 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= @@PROJECT_NAME@@ -:toc: -:icons: font - -____ -@@PROJECT_DESCRIPTION@@ -____ - -== Quick Start - -[source,bash] ----- -# Build (offline, zero dependencies) -just build - -# Test -just test - -# Verify RSR compliance -just verify ----- - -This project is *standalone by construction*: the scaffold fetches nothing. -`cargo build --offline` works on a machine with no network, because the -crate has zero dependencies and the licence texts ship in-tree under -`+LICENSES/+`. - -== RSR Compliance - -[cols="1,3"] -|=== -|Bronze |Documentation, security policy, SPDX headers, CI, licence classification -|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` -|Gold |No silent-skip recipes -|=== - -Verify with the estate's own checker: - -[source,bash] ----- -aletheia . ----- - -== Language: Rust/Creusot - -Per the estate language policy, Rust in this estate is always *Rust/Creusot* -— Rust plus https://github.com/creusot-rs/creusot[Creusot], the deductive -verifier that translates annotated Rust to Why3 and discharges proof -obligations with SMT solvers. - -The verification crate lives in `+verification/+` and is *deliberately -detached from the default Cargo workspace*, so the main crate stays -zero-dependency and air-gapped. Only `just proof` needs the Creusot -toolchain (nightly Rust + Why3 + SMT solvers), and only when you actually -run it. - -`+src/impl.rs+` is a single source of truth: both `+src/lib.rs+` and -`+verification/src/lib.rs+` `include!` it, so what Creusot verifies is the -code that ships. The specifications are gated behind `+cfg(creusot)+`, which -only `+creusot-rustc+` sets: - -[source,rust] ----- -#[cfg_attr(creusot, requires(lo@ <= hi@))] -#[cfg_attr(creusot, ensures(lo@ <= result@ && result@ <= hi@))] -pub fn clamp(value: u32, lo: u32, hi: u32) -> u32 { ... } ----- - -`+just proof+` translates and discharges both obligations; it exits non-zero -if any goal is unproved. - -See link:verification/README.adoc[verification/README.adoc] for setup. - -== Documentation - -* link:SECURITY.adoc[Security Policy] — vulnerability disclosure -* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute -* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards -* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions -* link:CHANGELOG.adoc[Changelog] — version history - -== Layout - -.... -. -├── Justfile # build automation (capital J — v2 shape) -├── LICENSE # licence statement -├── LICENSES/ # full licence texts (REUSE style) -├── src/ # crate source -├── tests/ # integration tests -├── verification/ # Rust/Creusot proof crate (detached from workspace) -├── .github/workflows/ # CI + estate gates -├── .machine_readable/ # machine-readable metadata -└── .well-known/ # security.txt, ai.txt, humans.txt -.... - -== Contributing - -See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. - -== License - -Code is licensed under the Mozilla Public License, version 2.0 -(`+MPL-2.0+`). Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). - -See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. - -''''' - -_Created from the aletheia v2 Bronze template._ diff --git a/aletheia/templates/zig/.editorconfig b/aletheia/templates/zig/.editorconfig deleted file mode 100644 index a5b818b..0000000 --- a/aletheia/templates/zig/.editorconfig +++ /dev/null @@ -1,19 +0,0 @@ -# @@PROJECT_NAME@@ - Editor Configuration -# https://editorconfig.org - -root = true - -[*] -charset = utf-8 -end_of_line = lf -indent_size = 4 -indent_style = space -insert_final_newline = true -trim_trailing_whitespace = true - -[*.adoc] -trim_trailing_whitespace = false - -[Justfile] -indent_style = space -indent_size = 4 diff --git a/aletheia/templates/zig/.github/workflows/ci.yml b/aletheia/templates/zig/.github/workflows/ci.yml deleted file mode 100644 index 553830f..0000000 --- a/aletheia/templates/zig/.github/workflows/ci.yml +++ /dev/null @@ -1,41 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# This workflow is managed by gh actions-lock. -name: CI - -on: - push: - branches: [main, master] - pull_request: - branches: [main, master] - workflow_dispatch: - -concurrency: - group: ${{ github.workflow }}-${{ github.ref }} - cancel-in-progress: true - -permissions: - actions: read - contents: read - -jobs: - check: - name: Build, test, lint (offline) - runs-on: ubuntu-latest - timeout-minutes: 20 - steps: - - name: Checkout - uses: actions/checkout@v7.0.1 - - - name: Install Zig - uses: mlugg/setup-zig@d1434d08867e3ee9daa34448df10607b98908d29 # v2 - with: - version: 0.16.0 - - - name: Build - run: zig build - - - name: Test - run: zig build test - - - name: Check formatting - run: zig fmt --check build.zig src test diff --git a/aletheia/templates/zig/.gitignore b/aletheia/templates/zig/.gitignore deleted file mode 100644 index b20e72f..0000000 --- a/aletheia/templates/zig/.gitignore +++ /dev/null @@ -1,5 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -/.zig-cache/ -.zig-cache/ -/zig-out/ -zig-out/ diff --git a/aletheia/templates/zig/.machine_readable/rsr-profile.a2ml b/aletheia/templates/zig/.machine_readable/rsr-profile.a2ml deleted file mode 100644 index 85d42c5..0000000 --- a/aletheia/templates/zig/.machine_readable/rsr-profile.a2ml +++ /dev/null @@ -1,12 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# RSR capability profile for @@PROJECT_NAME@@. Declares what this repo -# carries so the capability gates compute the applicable criterion set. -[profile] -capabilities = ["zig", "cli", "docs"] - -[rationale] -zig = "true: build.zig targets Zig 0.16 (see .tool-versions)" -cli = "true: src/main.zig produces an executable" -docs = "true: README + SECURITY + CONTRIBUTING + CODE_OF_CONDUCT + CHANGELOG" -no-library = "shared: src/root.zig is an importable module, but not published as a package" -no-container = "true: no Containerfile in the scaffold" diff --git a/aletheia/templates/zig/.tool-versions b/aletheia/templates/zig/.tool-versions deleted file mode 100644 index 1fa0956..0000000 --- a/aletheia/templates/zig/.tool-versions +++ /dev/null @@ -1,2 +0,0 @@ -# Toolchain pins, asdf/mise compatible. -zig 0.16.0 diff --git a/aletheia/templates/zig/Justfile b/aletheia/templates/zig/Justfile deleted file mode 100644 index f731a6f..0000000 --- a/aletheia/templates/zig/Justfile +++ /dev/null @@ -1,37 +0,0 @@ -# SPDX-License-Identifier: MPL-2.0 -# Justfile — build automation for @@PROJECT_NAME@@. -# See: https://github.com/casey/just -# -# Every recipe here is offline: this project has no external dependencies, -# so nothing is fetched at build time. Recipes fail loudly — a recipe that -# echoes a message and exits 0 would be a fake gate (RSR v2 6.1.5, Gold). - -default: - @just --list - -# Build the executable into zig-out/bin/ -build: - zig build - -# Run the program; pass arguments after the recipe name -run *ARGS: - zig build run -- {{ARGS}} - -# Run unit and integration tests -test: - zig build test - -# Check formatting (does not modify files) -fmt: - zig fmt --check build.zig src test - -# Apply formatting -fmt-fix: - zig fmt build.zig src test - -# Verify RSR compliance using the estate checker -verify: - aletheia . - -# Everything the CI gate runs, in the same order -check: build test fmt diff --git a/aletheia/templates/zig/README.adoc b/aletheia/templates/zig/README.adoc deleted file mode 100644 index 1e89576..0000000 --- a/aletheia/templates/zig/README.adoc +++ /dev/null @@ -1,83 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -= @@PROJECT_NAME@@ -:toc: -:icons: font - -____ -@@PROJECT_DESCRIPTION@@ -____ - -== Quick Start - -[source,bash] ----- -# Build (offline — nothing is downloaded) -just build - -# Test -just test - -# Verify RSR compliance -just verify ----- - -This project is *standalone by construction*: the scaffold fetches nothing, -the build has no external dependencies, and the licence texts ship in-tree -under `+LICENSES/+`. - -== RSR Compliance - -[cols="1,3"] -|=== -|Bronze |Documentation, security policy, SPDX headers, CI, licence classification -|Silver |`.editorconfig`, `.tool-versions`, machine-readable manifests, SHA-pinned CI, `+LICENSES/+` -|Gold |No silent-skip recipes -|=== - -Verify with the estate's own checker: - -[source,bash] ----- -aletheia . ----- - -== Language: @@LANG_DISPLAY@@ - -@@LANG_POLICY@@ - -== Documentation - -* link:SECURITY.adoc[Security Policy] — vulnerability disclosure -* link:CONTRIBUTING.adoc[Contributing Guide] — how to contribute -* link:CODE_OF_CONDUCT.adoc[Code of Conduct] — community standards -* link:MAINTAINERS.adoc[Maintainers] — ownership and decisions -* link:CHANGELOG.adoc[Changelog] — version history - -== Layout - -.... -. -├── Justfile # build automation (capital J — v2 shape) -├── LICENSE # licence statement -├── LICENSES/ # full licence texts (REUSE style) -├── src/ # source (layout follows the language's conventions) -├── .github/workflows/ # CI + estate gates -├── .machine_readable/ # machine-readable metadata -└── .well-known/ # security.txt, ai.txt, humans.txt -.... - -== Contributing - -See link:CONTRIBUTING.adoc[CONTRIBUTING.adoc]. - -== License - -Code is licensed under the Mozilla Public License, version 2.0 -(`+MPL-2.0+`). Documentation is licensed under Creative Commons -Attribution-ShareAlike 4.0 International (`+CC-BY-SA-4.0+`). - -See link:LICENSE[LICENSE] and the `+LICENSES/+` directory for full texts. - -''''' - -_Created from the aletheia v2 Bronze template._ diff --git a/aletheia/templates/zig/build.zig b/aletheia/templates/zig/build.zig deleted file mode 100644 index 1139f72..0000000 --- a/aletheia/templates/zig/build.zig +++ /dev/null @@ -1,71 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -//! Build graph for @@PROJECT_NAME@@. -//! -//! Zero dependencies and no network use: `zig build` compiles from this -//! tree alone, which is why the scaffold works air-gapped. -//! -//! NOTE ON build.zig.zon: there is none. Zig 0.16 requires a package -//! `fingerprint` in it, and — correctly — refuses a fingerprint that was -//! not generated for that package name, so a template cannot ship one -//! without guessing. It is not needed to build: run -//! `zig fetch --save ` when you add your first dependency and Zig -//! will create build.zig.zon with a valid fingerprint for you. - -const std = @import("std"); - -pub fn build(b: *std.Build) void { - const target = b.standardTargetOptions(.{}); - const optimize = b.standardOptimizeOption(.{}); - - // The library module — business logic, importable and testable. - const lib = b.addModule("@@MOD_NAME@@", .{ - .root_source_file = b.path("src/root.zig"), - .target = target, - .optimize = optimize, - }); - - // The CLI, which imports the library under the project's own name. - const exe = b.addExecutable(.{ - .name = "@@PROJECT_NAME@@", - .root_module = b.createModule(.{ - .root_source_file = b.path("src/main.zig"), - .target = target, - .optimize = optimize, - .imports = &.{ - .{ .name = "@@MOD_NAME@@", .module = lib }, - }, - }), - }); - b.installArtifact(exe); - - const run_step = b.step("run", "Run the app"); - const run_cmd = b.addRunArtifact(exe); - run_cmd.step.dependOn(b.getInstallStep()); - if (b.args) |args| run_cmd.addArgs(args); - run_step.dependOn(&run_cmd.step); - - // Unit tests live beside the code they exercise. - const lib_tests = b.addTest(.{ .root_module = lib }); - const run_lib_tests = b.addRunArtifact(lib_tests); - - const exe_tests = b.addTest(.{ .root_module = exe.root_module }); - const run_exe_tests = b.addRunArtifact(exe_tests); - - // Integration tests exercise the public API as a consumer would. - const integration_tests = b.addTest(.{ - .root_module = b.createModule(.{ - .root_source_file = b.path("test/integration_test.zig"), - .target = target, - .optimize = optimize, - .imports = &.{ - .{ .name = "@@MOD_NAME@@", .module = lib }, - }, - }), - }); - const run_integration_tests = b.addRunArtifact(integration_tests); - - const test_step = b.step("test", "Run unit and integration tests"); - test_step.dependOn(&run_lib_tests.step); - test_step.dependOn(&run_exe_tests.step); - test_step.dependOn(&run_integration_tests.step); -} diff --git a/aletheia/templates/zig/src/main.zig b/aletheia/templates/zig/src/main.zig deleted file mode 100644 index 20a6320..0000000 --- a/aletheia/templates/zig/src/main.zig +++ /dev/null @@ -1,73 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -//! @@PROJECT_NAME@@ — command-line entry point. -//! -//! Written against the Zig 0.16 I/O API (`std.process.Init` + `std.Io`). - -const std = @import("std"); -const Io = std.Io; -const core = @import("@@MOD_NAME@@"); - -const usage = - \\@@PROJECT_NAME@@ @@VERSION@@ - \\ - \\usage: - \\ @@PROJECT_NAME@@ clamp clamp a value into a range - \\ @@PROJECT_NAME@@ mean integer mean, rounded down - \\ @@PROJECT_NAME@@ --help show this message - \\ - \\All arguments are unsigned 32-bit integers. -; - -pub fn main(init: std.process.Init) !void { - const arena: std.mem.Allocator = init.arena.allocator(); - const io = init.io; - const args = try init.minimal.args.toSlice(arena); - - var stdout_buffer: [1024]u8 = undefined; - var stdout_file_writer: Io.File.Writer = .init(.stdout(), io, &stdout_buffer); - const stdout = &stdout_file_writer.interface; - - var stderr_buffer: [1024]u8 = undefined; - var stderr_file_writer: Io.File.Writer = .init(.stderr(), io, &stderr_buffer); - const stderr = &stderr_file_writer.interface; - - if (args.len < 2) { - try stdout.print("{s}\n", .{usage}); - try stdout.flush(); - return; - } - - const cmd = args[1]; - if (std.mem.eql(u8, cmd, "--help") or std.mem.eql(u8, cmd, "-h")) { - try stdout.print("{s}\n", .{usage}); - try stdout.flush(); - return; - } - - if (std.mem.eql(u8, cmd, "clamp")) { - if (args.len == 5) { - const value = std.fmt.parseInt(u32, args[2], 10) catch null; - const lo = std.fmt.parseInt(u32, args[3], 10) catch null; - const hi = std.fmt.parseInt(u32, args[4], 10) catch null; - if (value != null and lo != null and hi != null and lo.? <= hi.?) { - try stdout.print("{d}\n", .{core.clamp(value.?, lo.?, hi.?)}); - try stdout.flush(); - return; - } - } - } else if (std.mem.eql(u8, cmd, "mean")) { - if (args.len == 4) { - const a = std.fmt.parseInt(u32, args[2], 10) catch null; - const b = std.fmt.parseInt(u32, args[3], 10) catch null; - if (a != null and b != null) { - try stdout.print("{d}\n", .{core.meanFloor(a.?, b.?)}); - try stdout.flush(); - return; - } - } - } - - try stderr.print("error: unrecognised arguments\n\n{s}\n", .{usage}); - try stderr.flush(); - std.process.exit(1); -} diff --git a/aletheia/templates/zig/src/root.zig b/aletheia/templates/zig/src/root.zig deleted file mode 100644 index b9cf682..0000000 --- a/aletheia/templates/zig/src/root.zig +++ /dev/null @@ -1,48 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -//! Core library for @@PROJECT_NAME@@. -//! -//! Replace these sample functions with your own. - -const std = @import("std"); - -/// Clamp `value` into the inclusive range `[lo, hi]`. -/// -/// Asserts `lo <= hi`; an inverted range is a programming error, not a -/// silent no-op. -pub fn clamp(value: u32, lo: u32, hi: u32) u32 { - std.debug.assert(lo <= hi); - return @min(@max(value, lo), hi); -} - -/// Integer mean of two `u32`s, rounded towards zero. -/// -/// The naive `(a + b) / 2` overflows for large inputs; this form cannot, -/// because it never materialises the sum. -pub fn meanFloor(a: u32, b: u32) u32 { - return (a & b) + ((a ^ b) >> 1); -} - -test "clamp keeps value within range" { - try std.testing.expectEqual(@as(u32, 5), clamp(5, 0, 10)); - try std.testing.expectEqual(@as(u32, 1), clamp(0, 1, 10)); - try std.testing.expectEqual(@as(u32, 10), clamp(99, 0, 10)); -} - -test "clamp handles a degenerate range" { - try std.testing.expectEqual(@as(u32, 7), clamp(7, 7, 7)); -} - -test "meanFloor matches the naive form on small inputs" { - var a: u32 = 0; - while (a < 64) : (a += 1) { - var b: u32 = 0; - while (b < 64) : (b += 1) { - try std.testing.expectEqual((a + b) / 2, meanFloor(a, b)); - } - } -} - -test "meanFloor does not overflow" { - try std.testing.expectEqual(std.math.maxInt(u32), meanFloor(std.math.maxInt(u32), std.math.maxInt(u32))); - try std.testing.expectEqual(std.math.maxInt(u32) / 2, meanFloor(std.math.maxInt(u32), 0)); -} diff --git a/aletheia/templates/zig/test/integration_test.zig b/aletheia/templates/zig/test/integration_test.zig deleted file mode 100644 index f256d3e..0000000 --- a/aletheia/templates/zig/test/integration_test.zig +++ /dev/null @@ -1,37 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -//! Integration tests: exercise the public API as a consumer would. - -const std = @import("std"); -const core = @import("@@MOD_NAME@@"); - -test "clamp is idempotent" { - const values = [_]u32{ 0, 1, 5, 42, std.math.maxInt(u32) }; - for (values) |value| { - const once = core.clamp(value, 10, 100); - try std.testing.expectEqual(once, core.clamp(once, 10, 100)); - } -} - -test "clamp result is always inside the range" { - const lo: u32 = 10; - const hi: u32 = 100; - const values = [_]u32{ 0, 9, 10, 55, 100, 101, std.math.maxInt(u32) }; - for (values) |value| { - const got = core.clamp(value, lo, hi); - try std.testing.expect(got >= lo and got <= hi); - } -} - -test "meanFloor never exceeds either input" { - const cases = [_][2]u32{ - .{ 0, 0 }, - .{ 1, 2 }, - .{ std.math.maxInt(u32), 0 }, - .{ std.math.maxInt(u32), std.math.maxInt(u32) }, - .{ 7, 9 }, - }; - for (cases) |case| { - const mean = core.meanFloor(case[0], case[1]); - try std.testing.expect(mean <= @max(case[0], case[1])); - } -} diff --git a/aletheia/tests/integration_tests.rs b/aletheia/tests/integration_tests.rs deleted file mode 100644 index 7a8eda6..0000000 --- a/aletheia/tests/integration_tests.rs +++ /dev/null @@ -1,1717 +0,0 @@ -// SPDX-License-Identifier: MPL-2.0 -// Copyright (c) Jonathan D.A. Jewell -//! Integration tests for Aletheia RSR compliance verification. -//! -//! End-to-end coverage of the CLI surface: fixtures below encode the RSR -//! v2 file shape ( criteria `hyperpolymath/standards` -//! `0-canon/rsr/rsr-criteria-v2.a2ml`), NOT the retired 2025 v1 shape -//! (LICENSE.txt / justfile / flake.nix / .gitlab-ci.yml). Where v1 and -//! v2 conflict, a dedicated test pins the v2 behaviour. -//! -//! The binary under test is resolved via `CARGO_BIN_EXE_aletheia` (the -//! already-built binary), never via a nested `cargo run`. - -use std::fs; -use std::path::{Path, PathBuf}; -use std::process::Command; - -/// The already-built binary under test. -fn aletheia() -> Command { - Command::new(env!("CARGO_BIN_EXE_aletheia")) -} - -/// Helper to create a temporary test repository. -fn create_test_repo(name: &str) -> PathBuf { - let pid = std::process::id(); - let test_dir = std::env::temp_dir().join(format!("aletheia_test_{pid}_{name}")); - - // Clean up if it exists - if test_dir.exists() { - fs::remove_dir_all(&test_dir).ok(); - } - - fs::create_dir_all(&test_dir).expect("Failed to create test directory"); - test_dir -} - -/// Helper to create a file in the test repo. -fn create_file(base: &Path, path: &str, content: &str) { - let file_path = base.join(path); - - // Create parent directories if needed - if let Some(parent) = file_path.parent() { - fs::create_dir_all(parent).ok(); - } - - fs::write(file_path, content).expect("Failed to create file"); -} - -const PINNED_WORKFLOW: &str = "name: CI\non: [push]\njobs:\n t:\n runs-on: ubuntu-latest\n steps:\n - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1\n"; - -/// Create a fully compliant test repository (Bronze + Silver + Gold). -fn create_fully_compliant_repo(name: &str) -> PathBuf { - let repo = create_test_repo(name); - - // Infrastructure / CI (Bronze + Silver) - create_file(&repo, ".github/workflows/ci.yml", PINNED_WORKFLOW); - create_file(&repo, ".github/workflows/hypatia-scan.yml", PINNED_WORKFLOW); - create_file(&repo, ".github/workflows/governance.yml", PINNED_WORKFLOW); - - // Build system (Bronze + Silver) - create_file( - &repo, - "Justfile", - "build:\n\tcargo build\n\ntest:\n\tcargo test\n", - ); - create_file(&repo, ".editorconfig", "root = true\n"); - create_file(&repo, ".tool-versions", "rust 1.80\n"); - - // Documentation (Bronze) - create_file(&repo, "README.adoc", "= Test Project\n"); - create_file(&repo, "LICENSE", "Mozilla Public License Version 2.0\n"); - create_file( - &repo, - "LICENSES/MPL-2.0.txt", - "Mozilla Public License Version 2.0\n", - ); - create_file(&repo, "SECURITY.md", "# Security Policy\n"); - create_file(&repo, ".gitignore", "target/\n"); - create_file(&repo, ".gitattributes", "*.rs text eol=lf\n"); - - // Documentation (Silver) - create_file(&repo, "CODE_OF_CONDUCT.md", "# Code of Conduct\n"); - create_file(&repo, "CONTRIBUTING.md", "# Contributing\n"); - create_file(&repo, "CHANGELOG.adoc", "== Changelog\n"); - - // Well-known (Silver) - create_file( - &repo, - ".well-known/security.txt", - "Contact: security@example.org\n", - ); - create_file(&repo, ".well-known/ai.txt", "# AI Policy\n"); - create_file(&repo, ".well-known/humans.txt", "# Humans\n"); - - // Machine-readable (Silver) - create_file(&repo, "0-AI-MANIFEST.a2ml", "# agent front door\n"); - create_file( - &repo, - ".machine_readable/rsr-profile.a2ml", - "# capabilities\n", - ); - - // Source with SPDX header (Bronze) - create_file( - &repo, - "src/main.rs", - "// SPDX-License-Identifier: MPL-2.0\nfn main() {}\n", - ); - - repo -} - -/// Test verification of a fully compliant repository. -#[test] -fn test_fully_compliant_repository() { - let repo = create_fully_compliant_repo("compliant"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - assert!( - output.status.success(), - "Fully compliant repository should pass verification: {}", - String::from_utf8_lossy(&output.stderr) - ); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("Bronze-level RSR compliance: ACHIEVED"), - "Should achieve Bronze compliance" - ); - assert!( - stdout.contains("Silver-level RSR compliance: ACHIEVED"), - "Should achieve Silver compliance" - ); - assert!(stdout.contains("Score:"), "Should show score"); - - fs::remove_dir_all(repo).ok(); -} - -/// Test verification of a partially compliant repository. -#[test] -fn test_partially_compliant_repository() { - let repo = create_test_repo("partial"); - - create_file(&repo, "README.md", "# Test Project"); - create_file(&repo, "LICENSE", "Mozilla Public License Version 2.0"); - create_file(&repo, "src/main.rs", "fn main() {}"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - assert!( - !output.status.success(), - "Partially compliant repository should fail verification" - ); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("Bronze-level RSR compliance: NOT MET"), - "Should not achieve Bronze compliance" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test verification of empty repository. -#[test] -fn test_empty_repository() { - let repo = create_test_repo("empty"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - assert!( - !output.status.success(), - "Empty repository should fail verification" - ); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("Bronze-level RSR compliance: NOT MET"), - "Should not meet Bronze compliance" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test handling of non-existent path. -#[test] -fn test_nonexistent_path() { - let output = aletheia() - .arg("/nonexistent/path/that/does/not/exist") - .output() - .expect("Failed to run aletheia"); - - assert!(!output.status.success()); - assert_eq!(output.status.code(), Some(3)); - - let stderr = String::from_utf8_lossy(&output.stderr); - assert!( - stderr.contains("does not exist") || stderr.contains("Error"), - "Should report path error" - ); -} - -/// Test self-verification (Aletheia verifying itself). -#[test] -fn test_self_verification() { - let output = aletheia() - .current_dir(env!("CARGO_MANIFEST_DIR")) - .output() - .expect("Failed to run aletheia self-verification"); - - let stdout = String::from_utf8_lossy(&output.stdout); - - // Bronze compliance must always pass for aletheia itself. - assert!( - stdout.contains("Bronze-level RSR compliance: ACHIEVED"), - "Aletheia should achieve Bronze compliance on itself:\n{stdout}" - ); -} - -/// Test output format consistency. -#[test] -fn test_output_format() { - let output = aletheia() - .current_dir(env!("CARGO_MANIFEST_DIR")) - .output() - .expect("Failed to run aletheia"); - - let stdout = String::from_utf8_lossy(&output.stdout); - - assert!( - stdout.contains("Aletheia - RSR Compliance Verification Report"), - "Should have report header" - ); - assert!( - stdout.contains("Repository:"), - "Should show repository path" - ); - assert!(stdout.contains("Verified:"), "Should show timestamp"); - assert!( - stdout.contains("Documentation"), - "Should have Documentation section" - ); - assert!( - stdout.contains("Well-Known"), - "Should have Well-Known section" - ); - assert!( - stdout.contains("Build System"), - "Should have Build System section" - ); - assert!(stdout.contains("Security"), "Should have Security section"); - assert!(stdout.contains("Score:"), "Should show score"); - assert!( - stdout.contains("Bronze-level RSR compliance:"), - "Should show compliance status" - ); -} - -/// Test JSON output format. -#[test] -fn test_json_output() { - let repo = create_fully_compliant_repo("json_out"); - let output = aletheia() - .args(["--format", "json"]) - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia with JSON format"); - - assert!(output.status.success(), "Should succeed with JSON format"); - - let stdout = String::from_utf8_lossy(&output.stdout); - - assert!(stdout.contains("\"version\":"), "Should have version field"); - assert!( - stdout.contains("\"repository\":"), - "Should have repository field" - ); - assert!( - stdout.contains("\"verified_at\":"), - "Should have verified_at field" - ); - assert!(stdout.contains("\"score\":"), "Should have score field"); - assert!( - stdout.contains("\"bronze_compliant\":"), - "Should have bronze_compliant field" - ); - assert!(stdout.contains("\"checks\":"), "Should have checks array"); - assert!( - stdout.contains("\"warnings\":"), - "Should have warnings array" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test SARIF output format. -#[test] -fn test_sarif_output() { - let repo = create_fully_compliant_repo("sarif_out"); - let output = aletheia() - .args(["--format", "sarif"]) - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia with SARIF format"); - - assert!(output.status.success(), "Should succeed with SARIF format"); - - let stdout = String::from_utf8_lossy(&output.stdout); - - assert!( - stdout.contains("\"version\": \"2.1.0\""), - "Should have SARIF version" - ); - assert!(stdout.contains("\"runs\":"), "Should have runs array"); - assert!(stdout.contains("\"tool\":"), "Should have tool section"); - assert!( - stdout.contains("\"name\": \"aletheia\""), - "Should identify as aletheia" - ); - assert!(stdout.contains("\"rules\":"), "Should have rules"); - assert!(stdout.contains("\"results\":"), "Should have results"); - assert!(stdout.contains("\"ruleId\":"), "Results should have ruleId"); - assert!(stdout.contains("rsr/"), "Rule IDs should use rsr/ prefix"); - - fs::remove_dir_all(repo).ok(); -} - -/// Test quiet mode output (pass). -#[test] -fn test_quiet_mode() { - let repo = create_fully_compliant_repo("quiet_pass"); - let output = aletheia() - .arg("-q") - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia in quiet mode"); - - assert!(output.status.success(), "Should succeed in quiet mode"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert_eq!(stdout.trim(), "PASS", "Quiet mode should only output PASS"); - - fs::remove_dir_all(repo).ok(); -} - -/// Test quiet mode output (fail). -#[test] -fn test_quiet_mode_fail() { - let repo = create_test_repo("quiet_fail"); - let output = aletheia() - .arg("-q") - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia in quiet mode"); - - assert!(!output.status.success()); - let stdout = String::from_utf8_lossy(&output.stdout); - assert_eq!(stdout.trim(), "FAIL", "Quiet mode should only output FAIL"); - - fs::remove_dir_all(repo).ok(); -} - -/// Test verbose mode output. -#[test] -fn test_verbose_mode() { - let repo = create_fully_compliant_repo("verbose"); - let output = aletheia() - .arg("-v") - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia in verbose mode"); - - assert!(output.status.success(), "Should succeed in verbose mode"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("(Verbose)"), "Should indicate verbose mode"); - assert!( - stdout.contains("Version:"), - "Should show version in verbose" - ); - assert!( - stdout.contains("Exit code:"), - "Should show exit code explanation" - ); - assert!( - stdout.contains("Per-tier results:"), - "Should show per-tier counts" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test version flag. -#[test] -fn test_version_flag() { - let output = aletheia() - .arg("--version") - .output() - .expect("Failed to run aletheia with --version"); - - assert!(output.status.success(), "Should succeed with --version"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("aletheia"), "Should show program name"); -} - -/// Test help flag. -#[test] -fn test_help_flag() { - let output = aletheia() - .arg("--help") - .output() - .expect("Failed to run aletheia with --help"); - - assert!(output.status.success(), "Should succeed with --help"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains("USAGE:"), "Should show usage"); - assert!(stdout.contains("OPTIONS:"), "Should show options"); - assert!(stdout.contains("EXIT CODES:"), "Should show exit codes"); - assert!(stdout.contains("EXAMPLES:"), "Should show examples"); - assert!(stdout.contains("sarif"), "Should mention SARIF format"); -} - -/// Test exit codes for non-compliant repository. -#[test] -fn test_exit_code_compliance_failed() { - let repo = create_test_repo("exit_code_fail"); - - create_file(&repo, "README.md", "# Test"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - assert_eq!( - output.status.code(), - Some(1), - "Should exit with code 1 for compliance failure" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test exit code for invalid path. -#[test] -fn test_exit_code_invalid_path() { - let output = aletheia() - .arg("/nonexistent/path/12345") - .output() - .expect("Failed to run aletheia"); - - assert_eq!( - output.status.code(), - Some(3), - "Should exit with code 3 for invalid path" - ); -} - -/// Test exit code for invalid arguments. -#[test] -fn test_exit_code_invalid_args() { - let output = aletheia() - .arg("--invalid-option") - .output() - .expect("Failed to run aletheia"); - - assert_eq!( - output.status.code(), - Some(4), - "Should exit with code 4 for invalid arguments" - ); -} - -/// Test combined format flag. -#[test] -fn test_format_equals_syntax() { - let repo = create_fully_compliant_repo("fmt_eq"); - let output = aletheia() - .arg("--format=json") - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia with --format=json"); - - assert!(output.status.success(), "Should succeed with --format=json"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.starts_with('{'), "Should output JSON"); - - fs::remove_dir_all(repo).ok(); -} - -/// Test README.md accepted as README.adoc alternative. -#[test] -fn test_readme_md_alternative() { - let repo = create_fully_compliant_repo("readme_md"); - fs::remove_file(repo.join("README.adoc")).ok(); - create_file(&repo, "README.md", "# Test Project"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("✅ README.adoc (or README.md)"), - "Should accept README.md as README.adoc alternative" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test LICENSE.txt alone is the retired v1 shape (v2 wants LICENSE). -#[test] -fn test_license_txt_is_retired_shape() { - let repo = create_test_repo("license_txt"); - create_file(&repo, "LICENSE.txt", "MIT License"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("❌ LICENSE file (not LICENSE.txt)"), - "LICENSE.txt alone must fail the v2 license-file check" - ); - assert!( - stdout.contains("retired v1 shape"), - "Should explain the v1 retirement" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test timestamp is present in output. -#[test] -fn test_timestamp_in_output() { - let output = aletheia() - .current_dir(env!("CARGO_MANIFEST_DIR")) - .output() - .expect("Failed to run aletheia"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("Verified:"), - "Should show verification timestamp" - ); - assert!( - stdout.contains('T') && stdout.contains('Z'), - "Timestamp should be in ISO 8601 format" - ); -} - -/// Test .aletheia.toml disabling checks skips them. -#[test] -fn test_config_file() { - let repo = create_fully_compliant_repo("config_test"); - - create_file( - &repo, - ".aletheia.toml", - "[checks]\nchangelog = false\nwellknown-core = false\n", - ); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia with config"); - - assert!( - output.status.success(), - "Should succeed with checks disabled via config" - ); - - let stdout = String::from_utf8_lossy(&output.stdout); - // Disabled checks are skipped, not recorded. - assert!( - !stdout.contains("CHANGELOG.adoc (or .md)"), - "Disabled changelog check should not be reported" - ); - assert!( - !stdout.contains(".well-known core files"), - "Disabled well-known check should not be reported" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test level=silver makes Silver failures fatal. -#[test] -fn test_config_level_silver() { - let repo = create_fully_compliant_repo("level_silver"); - // Break a Silver-only check. - fs::remove_file(repo.join("CHANGELOG.adoc")).ok(); - create_file(&repo, ".aletheia.toml", "[aletheia]\nlevel = \"silver\"\n"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - assert_eq!( - output.status.code(), - Some(1), - "Silver failure with level=silver should exit 1" - ); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("Bronze-level RSR compliance: ACHIEVED"), - "Bronze should still hold" - ); - assert!( - stdout.contains("Silver-level RSR compliance: NOT MET"), - "Silver should fail" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test unknown level falls back to bronze with a warning. -#[test] -fn test_config_unknown_level_falls_back() { - let repo = create_fully_compliant_repo("level_unknown"); - create_file(&repo, ".aletheia.toml", "level = \"copper\"\n"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - assert!(output.status.success(), "Should fall back to bronze"); - let stderr = String::from_utf8_lossy(&output.stderr); - assert!( - stderr.contains("unknown level"), - "Should warn about the unknown level" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test SPDX header detection names the offending file. -#[test] -fn test_spdx_header_detection() { - let repo = create_test_repo("spdx_test"); - - create_file(&repo, "README.md", "# Test"); - create_file( - &repo, - "src/main.rs", - "// SPDX-License-Identifier: MPL-2.0\nfn main() {}", - ); - create_file(&repo, "src/lib.rs", "pub fn hello() {}"); - - let output = aletheia() - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("❌ SPDX license headers"), - "Should fail SPDX check for headerless file" - ); - assert!( - stdout.contains("src/lib.rs"), - "Suggestion should name the offending file" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test --format=sarif syntax. -#[test] -fn test_sarif_format_equals_syntax() { - let repo = create_fully_compliant_repo("sarif_eq"); - let output = aletheia() - .arg("--format=sarif") - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia with --format=sarif"); - - assert!( - output.status.success(), - "Should succeed with --format=sarif" - ); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!( - stdout.contains("sarif-schema-2.1.0"), - "Should reference SARIF schema" - ); - - fs::remove_dir_all(repo).ok(); -} - -/// Test HTML output format. -#[test] -fn test_html_output() { - let repo = create_fully_compliant_repo("html_out"); - let output = aletheia() - .args(["--format", "html"]) - .arg(repo.to_str().unwrap()) - .output() - .expect("Failed to run aletheia with HTML format"); - - assert!(output.status.success(), "Should succeed with HTML format"); - - let stdout = String::from_utf8_lossy(&output.stdout); - assert!(stdout.contains(""), "Should be valid HTML"); - assert!( - stdout.contains("Aletheia Compliance Report"), - "Should have report title" - ); - assert!(stdout.contains("