diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 4cec20e..2421583 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -74,3 +74,9 @@ jobs: - name: Check every .adoc renders run: ./scripts/check-docs-render.sh . + + # ...and that it renders *because it is AsciiDoc*, not because + # Asciidoctor's Markdown-compat mode quietly accepted a Markdown body. + # Needs no asciidoctor — it is a pure syntax scan. + - name: Check every .adoc is AsciiDoc, not Markdown + run: ./scripts/check-adoc-not-markdown.sh . diff --git a/.machine_readable/ai/PLACEHOLDERS.adoc b/.machine_readable/ai/PLACEHOLDERS.adoc index 472f600..fab8116 100644 --- a/.machine_readable/ai/PLACEHOLDERS.adoc +++ b/.machine_readable/ai/PLACEHOLDERS.adoc @@ -1,21 +1,22 @@ = Template Placeholders -# Template Placeholders All placeholders in this template follow the `{{PLACEHOLDER}}` pattern. After cloning, replace them with your project-specific values. -## Recommended: Interactive Bootstrap +== Recommended: Interactive Bootstrap -```bash +[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 +== Manual Replace -```bash +[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' .) @@ -28,80 +29,104 @@ sed -i 's/the-nash-equilibrium/my-project/g' $(grep -rl 'the-nash-equilibrium' . 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/{{CURRENT_DATE}}/$(date +%Y-%m-%d)/g" $(grep -rl '{{CURRENT_DATE}}' .) -``` +---- -## Placeholder Reference +== Placeholder Reference -### Author & Copyright +=== 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 | +[cols="1,1,1,1",options="header"] +|=== +| Placeholder | Description | Example | Files -### Project Identity +| `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 +|=== -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `The Nash Equilibrium` | 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 | -| `6X strategy board game exploring economic systems, planetary boundaries, and post-scarcity futures` | One-line description | `A tool for X` | flake.nix | -| `{{PROJECT}}` | Uppercase identifier (for Idris2 modules, C macros) | `MY_PROJECT` | ABI-FFI-README.md, src/interface/abi/*.idr, src/interface/ffi/*.zig | -| `the-nash-equilibrium` | Lowercase identifier (for C symbols, filenames) | `my_project` | ABI-FFI-README.md, src/interface/ffi/*.zig | -| `the-nash-equilibrium` | 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 | +=== Project Identity -### Dates +[cols="1,1,1,1",options="header"] +|=== +| Placeholder | Description | Example | Files -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `2026` | Current year | `2026` | SPDX headers (all files), GOVERNANCE.md, MAINTAINERS.md | -| `{{CURRENT_DATE}}` | Current date (ISO) | `2026-02-14` | STATE.a2ml, MAINTAINERS.md | -| `{{DATE}}` | Last updated date | `2026-02-14` | TOPOLOGY.md, THREAT-MODEL.md | +| `The Nash Equilibrium` | 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 +| `6X strategy board game exploring economic systems, planetary boundaries, and post-scarcity futures` | One-line description | `A tool for X` | flake.nix +| `{{PROJECT}}` | Uppercase identifier (for Idris2 modules, C macros) | `MY_PROJECT` | ABI-FFI-README.md, src/interface/abi/*.idr, src/interface/ffi/*.zig +| `the-nash-equilibrium` | Lowercase identifier (for C symbols, filenames) | `my_project` | ABI-FFI-README.md, src/interface/ffi/*.zig +| `the-nash-equilibrium` | 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 +|=== -### Contact & Security +=== Dates -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `j.d.a.jewell@open.ac.uk` | Security contact email | `security@example.org` | SECURITY.md | -| `TODO` | 40-char PGP fingerprint | `ABCD 1234 ...` | SECURITY.md | -| `TODO` | URL to public PGP key | `https://keys.openpgp.org/...` | SECURITY.md | -| `{{WEBSITE}}` | Project website | `https://example.org` | SECURITY.md | -| `j.d.a.jewell@open.ac.uk` | Conduct reports email | `conduct@example.org` | CODE_OF_CONDUCT.md | -| `maintainers` | Conduct committee name | `Code of Conduct Committee` | CODE_OF_CONDUCT.md | -| `48 hours` | SLA for initial response | `48 hours` | CODE_OF_CONDUCT.md | +[cols="1,1,1,1",options="header"] +|=== +| Placeholder | Description | Example | Files -### Git +| `2026` | Current year | `2026` | SPDX headers (all files), GOVERNANCE.md, MAINTAINERS.md +| `{{CURRENT_DATE}}` | Current date (ISO) | `2026-02-14` | STATE.a2ml, MAINTAINERS.md +| `{{DATE}}` | Last updated date | `2026-02-14` | TOPOLOGY.md, THREAT-MODEL.md +|=== -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `main` | Main branch name | `main` | CONTRIBUTING.md | +=== Contact & Security -### Build +[cols="1,1,1,1",options="header"] +|=== +| Placeholder | Description | Example | Files -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `{{LICENSE}}` | License name | `AGPL-3.0-or-later` | ABI-FFI-README.md | -| `6X strategy board game` | One-line project description | `FFI bridges between languages` | STATE.a2ml | +| `j.d.a.jewell@open.ac.uk` | Security contact email | `security@example.org` | SECURITY.md +| `TODO` | 40-char PGP fingerprint | `ABCD 1234 ...` | SECURITY.md +| `TODO` | URL to public PGP key | `https://keys.openpgp.org/...` | SECURITY.md +| `{{WEBSITE}}` | Project website | `https://example.org` | SECURITY.md +| `j.d.a.jewell@open.ac.uk` | Conduct reports email | `conduct@example.org` | CODE_OF_CONDUCT.md +| `maintainers` | Conduct committee name | `Code of Conduct Committee` | CODE_OF_CONDUCT.md +| `48 hours` | SLA for initial response | `48 hours` | CODE_OF_CONDUCT.md +|=== -### AI Manifest +=== Git -| 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 | +[cols="1,1,1,1",options="header"] +|=== +| Placeholder | Description | Example | Files -### AI Installation Guide +| `main` | Main branch name | `main` | CONTRIBUTING.md +|=== -| 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` | +=== Build + +[cols="1,1,1,1",options="header"] +|=== +| Placeholder | Description | Example | Files + +| `{{LICENSE}}` | License name | `AGPL-3.0-or-later` | ABI-FFI-README.md +| `6X strategy board game` | One-line project description | `FFI bridges between languages` | STATE.a2ml +|=== + +=== AI Manifest + +[cols="1,1,1,1",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 + +[cols="1,1,1",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 @@ -118,25 +143,29 @@ sections where the developer (or AI) must fill in: **finishbot checks:** `just validate-ai-install` verifies no `[TODO-AI-INSTALL]` markers remain. -## Deletion Markers +== Deletion Markers Some files contain deletion instructions: -| Marker | Meaning | File | -|---|---|---| -| `{{~ ... ~}}` | Delete this entire line after reading | ABI-FFI-README.md (line 1) | +[cols="1,1,1",options="header"] +|=== +| Marker | Meaning | File + +| `{{~ ... ~}}` | Delete this entire line after reading | ABI-FFI-README.md (line 1) +|=== -## Verification +== Verification After replacing all placeholders, verify none remain: -```bash +[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/Justfile b/Justfile index cee85f9..fad18f4 100644 --- a/Justfile +++ b/Justfile @@ -281,10 +281,20 @@ docs: just man @echo "Documentation generated in docs/" -# Check every .adoc actually renders (content-side counterpart to the .md ban) -docs-check: +# Check the docs three ways: named .adoc, parses, and is actually AsciiDoc. +# The three are independent — eight files once passed the first two while their +# bodies were still Markdown (SPDX headers rendering as visible text, tables +# rendering as garbage). See scripts/check-adoc-not-markdown.sh. +docs-check: docs-check-render docs-check-dialect + +# Every .adoc must parse (content-side counterpart to the .md extension ban) +docs-check-render: @./scripts/check-docs-render.sh . +# Every .adoc must be AsciiDoc, not Markdown wearing an .adoc extension +docs-check-dialect: + @./scripts/check-adoc-not-markdown.sh . + # Render the docs to HTML for local reading [reversible: rm -rf docs/generated/html] docs-html: #!/usr/bin/env bash diff --git a/docs/STATE-VISUALIZER.adoc b/docs/STATE-VISUALIZER.adoc index 2af3297..80e96cd 100644 --- a/docs/STATE-VISUALIZER.adoc +++ b/docs/STATE-VISUALIZER.adoc @@ -1,15 +1,11 @@ -= Project State Visualizer -[source] ----- - - - - -# RSR Template Repo — Project Topology +// SPDX-License-Identifier: CC-BY-SA-4.0 +// TOPOLOGY.md — Project architecture map and completion dashboard +// Last updated: 2026-02-28 += RSR Template Repo — Project Topology -## System Architecture +== System Architecture -``` +---- ┌─────────────────────────────────────────┐ │ NEW REPOSITORY │ │ (Consumer of this Template) │ @@ -56,11 +52,11 @@ │ Justfile / Mustfile .machine_readable/ │ │ Codeowners / Reuse 0-AI-MANIFEST.a2ml │ └─────────────────────────────────────────┘ -``` +---- -## Completion Dashboard +== Completion Dashboard -``` +---- COMPONENT STATUS NOTES ───────────────────────────────── ────────────────── ───────────────────────────────── CORE STANDARDS @@ -92,11 +88,11 @@ REPO INFRASTRUCTURE ───────────────────────────────────────────────────────────────────────────── OVERALL: ██████████ 100% RSR Template Stable & Certified -``` +---- -## Key Dependencies +== Key Dependencies -``` +---- Philosophy ──────► RSR Standard ──────► Template Scaffolding ──► New Repo │ │ │ │ ▼ ▼ ▼ ▼ @@ -112,9 +108,9 @@ CCCP Policy ─────► 0-AI-MANIFEST ────────► Justfil │ ▼ k9-svc deploy -``` +---- -## Update Protocol +== Update Protocol This file is maintained by both humans and AI agents. When updating: @@ -125,4 +121,3 @@ This file is maintained by both humans and AI agents. When updating: Progress bars use: `█` (filled) and `░` (empty), 10 characters wide. Percentages: 0%, 10%, 20%, ... 100% (in 10% increments). ----- diff --git a/docs/architecture/THREAT-MODEL.adoc b/docs/architecture/THREAT-MODEL.adoc index 15f42a7..8da8168 100644 --- a/docs/architecture/THREAT-MODEL.adoc +++ b/docs/architecture/THREAT-MODEL.adoc @@ -1,22 +1,23 @@ -= Threat Model - - +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) += Threat Model: The Nash Equilibrium -# Threat Model: The Nash Equilibrium +== Document Info -## Document Info +[cols="1,1",options="header"] +|=== +| Field | Value -| Field | Value | -|---------------|--------------------------------| -| Project | The Nash Equilibrium | -| Version | 1.0 | -| Last Reviewed | 2026-04-04 | -| Author | Jonathan D.A. Jewell | -| Methodology | STRIDE | +| Project | The Nash Equilibrium +| Version | 1.0 +| Last Reviewed | 2026-04-04 +| Author | Jonathan D.A. Jewell +| Methodology | STRIDE +|=== -## Scope +== Scope -### In Scope +=== In Scope - Application source code and build pipeline - CI/CD workflows (GitHub Actions) @@ -25,108 +26,135 @@ - Dependencies (direct and transitive) - Deployment artifacts (binaries, containers, SBOM) -### Out of Scope +=== 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 +== System Overview Brief description of The Nash Equilibrium and its architecture. -> See [STATE-VISUALIZER.adoc](../STATE-VISUALIZER.adoc) 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 | Cargo.lock, deno.lock, gleam.toml | -| 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 | - -## 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 | - -## Mitigations in Place +> See xref:../STATE-VISUALIZER.adoc[STATE-VISUALIZER.adoc] for the full architecture diagram and completion dashboard. + +== Assets + +[cols="1,1,1,1",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 | Cargo.lock, deno.lock, gleam.toml +| Infrastructure config | Confidential | Maintainers | Containerfiles, compose files, orchestration config +|=== + +== Trust Boundaries + +[cols="1,1,1",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 +|=== + +== Threat Actors + +[cols="1,1,1",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 + +[cols="1,1,1,1,1,1",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 + +[cols="1,1,1,1,1,1",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 + +[cols="1,1,1,1,1,1",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 + +[cols="1,1,1,1,1,1",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 + +[cols="1,1,1,1,1,1",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 + +[cols="1,1,1,1,1,1",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 +|=== + +== Mitigations in Place - **SLSA Provenance**: Build attestations via slsa-github-generator - **Secret Scanning**: TruffleHog + secret-scanner workflow on every push @@ -141,16 +169,19 @@ Brief description of The Nash Equilibrium and its architecture. - **Edge Security**: Gateway with policy enforcement (optional, where applicable) - **SBOM**: Generated and published with releases -## Residual Risks +== Residual Risks + +[cols="1,1,1",options="header"] +|=== +| Risk | Accepted Because | Review Trigger -| 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 | +| 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 +== Review Schedule This threat model should be reviewed: diff --git a/docs/decisions/0000-template.adoc b/docs/decisions/0000-template.adoc index 6710304..3c98be5 100644 --- a/docs/decisions/0000-template.adoc +++ b/docs/decisions/0000-template.adoc @@ -1,35 +1,33 @@ -= Architecture Decision Record: 0000-template - - - -# [NUMBER]. [TITLE] +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) += [NUMBER]. [TITLE] Date: YYYY-MM-DD -## Status +== Status -[Proposed | Accepted | Deprecated | Superseded by [ADR-NNNN](NNNN-title.md) | Rejected] +{startsb}Proposed | Accepted | Deprecated | Superseded by link:NNNN-title.md[ADR-NNNN] | Rejected{endsb} -## Context +== Context What is the issue that we're seeing that is motivating this decision or change? -## Decision +== Decision What is the change that we're proposing and/or doing? -## Consequences +== Consequences What becomes easier or more difficult to do because of this change? -### Positive +=== Positive - ... -### Negative +=== Negative - ... -### Neutral +=== Neutral - ... diff --git a/docs/decisions/0001-adopt-rsr-standard.adoc b/docs/decisions/0001-adopt-rsr-standard.adoc index 178057d..7e12646 100644 --- a/docs/decisions/0001-adopt-rsr-standard.adoc +++ b/docs/decisions/0001-adopt-rsr-standard.adoc @@ -1,16 +1,14 @@ -= Architecture Decision Record: 0001-adopt-rsr-standard - - - -# 1. Adopt Rhodium Standard Repository (RSR) Template +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) += 1. Adopt Rhodium Standard Repository (RSR) Template Date: 2026-02-14 -## Status +== Status Accepted -## Context +== Context Managing multiple repositories with an ad-hoc approach led to significant inconsistencies across the ecosystem. Common problems included: @@ -27,7 +25,7 @@ inconsistencies across the ecosystem. Common problems included: Without a single source of truth for repository structure, each new repo required manual setup and inevitably drifted from best practices over time. -## Decision +== Decision Adopt the Rhodium Standard Repository (RSR) template (`rsr-template-repo`) as the canonical starting point for all new repositories. Existing repositories @@ -50,15 +48,16 @@ The RSR template provides: New repositories are created by cloning the template: -```bash +[source,bash] +---- git clone https://github.com/hyperpolymath/rsr-template-repo new-repo-name cd new-repo-name rm -rf .git && git init -``` +---- -## Consequences +== Consequences -### Positive +=== Positive - Consistency across all repositories, enforced from creation - Automated compliance checking via `rsr-antipattern.yml` workflow @@ -69,7 +68,7 @@ rm -rf .git && git init - Reduced maintenance burden: fix once in template, propagate to all repos - Machine-readable state enables tooling and automation pipelines -### Negative +=== Negative - Migration effort for existing repos requires time and attention - Learning curve for contributors unfamiliar with RSR conventions @@ -77,7 +76,7 @@ rm -rf .git && git init - Some repos may have unique needs that do not fit the standard template without customization -### Neutral +=== Neutral - Existing CI/CD pipelines continue to work; RSR workflows are additive - Third-party dependencies retain their original licenses regardless of diff --git a/docs/developer/ABI-FFI-README.adoc b/docs/developer/ABI-FFI-README.adoc index d93f3b5..ea58de8 100644 --- a/docs/developer/ABI-FFI-README.adoc +++ b/docs/developer/ABI-FFI-README.adoc @@ -1,9 +1,7 @@ -= ABI/FFI Standards += the-nash-equilibrium ABI/FFI Documentation {{~ Aditionally delete this line and fill out the template below ~}} -# the-nash-equilibrium ABI/FFI Documentation - -## Overview +== Overview This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: @@ -12,9 +10,9 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: - **Generated C headers** bridge Idris2 ABI to Zig FFI - **Any language** can call through standard C ABI -## Architecture +== Architecture -``` +---- ┌─────────────────────────────────────────────┐ │ ABI Definitions (Idris2) │ │ src/abi/ │ @@ -46,11 +44,11 @@ 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-nash-equilibrium/ ├── src/ │ ├── abi/ # ABI definitions (Idris2) @@ -78,15 +76,16 @@ the-nash-equilibrium/ ├── 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: -```idris +[source,idris] +---- -- Prove struct size is correct public export exampleStructSize : HasSize ExampleStruct 16 @@ -98,13 +97,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 @@ -112,13 +112,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 @@ -126,13 +127,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 { @@ -141,71 +143,78 @@ 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 +=== Generate C Header from Idris2 ABI -```bash +[source,bash] +---- cd src/abi idris2 --cg c-header Types.idr -o ../../generated/abi/the-nash-equilibrium.h -``` +---- -### Cross-Compile +=== Cross-Compile -```bash +[source,bash] +---- cd ffi/zig # Linux x86_64 @@ -216,13 +225,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 "the-nash-equilibrium.h" int main() { @@ -238,16 +248,18 @@ int main() { the-nash-equilibrium_free(handle); return 0; } -``` +---- Compile with: -```bash +[source,bash] +---- gcc -o example example.c -lthe-nash-equilibrium -L./zig-out/lib -``` +---- -### From Idris2 +=== From Idris2 -```idris +[source,idris] +---- import the-nash-equilibrium.ABI.Foreign main : IO () @@ -260,11 +272,12 @@ main = do free handle putStrLn "Success" -``` +---- -### From Rust +=== From Rust -```rust +[source,rust] +---- #[link(name = "the-nash-equilibrium")] extern "C" { fn the-nash-equilibrium_init() -> *mut std::ffi::c_void; @@ -283,11 +296,12 @@ fn main() { the-nash-equilibrium_free(handle); } } -``` +---- -### From Julia +=== From Julia -```julia +[source,julia] +---- const libthe-nash-equilibrium = "libthe-nash-equilibrium" function init() @@ -313,27 +327,30 @@ 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) +=== ABI Verification (Idris2) -```idris +[source,idris] +---- -- Compile-time verification %runElab verifyABI @@ -343,9 +360,9 @@ main = do verifyLayoutsCorrect verifyAlignmentsCorrect putStrLn "ABI verification passed" -``` +---- -## Contributing +== Contributing When modifying the ABI/FFI: @@ -355,9 +372,10 @@ When modifying the ABI/FFI: - Ensure backward compatibility 2. **Generate C header** - ```bash + [source,bash] + ---- idris2 --cg c-header src/abi/Types.idr -o generated/abi/the-nash-equilibrium.h - ``` + ---- 3. **Update FFI implementation** (`ffi/zig/src/main.zig`) - Implement new functions @@ -373,12 +391,12 @@ When modifying the ABI/FFI: - Usage examples - Migration guide (if breaking changes) -## License +== License AGPL-3.0-or-later -## 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) +- link:https://idris2.readthedocs.io[Idris2 Documentation] +- link:https://ziglang.org/documentation/master/[Zig Documentation] +- link:https://github.com/hyperpolymath/rhodium-standard-repositories[Rhodium Standard Repositories] diff --git a/docs/governance/MAINTENANCE-CHECKLIST.adoc b/docs/governance/MAINTENANCE-CHECKLIST.adoc index 1160797..d3707db 100644 --- a/docs/governance/MAINTENANCE-CHECKLIST.adoc +++ b/docs/governance/MAINTENANCE-CHECKLIST.adoc @@ -1,5 +1,4 @@ -= Maintenance Checklist -# Maintenance Checklist (Cross-Repo) += Maintenance Checklist (Cross-Repo) Use this as a repeatable maintenance runbook for any repo. @@ -8,125 +7,125 @@ Companion policy: - `docs/practice/SOFTWARE-DEVELOPMENT-APPROACH.adoc` (human-readable) - `.machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml` (machine-readable) -## Canonical Repo Baseline (Final) +== Canonical Repo Baseline (Final) Apply this baseline to every repo unless an explicit exception is recorded. -### Three-Axis Default Model +=== Three-Axis Default Model -- [ ] Axis 1 (scope priority, runs first): `must > intend > like` -- [ ] Axis 2 (maintenance priority): `corrective > adaptive > perfective` -- [ ] Axis 3 (audit priority): `systems > compliance > effects` -- [ ] Perfective items are derived from Axis 1 honest state (not started independently). +* [ ] Axis 1 (scope priority, runs first): `must > intend > like` +* [ ] Axis 2 (maintenance priority): `corrective > adaptive > perfective` +* [ ] Axis 3 (audit priority): `systems > compliance > effects` +* [ ] Perfective items are derived from Axis 1 honest state (not started independently). -### Axis 1 Scoping Pass (Mandatory) +=== Axis 1 Scoping Pass (Mandatory) Before Axis 2/3 execution, assemble a scoped worklist from evidence: -- [ ] Read and reconcile: `README`, roadmap, status docs, maintenance checklist, and current CI/security docs. -- [ ] Scan for unfinished markers: `TODO`, `FIXME`, `XXX`, `HACK`, `STUB`, `PARTIAL`. -- [ ] If Idris is present, scan unsoundness markers: `believe_me`, `assert_total`. -- [ ] Identify declared intent vs actual implementation (docs honesty check). -- [ ] Produce a scope assembly artifact with prioritized entries under: +* [ ] Read and reconcile: `README`, roadmap, status docs, maintenance checklist, and current CI/security docs. +* [ ] Scan for unfinished markers: `TODO`, `FIXME`, `XXX`, `HACK`, `STUB`, `PARTIAL`. +* [ ] If Idris is present, scan unsoundness markers: `believe_me`, `assert_total`. +* [ ] Identify declared intent vs actual implementation (docs honesty check). +* [ ] Produce a scope assembly artifact with prioritized entries under: - `must` (release blockers / safety / correctness) - `intend` (planned near-term) - `like` (nice-to-have) -### Axis 2 Maintenance Execution Rules +=== Axis 2 Maintenance Execution Rules -- [ ] Corrective first: fix breakage, defects, regressions, safety issues. -- [ ] Adaptive second: reconcile changed scope, remove stale references, cull no-longer-relevant work. -- [ ] Perfective third: only from current honest state established by Axis 1 and updated by corrective/adaptive actions. +* [ ] Corrective first: fix breakage, defects, regressions, safety issues. +* [ ] Adaptive second: reconcile changed scope, remove stale references, cull no-longer-relevant work. +* [ ] Perfective third: only from current honest state established by Axis 1 and updated by corrective/adaptive actions. -### Axis 3 Audit Rules +=== Axis 3 Audit Rules -- [ ] Verify systems are in place and actually operating. -- [ ] Verify documentation explains the real/current state (not aspirational-only), including documented exceptions. -- [ ] Verify safety and security controls are present, active, and evidenced. -- [ ] Verify observed effects/impacts are captured and reviewed. -- [ ] Effects audit includes: +* [ ] Verify systems are in place and actually operating. +* [ ] Verify documentation explains the real/current state (not aspirational-only), including documented exceptions. +* [ ] Verify safety and security controls are present, active, and evidenced. +* [ ] Verify observed effects/impacts are captured and reviewed. +* [ ] Effects audit includes: - benchmark execution and recorded results (with before/after where relevant) - explicit maintainer dialogue/status review on what changed, why, and next risks -- [ ] Audit compliance seams/compromises explicitly: +* [ ] Audit compliance seams/compromises explicitly: - policy exceptions are recorded with rationale, scope, and expiry/review - exception does not silently broaden into general policy drift - language-policy contamination checks run (example: a single TS exception must not trigger broad TypeScript conversion) - run `panic-attack` as the compliance-audit scanner - run ecological checking under effects (using sustainabot guidance as current baseline) -### Generic Cleanup And Finish-Off Pass +=== Generic Cleanup And Finish-Off Pass Run this pass at the end of a corrective/adaptive/perfective cycle: -- [ ] Root cleanup: +* [ ] Root cleanup: - keep only required control/entry files in root - move non-essential docs/reports/fixtures to canonical folders -- [ ] Remove or archive stale work: +* [ ] Remove or archive stale work: - close out completed TODO/STUB/PARTIAL items - cull obsolete references, dead files, and superseded plans -- [ ] Documentation finish-off: +* [ ] Documentation finish-off: - ensure README, roadmap, status, and wiki match actual implementation state - ensure machine-readable policy/state files match human docs -- [ ] Security/compliance finish-off: +* [ ] Security/compliance finish-off: - run compliance scanner (`panic-attack`) and resolve high-priority findings - verify exception register and seams/compromises are explicitly bounded -- [ ] Effects finish-off: +* [ ] Effects finish-off: - run benchmark/effects checks and record evidence - conduct explicit maintainer review dialogue (what changed, why, remaining risks) -- [ ] Release-prep finish-off: +* [ ] Release-prep finish-off: - produce Must/Should/Could summary - produce immediate corrective/adaptive/perfective next-actions list -### Must +=== Must -- [ ] Keep required control files at repository root: +* [ ] Keep required control files at repository root: - `.gitignore`, `.gitattributes`, `.editorconfig`, `.tool-versions` - `Containerfile` - `.containerignore` (or `.dockerignore` only when required for compatibility) - `CNAME` and `.nojekyll` when using GitHub Pages/custom domain - `Justfile` (root by convention) -- [ ] Keep ownership/governance files present: +* [ ] Keep ownership/governance files present: - `MAINTAINER` in root - `.github/CODEOWNERS` -- [ ] Keep machine-readable canonical structure under `.machine_readable/`: +* [ ] Keep machine-readable canonical structure under `.machine_readable/`: - state/meta/ecosystem files (`*.a2ml` or repo standard) - `anchors/ANCHOR.a2ml` - `contractiles/` (`must`, `trust`, `lust`, and related) - `ai/` for AI guidance files - `bot_directives/` for bot control files -- [ ] Keep contractiles/invariants present and wired: +* [ ] Keep contractiles/invariants present and wired: - root `Mustfile` (or equivalent) with enforceable checks - `Trustfile` and `Intentfile` present -- [ ] Keep security metadata present: +* [ ] Keep security metadata present: - `.well-known/security.txt` and relevant policy metadata - CI security scanning configured and runnable -- [ ] Keep docs and navigation coherent: +* [ ] Keep docs and navigation coherent: - single navigation entry point in root (`NAVIGATION.adoc` or equivalent) - no duplicate conflicting docs for same purpose (for example both `.md` and `.adoc` in root unless intentionally required) -- [ ] Enforce ABI/FFI purity where the policy applies: +* [ ] Enforce ABI/FFI purity where the policy applies: - ABI definitions in Idris2 (`src/abi/*.idr`) - FFI implementations in Zig (`ffi/**/*.zig`) -- [ ] Ensure quality gate includes: formatting, lint, unit/integration tests, p2p/e2e checks, benchmark smoke, docs checks, security scan. +* [ ] Ensure quality gate includes: formatting, lint, unit/integration tests, p2p/e2e checks, benchmark smoke, docs checks, security scan. -### Should +=== Should -- [ ] Keep human docs primarily in AsciiDoc (`.adoc`) except where ecosystem rules require other formats (GitHub/community health, legal text, tool-specific files). -- [ ] Keep non-essential root files moved into structured folders: +* [ ] Keep human docs primarily in AsciiDoc (`.adoc`) except where ecosystem rules require other formats (GitHub/community health, legal text, tool-specific files). +* [ ] Keep non-essential root files moved into structured folders: - `docs/` (theory/practice/whitepapers/proofs/reports) - `tests/` (fixtures/outputs) - `docs/legal/` (while retaining root `LICENSE` when forge detection needs it) -- [ ] Maintain `.well-known/` for public metadata where applicable (`security.txt`, `humans.txt`, `ads.txt` mirrors if used). -- [ ] Keep CI policy checks for doc-format conventions and canonical file placement. -- [ ] Keep roadmap/status docs honest with dated evidence. +* [ ] Maintain `.well-known/` for public metadata where applicable (`security.txt`, `humans.txt`, `ads.txt` mirrors if used). +* [ ] Keep CI policy checks for doc-format conventions and canonical file placement. +* [ ] Keep roadmap/status docs honest with dated evidence. -### Could +=== Could -- [ ] Maintain both human and machine views of maintenance policy from a single source (generate one from the other). -- [ ] Add policy bots for corrective/adaptive/perfective/audit modes. -- [ ] Add repo-level architecture map (`TOPOLOGY.md`) and release-readiness dashboards. -- [ ] Add per-repo exception registry for approved policy deviations. +* [ ] Maintain both human and machine views of maintenance policy from a single source (generate one from the other). +* [ ] Add policy bots for corrective/adaptive/perfective/audit modes. +* [ ] Add repo-level architecture map (`TOPOLOGY.md`) and release-readiness dashboards. +* [ ] Add per-repo exception registry for approved policy deviations. -### Explicit Root-Placement Rule +=== Explicit Root-Placement Rule Do **not** move the following out of root if you want default tool behavior: @@ -135,7 +134,7 @@ Do **not** move the following out of root if you want default tool behavior: - `CNAME` and `.nojekyll` for GitHub Pages - `Justfile` -## Quick Automated Run (Script) +== Quick Automated Run (Script) Use the helper script first, then use the checklist for deeper/manual follow-up. @@ -143,14 +142,16 @@ Script locations: - `${REPOS_ROOT:-~/Documents/hyperpolymath-repos}/run-maintenance.sh` - `~/Desktop/run-maintenance.sh` -```bash +[source,bash] +---- ~/Desktop/run-maintenance.sh --repo /absolute/path/to/repo --output /tmp/maintenance-report.json jq . /tmp/maintenance-report.json -``` +---- Useful flags: -```bash +[source,bash] +---- # Strict mode: fail process on failed checks ~/Desktop/run-maintenance.sh --repo /absolute/path/to/repo --strict @@ -162,7 +163,7 @@ Useful flags: # Release hard-pass mode (fails on warnings or failures) ~/Desktop/run-maintenance.sh --repo /absolute/path/to/repo --fail-on-warn -``` +---- Permission policy in script: - Flags `g+w/o+w` files/dirs @@ -181,183 +182,199 @@ Important git behavior: - Permission hardening audits do not force collaborators to re-unlock every file on pull. - Keep lock mode opt-in, with restore path documented. -```bash +[source,bash] +---- # Audit-only (recommended default) ~/Desktop/run-maintenance.sh --repo /absolute/path/to/repo # Opt-in permission fixes (review output before commit) ~/Desktop/run-maintenance.sh --repo /absolute/path/to/repo --fix-perms -``` +---- -## 0) Setup +== 0) Setup -```bash +[source,bash] +---- REPO="/absolute/path/to/repo" cd "$REPO" -``` +---- -```bash +[source,bash] +---- date -u git rev-parse --abbrev-ref HEAD git rev-parse HEAD git status --porcelain -``` +---- -## 1) Preflight +== 1) Preflight -- [ ] Confirm clean intent: note existing unrelated dirty files before edits. -- [ ] Confirm runtime/toolchain versions. -- [ ] Confirm container mode expectation (`podman`/`podman-compose`) if required. +* [ ] Confirm clean intent: note existing unrelated dirty files before edits. +* [ ] Confirm runtime/toolchain versions. +* [ ] Confirm container mode expectation (`podman`/`podman-compose`) if required. -```bash +[source,bash] +---- command -v rg git jq || true command -v podman podman-compose || true -``` +---- -## 2) Dependency/Env Prereqs +== 2) Dependency/Env Prereqs -- [ ] Python deps in active interpreter (for Python paths). -- [ ] Language-specific tooling installed. +* [ ] Python deps in active interpreter (for Python paths). +* [ ] Language-specific tooling installed. -```bash +[source,bash] +---- python -c "import sys; print(sys.executable)" python -c "import pydantic; print(pydantic.__version__)" || echo "pydantic missing" -``` +---- -## 3) Corrective Maintenance First +== 3) Corrective Maintenance First -- [ ] Fix regressions, runtime errors, panics, broken commands, failing tests. -- [ ] Re-run failing checks immediately after each fix. +* [ ] Fix regressions, runtime errors, panics, broken commands, failing tests. +* [ ] Re-run failing checks immediately after each fix. -## 4) Code Health Scans +== 4) Code Health Scans -- [ ] `TODO/FIXME/XXX/HACK/STUB/PARTIAL` scan. -- [ ] Permission policy scan (`g+w/o+w`, executable hygiene). -- [ ] ABI/FFI policy scan (if applicable: Idris2 ABI, Zig FFI). +* [ ] `TODO/FIXME/XXX/HACK/STUB/PARTIAL` scan. +* [ ] Permission policy scan (`g+w/o+w`, executable hygiene). +* [ ] ABI/FFI policy scan (if applicable: Idris2 ABI, Zig FFI). -```bash +[source,bash] +---- rg -n "TODO|FIXME|XXX|HACK|STUB|PARTIAL" -g '!**/.git/**' -g '!**/target/**' . -``` +---- -```bash +[source,bash] +---- # Optional per-repo exceptions (regex per line): # .maintenance-perms-ignore # ^vendor/ # ^third_party/ -``` +---- -```bash +[source,bash] +---- # Adjust paths for your repo layout find . -type f \( -name '*.idr' -o -name '*.idris2' -o -name '*.zig' \) -``` +---- -## 5) Panic/Safety/Security Pass +== 5) Panic/Safety/Security Pass -- [ ] Run `panic-attacker` assail/assault. -- [ ] Triage findings by severity. -- [ ] Fix high first, then medium. -- [ ] Re-run until acceptable. +* [ ] Run `panic-attacker` assail/assault. +* [ ] Triage findings by severity. +* [ ] Fix high first, then medium. +* [ ] Re-run until acceptable. -```bash +[source,bash] +---- PANIC_BIN="${REPOS_ROOT:-~/Documents/hyperpolymath-repos}/panic-attacker/target/release/panic-attack" "$PANIC_BIN" assail "$REPO" --output /tmp/assail.json --output-format json --quiet jq -r '.weak_points | length' /tmp/assail.json jq -r '.weak_points[] | "\(.severity)|\(.location)|\(.description)"' /tmp/assail.json -``` +---- -```bash +[source,bash] +---- # If repo has production-only source builder, prefer this for baseline checks: ./scripts/ci/build-panic-assail-source.sh /tmp/panic-src "$PANIC_BIN" assail /tmp/panic-src --output /tmp/assail-prod.json --output-format json --quiet -``` +---- -## 6) Language-Specific Validation +== 6) Language-Specific Validation -### Rust +=== Rust -- [ ] Format -- [ ] Lint -- [ ] Tests -- [ ] Doc tests -- [ ] Benches (where relevant) +* [ ] Format +* [ ] Lint +* [ ] Tests +* [ ] Doc tests +* [ ] Benches (where relevant) -```bash +[source,bash] +---- cargo fmt --all --check cargo clippy --workspace --all-targets -- -D warnings cargo test --workspace cargo test --workspace --doc # Optional targeted benchmarks: cargo bench -``` +---- -### Python +=== Python -- [ ] Format/lint -- [ ] Type check -- [ ] Tests +* [ ] Format/lint +* [ ] Type check +* [ ] Tests -```bash +[source,bash] +---- ruff check . ruff format --check . mypy . pytest -q -``` +---- -### Elixir +=== Elixir -- [ ] Format check -- [ ] Lint/static checks -- [ ] Tests +* [ ] Format check +* [ ] Lint/static checks +* [ ] Tests -```bash +[source,bash] +---- mix format --check-formatted mix credo --strict mix test -``` +---- -## 7) Container/Runtime Checks (Podman) +== 7) Container/Runtime Checks (Podman) -- [ ] Build container path. -- [ ] Run smoke tests inside containerized flow. -- [ ] Compare host vs container behavior for parity. +* [ ] Build container path. +* [ ] Run smoke tests inside containerized flow. +* [ ] Compare host vs container behavior for parity. -```bash +[source,bash] +---- podman --version podman compose version || podman-compose --version -``` +---- -## 8) Benchmark + Regression Check +== 8) Benchmark + Regression Check -- [ ] Capture before/after metrics for touched hot paths. -- [ ] Record command + sample size + output. -- [ ] Fail change if critical path regresses beyond threshold. +* [ ] Capture before/after metrics for touched hot paths. +* [ ] Record command + sample size + output. +* [ ] Fail change if critical path regresses beyond threshold. -## 9) Adaptive and Perfective Maintenance +== 9) Adaptive and Perfective Maintenance -- [ ] Adaptive: compatibility updates (tooling/API/deprecations/config flags). -- [ ] Perfective: clarity, docs parity, developer workflow improvements. -- [ ] Update roadmap/checklist/docs to match actual implementation state. +* [ ] Adaptive: compatibility updates (tooling/API/deprecations/config flags). +* [ ] Perfective: clarity, docs parity, developer workflow improvements. +* [ ] Update roadmap/checklist/docs to match actual implementation state. -## 10) Final QA and Release Hygiene +== 10) Final QA and Release Hygiene -- [ ] Re-run full relevant checks one final time. -- [ ] Confirm no unintended file changes. -- [ ] Commit scoped changes with clear message. -- [ ] Push and capture commit SHA. +* [ ] Re-run full relevant checks one final time. +* [ ] Confirm no unintended file changes. +* [ ] Commit scoped changes with clear message. +* [ ] Push and capture commit SHA. -```bash +[source,bash] +---- git status --short git diff --stat git add git commit -m "maint: " git push -``` +---- -## 11) Maintenance Report Template +== 11) Maintenance Report Template Copy this block per repo run: -```text +[source,text] +---- Repo: Branch: Start UTC: @@ -401,92 +418,93 @@ Commit(s): Remaining Risks / Follow-ups: 1. 2. -``` +---- -## 12) Language-Repo Additions (Eclexia-Specific) +== 12) Language-Repo Additions (Eclexia-Specific) Add these checks for language/compiler repositories with formal ABI/FFI constraints: -- [x] README structure restored (index/TOC, audience paths, quickstart sanity). -- [x] Wiki split by audience (laypeople/users/developers) and linked from docs index. -- [x] Root-level clutter reduced (archive, analysis, reports relegated to `docs/` subtrees). -- [x] Machine-readable docs synchronized (`STATE.a2ml`, `META.a2ml`, `ECOSYSTEM.a2ml`, contractiles). -- [x] Human-readable docs synchronized (`README`, `QUICK_STATUS`, roadmap, wiki home). -- [x] `Mustfile` invariants present and enforceable in CI. -- [x] `Trustfile` and `Intentfile` present and complete. -- [x] FFI/ABI purity policy enforced (`*.zig` for FFI, `*.idr`/Idris2 for ABI). -- [x] `panic-attack` findings triaged with explicit severity budget for release. -- [x] Point-to-point, end-to-end, and benchmark checks wired in one quality gate. -- [x] CI workflows include quality + security + docs checks with explicit policy. -- [x] Release audit includes corrective/adaptive/perfective + Must/Should/Could. -- [x] Roadmap/status honesty pass completed (dates and current evidence updated). - -## 13) Latest Execution Record (Eclexia, 2026-02-24) +* [x] README structure restored (index/TOC, audience paths, quickstart sanity). +* [x] Wiki split by audience (laypeople/users/developers) and linked from docs index. +* [x] Root-level clutter reduced (archive, analysis, reports relegated to `docs/` subtrees). +* [x] Machine-readable docs synchronized (`STATE.a2ml`, `META.a2ml`, `ECOSYSTEM.a2ml`, contractiles). +* [x] Human-readable docs synchronized (`README`, `QUICK_STATUS`, roadmap, wiki home). +* [x] `Mustfile` invariants present and enforceable in CI. +* [x] `Trustfile` and `Intentfile` present and complete. +* [x] FFI/ABI purity policy enforced (`*.zig` for FFI, `*.idr`/Idris2 for ABI). +* [x] `panic-attack` findings triaged with explicit severity budget for release. +* [x] Point-to-point, end-to-end, and benchmark checks wired in one quality gate. +* [x] CI workflows include quality + security + docs checks with explicit policy. +* [x] Release audit includes corrective/adaptive/perfective + Must/Should/Could. +* [x] Roadmap/status honesty pass completed (dates and current evidence updated). + +== 13) Latest Execution Record (Eclexia, 2026-02-24) Repo: `/tmp/eclexia-releaseprep` (branch `release-prep`, base `533ec9e9447f374135cc9e2e81021624ddb3c0ad`) -### 13.1 Setup/Preflight +=== 13.1 Setup/Preflight -- [x] Captured UTC timestamp and git state. -- [x] Tooling presence verified (`rg`, `git`, `jq`, `cargo`, `rustc`, `just`). -- [x] Runtime/toolchain versions captured. -- [x] Container tooling checked (`podman`, `podman-compose`). +* [x] Captured UTC timestamp and git state. +* [x] Tooling presence verified (`rg`, `git`, `jq`, `cargo`, `rustc`, `just`). +* [x] Runtime/toolchain versions captured. +* [x] Container tooling checked (`podman`, `podman-compose`). -### 13.2 Corrective Maintenance +=== 13.2 Corrective Maintenance -- [x] Fixed `panic-attack` script path handling (`mktemp` output + local fallback binary detection). -- [x] Removed Idris `believe_me` usage from ABI wrappers. -- [x] Fixed conformance crash-noise path by skipping known intentional stack-overflow case in default runner. -- [x] Re-ran affected checks after each fix. +* [x] Fixed `panic-attack` script path handling (`mktemp` output + local fallback binary detection). +* [x] Removed Idris `believe_me` usage from ABI wrappers. +* [x] Fixed conformance crash-noise path by skipping known intentional stack-overflow case in default runner. +* [x] Re-ran affected checks after each fix. -### 13.3 Code-Health Scans +=== 13.3 Code-Health Scans -- [x] TODO/FIXME/STUB/PARTIAL scan run on active code paths. -- [x] ABI/FFI file inventory run (`*.idr`, `*.zig`). -- [x] Active-code marker count reduced/triaged; remaining items tracked in release audit. +* [x] TODO/FIXME/STUB/PARTIAL scan run on active code paths. +* [x] ABI/FFI file inventory run (`*.idr`, `*.zig`). +* [x] Active-code marker count reduced/triaged; remaining items tracked in release audit. -### 13.4 Security/Panic Pass +=== 13.4 Security/Panic Pass -- [x] `panic-attack` run and triaged. -- [x] Critical findings cleared (Idris unsoundness markers removed). -- [x] Current baseline: 0 weak points (Critical 0, High 0, Medium 0, Low 0). -- [x] High/Medium backlog fully eliminated. +* [x] `panic-attack` run and triaged. +* [x] Critical findings cleared (Idris unsoundness markers removed). +* [x] Current baseline: 0 weak points (Critical 0, High 0, Medium 0, Low 0). +* [x] High/Medium backlog fully eliminated. -### 13.5 Language Validation +=== 13.5 Language Validation -- [x] Final `just quality-gate` pass completed (docs, fmt, lint, unit, conformance, integration, p2p, e2e, bench). -- [x] Additional targeted reruns completed (`just test-conformance`, `just panic-attack`, `just docs-check`). +* [x] Final `just quality-gate` pass completed (docs, fmt, lint, unit, conformance, integration, p2p, e2e, bench). +* [x] Additional targeted reruns completed (`just test-conformance`, `just panic-attack`, `just docs-check`). -### 13.6 Adaptive/Perfective/Docs +=== 13.6 Adaptive/Perfective/Docs -- [x] README/wiki/docs structure and indexing restored. -- [x] Root tidy/relegation pass executed. -- [x] Roadmap/status honesty update performed with current date and evidence links. -- [x] Release audit created with corrective/adaptive/perfective + Must/Should/Could. -- [x] Full quality-gate rerun passed after hardening updates. -- [x] ABI/FFI extension lane added without breaking stable symbols (`ecl_abi_get_info`, `ecl_tracker_create_ex`, `ecl_tracker_snapshot`). -- [x] CI quality workflow now validates sibling `proven` repo presence and critical binding files. -- [x] Proven roadmap now includes explicit "critical core, not full rewrite" adoption guidance and flowchart. +* [x] README/wiki/docs structure and indexing restored. +* [x] Root tidy/relegation pass executed. +* [x] Roadmap/status honesty update performed with current date and evidence links. +* [x] Release audit created with corrective/adaptive/perfective + Must/Should/Could. +* [x] Full quality-gate rerun passed after hardening updates. +* [x] ABI/FFI extension lane added without breaking stable symbols (`ecl_abi_get_info`, `ecl_tracker_create_ex`, `ecl_tracker_snapshot`). +* [x] CI quality workflow now validates sibling `proven` repo presence and critical binding files. +* [x] Proven roadmap now includes explicit "critical core, not full rewrite" adoption guidance and flowchart. -### 13.7 Outstanding Items (Explicit) +=== 13.7 Outstanding Items (Explicit) -- [x] Stable `v1.0.0` technical gate readiness met (quality + panic scan clean). -- [x] Parser/codegen/runtime panic-path hardening completed for scanner-flagged paths. -- [x] Non-eclexia `proven` library checked: already Idris2-first with Zig ABI bridge; no additional integration changes required in this run. -- [ ] Remote push blocked by token scope: GitHub rejected branch updates (`release-prep`, `release-prep-pushable`) due missing `workflow` OAuth scope. +* [x] Stable `v1.0.0` technical gate readiness met (quality + panic scan clean). +* [x] Parser/codegen/runtime panic-path hardening completed for scanner-flagged paths. +* [x] Non-eclexia `proven` library checked: already Idris2-first with Zig ABI bridge; no additional integration changes required in this run. +* [ ] Remote push blocked by token scope: GitHub rejected branch updates (`release-prep`, `release-prep-pushable`) due missing `workflow` OAuth scope. -### 13.8 Artifacts +=== 13.8 Artifacts - Release audit: `docs/reports/V1-READINESS-AUDIT-2026-02-24.md` - Panic report: `/tmp/eclexia-panic-attack.KZ1jpC.json` (0 weak points) - Final quality gate log: `/tmp/eclexia-quality-gate-final2.log` (plus post-change reruns via terminal sessions) - Local commits: `88fa2af` (`release-prep`), `baa3d1c` (`release-prep-pushable`) + pending new commit from this pass -## 12) LLM Operator Instructions +== 12) LLM Operator Instructions Use this prompt with an LLM agent when you want the process run end-to-end: -```text +[source,text] +---- Run the maintenance workflow for this repo using MAINTENANCE-CHECKLIST.md. Required behavior: @@ -508,13 +526,14 @@ Constraints: - Do not revert unrelated existing dirty changes. - Stage and commit only scoped intended files. - If blocked, state exactly what is blocked and why. -``` +---- -## 13) AI Execution Integrity Contract (Mandatory) +== 13) AI Execution Integrity Contract (Mandatory) Use this when delegating maintenance to any AI (Gemini/Claude/ChatGPT/etc.). -```text +[source,text] +---- You must execute this maintenance run with strict integrity. Non-negotiable rules: @@ -537,33 +556,37 @@ Non-negotiable rules: - unresolved risks - exact next actions 10. Prioritize user safety and reputation: no “looks fine” claims without evidence. -``` +---- Recommended enforcement line for AI prompts: -```text +[source,text] +---- Fail closed: if evidence is missing for any checklist item, treat that item as NOT DONE. -``` +---- -## 14) Fleet Enrollment Automation (Gitbot + Hypatia) +== 14) Fleet Enrollment Automation (Gitbot + Hypatia) For centralized coverage across existing and new repos: -```bash +[source,bash] +---- cd ${REPOS_ROOT:-~/Documents/hyperpolymath-repos}/gitbot-fleet just enroll-repos -``` +---- Optional directive write-back to repos that already have `.machine_readable/`: -```bash +[source,bash] +---- cd ${REPOS_ROOT:-~/Documents/hyperpolymath-repos}/gitbot-fleet just enroll-repos /var$REPOS_DIR true -``` +---- Release hard gate from fleet: -```bash +[source,bash] +---- cd ${REPOS_ROOT:-~/Documents/hyperpolymath-repos}/gitbot-fleet just maintenance-hard-pass /absolute/path/to/repo -``` +---- diff --git a/docs/practice/AI-CONVENTIONS.adoc b/docs/practice/AI-CONVENTIONS.adoc index 23196be..29210a0 100644 --- a/docs/practice/AI-CONVENTIONS.adoc +++ b/docs/practice/AI-CONVENTIONS.adoc @@ -1,13 +1,11 @@ -= AI Conventions - - - -# AI Conventions (Authoritative Source) +// SPDX-License-Identifier: CC-BY-SA-4.0 +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) += 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 +== Session Startup 1. Read `0-AI-MANIFEST.a2ml` FIRST (mandatory gatekeeper). 2. Read `.machine_readable/STATE.a2ml` for current status and blockers. @@ -17,7 +15,7 @@ Per-tool config files (.cursorrules, .clinerules, etc.) reference this document. 6. Read `.machine_readable/policies/SOFTWARE-DEVELOPMENT-APPROACH.a2ml` for execution order. 7. Read `.machine_readable/AGENTIC.a2ml` for agent constraints. -## License +== License - All original code: **AGPL-3.0-or-later** - Fallback (platform-required only): MPL-2.0 with comment explaining why. @@ -25,56 +23,86 @@ Per-tool config files (.cursorrules, .clinerules, etc.) reference this document. - Preserve third-party licenses verbatim. - Every source file needs `# SPDX-License-Identifier: CC-BY-SA-4.0`. -## Author Attribution +== 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 Files State/metadata files, anchors, and policies (.a2ml) belong in `.machine_readable/` ONLY. NEVER create STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml, AGENTIC.a2ml, NEUROSYM.a2ml, PLAYBOOK.a2ml, ANCHOR.a2ml, MAINTENANCE-AXES.a2ml, MAINTENANCE-CHECKLIST.a2ml, or SOFTWARE-DEVELOPMENT-APPROACH.a2ml in the repository root. -## Banned Patterns +== Banned Patterns + +[cols="1,1,1",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="1,1",options="header"] +|=== +| Banned | Use Instead + +| TypeScript +| ReScript -| 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 | +| Node.js / npm / bun +| Deno -## Banned Languages +| Go +| Rust -| Banned | Use Instead | -|---------------------|--------------------| -| TypeScript | ReScript | -| Node.js / npm / bun | Deno | -| Go | Rust | -| Python | Julia / Rust | +| Python +| Julia / Rust +|=== -## Container Standard +== 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 +== ABI/FFI Standard - ABI definitions: **Idris2** with dependent types (`src/abi/`). - FFI implementation: **Zig** with C ABI compatibility (`ffi/zig/`). - Generated C headers: `generated/abi/`. -## Build System +== Build System Use `just` (Justfile) for all build, test, lint, and format tasks. -## References +== References - `0-AI-MANIFEST.a2ml` -- universal AI entry point - `.machine_readable/AGENTIC.a2ml` -- agent permissions and constraints diff --git a/scripts/check-adoc-not-markdown.sh b/scripts/check-adoc-not-markdown.sh new file mode 100755 index 0000000..fb8548f --- /dev/null +++ b/scripts/check-adoc-not-markdown.sh @@ -0,0 +1,134 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: MPL-2.0 +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) +# +# check-adoc-not-markdown.sh — an .adoc must be AsciiDoc, not Markdown wearing +# an .adoc extension. +# +# This is the third leg of the docs gate. The other two do not catch this: +# +# check-no-md-in-docs.sh — extension: is the file named .adoc? +# check-docs-render.sh — render: does asciidoctor parse it? +# check-adoc-not-markdown.sh — dialect: is the *body* actually AsciiDoc? +# +# The gap this closes is real, not theoretical. Eight files were committed as a +# `= Title` line bolted onto an unmodified Markdown body. They passed the +# extension check (named .adoc) and Asciidoctor's Markdown-compat mode rendered +# `##` headings and ``` fences without complaint — so they read as "clean" while +# their SPDX headers rendered as visible body text and their tables rendered as +# garbage. +# +# Flagged as Markdown (each renders wrong, or is the wrong dialect): +# ATX `## Heading` -> AsciiDoc `== Heading`. A `#` H1 parses as a +# *level-0* section; a second one is a hard error +# ("level 0 sections can only be used when +# doctype is book"). +# FENCE ```lang -> `[source,lang]` + `----` +# HTML -> `// comment`. HTML comments are NOT comments in +# AsciiDoc; they render as literal visible text. +# LINK [text](url) -> `link:url[text]` / `xref:file.adoc[text]`. +# Renders as literal text otherwise. +# TABLE |---|---| -> `[cols=...]` + `|===`. Renders as garbage. +# TASK - [ ] item -> `* [ ] item` (AsciiDoc checklist syntax). +# +# NOT flagged (all valid AsciiDoc, despite looking Markdown-ish): +# `**bold**` — unconstrained bold +# `-` bullets — a valid list marker +# `> quote` — a valid blockquote +# `* [ ]` tasks — the correct checklist form +# anything inside a delimited block (----, ...., ====, ++++, ****, ////), +# so shell `# comments` in a listing block are not mistaken for headings. +# +# Exit codes: +# 0 — every .adoc is genuine AsciiDoc +# 1 — one or more contain Markdown syntax +# 2 — usage / setup error + +set -euo pipefail + +REPO_ROOT="${1:-.}" + +if [ ! -d "$REPO_ROOT" ]; then + echo "FAIL: not a directory: $REPO_ROOT" >&2 + exit 2 +fi + +# Quarantine for pre-existing offenders. Empty is the goal, and it is currently +# empty — keep it that way. Do not add a file here to make a red build green. +ALLOWED=() + +mapfile -t FILES < <(find "$REPO_ROOT" -name '*.adoc' -type f -not -path '*/.git/*' | sort) + +if [ ${#FILES[@]} -eq 0 ]; then + echo "PASS: no .adoc files found (nothing to check)" + exit 0 +fi + +DETECT=' +BEGIN { inblock = 0; delim = "" } +{ + line = $0 + + # Delimited block open/close: 4+ of the delimiter char alone on the line. + if (line ~ /^(-{4,}|\.{4,}|={4,}|\+{4,}|\*{4,}|\/{4,})[ \t]*$/) { + d = substr(line, 1, 1) + if (inblock && d == delim) { inblock = 0; delim = "" } + else if (!inblock) { inblock = 1; delim = d } + next + } + + # A Markdown fence is itself a finding, and it also opens a block whose + # contents must not be scanned. + if (line ~ /^[ \t]*```/) { + if (inblock && delim == "`") { inblock = 0; delim = "" } + else if (!inblock) { inblock = 1; delim = "`" + emit("FENCE", "```lang -> [source,lang] + ----") } + next + } + + if (inblock) next + + if (line ~ /^#{1,6} /) emit("ATX", "## Heading -> == Heading") + if (line ~ / -> // c (renders as visible text!)") + if (line ~ /\[[^]]+\]\([^)]+\)/) emit("LINK", "[t](url) -> link:url[t] (renders as literal text!)") + if (line ~ /^\|[-: |]*-{3,}[-: |]*$/) emit("TABLE", "|---|---| -> [cols=...] + |===") + if (line ~ /^[ \t]*[-+] \[[ xX]\]/) emit("TASK", "- [ ] -> * [ ]") +} +function emit(kind, hint) { + printf "%s\t%d\t%s\t%s\t%s\n", FILENAME, FNR, kind, hint, substr(line, 1, 72) +} +' + +TMPOUT="$(mktemp)" +trap 'rm -f "$TMPOUT"' EXIT + +for f in "${FILES[@]}"; do + rel="${f#"$REPO_ROOT/"}" + rel="${rel#./}" + + skip=0 + for allowed in ${ALLOWED[@]+"${ALLOWED[@]}"}; do + if [ "$rel" = "$allowed" ]; then skip=1; break; fi + done + [ $skip -eq 1 ] && continue + + if awk "$DETECT" "$f" >> "$TMPOUT" 2>/dev/null; then :; fi +done + +if [ ! -s "$TMPOUT" ]; then + echo "PASS: ${#FILES[@]} .adoc files are genuine AsciiDoc (no Markdown syntax)" + exit 0 +fi + +FOUND=$(wc -l < "$TMPOUT") +NFILES=$(cut -f1 "$TMPOUT" | sort -u | wc -l) + +echo "FAIL: $FOUND instance(s) of Markdown syntax in $NFILES .adoc file(s):" >&2 +echo "" >&2 +while IFS=$'\t' read -r file lineno kind hint text; do + printf ' %s:%s [%s]\n %s\n fix: %s\n' \ + "${file#./}" "$lineno" "$kind" "$text" "$hint" >&2 +done < "$TMPOUT" +echo "" >&2 +echo "An .adoc file must be AsciiDoc, not Markdown renamed. Convert the body." >&2 +exit 1 diff --git a/scripts/check-docs-render.sh b/scripts/check-docs-render.sh index 5d757ab..344f14b 100755 --- a/scripts/check-docs-render.sh +++ b/scripts/check-docs-render.sh @@ -24,19 +24,14 @@ set -euo pipefail REPO_ROOT="${1:-.}" -# Quarantined: half-converted Markdown carrying an .adoc extension (a `= Title` -# line bolted onto a Markdown body — `#` headings, comments, | tables). -# These satisfy check-no-md-in-docs.sh by extension while still being Markdown. -# All are RSR boilerplate, not game design. Fix by converting the body properly, -# then delete the entry. Do not add game-design docs to this list. -ALLOWED=( - "docs/architecture/THREAT-MODEL.adoc" - "docs/decisions/0000-template.adoc" - "docs/decisions/0001-adopt-rsr-standard.adoc" - "docs/developer/ABI-FFI-README.adoc" - "docs/practice/AI-CONVENTIONS.adoc" - "docs/STATE-VISUALIZER.adoc" -) +# Quarantine for files that cannot yet be made to render. It is empty, and an +# empty list is the goal — do not add a file here to turn a red build green. +# +# It previously held six half-converted files (a `= Title` bolted onto a +# Markdown body). All six were converted to real AsciiDoc and removed from this +# list; the dialect that put them here is now blocked at source by +# check-adoc-not-markdown.sh. +ALLOWED=() if ! command -v asciidoctor >/dev/null 2>&1; then echo "FAIL: asciidoctor not found. Install with: gem install asciidoctor" >&2 @@ -64,7 +59,10 @@ for f in "${FILES[@]}"; do rel="${rel#./}" skip=0 - for allowed in "${ALLOWED[@]}"; do + # ${a[@]+"${a[@]}"} — expanding an empty array under `set -u` is an error + # on bash < 4.4 (still shipped by macOS). ALLOWED is empty and should stay + # that way, so this guard is load-bearing. + for allowed in ${ALLOWED[@]+"${ALLOWED[@]}"}; do if [ "$rel" = "$allowed" ]; then skip=1; break; fi done if [ $skip -eq 1 ]; then