diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index c224bf2..ac93e68 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -94,6 +94,7 @@ issue-98 = ".hypatia-ignore pruned to a comments-only audit record (all 10 entri 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." @@ -132,3 +133,6 @@ never-commit-dash-a = "Two separate defects reached main in one `git commit -a` 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-branch-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." diff --git a/.machine_readable/rsr-profile.a2ml b/.machine_readable/rsr-profile.a2ml new file mode 100644 index 0000000..fefc395 --- /dev/null +++ b/.machine_readable/rsr-profile.a2ml @@ -0,0 +1,31 @@ +# 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. +[profile] +capabilities = ["rust", "bash", "cli", "docs-site"] + +[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. diff --git a/.tool-versions b/.tool-versions new file mode 100644 index 0000000..6361280 --- /dev/null +++ b/.tool-versions @@ -0,0 +1,4 @@ +# 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`). +rust 1.98.1 diff --git a/.well-known/ai.txt b/.well-known/ai.txt new file mode 120000 index 0000000..741ed75 --- /dev/null +++ b/.well-known/ai.txt @@ -0,0 +1 @@ +../www/.well-known/ai.txt \ No newline at end of file diff --git a/.well-known/humans.txt b/.well-known/humans.txt new file mode 120000 index 0000000..0ec3042 --- /dev/null +++ b/.well-known/humans.txt @@ -0,0 +1 @@ +../www/.well-known/humans.txt \ No newline at end of file diff --git a/.well-known/security.txt b/.well-known/security.txt new file mode 120000 index 0000000..4982a45 --- /dev/null +++ b/.well-known/security.txt @@ -0,0 +1 @@ +../www/.well-known/security.txt \ No newline at end of file diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index 304642f..dcdb443 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -148,9 +148,9 @@ Hypatia's compliance scanner | `contractile.just` + `contractiles/` — shared build recipes | Universal across hyperpolymath repos -| *Guix (preferred dev shell; no manifest in tree)* -| QUICKSTART-DEV prescribes `guix shell`, but no `guix.scm`/`manifest.scm` is committed — environment setup is currently manual -| Ecosystem-wide where adopted (`flake.nix` retired estate-wide 2026-06; no guix-nix-policy gate in this repo) +| *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 diff --git a/QUICKSTART-DEV.adoc b/QUICKSTART-DEV.adoc index d4c3770..919b9fc 100644 --- a/QUICKSTART-DEV.adoc +++ b/QUICKSTART-DEV.adoc @@ -1,113 +1,113 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell -// Template: QUICKSTART-DEV.adoc — clone → build → test → PR -// Replace maa-framework, {{BUILD_CMD}}, {{TEST_CMD}}, {{LANG_STACK}} with actuals -= maa-framework — Quick Start for Developers += QUICKSTART-DEV — maa-framework contributor setup :toc: -:toclevels: 2 -== Tech Stack +// What a working dev loop looks like here, in one page. End users start +// at QUICKSTART-USER.adoc, maintainers at QUICKSTART-MAINTAINER.adoc. -{{LANG_STACK}} +== The stack -== Set Up Development Environment +* **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 (preferred) +== Option A: Guix (reproducible) -[source,bash] +[source,shell] ---- -guix shell +guix shell # auto-discovers manifest.scm at the root +just check ---- -=== Option B: Nix (fallback) +`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. -[source,bash] ----- -nix develop ----- - -=== Option C: Manual +== Option B: rustup (recommended for most) -[source,bash] +[source,shell] ---- -git clone https://github.com/hyperpolymath/maa-framework.git -cd maa-framework -git submodule update --init # absolute-zero/ (pinned upstream proofs) -just setup-dev +rustup toolchain install stable # 1.98.1 at time of writing; MSRV is 1.80 +cargo install just +just check ---- -== Build - -[source,bash] ----- -{{BUILD_CMD}} ----- +System rustc from your distro also works if it meets MSRV — the gate is +`just check`, not how the toolchain arrived. -== Test +== Build, test, MUST -[source,bash] +[source,shell] ---- -{{TEST_CMD}} +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 ---- -== Project Structure +`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. -[source] ----- -maa-framework/ -├── src/ # Source code -├── src/abi/ # Idris2 ABI definitions (if applicable) -├── ffi/zig/ # Zig FFI bridge (if applicable) -├── tests/ # Test suite -├── docs/ # Documentation -├── .machine_readable/ # Checkpoint files (STATE, META, ECOSYSTEM) -├── Justfile # Task runner recipes -├── guix.scm # Guix environment -├── flake.nix # Nix environment (fallback) -└── 0-AI-MANIFEST.a2ml # AI agent entry point ----- +Landmines (each bought with a real incident): -== Key Recipes +* 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. -[source,bash] ----- -just build # Build the project -just test # Run tests -just doctor # Self-diagnostic -just lint # Lint and format -just panic-scan # Security scan via panic-attacker -just tour # Guided tour of the codebase ----- +== Recipes you will actually use -== Before Submitting a PR +`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`. -[source,bash] ----- -just lint # Format and lint -just test # All tests pass -just panic-scan # No new security issues ----- - -== Contractile Invariants +== Wiring a new agent / LLM session in -Read `.machine_readable/MUST.contractile` before making changes. -Key invariants that must never be violated: +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/`. -{{MUST_INVARIANTS}} +== Layout (trimmed) -== LLM/AI Agent Development - -If using an AI assistant, load the warmup context first: - -[source,bash] ----- -just llm-context # Outputs role-appropriate context +[source] ---- - -Or read `0-AI-MANIFEST.a2ml` and `.claude/CLAUDE.md` directly. - -== Get Help - -* **Architecture**: link:EXPLAINME.adoc[EXPLAINME.adoc] -* **Wiki**: https://github.com/hyperpolymath/maa-framework/wiki -* **Report issue**: `just help-me` +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/manifest.scm b/manifest.scm new file mode 100644 index 0000000..3729296 --- /dev/null +++ b/manifest.scm @@ -0,0 +1,14 @@ +;; SPDX-License-Identifier: MPL-2.0 +;; Development manifest for maa-framework. Bare `guix shell` picks this up +;; automatically from the repo root (it searches cwd and parents for +;; manifest.scm — see "Invoking guix shell" in the manual) and provides the +;; toolchain for `just check` on the aletheia crate. +;; +;; Specs verified 2026-09-21: `rust` (unversioned alias in +;; gnu/packages/rust.scm — confirmed via Software Heritage; includes cargo), +;; `just` (gnu/packages/rust-apps.scm, 1.43.0), `git` (used in the manual's +;; own manifest example). No Guix daemon was available where this was +;; written, so it is reviewed, not executed — a bad spec fails loudly at +;; `guix shell` time; fix the spec, not the shell invocation. +(specifications->manifest + (list "rust" "just" "git")) diff --git a/mise.toml b/mise.toml index 6dd983f..236df61 100644 --- a/mise.toml +++ b/mise.toml @@ -1,57 +1,17 @@ +# SPDX-License-Identifier: MPL-2.0 +# Toolchain pins for mise (https://mise.jdx.dev). Kept in sync with +# .tool-versions (the asdf-compatible spelling the RSR tool-versions +# check reads). Pins measured 2026-09-21 from the stable channels. [tools] -# Language runtimes -node = "latest" -python = "latest" -rust = "latest" -go = "latest" -zig = "latest" -java = "latest" -bun = "latest" -denojs = "latest" +# Rust: the only compiled language in tree (aletheia crate, edition 2021, +# MSRV 1.80). Pinned to current stable — what CI's ambient toolchain is. +rust = "1.98.1" -# Package managers -npm = "latest" -yarn = "latest" -pnpm = "latest" -pip = "latest" -cargo = "latest" -go-task = "latest" - -# Formatting & Linting -gofmt = "latest" -black = "latest" -isort = "latest" -ruff = "latest" -prettier = "latest" -shfmt = "latest" -stylua = "latest" - -# Build tools -cmake = "latest" -make = "latest" -ninja = "latest" - -# Shell tools -git = "latest" -gnu-sed = "latest" -gnu-tar = "latest" -gnu-grep = "latest" - -# Testing -vitest = "latest" -pytest = "latest" -jest = "latest" - -[env] -# Common environment variables -NODE_ENV = "development" -PYTHONDONTWRITEBYTECODE = "1" -PYTHONUNBUFFERED = "1" - -# Task runner alias -[alias] -task = "go-task" -build = "cargo build --release || npm run build || go build" -test = "cargo test || npm test || go test ./..." -lint = "ruff check . || prettier --check . || black --check ." -fmt = "ruff format . || prettier --write . || black ." +# just is intentionally NOT pinned: any recent just runs these Justfiles. +# Install via cargo (`cargo install just`) or your package manager. +# git is system-provided, not toolchain-managed. +# +# The 30-entry all-"latest" template this replaced installed runtimes the +# estate bans here (node/python/go) and pinned nothing — "latest" is not a +# pin. Task shortcuts live in the Justfile (`just build/test/check/...`), +# not in mise aliases, so the old [alias] command table went with it.