aprender
CLAUDE.md137 starsChanged 2 months agoMITView on GitHub
Aprender is a next-generation ML framework in pure Rust — a monorepo where the workspace, not this file, is the source of truth. Install: cargo install aprender → apr binary. Core library in crates/aprender-core/ ([lib] name = "aprender"). 20 repos (5 core + 15 satellites, per docs/specifications/aprender-monorepo-consolidation.md) were merged in and archived 20/20. Every count in this file drifted. The published figures were wrong by 3.2× on the test count and 29 minor versions on the release line before they…
- Deletes or force-pushes
- Installs packages
- Commits and pushes
In this repository5 other files it gives its agents.
- code-quality-reviewSkill
- apr-dogfoodSkill
- dogfoodSkill
- pre-releaseSkill
- pr-reviewSkill
The file
Show its rules and text
We split this CLAUDE.md into the rules it gives an agent
20 rules. About 0 are common, 9 are distinctive, and 11 are very specific to this project.
≈0
Common · estimate
Many files like this have a rule of this kind.
≈9
Distinctive · estimate
This author's own choices. Worth a look.
11
Very specific
Tied to their project's names, files or tools. Probably skip.
- Common
- Distinctive
- Very specific
- Distinctive: line 17
Every count in this file drifted.
- Very specific: line 41
Create feature branch: git checkout -b <name>
- Very specific: line 42
Commit on branch, push: git push -u origin <name>
- Very specific: line 51
Run any read-only diagnostic (apr inspect, apr trace, pmat query, gh pr view)
- Distinctive: line 53
Create feature branches and commit work-in-progress
- Very specific: line 56
Update PR branches when BEHIND (gh pr update-branch)
- Very specific: line 59
Update memory files (memory/*.md) with new lessons
- Distinctive: line 75
After landing or arming a PR, emit ONE line:
- Distinctive: line 82
Stop and summarize when:
- Distinctive: line 83
All P0/P1 items in the current §80-class priority queue are landed OR blocked on external compute/auth
- Very specific: line 88
When using /loop, treat fallback wakeups as cheap and merge events as primary.
- Very specific: line 126
Step 0 — pin the binary, ALWAYS: Never invoke a bare apr, and never hardcode an absolute path to one.
- Distinctive: line 169
All tools support GGUF, APR, and SafeTensors formats.
- Very specific: line 245
Always profile with apr profile/apr trace/apr bench before optimizing.
- Very specific: line 390
3. Pin the binary: Never a bare apr, never a hardcoded absolute path — see Step 0 above.
- Very specific: line 469
ci.yml: check, fmt, clippy, test, coverage (Codecov), mutation testing, security audit, docs, bashrs
- Distinctive: line 519
Scores: Only one of these has a citable measurement, so only one is stated:
- Very specific: line 581
If it genuinely isn't a provable contract, use a different YAML schema under a different directory and a purpose-built apr subcommand — not …
- Distinctive: line 628
Write tests targeting those functions
- Distinctive: line 642
Use proactively for trueno SIMD patterns, cross-language equivalents, and stack best practices.
≈ “Common” is an estimate: at least 1 in 5 of the 26,980 CLAUDE.md files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.
Files
CLAUDE.md
Project Overview
Aprender is a next-generation ML framework in pure Rust — a monorepo where the
workspace, not this file, is the source of truth. Install: cargo install aprender →
apr binary. Core library in crates/aprender-core/ ([lib] name = "aprender").
20 repos (5 core + 15 satellites, per docs/specifications/aprender-monorepo-consolidation.md)
were merged in and archived 20/20.
Derive the numbers; do not quote them (#2331)
Every count in this file drifted. The published figures were wrong by 3.2× on the test count and 29 minor versions on the release line before they were checked. So the table gives the command, and the value is only a dated sample. If a number here disagrees with its command, the command wins.
| Fact | Derive with | Sample (2026-08-13) |
| Workspace crates | cargo metadata --no-deps --format-version 1 | python3 -c "import json,sys;print(len(json.load(sys.stdin)['packages']))" | 78 — 77 under crates/ plus the root facade |
Dirs under crates/ | ls -1d crates/*/ | wc -l | 82. This is not the crate count: 4 are excluded in the root Cargo.toml, and aprender-contracts-staging has no manifest. A directory is not a crate |
apr subcommands | apr --help; registry is contracts/apr-cli-commands-v1.yaml §commands, mirrored by crates/apr-cli/tests/cli_commands.rs::registered_commands | 111, in 10 categories |
| Provable contracts | find contracts -name '*.yaml' | wc -l | 1768 |
| Workspace lib tests | the Summary line of CI's workspace-test job (see Build Commands for the exact nextest invocation) | 80,604 passed, 130 skipped, across 69 binaries — CI run 31631488466, main @ d40756541, 2026-08-12 |
| Released version | git tag --sort=-creatordate | head -1 · gh release list | v0.63.0, 2026-08-01 ("provenance") |
crates/aprender-core/tests/readme_contract.rs is the drift gate for all three published
docs: README.md's crate/contract counts, docs/BEATS.md vs the beat contracts, and every
repo-relative file path cited in this file. A path here that does not exist fails the
build (FALSIFY-DOCS-CLAUDE-001) — that is what caught the six pre-monorepo realizar/…
and src/format/… paths this file still advertised. Counts it cannot check, you re-derive.
Git Workflow (Branch Protection)
main is protected. Required status checks: ci / gate + gate + workspace-test. Branch protection names ci / gate, the org ruleset names gate, and a merge needs both. Direct pushes blocked.
- Create feature branch:
git checkout -b <name> - Commit on branch, push:
git push -u origin <name> - Open PR:
gh pr create - CI must pass before merge — enforced by GitHub
Autonomous Operation Mode (DEFAULT)
Operate autonomously by default. Ship PRs, don't ask permission for routine work.
Just do it (no check-in needed)
- Run any read-only diagnostic (
apr inspect,apr trace,pmat query,gh pr view) - Build / test / lint / clippy on any branch
- Create feature branches and commit work-in-progress
- Open PRs with auto-merge armed (
gh pr merge --squash --auto --delete-branch) - Re-run failed CI jobs (
gh run rerun --failed) per memory rules - Update PR branches when BEHIND (
gh pr update-branch) - Author spec amendments (§N entries) when findings warrant
- Capture evidence into
evidence/section-NN-*/findings.json - Update memory files (
memory/*.md) with new lessons - Continue cascades — when one PR lands, automatically start the next prioritized item per §80-class queues
- Record a defect as one line in
docs/findings/<session>.jsonl(schemacontracts/findings-ledger-v1.yaml, appended byscripts/findings_ledger.sh add) or in the cop inbox, not as a new spec section, rather than asking "should I file this?" - Pivot strategies (e.g. when P0-A blocks, immediately try P0-B; when P0-B blocks, surface §81-class amendment and continue to next prereq)
Check in BEFORE acting (real escalations only)
- Compute spend > 1hr on non-lambda-vector hosts (lambda-vector is pre-authorized per
feedback_compute_pre_authorized.md) - Destructive ops:
git push --force,gh release delete, dropping branches/tags on main,cargo yank - Modifying CI workflows (
.github/workflows/*.yml) Crates.io publish cascade (always ask beforeWITHDRAWN — T-4 is unattended under standing operator authorization (APR-RELEASE-001 rev. 2026-09-17 §T-4; 0.68.1 and 0.68.2 both shipped that way withmake publish)attended_min 0; operator, 2026-09-20, verbatim: "tell agent to auto-publish and never wait for me"). The pre-publish gates ARE the authorization: dogfood GO on the release commit, release assets verified, clean-room green on the tag, publish preflight R1–R6, and the--checkdry-run, which is a receipt and not a stop.cargo yankremains a check-in.- Architectural pivots (changing model architecture, retraining from scratch, switching tokenizers)
- Anything contradicting an explicit user instruction earlier in the session
Telemetry mode (one-line per PR)
After landing or arming a PR, emit ONE line:
✅ PR #1699 (P0-F arch case mapping) auto-merge armed — 9/9 unit tests pass, llama-cli now accepts the GGUFThen immediately continue to the next prioritized work. Do NOT ask "should I continue?" — assume yes.
When to stop autonomously
Stop and summarize when:
- All P0/P1 items in the current §80-class priority queue are landed OR blocked on external compute/auth
- A surfaced defect requires architectural decision (e.g. "should we add
--force-overfitor hard-fail?") - 5+ PRs in flight all stuck on the same flake — surface the flake pattern rather than keep rerunning
Loop behavior
When using /loop, treat fallback wakeups as cheap and merge events as primary. Don't poll, don't echo "still waiting." Monitor scripts should emit terminal states only (PASS, FAIL, MERGED).
Build Commands
cargo build --release # Optimized build (every workspace member; no default-members)
cargo test -p aprender-core --lib # Core ML library only
cargo test -p apr-cli --lib # CLI tests only
cargo check --workspace # Type-check the whole workspace
cargo fmt --all -- --check # Check formatting (--all, not just the root package)
cargo clippy -p <crate> --lib -- -D warnings # Strict lint. Bare `cargo clippy` only
# lints the ROOT FACADE package, which is nearly empty
# What CI's `workspace-test` job actually runs (.github/workflows/ci.yml). Reproduce
# THIS, not `cargo test --workspace --lib` — the three excluded crates need a GPU
# toolchain and are gated separately:
cargo nextest run --profile ci --workspace --lib \
--exclude aprender-gpu --exclude aprender-cuda-edge --exclude aprender-compute
cargo test -p aprender-compute --lib # the SIMD crate, run as its own CI step
# Install
cargo install aprender # Install `apr` binary (like cargo install ollama)
apr --version # Verify
# Makefile tiered quality gates
make tier1 # Fast feedback (<1s): fmt, clippy, check
make tier2 # Pre-commit (<5s): tests + strict clippy
make tier3 # Pre-push (1-5min): full validation + coverage
make tier4 # CI/CD: includes pmat analysis
make coverage # Coverage report (enforced floor: COV_FLOOR in Makefile, target ≥95%)Debugging: Use apr Tools First (MANDATORY)
STOP. Before reading code or grepping, USE THE APR DIAGNOSTIC TOOLCHAIN.
GH-202 lesson: we read code instead of running apr qa which would have instantly shown the failure.
Step 0 — pin the binary, ALWAYS. Never invoke a bare apr, and never hardcode
an absolute path to one. Four apr binaries were found coexisting on the dev box
(0.60.0 ×2, 0.61.0, 0.62.0); a bare apr resolved to a 26-day-old copy, and
the path this file used to call "canonical" was two minor versions stale. There is
no correct path to hardcode — the gitignored config.toml under .cargo/ redirects cargo's
target-dir, so the main checkout and a fresh worktree build to different places.
. scripts/apr_bin.sh || exit 1 # exports $APR, proves it was built from HEADEverything below uses "$APR". A diagnostic run against the wrong binary is worse
than no diagnostic: it produces a confident answer about code you are not running.
# Step 1: ALWAYS start here (catches 80% of issues)
"$APR" qa model.apr
# Step 2: Check tensor shapes/stats
"$APR" tensors model.apr | head -20
# Step 3: Diff against known-good model
"$APR" diff model.apr reference.gguf
# Step 4: Format/metadata integrity
"$APR" validate model.apr --quality
"$APR" lint model.apr
# Step 5: ONLY NOW read code| Tool | Purpose |
apr qa | Falsifiable QA gates (first tool for ANY issue) |
apr tensors | Tensor inspection (shapes/stats) |
apr validate | Integrity check |
apr lint | Best practices |
apr diff | Model comparison (tensor-by-tensor) |
apr trace | Layer-by-layer analysis |
apr profile | Roofline analysis (memory vs compute bound) |
apr inspect | Metadata inspection |
apr debug | Quick debug output ("drama" mode for verbose) |
All tools support GGUF, APR, and SafeTensors formats. If a tool says "format not supported", that's a BUG.
Realizar Inference Tracing
There is no realizar binary. realizar is the library name of the
aprender-serve package ([lib] name = "realizar", crates/aprender-serve/Cargo.toml);
that package ships no [[bin]]. Tracing is driven through apr run:
"$APR" run model.safetensors --prompt "2+2?" --trace
"$APR" run model.gguf --prompt "Hi" --trace --trace-steps tokenize,sample,decode
"$APR" run model.gguf --prompt "Hi" --trace --trace-level payload # or --trace-payloadThe flag is --trace-steps <a,b,c> (comma-delimited), not --trace=<...>.
--trace-level accepts none|basic|layer|payload|chrome and defaults to basic.
Implementation: crates/aprender-serve/src/inference_trace/ (a DIRECTORY — mod.rs
plus save_tensor*.rs, gpu_stage_dump.rs, tracer_contracts.rs, …).
TraceSteps (TraceStep in crates/aprender-serve/src/inference_trace/mod.rs): Tokenize, Embed, LayerNorm,
Attention, FFN, TransformerBlock, LmHead, Sample, Decode, KernelLaunch
(PTX-level, GH-219), BrickProfile (trueno BrickProfiler).
Architecture
- Trait-Based Multiple Dispatch - Julia-inspired pattern
- Backend Agnostic - CPU (SIMD), GPU, WASM via Trueno
- Three-Tier API: High (
Estimatortrait), Mid (Optimizer/Loss/Regularizer), Low (Trueno primitives)
Monorepo layout (flat crates/aprender-* per the Polars/Burn/Nushell pattern; for
the crate count run the command in the Project Overview table, don't trust a number here):
crates/aprender-core/— ML library ([lib] name = "aprender")crates/aprender-compute/— SIMD/GPU (was trueno, [lib] name = "trueno")crates/aprender-serve/— inference server (was realizar, [lib] name = "realizar")crates/aprender-train/— training (was entrenar, [lib] name = "entrenar")crates/apr-cli/— CLI logic (internal,aprbinary from root facade)- Root
Cargo.toml— workspace + facade (cargo install aprender→apr)
Runtime: aprender-compute (SIMD), aprender-contracts (provable contracts)
Dev Tools: proptest, criterion, pmat, cargo-mutants
CRITICAL: Realizar-First Architecture
ALL inference/serving MUST use realizar. The aprender crate is for TRAINING ONLY.
| Responsibility | aprender | realizar | trueno |
| Model Training / Autograd | Primary | Never | Compute |
| .apr Format R/W | Primary | Read-only | - |
| Model Serving / HTTP / KV Cache | FORBIDDEN | Primary | Compute/Storage |
| GGUF/SafeTensors Loading | Never | Primary | - |
| CUDA/GPU Inference | Never | Primary | Kernels |
// WRONG - bypasses realizar
use aprender::models::Qwen2Model;
let output = model.generate(&input_ids, 32, 0.7, 0.9);
// CORRECT - uses realizar
use realizar::Model;
let model = Model::load_safetensors(&path)?;
let output = model.generate(&input_ids, config)?;# BEST - apr CLI uses realizar automatically
cargo run --bin apr --features inference -- run model.safetensors \
--prompt "What is 2+2?" --max-tokens 32Feature flag (crates/apr-cli/Cargo.toml): inference = ["realizar", "trueno", "tokio",
"axum", "futures-util"], and default = ["hf-hub", "safetensors-compare", "inference",
"training", "visualization", "zram"] — so inference is on unless you pass
--no-default-features. GPU work needs --features cuda, which pulls in inference,
the cuda features of realizar and entrenar.
Always profile with apr profile/apr trace/apr bench before optimizing.
Performance Targets (Ollama Parity)
| Model | CPU (tok/s) | GPU (tok/s) | Memory |
| 1B Q4_K | 100+ | 500+ | 600MB |
| 7B Q4_K | 30+ | 150+ | 4GB |
| 13B Q4_K | 15+ | 80+ | 8GB |
These are targets, not measurements. For what is actually measured against Ollama,
see docs/BEATS.md: GPU decode on RTX 4090 sm_89 is at parity (1.015–1.109×), and
contracts/beat-ollama-decode-throughput-speed-v1.yaml enforces beat_threshold: 0.9000
— a no-collapse floor. The old "apr beats Ollama 1.371×" headline is withdrawn.
Architecture: Trueno SIMD backend, realizar fused dequant+matmul kernels, PagedAttention KV cache, optional wgpu/CUDA.
FFN Gate+Up Kernel Fusion (PMAT-FFN-FUSION)
The SwiGLU FFN block fuses gate and up projections into a single rayon dispatch via
generic_fused_gate_up_matvec_into<F> (crates/aprender-serve/src/quantize/fused_gate_up.rs:63). This halves
rayon spawn overhead (56→28 dispatches/token on 28-layer models) and improves L1/L2 cache
reuse by loading the activation vector once per midi-tile instead of twice.
- Fused path: Q4K, Q5K, Q6K when both gate+up weights share the same qtype and dims
- Fallback:
rayon::joinwith two separatefused_matmul_intofor mixed types - Q8K path: Existing
fused_q4k_q8k_ffn_up_gate_intostill used when Q8K activations available - Key files:
crates/aprender-serve/src/quantize/fused_gate_up.rs,crates/aprender-serve/src/gguf/inference/fused_matmul_into.rs(fused_gate_up_matmul_into)
LAYOUT-001/002: Tensor Layout Safety
CRITICAL: GGUF/APR use ROW-MAJOR layout. This bug has occurred 100+ times.
APR and realizar are EXCLUSIVELY row-major. GGUF column-major data is transposed at import boundary.
GGUF (col-major) ──(TRANSPOSE at import)──► APR (row-major) ──► realizar ──► output
SafeTensors (native) ──────────────────────► APR (row-major) ──► realizar ──► outputFORBIDDEN IMPORTS (produce garbage):
// NEVER for GGUF/APR data:
use trueno::backends::q4k::matmul_q4k_f32_colmajor;
use trueno::backends::q6k::matmul_q6k_f32_colmajor;
// (and their _dispatch variants)REQUIRED IMPORTS (row-major):
use crate::quantize::fused_q4k_parallel_matvec;
use crate::quantize::fused_q6k_parallel_matvec;Key Files (all under crates/aprender-core/ — the pre-monorepo top-level src/
paths this file used to give have not existed since APR-MONO):
contracts/tensor-layout-v1.yaml- SOURCE OF TRUTHcrates/aprender-core/src/format/layout_contract.rs- Rust validation APIcrates/aprender-core/src/format/converter/write.rs- GGUF→APR import with transposecrates/aprender-core/src/format/converter/mod.rs-transpose_q4k_for_matmul(),transpose_q6k_for_matmul()
use aprender::format::layout_contract::{CONTRACT, LayoutContract};
CONTRACT.should_transpose_gguf("output.weight"); // true for 2D, false for 1D
CONTRACT.validate_apr_shape("lm_head.weight", &[vocab, hidden], vocab, hidden)?;Code Scheduled for Deletion
- DELETED (Refs #224, #1977).src/models/qwen2/mod.rs::generate()/forward()Qwen2Modelhas no inference path; all inference (incl. KV caching) goes throughrealizar. Only construction, weight loading, and introspection remain.examples/qwen_inference.rs- DELETED (Refs #224). Use theaprCLI /realizarfor inference.
Publishing Safety (CB-510 Lesson)
CRITICAL: .gitignore and Cargo.toml exclude patterns must use root-anchored paths.
The unanchored pattern models/ silently matches src/models/ — hiding source code from git and crates.io. Always use /models/ (root-anchored).
# Pre-publish checks (also in make tier3). Both print the count they checked —
# read it off the output, don't quote a number from this file.
bash scripts/check_include_files.sh # scans src/ AND crates/; printed 1771 on 2026-08-13
# After creating new include!() files, verify they're not gitignored:
git ls-files --others --exclude-standard crates/
git check-ignore -v crates/<crate>/src/path/to/new_file.rs # exit 1 == not ignored (good)The one of the two that a merge-path CI step runs verbatim — so it stays a bash claim fence (ONT-4c,
contracts/claude-md.yaml); the fence above is text because no workflow runs those lines:
setsid --wait bash scripts/check_package_includes.sh # as CI runs it; scans src/ ONLY, against `cargo package -p aprender --list`check_package_includes.sh is currently vacuous — know this before trusting it.
It greps include!( in the root src/ only, and the root src/ is a two-file facade
(src/lib.rs, src/bin/) with zero include!() directives. So it reports
OK: All 0 include!() files are included in cargo package and can never fail. The
real coverage against CB-510 today comes from check_include_files.sh (1771 files,
src/ + crates/). Extending the package check to the 70+ publishable member crates
is open work — do not treat its green as evidence.
After any .gitignore or Cargo.toml exclude change: re-run both scripts.
Shell Scripts: Use bashrs (NOT shellcheck)
bashrs lint scripts/*.sh # Lint
bashrs purify scripts/ci.sh # Determinism + idempotency
bashrs make lint Makefile # Makefile linting
bashrs gate --strict . # Full quality gateRequired: set -euo pipefail, no ls for iteration, quoted variables, explicit error handling.
Exception — a SOURCED library must be option-neutral. set in a sourced file
mutates the caller's shell. scripts/apr_bin.sh opened with set -euo pipefail;
qwen-story.sh sources it and had deliberately chosen no -e so it could run every
beat and tally failures. The leak killed the nightly six lines in. Sourceable
libraries fail by return status instead: . scripts/lib.sh || exit 1. Enforced by
scripts/check_sourced_libs_option_neutral.sh.
Verification Discipline (MANDATORY — read before reporting any result)
These are not style notes. Each cost real time, and in every case the general principle was known and the specific instance still went wrong.
1. Never read $? through a pipe. It is the LAST command's status.
cmd > /tmp/out.log 2>&1; rc=$? # correct
cmd | tee /tmp/out.log; rc=${PIPESTATUS[0]} # correct (bash)
cmd | grep -E "^error"; echo "exit=$?" # WRONG — that is grep's statusThis shipped twice — qwen-story-daily captured tee's status so its fail-the-job
step was unreachable and three green runs proved nothing (#2336); make publish's
POST-PUBLISH VERIFICATION did the same, so it could never report a broken published
crate (#2360). When a result looks good, check how it was measured.
2. Never label a run by intent — prove the mechanism engaged. A repro harness
printed device: GPU while built without --features cuda; three findings were
reported from CPU runs. CUDA_VISIBLE_DEVICES says what is visible, never what was
used. Cite a trace line, a version+SHA, or a behaviour delta.
3. Pin the binary. Never a bare apr, never a hardcoded absolute path — see
Step 0 above. Four apr binaries once coexisted here and a bare apr resolved to a
26-day-old one.
4. Extending a guard's SCOPE requires re-mutating in the new scope. The old proof
does not transfer. Extending check_apr_bin_pinned.sh to the Makefile found real
violations and was still blind to \t@apr …, the most common Makefile form — caught
only by re-running the RED-turning mutation there (#2360).
5. A guard that does not scan the surface where the DECISION is made is theater. Enumerate the decision surfaces — release, publish, certify, gate — then check coverage. Covering "CI" is not covering "the release".
6. One failing input is an anecdote. Vary it before naming a cause, and especially before blocking a release. Four neighbouring prompts once inverted a diagnosis from "GPU correctness defect" to "the gate sampled a near-tie" (#2359).
7. Guard regexes ship a case table. The apr-invocation patterns were wrong five
times; every one was caught by a must-match/must-not-match table, none by review.
Re-run the table rather than re-reading the pattern.
8. A shadowed artifact is worse than a missing one — edits look effective and
change nothing. ~/.local/bin/apr shadowed a fresh install; ~/.claude/skills/dogfood/
shadowed the repo's release-certifying skill so hardening it edited a file that never
ran (#2361). When a fix seems to have no effect, ask what else claims that name
(type -aP <cmd>; user-scope vs repo-scope skills; always set an explicit name:).
Testing
Target: 60% unit, 30% property, 10% integration. Coverage: 90.84% line (849706/935347, measured 2026-09-24 by a manual workflow_dispatch of coverage-nightly (run 36065904363) on branch PMAT-3839-cov-regex-scope @ 237f10f8b, folded into batch/0.70.0 and NOT on main until that batch merges; main's own nightly (49fe19c28, 2026-09-24) still measured 826969/941649 = 87.82% under the old regex (run 35937679357); target ≥95%, enforced floor 89% via COV_FLOOR). Before #3839 the exclude regex still described the pre-monorepo tree, so the 88.78% of 2026-07-29 measured a different set of files. The long-quoted "96.35%" predates the measurement ever working - the pipeline reported 0/0 until #2333.
cargo test -p <crate> --lib # Unit tests for one crate (what you run while working)
cargo test -p <crate> --test <target> # ONE integration target. There is NO root
# `tests/` dir, so `cargo test --test integration`
# fails at the workspace root — the `integration.rs`
# targets live per-crate (aprender-core, aprender-data,
# aprender-registry, …)
cargo test --doc # Doctests
make coverage # Coverage report (disables mold linker, single-phase llvm-cov)For the workspace-wide number, reproduce CI's workspace-test nextest command (see
Build Commands) and read its Summary line — 80,604 tests on 2026-08-12. Only a
subset of integration targets is wired into CI: .github/workflows/ci.yml runs --lib
across the workspace, plus the explicit commands in ci/explicit-test-commands.d/ —
one NNN-<slug>.cmd file per command, run in sorted order (beats, cli_commands,
monorepo_invariants, readme_contract, …). A new tests/*.rs file is dark until
a fragment names it; take a free ordinal between two others, never renumber.
Mutation testing: cargo mutants --no-times --timeout 300 --in-place -- --all-features (or via CI).
Linting
Workspace-level lints in Cargo.toml ([workspace.lints.rust] / [workspace.lints.clippy]).
Key: unsafe_code = "forbid", clippy::all + pedantic = "warn", ML-specific allows for casts/float_cmp.
Both ends of the toolchain range are gated (#2370). rust-toolchain.toml pins one
exact release, so every gate we own — make tier1/2/3, sovereign-ci lint — lints
under that one clippy and nothing else.
| End | Guard | Runs |
FLOOR — declared rust-version still builds | scripts/check_msrv.sh | on demand |
| CEILING — current stable clippy is clean | scripts/check_clippy_current_stable.sh / make lint-current | toolchain-ceiling.yml, daily 05:00 UTC |
Without the ceiling gate, findings from newer clippy releases accumulate invisibly:
#2370 was a fresh mbp whose homebrew rustc is not rustup-managed (so the pin is
silently inert) running plain make and getting 28 errors out of tier2 — the tree
had 107 findings across 12 lints by then, none of which any gate had ever run.
The ceiling gate refuses to pass vacuously (stale stable, missing clippy component,
broken version comparator) and ships a comparator case table that tier3 re-runs.
Clippy's lint set is not monotonic: the #2370 tree is clean on 1.93/1.96/1.97 and
1.95 alone reports 8 collapsible_match findings. A green ceiling gate means
"clean on the pin and on current stable", never "clean on every release between".
CI/CD (.github/workflows/)
- ci.yml: check, fmt, clippy, test, coverage (Codecov), mutation testing, security audit, docs, bashrs
- benchmark.yml: criterion benchmarks on PR/weekly, auto PR comments
- security.yml: cargo-audit, cargo-deny (license/banned crates), cargo-outdated (weekly)
- dependabot.yml: weekly Rust deps, monthly GH Actions
- book.yml: EXTREME TDD book to GitHub Pages
- binary-release.yml:
pvbinaries onrelease: published(the release itself is cut by hand:scripts/bump-version.sh, tag,gh release create; see docs/specifications/PP-LLAMA-001-MASTER.md §7.2)
Modules
v0.4.0 (TOP 10 ML): LinearRegression, LogisticRegression, DecisionTree, RandomForest, GBM, NaiveBayes, KNN, SVM, KMeans, PCA + model selection + metrics
v0.7.x (Advanced): ARIMA time series, text processing (tokenizers, stop words, stemming, chat templates via minijinja), Bayesian inference (conjugate priors, BLR), GLMs (Poisson/Gamma/Binomial), ICA decomposition, graph algorithms (Dijkstra/A*/PageRank/community detection)
Key Files
crates/aprender-core/src/lib.rs- ML library entry, module exportscrates/aprender-core/src/traits.rs- Core traits (Estimator, UnsupervisedEstimator, Transformer)crates/aprender-core/src/primitives/- Vector/Matrix with Cholesky solvercrates/aprender-core/src/format/- APR format, validation, lint, converter, exportcrates/aprender-core/src/text/chat_template/- Chat template engine (a DIRECTORY: mod.rs + template.rs/raw_template.rs/ship_008.rs via include!)crates/apr-cli/- CLI logic (command registry:contracts/apr-cli-commands-v1.yaml)src/bin/apr.rs- Root binary entry point (cargo install aprender)contracts/- provable contracts, merged from all 20 repos (find contracts -name '*.yaml' | wc -l)docs/specifications/aprender-monorepo-consolidation.md- Monorepo specdocs/BEATS.md- the public beat scoreboard. Gated againstcontracts/bycrates/aprender-core/tests/readme_contract.rs
APR CLI (cargo install aprender)
111 commands across 10 categories as of 2026-08-15; the registry is
contracts/apr-cli-commands-v1.yaml (§commands), mirrored by
crates/apr-cli/tests/cli_commands.rs::registered_commands and enforced by
FALSIFY-CLI-001/002. The contract deliberately hand-maintains no count — parse
the commands: list, never grep -c '^ - name:' (117; other same-indent
name: keys exist in the file).
Key commands: run, chat, serve, pull, finetune, prune, distill, merge, quantize, inspect, debug, validate, diff, tensors, trace, lint, explain, export, import, convert, compile, train, tune, eval, bench, profile, qa, mcp, probar, cbtop, tui, hex, tree, flow, qualify
apr validate model.apr --quality
apr convert model.safetensors --quantize int8 -o model-int8.apr
apr export model.apr --format gguf -o model.gguf
apr merge model1.apr model2.apr --strategy weighted --weights 0.7,0.3 -o merged.apr
apr qa model.gguf --assert-tps 100 --jsonPMAT Quality Analysis
Version: run pmat --version (3.30.0 on this box, 2026-08-13). .pmat-gates.toml
still carries a header comment claiming it was "Updated for PMAT v2.215.0".
Scores. Only one of these has a citable measurement, so only one is stated:
| Score | Value | Provenance |
| Line coverage | 90.84% (849706/935347) | coverage-nightly workflow_dispatch run 36065904363, 2026-09-24, on branch commit 237f10f8b (monorepo scope, #3839; in batch/0.70.0, not yet main, whose scheduled nightly 35937679357 read 87.82%). The previous 88.78% (2026-07-29, 95145584f) used the pre-monorepo exclude regex. The long-quoted "96.35%"/"96.94%" predates the pipeline ever working — it reported 0/0 until #2333 |
| Project score / TDG / mutation % | re-derive — pmat rust-project-score, pmat tdg . --include-components, cargo mutants | The previously published "124/134", "TDG 95.2/100" and "Mutation 85.3%" carried no date or commit and could not be reproduced from the tree |
Thresholds — read from the config, which does not say what this file used to say:
| Gate | Configured as | Where |
| Coverage (aspirational) | min_coverage = 95.0 | .pmat-gates.toml |
| Coverage (enforced) | COV_FLOOR := 89 — a ratchet under the last measured value, and the one that actually fails a build | Makefile (COV_FLOOR), .github/workflows/coverage-nightly.yml |
| Cyclomatic complexity | max_complexity = 10 per fn | .pmat-gates.toml |
| TDG | min_grade = "B" — not "≥95" | .pmat-gates.toml [tdg] |
| Mutation | MUTANTS_MAX_MISSED (default 0) surviving mutants on the PR diff — not a global 85% score | .github/workflows/ci.yml:517 |
| Verification ladder | min_level = "L3" | .pmat-gates.toml |
unwrap() | banned outright | .clippy.toml disallowed-methods |
SATD is checked by pmat analyze satd, but no SATD threshold is configured in
.pmat-gates.toml; the pre-commit hook there is pmat comply check --failures-only.
pmat quality-gates # Run all gates (config: .pmat-gates.toml)
pmat rust-project-score # Project analysis
pmat analyze complexity # Cyclomatic/cognitive complexity
pmat analyze satd # Zero TODO/FIXME/HACK
pmat tdg . --include-components # Technical debt grading
pmat query "error handling" # Semantic code search with quality annotations (RAG-powered)
pmat embed sync # Sync embeddings for codebase (run before query)unwrap() banned via .clippy.toml disallowed-methods. Use expect() or ok_or_else(|| ...)?. See Issue #41.
Contract Validation: DOGFOOD pv, NEVER bash
provable-contracts is merged in-tree (APR-MONO Phase 2b). It lives as three crates:
crates/aprender-contracts/— evaluation enginecrates/aprender-contracts-macros/—#[contract]derivecrates/aprender-contracts-cli/—pvbinary
pv is THE dogfooded contract CLI. When you need to validate, lint, score, scaffold, diff, audit, generate proofs, or run falsification tests on a YAML contract in contracts/, use pv. Writing a bash/yq/python script that re-implements what pv already does is muda (waste) and will be rejected.
pv validate contracts/apr-code-parity-v1.yaml # schema + falsification gates
pv lint contracts/ # validate + audit + score on all
pv status contracts/tensor-layout-v1.yaml # equations, obligations, coverage
pv query "tensor layout" --limit 5 # search contracts by intent
pv diff contracts/apr-mcp-server-v1.yaml HEAD~3 # semver bump suggestion
pv coverage # cross-contract obligation coveragepv --help lists the full set (42 subcommands + help in pv 0.49.0): explain,
validate, check-parity, scaffold, extract-pytorch, codegen, kani, probar, status,
audit, diff, coverage, generate, graph, equations, lean, lean-status, proof-status,
lint, score, query, invariants, coq, fuzz, mirai, flux, tla, book, infer, unlock,
roofline, pipeline, kaizen, certify, verify-structure, verify-pipeline,
verify-bindings, migrate.
If pv validate rejects a contract (wrong kind, missing required fields), the fix is one of:
- Restructure the contract to fit the existing schema (usually
KernelContractshape withequations,proof_obligations,falsification_tests). - Extend
crates/aprender-contracts/src/schema/to add the newkind+ validator rule (real engineering task, own PMAT ticket). - If it genuinely isn't a provable contract, use a different YAML schema under a different directory and a purpose-built
aprsubcommand — notcontracts/.
Never: work around pv with a shell script. The in-tree tool is the source of truth.
CRITICAL: Code Search Policy
NEVER use grep/glob for code search. ALWAYS use pmat query. The full decision tree, enrichment flags
(-G, --churn, --duplicates, --entropy, --faults), search modes (--regex, --literal) and coverage-gap
workflow are in the author-local ~/.claude/CLAUDE.md; the commands every contributor needs are kept here, plus the coverage + contracts rule below.
pmat query "<intent>" --limit 10 --include-source # semantic search with quality annotations
pmat query "<intent>" --rank-by pagerank # most important functions
pmat query "<intent>" --rank-by indegree # most-called utilities
pmat query "<intent>" --path src/api/ # restrict to a path
pmat query "<intent>" --format json # or markdown; default is text
pmat query "<intent>" --min-grade B --max-complexity 15 --exclude-tests
pmat query "<intent>" -G # fuse git-history intent (also --churn --duplicates --entropy --faults)
# Siblings (aprender, trueno, realizar; 60k+ functions) auto-merge into the index; build once per project:
pmat query "init" --rebuild-index --limit 1Coverage-Guided Search (pmat 3.0.0+)
Use pmat query --coverage to find untested code. NEVER parse coverage JSON manually.
# Find top uncovered functions (no query needed)
pmat query --coverage-gaps
# Find uncovered functions matching a semantic query
pmat query "error handling" --coverage --uncovered-only
# Use pre-existing coverage data (avoids re-running cargo llvm-cov)
pmat query --coverage-gaps --coverage-file /path/to/coverage.json
# Coverage auto-detection: runs `cargo llvm-cov report --json` automatically
# Prerequisite: run `cargo llvm-cov test --lib --no-report` first to generate dataWorkflow for coverage improvement (MUST co-evolve with contracts):
cargo llvm-cov test --lib --no-report— generate coverage datapmat query --coverage-gaps --exclude-tests— find top uncovered functions by impact- For EACH function being tested, ALSO:
a. Add
#[contract]annotation if missing b. Add/strengthen falsification conditions in the relevant contract YAML c. Eliminate placeholder preconditions - Write tests targeting those functions
make coverage— verify improvementpmat comply check— verify contract density improved
RULE: Coverage without contracts is REJECTED. Both must improve together. See monorepo spec Rule 7: Coverage + Contracts Co-Evolution.
Stack Documentation Search
batuta oracle --rag "your question here" # Search entire Sovereign AI Stack
batuta oracle --rag-index # Reindex (the command prints the doc count)Use proactively for trueno SIMD patterns, cross-language equivalents, and stack best practices.
SSC Training Infrastructure Status (snapshot 2026-03-22 — STALE, re-verify before acting)
Moved to docs/ssc-training-status-2026-03-22.md (a 2026-03-22 snapshot, stale; re-verify before acting).
Does it work?
Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.
No reviews yet
People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.
- It worked
- Partly
- It didn't
Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.
Your trail
Files you open will collect here, so you can find them again.
Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.
Now do this for your own.
Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.

