From 31bc84f01e375bc3ddcfbd17c1cb1b933700a498 Mon Sep 17 00:00:00 2001 From: "Jonathan D.A. Jewell" <6759885+hyperpolymath@users.noreply.github.com> Date: Mon, 24 Aug 2026 08:46:18 +0100 Subject: [PATCH] refactor: migrate repository documentation from Markdown to AsciiDoc --- .claude/tasks/prod-readiness/README.adoc | 162 +++++++ .claude/tasks/prod-readiness/README.md | 112 ----- .../prod-readiness/w1-1-neural-guardrail.adoc | 96 ++++ .../prod-readiness/w1-1-neural-guardrail.md | 79 ---- .../w1-2-stats-degenerate-inputs.adoc | 62 +++ .../w1-2-stats-degenerate-inputs.md | 54 --- .../w1-3-executor-router-coverage.adoc | 57 +++ .../w1-3-executor-router-coverage.md | 51 -- .../w1-4-documented-install-path.adoc | 69 +++ .../w1-4-documented-install-path.md | 57 --- .../w1-5-supply-chain-pinning.adoc | 57 +++ .../w1-5-supply-chain-pinning.md | 48 -- .../prod-readiness/w1-6-zig-ffi-compiles.adoc | 69 +++ .../prod-readiness/w1-6-zig-ffi-compiles.md | 60 --- .../prod-readiness/w1-7-agda-proofs-ci.adoc | 61 +++ .../prod-readiness/w1-7-agda-proofs-ci.md | 52 --- .../prod-readiness/w2-1-release-pipeline.adoc | 69 +++ .../prod-readiness/w2-1-release-pipeline.md | 59 --- .../prod-readiness/w2-2-guix-package.adoc | 67 +++ .../tasks/prod-readiness/w2-2-guix-package.md | 56 --- .../tasks/prod-readiness/w2-3-containers.adoc | 65 +++ .../tasks/prod-readiness/w2-3-containers.md | 52 --- .../w2-4-experimental-reframe.adoc | 64 +++ .../w2-4-experimental-reframe.md | 51 -- .../w2-5-reference-validation.adoc | 54 +++ .../w2-5-reference-validation.md | 44 -- .../prod-readiness/w2-6-observability.adoc | 56 +++ .../prod-readiness/w2-6-observability.md | 46 -- .../prod-readiness/w2-7-prompt-injection.adoc | 49 ++ .../prod-readiness/w2-7-prompt-injection.md | 43 -- .../prod-readiness/w2-8-polish-sweep.adoc | 61 +++ .../tasks/prod-readiness/w2-8-polish-sweep.md | 52 --- ABI-FFI-README.md => ABI-FFI-README.adoc | 298 ++++++------ CHANGELOG.adoc | 9 + CHANGELOG.md | 15 - CODE_OF_CONDUCT.adoc | 339 ++++++++++++++ CODE_OF_CONDUCT.md | 311 ------------- CONTRIBUTING.adoc | 113 +++++ CONTRIBUTING.md | 125 ----- GOVERNANCE.adoc | 262 +++++++++++ GOVERNANCE.md | 225 --------- MAINTAINERS.adoc | 63 ++- MAINTAINERS.md | 40 -- PLACEHOLDERS.adoc | 219 +++++++++ PLACEHOLDERS.md | 145 ------ PROOF-NEEDS.adoc | 79 ++++ PROOF-NEEDS.md | 62 --- SECURITY.adoc | 437 ++++++++++++++++++ SECURITY.md | 378 --------------- TEST-NEEDS.adoc | 98 ++++ TEST-NEEDS.md | 66 --- TOPOLOGY.md => TOPOLOGY.adoc | 42 +- docs/AI-CONVENTIONS.adoc | 88 ++++ docs/AI-CONVENTIONS.md | 85 ---- ...-COMPARISON.md => BETLANG-COMPARISON.adoc} | 10 +- docs/CROSS-VERIFICATION-ARCHITECTURE.adoc | 60 +++ docs/CROSS-VERIFICATION-ARCHITECTURE.md | 55 --- docs/QUICKSTART.adoc | 25 + docs/QUICKSTART.md | 25 - docs/THREAT-MODEL.adoc | 316 +++++++++++++ docs/THREAT-MODEL.md | 191 -------- docs/decisions/0000-template.adoc | 33 ++ docs/decisions/0000-template.md | 37 -- docs/decisions/0001-adopt-rsr-standard.adoc | 94 ++++ docs/decisions/0001-adopt-rsr-standard.md | 88 ---- .../0002-kautz-classification-and-target.adoc | 121 +++++ .../0002-kautz-classification-and-target.md | 101 ---- docs/decisions/README.adoc | 18 + docs/decisions/README.md | 19 - docs/tech-debt-2026-05-26.adoc | 70 +++ docs/tech-debt-2026-05-26.md | 56 --- llm-warmup-dev.adoc | 19 + llm-warmup-dev.md | 20 - llm-warmup-user.adoc | 19 + llm-warmup-user.md | 20 - 75 files changed, 3748 insertions(+), 3182 deletions(-) create mode 100644 .claude/tasks/prod-readiness/README.adoc delete mode 100644 .claude/tasks/prod-readiness/README.md create mode 100644 .claude/tasks/prod-readiness/w1-1-neural-guardrail.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-1-neural-guardrail.md create mode 100644 .claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.md create mode 100644 .claude/tasks/prod-readiness/w1-3-executor-router-coverage.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-3-executor-router-coverage.md create mode 100644 .claude/tasks/prod-readiness/w1-4-documented-install-path.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-4-documented-install-path.md create mode 100644 .claude/tasks/prod-readiness/w1-5-supply-chain-pinning.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-5-supply-chain-pinning.md create mode 100644 .claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.md create mode 100644 .claude/tasks/prod-readiness/w1-7-agda-proofs-ci.adoc delete mode 100644 .claude/tasks/prod-readiness/w1-7-agda-proofs-ci.md create mode 100644 .claude/tasks/prod-readiness/w2-1-release-pipeline.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-1-release-pipeline.md create mode 100644 .claude/tasks/prod-readiness/w2-2-guix-package.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-2-guix-package.md create mode 100644 .claude/tasks/prod-readiness/w2-3-containers.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-3-containers.md create mode 100644 .claude/tasks/prod-readiness/w2-4-experimental-reframe.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-4-experimental-reframe.md create mode 100644 .claude/tasks/prod-readiness/w2-5-reference-validation.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-5-reference-validation.md create mode 100644 .claude/tasks/prod-readiness/w2-6-observability.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-6-observability.md create mode 100644 .claude/tasks/prod-readiness/w2-7-prompt-injection.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-7-prompt-injection.md create mode 100644 .claude/tasks/prod-readiness/w2-8-polish-sweep.adoc delete mode 100644 .claude/tasks/prod-readiness/w2-8-polish-sweep.md rename ABI-FFI-README.md => ABI-FFI-README.adoc (65%) create mode 100644 CHANGELOG.adoc delete mode 100644 CHANGELOG.md create mode 100644 CODE_OF_CONDUCT.adoc delete mode 100644 CODE_OF_CONDUCT.md create mode 100644 CONTRIBUTING.adoc delete mode 100644 CONTRIBUTING.md create mode 100644 GOVERNANCE.adoc delete mode 100644 GOVERNANCE.md delete mode 100644 MAINTAINERS.md create mode 100644 PLACEHOLDERS.adoc delete mode 100644 PLACEHOLDERS.md create mode 100644 PROOF-NEEDS.adoc delete mode 100644 PROOF-NEEDS.md create mode 100644 SECURITY.adoc delete mode 100644 SECURITY.md create mode 100644 TEST-NEEDS.adoc delete mode 100644 TEST-NEEDS.md rename TOPOLOGY.md => TOPOLOGY.adoc (92%) create mode 100644 docs/AI-CONVENTIONS.adoc delete mode 100644 docs/AI-CONVENTIONS.md rename docs/{BETLANG-COMPARISON.md => BETLANG-COMPARISON.adoc} (96%) create mode 100644 docs/CROSS-VERIFICATION-ARCHITECTURE.adoc delete mode 100644 docs/CROSS-VERIFICATION-ARCHITECTURE.md create mode 100644 docs/QUICKSTART.adoc delete mode 100644 docs/QUICKSTART.md create mode 100644 docs/THREAT-MODEL.adoc delete mode 100644 docs/THREAT-MODEL.md create mode 100644 docs/decisions/0000-template.adoc delete mode 100644 docs/decisions/0000-template.md create mode 100644 docs/decisions/0001-adopt-rsr-standard.adoc delete mode 100644 docs/decisions/0001-adopt-rsr-standard.md create mode 100644 docs/decisions/0002-kautz-classification-and-target.adoc delete mode 100644 docs/decisions/0002-kautz-classification-and-target.md create mode 100644 docs/decisions/README.adoc delete mode 100644 docs/decisions/README.md create mode 100644 docs/tech-debt-2026-05-26.adoc delete mode 100644 docs/tech-debt-2026-05-26.md create mode 100644 llm-warmup-dev.adoc delete mode 100644 llm-warmup-dev.md create mode 100644 llm-warmup-user.adoc delete mode 100644 llm-warmup-user.md diff --git a/.claude/tasks/prod-readiness/README.adoc b/.claude/tasks/prod-readiness/README.adoc new file mode 100644 index 0000000..ec91170 --- /dev/null +++ b/.claude/tasks/prod-readiness/README.adoc @@ -0,0 +1,162 @@ +== Production-Readiness — Execution Pack + +Self-contained work orders from the 2026-07-10 ten-dimension +production-readiness audit of statistikles. Each file is a standalone +brief runnable by a fresh Claude session with *no dependency on the +originating conversation*, with a recommended model (*Opus / Sonnet / +Haiku*) for implementation and for adversarial verification. + +* *Wave 1* = "`basically running & functioning acceptably`" (the P0 +guarantee + the crash/robustness/coverage/install fixes). Do these +*first*. +* *Wave 2* = everything beyond that (release engineering, packaging, +honesty reframes, deeper test coverage, observability, polish). + +All of wave 1 and most of wave 2 are now *merged to `+main+`*. Only two +work orders remain open: *W2-6 (observability)* and *W2-7 +(prompt-injection delimiting)*. + +=== How to run + +*One task, any session:* > "`Execute the work order in +`+.claude/tasks/prod-readiness/w1-1-neural-guardrail.md+`. > Use the +model it names; follow the execution contract in the README.`" + +*A whole wave as a fleet (Claude Code, budget permitting):* > +`+Workflow({ name: "prod-readiness" })+` — the runner reads this folder, +routes each > task to its model, and does implement → adversarial-verify +→ open-PR. See > `+.claude/workflows/prod-readiness.js+`. + +=== Model routing + +==== Wave 1 — basic functioning (do first, in order) + +*Status (2026-07-11):* all eight wave-1 packages are *MERGED* to +`+main+`. + +[width="100%",cols="10%,15%,20%,15%,20%,20%",options="header",] +|=== +|# |Task |Branch |Impl |Verify |Status +|1 |link:w1-1-neural-guardrail.md[Neural boundary guardrail (*P0*)] +|`+fix/neural-boundary-guardrail+` |*opus* |*opus* |✅ #37 + +|2 |link:w1-2-stats-degenerate-inputs.md[Degenerate-input guards + +`+@assert+`→`+ArgumentError+`] |`+fix/stats-degenerate-inputs+` |sonnet +|opus |✅ #40 + +|3 |link:w1-3-executor-router-coverage.md[Table-driven router tests + CI +coverage] |`+test/executor-router-coverage+` |sonnet |sonnet |✅ #41 + +|4 |link:w1-4-documented-install-path.md[Real install path +(Justfile, quickstarts, smoke CI)] +|`+fix/documented-install-path+` |sonnet |haiku |✅ #34 + +|5 |link:w1-5-supply-chain-pinning.md[Pin compute half + prune +Dependabot + threat model] |`+fix/supply-chain-pinning+` |sonnet |sonnet +|✅ #35 + +|6 |link:w1-6-zig-ffi-compiles.md[Make Zig FFI compile + +`+zig build test+` CI] |`+fix/zig-ffi-compiles+` |*opus* |sonnet |✅ #38 + +|7 |link:w1-7-agda-proofs-ci.md[Type-checking Agda proofs + +`+agda --safe+` CI] |`+fix/agda-proofs-ci+` |*opus* |sonnet |✅ #42 + +|8 |Hygiene / security-templates |`+chore/hygiene-security-templates+` +|haiku |haiku |✅ #33 +|=== + +==== Wave 2 — beyond basic functioning + +*Status (2026-07-11):* six of eight merged; *W2-6* and *W2-7* remain +*OPEN*. A dedicated chi-square correctness review (Yates-clamp fix + +ground-truth tests) also landed as *#47*, outside the original wave +plan. + +[width="100%",cols="10%,15%,20%,15%,20%,20%",options="header",] +|=== +|# |Task |Branch |Impl |Verify |Status +|1 |link:w2-1-release-pipeline.md[Release: JuliaRegistrator + TagBot + +SBOM] |`+feat/release-registrator-tagbot+` |*opus* |*opus* |✅ #43 + +|2 |link:w2-2-guix-package.md[Buildable guix.scm] +|`+feat/guix-real-package+` |*opus* |sonnet |✅ #39 + +|3 |link:w2-3-containers.md[Runnable Containerfile + devcontainer] +|`+feat/containers-runnable+` |sonnet |sonnet |✅ #44 + +|4 |link:w2-4-experimental-reframe.md[Experimental reframe: FFI + proofs +docs] |`+docs/experimental-reframe+` |sonnet |sonnet |✅ #48 + +|5 |link:w2-5-reference-validation.md[Extend ground-truth reference +validation] |`+test/reference-validation-extension+` |sonnet |*opus* |✅ +#46 + +|6 |link:w2-6-observability.md[Structured logging + audit trail] +|`+feat/structured-observability+` |sonnet |sonnet |*OPEN* + +|7 |link:w2-7-prompt-injection.md[Prompt-injection delimiting] +|`+fix/prompt-injection-delimiting+` |sonnet |haiku |*OPEN* + +|8 |link:w2-8-polish-sweep.md[Polish sweep] |`+chore/polish-sweep+` +|haiku |haiku |✅ #45 +|=== + +*Routing rationale.* Opus for design-sensitive, safety-critical, or +niche-toolchain work (the guarantee guardrail, release engineering, +Guix, Zig/Agda, statistical ground-truth). Sonnet for well-specified +implementation. Haiku for mechanical sweeps. Verification is adversarial +— the verifier tries to _refute_ the implementation against the work +order’s acceptance criteria — and is deliberately assigned the model +that should be able to follow the spec: if the verify-model can’t +confirm it, the spec or the code isn’t done. + +=== Decisions of record (user-approved 2026-07-10 — do not relitigate) + +[arabic] +. *Release = JuliaRegistrator + TagBot* (General registry), not +artifact-only. +. *FFI (Zig/C-ABI) and Agda proofs are EXPERIMENTAL* — make them compile +& CI-check (wave 1), reframe docs (wave 2); do NOT invest in the Idris2 +ABI or proofs-over-ℝ yet. +. *guix.scm gets made real* (buildable), not deleted — governance has a +"`Guix primary`" policy check. +. *Merge gate is active*: the Base ruleset requires the "`E2E — Julia +Test Suite`" status check. A PR cannot merge red. + +=== Verified toolchain facts (WSL Debian, set up 2026-07-10) + +* *Julia 1.10.11* via juliaup; on PATH only in a *login shell* +(`+bash -lc+`). Baseline `+Pkg.test()+` = *4404 tests green* (Full 424 / +E2E 145 / Property 3800 / Reference 35). ALWAYS serialize Julia runs: +`+flock /tmp/statistikles-julia.lock -c '…'+` (16 GB RAM ceiling). Warm +depot exists; `+instantiate+precompile+` ≈ 1m46s, test ≈ 36s after +precompile. +* *Zig 0.16.0* tarball at +`+/home/hyperpolymath/zig/zig-x86_64-linux-0.16.0/zig+` (also +`+~/.local/bin/zig+` in login shells). ⚠ 0.15+/0.16 has breaking std +changes (Io writer/reader redesign) — if the repo’s Zig targets ≤0.14, +fetch an older tarball into the same dir. +* *Agda 2.6.4.3 + agda-stdlib 2.1* (apt); stdlib wired via +`+~/.agda/libraries+` + `+~/.agda/defaults+`. ⚠ stdlib 2.1 renamed some +modules vs 1.x — expect import tweaks. + +=== Execution contract (every task) + +* Branch from up-to-date `+origin/main+` using the named branch. If a +wave-1 prerequisite is unmerged and you touch the same files, branch +from that branch and say so in the PR. +* Commits SSH-signed (environment is pre-configured). End messages with +the `+Co-Authored-By+` trailer for your model. +* Run the work order’s *Local verification* before pushing; on 16 GB +RAM, wrap Julia in `+flock /tmp/statistikles-julia.lock+`. Never claim +verification you didn’t run. +* Diffs surgical; match surrounding style. GitHub Actions *SHA-pinned* +with a version comment. Never job-level `+hashFiles()+`/`+secrets+` +conditionals (silent startup_failure) — step-level only. +* *Do not open GitHub issues* and *do not merge/delete/force-push.* Open +exactly one PR to `+main+` per task, titled per the work order; body = +what changed & why (file refs) + verification run & result + anything +skipped. Stop there. +* Python is banned in repo code (governance-enforced). Deriving test +constants with Python/R locally is fine; only the constants + a +derivation note enter the repo. diff --git a/.claude/tasks/prod-readiness/README.md b/.claude/tasks/prod-readiness/README.md deleted file mode 100644 index d09767a..0000000 --- a/.claude/tasks/prod-readiness/README.md +++ /dev/null @@ -1,112 +0,0 @@ - -# Production-Readiness — Execution Pack - -Self-contained work orders from the 2026-07-10 ten-dimension production-readiness -audit of statistikles. Each file is a standalone brief runnable by a fresh Claude -session with **no dependency on the originating conversation**, with a recommended -model (**Opus / Sonnet / Haiku**) for implementation and for adversarial verification. - -- **Wave 1** = "basically running & functioning acceptably" (the P0 guarantee + the - crash/robustness/coverage/install fixes). Do these **first**. -- **Wave 2** = everything beyond that (release engineering, packaging, honesty - reframes, deeper test coverage, observability, polish). - -All of wave 1 and most of wave 2 are now **merged to `main`**. Only two work orders -remain open: **W2-6 (observability)** and **W2-7 (prompt-injection delimiting)**. - -## How to run - -**One task, any session:** -> "Execute the work order in `.claude/tasks/prod-readiness/w1-1-neural-guardrail.md`. -> Use the model it names; follow the execution contract in the README." - -**A whole wave as a fleet (Claude Code, budget permitting):** -> `Workflow({ name: "prod-readiness" })` — the runner reads this folder, routes each -> task to its model, and does implement → adversarial-verify → open-PR. See -> `.claude/workflows/prod-readiness.js`. - -## Model routing - -### Wave 1 — basic functioning (do first, in order) - -**Status (2026-07-11):** all eight wave-1 packages are **MERGED** to `main`. - -| # | Task | Branch | Impl | Verify | Status | -|---|------|--------|------|--------|--------| -| 1 | [Neural boundary guardrail (**P0**)](w1-1-neural-guardrail.md) | `fix/neural-boundary-guardrail` | **opus** | **opus** | ✅ #37 | -| 2 | [Degenerate-input guards + `@assert`→`ArgumentError`](w1-2-stats-degenerate-inputs.md) | `fix/stats-degenerate-inputs` | sonnet | opus | ✅ #40 | -| 3 | [Table-driven router tests + CI coverage](w1-3-executor-router-coverage.md) | `test/executor-router-coverage` | sonnet | sonnet | ✅ #41 | -| 4 | [Real install path (Justfile, quickstarts, smoke CI)](w1-4-documented-install-path.md) | `fix/documented-install-path` | sonnet | haiku | ✅ #34 | -| 5 | [Pin compute half + prune Dependabot + threat model](w1-5-supply-chain-pinning.md) | `fix/supply-chain-pinning` | sonnet | sonnet | ✅ #35 | -| 6 | [Make Zig FFI compile + `zig build test` CI](w1-6-zig-ffi-compiles.md) | `fix/zig-ffi-compiles` | **opus** | sonnet | ✅ #38 | -| 7 | [Type-checking Agda proofs + `agda --safe` CI](w1-7-agda-proofs-ci.md) | `fix/agda-proofs-ci` | **opus** | sonnet | ✅ #42 | -| 8 | Hygiene / security-templates | `chore/hygiene-security-templates` | haiku | haiku | ✅ #33 | - -### Wave 2 — beyond basic functioning - -**Status (2026-07-11):** six of eight merged; **W2-6** and **W2-7** remain **OPEN**. A -dedicated chi-square correctness review (Yates-clamp fix + ground-truth tests) also -landed as **#47**, outside the original wave plan. - -| # | Task | Branch | Impl | Verify | Status | -|---|------|--------|------|--------|--------| -| 1 | [Release: JuliaRegistrator + TagBot + SBOM](w2-1-release-pipeline.md) | `feat/release-registrator-tagbot` | **opus** | **opus** | ✅ #43 | -| 2 | [Buildable guix.scm](w2-2-guix-package.md) | `feat/guix-real-package` | **opus** | sonnet | ✅ #39 | -| 3 | [Runnable Containerfile + devcontainer](w2-3-containers.md) | `feat/containers-runnable` | sonnet | sonnet | ✅ #44 | -| 4 | [Experimental reframe: FFI + proofs docs](w2-4-experimental-reframe.md) | `docs/experimental-reframe` | sonnet | sonnet | ✅ #48 | -| 5 | [Extend ground-truth reference validation](w2-5-reference-validation.md) | `test/reference-validation-extension` | sonnet | **opus** | ✅ #46 | -| 6 | [Structured logging + audit trail](w2-6-observability.md) | `feat/structured-observability` | sonnet | sonnet | **OPEN** | -| 7 | [Prompt-injection delimiting](w2-7-prompt-injection.md) | `fix/prompt-injection-delimiting` | sonnet | haiku | **OPEN** | -| 8 | [Polish sweep](w2-8-polish-sweep.md) | `chore/polish-sweep` | haiku | haiku | ✅ #45 | - -**Routing rationale.** Opus for design-sensitive, safety-critical, or niche-toolchain -work (the guarantee guardrail, release engineering, Guix, Zig/Agda, statistical -ground-truth). Sonnet for well-specified implementation. Haiku for mechanical sweeps. -Verification is adversarial — the verifier tries to *refute* the implementation against -the work order's acceptance criteria — and is deliberately assigned the model that -should be able to follow the spec: if the verify-model can't confirm it, the spec or -the code isn't done. - -## Decisions of record (user-approved 2026-07-10 — do not relitigate) - -1. **Release = JuliaRegistrator + TagBot** (General registry), not artifact-only. -2. **FFI (Zig/C-ABI) and Agda proofs are EXPERIMENTAL** — make them compile & CI-check - (wave 1), reframe docs (wave 2); do NOT invest in the Idris2 ABI or proofs-over-ℝ yet. -3. **guix.scm gets made real** (buildable), not deleted — governance has a "Guix primary" - policy check. -4. **Merge gate is active**: the Base ruleset requires the "E2E — Julia Test Suite" - status check. A PR cannot merge red. - -## Verified toolchain facts (WSL Debian, set up 2026-07-10) - -- **Julia 1.10.11** via juliaup; on PATH only in a **login shell** (`bash -lc`). - Baseline `Pkg.test()` = **4404 tests green** (Full 424 / E2E 145 / Property 3800 / - Reference 35). ALWAYS serialize Julia runs: `flock /tmp/statistikles-julia.lock -c '…'` - (16 GB RAM ceiling). Warm depot exists; `instantiate+precompile` ≈ 1m46s, test ≈ 36s - after precompile. -- **Zig 0.16.0** tarball at `/home/hyperpolymath/zig/zig-x86_64-linux-0.16.0/zig` - (also `~/.local/bin/zig` in login shells). ⚠ 0.15+/0.16 has breaking std changes - (Io writer/reader redesign) — if the repo's Zig targets ≤0.14, fetch an older - tarball into the same dir. -- **Agda 2.6.4.3 + agda-stdlib 2.1** (apt); stdlib wired via `~/.agda/libraries` + - `~/.agda/defaults`. ⚠ stdlib 2.1 renamed some modules vs 1.x — expect import tweaks. - -## Execution contract (every task) - -- Branch from up-to-date `origin/main` using the named branch. If a wave-1 prerequisite - is unmerged and you touch the same files, branch from that branch and say so in the PR. -- Commits SSH-signed (environment is pre-configured). End messages with the - `Co-Authored-By` trailer for your model. -- Run the work order's **Local verification** before pushing; on 16 GB RAM, wrap Julia - in `flock /tmp/statistikles-julia.lock`. Never claim verification you didn't run. -- Diffs surgical; match surrounding style. GitHub Actions **SHA-pinned** with a version - comment. Never job-level `hashFiles()`/`secrets` conditionals (silent startup_failure) - — step-level only. -- **Do not open GitHub issues** and **do not merge/delete/force-push.** Open exactly one - PR to `main` per task, titled per the work order; body = what changed & why (file - refs) + verification run & result + anything skipped. Stop there. -- Python is banned in repo code (governance-enforced). Deriving test constants with - Python/R locally is fine; only the constants + a derivation note enter the repo. diff --git a/.claude/tasks/prod-readiness/w1-1-neural-guardrail.adoc b/.claude/tasks/prod-readiness/w1-1-neural-guardrail.adoc new file mode 100644 index 0000000..e24be41 --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-1-neural-guardrail.adoc @@ -0,0 +1,96 @@ +== W1-1 · Neural boundary guardrail (P0) + hardening + +*Model:* impl=opus · verify=opus · *Branch:* +`+fix/neural-boundary-guardrail+` *Priority: P0 — this is the product’s +raison d’être made real.* + +=== Context + +The flagship guarantee — "`no number is ever produced by the LLM`" — is +currently *prompt-only* (`+src/tools/chat.jl+` SYSTEM_PROMPT ~lines +29-66) with zero output validation. `+chat.jl+` (~114-119) prints +assistant content verbatim; nothing checks that numerals in the reply +came from a tool result. Surrounding this are crash/robustness gaps: +unguarded tool-call JSON parsing, no HTTP timeout, silent-null unknown +sub-types, dropped `+tools+` on follow-up calls (no multi-step +chaining), and `+@assert+`-based resource assumptions. + +=== Requirements (implement in `+src/tools/+`) + +*(a) NEW `+src/tools/guardrail.jl+`:* - `+collect_numbers(x)+` — +recursively harvest every numeric value from tool-result +Dicts/Vectors/nested structures. - +`+extract_numeric_tokens(text::String)+` — find numeric literals in +assistant prose (ints, decimals, scientific notation, percentages). - +`+validate_numeric_provenance(text, tool_results, user_numbers; rtol=1e-6) -> (ok::Bool, orphans::Vector{String})+`. +A token is legitimate if it approx-matches (rtol) any harvested +tool-result number, OR its ÷100 / ×100 variant matches (percent +phrasing), OR it appears in the user’s own input numbers, OR it is a +small structural integer 0..12. + +*(b) `+chat.jl+`:* record all tool results for the turn; after the final +assistant content, run the guardrail (parse user-message numbers as +`+user_numbers+`). If orphans exist AND tool calls happened: ONE retry +asking the model to restate using only tool-result numbers; if orphans +persist, print the reply with a clear warning block listing the +unverified numbers. If the reply has numeric tokens but NO tool call was +made: same retry-once-then-warn with a "`no symbolic computation was +performed`" message. *Never silently rewrite model text — flag, never +fabricate.* + +*(c) `+lmstudio.jl+` `+process_tool_calls+`:* wrap the per-tool-call +body (nested key access + `+JSON3.read+` of arguments, ~lines 88-101) in +try/catch; on failure push a `+role:"tool"+` message with a clean +`+Dict("error"=>...)+` so the model recovers. *Pass the `+tools+` +parameter on the follow-up call* (currently dropped ~line 104) and +iterate tool-call rounds in a bounded loop (max 5) until a reply has no +tool_calls. Add HTTP timeouts to `+call_lm_studio+` and the `+chat.jl+` +HTTP call: `+connect_timeout=10+`, `+readtimeout=120+`, `+retry=false+` +(see `+echidna_adapter.jl+` for the existing pattern); timeout → return +the existing error-Dict shape. + +*(d) `+chat.jl+` REPL while-loop:* try/catch around the turn body — +print a concise error and continue; one bad turn must never kill the +session. + +*(e) `+executor.jl+`:* clamp caller-supplied +`+n_reps+`/`+n_permutations+` to ≤100_000 and component counts `+k+` to +≤20 (return `+Dict("error"=>...)+` when exceeded); add a trailing +`+else return Dict("error"=>"Unknown type '…' for ")+` to EVERY +inner sub-type dispatch (grep every inner if/elseif chain: t_test, +time_series, information_theory, survival_analysis, robust_stats, +causal_inference, spatial_stats, advanced_modeling, algebraic_stats, +nonparametric_test, and any others); gate the `+trace+` backtrace field +in the catch-all behind ENV `+STATISTIKLES_DEBUG+` (default off), +keeping a concise stable error string. + +*(f) tests — NEW `+test/guardrail_test.jl+`:* unit tests for the three +guardrail functions incl. a *clean fixture* (all numbers from tool +results, with rounding/percent variants) that passes and an +*injected-fabrication fixture* that MUST be flagged; tests for +`+process_tool_calls+` recovery with malformed tool_call dicts (missing +keys, non-JSON arguments) — construct response Dicts directly, no HTTP; +tests for clamps and unknown-sub-type else-errors via `+execute_tool+`. +Wire into `+test/runtests.jl+`. + +=== Acceptance criteria + +* [ ] Guardrail flags an injected fabricated number and passes a clean +reply (both tested). +* [ ] Malformed tool-call dicts recover instead of crashing (tested). +* [ ] Every inner sub-type dispatch has an `+else+`-error; clamps +enforced (tested). +* [ ] HTTP calls have timeouts; follow-up call passes `+tools+`; loop is +bounded. +* [ ] Full suite green locally (was 4404 tests) + the new tests. + +=== Local verification + +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'+` +in a WSL login shell +(`+wsl.exe -d Debian -u hyperpolymath -- bash -lc '…'+`). + +=== Out of scope + +Prompt-injection input delimiting (that is W2-7, which builds on this +guardrail). diff --git a/.claude/tasks/prod-readiness/w1-1-neural-guardrail.md b/.claude/tasks/prod-readiness/w1-1-neural-guardrail.md deleted file mode 100644 index ba23a74..0000000 --- a/.claude/tasks/prod-readiness/w1-1-neural-guardrail.md +++ /dev/null @@ -1,79 +0,0 @@ -# W1-1 · Neural boundary guardrail (P0) + hardening - -**Model:** impl=opus · verify=opus · **Branch:** `fix/neural-boundary-guardrail` -**Priority: P0 — this is the product's raison d'être made real.** - -## Context - -The flagship guarantee — "no number is ever produced by the LLM" — is currently -**prompt-only** (`src/tools/chat.jl` SYSTEM_PROMPT ~lines 29-66) with zero output -validation. `chat.jl` (~114-119) prints assistant content verbatim; nothing checks -that numerals in the reply came from a tool result. Surrounding this are crash/robustness -gaps: unguarded tool-call JSON parsing, no HTTP timeout, silent-null unknown sub-types, -dropped `tools` on follow-up calls (no multi-step chaining), and `@assert`-based -resource assumptions. - -## Requirements (implement in `src/tools/`) - -**(a) NEW `src/tools/guardrail.jl`:** -- `collect_numbers(x)` — recursively harvest every numeric value from tool-result - Dicts/Vectors/nested structures. -- `extract_numeric_tokens(text::String)` — find numeric literals in assistant prose - (ints, decimals, scientific notation, percentages). -- `validate_numeric_provenance(text, tool_results, user_numbers; rtol=1e-6) -> (ok::Bool, orphans::Vector{String})`. - A token is legitimate if it approx-matches (rtol) any harvested tool-result number, - OR its ÷100 / ×100 variant matches (percent phrasing), OR it appears in the user's own - input numbers, OR it is a small structural integer 0..12. - -**(b) `chat.jl`:** record all tool results for the turn; after the final assistant -content, run the guardrail (parse user-message numbers as `user_numbers`). If orphans -exist AND tool calls happened: ONE retry asking the model to restate using only -tool-result numbers; if orphans persist, print the reply with a clear warning block -listing the unverified numbers. If the reply has numeric tokens but NO tool call was -made: same retry-once-then-warn with a "no symbolic computation was performed" message. -**Never silently rewrite model text — flag, never fabricate.** - -**(c) `lmstudio.jl` `process_tool_calls`:** wrap the per-tool-call body (nested key -access + `JSON3.read` of arguments, ~lines 88-101) in try/catch; on failure push a -`role:"tool"` message with a clean `Dict("error"=>...)` so the model recovers. **Pass -the `tools` parameter on the follow-up call** (currently dropped ~line 104) and iterate -tool-call rounds in a bounded loop (max 5) until a reply has no tool_calls. Add HTTP -timeouts to `call_lm_studio` and the `chat.jl` HTTP call: `connect_timeout=10`, -`readtimeout=120`, `retry=false` (see `echidna_adapter.jl` for the existing pattern); -timeout → return the existing error-Dict shape. - -**(d) `chat.jl` REPL while-loop:** try/catch around the turn body — print a concise -error and continue; one bad turn must never kill the session. - -**(e) `executor.jl`:** clamp caller-supplied `n_reps`/`n_permutations` to ≤100_000 and -component counts `k` to ≤20 (return `Dict("error"=>...)` when exceeded); add a trailing -`else return Dict("error"=>"Unknown type '…' for ")` to EVERY inner sub-type -dispatch (grep every inner if/elseif chain: t_test, time_series, information_theory, -survival_analysis, robust_stats, causal_inference, spatial_stats, advanced_modeling, -algebraic_stats, nonparametric_test, and any others); gate the `trace` backtrace field -in the catch-all behind ENV `STATISTIKLES_DEBUG` (default off), keeping a concise stable -error string. - -**(f) tests — NEW `test/guardrail_test.jl`:** unit tests for the three guardrail -functions incl. a **clean fixture** (all numbers from tool results, with rounding/percent -variants) that passes and an **injected-fabrication fixture** that MUST be flagged; tests -for `process_tool_calls` recovery with malformed tool_call dicts (missing keys, non-JSON -arguments) — construct response Dicts directly, no HTTP; tests for clamps and -unknown-sub-type else-errors via `execute_tool`. Wire into `test/runtests.jl`. - -## Acceptance criteria - -- [ ] Guardrail flags an injected fabricated number and passes a clean reply (both tested). -- [ ] Malformed tool-call dicts recover instead of crashing (tested). -- [ ] Every inner sub-type dispatch has an `else`-error; clamps enforced (tested). -- [ ] HTTP calls have timeouts; follow-up call passes `tools`; loop is bounded. -- [ ] Full suite green locally (was 4404 tests) + the new tests. - -## Local verification - -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'` -in a WSL login shell (`wsl.exe -d Debian -u hyperpolymath -- bash -lc '…'`). - -## Out of scope - -Prompt-injection input delimiting (that is W2-7, which builds on this guardrail). diff --git a/.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.adoc b/.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.adoc new file mode 100644 index 0000000..0b99e1b --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.adoc @@ -0,0 +1,62 @@ +== W1-2 · Degenerate-input guards + `+@assert+`→`+ArgumentError+` + +*Model:* impl=sonnet · verify=opus · *Branch:* +`+fix/stats-degenerate-inputs+` + +=== Context + +The compute core is correct on the happy path and reference-validated, +but degenerate inputs leak `+NaN+`/`+Inf+` verbatim to the user — +violating the finiteness + JSON- serialisability contract and the +"`nothing fabricated`" guarantee. Separately, ~26 validation `+@assert+` +sites across ~13 modules are the sole guard on user/LLM data; Julia +documents `+@assert+` as disable-able, so mismatched-length/out-of-range +inputs could proceed to `+BoundsError+` or silently-wrong numbers. + +=== Requirements + +*(a) Degenerate guards* (`+src/stats/*.jl+`): skewness requires n≥3; +kurtosis n≥4; pearson/regression guard zero denominators (`+den>0+`, +`+ss_tot>0+`, `+(1-r^2)>0+`); t-tests guard `+se==0+` and `+n<2+`; +zero-variance groups. Follow the guard patterns already in +`+spearman+`/`+one_way_anova+`. On a degenerate case return `+nothing+` +(JSON null) for that field plus, where the Dict shape allows, a short +`+"note"+` explaining why — never NaN/Inf. Also convert misleading +sentinels `+harmonic_mean=0.0+`, `+cv=Inf+`, `+geometric_mean=NaN+` to +`+nothing+`+note. + +*(b) Replace validation `+@assert+`s* that guard user/LLM data with +`+throw(ArgumentError("…"))+` carrying a precise message (grep +`+@assert+` under `+src/+`; known sites include +`+correlation_regression.jl:17,54,206+`, `+descriptive.jl:132+`, +`+information_theory.jl:26+`, `+representations.jl:15+`, +`+bridge/typell_levels.jl:59+`). Add NEW `+src/stats/validation.jl+` +with small helpers (`+require_equal_length+`, `+require_nonempty+`, +`+require_positive+`, `+require_probability+`, …) and use them. Keep +`+@assert+` only for true internal invariants. + +*(c) tests — NEW `+test/degenerate_input_test.jl+`:* n=1/2/3 vectors, +constant vectors, zero-variance two-group cases; assert no +`+NaN+`/`+Inf+` anywhere in returned Dicts (reuse the serialisability +walk from `+e2e_test.jl+`); `+@test_throws ArgumentError+` for the +converted validations. Wire into `+runtests.jl+`. + +*NOTE:* `+descriptive_stats+`’ `+outlier_fences+` was already fixed to a +`+Vector+` (PR #31, merged). Do not touch it. + +=== Acceptance criteria + +* [ ] No core stat function returns NaN/Inf on degenerate input +(tested). +* [ ] Converted validations throw `+ArgumentError+` (tested). +* [ ] Full suite green + new tests. + +=== Local verification + +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'+` +(WSL login shell). Sibling W1-1 also adds guards; if both are unmerged +and overlap on a file, note it — do not duplicate. + +=== Out of scope + +The guardrail/provenance layer (W1-1); reference-value coverage (W2-5). diff --git a/.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.md b/.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.md deleted file mode 100644 index 781dfa5..0000000 --- a/.claude/tasks/prod-readiness/w1-2-stats-degenerate-inputs.md +++ /dev/null @@ -1,54 +0,0 @@ -# W1-2 · Degenerate-input guards + `@assert`→`ArgumentError` - -**Model:** impl=sonnet · verify=opus · **Branch:** `fix/stats-degenerate-inputs` - -## Context - -The compute core is correct on the happy path and reference-validated, but degenerate -inputs leak `NaN`/`Inf` verbatim to the user — violating the finiteness + JSON- -serialisability contract and the "nothing fabricated" guarantee. Separately, ~26 -validation `@assert` sites across ~13 modules are the sole guard on user/LLM data; -Julia documents `@assert` as disable-able, so mismatched-length/out-of-range inputs -could proceed to `BoundsError` or silently-wrong numbers. - -## Requirements - -**(a) Degenerate guards** (`src/stats/*.jl`): skewness requires n≥3; kurtosis n≥4; -pearson/regression guard zero denominators (`den>0`, `ss_tot>0`, `(1-r^2)>0`); t-tests -guard `se==0` and `n<2`; zero-variance groups. Follow the guard patterns already in -`spearman`/`one_way_anova`. On a degenerate case return `nothing` (JSON null) for that -field plus, where the Dict shape allows, a short `"note"` explaining why — never -NaN/Inf. Also convert misleading sentinels `harmonic_mean=0.0`, `cv=Inf`, -`geometric_mean=NaN` to `nothing`+note. - -**(b) Replace validation `@assert`s** that guard user/LLM data with -`throw(ArgumentError("…"))` carrying a precise message (grep `@assert` under `src/`; -known sites include `correlation_regression.jl:17,54,206`, `descriptive.jl:132`, -`information_theory.jl:26`, `representations.jl:15`, `bridge/typell_levels.jl:59`). Add -NEW `src/stats/validation.jl` with small helpers (`require_equal_length`, -`require_nonempty`, `require_positive`, `require_probability`, …) and use them. Keep -`@assert` only for true internal invariants. - -**(c) tests — NEW `test/degenerate_input_test.jl`:** n=1/2/3 vectors, constant vectors, -zero-variance two-group cases; assert no `NaN`/`Inf` anywhere in returned Dicts (reuse -the serialisability walk from `e2e_test.jl`); `@test_throws ArgumentError` for the -converted validations. Wire into `runtests.jl`. - -**NOTE:** `descriptive_stats`' `outlier_fences` was already fixed to a `Vector` (PR #31, -merged). Do not touch it. - -## Acceptance criteria - -- [ ] No core stat function returns NaN/Inf on degenerate input (tested). -- [ ] Converted validations throw `ArgumentError` (tested). -- [ ] Full suite green + new tests. - -## Local verification - -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'` -(WSL login shell). Sibling W1-1 also adds guards; if both are unmerged and overlap on a -file, note it — do not duplicate. - -## Out of scope - -The guardrail/provenance layer (W1-1); reference-value coverage (W2-5). diff --git a/.claude/tasks/prod-readiness/w1-3-executor-router-coverage.adoc b/.claude/tasks/prod-readiness/w1-3-executor-router-coverage.adoc new file mode 100644 index 0000000..e5d7ccd --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-3-executor-router-coverage.adoc @@ -0,0 +1,57 @@ +== W1-3 · Table-driven router tests + CI coverage + +*Model:* impl=sonnet · verify=sonnet · *Branch:* +`+test/executor-router-coverage+` + +=== Context + +`+src/tools/executor.jl+` has ~75 dispatch arms but `+execute_tool+` is +tested exactly once (anova, `+reference_validation_test.jl:103+`). The +string→function mapping and argument coercion — the precise layer the +LLM drives — is unverified for 74/75 tools; `+lmstudio.jl+` has zero +test references. Coverage is entirely unmeasured (no flag, no reporter, +no gate) across ~90 source files. + +=== Requirements + +*(a) NEW `+test/executor_router_test.jl+`:* programmatically enumerate +every registered tool name from `+src/tools/definitions.jl+` (parse the +definitions structure — do NOT hand-copy the list); maintain a table of +minimal valid arguments per tool; for each, call +`+execute_tool(name, args)+` and assert the result is a `+Dict+` NOT +containing `+"error"+`. Maintain an explicit skip-list with a reason +string for tools genuinely needing external services/files, and assert +the skip-list stays small. For ≥5 high-traffic tools (t_test, +descriptive_stats, correlation, regression, mann_whitney) cross-check +key numbers against the direct Julia function call (the anova pattern). +*The test must FAIL if a new tool is registered without a table entry or +skip reason* — that is the point. Wire into `+runtests.jl+`. + +*(b) `+.github/workflows/e2e.yml+`:* switch to +`+Pkg.test(coverage=true)+`; add a SHA-pinned +`+julia-actions/julia-processcoverage+` step; compute total % and echo +to `+GITHUB_STEP_SUMMARY+`; upload an lcov artifact. *INFORMATIONAL +only* (no threshold gate yet). Match existing SHA-pinning style (every +action pinned by full commit SHA + version comment). + +*Sibling caution:* W1-1 adds `+else+`-error branches for unknown +sub-types and clamps — do NOT assert unknown sub-types return +`+nothing+`, and use argument values within clamp bounds. + +=== Acceptance criteria + +* [ ] Every registered tool is exercised or explicitly +skipped-with-reason (tested). +* [ ] ≥5 tools cross-checked vs direct calls. +* [ ] e2e.yml runs with coverage and reports a %; actions SHA-pinned. +* [ ] Full suite green + new test. + +=== Local verification + +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'+` +(WSL login shell). YAML: actionlint if available, else careful review. + +=== Out of scope + +Enforcing a coverage threshold (informational first); extending +ground-truth reference values (W2-5). diff --git a/.claude/tasks/prod-readiness/w1-3-executor-router-coverage.md b/.claude/tasks/prod-readiness/w1-3-executor-router-coverage.md deleted file mode 100644 index f519d50..0000000 --- a/.claude/tasks/prod-readiness/w1-3-executor-router-coverage.md +++ /dev/null @@ -1,51 +0,0 @@ -# W1-3 · Table-driven router tests + CI coverage - -**Model:** impl=sonnet · verify=sonnet · **Branch:** `test/executor-router-coverage` - -## Context - -`src/tools/executor.jl` has ~75 dispatch arms but `execute_tool` is tested exactly once -(anova, `reference_validation_test.jl:103`). The string→function mapping and argument -coercion — the precise layer the LLM drives — is unverified for 74/75 tools; `lmstudio.jl` -has zero test references. Coverage is entirely unmeasured (no flag, no reporter, no gate) -across ~90 source files. - -## Requirements - -**(a) NEW `test/executor_router_test.jl`:** programmatically enumerate every registered -tool name from `src/tools/definitions.jl` (parse the definitions structure — do NOT -hand-copy the list); maintain a table of minimal valid arguments per tool; for each, -call `execute_tool(name, args)` and assert the result is a `Dict` NOT containing -`"error"`. Maintain an explicit skip-list with a reason string for tools genuinely -needing external services/files, and assert the skip-list stays small. For ≥5 -high-traffic tools (t_test, descriptive_stats, correlation, regression, mann_whitney) -cross-check key numbers against the direct Julia function call (the anova pattern). **The -test must FAIL if a new tool is registered without a table entry or skip reason** — that -is the point. Wire into `runtests.jl`. - -**(b) `.github/workflows/e2e.yml`:** switch to `Pkg.test(coverage=true)`; add a -SHA-pinned `julia-actions/julia-processcoverage` step; compute total % and echo to -`GITHUB_STEP_SUMMARY`; upload an lcov artifact. **INFORMATIONAL only** (no threshold -gate yet). Match existing SHA-pinning style (every action pinned by full commit SHA + -version comment). - -**Sibling caution:** W1-1 adds `else`-error branches for unknown sub-types and clamps — -do NOT assert unknown sub-types return `nothing`, and use argument values within clamp -bounds. - -## Acceptance criteria - -- [ ] Every registered tool is exercised or explicitly skipped-with-reason (tested). -- [ ] ≥5 tools cross-checked vs direct calls. -- [ ] e2e.yml runs with coverage and reports a %; actions SHA-pinned. -- [ ] Full suite green + new test. - -## Local verification - -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'` -(WSL login shell). YAML: actionlint if available, else careful review. - -## Out of scope - -Enforcing a coverage threshold (informational first); extending ground-truth reference -values (W2-5). diff --git a/.claude/tasks/prod-readiness/w1-4-documented-install-path.adoc b/.claude/tasks/prod-readiness/w1-4-documented-install-path.adoc new file mode 100644 index 0000000..357e0c8 --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-4-documented-install-path.adoc @@ -0,0 +1,69 @@ +== W1-4 · Make the documented install path real + +*Model:* impl=sonnet · verify=haiku · *Branch:* +`+fix/documented-install-path+` + +=== Context + +`+QUICKSTART-USER.adoc+` drives +`+just setup+`/`+just run+`/`+just deps+`, but `+setup+` doesn’t exist, +`+run+` prints "`Run not configured yet`" (`+Justfile:347-349+`), +`+deps+`/`+build+` are no-op echoes with TODOs. A new user following the +documented quickstart cannot install or run. Only the raw README +`+julia --project=.+` path works. Four quickstarts diverge; +`+docs/QUICKSTART.md+` even clones a different repo. + +=== Requirements + +*(a) Justfile* — real recipes wrapping the working commands: +`+setup: julia --project=. -e 'using Pkg; Pkg.instantiate()'+`; +`+deps:+` alias/dependency of setup; +`+build: julia --project=. -e 'using Pkg; Pkg.precompile()'+`; +`+run: julia --project=. -e 'using Statistikles; main()'+`. Keep the +test recipe correct. If docs reference `+stapeln-run+`, either alias it +to `+run+` or drop the reference — be consistent. + +*(b) Quickstarts* — replace remaining template placeholder content in +`+QUICKSTART-USER.adoc+` (token list ~line 4, "`See README.adoc`" body) +with a real minimal quickstart matching the new recipes; correct +expected-output claims (check what `+src/Statistikles.jl+` `+main()+` +actually prints — don’t promise unprinted strings). +`+QUICKSTART-DEV.adoc+`: replace +`+{{BUILD_CMD}}+`/`+{{TEST_CMD}}+`/`+{{LANG_STACK}}+` with real Julia +commands; fix references to nonexistent +`+just setup-dev+`/`+panic-scan+`/`+flake.nix+`/ `+tests/+` (tests live +in `+test/+`). `+QUICKSTART-MAINTAINER.adoc+`: trim references to +missing recipes. `+docs/QUICKSTART.md+`: reconcile to statistikles or +reduce to a pointer. *One canonical, tested command story.* + +*(c) `+.tool-versions+`:* add `+julia+` pinned to the CI minor (check +`+e2e.yml+` — 1.10.x). + +*(d) `+README.adoc+`:* fix the module-count claim (says 17; count +`+src/stats/*.jl+` and state the real number — audit found ~40). + +*(e) NEW `+.github/workflows/install-smoke.yml+`:* ubuntu-latest; +SHA-pinned `+actions/checkout+` + `+julia-actions/setup-julia+` (1.10) +matching repo pinning style; install `+just+` (SHA-pinned action or +apt); run +`+just setup && julia --project=. -e 'using Statistikles' && just --list+`. +NO job-level `+hashFiles()+`/`+secrets+` conditionals — step-level only. + +=== Acceptance criteria + +* [ ] Every recipe referenced by any quickstart exists in the Justfile +(grep-verified). +* [ ] No `+{{placeholders}}+` remain in touched docs. +* [ ] install-smoke.yml is schema-valid and SHA-pinned. +* [ ] README module count matches reality. + +=== Local verification + +In WSL: `+sudo apt-get install -y just+` (NOPASSWD sudo), then +`+just --list+` in the repo parses; grep that every +quickstart-referenced recipe exists. Optionally `+just setup+` under the +Julia lock. + +=== Out of scope + +Container/devcontainer install (W2-3); release (W2-1). diff --git a/.claude/tasks/prod-readiness/w1-4-documented-install-path.md b/.claude/tasks/prod-readiness/w1-4-documented-install-path.md deleted file mode 100644 index 36f2a3a..0000000 --- a/.claude/tasks/prod-readiness/w1-4-documented-install-path.md +++ /dev/null @@ -1,57 +0,0 @@ -# W1-4 · Make the documented install path real - -**Model:** impl=sonnet · verify=haiku · **Branch:** `fix/documented-install-path` - -## Context - -`QUICKSTART-USER.adoc` drives `just setup`/`just run`/`just deps`, but `setup` doesn't -exist, `run` prints "Run not configured yet" (`Justfile:347-349`), `deps`/`build` are -no-op echoes with TODOs. A new user following the documented quickstart cannot install -or run. Only the raw README `julia --project=.` path works. Four quickstarts diverge; -`docs/QUICKSTART.md` even clones a different repo. - -## Requirements - -**(a) Justfile** — real recipes wrapping the working commands: -`setup: julia --project=. -e 'using Pkg; Pkg.instantiate()'`; `deps:` alias/dependency -of setup; `build: julia --project=. -e 'using Pkg; Pkg.precompile()'`; -`run: julia --project=. -e 'using Statistikles; main()'`. Keep the test recipe correct. -If docs reference `stapeln-run`, either alias it to `run` or drop the reference — be -consistent. - -**(b) Quickstarts** — replace remaining template placeholder content in -`QUICKSTART-USER.adoc` (token list ~line 4, "See README.adoc" body) with a real minimal -quickstart matching the new recipes; correct expected-output claims (check what -`src/Statistikles.jl` `main()` actually prints — don't promise unprinted strings). -`QUICKSTART-DEV.adoc`: replace `{{BUILD_CMD}}`/`{{TEST_CMD}}`/`{{LANG_STACK}}` with real -Julia commands; fix references to nonexistent `just setup-dev`/`panic-scan`/`flake.nix`/ -`tests/` (tests live in `test/`). `QUICKSTART-MAINTAINER.adoc`: trim references to -missing recipes. `docs/QUICKSTART.md`: reconcile to statistikles or reduce to a pointer. -**One canonical, tested command story.** - -**(c) `.tool-versions`:** add `julia` pinned to the CI minor (check `e2e.yml` — 1.10.x). - -**(d) `README.adoc`:** fix the module-count claim (says 17; count `src/stats/*.jl` and -state the real number — audit found ~40). - -**(e) NEW `.github/workflows/install-smoke.yml`:** ubuntu-latest; SHA-pinned -`actions/checkout` + `julia-actions/setup-julia` (1.10) matching repo pinning style; -install `just` (SHA-pinned action or apt); run `just setup && julia --project=. -e 'using Statistikles' && just --list`. -NO job-level `hashFiles()`/`secrets` conditionals — step-level only. - -## Acceptance criteria - -- [ ] Every recipe referenced by any quickstart exists in the Justfile (grep-verified). -- [ ] No `{{placeholders}}` remain in touched docs. -- [ ] install-smoke.yml is schema-valid and SHA-pinned. -- [ ] README module count matches reality. - -## Local verification - -In WSL: `sudo apt-get install -y just` (NOPASSWD sudo), then `just --list` in the repo -parses; grep that every quickstart-referenced recipe exists. Optionally `just setup` -under the Julia lock. - -## Out of scope - -Container/devcontainer install (W2-3); release (W2-1). diff --git a/.claude/tasks/prod-readiness/w1-5-supply-chain-pinning.adoc b/.claude/tasks/prod-readiness/w1-5-supply-chain-pinning.adoc new file mode 100644 index 0000000..991afa4 --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-5-supply-chain-pinning.adoc @@ -0,0 +1,57 @@ +== W1-5 · Pin the compute half + prune Dependabot + real threat model + +*Model:* impl=sonnet · verify=sonnet · *Branch:* +`+fix/supply-chain-pinning+` + +=== Context + +The Julia layer that produces every number has *no `+Manifest.toml+`* +committed and Dependabot lists ecosystems (mix/npm/pip/nix) that don’t +exist here (Julia is unsupported by Dependabot). The trusted numeric +layer is neither pinned nor vuln-monitored, and `+docs/THREAT-MODEL.md+` +falsely claims "`lockfiles committed`" and is otherwise generic STRIDE +boilerplate that never models the neurosymbolic or FFI boundary. + +=== Requirements + +*(a)* Generate `+Manifest.toml+` with the SAME Julia minor as CI (1.10) +— +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.instantiate()"'+`. +Remove the `+Manifest.toml+` ignore line from `+.gitignore+` and commit +the manifest. Read `+e2e.yml+` to confirm nothing deletes the manifest +(Pkg.instantiate honours a committed manifest by default — no workflow +change needed). + +*(b)* `+.github/dependabot.yml+`: verify each listed ecosystem against +the tree; remove dead entries; keep `+github-actions+` (and any +genuinely present). Note in the PR body that Julia has no Dependabot +ecosystem and the committed Manifest + CI instantiate is the +compensating control. + +*(c)* `+docs/THREAT-MODEL.md+`: add a section modelling the actual +*neurosymbolic boundary* — LLM numeric fabrication (mitigated by the +W1-1 guardrail), prompt injection via user data (W2-7), tool +mis-routing, silent-null sub-types — and the *FFI/C-ABI boundary* +(memory safety, unvalidated inputs crossing the ABI). Fix +false/boilerplate claims: references to Cargo.lock/deno.lock that don’t +exist, the nonexistent `+scorecard-enforcer.yml+`, and the "`lockfiles +committed`" row (now true only for Manifest.toml). Keep the existing +STRIDE structure — surgical edits, not a rewrite. + +=== Acceptance criteria + +* [ ] `+Manifest.toml+` tracked & committed; `+.gitignore+` no longer +excludes it. +* [ ] dependabot.yml lists only ecosystems that exist. +* [ ] THREAT-MODEL models the neural + FFI boundaries; no false +lockfile/workflow refs. +* [ ] Governance CI still green on the PR. + +=== Local verification + +`+flock … Pkg.instantiate()+` produced a Manifest that `+git status+` +shows staged; grep THREAT-MODEL for the removed false claims. + +=== Out of scope + +SBOM publishing (W2-1); making the FFI real. diff --git a/.claude/tasks/prod-readiness/w1-5-supply-chain-pinning.md b/.claude/tasks/prod-readiness/w1-5-supply-chain-pinning.md deleted file mode 100644 index b03fd0b..0000000 --- a/.claude/tasks/prod-readiness/w1-5-supply-chain-pinning.md +++ /dev/null @@ -1,48 +0,0 @@ -# W1-5 · Pin the compute half + prune Dependabot + real threat model - -**Model:** impl=sonnet · verify=sonnet · **Branch:** `fix/supply-chain-pinning` - -## Context - -The Julia layer that produces every number has **no `Manifest.toml`** committed and -Dependabot lists ecosystems (mix/npm/pip/nix) that don't exist here (Julia is unsupported -by Dependabot). The trusted numeric layer is neither pinned nor vuln-monitored, and -`docs/THREAT-MODEL.md` falsely claims "lockfiles committed" and is otherwise generic -STRIDE boilerplate that never models the neurosymbolic or FFI boundary. - -## Requirements - -**(a)** Generate `Manifest.toml` with the SAME Julia minor as CI (1.10) — -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.instantiate()"'`. -Remove the `Manifest.toml` ignore line from `.gitignore` and commit the manifest. -Read `e2e.yml` to confirm nothing deletes the manifest (Pkg.instantiate honours a -committed manifest by default — no workflow change needed). - -**(b)** `.github/dependabot.yml`: verify each listed ecosystem against the tree; remove -dead entries; keep `github-actions` (and any genuinely present). Note in the PR body -that Julia has no Dependabot ecosystem and the committed Manifest + CI instantiate is the -compensating control. - -**(c)** `docs/THREAT-MODEL.md`: add a section modelling the actual **neurosymbolic -boundary** — LLM numeric fabrication (mitigated by the W1-1 guardrail), prompt injection -via user data (W2-7), tool mis-routing, silent-null sub-types — and the **FFI/C-ABI -boundary** (memory safety, unvalidated inputs crossing the ABI). Fix false/boilerplate -claims: references to Cargo.lock/deno.lock that don't exist, the nonexistent -`scorecard-enforcer.yml`, and the "lockfiles committed" row (now true only for -Manifest.toml). Keep the existing STRIDE structure — surgical edits, not a rewrite. - -## Acceptance criteria - -- [ ] `Manifest.toml` tracked & committed; `.gitignore` no longer excludes it. -- [ ] dependabot.yml lists only ecosystems that exist. -- [ ] THREAT-MODEL models the neural + FFI boundaries; no false lockfile/workflow refs. -- [ ] Governance CI still green on the PR. - -## Local verification - -`flock … Pkg.instantiate()` produced a Manifest that `git status` shows staged; grep -THREAT-MODEL for the removed false claims. - -## Out of scope - -SBOM publishing (W2-1); making the FFI real. diff --git a/.claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.adoc b/.claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.adoc new file mode 100644 index 0000000..395e452 --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.adoc @@ -0,0 +1,69 @@ +== W1-6 · Make the Zig FFI compile + memory-safety fixes + CI + +*Model:* impl=opus · verify=sonnet · *Branch:* `+fix/zig-ffi-compiles+` + +=== Context + +The FFI does not compile: `+ffi/zig/src/main.zig+` (~42-67) declares +`+Handle+` as `+opaque {}+` yet gives it fields and +`+allocator.create(Handle)+`s it (both hard Zig compile errors); +`+ffi/zig/test/integration_test.zig+` has its own conflicting +`+Handle+`. No workflow runs `+zig build+`, so every check is green +while the FFI is broken. *User decision: the FFI is EXPERIMENTAL* — make +it compile and CI-check; do NOT wire it to the Julia core or build the +(nonexistent) Idris2 ABI. + +⚠ *Zig version:* the setup environment installed Zig *0.16.0*, which has +breaking std changes (Io writer/reader redesign). If the code targets +≤0.14, fetch a matching older tarball into `+/home/hyperpolymath/zig/+` +and use its binary. State the version you built against in the PR. + +=== Requirements + +*(a)* `+main.zig+`: make `+Handle+` a real struct (internal), exported +across the C ABI as an opaque pointer (idiomatic for the Zig version you +use). Fix the double-free / use-after-free the audit flagged — add a +liveness/magic flag checked in `+statistikles_free+` and +`+statistikles_process+`; freeing twice must be a safe no-op returning +an error code, not UB. Fix the `+statistikles_last_error+` +string-ownership leak (stable storage owned by the handle or a static +buffer — document the ownership rule in a comment). Add +`+export fn statistikles_abi_version() callconv(.C) u32+` returning a +monotonic ABI number alongside the existing version string. + +*(b)* `+test/integration_test.zig+`: use the ONE shared `+Handle+` +(import from the root module — restructure `+build.zig+` test wiring if +needed); make the double-free test assert the safe-error behaviour +instead of "`should not crash`". + +*(c)* `+build.zig+`: remove or satisfy references to missing +`+include/statistikles.h+` and `+bench/bench.zig+` (audit says both are +referenced but absent — prefer removing dead steps unless trivially +satisfiable). + +*(d)* NEW `+.github/workflows/zig.yml+`: SHA-pinned checkout + a pinned +Zig setup action (e.g. `+mlugg/setup-zig+` by full SHA) matching the +version you built against; run `+zig build test+` in `+ffi/zig+`. Match +repo SHA-pinning style. + +*(e)* HONESTY: the exported ops are placeholders not backed by the Julia +core. Keep a clear comment block saying so + mention it in the PR body. +Do NOT invent a Julia bridge. (The doc-level reframe is W2-4.) + +=== Acceptance criteria + +* [ ] `+zig build test+` passes locally (state the Zig version). +* [ ] Double-free is a safe error, not UB (tested); no `+last_error+` +leak. +* [ ] `+zig.yml+` green on the PR; SHA-pinned. +* [ ] No commented-out/dead references remain in `+build.zig+`. + +=== Local verification + +WSL login shell: `+cd /ffi/zig && zig build test+` (zig on PATH in +login shell, or full path +`+/home/hyperpolymath/zig/zig-x86_64-linux-/zig+`). + +=== Out of scope + +Real Julia-backed FFI semantics; the Idris2 ABI; doc reframe (W2-4). diff --git a/.claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.md b/.claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.md deleted file mode 100644 index 7ba7c5c..0000000 --- a/.claude/tasks/prod-readiness/w1-6-zig-ffi-compiles.md +++ /dev/null @@ -1,60 +0,0 @@ -# W1-6 · Make the Zig FFI compile + memory-safety fixes + CI - -**Model:** impl=opus · verify=sonnet · **Branch:** `fix/zig-ffi-compiles` - -## Context - -The FFI does not compile: `ffi/zig/src/main.zig` (~42-67) declares `Handle` as -`opaque {}` yet gives it fields and `allocator.create(Handle)`s it (both hard Zig -compile errors); `ffi/zig/test/integration_test.zig` has its own conflicting `Handle`. -No workflow runs `zig build`, so every check is green while the FFI is broken. -**User decision: the FFI is EXPERIMENTAL** — make it compile and CI-check; do NOT wire it -to the Julia core or build the (nonexistent) Idris2 ABI. - -⚠ **Zig version:** the setup environment installed Zig **0.16.0**, which has breaking std -changes (Io writer/reader redesign). If the code targets ≤0.14, fetch a matching older -tarball into `/home/hyperpolymath/zig/` and use its binary. State the version you built -against in the PR. - -## Requirements - -**(a)** `main.zig`: make `Handle` a real struct (internal), exported across the C ABI as -an opaque pointer (idiomatic for the Zig version you use). Fix the double-free / -use-after-free the audit flagged — add a liveness/magic flag checked in -`statistikles_free` and `statistikles_process`; freeing twice must be a safe no-op -returning an error code, not UB. Fix the `statistikles_last_error` string-ownership leak -(stable storage owned by the handle or a static buffer — document the ownership rule in a -comment). Add `export fn statistikles_abi_version() callconv(.C) u32` returning a -monotonic ABI number alongside the existing version string. - -**(b)** `test/integration_test.zig`: use the ONE shared `Handle` (import from the root -module — restructure `build.zig` test wiring if needed); make the double-free test assert -the safe-error behaviour instead of "should not crash". - -**(c)** `build.zig`: remove or satisfy references to missing `include/statistikles.h` and -`bench/bench.zig` (audit says both are referenced but absent — prefer removing dead steps -unless trivially satisfiable). - -**(d)** NEW `.github/workflows/zig.yml`: SHA-pinned checkout + a pinned Zig setup action -(e.g. `mlugg/setup-zig` by full SHA) matching the version you built against; run -`zig build test` in `ffi/zig`. Match repo SHA-pinning style. - -**(e)** HONESTY: the exported ops are placeholders not backed by the Julia core. Keep a -clear comment block saying so + mention it in the PR body. Do NOT invent a Julia bridge. -(The doc-level reframe is W2-4.) - -## Acceptance criteria - -- [ ] `zig build test` passes locally (state the Zig version). -- [ ] Double-free is a safe error, not UB (tested); no `last_error` leak. -- [ ] `zig.yml` green on the PR; SHA-pinned. -- [ ] No commented-out/dead references remain in `build.zig`. - -## Local verification - -WSL login shell: `cd /ffi/zig && zig build test` (zig on PATH in login shell, or -full path `/home/hyperpolymath/zig/zig-x86_64-linux-/zig`). - -## Out of scope - -Real Julia-backed FFI semantics; the Idris2 ABI; doc reframe (W2-4). diff --git a/.claude/tasks/prod-readiness/w1-7-agda-proofs-ci.adoc b/.claude/tasks/prod-readiness/w1-7-agda-proofs-ci.adoc new file mode 100644 index 0000000..c4836db --- /dev/null +++ b/.claude/tasks/prod-readiness/w1-7-agda-proofs-ci.adoc @@ -0,0 +1,61 @@ +== W1-7 · Type-checking Agda proofs + `+agda --safe+` CI + honest catalogue + +*Model:* impl=opus · verify=sonnet · *Branch:* `+fix/agda-proofs-ci+` + +=== Context + +`+proofs/README.adoc+` claims "`Verified by Agda’s type checker — no +postulates,`" but no workflow runs Agda, ≥2 of the 3 files likely don’t +type-check (missing `+_|>_+` import; a helper type mismatch), all proofs +quantify over ℕ while claims/computation are over ℝ/Float64, and the +catalogue labels trivial lemmas as statistical theorems (e.g. +"`Bonferroni`" = `+x ≤ x+Σ+`, "`tie-correction`" = `+a≤b → a²≤b²+`, +"`mean-ordering`" = `+≤-trans+`). *User decision: proofs are +EXPERIMENTAL* — make them compile & CI-check and relabel honestly; do +NOT restate over ℝ. + +⚠ *Toolchain:* setup installed *Agda 2.6.4.3 + agda-stdlib 2.1*, wired +via `+~/.agda/libraries+` + `+~/.agda/defaults+`. stdlib 2.1 renamed +some modules vs 1.x — expect import tweaks. + +=== Requirements + +*(a)* Fix compile errors so ALL modules under `+proofs/+` pass +`+agda --safe+` (do not weaken `+--safe+`). Resolve import paths against +stdlib 2.1. + +*(b)* `+proofs/README.adoc+`: relabel every catalogue entry to the lemma +*actually proven* (precise statement), keep the aspirational statistical +theorem in a separate clearly-marked "`target (pending)`" column/note, +and add an explicit scope statement that current proofs quantify over ℕ, +not the Float64 the runtime uses. Honesty fix — do not delete proofs, do +not restate over reals here. + +*(c)* NEW `+.github/workflows/agda.yml+`: ubuntu-latest; install agda + +agda-stdlib (apt); configure the stdlib library file; run +`+agda --safe+` on every module under `+proofs/+` (glob or explicit list +with a guard that FAILS if a new `+.agda+` file isn’t checked). SHA-pin +any actions; match repo pinning style. + +*(d)* If a governance/grep workflow scans for `+sorry+`/`+postulate+` +but skips `+proofs/+`, extend it to cover `+proofs/+` (check +`+.github/workflows+` and extend surgically). + +=== Acceptance criteria + +* [ ] `+agda --safe+` passes on every `+proofs/**/*.agda+` locally. +* [ ] README catalogue states the real lemma per entry + a ℕ-scope +disclaimer. +* [ ] `+agda.yml+` green on the PR; fails if a new proof file is +unchecked. + +=== Local verification + +WSL login shell: `+cd /proofs && agda --safe .agda+` +(stdlib resolves via `+~/.agda/defaults+`). First run is slow while +stdlib interfaces build. + +=== Out of scope + +Proofs over ℝ; new theorems; the Julia↔Agda correspondence (deferred by +user decision). Broader doc reframe is W2-4. diff --git a/.claude/tasks/prod-readiness/w1-7-agda-proofs-ci.md b/.claude/tasks/prod-readiness/w1-7-agda-proofs-ci.md deleted file mode 100644 index 768b191..0000000 --- a/.claude/tasks/prod-readiness/w1-7-agda-proofs-ci.md +++ /dev/null @@ -1,52 +0,0 @@ -# W1-7 · Type-checking Agda proofs + `agda --safe` CI + honest catalogue - -**Model:** impl=opus · verify=sonnet · **Branch:** `fix/agda-proofs-ci` - -## Context - -`proofs/README.adoc` claims "Verified by Agda's type checker — no postulates," but no -workflow runs Agda, ≥2 of the 3 files likely don't type-check (missing `_|>_` import; a -helper type mismatch), all proofs quantify over ℕ while claims/computation are over -ℝ/Float64, and the catalogue labels trivial lemmas as statistical theorems (e.g. -"Bonferroni" = `x ≤ x+Σ`, "tie-correction" = `a≤b → a²≤b²`, "mean-ordering" = `≤-trans`). -**User decision: proofs are EXPERIMENTAL** — make them compile & CI-check and relabel -honestly; do NOT restate over ℝ. - -⚠ **Toolchain:** setup installed **Agda 2.6.4.3 + agda-stdlib 2.1**, wired via -`~/.agda/libraries` + `~/.agda/defaults`. stdlib 2.1 renamed some modules vs 1.x — -expect import tweaks. - -## Requirements - -**(a)** Fix compile errors so ALL modules under `proofs/` pass `agda --safe` (do not -weaken `--safe`). Resolve import paths against stdlib 2.1. - -**(b)** `proofs/README.adoc`: relabel every catalogue entry to the lemma **actually -proven** (precise statement), keep the aspirational statistical theorem in a separate -clearly-marked "target (pending)" column/note, and add an explicit scope statement that -current proofs quantify over ℕ, not the Float64 the runtime uses. Honesty fix — do not -delete proofs, do not restate over reals here. - -**(c)** NEW `.github/workflows/agda.yml`: ubuntu-latest; install agda + agda-stdlib -(apt); configure the stdlib library file; run `agda --safe` on every module under -`proofs/` (glob or explicit list with a guard that FAILS if a new `.agda` file isn't -checked). SHA-pin any actions; match repo pinning style. - -**(d)** If a governance/grep workflow scans for `sorry`/`postulate` but skips `proofs/`, -extend it to cover `proofs/` (check `.github/workflows` and extend surgically). - -## Acceptance criteria - -- [ ] `agda --safe` passes on every `proofs/**/*.agda` locally. -- [ ] README catalogue states the real lemma per entry + a ℕ-scope disclaimer. -- [ ] `agda.yml` green on the PR; fails if a new proof file is unchecked. - -## Local verification - -WSL login shell: `cd /proofs && agda --safe .agda` (stdlib resolves via -`~/.agda/defaults`). First run is slow while stdlib interfaces build. - -## Out of scope - -Proofs over ℝ; new theorems; the Julia↔Agda correspondence (deferred by user decision). -Broader doc reframe is W2-4. diff --git a/.claude/tasks/prod-readiness/w2-1-release-pipeline.adoc b/.claude/tasks/prod-readiness/w2-1-release-pipeline.adoc new file mode 100644 index 0000000..4043bee --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-1-release-pipeline.adoc @@ -0,0 +1,69 @@ +== W2-1 · Release pipeline: JuliaRegistrator + TagBot + SBOM + +*Model:* impl=opus · verify=opus · *Branch:* +`+feat/release-registrator-tagbot+` + +=== Context + +`+.github/workflows/release.yml+` is an unfilled template: the build job +is `+echo "Build your artifacts here"+` (~lines 27-29), artifact upload +is commented out, and the SLSA provenance job passes +`+base64-subjects: ""+` which makes slsa-github-generator *error on any +`+v*+` tag push* — the release pipeline has never produced a successful +run (no tags exist yet). The user decided (2026-07-10, binding): release +via *JuliaRegistrator + TagBot* to the Julia General registry. Also +required: an SBOM actually published with releases (currently only a +silent `+|| echo+` local Justfile recipe). + +=== Requirements + +[arabic] +. *TagBot*: add `+.github/workflows/TagBot.yml+` using +`+JuliaRegistries/TagBot+` (SHA-pinned + version comment, matching repo +pinning style), triggered per TagBot docs (issue_comment from +JuliaTagBot / workflow_dispatch). Configure `+ssh: false+` default token +flow unless the repo requires otherwise. +. *Registration path*: document — in a new `+docs/RELEASING.adoc+` — the +exact maintainer flow: bump `+version+` in Project.toml → merge to main +→ comment `+@JuliaRegistrator register+` on the commit (or install the +Registrator GitHub app) → General registry PR → TagBot cuts the GitHub +release. Include first-registration caveats (AutoMerge requirements: +[compat] completeness — `+Statistics = "1"+` was added in wave 1; +name/UUID rules). +. *release.yml rewrite*: on `+v*+` tags (which TagBot creates): build a +source tarball artifact, generate an SPDX SBOM with +`+anchore/sbom-action+` (syft, SHA-pinned), attach both to the GitHub +release, and compute *real* `+base64-subjects+` (sha256sum of the +artifacts, base64-encoded per slsa-github-generator docs) for the SLSA +job — or, if you judge the SLSA job unsalvageable without binary +artifacts, remove it and say so in the PR body with reasoning. Keep the +existing git-cliff changelog step if present and functional. +. Remove/replace all `+TODO: Replace with your build commands+` template +residue in release.yml. +. *Never* create or push a tag in this task. The pipeline must be inert +until a maintainer registers a version. + +=== Acceptance criteria + +* [ ] `+actionlint+`-clean (or careful manual YAML review if actionlint +unavailable); every action SHA-pinned with version comment. +* [ ] No job-level `+hashFiles()+`/`+secrets+` conditionals (repo rule: +step-level only). +* [ ] A dry validation of the SLSA subjects computation (run the shell +snippet locally on a dummy file and show the output in the PR body), OR +the job removed with justification. +* [ ] `+docs/RELEASING.adoc+` walks a maintainer end-to-end with zero +external lookups. +* [ ] PR body includes a "`first release checklist`" (version bump, +registrator comment, what to watch for in AutoMerge). + +=== Local verification + +`+actionlint+` on changed workflows if available; otherwise line-by-line +schema review. Shell-test the sha256/base64 subjects snippet with a +scratch file. No Julia needed. + +=== Out of scope + +Actually registering the package; creating tags; container image +releases. diff --git a/.claude/tasks/prod-readiness/w2-1-release-pipeline.md b/.claude/tasks/prod-readiness/w2-1-release-pipeline.md deleted file mode 100644 index 777b40c..0000000 --- a/.claude/tasks/prod-readiness/w2-1-release-pipeline.md +++ /dev/null @@ -1,59 +0,0 @@ -# W2-1 · Release pipeline: JuliaRegistrator + TagBot + SBOM - -**Model:** impl=opus · verify=opus · **Branch:** `feat/release-registrator-tagbot` - -## Context - -`.github/workflows/release.yml` is an unfilled template: the build job is -`echo "Build your artifacts here"` (~lines 27-29), artifact upload is commented out, -and the SLSA provenance job passes `base64-subjects: ""` which makes -slsa-github-generator **error on any `v*` tag push** — the release pipeline has never -produced a successful run (no tags exist yet). The user decided (2026-07-10, binding): -release via **JuliaRegistrator + TagBot** to the Julia General registry. Also required: -an SBOM actually published with releases (currently only a silent `|| echo` local -Justfile recipe). - -## Requirements - -1. **TagBot**: add `.github/workflows/TagBot.yml` using `JuliaRegistries/TagBot` - (SHA-pinned + version comment, matching repo pinning style), triggered per TagBot - docs (issue_comment from JuliaTagBot / workflow_dispatch). Configure `ssh: false` - default token flow unless the repo requires otherwise. -2. **Registration path**: document — in a new `docs/RELEASING.adoc` — the exact - maintainer flow: bump `version` in Project.toml → merge to main → comment - `@JuliaRegistrator register` on the commit (or install the Registrator GitHub app) → - General registry PR → TagBot cuts the GitHub release. Include first-registration - caveats (AutoMerge requirements: [compat] completeness — `Statistics = "1"` was - added in wave 1; name/UUID rules). -3. **release.yml rewrite**: on `v*` tags (which TagBot creates): build a source - tarball artifact, generate an SPDX SBOM with `anchore/sbom-action` (syft, - SHA-pinned), attach both to the GitHub release, and compute **real** - `base64-subjects` (sha256sum of the artifacts, base64-encoded per - slsa-github-generator docs) for the SLSA job — or, if you judge the SLSA job - unsalvageable without binary artifacts, remove it and say so in the PR body with - reasoning. Keep the existing git-cliff changelog step if present and functional. -4. Remove/replace all `TODO: Replace with your build commands` template residue in - release.yml. -5. **Never** create or push a tag in this task. The pipeline must be inert until a - maintainer registers a version. - -## Acceptance criteria - -- [ ] `actionlint`-clean (or careful manual YAML review if actionlint unavailable); - every action SHA-pinned with version comment. -- [ ] No job-level `hashFiles()`/`secrets` conditionals (repo rule: step-level only). -- [ ] A dry validation of the SLSA subjects computation (run the shell snippet locally - on a dummy file and show the output in the PR body), OR the job removed with - justification. -- [ ] `docs/RELEASING.adoc` walks a maintainer end-to-end with zero external lookups. -- [ ] PR body includes a "first release checklist" (version bump, registrator comment, - what to watch for in AutoMerge). - -## Local verification - -`actionlint` on changed workflows if available; otherwise line-by-line schema review. -Shell-test the sha256/base64 subjects snippet with a scratch file. No Julia needed. - -## Out of scope - -Actually registering the package; creating tags; container image releases. diff --git a/.claude/tasks/prod-readiness/w2-2-guix-package.adoc b/.claude/tasks/prod-readiness/w2-2-guix-package.adoc new file mode 100644 index 0000000..fc82c72 --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-2-guix-package.adoc @@ -0,0 +1,67 @@ +== W2-2 · Make guix.scm a real, buildable package + +*Model:* impl=opus · verify=sonnet · *Branch:* +`+feat/guix-real-package+` + +=== Context + +`+guix.scm+` is a template placeholder: synopsis is literally +`+{{PROJECT_PURPOSE}}+` (~line 67), native-inputs/inputs are empty +(~lines 54-65), and the build/check phases are deleted (~lines 45-53) — +the only "`build`" copies README.adoc into share/doc. It is not a +buildable package, yet governance CI runs a "`Guix primary / Nix +fallback policy`" check and docs claim reproducible builds. User +decision (binding): *fill it to actually build*, do not delete. + +=== Requirements + +[arabic] +. Rewrite `+guix.scm+` as a real package for a Julia project: `+julia+` +in inputs (Guix has a `+julia+` package and a `+julia-build-system+` — +evaluate whether `+julia-build-system+` fits a project-with-Manifest +layout, or use `+copy-build-system+`/`+gnu-build-system+` with explicit +phases that (a) copy the project, (b) run +`+julia --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'+` +where sandbox network policy allows, or vendor via the committed +Manifest.toml — document which strategy you chose and why in comments). +Note Guix builds are network-isolated: if full dependency instantiation +inside the build sandbox is not feasible, the honest scope is a package +that installs the source tree + a launcher script and _checks_ +`+julia -e 'using Pkg; Pkg.status()'+` syntax-level integrity. State the +limitation in a comment header — do NOT fake a check phase that doesn’t +verify anything. +. Real `+synopsis+` and `+description+` (from README: neurosymbolic +statistical analysis assistant — Julia computes, LLMs route). License +field must match repo (MPL-2.0). Fill `+home-page+` with the GitHub URL. +. Replace every remaining `+{{...}}+` placeholder in the file. +. Verify: `+guix build -f guix.scm+` in a Guix environment if available; +otherwise at minimum `+guile -c '(load "guix.scm")'+`-style syntax +validation or `+guix repl+`-less S-expression parse check (balanced +parens, valid module refs verified against the Guix manual), stated +honestly in the PR. +. Check `+.guix-channel+` at repo root for consistency with the new +package (channel metadata must not reference missing directories). + +=== Acceptance criteria + +* [ ] No `+{{placeholders}}+` remain in guix.scm. +* [ ] Package form is syntactically valid Scheme (paren-balanced, +evaluable). +* [ ] Build strategy is honest — no deleted-phase-pretending-to-build; +limitations documented in comments. +* [ ] Governance "`Guix primary / Nix fallback policy`" CI check still +passes on the PR. +* [ ] PR body states exactly what level of build verification was +possible. + +=== Local verification + +If `+guix+` is installed: `+guix build -f guix.scm+` (or `+--dry-run+`). +Otherwise: Scheme syntax validation + cross-check every symbol against +Guix package/module names via web search of the Guix manual. Never claim +a build you didn’t run. + +=== Out of scope + +Nix flakes; publishing to a channel; CI job running guix (note as +follow-up if valuable). diff --git a/.claude/tasks/prod-readiness/w2-2-guix-package.md b/.claude/tasks/prod-readiness/w2-2-guix-package.md deleted file mode 100644 index bbdcc87..0000000 --- a/.claude/tasks/prod-readiness/w2-2-guix-package.md +++ /dev/null @@ -1,56 +0,0 @@ -# W2-2 · Make guix.scm a real, buildable package - -**Model:** impl=opus · verify=sonnet · **Branch:** `feat/guix-real-package` - -## Context - -`guix.scm` is a template placeholder: synopsis is literally `{{PROJECT_PURPOSE}}` -(~line 67), native-inputs/inputs are empty (~lines 54-65), and the build/check phases -are deleted (~lines 45-53) — the only "build" copies README.adoc into share/doc. It is -not a buildable package, yet governance CI runs a "Guix primary / Nix fallback policy" -check and docs claim reproducible builds. User decision (binding): **fill it to -actually build**, do not delete. - -## Requirements - -1. Rewrite `guix.scm` as a real package for a Julia project: `julia` in inputs - (Guix has a `julia` package and a `julia-build-system` — evaluate whether - `julia-build-system` fits a project-with-Manifest layout, or use - `copy-build-system`/`gnu-build-system` with explicit phases that (a) copy the - project, (b) run `julia --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'` - where sandbox network policy allows, or vendor via the committed Manifest.toml — - document which strategy you chose and why in comments). - Note Guix builds are network-isolated: if full dependency instantiation inside the - build sandbox is not feasible, the honest scope is a package that installs the - source tree + a launcher script and *checks* `julia -e 'using Pkg; Pkg.status()'` - syntax-level integrity. State the limitation in a comment header — do NOT fake a - check phase that doesn't verify anything. -2. Real `synopsis` and `description` (from README: neurosymbolic statistical analysis - assistant — Julia computes, LLMs route). License field must match repo (MPL-2.0). - Fill `home-page` with the GitHub URL. -3. Replace every remaining `{{...}}` placeholder in the file. -4. Verify: `guix build -f guix.scm` in a Guix environment if available; otherwise at - minimum `guile -c '(load "guix.scm")'`-style syntax validation or - `guix repl`-less S-expression parse check (balanced parens, valid module refs - verified against the Guix manual), stated honestly in the PR. -5. Check `.guix-channel` at repo root for consistency with the new package - (channel metadata must not reference missing directories). - -## Acceptance criteria - -- [ ] No `{{placeholders}}` remain in guix.scm. -- [ ] Package form is syntactically valid Scheme (paren-balanced, evaluable). -- [ ] Build strategy is honest — no deleted-phase-pretending-to-build; limitations - documented in comments. -- [ ] Governance "Guix primary / Nix fallback policy" CI check still passes on the PR. -- [ ] PR body states exactly what level of build verification was possible. - -## Local verification - -If `guix` is installed: `guix build -f guix.scm` (or `--dry-run`). Otherwise: Scheme -syntax validation + cross-check every symbol against Guix package/module names via -web search of the Guix manual. Never claim a build you didn't run. - -## Out of scope - -Nix flakes; publishing to a channel; CI job running guix (note as follow-up if valuable). diff --git a/.claude/tasks/prod-readiness/w2-3-containers.adoc b/.claude/tasks/prod-readiness/w2-3-containers.adoc new file mode 100644 index 0000000..669ecfa --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-3-containers.adoc @@ -0,0 +1,65 @@ +== W2-3 · Runnable Containerfile + devcontainer + +*Model:* impl=sonnet · verify=sonnet · *Branch:* +`+feat/containers-runnable+` + +=== Context + +Neither container surface yields a runnable app. `+Containerfile+` (repo +root): the build-deps section (~lines 12-16) and build commands (~21-25) +are fully commented out, no artifact is copied into the runtime stage +(~30-35), the base is `+chainguard/static+` (static-binary base — +unusable for Julia), and ENTRYPOINT is commented out (~41). +`+.devcontainer/devcontainer.json+` installs git/just/nickel features +but *no Julia*, and its postCreateCommand ran the no-op `+just deps+` +stub (wave-1 PR 4/8 made `+just+` recipes real — coordinate). There is +also `+.devcontainer/Containerfile+`. + +=== Requirements + +[arabic] +. *Containerfile*: multi-stage or single-stage image based on the +official `+docker.io/julia:1.10+` image (pin by digest for +reproducibility; add version comment). Copy the project, run +`+julia --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'+` +at build time, set +`+ENTRYPOINT ["julia", "--project=/app", "-e", "using Statistikles; main()"]+` +(verify the actual entry function in `+src/Statistikles.jl+` first). +Respect the committed Manifest.toml (wave-1 PR 5/8) if present. Non-root +runtime user. +. *devcontainer.json*: add Julia via the community devcontainer feature +(`+ghcr.io/julialang/devcontainer-features/julia+` — verify current id) +pinned to 1.10, or base the devcontainer on the julia image; make +postCreate run the real `+just setup+` (or +`+julia --project=. -e 'using Pkg; Pkg.instantiate()'+` directly if just +isn’t guaranteed). Keep existing features that are real. +. *CI*: new `+.github/workflows/container-build.yml+` that builds the +Containerfile with podman or docker (`+docker build .+` on ubuntu-latest +is simplest) on PRs touching +Containerfile/Project.toml/Manifest.toml/src — build only, no push, no +registry login. SHA-pin actions; step-level conditionals only. +. Reconcile QUICKSTART "`Option 2`" container instructions with the +now-real image (exact `+podman build+`/`+podman run+` commands that +work). + +=== Acceptance criteria + +* [ ] `+docker build .+` (or podman) completes locally, and +`+docker run +` reaches the Statistikles entrypoint (interactive +REPL may just print its banner and wait — that counts; document expected +behavior). +* [ ] Devcontainer JSON is schema-valid; postCreate references only real +commands. +* [ ] CI build job green on the PR. +* [ ] No commented-out template blocks remain in either Containerfile. + +=== Local verification + +`+docker build+`/`+podman build+` if a container runtime is available +(state which); otherwise rely on the new CI job and say so. +JSON-validate devcontainer.json. + +=== Out of scope + +Publishing images to a registry; multi-arch builds; guix (separate task +W2-2). diff --git a/.claude/tasks/prod-readiness/w2-3-containers.md b/.claude/tasks/prod-readiness/w2-3-containers.md deleted file mode 100644 index b2accd7..0000000 --- a/.claude/tasks/prod-readiness/w2-3-containers.md +++ /dev/null @@ -1,52 +0,0 @@ -# W2-3 · Runnable Containerfile + devcontainer - -**Model:** impl=sonnet · verify=sonnet · **Branch:** `feat/containers-runnable` - -## Context - -Neither container surface yields a runnable app. `Containerfile` (repo root): the -build-deps section (~lines 12-16) and build commands (~21-25) are fully commented out, -no artifact is copied into the runtime stage (~30-35), the base is `chainguard/static` -(static-binary base — unusable for Julia), and ENTRYPOINT is commented out (~41). -`.devcontainer/devcontainer.json` installs git/just/nickel features but **no Julia**, -and its postCreateCommand ran the no-op `just deps` stub (wave-1 PR 4/8 made `just` -recipes real — coordinate). There is also `.devcontainer/Containerfile`. - -## Requirements - -1. **Containerfile**: multi-stage or single-stage image based on the official - `docker.io/julia:1.10` image (pin by digest for reproducibility; add version - comment). Copy the project, run - `julia --project=. -e 'using Pkg; Pkg.instantiate(); Pkg.precompile()'` at build - time, set `ENTRYPOINT ["julia", "--project=/app", "-e", "using Statistikles; main()"]` - (verify the actual entry function in `src/Statistikles.jl` first). Respect the - committed Manifest.toml (wave-1 PR 5/8) if present. Non-root runtime user. -2. **devcontainer.json**: add Julia via the community devcontainer feature - (`ghcr.io/julialang/devcontainer-features/julia` — verify current id) pinned to 1.10, - or base the devcontainer on the julia image; make postCreate run the real - `just setup` (or `julia --project=. -e 'using Pkg; Pkg.instantiate()'` directly if - just isn't guaranteed). Keep existing features that are real. -3. **CI**: new `.github/workflows/container-build.yml` that builds the Containerfile - with podman or docker (`docker build .` on ubuntu-latest is simplest) on PRs - touching Containerfile/Project.toml/Manifest.toml/src — build only, no push, no - registry login. SHA-pin actions; step-level conditionals only. -4. Reconcile QUICKSTART "Option 2" container instructions with the now-real image - (exact `podman build`/`podman run` commands that work). - -## Acceptance criteria - -- [ ] `docker build .` (or podman) completes locally, and - `docker run ` reaches the Statistikles entrypoint (interactive REPL may - just print its banner and wait — that counts; document expected behavior). -- [ ] Devcontainer JSON is schema-valid; postCreate references only real commands. -- [ ] CI build job green on the PR. -- [ ] No commented-out template blocks remain in either Containerfile. - -## Local verification - -`docker build`/`podman build` if a container runtime is available (state which); -otherwise rely on the new CI job and say so. JSON-validate devcontainer.json. - -## Out of scope - -Publishing images to a registry; multi-arch builds; guix (separate task W2-2). diff --git a/.claude/tasks/prod-readiness/w2-4-experimental-reframe.adoc b/.claude/tasks/prod-readiness/w2-4-experimental-reframe.adoc new file mode 100644 index 0000000..f164ba4 --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-4-experimental-reframe.adoc @@ -0,0 +1,64 @@ +== W2-4 · Experimental reframe: FFI + formal-proofs documentation + +*Model:* impl=sonnet · verify=sonnet · *Branch:* +`+docs/experimental-reframe+` + +=== Context + +The audit found the Zig FFI and Agda proofs are aspirational: FFI ops +are placeholders calling no Julia code, the "`Idris2 ABI + generated +header`" pipeline in `+ABI-FFI-README.md+` doesn’t exist, and the Agda +proofs cover ℕ-lemmas, not the ℝ/Float64 statistical theorems the docs +imply. *User decision (binding): reframe both as EXPERIMENTAL* +repo-wide. W1-6 and W1-7 already made both compile + CI-check with +honest _inline_ labels; this task is the docs/positioning sweep. +*Depends on W1-6 and W1-7 being merged (or branch from their state).* + +=== Requirements + +[arabic] +. Inventory every claim: grep `+README.adoc+`, `+EXPLAINME.adoc+`, +`+ABI-FFI-README.md+`, `+PROOF-NEEDS.md+`, `+proofs/README.adoc+`, +`+docs/**+`, `+.machine_readable/**+`, `+RSR_OUTLINE.adoc+`, quickstarts +for: "`formally verified`", "`formally proven`", "`proof-backed`", +"`Idris2 ABI`", "`Level 10`", "`verified by Agda`", "`production-ready`" +(in FFI/proof context), and any text asserting the C-ABI exposes the +stats core. +. Rewrite each hit to the honest state with consistent vocabulary: +* FFI: "`**Experimental** — compiles and is CI-tested, but entry points +are placeholders not yet backed by the Julia core; the Idris2 ABI layer +is design-only.`" +* Proofs: "`**Experimental** — small ℕ-level lemmas type-checked by +`+agda --safe+` in CI; the statistical theorems over ℝ remain open +targets.`" +. Add ONE canonical "`Experimental surfaces`" section to `+README.adoc+` +(short, under the architecture section) describing both boundaries and +linking the detailed docs; other docs reference it rather than +re-asserting. +. `+.machine_readable+` a2ml manifests (e.g. NEUROSYM.a2ml, META.a2ml): +align any proof/FFI maturity fields so machine-readable claims don’t +exceed human-readable ones. Keep a2ml syntax valid (the "`Validate A2ML +manifests`" CI job checks these). +. Do NOT weaken the Julia core’s tested/reference-validated claims +(true). Do NOT delete PROOF-NEEDS.md — label it "`open targets`". + +=== Acceptance criteria + +* [ ] `+git grep -in "formally verified\|formally proven"+` returns only +accurate proofs/-internal descriptions or explicit "`not yet / target`" +phrasing. +* [ ] No doc asserts the C-ABI reaches the stats core. +* [ ] README has the single canonical "`Experimental surfaces`" section; +others link it. +* [ ] A2ML validation CI job passes; PR body lists every file with +before→after. + +=== Local verification + +The acceptance-criteria grep; re-run any manifest validator (`+just+` +validate recipe or rely on CI). + +=== Out of scope + +Making FFI real / proofs over ℝ (user-deferred); code changes beyond +comment-text. diff --git a/.claude/tasks/prod-readiness/w2-4-experimental-reframe.md b/.claude/tasks/prod-readiness/w2-4-experimental-reframe.md deleted file mode 100644 index 33efc84..0000000 --- a/.claude/tasks/prod-readiness/w2-4-experimental-reframe.md +++ /dev/null @@ -1,51 +0,0 @@ -# W2-4 · Experimental reframe: FFI + formal-proofs documentation - -**Model:** impl=sonnet · verify=sonnet · **Branch:** `docs/experimental-reframe` - -## Context - -The audit found the Zig FFI and Agda proofs are aspirational: FFI ops are placeholders -calling no Julia code, the "Idris2 ABI + generated header" pipeline in `ABI-FFI-README.md` -doesn't exist, and the Agda proofs cover ℕ-lemmas, not the ℝ/Float64 statistical theorems -the docs imply. **User decision (binding): reframe both as EXPERIMENTAL** repo-wide. -W1-6 and W1-7 already made both compile + CI-check with honest *inline* labels; this task -is the docs/positioning sweep. **Depends on W1-6 and W1-7 being merged (or branch from -their state).** - -## Requirements - -1. Inventory every claim: grep `README.adoc`, `EXPLAINME.adoc`, `ABI-FFI-README.md`, - `PROOF-NEEDS.md`, `proofs/README.adoc`, `docs/**`, `.machine_readable/**`, - `RSR_OUTLINE.adoc`, quickstarts for: "formally verified", "formally proven", - "proof-backed", "Idris2 ABI", "Level 10", "verified by Agda", "production-ready" - (in FFI/proof context), and any text asserting the C-ABI exposes the stats core. -2. Rewrite each hit to the honest state with consistent vocabulary: - - FFI: "**Experimental** — compiles and is CI-tested, but entry points are - placeholders not yet backed by the Julia core; the Idris2 ABI layer is design-only." - - Proofs: "**Experimental** — small ℕ-level lemmas type-checked by `agda --safe` in - CI; the statistical theorems over ℝ remain open targets." -3. Add ONE canonical "Experimental surfaces" section to `README.adoc` (short, under the - architecture section) describing both boundaries and linking the detailed docs; other - docs reference it rather than re-asserting. -4. `.machine_readable` a2ml manifests (e.g. NEUROSYM.a2ml, META.a2ml): align any - proof/FFI maturity fields so machine-readable claims don't exceed human-readable ones. - Keep a2ml syntax valid (the "Validate A2ML manifests" CI job checks these). -5. Do NOT weaken the Julia core's tested/reference-validated claims (true). Do NOT delete - PROOF-NEEDS.md — label it "open targets". - -## Acceptance criteria - -- [ ] `git grep -in "formally verified\|formally proven"` returns only accurate - proofs/-internal descriptions or explicit "not yet / target" phrasing. -- [ ] No doc asserts the C-ABI reaches the stats core. -- [ ] README has the single canonical "Experimental surfaces" section; others link it. -- [ ] A2ML validation CI job passes; PR body lists every file with before→after. - -## Local verification - -The acceptance-criteria grep; re-run any manifest validator (`just` validate recipe or -rely on CI). - -## Out of scope - -Making FFI real / proofs over ℝ (user-deferred); code changes beyond comment-text. diff --git a/.claude/tasks/prod-readiness/w2-5-reference-validation.adoc b/.claude/tasks/prod-readiness/w2-5-reference-validation.adoc new file mode 100644 index 0000000..35e72f2 --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-5-reference-validation.adoc @@ -0,0 +1,54 @@ +== W2-5 · Extend ground-truth reference validation to advanced modules + +*Model:* impl=sonnet · verify=opus · *Branch:* +`+test/reference-validation-extension+` + +=== Context + +`+test/reference_validation_test.jl+` compares against hand-derived +ground truth for only ~7 of ~40 stat modules (descriptive moments, Welch +t, Pearson, OLS, ANOVA, Mann-Whitney, Levene). The advanced surface +(bayesian, survival, SEM, ML, meta-analysis, causality, Kruskal-Wallis, +chi-square, logistic/multiple regression, Kaplan-Meier) has only +`+isa Dict+`/`+haskey+` smoke tests — a wrong-but-deterministic number +there is exactly the failure the project exists to prevent. + +=== Requirements + +[arabic] +. Pick the highest-traffic advanced tools (suggested first tranche: +Kruskal-Wallis, chi-square test of independence, multiple linear +regression, logistic regression, Kaplan-Meier survival, +fixed/random-effects meta-analysis). For each, derive *independent +ground-truth* expected values — from a textbook worked example OR a +second implementation (R / SciPy / Julia’s own upstream packages) run +*locally*. Python/R is fine for deriving constants (it is banned only in +_repo code_); commit only the constants plus a comment citing the +source/derivation. +. Add assertions to `+reference_validation_test.jl+` (or a new +`+reference_validation_advanced_test.jl+` wired into `+runtests.jl+`) +checking key statistics to a stated tolerance (`+isapprox+`, atol/rtol +documented per case). +. Where a function’s output disagrees with ground truth, that is a *real +bug find* — report it clearly in the PR body (do NOT silently loosen +tolerance to make it pass; if you must, open the failing case as an +`+@test_broken+` with a comment and flag it). + +=== Acceptance criteria + +* [ ] ≥6 advanced tools have hand-derived/second-implementation +reference assertions. +* [ ] Every expected constant has a source comment (textbook page or +tool+version). +* [ ] Full suite green (or documented `+@test_broken+` for genuine +discrepancies found). + +=== Local verification + +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'+` +(WSL login shell). Derivation scripts may live in scratch, not the repo. + +=== Out of scope + +Property-based tests (already strong); fixing discovered bugs beyond +flagging them (open follow-up work orders for real bugs found). diff --git a/.claude/tasks/prod-readiness/w2-5-reference-validation.md b/.claude/tasks/prod-readiness/w2-5-reference-validation.md deleted file mode 100644 index eccdfd8..0000000 --- a/.claude/tasks/prod-readiness/w2-5-reference-validation.md +++ /dev/null @@ -1,44 +0,0 @@ -# W2-5 · Extend ground-truth reference validation to advanced modules - -**Model:** impl=sonnet · verify=opus · **Branch:** `test/reference-validation-extension` - -## Context - -`test/reference_validation_test.jl` compares against hand-derived ground truth for only -~7 of ~40 stat modules (descriptive moments, Welch t, Pearson, OLS, ANOVA, Mann-Whitney, -Levene). The advanced surface (bayesian, survival, SEM, ML, meta-analysis, causality, -Kruskal-Wallis, chi-square, logistic/multiple regression, Kaplan-Meier) has only -`isa Dict`/`haskey` smoke tests — a wrong-but-deterministic number there is exactly the -failure the project exists to prevent. - -## Requirements - -1. Pick the highest-traffic advanced tools (suggested first tranche: Kruskal-Wallis, - chi-square test of independence, multiple linear regression, logistic regression, - Kaplan-Meier survival, fixed/random-effects meta-analysis). For each, derive - **independent ground-truth** expected values — from a textbook worked example OR a - second implementation (R / SciPy / Julia's own upstream packages) run **locally**. - Python/R is fine for deriving constants (it is banned only in *repo code*); commit - only the constants plus a comment citing the source/derivation. -2. Add assertions to `reference_validation_test.jl` (or a new - `reference_validation_advanced_test.jl` wired into `runtests.jl`) checking key - statistics to a stated tolerance (`isapprox`, atol/rtol documented per case). -3. Where a function's output disagrees with ground truth, that is a **real bug find** — - report it clearly in the PR body (do NOT silently loosen tolerance to make it pass; - if you must, open the failing case as an `@test_broken` with a comment and flag it). - -## Acceptance criteria - -- [ ] ≥6 advanced tools have hand-derived/second-implementation reference assertions. -- [ ] Every expected constant has a source comment (textbook page or tool+version). -- [ ] Full suite green (or documented `@test_broken` for genuine discrepancies found). - -## Local verification - -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'` -(WSL login shell). Derivation scripts may live in scratch, not the repo. - -## Out of scope - -Property-based tests (already strong); fixing discovered bugs beyond flagging them -(open follow-up work orders for real bugs found). diff --git a/.claude/tasks/prod-readiness/w2-6-observability.adoc b/.claude/tasks/prod-readiness/w2-6-observability.adoc new file mode 100644 index 0000000..42df690 --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-6-observability.adoc @@ -0,0 +1,56 @@ +== W2-6 · Structured logging + audit trail + +*Model:* impl=sonnet · verify=sonnet · *Branch:* +`+feat/structured-observability+` + +=== Context + +Observability is limited to bare `+println+` (`+lmstudio.jl:93+` prints +the symbolic-execute breadcrumb; errors go to stdout). No `+Logging+` +stdlib use, no request/trace IDs, no timing, no persisted audit trail — +despite the product marketing auditability. A VeriSimDB persistence +layer exists (`+src/bridge/verisimdb_schema.jl+`) but is never invoked +from the runtime path. *Depends on / coordinates with W1-1* (which +restructures chat/executor). + +=== Requirements + +[arabic] +. Introduce `+Logging+`-based structured logging +(`+@info+`/`+@warn+`/`+@error+`) across the runtime path +(`+src/tools/chat.jl+`, `+executor.jl+`, `+lmstudio.jl+`), replacing +ad-hoc `+println+`. Attach a *per-chat-turn correlation id* and a +per-tool-call id; log for each tool call: tool name, an argument hash +(not raw args — may contain user data), result summary (shape/keys, not +full values), and duration. +. Make verbosity configurable via ENV (`+STATISTIKLES_LOG_LEVEL+`, +default `+Info+`), and keep the human-facing REPL output clean (logs to +stderr / a logger, not interleaved with answers). +. *Wire the dormant VeriSimDB audit path*: from `+execute_tool+` (or +`+process_tool_calls+`), record an audit entry (turn id, tool, arg hash, +result provenance) via `+src/bridge/verisimdb_schema.jl+`. If VeriSimDB +requires a backend not available in tests, make persistence +pluggable/no-op-by-default and unit-test the record construction — do +not make the test suite depend on an external DB. +. Tests: NEW `+test/observability_test.jl+` — assert log records carry a +correlation id and tool metadata (capture with +`+Test.collect_test_logs+`/`+with_logger+`); assert the audit-record +constructor produces the expected shape. Wire into `+runtests.jl+`. + +=== Acceptance criteria + +* [ ] Runtime path uses structured logging with correlation ids (tested +via captured logs). +* [ ] REPL answers are not polluted by log lines. +* [ ] Audit-record construction is tested; persistence is +pluggable/no-op-safe in CI. +* [ ] Full suite green + new test. + +=== Local verification + +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'+` +(WSL login shell). + +=== Out of scope + +Standing up a real VeriSimDB backend; log shipping/telemetry infra. diff --git a/.claude/tasks/prod-readiness/w2-6-observability.md b/.claude/tasks/prod-readiness/w2-6-observability.md deleted file mode 100644 index c1fb603..0000000 --- a/.claude/tasks/prod-readiness/w2-6-observability.md +++ /dev/null @@ -1,46 +0,0 @@ -# W2-6 · Structured logging + audit trail - -**Model:** impl=sonnet · verify=sonnet · **Branch:** `feat/structured-observability` - -## Context - -Observability is limited to bare `println` (`lmstudio.jl:93` prints the symbolic-execute -breadcrumb; errors go to stdout). No `Logging` stdlib use, no request/trace IDs, no -timing, no persisted audit trail — despite the product marketing auditability. A VeriSimDB -persistence layer exists (`src/bridge/verisimdb_schema.jl`) but is never invoked from the -runtime path. **Depends on / coordinates with W1-1** (which restructures chat/executor). - -## Requirements - -1. Introduce `Logging`-based structured logging (`@info`/`@warn`/`@error`) across the - runtime path (`src/tools/chat.jl`, `executor.jl`, `lmstudio.jl`), replacing ad-hoc - `println`. Attach a **per-chat-turn correlation id** and a per-tool-call id; log for - each tool call: tool name, an argument hash (not raw args — may contain user data), - result summary (shape/keys, not full values), and duration. -2. Make verbosity configurable via ENV (`STATISTIKLES_LOG_LEVEL`, default `Info`), and - keep the human-facing REPL output clean (logs to stderr / a logger, not interleaved - with answers). -3. **Wire the dormant VeriSimDB audit path**: from `execute_tool` (or `process_tool_calls`), - record an audit entry (turn id, tool, arg hash, result provenance) via - `src/bridge/verisimdb_schema.jl`. If VeriSimDB requires a backend not available in - tests, make persistence pluggable/no-op-by-default and unit-test the record - construction — do not make the test suite depend on an external DB. -4. Tests: NEW `test/observability_test.jl` — assert log records carry a correlation id - and tool metadata (capture with `Test.collect_test_logs`/`with_logger`); assert the - audit-record constructor produces the expected shape. Wire into `runtests.jl`. - -## Acceptance criteria - -- [ ] Runtime path uses structured logging with correlation ids (tested via captured logs). -- [ ] REPL answers are not polluted by log lines. -- [ ] Audit-record construction is tested; persistence is pluggable/no-op-safe in CI. -- [ ] Full suite green + new test. - -## Local verification - -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'` -(WSL login shell). - -## Out of scope - -Standing up a real VeriSimDB backend; log shipping/telemetry infra. diff --git a/.claude/tasks/prod-readiness/w2-7-prompt-injection.adoc b/.claude/tasks/prod-readiness/w2-7-prompt-injection.adoc new file mode 100644 index 0000000..b85c044 --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-7-prompt-injection.adoc @@ -0,0 +1,49 @@ +== W2-7 · Prompt-injection delimiting + +*Model:* impl=sonnet · verify=haiku · *Branch:* +`+fix/prompt-injection-delimiting+` + +=== Context + +User-supplied data (dataset values, column names, free text) flows into +LLM prompts with no delimiting or labeling, so a crafted dataset/caption +can carry instructions that the model may follow — and, absent the W1-1 +output guardrail, could forge a statistic. *Depends on W1-1* (the +numeric-provenance guardrail is the primary defense; this task is +defense-in-depth on the input side). + +=== Requirements + +[arabic] +. In `+src/tools/chat.jl+` / prompt construction: wrap all untrusted +user data in clearly delimited, labeled segments (e.g. a fenced +`++` block or a documented delimiter), and add a +system-prompt clause instructing the model to treat everything inside as +data, never as instructions. Neutralize/escape any delimiter collisions +in the user content. +. Keep it minimal and robust — do not attempt to "`sanitize`" +statistical content (numbers/strings must pass through intact for +computation); the goal is _framing_, not filtering. +. Tests: NEW `+test/prompt_injection_test.jl+` — construct a prompt from +user data that contains an injection string and a delimiter-collision +attempt; assert the built prompt places the data inside the labeled +block with collisions neutralized. (Unit-test the prompt-construction +function directly — no live LLM.) + +=== Acceptance criteria + +* [ ] Untrusted data is delimited + labeled in the constructed prompt +(tested). +* [ ] Delimiter-collision in user content is neutralized (tested). +* [ ] System prompt instructs data-not-instructions handling. +* [ ] Full suite green + new test. + +=== Local verification + +`+flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'+` +(WSL login shell). + +=== Out of scope + +The output-provenance guardrail (W1-1, the primary control); model-side +jailbreak robustness (out of our control). diff --git a/.claude/tasks/prod-readiness/w2-7-prompt-injection.md b/.claude/tasks/prod-readiness/w2-7-prompt-injection.md deleted file mode 100644 index b4d5da3..0000000 --- a/.claude/tasks/prod-readiness/w2-7-prompt-injection.md +++ /dev/null @@ -1,43 +0,0 @@ -# W2-7 · Prompt-injection delimiting - -**Model:** impl=sonnet · verify=haiku · **Branch:** `fix/prompt-injection-delimiting` - -## Context - -User-supplied data (dataset values, column names, free text) flows into LLM prompts with -no delimiting or labeling, so a crafted dataset/caption can carry instructions that the -model may follow — and, absent the W1-1 output guardrail, could forge a statistic. -**Depends on W1-1** (the numeric-provenance guardrail is the primary defense; this task -is defense-in-depth on the input side). - -## Requirements - -1. In `src/tools/chat.jl` / prompt construction: wrap all untrusted user data in clearly - delimited, labeled segments (e.g. a fenced `` block or a - documented delimiter), and add a system-prompt clause instructing the model to treat - everything inside as data, never as instructions. Neutralize/escape any delimiter - collisions in the user content. -2. Keep it minimal and robust — do not attempt to "sanitize" statistical content - (numbers/strings must pass through intact for computation); the goal is *framing*, not - filtering. -3. Tests: NEW `test/prompt_injection_test.jl` — construct a prompt from user data that - contains an injection string and a delimiter-collision attempt; assert the built prompt - places the data inside the labeled block with collisions neutralized. (Unit-test the - prompt-construction function directly — no live LLM.) - -## Acceptance criteria - -- [ ] Untrusted data is delimited + labeled in the constructed prompt (tested). -- [ ] Delimiter-collision in user content is neutralized (tested). -- [ ] System prompt instructs data-not-instructions handling. -- [ ] Full suite green + new test. - -## Local verification - -`flock /tmp/statistikles-julia.lock -c 'cd && julia --project=. -e "using Pkg; Pkg.test()"'` -(WSL login shell). - -## Out of scope - -The output-provenance guardrail (W1-1, the primary control); model-side jailbreak -robustness (out of our control). diff --git a/.claude/tasks/prod-readiness/w2-8-polish-sweep.adoc b/.claude/tasks/prod-readiness/w2-8-polish-sweep.adoc new file mode 100644 index 0000000..24866c0 --- /dev/null +++ b/.claude/tasks/prod-readiness/w2-8-polish-sweep.adoc @@ -0,0 +1,61 @@ +== W2-8 · Polish sweep (mechanical P2 cleanup) + +*Model:* impl=haiku · verify=haiku · *Branch:* `+chore/polish-sweep+` + +=== Context + +A batch of low-risk P2 items from the audit. Each is small and +mechanical. Skip any that a wave-1 PR already resolved (check +`+git log+`/the file before editing) and note skips in the PR body. +*Purely mechanical — introduce no behavior change beyond what’s listed.* + +=== Requirements (do each; verify the file first) + +[arabic] +. *Undefined-stat sentinels → null+reason*: if not already handled by +W1-2, ensure `+harmonic_mean+`, `+cv+`, `+geometric_mean+` return +`+nothing+` + a `+"note"+` on undefined input (grep `+src/stats+` for +these). +. *`+.tool-versions+`*: add `+julia 1.10.x+` (match CI) if W1-4 didn’t. +. *`+Project.toml+` [compat]*: add `+Statistics = "1"+` and, for +AutoMerge quiet, +`+Dates+`/`+LinearAlgebra+`/`+Printf+`/`+Random+`/`+UUIDs = "1"+` if not +present. +. *README module count*: if W1-4 didn’t fix it, correct "`17 modules`" +to the real `+src/stats/*.jl+` count. +. *SHA-pin version comments*: normalize inconsistent annotations (same +checkout SHA commented `+# v7.0.0+` in one workflow and `+# v4+` in +another) to the true tag across `+.github/workflows/*+`. +. *Template banners*: remove any remaining "`delete before publishing`" +banners in `+CODE_OF_CONDUCT.md+` / `+docs/AI_INSTALLATION_GUIDE.adoc+` +(W1-8/#33 did SECURITY.md + security.txt; check these two). +. *`+build.zig+`* dead refs (`+include/statistikles.h+`, +`+bench/bench.zig+`): if W1-6 didn’t remove them, do so. +. *Duplicate CODEOWNERS / dead `+tests/+`*: if #33 didn’t fully resolve, +keep one `+.github/CODEOWNERS+`, remove dead entries. + +=== Explicitly DO NOT + +* Touch `+.gitlab-ci.yml+` or `+deny.toml+` (flagged as scaffolding but +carry load-bearing policy claims — a separate decision; note as +recommended follow-up in the PR body). +* Delete `+generated/+` again (#33 handled it). +* Make any behavioral/statistical change beyond the null-sentinel item. + +=== Acceptance criteria + +* [ ] Each item done OR explicitly noted as +already-resolved-by-a-prior-PR. +* [ ] No `+{{placeholder}}+`/template banner remains in touched files. +* [ ] Full suite green (if any `+src/+` touched) — else N/A stated. + +=== Local verification + +If `+src/+` touched: +`+flock /tmp/statistikles-julia.lock -c '… Pkg.test()'+`. Otherwise grep +confirmations per item. + +=== Out of scope + +`+.gitlab-ci.yml+`/`+deny.toml+` decision; anything requiring judgment +beyond the list. diff --git a/.claude/tasks/prod-readiness/w2-8-polish-sweep.md b/.claude/tasks/prod-readiness/w2-8-polish-sweep.md deleted file mode 100644 index 89a3248..0000000 --- a/.claude/tasks/prod-readiness/w2-8-polish-sweep.md +++ /dev/null @@ -1,52 +0,0 @@ -# W2-8 · Polish sweep (mechanical P2 cleanup) - -**Model:** impl=haiku · verify=haiku · **Branch:** `chore/polish-sweep` - -## Context - -A batch of low-risk P2 items from the audit. Each is small and mechanical. Skip any that -a wave-1 PR already resolved (check `git log`/the file before editing) and note skips in -the PR body. **Purely mechanical — introduce no behavior change beyond what's listed.** - -## Requirements (do each; verify the file first) - -1. **Undefined-stat sentinels → null+reason**: if not already handled by W1-2, ensure - `harmonic_mean`, `cv`, `geometric_mean` return `nothing` + a `"note"` on undefined - input (grep `src/stats` for these). -2. **`.tool-versions`**: add `julia 1.10.x` (match CI) if W1-4 didn't. -3. **`Project.toml` [compat]**: add `Statistics = "1"` and, for AutoMerge quiet, - `Dates`/`LinearAlgebra`/`Printf`/`Random`/`UUIDs = "1"` if not present. -4. **README module count**: if W1-4 didn't fix it, correct "17 modules" to the real - `src/stats/*.jl` count. -5. **SHA-pin version comments**: normalize inconsistent annotations (same checkout SHA - commented `# v7.0.0` in one workflow and `# v4` in another) to the true tag across - `.github/workflows/*`. -6. **Template banners**: remove any remaining "delete before publishing" banners in - `CODE_OF_CONDUCT.md` / `docs/AI_INSTALLATION_GUIDE.adoc` (W1-8/#33 did SECURITY.md + - security.txt; check these two). -7. **`build.zig`** dead refs (`include/statistikles.h`, `bench/bench.zig`): if W1-6 - didn't remove them, do so. -8. **Duplicate CODEOWNERS / dead `tests/`**: if #33 didn't fully resolve, keep one - `.github/CODEOWNERS`, remove dead entries. - -## Explicitly DO NOT - -- Touch `.gitlab-ci.yml` or `deny.toml` (flagged as scaffolding but carry load-bearing - policy claims — a separate decision; note as recommended follow-up in the PR body). -- Delete `generated/` again (#33 handled it). -- Make any behavioral/statistical change beyond the null-sentinel item. - -## Acceptance criteria - -- [ ] Each item done OR explicitly noted as already-resolved-by-a-prior-PR. -- [ ] No `{{placeholder}}`/template banner remains in touched files. -- [ ] Full suite green (if any `src/` touched) — else N/A stated. - -## Local verification - -If `src/` touched: `flock /tmp/statistikles-julia.lock -c '… Pkg.test()'`. Otherwise grep -confirmations per item. - -## Out of scope - -`.gitlab-ci.yml`/`deny.toml` decision; anything requiring judgment beyond the list. diff --git a/ABI-FFI-README.md b/ABI-FFI-README.adoc similarity index 65% rename from ABI-FFI-README.md rename to ABI-FFI-README.adoc index fe08689..cb630a3 100644 --- a/ABI-FFI-README.md +++ b/ABI-FFI-README.adoc @@ -1,35 +1,36 @@ - -# STATISTIKLES ABI/FFI Documentation - -> **STATUS — EXPERIMENTAL.** The Zig FFI compiles and is CI-tested -> (`.github/workflows/zig.yml`), but its exported entry points are placeholders, -> not yet backed by the Julia statistical core. The Idris2 ABI layer described -> below is **design-only**: `src/abi/` does not exist in this repo (the template -> scaffolding that once lived there was removed — see `PROOF-NEEDS.md`, "Template -> ABI Cleanup"). Everything in this document past this notice describes the -> *intended* Hyperpolymath RSR design, not the current state of this repository. -> See the "Experimental surfaces" section of `README.adoc` for the canonical -> summary. - -## Overview - -This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design -(target design; not yet fully implemented in this repo): - -- **ABI (Application Binary Interface)** *intended* to be defined in **Idris2** - with formal proofs — not yet present (`src/abi/` does not exist) -- **FFI (Foreign Function Interface)** implemented in **Zig** for C compatibility - — compiles and is CI-tested, but operations are placeholders -- **Generated C headers** *would* bridge Idris2 ABI to Zig FFI — no generation - pipeline exists yet -- **Any language** can call through the standard C ABI once real operations land - -## Architecture - -``` +== STATISTIKLES ABI/FFI Documentation + +____ +*STATUS — EXPERIMENTAL.* The Zig FFI compiles and is CI-tested +(`+.github/workflows/zig.yml+`), but its exported entry points are +placeholders, not yet backed by the Julia statistical core. The Idris2 +ABI layer described below is *design-only*: `+src/abi/+` does not exist +in this repo (the template scaffolding that once lived there was removed +— see `+PROOF-NEEDS.md+`, "`Template ABI Cleanup`"). Everything in this +document past this notice describes the _intended_ Hyperpolymath RSR +design, not the current state of this repository. See the "`Experimental +surfaces`" section of `+README.adoc+` for the canonical summary. +____ + +=== Overview + +This library follows the *Hyperpolymath RSR Standard* for ABI and FFI +design (target design; not yet fully implemented in this repo): + +* *ABI (Application Binary Interface)* _intended_ to be defined in +*Idris2* with formal proofs — not yet present (`+src/abi/+` does not +exist) +* *FFI (Foreign Function Interface)* implemented in *Zig* for C +compatibility — compiles and is CI-tested, but operations are +placeholders +* *Generated C headers* _would_ bridge Idris2 ABI to Zig FFI — no +generation pipeline exists yet +* *Any language* can call through the standard C ABI once real +operations land + +=== Architecture + +.... ┌─────────────────────────────────────────────┐ │ ABI Definitions (Idris2) │ │ src/abi/ │ @@ -61,14 +62,15 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design │ Any Language via C ABI │ │ - Rust, ReScript, Julia, Python, etc. │ └─────────────────────────────────────────────┘ -``` +.... -## Directory Structure +=== Directory Structure -The tree below is the *target* layout. `src/abi/`, `generated/abi/`, and -`bindings/` do not exist in this repo yet — only `ffi/zig/` is real. +The tree below is the _target_ layout. `+src/abi/+`, `+generated/abi/+`, +and `+bindings/+` do not exist in this repo yet — only `+ffi/zig/+` is +real. -``` +.... statistikles/ ├── src/ │ ├── abi/ # NOT PRESENT — ABI definitions (Idris2), design-only @@ -96,15 +98,17 @@ statistikles/ ├── rust/ ├── rescript/ └── julia/ -``` +.... -## Why Idris2 for ABI? +=== Why Idris2 for ABI? -### 1. **Formal Verification** +==== 1. *Formal Verification* -Idris2's dependent types allow proving properties about the ABI at compile-time: +Idris2’s dependent types allow proving properties about the ABI at +compile-time: -```idris +[source,idris] +---- -- Prove struct size is correct public export exampleStructSize : HasSize ExampleStruct 16 @@ -116,13 +120,14 @@ fieldAligned : Divides 8 (offsetOf ExampleStruct.field) -- Prove ABI is platform-compatible public export abiCompatible : Compatible (ABI 1) (ABI 2) -``` +---- -### 2. **Type Safety** +==== 2. *Type Safety* Encode invariants that C/Zig cannot express: -```idris +[source,idris] +---- -- Non-null pointer guaranteed at type level data Handle : Type where MkHandle : (ptr : Bits64) -> {auto 0 nonNull : So (ptr /= 0)} -> Handle @@ -130,13 +135,14 @@ data Handle : Type where -- Array with length proof data Buffer : (n : Nat) -> Type where MkBuffer : Vect n Byte -> Buffer n -``` +---- -### 3. **Platform Abstraction** +==== 3. *Platform Abstraction* Platform-specific types with compile-time selection: -```idris +[source,idris] +---- CInt : Platform -> Type CInt Linux = Bits32 CInt Windows = Bits32 @@ -144,13 +150,14 @@ CInt Windows = Bits32 CSize : Platform -> Type CSize Linux = Bits64 CSize Windows = Bits64 -``` +---- -### 4. **Safe Evolution** +==== 4. *Safe Evolution* Prove that new ABI versions are backward-compatible: -```idris +[source,idris] +---- -- Compiler enforces compatibility abiUpgrade : ABI 1 -> ABI 2 abiUpgrade old = MkABI2 { @@ -159,74 +166,81 @@ abiUpgrade old = MkABI2 { -- Can add new fields new_features = defaults } -``` +---- -## Why Zig for FFI? +=== Why Zig for FFI? -### 1. **C ABI Compatibility** +==== 1. *C ABI Compatibility* Zig exports C-compatible functions naturally: -```zig +[source,zig] +---- export fn library_function(param: i32) i32 { return param * 2; } -``` +---- -### 2. **Memory Safety** +==== 2. *Memory Safety* Compile-time safety without runtime overhead: -```zig +[source,zig] +---- // Null check enforced at compile time const handle = init() orelse return error.InitFailed; defer free(handle); -``` +---- -### 3. **Cross-Compilation** +==== 3. *Cross-Compilation* Built-in cross-compilation to any platform: -```bash +[source,bash] +---- zig build -Dtarget=x86_64-linux zig build -Dtarget=aarch64-macos zig build -Dtarget=x86_64-windows -``` +---- -### 4. **Zero Dependencies** +==== 4. *Zero Dependencies* No runtime, no libc required (unless explicitly needed): -```zig +[source,zig] +---- // Minimal binary size pub const lib = @import("std"); // Only includes what you use -``` +---- -## Building +=== Building -### Build FFI Library +==== Build FFI Library -```bash +[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 (target design — not runnable today) +==== Generate C Header from Idris2 ABI (target design — not runnable today) -`src/abi/` does not exist in this repo, so the command below has no `Types.idr` -to compile. It documents the intended pipeline only. +`+src/abi/+` does not exist in this repo, so the command below has no +`+Types.idr+` to compile. It documents the intended pipeline only. -```bash +[source,bash] +---- cd src/abi idris2 --cg c-header Types.idr -o ../../generated/abi/statistikles.h -``` +---- -### Cross-Compile +==== Cross-Compile -```bash +[source,bash] +---- cd ffi/zig # Linux x86_64 @@ -237,13 +251,14 @@ zig build -Dtarget=aarch64-macos # Windows x86_64 zig build -Dtarget=x86_64-windows -``` +---- -## Usage +=== Usage -### From C +==== From C -```c +[source,c] +---- #include "statistikles.h" int main() { @@ -259,16 +274,19 @@ int main() { statistikles_free(handle); return 0; } -``` +---- Compile with: -```bash + +[source,bash] +---- gcc -o example example.c -lstatistikles -L./zig-out/lib -``` +---- -### From Idris2 +==== From Idris2 -```idris +[source,idris] +---- import STATISTIKLES.ABI.Foreign main : IO () @@ -281,11 +299,12 @@ main = do free handle putStrLn "Success" -``` +---- -### From Rust +==== From Rust -```rust +[source,rust] +---- #[link(name = "statistikles")] extern "C" { fn statistikles_init() -> *mut std::ffi::c_void; @@ -304,11 +323,12 @@ fn main() { statistikles_free(handle); } } -``` +---- -### From Julia +==== From Julia -```julia +[source,julia] +---- const libstatistikles = "libstatistikles" function init() @@ -334,30 +354,34 @@ try finally cleanup(handle) end -``` +---- -## Testing +=== Testing -### Unit Tests (Zig) +==== Unit Tests (Zig) -```bash +[source,bash] +---- cd ffi/zig zig build test -``` +---- -### Integration Tests +==== Integration Tests -```bash +[source,bash] +---- cd ffi/zig zig build test-integration -``` +---- -### ABI Verification (Idris2) (target design — not runnable today) +==== ABI Verification (Idris2) (target design — not runnable today) -There is no Idris2 ABI in this repo to run `verifyABI`/`verifyLayoutsCorrect` -against; this block documents the intended verification surface only. +There is no Idris2 ABI in this repo to run +`+verifyABI+`/`+verifyLayoutsCorrect+` against; this block documents the +intended verification surface only. -```idris +[source,idris] +---- -- Compile-time verification %runElab verifyABI @@ -367,45 +391,45 @@ main = do verifyLayoutsCorrect verifyAlignmentsCorrect putStrLn "ABI verification passed" -``` +---- -## Contributing +=== Contributing When modifying the ABI/FFI: -1. **Update ABI first** (`src/abi/*.idr`) — target design; `src/abi/` does not - exist yet, so this step is currently a no-op - - Modify type definitions - - Update proofs - - Ensure backward compatibility - -2. **Generate C header** - ```bash - idris2 --cg c-header src/abi/Types.idr -o generated/abi/statistikles.h - ``` - -3. **Update FFI implementation** (`ffi/zig/src/main.zig`) - - Implement new functions - - Match ABI types exactly - -4. **Add tests** - - Unit tests in Zig - - Integration tests - - ABI verification tests - -5. **Update documentation** - - Function signatures - - Usage examples - - Migration guide (if breaking changes) - -## License +[arabic] +. *Update ABI first* (`+src/abi/*.idr+`) — target design; `+src/abi/+` +does not exist yet, so this step is currently a no-op +* Modify type definitions +* Update proofs +* Ensure backward compatibility +. *Generate C header* ++ +[source,bash] +---- +idris2 --cg c-header src/abi/Types.idr -o generated/abi/statistikles.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 +=== See Also -- [Idris2 Documentation](https://idris2.readthedocs.io) -- [Zig Documentation](https://ziglang.org/documentation/master/) -- [Rhodium Standard Repositories](https://github.com/hyperpolymath/rhodium-standard-repositories) -- [FFI Migration Guide](../ffi-migration-guide.md) -- [ABI Migration Guide](../abi-migration-guide.md) +* 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/CHANGELOG.adoc b/CHANGELOG.adoc new file mode 100644 index 0000000..ca1c652 --- /dev/null +++ b/CHANGELOG.adoc @@ -0,0 +1,9 @@ +== Changelog + +All notable changes to this project will be documented in this file. + +The format is based on https://keepachangelog.com/en/1.1.0/[Keep a +Changelog], and this project adheres to +https://semver.org/spec/v2.0.0.html[Semantic Versioning]. + +=== [Unreleased] diff --git a/CHANGELOG.md b/CHANGELOG.md deleted file mode 100644 index ec7f2e1..0000000 --- a/CHANGELOG.md +++ /dev/null @@ -1,15 +0,0 @@ - -# 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.1.0/), -and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). - - - - -## [Unreleased] diff --git a/CODE_OF_CONDUCT.adoc b/CODE_OF_CONDUCT.adoc new file mode 100644 index 0000000..e616255 --- /dev/null +++ b/CODE_OF_CONDUCT.adoc @@ -0,0 +1,339 @@ +== Code of Conduct + +=== Our Pledge + +We as members, contributors, and leaders pledge to make participation in +Statistikles 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, colour, 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. + +We recognise that a thriving open source community requires +*psychological safety* — an environment where people can contribute, ask +questions, make mistakes, and learn without fear of ridicule or +retaliation. + +''''' + +=== Our Standards + +==== Expected Behaviour + +The following behaviours contribute to a positive environment: + +*Communication* - Using welcoming and inclusive language - Being +respectful of differing viewpoints and experiences - Giving and +gracefully accepting constructive feedback - Assuming good intent while +addressing impact - Communicating clearly and patiently, especially with +newcomers + +*Collaboration* - Focusing on what is best for the community - Showing +empathy and kindness toward other community members - Being +collaborative rather than competitive - Mentoring and supporting less +experienced contributors - Celebrating others’ contributions and +successes + +*Professionalism* - Accepting responsibility and apologising to those +affected by our mistakes - Learning from the experience and avoiding +repetition - Respecting others’ time and attention - Staying on topic in +project spaces - Following project guidelines and conventions + +*Accessibility* - Using plain language and avoiding unnecessary jargon - +Providing alt text for images and transcripts for audio/video - Being +patient with those using assistive technologies - Accommodating +different communication styles and needs - Recognising that not everyone +communicates the same way + +==== Unacceptable Behaviour + +The following behaviours are considered harassment and are unacceptable: + +*Harassment* - The use of sexualised language or imagery, and sexual +attention or advances of any kind - Trolling, insulting or derogatory +comments, and personal or political attacks - Public or private +harassment - Deliberate intimidation, stalking, or following (online or +in-person) - Unwelcome physical contact or simulated physical contact +(e.g., emoji) - Sustained disruption of talks, events, or online +discussions + +*Discrimination* - Discriminatory jokes and language - Posting or +threatening to post others’ personally identifying information +("`doxing`") - Advocating for, or encouraging, any of the above +behaviour - Microaggressions — subtle, often unintentional, +discriminatory comments or actions + +*Professional Misconduct* - Publishing others’ private information +without explicit permission - Misrepresenting affiliation or +contributions - Plagiarism or claiming credit for others’ work - +Retaliating against anyone who reports a Code of Conduct violation - +Other conduct which could reasonably be considered inappropriate in a +professional setting + +==== Grey Areas + +Some situations require judgement. When uncertain: + +* *Intent vs Impact*: Good intentions do not excuse harmful impact. +Focus on making things right. +* *Power Dynamics*: Those with more power (maintainers, employers, +experienced contributors) must be especially mindful of their impact. +* *Cultural Differences*: What’s acceptable varies by culture. When in +doubt, err on the side of caution and ask. +* *Humour*: Jokes at others’ expense are rarely funny to everyone. Punch +up, not down. + +''''' + +=== Scope + +This Code of Conduct applies within all community spaces, including: + +*Online Spaces* - Repository discussions, issues, and pull/merge +requests - Project chat channels (Matrix, Discord, Slack, IRC) - Mailing +lists and forums - Social media when representing the project - Video +calls and virtual meetings + +*In-Person Spaces* - Conferences, meetups, and events - Workshops and +training sessions - Any gathering where you represent the project + +*Representation* This Code of Conduct also applies when an individual is +officially representing the community in public spaces. Examples +include: + +* Using an official project email address +* Posting via an official social media account +* Acting as an appointed representative at an event +* Speaking on behalf of the project + +''''' + +=== Enforcement + +==== Reporting + +If you experience or witness unacceptable behaviour, or have any other +concerns, please report it as soon as possible. + +*How to Report* + +[width="99%",cols="30%,33%,37%",options="header",] +|=== +|Method |Details |Best For +|*Email* |j.d.a.jewell@open.ac.uk |Detailed reports, sensitive matters + +|*Private Message* |Contact any maintainer directly |Quick questions, +minor issues + +|*Anonymous Form* |[Link to form if available] |When you need anonymity +|=== + +*What to Include* + +* Your contact information (unless anonymous) +* Names/usernames of those involved +* Description of what happened +* When and where it occurred +* Any witnesses +* Any supporting evidence (screenshots, links) +* How you would like us to respond (if you have a preference) + +*What Happens Next* + +[arabic] +. You will receive acknowledgment within *48 hours* +. The Statistikles maintainers will review the report +. We may ask for additional information +. We will determine appropriate action +. We will inform you of the outcome (respecting others’ privacy) + +==== Confidentiality + +All reports will be handled with discretion: + +* Reporter identity is protected by default +* Details are shared only with those who need to know +* We will ask before naming you in any communication +* Anonymous reports are accepted and investigated + +==== Conflicts of Interest + +If a Statistikles maintainers member is involved in an incident: + +* They will recuse themselves from the process +* Another maintainer or external party will handle the report +* We will disclose any potential conflicts + +''''' + +=== Enforcement Guidelines + +The Statistikles maintainers will follow these guidelines in determining +consequences: + +==== 1. Correction + +*Community Impact*: Use of inappropriate language or other behaviour +deemed unprofessional or unwelcome. + +*Consequence*: A private, written warning providing clarity around the +nature of the violation and an explanation of why the behaviour was +inappropriate. A public apology may be requested. + +*Duration*: Immediate + +==== 2. Warning + +*Community Impact*: A violation through a single incident or series of +actions. + +*Consequence*: A warning with consequences for continued behaviour. No +interaction with the people involved, including unsolicited interaction +with those enforcing the Code of Conduct, for a specified period. 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. + +*Duration*: 1-4 weeks + +==== 3. Temporary Ban + +*Community Impact*: A serious violation of community standards, +including sustained inappropriate behaviour. + +*Consequence*: A temporary ban from any sort of interaction or public +communication with the community for a specified period. 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. + +*Duration*: 1-6 months + +==== 4. Permanent Ban + +*Community Impact*: Demonstrating a pattern of violation of community +standards, including sustained inappropriate behaviour, 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. + +*Duration*: Permanent (with appeal rights after 12 months) + +==== Enforcement Across Perimeters + +For contributors with elevated access (Perimeter 2 or 1): + +[cols=",",options="header",] +|=== +|Level |Additional Consequence +|Correction |Noted in contributor record +|Warning |Access privileges may be temporarily reduced +|Temporary Ban |Access reduced to Perimeter 3 for ban duration +|Permanent Ban |All access revoked +|=== + +''''' + +=== Appeals + +If you believe an enforcement decision was made in error: + +[arabic] +. *Wait 7 days* after the decision (cooling-off period) +. *Email* j.d.a.jewell@open.ac.uk with subject line "`Appeal: [Original +Report ID]`" +. *Explain* why you believe the decision should be reconsidered +. *Provide* any new information not previously available + +*Appeals Process* + +* Appeals are reviewed by a different Statistikles maintainers member +than the original +* You will receive a response within 14 days +* The appeals decision is final +* You may only appeal once per incident + +*Grounds for Appeal* + +* Procedural errors in the original investigation +* New evidence not previously available +* Disproportionate response to the violation +* Misunderstanding of facts + +''''' + +=== Supporting Those Who Report + +We are committed to supporting those who report violations: + +*We Will* - Believe and take all reports seriously - Respect your +privacy and confidentiality preferences - Keep you informed of progress +(if you wish) - Take steps to protect you from retaliation - Provide +resources if you need support + +*We Will Not* - Require you to confront the person directly - Dismiss +reports without investigation - Reveal your identity without consent - +Tolerate retaliation against reporters - Rush you to make decisions + +''''' + +=== Prevention + +Beyond enforcement, we actively work to prevent issues: + +*Onboarding* - All contributors are expected to read this Code of +Conduct - Perimeter 2 applicants must confirm they’ve read and +understood it - Maintainers receive additional training on enforcement + +*Culture* - We model the behaviour we expect - We intervene early when +we see potential issues - We thank people for positive contributions - +We create opportunities for diverse voices + +*Review* - This Code of Conduct is reviewed annually - Community +feedback is welcomed - Changes are communicated clearly + +''''' + +=== Acknowledgments + +This Code of Conduct is adapted from: + +* https://www.contributor-covenant.org/[Contributor Covenant], version +2.1 +* https://www.djangoproject.com/conduct/[Django Code of Conduct] +* https://www.rust-lang.org/policies/code-of-conduct[Rust Code of +Conduct] +* https://www.python.org/psf/conduct/[Python Community Code of Conduct] + +We thank these communities for their leadership in creating welcoming +spaces. + +''''' + +=== Questions? + +If you have questions about this Code of Conduct: + +* Open a +https://github.com/hyperpolymath/statistikles/discussions[Discussion] +(for general questions) +* Email j.d.a.jewell@open.ac.uk (for private questions) +* Contact any maintainer directly + +''''' + +=== Summary + +*Be kind. Be respectful. Be collaborative.* + +We’re all here because we care about this project. Let’s make it a place +where everyone can do their best work. + +''''' + +Last updated: 2026 · Based on Contributor Covenant 2.1 diff --git a/CODE_OF_CONDUCT.md b/CODE_OF_CONDUCT.md deleted file mode 100644 index b9804fd..0000000 --- a/CODE_OF_CONDUCT.md +++ /dev/null @@ -1,311 +0,0 @@ - -# Code of Conduct - -## Our Pledge - -We as members, contributors, and leaders pledge to make participation in Statistikles 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, colour, 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. - -We recognise that a thriving open source community requires **psychological safety** — an environment where people can contribute, ask questions, make mistakes, and learn without fear of ridicule or retaliation. - ---- - -## Our Standards - -### Expected Behaviour - -The following behaviours contribute to a positive environment: - -**Communication** -- Using welcoming and inclusive language -- Being respectful of differing viewpoints and experiences -- Giving and gracefully accepting constructive feedback -- Assuming good intent while addressing impact -- Communicating clearly and patiently, especially with newcomers - -**Collaboration** -- Focusing on what is best for the community -- Showing empathy and kindness toward other community members -- Being collaborative rather than competitive -- Mentoring and supporting less experienced contributors -- Celebrating others' contributions and successes - -**Professionalism** -- Accepting responsibility and apologising to those affected by our mistakes -- Learning from the experience and avoiding repetition -- Respecting others' time and attention -- Staying on topic in project spaces -- Following project guidelines and conventions - -**Accessibility** -- Using plain language and avoiding unnecessary jargon -- Providing alt text for images and transcripts for audio/video -- Being patient with those using assistive technologies -- Accommodating different communication styles and needs -- Recognising that not everyone communicates the same way - -### Unacceptable Behaviour - -The following behaviours are considered harassment and are unacceptable: - -**Harassment** -- The use of sexualised language or imagery, and sexual attention or advances of any kind -- Trolling, insulting or derogatory comments, and personal or political attacks -- Public or private harassment -- Deliberate intimidation, stalking, or following (online or in-person) -- Unwelcome physical contact or simulated physical contact (e.g., emoji) -- Sustained disruption of talks, events, or online discussions - -**Discrimination** -- Discriminatory jokes and language -- Posting or threatening to post others' personally identifying information ("doxing") -- Advocating for, or encouraging, any of the above behaviour -- Microaggressions — subtle, often unintentional, discriminatory comments or actions - -**Professional Misconduct** -- Publishing others' private information without explicit permission -- Misrepresenting affiliation or contributions -- Plagiarism or claiming credit for others' work -- Retaliating against anyone who reports a Code of Conduct violation -- Other conduct which could reasonably be considered inappropriate in a professional setting - -### Grey Areas - -Some situations require judgement. When uncertain: - -- **Intent vs Impact**: Good intentions do not excuse harmful impact. Focus on making things right. -- **Power Dynamics**: Those with more power (maintainers, employers, experienced contributors) must be especially mindful of their impact. -- **Cultural Differences**: What's acceptable varies by culture. When in doubt, err on the side of caution and ask. -- **Humour**: Jokes at others' expense are rarely funny to everyone. Punch up, not down. - ---- - -## Scope - -This Code of Conduct applies within all community spaces, including: - -**Online Spaces** -- Repository discussions, issues, and pull/merge requests -- Project chat channels (Matrix, Discord, Slack, IRC) -- Mailing lists and forums -- Social media when representing the project -- Video calls and virtual meetings - -**In-Person Spaces** -- Conferences, meetups, and events -- Workshops and training sessions -- Any gathering where you represent the project - -**Representation** -This Code of Conduct also applies when an individual is officially representing the community in public spaces. Examples include: - -- Using an official project email address -- Posting via an official social media account -- Acting as an appointed representative at an event -- Speaking on behalf of the project - ---- - -## Enforcement - -### Reporting - -If you experience or witness unacceptable behaviour, or have any other concerns, please report it as soon as possible. - -**How to Report** - -| Method | Details | Best For | -|--------|---------|----------| -| **Email** | j.d.a.jewell@open.ac.uk | Detailed reports, sensitive matters | -| **Private Message** | Contact any maintainer directly | Quick questions, minor issues | -| **Anonymous Form** | [Link to form if available] | When you need anonymity | - -**What to Include** - -- Your contact information (unless anonymous) -- Names/usernames of those involved -- Description of what happened -- When and where it occurred -- Any witnesses -- Any supporting evidence (screenshots, links) -- How you would like us to respond (if you have a preference) - -**What Happens Next** - -1. You will receive acknowledgment within **48 hours** -2. The Statistikles maintainers will review the report -3. We may ask for additional information -4. We will determine appropriate action -5. We will inform you of the outcome (respecting others' privacy) - -### Confidentiality - -All reports will be handled with discretion: - -- Reporter identity is protected by default -- Details are shared only with those who need to know -- We will ask before naming you in any communication -- Anonymous reports are accepted and investigated - -### Conflicts of Interest - -If a Statistikles maintainers member is involved in an incident: - -- They will recuse themselves from the process -- Another maintainer or external party will handle the report -- We will disclose any potential conflicts - ---- - -## Enforcement Guidelines - -The Statistikles maintainers will follow these guidelines in determining consequences: - -### 1. Correction - -**Community Impact**: Use of inappropriate language or other behaviour deemed unprofessional or unwelcome. - -**Consequence**: A private, written warning providing clarity around the nature of the violation and an explanation of why the behaviour was inappropriate. A public apology may be requested. - -**Duration**: Immediate - -### 2. Warning - -**Community Impact**: A violation through a single incident or series of actions. - -**Consequence**: A warning with consequences for continued behaviour. No interaction with the people involved, including unsolicited interaction with those enforcing the Code of Conduct, for a specified period. 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. - -**Duration**: 1-4 weeks - -### 3. Temporary Ban - -**Community Impact**: A serious violation of community standards, including sustained inappropriate behaviour. - -**Consequence**: A temporary ban from any sort of interaction or public communication with the community for a specified period. 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. - -**Duration**: 1-6 months - -### 4. Permanent Ban - -**Community Impact**: Demonstrating a pattern of violation of community standards, including sustained inappropriate behaviour, 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. - -**Duration**: Permanent (with appeal rights after 12 months) - -### Enforcement Across Perimeters - -For contributors with elevated access (Perimeter 2 or 1): - -| Level | Additional Consequence | -|-------|----------------------| -| Correction | Noted in contributor record | -| Warning | Access privileges may be temporarily reduced | -| Temporary Ban | Access reduced to Perimeter 3 for ban duration | -| Permanent Ban | All access revoked | - ---- - -## Appeals - -If you believe an enforcement decision was made in error: - -1. **Wait 7 days** after the decision (cooling-off period) -2. **Email** j.d.a.jewell@open.ac.uk with subject line "Appeal: [Original Report ID]" -3. **Explain** why you believe the decision should be reconsidered -4. **Provide** any new information not previously available - -**Appeals Process** - -- Appeals are reviewed by a different Statistikles maintainers member than the original -- You will receive a response within 14 days -- The appeals decision is final -- You may only appeal once per incident - -**Grounds for Appeal** - -- Procedural errors in the original investigation -- New evidence not previously available -- Disproportionate response to the violation -- Misunderstanding of facts - ---- - -## Supporting Those Who Report - -We are committed to supporting those who report violations: - -**We Will** -- Believe and take all reports seriously -- Respect your privacy and confidentiality preferences -- Keep you informed of progress (if you wish) -- Take steps to protect you from retaliation -- Provide resources if you need support - -**We Will Not** -- Require you to confront the person directly -- Dismiss reports without investigation -- Reveal your identity without consent -- Tolerate retaliation against reporters -- Rush you to make decisions - ---- - -## Prevention - -Beyond enforcement, we actively work to prevent issues: - -**Onboarding** -- All contributors are expected to read this Code of Conduct -- Perimeter 2 applicants must confirm they've read and understood it -- Maintainers receive additional training on enforcement - -**Culture** -- We model the behaviour we expect -- We intervene early when we see potential issues -- We thank people for positive contributions -- We create opportunities for diverse voices - -**Review** -- This Code of Conduct is reviewed annually -- Community feedback is welcomed -- Changes are communicated clearly - ---- - -## Acknowledgments - -This Code of Conduct is adapted from: - -- [Contributor Covenant](https://www.contributor-covenant.org/), version 2.1 -- [Django Code of Conduct](https://www.djangoproject.com/conduct/) -- [Rust Code of Conduct](https://www.rust-lang.org/policies/code-of-conduct) -- [Python Community Code of Conduct](https://www.python.org/psf/conduct/) - -We thank these communities for their leadership in creating welcoming spaces. - ---- - -## Questions? - -If you have questions about this Code of Conduct: - -- Open a [Discussion](https://github.com/hyperpolymath/statistikles/discussions) (for general questions) -- Email j.d.a.jewell@open.ac.uk (for private questions) -- Contact any maintainer directly - ---- - -## Summary - -**Be kind. Be respectful. Be collaborative.** - -We're all here because we care about this project. Let's make it a place where everyone can do their best work. - ---- - -Last updated: 2026 · Based on Contributor Covenant 2.1 diff --git a/CONTRIBUTING.adoc b/CONTRIBUTING.adoc new file mode 100644 index 0000000..cfde1b7 --- /dev/null +++ b/CONTRIBUTING.adoc @@ -0,0 +1,113 @@ +== Clone the repository + +git clone https://github.com/hyperpolymath/statistikles.git cd +statistikles + +== Using Nix (recommended for reproducibility) + +nix develop + +== Or using toolbox/distrobox + +toolbox create statistikles-dev toolbox enter statistikles-dev # Install +dependencies manually + +== Verify setup + +just check # or: cargo check / mix compile / etc. just test # Run test +suite + +.... + +### Repository Structure +.... + +statistikles/ ├── src/ # Source code (Perimeter 1-2) ├── lib/ # Library +code (Perimeter 1-2) ├── extensions/ # Extensions (Perimeter 2) ├── +plugins/ # Plugins (Perimeter 2) ├── tools/ # Tooling (Perimeter 2) ├── +docs/ # Documentation (Perimeter 3) │ ├── architecture/ # ADRs, specs +(Perimeter 2) │ └── proposals/ # RFCs (Perimeter 3) ├── examples/ # +Examples (Perimeter 3) ├── spec/ # Spec tests (Perimeter 3) ├── tests/ # +Test suite (Perimeter 2-3) ├── .machine_readable/ # ALL machine-readable +content (Perimeter 1) │ ├── *.a2ml # State files (STATE, META, +ECOSYSTEM, etc.) │ ├── bot_directives/ # Bot configs │ └── contractiles/ +# Policy contracts (k9, dust, lust, must, trust) ├── .well-known/ # +Protocol files (Perimeter 1-3) ├── .github/ # GitHub config (Perimeter +1) │ ├── ISSUE_TEMPLATE/ │ └── workflows/ ├── CHANGELOG.md ├── +CODE_OF_CONDUCT.md ├── CONTRIBUTING.md # This file ├── GOVERNANCE.md ├── +LICENSE ├── MAINTAINERS.md ├── README.adoc ├── SECURITY.md ├── flake.nix +# Nix flake — fallback (Perimeter 1) ├── guix.scm # Guix package — +primary (Perimeter 1) └── Justfile # Task runner (Perimeter 1) + +.... + +--- + +## How to Contribute + +### Reporting Bugs + +**Before reporting**: +1. Search existing issues +2. Check if it's already fixed in `main` +3. Determine which perimeter the bug affects + +**When reporting**: + +Use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.md) and include: + +- Clear, descriptive title +- Environment details (OS, versions, toolchain) +- Steps to reproduce +- Expected vs actual behaviour +- Logs, screenshots, or minimal reproduction + +### Suggesting Features + +**Before suggesting**: +1. Check the [roadmap](ROADMAP.md) if available +2. Search existing issues and discussions +3. Consider which perimeter the feature belongs to + +**When suggesting**: + +Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.md) and include: + +- Problem statement (what pain point does this solve?) +- Proposed solution +- Alternatives considered +- Which perimeter this affects + +### Your First Contribution + +Look for issues labelled: + +- [`good first issue`](https://github.com/hyperpolymath/statistikles/labels/good%20first%20issue) — Simple Perimeter 3 tasks +- [`help wanted`](https://github.com/hyperpolymath/statistikles/labels/help%20wanted) — Community help needed +- [`documentation`](https://github.com/hyperpolymath/statistikles/labels/documentation) — Docs improvements +- [`perimeter-3`](https://github.com/hyperpolymath/statistikles/labels/perimeter-3) — Community sandbox scope + +--- + +## Development Workflow + +### Branch Naming +.... + +docs/short-description # Documentation (P3) test/what-added # Test +additions (P3) feat/short-description # New features (P2) +fix/issue-number-description # Bug fixes (P2) refactor/what-changed # +Code improvements (P2) security/what-fixed # Security fixes (P1-2) + +.... + +### Commit Messages + +We follow [Conventional Commits](https://www.conventionalcommits.org/): +.... + +(): + +{empty}[optional body] + +{empty}[optional footer] diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md deleted file mode 100644 index e6a174b..0000000 --- a/CONTRIBUTING.md +++ /dev/null @@ -1,125 +0,0 @@ - -# Clone the repository -git clone https://github.com/hyperpolymath/statistikles.git -cd statistikles - -# Using Nix (recommended for reproducibility) -nix develop - -# Or using toolbox/distrobox -toolbox create statistikles-dev -toolbox enter statistikles-dev -# Install dependencies manually - -# Verify setup -just check # or: cargo check / mix compile / etc. -just test # Run test suite -``` - -### Repository Structure -``` -statistikles/ -├── src/ # Source code (Perimeter 1-2) -├── lib/ # Library code (Perimeter 1-2) -├── extensions/ # Extensions (Perimeter 2) -├── plugins/ # Plugins (Perimeter 2) -├── tools/ # Tooling (Perimeter 2) -├── docs/ # Documentation (Perimeter 3) -│ ├── architecture/ # ADRs, specs (Perimeter 2) -│ └── proposals/ # RFCs (Perimeter 3) -├── examples/ # Examples (Perimeter 3) -├── spec/ # Spec tests (Perimeter 3) -├── tests/ # Test suite (Perimeter 2-3) -├── .machine_readable/ # ALL machine-readable content (Perimeter 1) -│ ├── *.a2ml # State files (STATE, META, ECOSYSTEM, etc.) -│ ├── bot_directives/ # Bot configs -│ └── contractiles/ # Policy contracts (k9, dust, lust, must, trust) -├── .well-known/ # Protocol files (Perimeter 1-3) -├── .github/ # GitHub config (Perimeter 1) -│ ├── ISSUE_TEMPLATE/ -│ └── workflows/ -├── CHANGELOG.md -├── CODE_OF_CONDUCT.md -├── CONTRIBUTING.md # This file -├── GOVERNANCE.md -├── LICENSE -├── MAINTAINERS.md -├── README.adoc -├── SECURITY.md -├── flake.nix # Nix flake — fallback (Perimeter 1) -├── guix.scm # Guix package — primary (Perimeter 1) -└── Justfile # Task runner (Perimeter 1) -``` - ---- - -## How to Contribute - -### Reporting Bugs - -**Before reporting**: -1. Search existing issues -2. Check if it's already fixed in `main` -3. Determine which perimeter the bug affects - -**When reporting**: - -Use the [bug report template](.github/ISSUE_TEMPLATE/bug_report.md) and include: - -- Clear, descriptive title -- Environment details (OS, versions, toolchain) -- Steps to reproduce -- Expected vs actual behaviour -- Logs, screenshots, or minimal reproduction - -### Suggesting Features - -**Before suggesting**: -1. Check the [roadmap](ROADMAP.md) if available -2. Search existing issues and discussions -3. Consider which perimeter the feature belongs to - -**When suggesting**: - -Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.md) and include: - -- Problem statement (what pain point does this solve?) -- Proposed solution -- Alternatives considered -- Which perimeter this affects - -### Your First Contribution - -Look for issues labelled: - -- [`good first issue`](https://github.com/hyperpolymath/statistikles/labels/good%20first%20issue) — Simple Perimeter 3 tasks -- [`help wanted`](https://github.com/hyperpolymath/statistikles/labels/help%20wanted) — Community help needed -- [`documentation`](https://github.com/hyperpolymath/statistikles/labels/documentation) — Docs improvements -- [`perimeter-3`](https://github.com/hyperpolymath/statistikles/labels/perimeter-3) — Community sandbox scope - ---- - -## Development Workflow - -### Branch Naming -``` -docs/short-description # Documentation (P3) -test/what-added # Test additions (P3) -feat/short-description # New features (P2) -fix/issue-number-description # Bug fixes (P2) -refactor/what-changed # Code improvements (P2) -security/what-fixed # Security fixes (P1-2) -``` - -### Commit Messages - -We follow [Conventional Commits](https://www.conventionalcommits.org/): -``` -(): - -[optional body] - -[optional footer] diff --git a/GOVERNANCE.adoc b/GOVERNANCE.adoc new file mode 100644 index 0000000..2be1697 --- /dev/null +++ b/GOVERNANCE.adoc @@ -0,0 +1,262 @@ +== Project Governance + +This document describes the governance model for *Statistikles*. + +''''' + +=== Project Governance Model + +Statistikles follows a *Benevolent Dictator For Life (BDFL)* governance +model. This model is well-suited for solo maintainers and small project +teams where rapid, consistent decision-making is more valuable than +formal consensus processes. + +The BDFL has final authority on all project decisions, including +technical direction, release schedules, contributor access, and +community standards. + +____ +*Transition clause:* When the core team exceeds three active +maintainers, this project should transition to a *consensus-based +governance model* with documented voting procedures. That transition +should itself be recorded as an Architecture Decision Record (ADR) in +`+docs/decisions/+`. +____ + +''''' + +=== Decision Making + +==== Day-to-day decisions + +* The BDFL makes final decisions on all matters. +* Routine decisions (bug fixes, dependency updates, minor improvements) +may be made by any maintainer with commit access. +* Maintainers are expected to use good judgement and seek input on +non-trivial changes. + +==== Proposing changes + +* Contributors can propose changes by opening issues or pull requests. +* Significant changes (new features, breaking changes, architectural +shifts) should be discussed in an issue before implementation begins. +* The BDFL will provide a clear accept/reject decision with reasoning. + +==== Architecture Decision Records (ADRs) + +* Significant technical decisions are documented as ADRs in +`+docs/decisions/+`. +* ADR statuses: `+proposed+`, `+accepted+`, `+deprecated+`, +`+superseded+`, `+rejected+`. +* ADRs provide a historical record of why decisions were made and what +alternatives were considered. +* See `+.machine_readable/META.a2ml+` for the machine-readable ADR +index. + +''''' + +=== Roles + +==== BDFL (Benevolent Dictator For Life) + +* The project creator and ultimate decision-maker. +* Sets the project’s technical direction and long-term vision. +* Has final say on all matters, including maintainer appointments and +removals. +* Responsible for ensuring the project adheres to RSR standards. + +==== Maintainer + +* Has commit access to the repository. +* Reviews and merges pull requests. +* Triages issues and manages releases. +* Upholds code quality, security standards, and the Code of Conduct. +* Listed in MAINTAINERS.md. + +==== Contributor + +* Anyone who submits pull requests, opens issues, or participates in +discussions. +* Does not have direct commit access. +* Contributions are reviewed by maintainers before merging. +* All contributors must follow the link:CODE_OF_CONDUCT.md[Code of +Conduct]. + +==== Bot + +* Automated agents managed via your bot orchestration system. +* Perform automated code review, security scanning, dependency updates, +and standards enforcement. +* Bot actions are subject to the same quality and review standards as +human contributions. +* Configure your bots in `+.machine_readable/bot_directives/+`. + +''''' + +=== Becoming a Maintainer + +A contributor may be nominated to become a maintainer when they +demonstrate: + +[arabic] +. *Sustained quality contributions* – a track record of well-crafted +pull requests that follow project conventions and require minimal +revision. +. *Understanding of RSR standards* – familiarity with the Repository +Structure Requirements, security policies, and CI/CD workflows used +across the project. +. *Constructive participation* – helpful issue triage, thoughtful code +review comments, and mentoring of other contributors. +. *Reliability* – consistent engagement over a meaningful period +(typically 3+ months of active contribution). + +==== Process + +[arabic] +. An existing maintainer nominates the candidate by opening a private +discussion with the BDFL. +. The BDFL reviews the candidate’s contribution history and community +interactions. +. The BDFL approves or declines the nomination, with reasoning provided +to the nominator. +. If approved, the new maintainer is added to MAINTAINERS.md and granted +appropriate repository access. + +''''' + +=== Removing a Maintainer + +A maintainer may be removed under the following circumstances: + +* *Inactivity*: No meaningful contributions or reviews for 12 or more +consecutive months. The maintainer will be contacted before removal and +offered the option to move to emeritus status voluntarily. +* *Code of Conduct violation*: Behaviour that violates the +link:CODE_OF_CONDUCT.md[Code of Conduct], as determined through the +enforcement process described therein. +* *BDFL discretion*: The BDFL may remove a maintainer for other reasons +(e.g., repeated disregard for project standards, loss of trust). +Reasoning will be documented privately. + +Removed maintainers are moved to the Emeritus section of MAINTAINERS.md +unless removal was due to a serious Code of Conduct violation. + +''''' + +=== Code of Conduct + +All participants in this project are expected to follow the +link:CODE_OF_CONDUCT.md[Code of Conduct]. The Code of Conduct applies to +all project spaces, including issues, pull requests, discussions, and +any forum where the project is represented. + +Enforcement of the Code of Conduct is described in that document. The +BDFL serves as the final arbiter in conduct disputes. + +''''' + +=== Amendments + +This governance document may be amended by the BDFL at any time. All +amendments will be: + +[arabic] +. Documented as an ADR in `+docs/decisions/+` explaining the rationale +for the change. +. Committed to the repository with a clear commit message. +. Communicated to existing maintainers and contributors via the +project’s usual channels. + +Substantive changes (e.g., changing the governance model itself) should +be discussed with the community before adoption, even though the BDFL +retains final authority. + +''''' + +=== Contribution Lifecycle + +[cols=",",options="header",] +|=== +|Stage |Process +|*Ideation* |Open issue, discuss feasibility +|*Development* |Fork, implement, test thoroughly +|*Review* |Submit PR, maintainer reviews within 7 days +|*Merge* |Maintainer merges or requests changes +|*Release* |Maintainer publishes according to project conventions +|=== + +=== Conflict Resolution + +In case of disagreements: + +[arabic] +. Discuss in the relevant GitHub issue or PR. +. Provide technical justification for positions. +. Maintainer mediates and makes the final decision. +. The decision is documented and can be revisited later. + +=== Project Policies + +This repository adheres to hyperpolymath estate-wide policies: + +* *Licence* — MPL-2.0 for code, CC-BY-SA-4.0 for prose (per +`+standards/LICENCE-POLICY.adoc+`) +* *Code of Conduct* — follows hyperpolymath `+CODE_OF_CONDUCT.md+` +* *Security* — follows hyperpolymath `+SECURITY.md+` +* *Contributing* — follows hyperpolymath `+CONTRIBUTING.adoc+` +conventions + +=== Repository-Specific Conventions + +[width="100%",cols="50%,50%",options="header",] +|=== +|Convention |Description +|*Signing* |All commits must be signed (SSH or GPG) + +|*SPDX headers* |All source files must carry SPDX licence identifiers + +|*Contractiles* |`+Mustfile+`, `+Trustfile+`, `+Intendfile+`, +`+Adjustfile+` in root + +|*Machine readable* |`+META.a2ml+` in `+.machine_readable/6a2/+` + +|*CI/CD* |GitHub Actions workflows in `+.github/workflows/+` +|=== + +=== Governance Evolution + +As the project grows, this governance model may evolve: + +* *Adding co-maintainers* — when contribution volume warrants it +* *Forming a team* — for complex multi-maintainer projects +* *Adopting TPCF* — for large, multi-repository projects (see +`+rhodium-standard-repositories+`) + +Changes to this document require the same process as Significant Changes +above. + +=== See Also + +* link:MAINTAINERS.md[Maintainers] +* link:CODE_OF_CONDUCT.md[Code of Conduct] +* link:CONTRIBUTING.md[Contributing Guide] +* https://github.com/hyperpolymath/standards/blob/main/LICENCE-POLICY.adoc[Estate +Licence Policy] +* https://github.com/hyperpolymath/standards[rhodium-standard-repositories +(TPCF)] + +=== Changelog + +[width="100%",cols="34%,33%,33%",options="header",] +|=== +|Date |Change |By +|2026-06-07 |Initial governance model established |@hyperpolymath + +|2026-07-27 |Merged in the sections that had lived only in +`+GOVERNANCE.adoc+`, which was deleted in #68; this file is now the +single source. |@hyperpolymath +|=== + +''''' + +Copyright (c) 2026 hyperpolymath. Licensed under MPL-2.0. diff --git a/GOVERNANCE.md b/GOVERNANCE.md deleted file mode 100644 index 460a1fb..0000000 --- a/GOVERNANCE.md +++ /dev/null @@ -1,225 +0,0 @@ - -# Project Governance - -This document describes the governance model for **Statistikles**. - ---- - -## Project Governance Model - -Statistikles follows a **Benevolent Dictator For Life (BDFL)** governance model. -This model is well-suited for solo maintainers and small project teams where rapid, -consistent decision-making is more valuable than formal consensus processes. - -The BDFL has final authority on all project decisions, including technical direction, -release schedules, contributor access, and community standards. - -> **Transition clause:** When the core team exceeds three active maintainers, this -> project should transition to a **consensus-based governance model** with documented -> voting procedures. That transition should itself be recorded as an Architecture -> Decision Record (ADR) in `docs/decisions/`. - ---- - -## Decision Making - -### Day-to-day decisions - -- The BDFL makes final decisions on all matters. -- Routine decisions (bug fixes, dependency updates, minor improvements) may be made - by any maintainer with commit access. -- Maintainers are expected to use good judgement and seek input on non-trivial changes. - -### Proposing changes - -- Contributors can propose changes by opening issues or pull requests. -- Significant changes (new features, breaking changes, architectural shifts) should - be discussed in an issue before implementation begins. -- The BDFL will provide a clear accept/reject decision with reasoning. - -### Architecture Decision Records (ADRs) - -- Significant technical decisions are documented as ADRs in `docs/decisions/`. -- ADR statuses: `proposed`, `accepted`, `deprecated`, `superseded`, `rejected`. -- ADRs provide a historical record of why decisions were made and what alternatives - were considered. -- See `.machine_readable/META.a2ml` for the machine-readable ADR index. - ---- - -## Roles - -### BDFL (Benevolent Dictator For Life) - -- The project creator and ultimate decision-maker. -- Sets the project's technical direction and long-term vision. -- Has final say on all matters, including maintainer appointments and removals. -- Responsible for ensuring the project adheres to RSR standards. - -### Maintainer - -- Has commit access to the repository. -- Reviews and merges pull requests. -- Triages issues and manages releases. -- Upholds code quality, security standards, and the Code of Conduct. -- Listed in [MAINTAINERS.md](MAINTAINERS.md). - -### Contributor - -- Anyone who submits pull requests, opens issues, or participates in discussions. -- Does not have direct commit access. -- Contributions are reviewed by maintainers before merging. -- All contributors must follow the [Code of Conduct](CODE_OF_CONDUCT.md). - -### Bot - -- Automated agents managed via your bot orchestration system. -- Perform automated code review, security scanning, dependency updates, and - standards enforcement. -- Bot actions are subject to the same quality and review standards as human - contributions. -- Configure your bots in `.machine_readable/bot_directives/`. - ---- - -## Becoming a Maintainer - -A contributor may be nominated to become a maintainer when they demonstrate: - -1. **Sustained quality contributions** -- a track record of well-crafted pull requests - that follow project conventions and require minimal revision. -2. **Understanding of RSR standards** -- familiarity with the Repository Structure - Requirements, security policies, and CI/CD workflows used across the project. -3. **Constructive participation** -- helpful issue triage, thoughtful code review - comments, and mentoring of other contributors. -4. **Reliability** -- consistent engagement over a meaningful period (typically 3+ - months of active contribution). - -### Process - -1. An existing maintainer nominates the candidate by opening a private discussion - with the BDFL. -2. The BDFL reviews the candidate's contribution history and community interactions. -3. The BDFL approves or declines the nomination, with reasoning provided to the - nominator. -4. If approved, the new maintainer is added to [MAINTAINERS.md](MAINTAINERS.md) and - granted appropriate repository access. - ---- - -## Removing a Maintainer - -A maintainer may be removed under the following circumstances: - -- **Inactivity**: No meaningful contributions or reviews for 12 or more consecutive - months. The maintainer will be contacted before removal and offered the option to - move to emeritus status voluntarily. -- **Code of Conduct violation**: Behaviour that violates the - [Code of Conduct](CODE_OF_CONDUCT.md), as determined through the enforcement - process described therein. -- **BDFL discretion**: The BDFL may remove a maintainer for other reasons (e.g., - repeated disregard for project standards, loss of trust). Reasoning will be - documented privately. - -Removed maintainers are moved to the Emeritus section of -[MAINTAINERS.md](MAINTAINERS.md) unless removal was due to a serious Code of Conduct -violation. - ---- - -## Code of Conduct - -All participants in this project are expected to follow the -[Code of Conduct](CODE_OF_CONDUCT.md). The Code of Conduct applies to all project -spaces, including issues, pull requests, discussions, and any forum where the project -is represented. - -Enforcement of the Code of Conduct is described in that document. The BDFL serves as -the final arbiter in conduct disputes. - ---- - -## Amendments - -This governance document may be amended by the BDFL at any time. All amendments will -be: - -1. Documented as an ADR in `docs/decisions/` explaining the rationale for the change. -2. Committed to the repository with a clear commit message. -3. Communicated to existing maintainers and contributors via the project's usual - channels. - -Substantive changes (e.g., changing the governance model itself) should be discussed -with the community before adoption, even though the BDFL retains final authority. - ---- - -## Contribution Lifecycle - -| Stage | Process | -|---|---| -| **Ideation** | Open issue, discuss feasibility | -| **Development** | Fork, implement, test thoroughly | -| **Review** | Submit PR, maintainer reviews within 7 days | -| **Merge** | Maintainer merges or requests changes | -| **Release** | Maintainer publishes according to project conventions | - -## Conflict Resolution - -In case of disagreements: - -1. Discuss in the relevant GitHub issue or PR. -2. Provide technical justification for positions. -3. Maintainer mediates and makes the final decision. -4. The decision is documented and can be revisited later. - -## Project Policies - -This repository adheres to hyperpolymath estate-wide policies: - -- **Licence** — MPL-2.0 for code, CC-BY-SA-4.0 for prose (per `standards/LICENCE-POLICY.adoc`) -- **Code of Conduct** — follows hyperpolymath `CODE_OF_CONDUCT.md` -- **Security** — follows hyperpolymath `SECURITY.md` -- **Contributing** — follows hyperpolymath `CONTRIBUTING.adoc` conventions - -## Repository-Specific Conventions - -| Convention | Description | -|---|---| -| **Signing** | All commits must be signed (SSH or GPG) | -| **SPDX headers** | All source files must carry SPDX licence identifiers | -| **Contractiles** | `Mustfile`, `Trustfile`, `Intendfile`, `Adjustfile` in root | -| **Machine readable** | `META.a2ml` in `.machine_readable/6a2/` | -| **CI/CD** | GitHub Actions workflows in `.github/workflows/` | - -## Governance Evolution - -As the project grows, this governance model may evolve: - -- **Adding co-maintainers** — when contribution volume warrants it -- **Forming a team** — for complex multi-maintainer projects -- **Adopting TPCF** — for large, multi-repository projects (see `rhodium-standard-repositories`) - -Changes to this document require the same process as Significant Changes above. - -## See Also - -- [Maintainers](MAINTAINERS.md) -- [Code of Conduct](CODE_OF_CONDUCT.md) -- [Contributing Guide](CONTRIBUTING.md) -- [Estate Licence Policy](https://github.com/hyperpolymath/standards/blob/main/LICENCE-POLICY.adoc) -- [rhodium-standard-repositories (TPCF)](https://github.com/hyperpolymath/standards) - -## Changelog - -| Date | Change | By | -|---|---|---| -| 2026-06-07 | Initial governance model established | @hyperpolymath | -| 2026-07-27 | Merged in the sections that had lived only in `GOVERNANCE.adoc`, which was deleted in #68; this file is now the single source. | @hyperpolymath | - ---- - -Copyright (c) 2026 hyperpolymath. Licensed under MPL-2.0. diff --git a/MAINTAINERS.adoc b/MAINTAINERS.adoc index aa23a55..8a038af 100644 --- a/MAINTAINERS.adoc +++ b/MAINTAINERS.adoc @@ -1,48 +1,43 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= Maintainers -:toc: preamble +== Maintainers -This document lists the maintainers of this project and their responsibilities. +This document lists the current and former maintainers of +*Statistikles*. -== Current Maintainers +''''' -[cols="2,3,2",options="header"] -|=== -| Name | Role | Contact +=== Current Maintainers -| Jonathan D.A. Jewell -| Lead Maintainer -| https://github.com/hyperpolymath[@hyperpolymath] +[width="100%",cols="24%,29%,22%,25%",options="header",] +|=== +|Name |GitHub |Role |Since +|Jonathan D.A. Jewell |https://github.com/hyperpolymath[@hyperpolymath] +|BDFL |2026-02-20 |=== -== 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 +''''' -== Becoming a Maintainer +=== How to Become a Maintainer -Contributors who demonstrate: +Contributors who demonstrate sustained, high-quality contributions and a +solid understanding of the project’s standards and goals may be +nominated to become maintainers. The full criteria and process are +described in GOVERNANCE.md. If you are interested, the best path is to +start contributing consistently and engage constructively in issues and +code reviews. -* 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. +=== Emeritus -== Decision Making +Former maintainers who have stepped back from active maintenance. We are +grateful for their contributions. -* 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=",,,",options="header",] +|=== +|Name |GitHub |Role |Active +|_None yet_ | | | +|=== -== Contact +''''' -For questions about project governance, open an issue or contact the maintainers listed above. +Copyright (c) 2026 hyperpolymath. Licensed under MPL-2.0. diff --git a/MAINTAINERS.md b/MAINTAINERS.md deleted file mode 100644 index 7c6a918..0000000 --- a/MAINTAINERS.md +++ /dev/null @@ -1,40 +0,0 @@ - -# Maintainers - -This document lists the current and former maintainers of **Statistikles**. - ---- - -## Current Maintainers - -| Name | GitHub | Role | Since | -|------|--------|------|-------| -| Jonathan D.A. Jewell | [@hyperpolymath](https://github.com/hyperpolymath) | BDFL | 2026-02-20 | - ---- - -## How to Become a Maintainer - -Contributors who demonstrate sustained, high-quality contributions and a solid -understanding of the project's standards and goals may be nominated to become -maintainers. The full criteria and process are described in -[GOVERNANCE.md](GOVERNANCE.md). If you are interested, the best path is to start -contributing consistently and engage constructively in issues and code reviews. - ---- - -## Emeritus - -Former maintainers who have stepped back from active maintenance. We are grateful -for their contributions. - -| Name | GitHub | Role | Active | -|------|--------|------|--------| -| *None yet* | | | | - ---- - -Copyright (c) 2026 hyperpolymath. Licensed under MPL-2.0. diff --git a/PLACEHOLDERS.adoc b/PLACEHOLDERS.adoc new file mode 100644 index 0000000..fdda6b3 --- /dev/null +++ b/PLACEHOLDERS.adoc @@ -0,0 +1,219 @@ +== Template Placeholders + +All placeholders in this template follow the `+{{PLACEHOLDER}}+` +pattern. After cloning, replace them with your project-specific values. + +=== Recommended: Interactive Bootstrap + +[source,bash] +---- +just init +---- + +This interactively prompts for all values, replaces every placeholder, +validates the result, and runs k9-svc checks if available. + +=== Manual Replace + +[source,bash] +---- +# If you prefer manual replacement (run from repo root) + +sed -i 's/Jonathan D.A. Jewell/Jane Doe/g' $(grep -rl 'Jonathan D.A. Jewell' .) +sed -i 's/j.d.a.jewell@open.ac.uk/jane@example.org/g' $(grep -rl 'j.d.a.jewell@open.ac.uk' .) +sed -i 's/hyperpolymath/my-org/g' $(grep -rl 'hyperpolymath' .) +sed -i 's/Statistikles/my-project/g' $(grep -rl 'Statistikles' .) +sed -i 's/{{PROJECT}}/MY_PROJECT/g' $(grep -rl '{{PROJECT}}' .) +sed -i 's/{{project}}/my_project/g' $(grep -rl '{{project}}' .) +sed -i 's/statistikles/my-project/g' $(grep -rl 'statistikles' .) +sed -i 's/github.com/github.com/g' $(grep -rl 'github.com' .) +sed -i "s/2026/$(date +%Y)/g" $(grep -rl '2026' .) +sed -i "s/2026-03-16/$(date +%Y-%m-%d)/g" $(grep -rl '2026-03-16' .) +---- + +=== Placeholder Reference + +==== Author & Copyright + +[width="100%",cols="25%,25%,25%,25%",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+Jonathan D.A. Jewell+` |Full legal name |`+Jane Doe+` |SPDX headers +(all files), MAINTAINERS.md, .mailmap, .reuse/dep5, +docs/AI-CONVENTIONS.md + +|`+j.d.a.jewell@open.ac.uk+` |Primary contact email +|`+jane@example.org+` |SPDX headers (all files), .mailmap, .reuse/dep5, +.well-known/humans.txt + +|`+{{AUTHOR_EMAIL_ALT}}+` |Previous/secondary email (for .mailmap) +|`+old@example.com+` |.mailmap + +|`+{{AUTHOR_ORG}}+` |Author’s organization/affiliation +|`+Acme University+` |project-metadata.k9.ncl + +|`+{{AUTHOR_LAST}}+` |Author surname (for citations) |`+Doe+` +|docs/CITATIONS.adoc + +|`+{{AUTHOR_FIRST}}+` |Author first name (for citations) |`+Jane+` +|docs/CITATIONS.adoc + +|`+{{AUTHOR_INITIALS}}+` |Author initials (for citations) |`+J.+` +|docs/CITATIONS.adoc +|=== + +==== Project Identity + +[width="100%",cols="25%,25%,25%,25%",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+Statistikles+` |Human-readable project name |`+My Project+` +|SECURITY.md, CODE_OF_CONDUCT.md, TOPOLOGY.md, STATE.a2ml, Justfile, +GOVERNANCE.md, MAINTAINERS.md, flake.nix, devcontainer.json + +|`+{{PROJECT_DESCRIPTION}}+` |One-line description |`+A tool for X+` +|flake.nix + +|`+{{PROJECT}}+` |Uppercase identifier (for Idris2 modules, C macros) +|`+MY_PROJECT+` |ABI-FFI-README.md, src/abi/_.idr, ffi/zig/_.zig + +|`+{{project}}+` |Lowercase identifier (for C symbols, filenames) +|`+my_project+` |ABI-FFI-README.md, ffi/zig/*.zig + +|`+statistikles+` |Repository name (slug) |`+my-project+` +|CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md, cliff.toml + +|`+hyperpolymath+` |GitHub/GitLab org or username |`+my-org+` |SPDX +headers, CONTRIBUTING.md, SECURITY.md, GOVERNANCE.md, MAINTAINERS.md, +CODEOWNERS, mirror.yml, cliff.toml + +|`+github.com+` |Git forge domain |`+github.com+` |CONTRIBUTING.md +|=== + +==== Dates + +[width="100%",cols="25%,25%,25%,25%",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+2026+` |Current year |`+2026+` |SPDX headers (all files), +GOVERNANCE.md, MAINTAINERS.md + +|`+2026-03-16+` |Current date (ISO) |`+2026-02-14+` |STATE.a2ml, +MAINTAINERS.md + +|`+{{DATE}}+` |Last updated date |`+2026-02-14+` |TOPOLOGY.md, +THREAT-MODEL.md +|=== + +==== Contact & Security + +[width="100%",cols="25%,25%,25%,25%",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+6759885+hyperpolymath@users.noreply.github.com+` |Security contact +email |`+security@example.org+` |SECURITY.md + +|`+[PGP fingerprint not set]+` |40-char PGP fingerprint +|`+ABCD 1234 ...+` |SECURITY.md + +|`+{{PGP_KEY_URL}}+` |URL to public PGP key +|`+https://keys.openpgp.org/...+` |SECURITY.md + +|`+{{WEBSITE}}+` |Project website |`+https://example.org+` |SECURITY.md + +|`+{{CONDUCT_EMAIL}}+` |Conduct reports email |`+conduct@example.org+` +|CODE_OF_CONDUCT.md + +|`+{{CONDUCT_TEAM}}+` |Conduct committee name +|`+Code of Conduct Committee+` |CODE_OF_CONDUCT.md + +|`+{{RESPONSE_TIME}}+` |SLA for initial response |`+48 hours+` +|CODE_OF_CONDUCT.md +|=== + +==== Git + +[cols=",,,",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+main+` |Main branch name |`+main+` |CONTRIBUTING.md +|=== + +==== Build + +[width="100%",cols="25%,25%,25%,25%",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+MPL-2.0+` |License name |`+MPL-2.0+` |ABI-FFI-README.md + +|`+{{PROJECT_PURPOSE}}+` |One-line project description +|`+FFI bridges between languages+` |STATE.a2ml +|=== + +==== AI Manifest + +[width="100%",cols="25%,25%,25%,25%",options="header",] +|=== +|Placeholder |Description |Example |Files +|`+[YOUR-REPO-NAME]+` |Repository name |`+my-project+` +|0-AI-MANIFEST.a2ml + +|`+[DATE]+` |Creation date |`+2026-02-14+` |0-AI-MANIFEST.a2ml + +|`+[YOUR-NAME/ORG]+` |Maintainer name |`+hyperpolymath+` +|0-AI-MANIFEST.a2ml +|=== + +==== AI Installation Guide + +[width="100%",cols="34%,33%,33%",options="header",] +|=== +|Marker |Description |Files +|`+[TODO-AI-INSTALL]+` |Unfilled section in AI installation guide +|`+docs/AI_INSTALLATION_GUIDE.adoc+`, +`+docs/AI-INSTALL-README-SECTION.adoc+`, `+README.adoc+` +|=== + +These are *not* standard `+{{PLACEHOLDER}}+` markers – they are TODO +markers that must be replaced with project-specific content before +release. They mark sections where the developer (or AI) must fill in: + +* What questions the AI should ask the user +* Exact prerequisite check and install commands +* Privacy notice specific to this project +* Complete installation command block +* Credential setup instructions (URLs, scopes, env vars) +* Verification commands and expected output +* Error handling table +* Example conversation + +*finishbot checks:* `+just validate-ai-install+` verifies no +`+[TODO-AI-INSTALL]+` markers remain. + +=== Deletion Markers + +Some files contain deletion instructions: + +[width="100%",cols="34%,33%,33%",options="header",] +|=== +|Marker |Meaning |File +|`+{{~ ... ~}}+` |Delete this entire line after reading +|ABI-FFI-README.md (line 1) +|=== + +=== Verification + +After replacing all placeholders, verify none remain: + +[source,bash] +---- +grep -rn '{{' . --include='*.md' --include='*.adoc' --include='*.a2ml' \ + --include='*.scm' --include='*.idr' --include='*.zig' --include='*.res' \ + --include='Justfile' --include='*.nix' --include='*.toml' --include='*.yml' \ + --include='*.yaml' --include='*.hs' --include='*.ncl' --include='*.txt' \ + --include='*.json' --include='Containerfile' --include='dep5' \ + | grep -v 'PLACEHOLDERS.md' | grep -v 'node_modules' +---- + +If the above command produces no output, all placeholders have been +replaced. diff --git a/PLACEHOLDERS.md b/PLACEHOLDERS.md deleted file mode 100644 index bf76247..0000000 --- a/PLACEHOLDERS.md +++ /dev/null @@ -1,145 +0,0 @@ - -# Template Placeholders - -All placeholders in this template follow the `{{PLACEHOLDER}}` pattern. -After cloning, replace them with your project-specific values. - -## Recommended: Interactive Bootstrap - -```bash -just init -``` - -This interactively prompts for all values, replaces every placeholder, -validates the result, and runs k9-svc checks if available. - -## Manual Replace - -```bash -# If you prefer manual replacement (run from repo root) - -sed -i 's/Jonathan D.A. Jewell/Jane Doe/g' $(grep -rl 'Jonathan D.A. Jewell' .) -sed -i 's/j.d.a.jewell@open.ac.uk/jane@example.org/g' $(grep -rl 'j.d.a.jewell@open.ac.uk' .) -sed -i 's/hyperpolymath/my-org/g' $(grep -rl 'hyperpolymath' .) -sed -i 's/Statistikles/my-project/g' $(grep -rl 'Statistikles' .) -sed -i 's/{{PROJECT}}/MY_PROJECT/g' $(grep -rl '{{PROJECT}}' .) -sed -i 's/{{project}}/my_project/g' $(grep -rl '{{project}}' .) -sed -i 's/statistikles/my-project/g' $(grep -rl 'statistikles' .) -sed -i 's/github.com/github.com/g' $(grep -rl 'github.com' .) -sed -i "s/2026/$(date +%Y)/g" $(grep -rl '2026' .) -sed -i "s/2026-03-16/$(date +%Y-%m-%d)/g" $(grep -rl '2026-03-16' .) -``` - -## Placeholder Reference - -### Author & Copyright - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `Jonathan D.A. Jewell` | Full legal name | `Jane Doe` | SPDX headers (all files), MAINTAINERS.md, .mailmap, .reuse/dep5, docs/AI-CONVENTIONS.md | -| `j.d.a.jewell@open.ac.uk` | Primary contact email | `jane@example.org` | SPDX headers (all files), .mailmap, .reuse/dep5, .well-known/humans.txt | -| `{{AUTHOR_EMAIL_ALT}}` | Previous/secondary email (for .mailmap) | `old@example.com` | .mailmap | -| `{{AUTHOR_ORG}}` | Author's organization/affiliation | `Acme University` | project-metadata.k9.ncl | -| `{{AUTHOR_LAST}}` | Author surname (for citations) | `Doe` | docs/CITATIONS.adoc | -| `{{AUTHOR_FIRST}}` | Author first name (for citations) | `Jane` | docs/CITATIONS.adoc | -| `{{AUTHOR_INITIALS}}` | Author initials (for citations) | `J.` | docs/CITATIONS.adoc | - -### Project Identity - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `Statistikles` | Human-readable project name | `My Project` | SECURITY.md, CODE_OF_CONDUCT.md, TOPOLOGY.md, STATE.a2ml, Justfile, GOVERNANCE.md, MAINTAINERS.md, flake.nix, devcontainer.json | -| `{{PROJECT_DESCRIPTION}}` | One-line description | `A tool for X` | flake.nix | -| `{{PROJECT}}` | Uppercase identifier (for Idris2 modules, C macros) | `MY_PROJECT` | ABI-FFI-README.md, src/abi/*.idr, ffi/zig/*.zig | -| `{{project}}` | Lowercase identifier (for C symbols, filenames) | `my_project` | ABI-FFI-README.md, ffi/zig/*.zig | -| `statistikles` | Repository name (slug) | `my-project` | CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md, cliff.toml | -| `hyperpolymath` | GitHub/GitLab org or username | `my-org` | SPDX headers, CONTRIBUTING.md, SECURITY.md, GOVERNANCE.md, MAINTAINERS.md, CODEOWNERS, mirror.yml, cliff.toml | -| `github.com` | Git forge domain | `github.com` | CONTRIBUTING.md | - -### Dates - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `2026` | Current year | `2026` | SPDX headers (all files), GOVERNANCE.md, MAINTAINERS.md | -| `2026-03-16` | Current date (ISO) | `2026-02-14` | STATE.a2ml, MAINTAINERS.md | -| `{{DATE}}` | Last updated date | `2026-02-14` | TOPOLOGY.md, THREAT-MODEL.md | - -### Contact & Security - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `6759885+hyperpolymath@users.noreply.github.com` | Security contact email | `security@example.org` | SECURITY.md | -| `[PGP fingerprint not set]` | 40-char PGP fingerprint | `ABCD 1234 ...` | SECURITY.md | -| `{{PGP_KEY_URL}}` | URL to public PGP key | `https://keys.openpgp.org/...` | SECURITY.md | -| `{{WEBSITE}}` | Project website | `https://example.org` | SECURITY.md | -| `{{CONDUCT_EMAIL}}` | Conduct reports email | `conduct@example.org` | CODE_OF_CONDUCT.md | -| `{{CONDUCT_TEAM}}` | Conduct committee name | `Code of Conduct Committee` | CODE_OF_CONDUCT.md | -| `{{RESPONSE_TIME}}` | SLA for initial response | `48 hours` | CODE_OF_CONDUCT.md | - -### Git - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `main` | Main branch name | `main` | CONTRIBUTING.md | - -### Build - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `MPL-2.0` | License name | `MPL-2.0` | ABI-FFI-README.md | -| `{{PROJECT_PURPOSE}}` | One-line project description | `FFI bridges between languages` | STATE.a2ml | - -### AI Manifest - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `[YOUR-REPO-NAME]` | Repository name | `my-project` | 0-AI-MANIFEST.a2ml | -| `[DATE]` | Creation date | `2026-02-14` | 0-AI-MANIFEST.a2ml | -| `[YOUR-NAME/ORG]` | Maintainer name | `hyperpolymath` | 0-AI-MANIFEST.a2ml | - -### AI Installation Guide - -| Marker | Description | Files | -|---|---|---| -| `[TODO-AI-INSTALL]` | Unfilled section in AI installation guide | `docs/AI_INSTALLATION_GUIDE.adoc`, `docs/AI-INSTALL-README-SECTION.adoc`, `README.adoc` | - -These are **not** standard `{{PLACEHOLDER}}` markers -- they are TODO markers -that must be replaced with project-specific content before release. They mark -sections where the developer (or AI) must fill in: - -- What questions the AI should ask the user -- Exact prerequisite check and install commands -- Privacy notice specific to this project -- Complete installation command block -- Credential setup instructions (URLs, scopes, env vars) -- Verification commands and expected output -- Error handling table -- Example conversation - -**finishbot checks:** `just validate-ai-install` verifies no `[TODO-AI-INSTALL]` markers remain. - -## Deletion Markers - -Some files contain deletion instructions: - -| Marker | Meaning | File | -|---|---|---| -| `{{~ ... ~}}` | Delete this entire line after reading | ABI-FFI-README.md (line 1) | - -## Verification - -After replacing all placeholders, verify none remain: - -```bash -grep -rn '{{' . --include='*.md' --include='*.adoc' --include='*.a2ml' \ - --include='*.scm' --include='*.idr' --include='*.zig' --include='*.res' \ - --include='Justfile' --include='*.nix' --include='*.toml' --include='*.yml' \ - --include='*.yaml' --include='*.hs' --include='*.ncl' --include='*.txt' \ - --include='*.json' --include='Containerfile' --include='dep5' \ - | grep -v 'PLACEHOLDERS.md' | grep -v 'node_modules' -``` - -If the above command produces no output, all placeholders have been replaced. diff --git a/PROOF-NEEDS.adoc b/PROOF-NEEDS.adoc new file mode 100644 index 0000000..7d1f964 --- /dev/null +++ b/PROOF-NEEDS.adoc @@ -0,0 +1,79 @@ +== PROOF-NEEDS.md — Open Proof Targets + +_Status: EXPERIMENTAL._ This file catalogues *open targets* for the Agda +proof suite in `+proofs/+` — work not yet done, not a claim of coverage. +For the proofs that already exist and what they actually prove (ℕ-level +lemmas, not the ℝ/Float64 statistical theorems), see +`+proofs/README.adoc+`. For the overall FFI + proofs status, see the +"`Experimental surfaces`" section of `+README.adoc+`. + +=== Current State + +* *LOC*: ~11,900 +* *Languages*: Julia, Agda, Zig (Idris2 template ABI removed 2026-03-29 +— see "`Template ABI Cleanup`" below; `+src/abi/+` does not exist) +* *Existing ABI proofs*: none — the template-level `+src/abi/*.idr+` +files were removed 2026-03-29 for creating a false impression of formal +verification +* *Existing verification*: 3 Agda proof files in +`+proofs/Statistikles/+` +** `+Inequalities.agda+` — statistical inequalities +** `+RankIdentities.agda+` — rank-based test identities +** `+TropicalSemiring.agda+` — tropical semiring properties (mentions +"`no postulates`" in comment, but grep found a match — needs audit) +* *Dangerous patterns*: Comment in TropicalSemiring.agda references +postulates (may be a negation — "`no postulates`") + +=== What Needs Proving + +==== Tropical Semiring Audit (proofs/Statistikles/TropicalSemiring.agda) + +* Verify the "`no postulates`" claim is still accurate +* Ensure semiring laws (associativity, commutativity, distributivity, +identity) are all constructively proven + +==== Statistical Test Correctness (Julia core) + +* Julia code implements statistical tests — the Agda proofs should +correspond to these +* Prove: test implementations match their mathematical specifications +* Gap analysis: which Julia tests have Agda proofs and which do not? + +==== Bridge Correctness (src/bridge/) + +* `+typell_levels.jl+`, `+echidna_adapter.jl+`, `+verisimdb_schema.jl+`, +`+aspasia_bridge.jl+`, `+betlang_bridge.jl+` +* Prove: type-level bridges preserve the statistical properties proven +in Agda + +==== Integration Correctness (src/integrations/) + +* `+smtlib_integration.jl+` — SMT-LIB integration should produce valid +SMT queries +* `+quantum_integration.jl+` — quantum probability calculations need +mathematical proofs + +==== Additional Inequalities + +* Extend `+Inequalities.agda+` to cover all statistical inequalities +used in the Julia code +* Each inequality used at runtime should have a corresponding Agda proof + +=== Recommended Prover + +* *Agda* (already in use — extend existing proof suite) +* *Lean4* alternative for the quantum probability proofs (Mathlib has +probability theory) + +=== Priority + +*MEDIUM* — Good existing proof coverage. Statistical correctness proofs +are valuable but the tool is not security-critical. Focus on completing +the gap analysis between Julia implementations and Agda proofs. + +=== 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/PROOF-NEEDS.md b/PROOF-NEEDS.md deleted file mode 100644 index 0fcbe56..0000000 --- a/PROOF-NEEDS.md +++ /dev/null @@ -1,62 +0,0 @@ - -# PROOF-NEEDS.md — Open Proof Targets - -*Status: EXPERIMENTAL.* This file catalogues **open targets** for the Agda -proof suite in `proofs/` — work not yet done, not a claim of coverage. For the -proofs that already exist and what they actually prove (ℕ-level lemmas, not -the ℝ/Float64 statistical theorems), see `proofs/README.adoc`. For the overall -FFI + proofs status, see the "Experimental surfaces" section of `README.adoc`. - -## Current State - -- **LOC**: ~11,900 -- **Languages**: Julia, Agda, Zig (Idris2 template ABI removed 2026-03-29 — see - "Template ABI Cleanup" below; `src/abi/` does not exist) -- **Existing ABI proofs**: none — the template-level `src/abi/*.idr` files were - removed 2026-03-29 for creating a false impression of formal verification -- **Existing verification**: 3 Agda proof files in `proofs/Statistikles/` - - `Inequalities.agda` — statistical inequalities - - `RankIdentities.agda` — rank-based test identities - - `TropicalSemiring.agda` — tropical semiring properties (mentions "no postulates" in comment, but grep found a match — needs audit) -- **Dangerous patterns**: Comment in TropicalSemiring.agda references postulates (may be a negation — "no postulates") - -## What Needs Proving - -### Tropical Semiring Audit (proofs/Statistikles/TropicalSemiring.agda) -- Verify the "no postulates" claim is still accurate -- Ensure semiring laws (associativity, commutativity, distributivity, identity) are all constructively proven - -### Statistical Test Correctness (Julia core) -- Julia code implements statistical tests — the Agda proofs should correspond to these -- Prove: test implementations match their mathematical specifications -- Gap analysis: which Julia tests have Agda proofs and which do not? - -### Bridge Correctness (src/bridge/) -- `typell_levels.jl`, `echidna_adapter.jl`, `verisimdb_schema.jl`, `aspasia_bridge.jl`, `betlang_bridge.jl` -- Prove: type-level bridges preserve the statistical properties proven in Agda - -### Integration Correctness (src/integrations/) -- `smtlib_integration.jl` — SMT-LIB integration should produce valid SMT queries -- `quantum_integration.jl` — quantum probability calculations need mathematical proofs - -### Additional Inequalities -- Extend `Inequalities.agda` to cover all statistical inequalities used in the Julia code -- Each inequality used at runtime should have a corresponding Agda proof - -## Recommended Prover - -- **Agda** (already in use — extend existing proof suite) -- **Lean4** alternative for the quantum probability proofs (Mathlib has probability theory) - -## Priority - -**MEDIUM** — Good existing proof coverage. Statistical correctness proofs are valuable but the tool is not security-critical. Focus on completing the gap analysis between Julia implementations and Agda proofs. - -## 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/SECURITY.adoc b/SECURITY.adoc new file mode 100644 index 0000000..2dd86e5 --- /dev/null +++ b/SECURITY.adoc @@ -0,0 +1,437 @@ +== Security Policy + +We take security seriously. We appreciate your efforts to responsibly +disclose vulnerabilities and will make every effort to acknowledge your +contributions. + +=== Table of Contents + +* link:#reporting-a-vulnerability[Reporting a Vulnerability] +* link:#what-to-include[What to Include] +* link:#response-timeline[Response Timeline] +* link:#disclosure-policy[Disclosure Policy] +* link:#scope[Scope] +* link:#safe-harbour[Safe Harbour] +* link:#recognition[Recognition] +* link:#security-updates[Security Updates] +* link:#security-best-practices[Security Best Practices] + +''''' + +=== Reporting a Vulnerability + +==== Preferred Method: GitHub Security Advisories + +The preferred method for reporting security vulnerabilities is through +GitHub’s Security Advisory feature: + +[arabic] +. Navigate to +https://github.com/hyperpolymath/statistikles/security/advisories/new[Report +a Vulnerability] +. Click *"`Report a vulnerability`"* +. Complete the form with as much detail as possible +. Submit — we’ll receive a private notification + +This method ensures: + +* End-to-end encryption of your report +* Private discussion space for collaboration +* Coordinated disclosure tooling +* Automatic credit when the advisory is published + +==== Alternative: Email + +If you cannot use GitHub Security Advisories, you may email us directly: + +[cols=",",] +|=== +|*Email* |j.d.a.jewell@open.ac.uk +|=== + +____ +*⚠️ Important:* Do not report security vulnerabilities through public +GitHub issues, pull requests, discussions, or social media. +____ + +''''' + +=== What to Include + +A good vulnerability report helps us understand and reproduce the issue +quickly. + +==== Required Information + +* *Description*: Clear explanation of the vulnerability +* *Impact*: What an attacker could achieve (confidentiality, integrity, +availability) +* *Affected versions*: Which versions/commits are affected +* *Reproduction steps*: Detailed steps to reproduce the issue + +==== Helpful Additional Information + +* *Proof of concept*: Code, scripts, or screenshots demonstrating the +vulnerability +* *Attack scenario*: Realistic attack scenario showing exploitability +* *CVSS score*: Your assessment of severity (use +https://www.first.org/cvss/calculator/3.1[CVSS 3.1 Calculator]) +* *CWE ID*: Common Weakness Enumeration identifier if known +* *Suggested fix*: If you have ideas for remediation +* *References*: Links to related vulnerabilities, research, or +advisories + +==== Example Report Structure + +[source,markdown] +---- +## Summary +[One-sentence description of the vulnerability] + +## Vulnerability Type +[e.g., SQL Injection, XSS, SSRF, Path Traversal, etc.] + +## Affected Component +[File path, function name, API endpoint, etc.] + +## Affected Versions +[Version range or specific commits] + +## Severity Assessment +- CVSS 3.1 Score: [X.X] +- CVSS Vector: [CVSS:3.1/AV:X/AC:X/PR:X/UI:X/S:X/C:X/I:X/A:X] + +## Description +[Detailed technical description] + +## Steps to Reproduce +1. [First step] +2. [Second step] +3. [...] + +## Proof of Concept +[Code, curl commands, screenshots, etc.] + +## Impact +[What can an attacker achieve?] + +## Suggested Remediation +[Optional: your ideas for fixing] + +## References +[Links to related issues, CVEs, research] +---- + +''''' + +=== Response Timeline + +We commit to the following response times: + +[width="100%",cols="24%,35%,41%",options="header",] +|=== +|Stage |Timeframe |Description +|*Initial Response* |48 hours |We acknowledge receipt and confirm we’re +investigating + +|*Triage* |7 days |We assess severity, confirm the vulnerability, and +estimate timeline + +|*Status Update* |Every 7 days |Regular updates on remediation progress + +|*Resolution* |90 days |Target for fix development and release (complex +issues may take longer) + +|*Disclosure* |90 days |Public disclosure after fix is available +(coordinated with you) +|=== + +____ +*Note:* These are targets, not guarantees. Complex vulnerabilities may +require more time. We’ll communicate openly about any delays. +____ + +''''' + +=== Disclosure Policy + +We follow *coordinated disclosure* (also known as responsible +disclosure): + +[arabic] +. *You report* the vulnerability privately +. *We acknowledge* and begin investigation +. *We develop* a fix and prepare a release +. *We coordinate* disclosure timing with you +. *We publish* security advisory and fix simultaneously +. *You may publish* your research after disclosure + +==== Our Commitments + +* We will not take legal action against researchers who follow this +policy +* We will work with you to understand and resolve the issue +* We will credit you in the security advisory (unless you prefer +anonymity) +* We will notify you before public disclosure +* We will publish advisories with sufficient detail for users to assess +risk + +==== Your Commitments + +* Report vulnerabilities promptly after discovery +* Give us reasonable time to address the issue before disclosure +* Do not access, modify, or delete data beyond what’s necessary to +demonstrate the vulnerability +* Do not degrade service availability (no DoS testing on production) +* Do not share vulnerability details with others until coordinated +disclosure + +==== Disclosure Timeline + +.... +Day 0 You report vulnerability +Day 1-2 We acknowledge receipt +Day 7 We confirm vulnerability and share initial assessment +Day 7-90 We develop and test fix +Day 90 Coordinated public disclosure + (earlier if fix is ready; later by mutual agreement) +.... + +If we cannot reach agreement on disclosure timing, we default to 90 days +from your initial report. + +''''' + +=== Scope + +==== In Scope ✅ + +The following are within scope for security research: + +* This repository (`+hyperpolymath/statistikles+`) and all its code +* Official releases and packages published from this repository +* Documentation that could lead to security issues +* Build and deployment configurations in this repository +* Dependencies (report here, we’ll coordinate with upstream) + +==== Out of Scope ❌ + +The following are *not* in scope: + +* Third-party services we integrate with (report directly to them) +* Social engineering attacks against maintainers +* Physical security +* Denial of service attacks against production infrastructure +* Spam, phishing, or other non-technical attacks +* Issues already reported or publicly known +* Theoretical vulnerabilities without proof of concept + +==== Qualifying Vulnerabilities + +We’re particularly interested in: + +* Remote code execution +* SQL injection, command injection, code injection +* Authentication/authorisation bypass +* Cross-site scripting (XSS) and cross-site request forgery (CSRF) +* Server-side request forgery (SSRF) +* Path traversal / local file inclusion +* Information disclosure (credentials, PII, secrets) +* Cryptographic weaknesses +* Deserialisation vulnerabilities +* Memory safety issues (buffer overflows, use-after-free, etc.) +* Supply chain vulnerabilities (dependency confusion, etc.) +* Significant logic flaws + +==== Non-Qualifying Issues + +The following generally do not qualify as security vulnerabilities: + +* Missing security headers on non-sensitive pages +* Clickjacking on pages without sensitive actions +* Self-XSS (requires victim to paste code) +* Missing rate limiting (unless it enables a specific attack) +* Username/email enumeration (unless high-risk context) +* Missing cookie flags on non-sensitive cookies +* Software version disclosure +* Verbose error messages (unless exposing secrets) +* Best practice deviations without demonstrable impact + +''''' + +=== Safe Harbour + +We support security research conducted in good faith. + +==== Our Promise + +If you conduct security research in accordance with this policy: + +* ✅ We will not initiate legal action against you +* ✅ We will not report your activity to law enforcement +* ✅ We will work with you in good faith to resolve issues +* ✅ We consider your research authorised under the Computer Fraud and +Abuse Act (CFAA), UK Computer Misuse Act, and similar laws +* ✅ We waive any potential claim against you for circumvention of +security controls + +==== Good Faith Requirements + +To qualify for safe harbour, you must: + +* Comply with this security policy +* Report vulnerabilities promptly +* Avoid privacy violations (do not access others’ data) +* Avoid service degradation (no destructive testing) +* Not exploit vulnerabilities beyond proof-of-concept +* Not use vulnerabilities for profit (beyond bug bounties where offered) + +____ +*⚠️ Important:* This safe harbour does not extend to third-party +systems. Always check their policies before testing. +____ + +''''' + +=== Recognition + +We believe in recognising security researchers who help us improve. + +==== Hall of Fame + +Researchers who report valid vulnerabilities will be acknowledged in our +link:SECURITY-ACKNOWLEDGMENTS.md[Security Acknowledgments] (unless they +prefer anonymity). + +Recognition includes: + +* Your name (or chosen alias) +* Link to your website/profile (optional) +* Brief description of the vulnerability class +* Date of report + +==== What We Offer + +* ✅ Public credit in security advisories +* ✅ Acknowledgment in release notes +* ✅ Entry in our Hall of Fame +* ✅ Reference/recommendation letter upon request (for significant +findings) + +==== What We Don’t Currently Offer + +* ❌ Monetary bug bounties +* ❌ Hardware or swag +* ❌ Paid security research contracts + +____ +*Note:* We’re a community project with limited resources. Your +contributions help everyone who uses this software. +____ + +''''' + +=== Security Updates + +==== Receiving Updates + +To stay informed about security updates: + +* *Watch this repository*: Click "`Watch`" → "`Custom`" → Select +"`Security alerts`" +* *GitHub Security Advisories*: Published at +https://github.com/hyperpolymath/statistikles/security/advisories[Security +Advisories] +* *Release notes*: Security fixes noted in link:CHANGELOG.md[CHANGELOG] + +==== Update Policy + +[cols=",",options="header",] +|=== +|Severity |Response +|*Critical/High* |Patch release as soon as fix is ready +|*Medium* |Included in next scheduled release (or earlier) +|*Low* |Included in next scheduled release +|=== + +==== Supported Versions + +[cols=",,",options="header",] +|=== +|Version |Supported |Notes +|`+main+` branch |✅ Yes |Latest development +|Latest release |✅ Yes |Current stable +|Previous minor release |✅ Yes |Security fixes backported +|Older versions |❌ No |Please upgrade +|=== + +''''' + +=== Security Best Practices + +When using Statistikles, we recommend: + +==== General + +* Keep dependencies up to date +* Use the latest stable release +* Subscribe to security notifications +* Review configuration against security documentation +* Follow principle of least privilege + +==== For Contributors + +* Never commit secrets, credentials, or API keys +* Use signed commits (`+git config commit.gpgsign true+`) +* Review dependencies before adding them +* Run security linters locally before pushing +* Report any concerns about existing code + +''''' + +=== Additional Resources + +* https://github.com/hyperpolymath/statistikles/security/advisories[Security +Advisories] +* link:CHANGELOG.md[Changelog] +* link:CONTRIBUTING.md[Contributing Guidelines] +* https://cve.mitre.org/[CVE Database] +* https://www.first.org/cvss/calculator/3.1[CVSS Calculator] + +''''' + +=== Contact + +[width="100%",cols="50%,50%",options="header",] +|=== +|Purpose |Contact +|*Security issues* +|https://github.com/hyperpolymath/statistikles/security/advisories/new[Report +via GitHub] or j.d.a.jewell@open.ac.uk + +|*General questions* +|https://github.com/hyperpolymath/statistikles/discussions[GitHub +Discussions] + +|*Other enquiries* |See link:README.md[README] for contact information +|=== + +''''' + +=== Policy Changes + +This security policy may be updated from time to time. Significant +changes will be: + +* Committed to this repository with a clear commit message +* Noted in the changelog +* Announced via GitHub Discussions (for major changes) + +''''' + +_Thank you for helping keep Statistikles and its users safe._ 🛡️ + +''''' + +Last updated: 2026 · Policy version: 1.0.0 diff --git a/SECURITY.md b/SECURITY.md deleted file mode 100644 index f78898f..0000000 --- a/SECURITY.md +++ /dev/null @@ -1,378 +0,0 @@ - -# Security Policy - -We take security seriously. We appreciate your efforts to responsibly disclose vulnerabilities and will make every effort to acknowledge your contributions. - -## Table of Contents - -- [Reporting a Vulnerability](#reporting-a-vulnerability) -- [What to Include](#what-to-include) -- [Response Timeline](#response-timeline) -- [Disclosure Policy](#disclosure-policy) -- [Scope](#scope) -- [Safe Harbour](#safe-harbour) -- [Recognition](#recognition) -- [Security Updates](#security-updates) -- [Security Best Practices](#security-best-practices) - ---- - -## Reporting a Vulnerability - -### Preferred Method: GitHub Security Advisories - -The preferred method for reporting security vulnerabilities is through GitHub's Security Advisory feature: - -1. Navigate to [Report a Vulnerability](https://github.com/hyperpolymath/statistikles/security/advisories/new) -2. Click **"Report a vulnerability"** -3. Complete the form with as much detail as possible -4. Submit — we'll receive a private notification - -This method ensures: - -- End-to-end encryption of your report -- Private discussion space for collaboration -- Coordinated disclosure tooling -- Automatic credit when the advisory is published - -### Alternative: Email - -If you cannot use GitHub Security Advisories, you may email us directly: - -| | | -|---|---| -| **Email** | j.d.a.jewell@open.ac.uk | - -> **⚠️ Important:** Do not report security vulnerabilities through public GitHub issues, pull requests, discussions, or social media. - ---- - -## What to Include - -A good vulnerability report helps us understand and reproduce the issue quickly. - -### Required Information - -- **Description**: Clear explanation of the vulnerability -- **Impact**: What an attacker could achieve (confidentiality, integrity, availability) -- **Affected versions**: Which versions/commits are affected -- **Reproduction steps**: Detailed steps to reproduce the issue - -### Helpful Additional Information - -- **Proof of concept**: Code, scripts, or screenshots demonstrating the vulnerability -- **Attack scenario**: Realistic attack scenario showing exploitability -- **CVSS score**: Your assessment of severity (use [CVSS 3.1 Calculator](https://www.first.org/cvss/calculator/3.1)) -- **CWE ID**: Common Weakness Enumeration identifier if known -- **Suggested fix**: If you have ideas for remediation -- **References**: Links to related vulnerabilities, research, or advisories - -### Example Report Structure - -```markdown -## Summary -[One-sentence description of the vulnerability] - -## Vulnerability Type -[e.g., SQL Injection, XSS, SSRF, Path Traversal, etc.] - -## Affected Component -[File path, function name, API endpoint, etc.] - -## Affected Versions -[Version range or specific commits] - -## Severity Assessment -- CVSS 3.1 Score: [X.X] -- CVSS Vector: [CVSS:3.1/AV:X/AC:X/PR:X/UI:X/S:X/C:X/I:X/A:X] - -## Description -[Detailed technical description] - -## Steps to Reproduce -1. [First step] -2. [Second step] -3. [...] - -## Proof of Concept -[Code, curl commands, screenshots, etc.] - -## Impact -[What can an attacker achieve?] - -## Suggested Remediation -[Optional: your ideas for fixing] - -## References -[Links to related issues, CVEs, research] -``` - ---- - -## Response Timeline - -We commit to the following response times: - -| Stage | Timeframe | Description | -|-------|-----------|-------------| -| **Initial Response** | 48 hours | We acknowledge receipt and confirm we're investigating | -| **Triage** | 7 days | We assess severity, confirm the vulnerability, and estimate timeline | -| **Status Update** | Every 7 days | Regular updates on remediation progress | -| **Resolution** | 90 days | Target for fix development and release (complex issues may take longer) | -| **Disclosure** | 90 days | Public disclosure after fix is available (coordinated with you) | - -> **Note:** These are targets, not guarantees. Complex vulnerabilities may require more time. We'll communicate openly about any delays. - ---- - -## Disclosure Policy - -We follow **coordinated disclosure** (also known as responsible disclosure): - -1. **You report** the vulnerability privately -2. **We acknowledge** and begin investigation -3. **We develop** a fix and prepare a release -4. **We coordinate** disclosure timing with you -5. **We publish** security advisory and fix simultaneously -6. **You may publish** your research after disclosure - -### Our Commitments - -- We will not take legal action against researchers who follow this policy -- We will work with you to understand and resolve the issue -- We will credit you in the security advisory (unless you prefer anonymity) -- We will notify you before public disclosure -- We will publish advisories with sufficient detail for users to assess risk - -### Your Commitments - -- Report vulnerabilities promptly after discovery -- Give us reasonable time to address the issue before disclosure -- Do not access, modify, or delete data beyond what's necessary to demonstrate the vulnerability -- Do not degrade service availability (no DoS testing on production) -- Do not share vulnerability details with others until coordinated disclosure - -### Disclosure Timeline - -``` -Day 0 You report vulnerability -Day 1-2 We acknowledge receipt -Day 7 We confirm vulnerability and share initial assessment -Day 7-90 We develop and test fix -Day 90 Coordinated public disclosure - (earlier if fix is ready; later by mutual agreement) -``` - -If we cannot reach agreement on disclosure timing, we default to 90 days from your initial report. - ---- - -## Scope - -### In Scope ✅ - -The following are within scope for security research: - -- This repository (`hyperpolymath/statistikles`) and all its code -- Official releases and packages published from this repository -- Documentation that could lead to security issues -- Build and deployment configurations in this repository -- Dependencies (report here, we'll coordinate with upstream) - -### Out of Scope ❌ - -The following are **not** in scope: - -- Third-party services we integrate with (report directly to them) -- Social engineering attacks against maintainers -- Physical security -- Denial of service attacks against production infrastructure -- Spam, phishing, or other non-technical attacks -- Issues already reported or publicly known -- Theoretical vulnerabilities without proof of concept - -### Qualifying Vulnerabilities - -We're particularly interested in: - -- Remote code execution -- SQL injection, command injection, code injection -- Authentication/authorisation bypass -- Cross-site scripting (XSS) and cross-site request forgery (CSRF) -- Server-side request forgery (SSRF) -- Path traversal / local file inclusion -- Information disclosure (credentials, PII, secrets) -- Cryptographic weaknesses -- Deserialisation vulnerabilities -- Memory safety issues (buffer overflows, use-after-free, etc.) -- Supply chain vulnerabilities (dependency confusion, etc.) -- Significant logic flaws - -### Non-Qualifying Issues - -The following generally do not qualify as security vulnerabilities: - -- Missing security headers on non-sensitive pages -- Clickjacking on pages without sensitive actions -- Self-XSS (requires victim to paste code) -- Missing rate limiting (unless it enables a specific attack) -- Username/email enumeration (unless high-risk context) -- Missing cookie flags on non-sensitive cookies -- Software version disclosure -- Verbose error messages (unless exposing secrets) -- Best practice deviations without demonstrable impact - ---- - -## Safe Harbour - -We support security research conducted in good faith. - -### Our Promise - -If you conduct security research in accordance with this policy: - -- ✅ We will not initiate legal action against you -- ✅ We will not report your activity to law enforcement -- ✅ We will work with you in good faith to resolve issues -- ✅ We consider your research authorised under the Computer Fraud and Abuse Act (CFAA), UK Computer Misuse Act, and similar laws -- ✅ We waive any potential claim against you for circumvention of security controls - -### Good Faith Requirements - -To qualify for safe harbour, you must: - -- Comply with this security policy -- Report vulnerabilities promptly -- Avoid privacy violations (do not access others' data) -- Avoid service degradation (no destructive testing) -- Not exploit vulnerabilities beyond proof-of-concept -- Not use vulnerabilities for profit (beyond bug bounties where offered) - -> **⚠️ Important:** This safe harbour does not extend to third-party systems. Always check their policies before testing. - ---- - -## Recognition - -We believe in recognising security researchers who help us improve. - -### Hall of Fame - -Researchers who report valid vulnerabilities will be acknowledged in our [Security Acknowledgments](SECURITY-ACKNOWLEDGMENTS.md) (unless they prefer anonymity). - -Recognition includes: - -- Your name (or chosen alias) -- Link to your website/profile (optional) -- Brief description of the vulnerability class -- Date of report - -### What We Offer - -- ✅ Public credit in security advisories -- ✅ Acknowledgment in release notes -- ✅ Entry in our Hall of Fame -- ✅ Reference/recommendation letter upon request (for significant findings) - -### What We Don't Currently Offer - -- ❌ Monetary bug bounties -- ❌ Hardware or swag -- ❌ Paid security research contracts - -> **Note:** We're a community project with limited resources. Your contributions help everyone who uses this software. - ---- - -## Security Updates - -### Receiving Updates - -To stay informed about security updates: - -- **Watch this repository**: Click "Watch" → "Custom" → Select "Security alerts" -- **GitHub Security Advisories**: Published at [Security Advisories](https://github.com/hyperpolymath/statistikles/security/advisories) -- **Release notes**: Security fixes noted in [CHANGELOG](CHANGELOG.md) - -### Update Policy - -| Severity | Response | -|----------|----------| -| **Critical/High** | Patch release as soon as fix is ready | -| **Medium** | Included in next scheduled release (or earlier) | -| **Low** | Included in next scheduled release | - -### Supported Versions - - - -| Version | Supported | Notes | -|---------|-----------|-------| -| `main` branch | ✅ Yes | Latest development | -| Latest release | ✅ Yes | Current stable | -| Previous minor release | ✅ Yes | Security fixes backported | -| Older versions | ❌ No | Please upgrade | - ---- - -## Security Best Practices - -When using Statistikles, we recommend: - -### General - -- Keep dependencies up to date -- Use the latest stable release -- Subscribe to security notifications -- Review configuration against security documentation -- Follow principle of least privilege - -### For Contributors - -- Never commit secrets, credentials, or API keys -- Use signed commits (`git config commit.gpgsign true`) -- Review dependencies before adding them -- Run security linters locally before pushing -- Report any concerns about existing code - ---- - -## Additional Resources - -- [Security Advisories](https://github.com/hyperpolymath/statistikles/security/advisories) -- [Changelog](CHANGELOG.md) -- [Contributing Guidelines](CONTRIBUTING.md) -- [CVE Database](https://cve.mitre.org/) -- [CVSS Calculator](https://www.first.org/cvss/calculator/3.1) - ---- - -## Contact - -| Purpose | Contact | -|---------|---------| -| **Security issues** | [Report via GitHub](https://github.com/hyperpolymath/statistikles/security/advisories/new) or j.d.a.jewell@open.ac.uk | -| **General questions** | [GitHub Discussions](https://github.com/hyperpolymath/statistikles/discussions) | -| **Other enquiries** | See [README](README.md) for contact information | - ---- - -## Policy Changes - -This security policy may be updated from time to time. Significant changes will be: - -- Committed to this repository with a clear commit message -- Noted in the changelog -- Announced via GitHub Discussions (for major changes) - ---- - -*Thank you for helping keep Statistikles and its users safe.* 🛡️ - ---- - -Last updated: 2026 · Policy version: 1.0.0 diff --git a/TEST-NEEDS.adoc b/TEST-NEEDS.adoc new file mode 100644 index 0000000..377cb44 --- /dev/null +++ b/TEST-NEEDS.adoc @@ -0,0 +1,98 @@ +== TEST-NEEDS: statistikles + +=== CRG Grade: C — ACHIEVED 2026-04-04 + +=== Current State + +[width="100%",cols="40%,26%,34%",options="header",] +|=== +|Category |Count |Details +|*Source modules* |67 |Julia: 41 stats modules (descriptive, +inferential, bayesian, SEM, timeseries, survival, etc.), pipeline, +output, integrations, bridge (Idris2 template ABI removed 2026-03-29; +Zig FFI remains) + +|*Unit tests* |693 |@test assertions across runtests.jl + 7 wired suites +(e2e, property, reference-validation ×2, degenerate-input, guardrail, +executor-router) – comprehensive @test/@testset coverage (E2E & property +also broken out below) + +|*E2E tests* |yes |test/e2e_test.jl – full descriptive pipeline, error +handling (empty/NaN), combined descriptive+inferential + +|*Property tests* |yes |test/property_test.jl – invariants (constant +arrays, sort-invariance, power-mean ordering, p-value/correlation +bounds) + +|*Integration tests* |0 |No dedicated tests for the 8 claimed external +integrations + +|*Benchmarks* |yes |benches/benchmarks.jl (BenchmarkTools; +descriptive_stats at 3 scales + batch scenario) + +|*Agda proofs* |3 files |proofs/Statistikles/ (Inequalities, +RankIdentities, TropicalSemiring) +|=== + +=== What’s Missing + +==== P2P Tests + +* [ ] No tests for VeriSimDB integration (claimed: port 8096) +* [ ] No tests for pipeline module orchestrating multiple stats modules +* [ ] No tests for TypeLL level integration + +==== E2E Tests + +* [x] Full statistical analysis pipeline from data input to output +report (test/e2e_test.jl) +* [ ] No test for integration with external data sources + +==== Aspect Tests + +* [ ] *Security*: No input sanitization tests for user-provided data +* [ ] *Performance*: No performance tests despite being a +computation-heavy stats library +* [ ] *Concurrency*: No parallel computation tests (Julia supports +multi-threading) +* [x] *Error handling*: empty / single-element / NaN-containing / +all-NaN datasets covered in test/e2e_test.jl + +==== Benchmarks Needed + +* [x] benches/benchmarks.jl exists (BenchmarkTools; descriptive_stats at +three scales + batch) +* [ ] Descriptive stats throughput at larger scales (10M/100M +datapoints) +* [ ] Bayesian MCMC convergence timing +* [ ] SEM fitting performance +* [ ] Time series forecasting latency +* [ ] Memory usage for large datasets + +==== Self-Tests + +* [ ] No self-diagnostic mode + +=== FLAGGED ISSUES + +* *693 @test assertions is solid coverage* – best among all scanned +repos +* *Single test file for 65 modules* – RESOLVED 2026-07-11: the suite is +split across runtests.jl + 7 wired files (e2e, property, +reference-validation ×2, degenerate-input, guardrail, executor-router) +* *0 integration tests despite 8 claimed integrations* – integration +claims unverified +* *ffi/zig comments reference deleted src/abi/Foreign.idr* – RESOLVED +(#38, #48): the Foreign.idr references were removed; the Zig FFI now +compiles with a `+zig build test+` CI job and is documented as an +EXPERIMENTAL placeholder surface (entry points are not yet backed by the +Julia core) + +=== Priority: P2 (MEDIUM) – unit tests are decent; integration tests are the main gap + +=== FAKE-FUZZ ALERT — RESOLVED 2026-07-07 + +* `+tests/fuzz/placeholder.txt+` (scorecard placeholder inherited from +rsr-template-repo, no real fuzz coverage) was removed on 2026-07-07 +* A real fuzz harness remains open work (see +rsr-template-repo/tests/fuzz/README.adoc) diff --git a/TEST-NEEDS.md b/TEST-NEEDS.md deleted file mode 100644 index 8d4a7ea..0000000 --- a/TEST-NEEDS.md +++ /dev/null @@ -1,66 +0,0 @@ - -# TEST-NEEDS: statistikles - -## CRG Grade: C — ACHIEVED 2026-04-04 - -## Current State - -| Category | Count | Details | -|----------|-------|---------| -| **Source modules** | 67 | Julia: 41 stats modules (descriptive, inferential, bayesian, SEM, timeseries, survival, etc.), pipeline, output, integrations, bridge (Idris2 template ABI removed 2026-03-29; Zig FFI remains) | -| **Unit tests** | 693 | @test assertions across runtests.jl + 7 wired suites (e2e, property, reference-validation ×2, degenerate-input, guardrail, executor-router) -- comprehensive @test/@testset coverage (E2E & property also broken out below) | -| **E2E tests** | yes | test/e2e_test.jl -- full descriptive pipeline, error handling (empty/NaN), combined descriptive+inferential | -| **Property tests** | yes | test/property_test.jl -- invariants (constant arrays, sort-invariance, power-mean ordering, p-value/correlation bounds) | -| **Integration tests** | 0 | No dedicated tests for the 8 claimed external integrations | -| **Benchmarks** | yes | benches/benchmarks.jl (BenchmarkTools; descriptive_stats at 3 scales + batch scenario) | -| **Agda proofs** | 3 files | proofs/Statistikles/ (Inequalities, RankIdentities, TropicalSemiring) | - -## What's Missing - -### P2P Tests -- [ ] No tests for VeriSimDB integration (claimed: port 8096) -- [ ] No tests for pipeline module orchestrating multiple stats modules -- [ ] No tests for TypeLL level integration - -### E2E Tests -- [x] Full statistical analysis pipeline from data input to output report (test/e2e_test.jl) -- [ ] No test for integration with external data sources - -### Aspect Tests -- [ ] **Security**: No input sanitization tests for user-provided data -- [ ] **Performance**: No performance tests despite being a computation-heavy stats library -- [ ] **Concurrency**: No parallel computation tests (Julia supports multi-threading) -- [x] **Error handling**: empty / single-element / NaN-containing / all-NaN datasets covered in test/e2e_test.jl - -### Benchmarks Needed -- [x] benches/benchmarks.jl exists (BenchmarkTools; descriptive_stats at three scales + batch) -- [ ] Descriptive stats throughput at larger scales (10M/100M datapoints) -- [ ] Bayesian MCMC convergence timing -- [ ] SEM fitting performance -- [ ] Time series forecasting latency -- [ ] Memory usage for large datasets - -### Self-Tests -- [ ] No self-diagnostic mode - -## FLAGGED ISSUES -- **693 @test assertions is solid coverage** -- best among all scanned repos -- **Single test file for 65 modules** -- RESOLVED 2026-07-11: the suite is split - across runtests.jl + 7 wired files (e2e, property, reference-validation ×2, - degenerate-input, guardrail, executor-router) -- **0 integration tests despite 8 claimed integrations** -- integration claims unverified -- **ffi/zig comments reference deleted src/abi/Foreign.idr** -- RESOLVED (#38, #48): - the Foreign.idr references were removed; the Zig FFI now compiles with a - `zig build test` CI job and is documented as an EXPERIMENTAL placeholder surface - (entry points are not yet backed by the Julia core) - -## Priority: P2 (MEDIUM) -- unit tests are decent; integration tests are the main gap - -## FAKE-FUZZ ALERT — RESOLVED 2026-07-07 - -- `tests/fuzz/placeholder.txt` (scorecard placeholder inherited from - rsr-template-repo, no real fuzz coverage) was removed on 2026-07-07 -- A real fuzz harness remains open work (see rsr-template-repo/tests/fuzz/README.adoc) diff --git a/TOPOLOGY.md b/TOPOLOGY.adoc similarity index 92% rename from TOPOLOGY.md rename to TOPOLOGY.adoc index 7b15968..8a11d7d 100644 --- a/TOPOLOGY.md +++ b/TOPOLOGY.adoc @@ -1,15 +1,8 @@ - - - +== Statistikles — Project Topology -# Statistikles — Project Topology +=== System Architecture -## System Architecture - -``` +.... ┌──────────────────────────────────┐ │ USER (natural language) │ │ "Is there a significant diff?" │ @@ -73,11 +66,11 @@ Copyright (c) Jonathan D.A. Jewell │ │ explain / prove / demonstrate ││ │ └──────────────────────────────┘│ └──────────────────────────────────┘ -``` +.... -## Completion Dashboard +=== Completion Dashboard -``` +.... COMPONENT STATUS NOTES ───────────────────────────────── ────────────────── ───────────────────────────────── CORE ARCHITECTURE @@ -121,11 +114,11 @@ INFRASTRUCTURE OVERALL: ███████░░░ 70% Symbolic library real & tested; neural path + external verification pipeline pending -``` +.... -## Key Dependencies +=== Key Dependencies -``` +.... LM Studio (local) ──► Statistikles ──► Julia stdlib (Statistics, LinearAlgebra) │ │ │ ├── Distributions.jl @@ -136,16 +129,17 @@ LM Studio (local) ──► Statistikles ──► Julia stdlib (Statistics, Lin ▼ (planned) echidna (GraphQL) ──► Formal proof verification adversarial SLM ───► Independent neurosymbolic audit -``` +.... -## Update Protocol +=== Update Protocol This file is maintained by both humans and AI agents. When updating: -1. **After completing a component**: Change its bar and percentage -2. **After adding a component**: Add a new row in the appropriate section -3. **After architectural changes**: Update the ASCII diagram -4. **Date**: Update the `Last updated` comment at the top of this file +[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). +Progress bars use: `+█+` (filled) and `+░+` (empty), 10 characters wide. +Percentages: 0%, 10%, 20%, … 100% (in 10% increments). diff --git a/docs/AI-CONVENTIONS.adoc b/docs/AI-CONVENTIONS.adoc new file mode 100644 index 0000000..9c95367 --- /dev/null +++ b/docs/AI-CONVENTIONS.adoc @@ -0,0 +1,88 @@ +== AI Conventions (Authoritative Source) + +All AI coding agents working in this repository MUST follow these rules. +Per-tool config files (.cursorrules, .clinerules, etc.) reference this +document. + +=== Session Startup + +[arabic] +. Read `+0-AI-MANIFEST.a2ml+` FIRST (mandatory gatekeeper). +. Read `+.machine_readable/STATE.a2ml+` for current status and blockers. +. Read `+.machine_readable/AGENTIC.a2ml+` for agent constraints. + +=== License + +* All original code: *MPL-2.0* +* Fallback (platform-required only): MPL-2.0 with comment explaining +why. +* NEVER use AGPL-3.0. +* Preserve third-party licenses verbatim. +* Every source file needs `+# SPDX-License-Identifier: CC-BY-SA-4.0+`. + +=== Author Attribution + +* Name: *Jonathan D.A. Jewell* +* Email: *j.d.a.jewell@open.ac.uk* +* Copyright: +`+Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +` + +=== State Files + +State/metadata files (.a2ml) belong in `+.machine_readable/+` ONLY. +NEVER create STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml, AGENTIC.a2ml, +NEUROSYM.a2ml, or PLAYBOOK.a2ml in the repository root. + +=== Banned Patterns + +[width="100%",cols="14%,50%,36%",options="header",] +|=== +|Language |Banned |Reason +|Idris2 |`+believe_me+`, `+assert_total+` |Unsound escape hatches +|Haskell |`+unsafeCoerce+`, `+unsafePerformIO+` |Breaks type safety +|OCaml |`+Obj.magic+`, `+Obj.repr+`, `+Obj.obj+` |Unsafe casting +|Coq |`+Admitted+` |Unproven assumption +|Lean |`+sorry+` |Unproven assumption +|Rust |`+transmute+` (unless FFI + SAFETY:) |Unsound reinterpret +|=== + +=== Banned Languages + +[cols=",",options="header",] +|=== +|Banned |Use Instead +|TypeScript |ReScript +|Node.js / npm / bun |Deno +|Go |Rust +|Python |Julia / Rust +|=== + +=== Container Standard + +* Runtime: *Podman* (never Docker). +* File: *Containerfile* (never Dockerfile). +* Base images: `+cgr.dev/chainguard/wolfi-base:latest+` or +`+cgr.dev/chainguard/static:latest+`. + +=== ABI/FFI Standard + +Target design (Hyperpolymath RSR standard) — see README.adoc’s +"`Experimental surfaces`" section for current status: + +* ABI definitions: *Idris2* with dependent types (`+src/abi/+`) — *not +present in this repo*; design-only. Do not assume `+src/abi/+` exists. +* FFI implementation: *Zig* with C ABI compatibility (`+ffi/zig/+`) — +real and CI-tested, but EXPERIMENTAL: exported ops are placeholders, not +yet backed by the Julia core. +* Generated C headers: `+generated/abi/+` — not present; no generation +pipeline exists yet. + +=== Build System + +Use `+just+` (Justfile) for all build, test, lint, and format tasks. + +=== References + +* `+0-AI-MANIFEST.a2ml+` – universal AI entry point +* `+.machine_readable/AGENTIC.a2ml+` – agent permissions and constraints +* `+.machine_readable/STATE.a2ml+` – current project state diff --git a/docs/AI-CONVENTIONS.md b/docs/AI-CONVENTIONS.md deleted file mode 100644 index 04222d0..0000000 --- a/docs/AI-CONVENTIONS.md +++ /dev/null @@ -1,85 +0,0 @@ - - - -# AI Conventions (Authoritative Source) - -All AI coding agents working in this repository MUST follow these rules. -Per-tool config files (.cursorrules, .clinerules, etc.) reference this document. - -## Session Startup - -1. Read `0-AI-MANIFEST.a2ml` FIRST (mandatory gatekeeper). -2. Read `.machine_readable/STATE.a2ml` for current status and blockers. -3. Read `.machine_readable/AGENTIC.a2ml` for agent constraints. - -## License - -- All original code: **MPL-2.0** -- Fallback (platform-required only): MPL-2.0 with comment explaining why. -- NEVER use AGPL-3.0. -- Preserve third-party licenses verbatim. -- Every source file needs `# SPDX-License-Identifier: CC-BY-SA-4.0`. - -## Author Attribution - -- Name: **Jonathan D.A. Jewell** -- Email: **j.d.a.jewell@open.ac.uk** -- Copyright: `Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ` - -## State Files - -State/metadata files (.a2ml) belong in `.machine_readable/` ONLY. -NEVER create STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml, AGENTIC.a2ml, -NEUROSYM.a2ml, or PLAYBOOK.a2ml in the repository root. - -## Banned Patterns - -| Language | Banned | Reason | -|----------|-------------------------------------|---------------------------| -| Idris2 | `believe_me`, `assert_total` | Unsound escape hatches | -| Haskell | `unsafeCoerce`, `unsafePerformIO` | Breaks type safety | -| OCaml | `Obj.magic`, `Obj.repr`, `Obj.obj` | Unsafe casting | -| Coq | `Admitted` | Unproven assumption | -| Lean | `sorry` | Unproven assumption | -| Rust | `transmute` (unless FFI + SAFETY:) | Unsound reinterpret | - -## Banned Languages - -| Banned | Use Instead | -|---------------------|--------------------| -| TypeScript | ReScript | -| Node.js / npm / bun | Deno | -| Go | Rust | -| Python | Julia / Rust | - -## Container Standard - -- Runtime: **Podman** (never Docker). -- File: **Containerfile** (never Dockerfile). -- Base images: `cgr.dev/chainguard/wolfi-base:latest` or `cgr.dev/chainguard/static:latest`. - -## ABI/FFI Standard - -Target design (Hyperpolymath RSR standard) — see README.adoc's "Experimental -surfaces" section for current status: - -- ABI definitions: **Idris2** with dependent types (`src/abi/`) — **not present - in this repo**; design-only. Do not assume `src/abi/` exists. -- FFI implementation: **Zig** with C ABI compatibility (`ffi/zig/`) — real and - CI-tested, but EXPERIMENTAL: exported ops are placeholders, not yet backed - by the Julia core. -- Generated C headers: `generated/abi/` — not present; no generation pipeline - exists yet. - -## Build System - -Use `just` (Justfile) for all build, test, lint, and format tasks. - -## References - -- `0-AI-MANIFEST.a2ml` -- universal AI entry point -- `.machine_readable/AGENTIC.a2ml` -- agent permissions and constraints -- `.machine_readable/STATE.a2ml` -- current project state diff --git a/docs/BETLANG-COMPARISON.md b/docs/BETLANG-COMPARISON.adoc similarity index 96% rename from docs/BETLANG-COMPARISON.md rename to docs/BETLANG-COMPARISON.adoc index 2ff03c2..041047e 100644 --- a/docs/BETLANG-COMPARISON.md +++ b/docs/BETLANG-COMPARISON.adoc @@ -1,10 +1,6 @@ - -# Statistikles + BetLang Capability Comparison +== Statistikles + BetLang Capability Comparison -``` +.... ┌─────────────────────────────┬──────────────────────┬──────────────────────┬──────────────┐ │ Capability │ BetLang (Racket) │ Statistikles (Julia) │ Winner │ ├─────────────────────────────┼──────────────────────┼──────────────────────┼──────────────┤ @@ -38,4 +34,4 @@ Copyright (c) Jonathan D.A. Jewell COMBINED POWER: Statistikles uses BetLang for Bayesian/sampling/optimization/uncertainty. BetLang uses Statistikles for hypothesis testing/formal verification/cross-verification. -``` +.... diff --git a/docs/CROSS-VERIFICATION-ARCHITECTURE.adoc b/docs/CROSS-VERIFICATION-ARCHITECTURE.adoc new file mode 100644 index 0000000..619afcb --- /dev/null +++ b/docs/CROSS-VERIFICATION-ARCHITECTURE.adoc @@ -0,0 +1,60 @@ +== Cross-Verification Architecture + +_Status: ASPIRATIONAL._ This document describes the target multi-repo +verification architecture. Only Layer 1 (Statistikles/Julia computation) +and a small experimental slice of Layer 3 (10 ℕ-level Agda lemmas, not +statistical identities over ℝ) exist today; Aspasia, ECHIDNA +arbitration, VeriSimDB persistence, and TypeLL levels 9-12 are design +targets, not implemented integrations. See the "`Experimental surfaces`" +section of `+README.adoc+` for the current, honest status of the FFI and +proofs boundaries specifically. + +=== Three-Body Verification Triangle + +.... + ECHIDNA (Formal Proofs) + ╱ Agda, Lean 4, Z3 ╲ + ╱ Arbitrates disputes ╲ + ╱ ╲ +Statistikles ◄─────────────────► Aspasia + (Julia) cross-verify via (GNU Octave) + Compute JSON transactions Audit +.... + +==== Layer 1: Statistikles (Julia) — Computation + +* All numerical computation happens in Julia’s symbolic kernel +* Every result includes BLAKE3 hash for reproducibility +* Results written as JSON transactions for Aspasia + +==== Layer 2: Aspasia (GNU Octave + Prolog) — Audit + +* Independent reimplementation using different BLAS/LAPACK +* Socratic engine: numerical, ontological, interpretation checks +* 6-step resolution ladder for disagreements (NIST StRD → Interval → +Symbolic → Human) + +==== Layer 3: ECHIDNA (Rust + 48 provers) — Arbitration (planned; not wired up) + +* Target: formal proofs of statistical identities via Agda/Lean 4. +Today, `+proofs/+` has 10 Agda lemmas proven over ℕ as discrete proxies +— not statistical identities over ℝ — and ECHIDNA dispatch from +`+src/bridge/echidna_adapter.jl+` is not yet implemented (see +`+proofs/README.adoc+`, "`Integration with ECHIDNA (aspirational)`") +* SMT verification of arithmetic properties via Z3/CVC5 +* Trust levels 1-5 for every verified property + +==== Layer 4: VeriSimDB (Port 8096) — Persistence + +* All results, audits, proofs persisted with VQL-UT queries +* 8 modalities: numerical, audit, proof, metadata, timeseries, graph, +raw, config + +==== Layer 5: TypeLL (Levels 1-10) — Type Safety (L1-3 real; L9-10 target) + +* From simple Float64 (L1) to a _target_ of formally-proven +epistemological types (L10) — L9-10 depend on the Layer 3 +proof/verification pipeline above, which is not yet wired up, so no +value in this codebase actually carries an L9/L10 guarantee yet +* Tropical semiring types at L7-8, verification provenance at L9-10 +(target) diff --git a/docs/CROSS-VERIFICATION-ARCHITECTURE.md b/docs/CROSS-VERIFICATION-ARCHITECTURE.md deleted file mode 100644 index e1edaaa..0000000 --- a/docs/CROSS-VERIFICATION-ARCHITECTURE.md +++ /dev/null @@ -1,55 +0,0 @@ - -# Cross-Verification Architecture - -*Status: ASPIRATIONAL.* This document describes the target multi-repo -verification architecture. Only Layer 1 (Statistikles/Julia computation) and -a small experimental slice of Layer 3 (10 ℕ-level Agda lemmas, not statistical -identities over ℝ) exist today; Aspasia, ECHIDNA arbitration, VeriSimDB -persistence, and TypeLL levels 9-12 are design targets, not implemented -integrations. See the "Experimental surfaces" section of `README.adoc` for the -current, honest status of the FFI and proofs boundaries specifically. - -## Three-Body Verification Triangle - -``` - ECHIDNA (Formal Proofs) - ╱ Agda, Lean 4, Z3 ╲ - ╱ Arbitrates disputes ╲ - ╱ ╲ -Statistikles ◄─────────────────► Aspasia - (Julia) cross-verify via (GNU Octave) - Compute JSON transactions Audit -``` - -### Layer 1: Statistikles (Julia) — Computation -- All numerical computation happens in Julia's symbolic kernel -- Every result includes BLAKE3 hash for reproducibility -- Results written as JSON transactions for Aspasia - -### Layer 2: Aspasia (GNU Octave + Prolog) — Audit -- Independent reimplementation using different BLAS/LAPACK -- Socratic engine: numerical, ontological, interpretation checks -- 6-step resolution ladder for disagreements (NIST StRD → Interval → Symbolic → Human) - -### Layer 3: ECHIDNA (Rust + 48 provers) — Arbitration (planned; not wired up) -- Target: formal proofs of statistical identities via Agda/Lean 4. Today, - `proofs/` has 10 Agda lemmas proven over ℕ as discrete proxies — not - statistical identities over ℝ — and ECHIDNA dispatch from - `src/bridge/echidna_adapter.jl` is not yet implemented (see - `proofs/README.adoc`, "Integration with ECHIDNA (aspirational)") -- SMT verification of arithmetic properties via Z3/CVC5 -- Trust levels 1-5 for every verified property - -### Layer 4: VeriSimDB (Port 8096) — Persistence -- All results, audits, proofs persisted with VQL-UT queries -- 8 modalities: numerical, audit, proof, metadata, timeseries, graph, raw, config - -### Layer 5: TypeLL (Levels 1-10) — Type Safety (L1-3 real; L9-10 target) -- From simple Float64 (L1) to a *target* of formally-proven epistemological - types (L10) — L9-10 depend on the Layer 3 proof/verification pipeline above, - which is not yet wired up, so no value in this codebase actually carries an - L9/L10 guarantee yet -- Tropical semiring types at L7-8, verification provenance at L9-10 (target) diff --git a/docs/QUICKSTART.adoc b/docs/QUICKSTART.adoc new file mode 100644 index 0000000..df97327 --- /dev/null +++ b/docs/QUICKSTART.adoc @@ -0,0 +1,25 @@ +== Quickstart + +The canonical quickstart guides live at the repository root: + +* link:../QUICKSTART-USER.adoc[QUICKSTART-USER.adoc] — install and run +in 5 minutes +* link:../QUICKSTART-DEV.adoc[QUICKSTART-DEV.adoc] — clone, build, test, +PR +* link:../QUICKSTART-MAINTAINER.adoc[QUICKSTART-MAINTAINER.adoc] — +packaging and deployment + +The short version: + +[source,bash] +---- +git clone https://github.com/hyperpolymath/statistikles.git +cd statistikles +just setup # julia --project=. -e 'using Pkg; Pkg.instantiate()' +just run # julia --project=. -e 'using Statistikles; main()' +just test # julia --project=. test/runtests.jl +---- + +Requires https://julialang.org/downloads/[Julia] 1.10+ and +https://github.com/casey/just[just]. See the link:../README.adoc[README] +for the full feature overview. diff --git a/docs/QUICKSTART.md b/docs/QUICKSTART.md deleted file mode 100644 index 2d8e178..0000000 --- a/docs/QUICKSTART.md +++ /dev/null @@ -1,25 +0,0 @@ - -# Quickstart - -The canonical quickstart guides live at the repository root: - -- [QUICKSTART-USER.adoc](../QUICKSTART-USER.adoc) — install and run in 5 minutes -- [QUICKSTART-DEV.adoc](../QUICKSTART-DEV.adoc) — clone, build, test, PR -- [QUICKSTART-MAINTAINER.adoc](../QUICKSTART-MAINTAINER.adoc) — packaging and deployment - -The short version: - -```bash -git clone https://github.com/hyperpolymath/statistikles.git -cd statistikles -just setup # julia --project=. -e 'using Pkg; Pkg.instantiate()' -just run # julia --project=. -e 'using Statistikles; main()' -just test # julia --project=. test/runtests.jl -``` - -Requires [Julia](https://julialang.org/downloads/) 1.10+ and -[just](https://github.com/casey/just). See the -[README](../README.adoc) for the full feature overview. diff --git a/docs/THREAT-MODEL.adoc b/docs/THREAT-MODEL.adoc new file mode 100644 index 0000000..a289f88 --- /dev/null +++ b/docs/THREAT-MODEL.adoc @@ -0,0 +1,316 @@ +== Threat Model: Statistikles + +=== Document Info + +[cols=",",options="header",] +|=== +|Field |Value +|Project |Statistikles +|Version |1.1 +|Last Reviewed |2026-07-10 +|Author |Jonathan D.A. Jewell +|Methodology |STRIDE +|=== + +=== Scope + +==== In Scope + +* Application source code and build pipeline +* CI/CD workflows (GitHub Actions) +* Container images and runtime environment +* Secrets and credential management +* Dependencies (direct and transitive) +* Deployment artifacts (binaries, containers, SBOM) + +==== Out of Scope + +* Physical security of hosting infrastructure +* GitHub/GitLab platform-level vulnerabilities +* End-user device security +* Social engineering attacks against maintainers (handled by org policy) + +=== System Overview + +Brief description of Statistikles and its architecture. + +____ +See link:../TOPOLOGY.md[TOPOLOGY.md] for the full architecture diagram +and completion dashboard. +____ + +=== Assets + +[width="100%",cols="25%,16%,13%,46%",options="header",] +|=== +|Asset |Classification |Owner |Notes +|Source code |Internal |Maintainers |Public repos are still +internal-integrity + +|Signing keys |Restricted |Release lead |Signing keys (e.g., Ed25519), +GPG keys + +|CI/CD secrets |Restricted |Maintainers |GITHUB_TOKEN, deploy tokens, +PATs + +|User/contributor data |Confidential |Org |Emails, contributor identity + +|Build artifacts |Internal |CI pipeline |Binaries, WASM bundles + +|Container images |Internal |CI pipeline |Chainguard-based, signed via +image signing tool + +|SBOM / provenance |Public |CI pipeline |SLSA attestations + +|Dependencies |Public |Lockfile |Project.toml + Manifest.toml (Julia); +GitHub Actions SHA pins + +|Infrastructure config |Confidential |Maintainers |Containerfiles, +compose files, orchestration config +|=== + +=== Trust Boundaries + +[width="100%",cols="35%,32%,33%",options="header",] +|=== +|Boundary |From (Lower Trust) |To (Higher Trust) +|Pull request submission |External contributor |Repository codebase + +|CI/CD workflow execution |Workflow definition |Runner with secrets +access + +|Container build boundary |Build stage |Runtime stage + +|External API calls |Third-party service |Application internals + +|User input (CLI/Web) |End user |Application logic + +|Dependency resolution |Package registry |Build environment + +|Forge mirroring |GitHub |GitLab / Bitbucket + +|Neural → symbolic handoff |LLM (chat interface) |Julia tool executor + +|FFI / C-ABI calls |External C-ABI caller |Zig FFI library (ffi/zig) +|=== + +=== Threat Actors + +[width="100%",cols="39%,44%,17%",options="header",] +|=== +|Actor |Motivation |Capability +|Script kiddie |Vandalism, clout |Low +|Disgruntled contributor |Sabotage, backdoor insertion |Medium +|Supply chain attacker |Wide-impact compromise |High +|Nation state |Espionage, disruption |Very High +|Automated bot |Credential stuffing, spam PRs |Low-Medium +|=== + +=== STRIDE Analysis + +==== Spoofing + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|Unsigned commits impersonate maintainer |Source code |Medium |High +|High |Require GPG-signed commits; vigilant code review + +|Forged bot actions (automated agents) |CI/CD pipeline |Low |High +|Medium |Bot tokens scoped minimally; audit bot activity + +|Spoofed package registry identity |Dependencies |Low |High |Medium |Pin +dependencies by hash; verify provenance +|=== + +==== Tampering + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|Malicious pull request |Source code |Medium |High |High |Branch +protection; required reviews; CodeQL + +|Dependency poisoning (typosquat) |Dependencies |Medium |High |High +|Lockfiles; secret-scanner; security scans + +|Tampered container base image |Container images |Low |High |Medium +|Chainguard images; image signing verification + +|Workflow file modification |CI/CD pipeline |Low |High |Medium +|CODEOWNERS on .github/; workflow-linter +|=== + +==== Repudiation + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|Unlogged deployment |Build artifacts |Medium |Medium |Medium |SLSA +provenance; deployment audit trail + +|Denied merge of vulnerable code |Source code |Low |Medium |Low |Git +history is immutable; signed commits + +|Secret rotation without record |CI/CD secrets |Low |Low |Low |Secret +rotation logged in STATE.a2ml +|=== + +==== Information Disclosure + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|Secrets leaked in git history |CI/CD secrets |Medium |High |High +|TruffleHog in CI; secret-scanner workflow + +|Verbose error messages in prod |Application logic |Medium |Medium +|Medium |Sanitize outputs; structured logging + +|SBOM reveals internal structure |Infrastructure |Low |Low |Low +|Accepted risk; SBOM is intentionally public +|=== + +==== Denial of Service + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|CI resource exhaustion (fork bomb in PR) |CI/CD pipeline |Medium +|Medium |Medium |Concurrency limits; timeout on workflows + +|Spam issues/PRs flooding triage |Maintainer time |Medium |Low |Low +|GitHub rate limits; bot auto-close stale + +|Large binary commits bloating repo |Source code |Low |Medium |Low +|.gitattributes LFS policy; pre-commit hooks +|=== + +==== Elevation of Privilege + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|Workflow injection via PR title/body |CI/CD pipeline |Medium |High +|High |Never interpolate PR fields in `+run:+`; use env vars + +|GITHUB_TOKEN over-scoped |CI/CD secrets |Medium |High |High +|`+permissions: read-all+` default; per-job scoping + +|Container escape |Runtime environment |Low |High |Medium |Hardened +container runtime; read-only rootfs; no-new-privileges + +|Compromised action dependency |CI/CD pipeline |Medium |High |High +|SHA-pin all actions; never use `+@latest+` tags +|=== + +=== Application-Specific Boundaries + +Statistikles is a neurosymbolic system: an LLM (the neural half) +interprets natural-language questions and dispatches to verified Julia +functions (the symbolic half) via the tool executor +(`+src/tools/executor.jl+`). The product’s core guarantee — every number +comes from auditable symbolic code, never from the LLM — makes these two +boundaries the primary application attack surface. + +==== Neural → Symbolic Boundary + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|LLM numeric fabrication ("`mollock`": invented p-values, effect sizes) +|Numeric outputs |High |High |High |System prompt forbids LLM arithmetic +(`+src/tools/chat.jl+`); numeric boundary guardrail checks that numerics +in responses originate from symbolic tool results + +|Prompt injection via user data (instructions embedded in CSV values, +column names, or the question) |Application logic |Medium |High |High +|LLM has no side-effecting tools; all tool calls dispatch to pure Julia +statistics; data is parsed as data (CSV/JSON3), never executed + +|Tool mis-routing (LLM selects the wrong test / wrong Julia function, +yielding plausible but wrong statistics) |Numeric outputs |Medium +|Medium |Medium |Typed tool schemas (`+src/tools/definitions.jl+`); +assumption checks in the stats layer; router/executor test coverage + +|Silent-null sub-types (degenerate inputs make a stats function return +`+NaN+`/`+missing+`/`+nothing+` silently; the LLM papers over the gap +with fabricated prose or numbers) |Numeric outputs |Medium |High |High +|Degenerate-input validation in the stats layer returns explicit errors +instead of silent nulls; executor surfaces errors verbatim to the user +|=== + +==== FFI / C-ABI Boundary (`+ffi/zig+`) + +[width="100%",cols="28%,14%,9%,6%,6%,37%",options="header",] +|=== +|Threat |Affected Asset |Likelihood |Impact |Risk |Mitigation +|Unvalidated inputs crossing the ABI (null handles, bad lengths, +non-terminated strings) |Runtime environment |Medium |High |High |Every +export checks handle/pointer validity and returns typed `+Result+` codes +(`+null_pointer+`, `+invalid_param+`) instead of dereferencing + +|Memory-safety violations (use-after-free, double-free, leaks across +`+statistikles_free+`/`+statistikles_free_string+`) |Runtime environment +|Low |High |Medium |Zig allocator discipline; opaque `+Handle+` prevents +direct field access; FFI integration tests (`+ffi/zig/test+`) + +|ABI layout drift between the Zig implementation and the declared C ABI +|Build artifacts |Low |Medium |Low |Layouts declared in one place and +kept in sync; FFI build + integration tests in CI +|=== + +=== Mitigations in Place + +* *SLSA Provenance*: Build attestations via slsa-github-generator +* *Secret Scanning*: TruffleHog + secret-scanner workflow on every push +* *Static Analysis*: CodeQL on supported languages +* *Supply Chain*: OpenSSF Scorecard (scorecard.yml) +* *Container Signing*: Ed25519 signatures on all published images +(optional: use your signing tool) +* *Container Runtime*: Hardened container runtime with formal +verification (optional) +* *Dependency Pinning*: All GitHub Actions SHA-pinned; Julia +Manifest.toml committed (Dependabot has no Julia ecosystem, so the +pinned manifest resolved by CI `+Pkg.instantiate+`/`+Pkg.test+` is the +compensating control) +* *Workflow Validation*: workflow-linter.yml checks all workflow changes +* *Security Scanning*: Neurosymbolic scanning (hypatia-scan.yml, +optional) +* *Bot Governance*: Bot orchestration with confidence thresholds +(optional) +* *Edge Security*: Gateway with policy enforcement (optional, where +applicable) +* *SBOM*: Generated and published with releases + +=== Residual Risks + +[width="100%",cols="39%,41%,20%",options="header",] +|=== +|Risk |Accepted Because |Review Trigger +|Zero-day in GitHub Actions runner |Platform responsibility; no feasible +mitigation |GitHub advisory + +|Maintainer account compromise |Mitigated by 2FA requirement; residual +remains |Any suspicious activity + +|Transitive dependency vulnerability (0-day) |Lockfiles limit blast +radius; scanning catches known CVEs |CVE database update + +|SBOM exposes internal component names |Transparency is a design goal +|Policy change +|=== + +=== Review Schedule + +This threat model should be reviewed: + +* *Quarterly* as a standing item +* *When architecture changes* (new services, new trust boundaries, new +deployment targets) +* *Before major releases* (v1.0, v2.0, etc.) +* *After any security incident* affecting this project or its +dependencies + +Reviewer should update the "`Last Reviewed`" date and version in +Document Info above. diff --git a/docs/THREAT-MODEL.md b/docs/THREAT-MODEL.md deleted file mode 100644 index 160962d..0000000 --- a/docs/THREAT-MODEL.md +++ /dev/null @@ -1,191 +0,0 @@ - - - -# Threat Model: Statistikles - -## Document Info - -| Field | Value | -|---------------|--------------------------------| -| Project | Statistikles | -| Version | 1.1 | -| Last Reviewed | 2026-07-10 | -| Author | Jonathan D.A. Jewell | -| Methodology | STRIDE | - -## Scope - -### In Scope - -- Application source code and build pipeline -- CI/CD workflows (GitHub Actions) -- Container images and runtime environment -- Secrets and credential management -- Dependencies (direct and transitive) -- Deployment artifacts (binaries, containers, SBOM) - -### Out of Scope - -- Physical security of hosting infrastructure -- GitHub/GitLab platform-level vulnerabilities -- End-user device security -- Social engineering attacks against maintainers (handled by org policy) - -## System Overview - -Brief description of Statistikles and its architecture. - -> See [TOPOLOGY.md](../TOPOLOGY.md) for the full architecture diagram and completion dashboard. - -## Assets - -| Asset | Classification | Owner | Notes | -|----------------------|----------------|-------------|--------------------------------------------| -| Source code | Internal | Maintainers | Public repos are still internal-integrity | -| Signing keys | Restricted | Release lead | Signing keys (e.g., Ed25519), GPG keys | -| CI/CD secrets | Restricted | Maintainers | GITHUB_TOKEN, deploy tokens, PATs | -| User/contributor data | Confidential | Org | Emails, contributor identity | -| Build artifacts | Internal | CI pipeline | Binaries, WASM bundles | -| Container images | Internal | CI pipeline | Chainguard-based, signed via image signing tool | -| SBOM / provenance | Public | CI pipeline | SLSA attestations | -| Dependencies | Public | Lockfile | Project.toml + Manifest.toml (Julia); GitHub Actions SHA pins | -| Infrastructure config | Confidential | Maintainers | Containerfiles, compose files, orchestration config | - -## Trust Boundaries - -| Boundary | From (Lower Trust) | To (Higher Trust) | -|-----------------------------|---------------------------|----------------------------| -| Pull request submission | External contributor | Repository codebase | -| CI/CD workflow execution | Workflow definition | Runner with secrets access | -| Container build boundary | Build stage | Runtime stage | -| External API calls | Third-party service | Application internals | -| User input (CLI/Web) | End user | Application logic | -| Dependency resolution | Package registry | Build environment | -| Forge mirroring | GitHub | GitLab / Bitbucket | -| Neural → symbolic handoff | LLM (chat interface) | Julia tool executor | -| FFI / C-ABI calls | External C-ABI caller | Zig FFI library (ffi/zig) | - -## Threat Actors - -| Actor | Motivation | Capability | -|--------------------------|-------------------------------|------------| -| Script kiddie | Vandalism, clout | Low | -| Disgruntled contributor | Sabotage, backdoor insertion | Medium | -| Supply chain attacker | Wide-impact compromise | High | -| Nation state | Espionage, disruption | Very High | -| Automated bot | Credential stuffing, spam PRs | Low-Medium | - -## STRIDE Analysis - -### Spoofing - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| Unsigned commits impersonate maintainer | Source code | Medium | High | High | Require GPG-signed commits; vigilant code review | -| Forged bot actions (automated agents) | CI/CD pipeline | Low | High | Medium | Bot tokens scoped minimally; audit bot activity | -| Spoofed package registry identity | Dependencies | Low | High | Medium | Pin dependencies by hash; verify provenance | - -### Tampering - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| Malicious pull request | Source code | Medium | High | High | Branch protection; required reviews; CodeQL | -| Dependency poisoning (typosquat) | Dependencies | Medium | High | High | Lockfiles; secret-scanner; security scans | -| Tampered container base image | Container images | Low | High | Medium | Chainguard images; image signing verification | -| Workflow file modification | CI/CD pipeline | Low | High | Medium | CODEOWNERS on .github/; workflow-linter | - -### Repudiation - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| Unlogged deployment | Build artifacts | Medium | Medium | Medium | SLSA provenance; deployment audit trail | -| Denied merge of vulnerable code | Source code | Low | Medium | Low | Git history is immutable; signed commits | -| Secret rotation without record | CI/CD secrets | Low | Low | Low | Secret rotation logged in STATE.a2ml | - -### Information Disclosure - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| Secrets leaked in git history | CI/CD secrets | Medium | High | High | TruffleHog in CI; secret-scanner workflow | -| Verbose error messages in prod | Application logic | Medium | Medium | Medium | Sanitize outputs; structured logging | -| SBOM reveals internal structure | Infrastructure | Low | Low | Low | Accepted risk; SBOM is intentionally public | - -### Denial of Service - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| CI resource exhaustion (fork bomb in PR) | CI/CD pipeline | Medium | Medium | Medium | Concurrency limits; timeout on workflows | -| Spam issues/PRs flooding triage | Maintainer time | Medium | Low | Low | GitHub rate limits; bot auto-close stale | -| Large binary commits bloating repo | Source code | Low | Medium | Low | .gitattributes LFS policy; pre-commit hooks | - -### Elevation of Privilege - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| Workflow injection via PR title/body | CI/CD pipeline | Medium | High | High | Never interpolate PR fields in `run:`; use env vars | -| GITHUB_TOKEN over-scoped | CI/CD secrets | Medium | High | High | `permissions: read-all` default; per-job scoping | -| Container escape | Runtime environment | Low | High | Medium | Hardened container runtime; read-only rootfs; no-new-privileges | -| Compromised action dependency | CI/CD pipeline | Medium | High | High | SHA-pin all actions; never use `@latest` tags | - -## Application-Specific Boundaries - -Statistikles is a neurosymbolic system: an LLM (the neural half) interprets -natural-language questions and dispatches to verified Julia functions (the -symbolic half) via the tool executor (`src/tools/executor.jl`). The product's -core guarantee — every number comes from auditable symbolic code, never from -the LLM — makes these two boundaries the primary application attack surface. - -### Neural → Symbolic Boundary - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| LLM numeric fabrication ("mollock": invented p-values, effect sizes) | Numeric outputs | High | High | High | System prompt forbids LLM arithmetic (`src/tools/chat.jl`); numeric boundary guardrail checks that numerics in responses originate from symbolic tool results | -| Prompt injection via user data (instructions embedded in CSV values, column names, or the question) | Application logic | Medium | High | High | LLM has no side-effecting tools; all tool calls dispatch to pure Julia statistics; data is parsed as data (CSV/JSON3), never executed | -| Tool mis-routing (LLM selects the wrong test / wrong Julia function, yielding plausible but wrong statistics) | Numeric outputs | Medium | Medium | Medium | Typed tool schemas (`src/tools/definitions.jl`); assumption checks in the stats layer; router/executor test coverage | -| Silent-null sub-types (degenerate inputs make a stats function return `NaN`/`missing`/`nothing` silently; the LLM papers over the gap with fabricated prose or numbers) | Numeric outputs | Medium | High | High | Degenerate-input validation in the stats layer returns explicit errors instead of silent nulls; executor surfaces errors verbatim to the user | - -### FFI / C-ABI Boundary (`ffi/zig`) - -| Threat | Affected Asset | Likelihood | Impact | Risk | Mitigation | -|---------------------------------|-------------------|------------|--------|--------|------------------------------------------------| -| Unvalidated inputs crossing the ABI (null handles, bad lengths, non-terminated strings) | Runtime environment | Medium | High | High | Every export checks handle/pointer validity and returns typed `Result` codes (`null_pointer`, `invalid_param`) instead of dereferencing | -| Memory-safety violations (use-after-free, double-free, leaks across `statistikles_free`/`statistikles_free_string`) | Runtime environment | Low | High | Medium | Zig allocator discipline; opaque `Handle` prevents direct field access; FFI integration tests (`ffi/zig/test`) | -| ABI layout drift between the Zig implementation and the declared C ABI | Build artifacts | Low | Medium | Low | Layouts declared in one place and kept in sync; FFI build + integration tests in CI | - -## Mitigations in Place - -- **SLSA Provenance**: Build attestations via slsa-github-generator -- **Secret Scanning**: TruffleHog + secret-scanner workflow on every push -- **Static Analysis**: CodeQL on supported languages -- **Supply Chain**: OpenSSF Scorecard (scorecard.yml) -- **Container Signing**: Ed25519 signatures on all published images (optional: use your signing tool) -- **Container Runtime**: Hardened container runtime with formal verification (optional) -- **Dependency Pinning**: All GitHub Actions SHA-pinned; Julia Manifest.toml committed (Dependabot has no Julia ecosystem, so the pinned manifest resolved by CI `Pkg.instantiate`/`Pkg.test` is the compensating control) -- **Workflow Validation**: workflow-linter.yml checks all workflow changes -- **Security Scanning**: Neurosymbolic scanning (hypatia-scan.yml, optional) -- **Bot Governance**: Bot orchestration with confidence thresholds (optional) -- **Edge Security**: Gateway with policy enforcement (optional, where applicable) -- **SBOM**: Generated and published with releases - -## Residual Risks - -| Risk | Accepted Because | Review Trigger | -|-----------------------------------------------|---------------------------------------------------|-------------------------| -| Zero-day in GitHub Actions runner | Platform responsibility; no feasible mitigation | GitHub advisory | -| Maintainer account compromise | Mitigated by 2FA requirement; residual remains | Any suspicious activity | -| Transitive dependency vulnerability (0-day) | Lockfiles limit blast radius; scanning catches known CVEs | CVE database update | -| SBOM exposes internal component names | Transparency is a design goal | Policy change | - -## Review Schedule - -This threat model should be reviewed: - -- **Quarterly** as a standing item -- **When architecture changes** (new services, new trust boundaries, new deployment targets) -- **Before major releases** (v1.0, v2.0, etc.) -- **After any security incident** affecting this project or its dependencies - -Reviewer should update the "Last Reviewed" date and version in Document Info above. diff --git a/docs/decisions/0000-template.adoc b/docs/decisions/0000-template.adoc new file mode 100644 index 0000000..de603ad --- /dev/null +++ b/docs/decisions/0000-template.adoc @@ -0,0 +1,33 @@ +== [NUMBER]. [TITLE] + +Date: YYYY-MM-DD + +=== Status + +{empty}[Proposed | Accepted | Deprecated | Superseded by +link:NNNN-title.md[ADR-NNNN] | Rejected] + +=== Context + +What is the issue that we’re seeing that is motivating this decision or +change? + +=== Decision + +What is the change that we’re proposing and/or doing? + +=== Consequences + +What becomes easier or more difficult to do because of this change? + +==== Positive + +* … + +==== Negative + +* … + +==== Neutral + +* … diff --git a/docs/decisions/0000-template.md b/docs/decisions/0000-template.md deleted file mode 100644 index 86734fb..0000000 --- a/docs/decisions/0000-template.md +++ /dev/null @@ -1,37 +0,0 @@ - - - -# [NUMBER]. [TITLE] - -Date: YYYY-MM-DD - -## Status - -[Proposed | Accepted | Deprecated | Superseded by [ADR-NNNN](NNNN-title.md) | Rejected] - -## Context - -What is the issue that we're seeing that is motivating this decision or change? - -## Decision - -What is the change that we're proposing and/or doing? - -## Consequences - -What becomes easier or more difficult to do because of this change? - -### Positive - -- ... - -### Negative - -- ... - -### Neutral - -- ... diff --git a/docs/decisions/0001-adopt-rsr-standard.adoc b/docs/decisions/0001-adopt-rsr-standard.adoc new file mode 100644 index 0000000..0dbd05a --- /dev/null +++ b/docs/decisions/0001-adopt-rsr-standard.adoc @@ -0,0 +1,94 @@ +== 1. Adopt Rhodium Standard Repository (RSR) Template + +Date: 2026-02-14 + +=== Status + +Accepted + +=== Context + +Managing multiple repositories with an ad-hoc approach led to +significant inconsistencies across the ecosystem. Common problems +included: + +* Missing or incomplete configuration files (SECURITY.md, +CONTRIBUTING.md, .editorconfig, etc.) +* State files (STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml) placed in the +repository root instead of the canonical `+.machine_readable/+` +directory +* Duplicate or conflicting workflow definitions across repos +* No standardized entry point for AI agents interacting with +repositories +* Inconsistent bot directive configurations leading to unreliable +automation +* No contractile enforcement or Justfile automation + +Without a single source of truth for repository structure, each new repo +required manual setup and inevitably drifted from best practices over +time. + +=== Decision + +Adopt the Rhodium Standard Repository (RSR) template +(`+rsr-template-repo+`) as the canonical starting point for all new +repositories. Existing repositories will migrate incrementally as they +receive active development. + +The RSR template provides: + +* *Machine-readable state files* in `+.machine_readable/+` (STATE.a2ml, +ECOSYSTEM.a2ml, META.a2ml, AGENTIC.a2ml, NEUROSYM.a2ml, PLAYBOOK.a2ml) +* *AI manifest* (`+0-AI-MANIFEST.a2ml+`) as a universal entry point for +all AI agents +* *Bot directives* in `+.machine_readable/bot_directives/+` for bot +orchestration integration +* *Contractiles* in `+.machine_readable/contractiles/+` (k9, dust, lust, +must, trust) for policy enforcement +* *Standardized workflows* (16+ GitHub Actions workflows, all +SHA-pinned) +* *Justfile automation* with standard recipes for common tasks +* *Security and governance files*: SECURITY.md, CONTRIBUTING.md, +CODE_OF_CONDUCT.md, LICENSE (MPL-2.0) +* *Architecture Decision Records* in `+docs/decisions/+` + +New repositories are created by cloning the template: + +[source,bash] +---- +git clone https://github.com/hyperpolymath/rsr-template-repo new-repo-name +cd new-repo-name +rm -rf .git && git init +---- + +=== Consequences + +==== Positive + +* Consistency across all repositories, enforced from creation +* Automated compliance checking via `+rsr-antipattern.yml+` workflow +* Bot fleet can operate reliably across all repos with predictable +structure +* AI agents (Claude, Gemini, etc.) have a standardized entry point via +`+0-AI-MANIFEST.a2ml+` +* New contributors can onboard faster with familiar, documented +structure +* Reduced maintenance burden: fix once in template, propagate to all +repos +* Machine-readable state enables tooling and automation pipelines + +==== Negative + +* Migration effort for existing repos requires time and attention +* Learning curve for contributors unfamiliar with RSR conventions +* Template updates need propagation mechanism to existing repos +* Some repos may have unique needs that do not fit the standard template +without customization + +==== Neutral + +* Existing CI/CD pipelines continue to work; RSR workflows are additive +* Third-party dependencies retain their original licenses regardless of +repo structure +* ADR process itself is part of the template, enabling future decisions +to be recorded consistently diff --git a/docs/decisions/0001-adopt-rsr-standard.md b/docs/decisions/0001-adopt-rsr-standard.md deleted file mode 100644 index d6fab39..0000000 --- a/docs/decisions/0001-adopt-rsr-standard.md +++ /dev/null @@ -1,88 +0,0 @@ - - - -# 1. Adopt Rhodium Standard Repository (RSR) Template - -Date: 2026-02-14 - -## Status - -Accepted - -## Context - -Managing multiple repositories with an ad-hoc approach led to significant -inconsistencies across the ecosystem. Common problems included: - -- Missing or incomplete configuration files (SECURITY.md, CONTRIBUTING.md, - .editorconfig, etc.) -- State files (STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml) placed in the repository - root instead of the canonical `.machine_readable/` directory -- Duplicate or conflicting workflow definitions across repos -- No standardized entry point for AI agents interacting with repositories -- Inconsistent bot directive configurations leading to unreliable automation -- No contractile enforcement or Justfile automation - -Without a single source of truth for repository structure, each new repo -required manual setup and inevitably drifted from best practices over time. - -## Decision - -Adopt the Rhodium Standard Repository (RSR) template (`rsr-template-repo`) as -the canonical starting point for all new repositories. Existing repositories -will migrate incrementally as they receive active development. - -The RSR template provides: - -- **Machine-readable state files** in `.machine_readable/` (STATE.a2ml, - ECOSYSTEM.a2ml, META.a2ml, AGENTIC.a2ml, NEUROSYM.a2ml, PLAYBOOK.a2ml) -- **AI manifest** (`0-AI-MANIFEST.a2ml`) as a universal entry point for all - AI agents -- **Bot directives** in `.machine_readable/bot_directives/` for bot orchestration integration -- **Contractiles** in `.machine_readable/contractiles/` (k9, dust, lust, must, trust) for - policy enforcement -- **Standardized workflows** (16+ GitHub Actions workflows, all SHA-pinned) -- **Justfile automation** with standard recipes for common tasks -- **Security and governance files**: SECURITY.md, CONTRIBUTING.md, - CODE_OF_CONDUCT.md, LICENSE (MPL-2.0) -- **Architecture Decision Records** in `docs/decisions/` - -New repositories are created by cloning the template: - -```bash -git clone https://github.com/hyperpolymath/rsr-template-repo new-repo-name -cd new-repo-name -rm -rf .git && git init -``` - -## Consequences - -### Positive - -- Consistency across all repositories, enforced from creation -- Automated compliance checking via `rsr-antipattern.yml` workflow -- Bot fleet can operate reliably across all repos with predictable structure -- AI agents (Claude, Gemini, etc.) have a standardized entry point via - `0-AI-MANIFEST.a2ml` -- New contributors can onboard faster with familiar, documented structure -- Reduced maintenance burden: fix once in template, propagate to all repos -- Machine-readable state enables tooling and automation pipelines - -### Negative - -- Migration effort for existing repos requires time and attention -- Learning curve for contributors unfamiliar with RSR conventions -- Template updates need propagation mechanism to existing repos -- Some repos may have unique needs that do not fit the standard template - without customization - -### Neutral - -- Existing CI/CD pipelines continue to work; RSR workflows are additive -- Third-party dependencies retain their original licenses regardless of - repo structure -- ADR process itself is part of the template, enabling future decisions - to be recorded consistently diff --git a/docs/decisions/0002-kautz-classification-and-target.adoc b/docs/decisions/0002-kautz-classification-and-target.adoc new file mode 100644 index 0000000..7cb3523 --- /dev/null +++ b/docs/decisions/0002-kautz-classification-and-target.adoc @@ -0,0 +1,121 @@ +== 2. Kautz Classification: Correct to Type 3, Target Type 4 + +Date: 2026-07-21 + +=== Status + +Accepted + +=== Context + +Statistikles described itself as a *Kautz Type 1* neurosymbolic system +in six places — `+README.adoc+` (twice), `+EXPLAINME.adoc+`, +`+guix.scm+`, `+0-AI-MANIFEST.a2ml+`, +`+.machine_readable/6a2/ECOSYSTEM.a2ml+`, and +`+.machine_readable/6a2/NEUROSYM.a2ml+` (prose plus `+kautz-type = 1+`). + +That label contradicted the description attached to it. +`+NEUROSYM.a2ml+` read: + +.... +kautz-type = 1 +description = "Neural | Symbolic — strict separation with defined interface" +.... + +In Kautz’s taxonomy (AAAI 2020 Engelmore Award lecture): + +[width="100%",cols="34%,33%,33%",options="header",] +|=== +|Type |Notation |Meaning +|1 |`+symbolic Neuro symbolic+` |A plain neural net. Symbols in, symbols +out — *the neural net does the work*. + +|2 |`+Symbolic[Neuro]+` |A symbolic problem solver calling a neural +subroutine (e.g. AlphaGo). + +|3 |`+Neuro \| Symbolic+` |A neural and a symbolic engine *cooperating +as co-routines* across a defined interface. + +|4 |`+Neuro:Symbolic → Neuro+` |Symbolic knowledge *compiled back into* +the neural component. +|=== + +The `+|+` pipe notation already in the description is Type 3’s. More +importantly, the architecture actually implemented is Type 3’s: + +* The neural role is _"`Natural language understanding and generation +ONLY`"_ +* The symbolic role is _"`ALL mathematical and statistical +computation`"_ +* There is one named gate: `+src/tools/executor.jl::execute_tool()+` +* The MOLLOCK rule — no statistical value may originate from neural +inference — is enforced at runtime by `+validate_numeric_provenance()+` +in `+src/tools/guardrail.jl+`, which traces every numeric literal in LLM +prose back to a recorded tool result + +Under Type 1 the LLM would itself be computing, which is exactly the +failure mode this project exists to prevent. The old label did not +merely misfile the project; it described the thing the MOLLOCK rule +forbids. + +Separately, *no target end-state had ever been recorded.* +`+docs/decisions/+` contained only the template and ADR 0001, and no +target appeared in `+RSR_OUTLINE.adoc+`, `+STATE.a2ml+`, or +`+NEUROSYM.a2ml+`. Elsewhere in the estate this _is_ tracked per project +— `+idaptik-ums+` records its own goal in +`+docs/adr/0001-ai-edit-kautz6-nesy.adoc+` (Kautz 6) — so the convention +existed and statistikles had simply not used it. + +=== Decision + +[arabic] +. *Classify Statistikles as Kautz Type 3.* Correct all six artefacts, +including `+kautz-type = 3+` in `+NEUROSYM.a2ml+`, and record the +taxonomy reasoning in that file so the correction is not silently +reverted by a future reader. +. *Adopt Kautz Type 4 (`+Neuro:Symbolic → Neuro+`) as the target +end-state*, recorded as `+kautz-target = 4+`. ++ +The lever already exists in `+NEUROSYM.a2ml [verification-pipeline]+`, +which lists six stages of which exactly one is `+implemented+`: ++ +[cols=",,",options="header",] +|=== +|Stage |Engine |Status +|compute |Julia symbolic functions |*implemented* +|explain |echidna GraphQL + mathematical working |planned +|prove |echidna formal verification |planned +|demonstrate |R/Julia visual walkthrough |planned +|annotate |code + mathematical annotation |planned +|*verify* |*adversarial neurosymbolic SLM* |*planned* +|=== ++ +That final `+verify+` stage — feeding symbolic//proof knowledge into a +trained adversarial model — is the Type 4 transition. + +=== Consequences + +* *Reaching Type 3 is not a work item.* It is already built; this ADR +corrects the paperwork. The engineering programme is 3 → 4, not 1 → 4. +* The five `+planned+` pipeline stages become the backlog for that +programme. +* Those stages *must stay honestly marked `+planned+`* until they +actually run. A `+status = "implemented"+` on an unbuilt stage would be +the documentation equivalent of a MOLLOCK, and the same objection +applies. +* Downstream consumers of `+ECOSYSTEM.a2ml+` / `+NEUROSYM.a2ml+` that +key on `+kautz-type+` will see the value change from `+1+` to `+3+`. +* Kautz levels are *not* uniform across this estate. Do not infer a +project’s level from a sibling; read its own ADR. + +=== References + +* H. Kautz, _The Third AI Summer_, AAAI Robert S. Engelmore Award +Lecture, 2020 +* `+.machine_readable/6a2/NEUROSYM.a2ml+` — classification, MOLLOCK +rule, pipeline stages +* `+src/tools/executor.jl+` — `+execute_tool()+`, the neural→symbolic +gate +* `+src/tools/guardrail.jl+` — `+validate_numeric_provenance()+`, +runtime MOLLOCK enforcement +* `+test/guardrail_test.jl+` — tests for the above diff --git a/docs/decisions/0002-kautz-classification-and-target.md b/docs/decisions/0002-kautz-classification-and-target.md deleted file mode 100644 index a87ce06..0000000 --- a/docs/decisions/0002-kautz-classification-and-target.md +++ /dev/null @@ -1,101 +0,0 @@ - - - -# 2. Kautz Classification: Correct to Type 3, Target Type 4 - -Date: 2026-07-21 - -## Status - -Accepted - -## Context - -Statistikles described itself as a **Kautz Type 1** neurosymbolic system in six -places — `README.adoc` (twice), `EXPLAINME.adoc`, `guix.scm`, `0-AI-MANIFEST.a2ml`, -`.machine_readable/6a2/ECOSYSTEM.a2ml`, and `.machine_readable/6a2/NEUROSYM.a2ml` -(prose plus `kautz-type = 1`). - -That label contradicted the description attached to it. `NEUROSYM.a2ml` read: - -``` -kautz-type = 1 -description = "Neural | Symbolic — strict separation with defined interface" -``` - -In Kautz's taxonomy (AAAI 2020 Engelmore Award lecture): - -| Type | Notation | Meaning | -|---|---|---| -| 1 | `symbolic Neuro symbolic` | A plain neural net. Symbols in, symbols out — **the neural net does the work**. | -| 2 | `Symbolic[Neuro]` | A symbolic problem solver calling a neural subroutine (e.g. AlphaGo). | -| 3 | `Neuro \| Symbolic` | A neural and a symbolic engine **cooperating as co-routines** across a defined interface. | -| 4 | `Neuro:Symbolic → Neuro` | Symbolic knowledge **compiled back into** the neural component. | - -The `|` pipe notation already in the description is Type 3's. More importantly, the -architecture actually implemented is Type 3's: - -- The neural role is *"Natural language understanding and generation ONLY"* -- The symbolic role is *"ALL mathematical and statistical computation"* -- There is one named gate: `src/tools/executor.jl::execute_tool()` -- The MOLLOCK rule — no statistical value may originate from neural inference — is - enforced at runtime by `validate_numeric_provenance()` in `src/tools/guardrail.jl`, - which traces every numeric literal in LLM prose back to a recorded tool result - -Under Type 1 the LLM would itself be computing, which is exactly the failure mode this -project exists to prevent. The old label did not merely misfile the project; it -described the thing the MOLLOCK rule forbids. - -Separately, **no target end-state had ever been recorded.** `docs/decisions/` contained -only the template and ADR 0001, and no target appeared in `RSR_OUTLINE.adoc`, -`STATE.a2ml`, or `NEUROSYM.a2ml`. Elsewhere in the estate this *is* tracked per project -— `idaptik-ums` records its own goal in `docs/adr/0001-ai-edit-kautz6-nesy.adoc` -(Kautz 6) — so the convention existed and statistikles had simply not used it. - -## Decision - -1. **Classify Statistikles as Kautz Type 3.** Correct all six artefacts, including - `kautz-type = 3` in `NEUROSYM.a2ml`, and record the taxonomy reasoning in that file - so the correction is not silently reverted by a future reader. - -2. **Adopt Kautz Type 4 (`Neuro:Symbolic → Neuro`) as the target end-state**, recorded - as `kautz-target = 4`. - - The lever already exists in `NEUROSYM.a2ml [verification-pipeline]`, which lists six - stages of which exactly one is `implemented`: - - | Stage | Engine | Status | - |---|---|---| - | compute | Julia symbolic functions | **implemented** | - | explain | echidna GraphQL + mathematical working | planned | - | prove | echidna formal verification | planned | - | demonstrate | R/Julia visual walkthrough | planned | - | annotate | code + mathematical annotation | planned | - | **verify** | **adversarial neurosymbolic SLM** | **planned** | - - That final `verify` stage — feeding symbolic//proof knowledge into a trained - adversarial model — is the Type 4 transition. - -## Consequences - -- **Reaching Type 3 is not a work item.** It is already built; this ADR corrects the - paperwork. The engineering programme is 3 → 4, not 1 → 4. -- The five `planned` pipeline stages become the backlog for that programme. -- Those stages **must stay honestly marked `planned`** until they actually run. A - `status = "implemented"` on an unbuilt stage would be the documentation equivalent of - a MOLLOCK, and the same objection applies. -- Downstream consumers of `ECOSYSTEM.a2ml` / `NEUROSYM.a2ml` that key on `kautz-type` - will see the value change from `1` to `3`. -- Kautz levels are **not** uniform across this estate. Do not infer a project's level - from a sibling; read its own ADR. - -## References - -- H. Kautz, *The Third AI Summer*, AAAI Robert S. Engelmore Award Lecture, 2020 -- `.machine_readable/6a2/NEUROSYM.a2ml` — classification, MOLLOCK rule, pipeline stages -- `src/tools/executor.jl` — `execute_tool()`, the neural→symbolic gate -- `src/tools/guardrail.jl` — `validate_numeric_provenance()`, runtime MOLLOCK enforcement -- `test/guardrail_test.jl` — tests for the above diff --git a/docs/decisions/README.adoc b/docs/decisions/README.adoc new file mode 100644 index 0000000..3dc7a48 --- /dev/null +++ b/docs/decisions/README.adoc @@ -0,0 +1,18 @@ +== Architecture Decision Records + +We record significant architectural decisions using +https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions[Architecture +Decision Records (ADRs)], as described by Michael Nygard. + +Each ADR captures the context, decision, and consequences of a choice +that affects the project’s structure, dependencies, or conventions. + +=== Creating a new ADR + +[source,bash] +---- +just adr "Title of decision" +---- + +This creates a new numbered file in `+docs/decisions/+` from the +template at `+0000-template.md+`. diff --git a/docs/decisions/README.md b/docs/decisions/README.md deleted file mode 100644 index 2eb087c..0000000 --- a/docs/decisions/README.md +++ /dev/null @@ -1,19 +0,0 @@ - - - -# Architecture Decision Records - -We record significant architectural decisions using [Architecture Decision Records (ADRs)](https://cognitect.com/blog/2011/11/15/documenting-architecture-decisions), as described by Michael Nygard. - -Each ADR captures the context, decision, and consequences of a choice that affects the project's structure, dependencies, or conventions. - -## Creating a new ADR - -```bash -just adr "Title of decision" -``` - -This creates a new numbered file in `docs/decisions/` from the template at `0000-template.md`. diff --git a/docs/tech-debt-2026-05-26.adoc b/docs/tech-debt-2026-05-26.adoc new file mode 100644 index 0000000..b1b89a0 --- /dev/null +++ b/docs/tech-debt-2026-05-26.adoc @@ -0,0 +1,70 @@ +SPDX-License-Identifier: CC-BY-SA-4.0 SPDX-FileCopyrightText: 2026 +Jonathan D.A. Jewell (hyperpolymath) –> + +== Tech-Debt Audit — statistikles — 2026-05-26 + +*Source:* estate-wide automated scan 2026-05-26. *Companion:* +https://github.com/hyperpolymath/standards/tree/main/docs/audits[`+hyperpolymath/standards+` +2026-05-26-estate-*-debt audits]. *Combined severity:* `+LOW+`. + +This file records the _raw findings_ — it does not by itself fix the +debt. Each section ends with a '`Recommended next move`' line; closing +the debt is follow-up work. + +=== 1. Proof debt + +No proof-bearing files (`+*.v+`, `+*.lean+`, `+*.agda+`, `+*.idr+`, +`+*.idr2+`, `+*.fst+`, `+*.dfy+`, `+*.tla+`, `+*.ads+`, `+*.adb+`) found +in this repo. + +*Recommended next move:* none. + +=== 2. Licence debt + +[cols=",",options="header",] +|=== +|Field |Value +|LICENSE file |`+LICENSE+` +|SPDX header |`+MPL-2.0+` +|Manifest licence |`+NONE+` +|Body classifier |`+Palimp-MPL-2.0+` +|Severity |`+ok+` +|=== + +*Recommended next move:* none for licence. + +=== 3. Documentation debt + +[cols=",",options="header",] +|=== +|Field |Value +|README lines |128 +|`+docs/+` files |14 +|`+docs/+` LoC |1375 +|CHANGELOG.md |Y +|CONTRIBUTING.md |Y +|CODE_OF_CONDUCT.md |Y +|SECURITY.md |Y +|Severity |`+LOW+` +|=== + +*Recommended next move:* `+docs/+` has only 14 file(s). Aim for ≥10 +organised docs (architecture, usage, contributing-guide, +troubleshooting, design-decisions). The user’s bar for a +"`heavily-developed and well-organised wiki`" is ≥10 files with topical +organisation. + +=== Cross-references + +* Estate proof-debt audit: +`+hyperpolymath/standards/docs/audits/2026-05-26-estate-proof-debt.md+` +* Estate licence-debt audit: +`+hyperpolymath/standards/docs/audits/2026-05-26-estate-licence-debt.md+` +* Estate documentation-debt audit: +`+hyperpolymath/standards/docs/audits/2026-05-26-estate-documentation-debt.md+` + +''''' + +🤖 Generated by Claude Code estate-wide tech-debt scan (2026-05-26). +This file is informational — closing the debt is follow-up work owned by +the maintainer. diff --git a/docs/tech-debt-2026-05-26.md b/docs/tech-debt-2026-05-26.md deleted file mode 100644 index cf2f639..0000000 --- a/docs/tech-debt-2026-05-26.md +++ /dev/null @@ -1,56 +0,0 @@ - -SPDX-License-Identifier: CC-BY-SA-4.0 -SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell (hyperpolymath) ---> - -# Tech-Debt Audit — statistikles — 2026-05-26 - -**Source:** estate-wide automated scan 2026-05-26. -**Companion:** [`hyperpolymath/standards` 2026-05-26-estate-*-debt audits](https://github.com/hyperpolymath/standards/tree/main/docs/audits). -**Combined severity:** `LOW`. - -This file records the *raw findings* — it does not by itself fix the debt. Each section ends with a 'Recommended next move' line; closing the debt is follow-up work. - -## 1. Proof debt - -No proof-bearing files (`*.v`, `*.lean`, `*.agda`, `*.idr`, `*.idr2`, `*.fst`, `*.dfy`, `*.tla`, `*.ads`, `*.adb`) found in this repo. - -**Recommended next move:** none. - -## 2. Licence debt - -| Field | Value | -|---|---| -| LICENSE file | `LICENSE` | -| SPDX header | `MPL-2.0` | -| Manifest licence | `NONE` | -| Body classifier | `Palimp-MPL-2.0` | -| Severity | `ok` | - -**Recommended next move:** none for licence. - -## 3. Documentation debt - -| Field | Value | -|---|---| -| README lines | 128 | -| `docs/` files | 14 | -| `docs/` LoC | 1375 | -| CHANGELOG.md | Y | -| CONTRIBUTING.md | Y | -| CODE_OF_CONDUCT.md | Y | -| SECURITY.md | Y | -| Severity | `LOW` | - -**Recommended next move:** `docs/` has only 14 file(s). Aim for ≥10 organised docs (architecture, usage, contributing-guide, troubleshooting, design-decisions). The user's bar for a "heavily-developed and well-organised wiki" is ≥10 files with topical organisation. - -## Cross-references - -- Estate proof-debt audit: `hyperpolymath/standards/docs/audits/2026-05-26-estate-proof-debt.md` -- Estate licence-debt audit: `hyperpolymath/standards/docs/audits/2026-05-26-estate-licence-debt.md` -- Estate documentation-debt audit: `hyperpolymath/standards/docs/audits/2026-05-26-estate-documentation-debt.md` - ---- - -🤖 Generated by Claude Code estate-wide tech-debt scan (2026-05-26). This file is informational — closing the debt is follow-up work owned by the maintainer. diff --git a/llm-warmup-dev.adoc b/llm-warmup-dev.adoc new file mode 100644 index 0000000..9c96755 --- /dev/null +++ b/llm-warmup-dev.adoc @@ -0,0 +1,19 @@ +== LLM Warmup — statistikles (Developer) + +=== What is statistikles? + +See README.adoc for overview. + +=== Key Commands + +* `+just setup+` — set up development environment +* `+just build+` — build the project +* `+just test+` — run tests +* `+just doctor+` — diagnose issues +* `+just heal+` — attempt auto-repair + +=== Quick Context + +* License: MPL-2.0 +* Part of hyperpolymath ecosystem +* See EXPLAINME.adoc for architecture diff --git a/llm-warmup-dev.md b/llm-warmup-dev.md deleted file mode 100644 index 69fc128..0000000 --- a/llm-warmup-dev.md +++ /dev/null @@ -1,20 +0,0 @@ - -# LLM Warmup — statistikles (Developer) - -## What is statistikles? -See README.adoc for overview. - -## Key Commands -- `just setup` — set up development environment -- `just build` — build the project -- `just test` — run tests -- `just doctor` — diagnose issues -- `just heal` — attempt auto-repair - -## Quick Context -- License: MPL-2.0 -- Part of hyperpolymath ecosystem -- See EXPLAINME.adoc for architecture diff --git a/llm-warmup-user.adoc b/llm-warmup-user.adoc new file mode 100644 index 0000000..dcb6ffd --- /dev/null +++ b/llm-warmup-user.adoc @@ -0,0 +1,19 @@ +== LLM Warmup — statistikles (User) + +=== What is statistikles? + +See README.adoc for overview. + +=== Key Commands + +* `+just setup+` — set up development environment +* `+just build+` — build the project +* `+just test+` — run tests +* `+just doctor+` — diagnose issues +* `+just heal+` — attempt auto-repair + +=== Quick Context + +* License: MPL-2.0 +* Part of hyperpolymath ecosystem +* See EXPLAINME.adoc for architecture diff --git a/llm-warmup-user.md b/llm-warmup-user.md deleted file mode 100644 index 1b3bb4a..0000000 --- a/llm-warmup-user.md +++ /dev/null @@ -1,20 +0,0 @@ - -# LLM Warmup — statistikles (User) - -## What is statistikles? -See README.adoc for overview. - -## Key Commands -- `just setup` — set up development environment -- `just build` — build the project -- `just test` — run tests -- `just doctor` — diagnose issues -- `just heal` — attempt auto-repair - -## Quick Context -- License: MPL-2.0 -- Part of hyperpolymath ecosystem -- See EXPLAINME.adoc for architecture