diff --git a/.devcontainer/Containerfile b/.devcontainer/Containerfile index 24f9f41..17f4e09 100644 --- a/.devcontainer/Containerfile +++ b/.devcontainer/Containerfile @@ -1,9 +1,9 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # -# Dev Container image for {{PROJECT_NAME}} +# Dev Container image for knot-rider # Base: Chainguard Wolfi (minimal, supply-chain-secure) -# Build: podman build -t {{PROJECT_NAME}}-dev -f .devcontainer/Containerfile . +# Build: podman build -t knot-rider-dev -f .devcontainer/Containerfile . # `:latest` suits a dev container (rebuilt daily); pin by digest # (...@sha256:) if you need a reproducible dev environment. @@ -26,7 +26,7 @@ RUN groupadd -g 1000 nonroot || true \ && useradd -m -u 1000 -g 1000 -s /bin/bash nonroot || true # Set workspace directory -WORKDIR /workspaces/{{PROJECT_NAME}} +WORKDIR /workspaces/knot-rider # Default shell ENV SHELL=/bin/bash diff --git a/.devcontainer/README.adoc b/.devcontainer/README.adoc index 5eee18b..169e044 100644 --- a/.devcontainer/README.adoc +++ b/.devcontainer/README.adoc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell = Dev Container Usage -:author: {{AUTHOR}} <{{AUTHOR_EMAIL}}> +:author: Jonathan D.A. Jewell == Overview @@ -25,4 +25,4 @@ This dev container uses `cgr.dev/chainguard/wolfi-base` with git, curl, bash, an == Customization -Replace `{{PROJECT_NAME}}` placeholders in both `devcontainer.json` and `Containerfile` with your actual project name. Run `just deps` to verify the environment after first launch. +Replace `knot-rider` placeholders in both `devcontainer.json` and `Containerfile` with your actual project name. Run `just deps` to verify the environment after first launch. diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json index a4b33e0..9ad0644 100644 --- a/.devcontainer/devcontainer.json +++ b/.devcontainer/devcontainer.json @@ -1,11 +1,11 @@ // SPDX-License-Identifier: MPL-2.0 -// Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +// Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) // -// Dev Container configuration for {{PROJECT_NAME}} +// Dev Container configuration for knot-rider // Works with: VS Code Dev Containers, GitHub Codespaces, Gitpod // Container runtime: Podman (recommended) or any OCI-compliant runtime { - "name": "{{PROJECT_NAME}}", + "name": "knot-rider", "build": { "dockerfile": "Containerfile", diff --git a/.envrc b/.envrc index 99e5508..1d0ad23 100644 --- a/.envrc +++ b/.envrc @@ -13,7 +13,7 @@ if has guix && [ -f guix.scm ]; then fi # Project environment variables -export PROJECT_NAME="{{PROJECT_NAME}}" +export PROJECT_NAME="knot-rider" export RSR_TIER="infrastructure" # Add non-secret project env vars above (e.g. DATABASE_URL, service endpoints). # Real secrets belong in .env (gitignored) — never commit them to .envrc. diff --git a/.github/.mailmap b/.github/.mailmap index 0ada9de..b47a9b9 100644 --- a/.github/.mailmap +++ b/.github/.mailmap @@ -1 +1 @@ -{{AUTHOR}} <{{AUTHOR_EMAIL}}> <{{AUTHOR_EMAIL_ALT}}> +Jonathan D.A. Jewell diff --git a/.github/CODEOWNERS b/.github/CODEOWNERS index 611b5a8..8d339b7 100644 --- a/.github/CODEOWNERS +++ b/.github/CODEOWNERS @@ -2,13 +2,13 @@ # CODEOWNERS - Define code review assignments # See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/about-code-owners # -# Replace {{OWNER}} with your GitHub username or team +# Replace hyperpolymath with your GitHub username or team # Default owners for everything -* @{{OWNER}} +* @hyperpolymath # Security-sensitive files require explicit review -SECURITY.md @{{OWNER}} -.github/workflows/ @{{OWNER}} -Trustfile.a2ml @{{OWNER}} -.machine_readable/ @{{OWNER}} +SECURITY.md @hyperpolymath +.github/workflows/ @hyperpolymath +Trustfile.a2ml @hyperpolymath +.machine_readable/ @hyperpolymath diff --git a/.github/CODE_OF_CONDUCT.md b/.github/CODE_OF_CONDUCT.md index 287e86a..7c915f2 100644 --- a/.github/CODE_OF_CONDUCT.md +++ b/.github/CODE_OF_CONDUCT.md @@ -4,29 +4,14 @@ Copyright (c) Jonathan D.A. Jewell --> # Code of Conduct - +> **Note:** This is a single-maintainer repository. The enforcement ladder +> below is kept as-written from the RSR community-health template for +> consistency across the estate; in practice reports go straight to the +> maintainer. ## Our Pledge -We as members, contributors, and leaders pledge to make participation in {{PROJECT_NAME}} 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 as members, contributors, and leaders pledge to make participation in knot-rider 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. @@ -140,7 +125,7 @@ If you experience or witness unacceptable behaviour, or have any other concerns, | Method | Details | Best For | |--------|---------|----------| -| **Email** | {{CONDUCT_EMAIL}} | Detailed reports, sensitive matters | +| **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 | @@ -156,8 +141,8 @@ If you experience or witness unacceptable behaviour, or have any other concerns, **What Happens Next** -1. You will receive acknowledgment within **{{RESPONSE_TIME}}** -2. The {{CONDUCT_TEAM}} will review the report +1. You will receive acknowledgment within **5 business days** +2. The maintainer 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) @@ -173,7 +158,7 @@ All reports will be handled with discretion: ### Conflicts of Interest -If a {{CONDUCT_TEAM}} member is involved in an incident: +If the maintainer is involved in an incident: - They will recuse themselves from the process - Another maintainer or external party will handle the report @@ -183,7 +168,7 @@ If a {{CONDUCT_TEAM}} member is involved in an incident: ## Enforcement Guidelines -The {{CONDUCT_TEAM}} will follow these guidelines in determining consequences: +The maintainer will follow these guidelines in determining consequences: ### 1. Correction @@ -235,13 +220,13 @@ For contributors with elevated access (Perimeter 2 or 1): If you believe an enforcement decision was made in error: 1. **Wait 7 days** after the decision (cooling-off period) -2. **Email** {{CONDUCT_EMAIL}} with subject line "Appeal: [Original Report ID]" +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 {{CONDUCT_TEAM}} member than the original +- Appeals are reviewed by a different maintainer than the original, if one is available - You will receive a response within 14 days - The appeals decision is final - You may only appeal once per incident @@ -314,8 +299,8 @@ We thank these communities for their leadership in creating welcoming spaces. If you have questions about this Code of Conduct: -- Open a [Discussion](https://{{FORGE}}/{{OWNER}}/{{REPO}}/discussions) (for general questions) -- Email {{CONDUCT_EMAIL}} (for private questions) +- Open a [Discussion](https://github.com/hyperpolymath/knot-rider/discussions) (for general questions) +- Email j.d.a.jewell@open.ac.uk (for private questions) - Contact any maintainer directly --- @@ -328,4 +313,4 @@ We're all here because we care about this project. Let's make it a place where e --- -Last updated: {{CURRENT_YEAR}} · Based on Contributor Covenant 2.1 +Last updated: 2026 · Based on Contributor Covenant 2.1 diff --git a/.github/CONTRIBUTING.md b/.github/CONTRIBUTING.md index 56222bd..8e521e2 100644 --- a/.github/CONTRIBUTING.md +++ b/.github/CONTRIBUTING.md @@ -3,15 +3,15 @@ SPDX-License-Identifier: CC-BY-SA-4.0 Copyright (c) Jonathan D.A. Jewell --> # Clone the repository -git clone https://{{FORGE}}/{{OWNER}}/{{REPO}}.git -cd {{REPO}} +git clone https://github.com/hyperpolymath/knot-rider.git +cd knot-rider # Using Guix (recommended for reproducibility) guix shell -D -f guix.scm # Or using toolbox/distrobox -toolbox create {{REPO}}-dev -toolbox enter {{REPO}}-dev +toolbox create knot-rider-dev +toolbox enter knot-rider-dev # Install dependencies manually # Verify setup @@ -21,7 +21,7 @@ just test # Run test suite ### Repository Structure ``` -{{REPO}}/ +knot-rider/ ├── src/ # Source code (Perimeter 1-2) ├── lib/ # Library code (Perimeter 1-2) ├── extensions/ # Extensions (Perimeter 2) @@ -61,7 +61,7 @@ just test # Run test suite **Before reporting**: 1. Search existing issues -2. Check if it's already fixed in `{{MAIN_BRANCH}}` +2. Check if it's already fixed in `main` 3. Determine which perimeter the bug affects **When reporting**: @@ -94,10 +94,10 @@ Use the [feature request template](.github/ISSUE_TEMPLATE/feature_request.md) an Look for issues labelled: -- [`good first issue`](https://{{FORGE}}/{{OWNER}}/{{REPO}}/labels/good%20first%20issue) — Simple Perimeter 3 tasks -- [`help wanted`](https://{{FORGE}}/{{OWNER}}/{{REPO}}/labels/help%20wanted) — Community help needed -- [`documentation`](https://{{FORGE}}/{{OWNER}}/{{REPO}}/labels/documentation) — Docs improvements -- [`perimeter-3`](https://{{FORGE}}/{{OWNER}}/{{REPO}}/labels/perimeter-3) — Community sandbox scope +- [`good first issue`](https://github.com/hyperpolymath/knot-rider/labels/good%20first%20issue) — Simple Perimeter 3 tasks +- [`help wanted`](https://github.com/hyperpolymath/knot-rider/labels/help%20wanted) — Community help needed +- [`documentation`](https://github.com/hyperpolymath/knot-rider/labels/documentation) — Docs improvements +- [`perimeter-3`](https://github.com/hyperpolymath/knot-rider/labels/perimeter-3) — Community sandbox scope --- diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index c078261..688a442 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,7 +1,7 @@ # SPDX-License-Identifier: MPL-2.0 -# Funding platforms for {{OWNER}} projects +# Funding platforms for hyperpolymath projects # See: https://docs.github.com/en/repositories/managing-your-repositorys-settings-and-features/customizing-your-repository/displaying-a-sponsor-button-in-your-repository -github: {{OWNER}} -ko_fi: {{OWNER}} -liberapay: {{OWNER}} +github: hyperpolymath +ko_fi: hyperpolymath +liberapay: hyperpolymath diff --git a/.github/GOVERNANCE.md b/.github/GOVERNANCE.md index 14c9c55..43d3013 100644 --- a/.github/GOVERNANCE.md +++ b/.github/GOVERNANCE.md @@ -4,13 +4,13 @@ Copyright (c) Jonathan D.A. Jewell --> # Project Governance -This document describes the governance model for **{{PROJECT_NAME}}**. +This document describes the governance model for **knot-rider**. --- ## Project Governance Model -{{PROJECT_NAME}} follows a **Benevolent Dictator For Life (BDFL)** governance model. +knot-rider 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. @@ -157,4 +157,4 @@ with the community before adoption, even though the BDFL retains final authority --- -Copyright (c) {{CURRENT_YEAR}} {{OWNER}}. Licensed under MPL-2.0. +Copyright (c) 2026 hyperpolymath. Licensed under MPL-2.0. diff --git a/.github/MAINTAINERS b/.github/MAINTAINERS index 145c4e9..63989c7 100644 --- a/.github/MAINTAINERS +++ b/.github/MAINTAINERS @@ -4,7 +4,7 @@ # Format: Name (role) # Replace placeholders with actual maintainer information. -{{AUTHOR}} <{{AUTHOR_EMAIL}}> (Lead Maintainer) +Jonathan D.A. Jewell (Lead Maintainer) # Additional maintainers: # Name (role) diff --git a/.github/SECURITY.md b/.github/SECURITY.md index 11588ca..2b42a84 100644 --- a/.github/SECURITY.md +++ b/.github/SECURITY.md @@ -4,24 +4,6 @@ Copyright (c) Jonathan D.A. Jewell --> # 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 @@ -44,7 +26,7 @@ We take security seriously. We appreciate your efforts to responsibly disclose v The preferred method for reporting security vulnerabilities is through GitHub's Security Advisory feature: -1. Navigate to [Report a Vulnerability](https://github.com/{{OWNER}}/{{REPO}}/security/advisories/new) +1. Navigate to [Report a Vulnerability](https://github.com/hyperpolymath/knot-rider/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 @@ -56,26 +38,11 @@ This method ensures: - Coordinated disclosure tooling - Automatic credit when the advisory is published -### Alternative: Encrypted Email - -If you cannot use GitHub Security Advisories, you may email us directly: - -| | | -|---|---| -| **Email** | {{SECURITY_EMAIL}} | -| **PGP Key** | [Download Public Key]({{PGP_KEY_URL}}) | -| **Fingerprint** | `{{PGP_FINGERPRINT}}` | +### Alternative: Email -```bash -# Import our PGP key -curl -sSL {{PGP_KEY_URL}} | gpg --import - -# Verify fingerprint -gpg --fingerprint {{SECURITY_EMAIL}} - -# Encrypt your report -gpg --armor --encrypt --recipient {{SECURITY_EMAIL}} report.txt -``` +If you cannot use GitHub Security Advisories, you may email j.d.a.jewell@open.ac.uk +directly. No PGP key is currently published for this repository — plain email +is the only alternative channel. > **⚠️ Important:** Do not report security vulnerabilities through public GitHub issues, pull requests, discussions, or social media. @@ -207,7 +174,7 @@ If we cannot reach agreement on disclosure timing, we default to 90 days from yo The following are within scope for security research: -- This repository (`{{OWNER}}/{{REPO}}`) and all its code +- This repository (`hyperpolymath/knot-rider`) 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 @@ -326,7 +293,7 @@ Recognition includes: 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/{{OWNER}}/{{REPO}}/security/advisories) +- **GitHub Security Advisories**: Published at [Security Advisories](https://github.com/hyperpolymath/knot-rider/security/advisories) - **Release notes**: Security fixes noted in [CHANGELOG](CHANGELOG.md) ### Update Policy @@ -352,7 +319,7 @@ To stay informed about security updates: ## Security Best Practices -When using {{PROJECT_NAME}}, we recommend: +When using knot-rider, we recommend: ### General @@ -374,8 +341,7 @@ When using {{PROJECT_NAME}}, we recommend: ## Additional Resources -- [Our PGP Public Key]({{PGP_KEY_URL}}) -- [Security Advisories](https://github.com/{{OWNER}}/{{REPO}}/security/advisories) +- [Security Advisories](https://github.com/hyperpolymath/knot-rider/security/advisories) - [Changelog](CHANGELOG.md) - [Contributing Guidelines](CONTRIBUTING.md) - [CVE Database](https://cve.mitre.org/) @@ -387,9 +353,9 @@ When using {{PROJECT_NAME}}, we recommend: | Purpose | Contact | |---------|---------| -| **Security issues** | [Report via GitHub](https://github.com/{{OWNER}}/{{REPO}}/security/advisories/new) or {{SECURITY_EMAIL}} | -| **General questions** | [GitHub Discussions](https://github.com/{{OWNER}}/{{REPO}}/discussions) | -| **Other enquiries** | See [README](README.md) for contact information | +| **Security issues** | [Report via GitHub](https://github.com/hyperpolymath/knot-rider/security/advisories/new) or j.d.a.jewell@open.ac.uk | +| **General questions** | [GitHub Discussions](https://github.com/hyperpolymath/knot-rider/discussions) | +| **Other enquiries** | See [README](README.adoc) for contact information | --- @@ -403,8 +369,8 @@ This security policy may be updated from time to time. Significant changes will --- -*Thank you for helping keep {{PROJECT_NAME}} and its users safe.* 🛡️ +*Thank you for helping keep knot-rider and its users safe.* 🛡️ --- -Last updated: {{CURRENT_YEAR}} · Policy version: 1.0.0 +Last updated: 2026 · Policy version: 1.0.0 diff --git a/.github/SUPPORT b/.github/SUPPORT index b06c59a..ac37fa2 100644 --- a/.github/SUPPORT +++ b/.github/SUPPORT @@ -2,6 +2,6 @@ For questions, help, and community discussion: -- GitHub Discussions: https://github.com/{{OWNER}}/{{REPO}}/discussions -- GitHub Issues: https://github.com/{{OWNER}}/{{REPO}}/issues +- GitHub Discussions: https://github.com/hyperpolymath/knot-rider/discussions +- GitHub Issues: https://github.com/hyperpolymath/knot-rider/issues - Documentation: See README.adoc in the root directory. diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 7048f63..1cf2861 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -2,7 +2,7 @@ SPDX-License-Identifier: CC-BY-SA-4.0 Copyright (c) Jonathan D.A. Jewell --> - + # Copilot Instructions @@ -16,7 +16,7 @@ Copyright (c) Jonathan D.A. Jewell - SPDX: `MPL-2.0` on all new files. - Never use AGPL-3.0. -- Copyright: `{{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}>` +- Copyright: `Jonathan D.A. Jewell (hyperpolymath) ` ## Code Style diff --git a/.github/settings.yml b/.github/settings.yml index 92306c4..7e4a800 100644 --- a/.github/settings.yml +++ b/.github/settings.yml @@ -7,14 +7,12 @@ # applied by the probot/settings app when changes are pushed to the default # branch. Install the app at: https://github.com/apps/settings # -# Template file — replace {{REPO}} and {{DESCRIPTION}} with actual values. - # ─── Repository Settings ─────────────────────────────────────────────────────── repository: - name: "{{REPO}}" - description: "{{DESCRIPTION}}" - homepage: "https://github.com/hyperpolymath/{{REPO}}" + name: "knot-rider" + description: "A shadowy flight into the dangerous world of a man, who is either permanently or very often undone by circumstance." + homepage: "https://github.com/hyperpolymath/knot-rider" private: false has_issues: true has_projects: true diff --git a/.github/workflows/container-build.yml b/.github/workflows/container-build.yml index 3e07a89..4533315 100644 --- a/.github/workflows/container-build.yml +++ b/.github/workflows/container-build.yml @@ -47,7 +47,7 @@ jobs: - name: Scan image (trivy, best-effort) run: | if command -v trivy >/dev/null 2>&1; then - trivy image --severity HIGH,CRITICAL --exit-code 0 {{project}}:latest || true + trivy image --severity HIGH,CRITICAL --exit-code 0 knot-rider:latest || true else echo "trivy not installed on this runner — skipping image scan" fi diff --git a/.machine_readable/6a2/CLADE.a2ml b/.machine_readable/6a2/CLADE.a2ml index b14389c..6264f45 100644 --- a/.machine_readable/6a2/CLADE.a2ml +++ b/.machine_readable/6a2/CLADE.a2ml @@ -6,8 +6,8 @@ uuid = "a5ea1382-a34c-5334-8a46-a2ebe904c810" primary-forge = "github" primary-owner = "hyperpolymath" -canonical-name = "rsr-template-repo" -prefixed-name = "rm-rsr-template-repo" +canonical-name = "knot-rider" +prefixed-name = "rm-knot-rider" [clade] primary = "rm" @@ -16,9 +16,9 @@ assigned = "2026-03-16" rationale = "" [forges] -github = "hyperpolymath/rsr-template-repo" -gitlab = "hyperpolymath/rsr-template-repo" -bitbucket = "hyperpolymath/rsr-template-repo" +github = "hyperpolymath/knot-rider" +gitlab = "hyperpolymath/knot-rider" +bitbucket = "hyperpolymath/knot-rider" [lineage] type = "standalone" diff --git a/.machine_readable/6a2/ECOSYSTEM.a2ml b/.machine_readable/6a2/ECOSYSTEM.a2ml index 0757418..cbf4910 100644 --- a/.machine_readable/6a2/ECOSYSTEM.a2ml +++ b/.machine_readable/6a2/ECOSYSTEM.a2ml @@ -1,45 +1,31 @@ # SPDX-License-Identifier: MPL-2.0 -# ECOSYSTEM.a2ml — Ecosystem position (META-TEMPLATE) +# ECOSYSTEM.a2ml — Ecosystem position # -# This is the ECOSYSTEM file for rsr-template-repo itself. It records the -# TEMPLATE's own position in the estate. When consumed by a new project, -# replace these fields with the target project's ecosystem position and -# related projects (see the NOTE FOR CONSUMERS at the bottom). +# knot-rider was scaffolded from rsr-template-repo. Its specific technical +# purpose has not been implemented or documented anywhere in this repository +# or the wider hyperpolymath estate registry — see README.adoc. [metadata] -project = "rsr-template-repo" +project = "knot-rider" ecosystem = "hyperpolymath" [position] -type = "repository-template" -purpose = "Canonical RSR-compliant repository template: scaffolding (CI/CD, AI manifests, ABI/FFI standards, container ecosystem, governance) that new hyperpolymath projects are instantiated from." -# IS-NOT — anti-identity (the boundary-erosion guard; each line is a real past confusion) -what-this-is-not = [ - "a project in its own right", - "Scaffoldia (the full-featured repo designer)", - "standards (the canon source this template operationalises)", -] +type = "unknown" +purpose = "RSR-scaffolded repository named knot-rider. GitHub's description is a Knight-Rider-intro pun, per README.adoc. No specific technical purpose is implemented or documented beyond that." +# IS-NOT — anti-identity (the boundary-erosion guard) +what-this-is-not = [] [pipeline] -position = "foundation" -chain = "standards → rsr-template-repo → (every estate repo)" -notes = "rsr-template-repo turns the RSR standard into runnable scaffolding. New repos are created from it via `just init`, which substitutes the {{PLACEHOLDER}} tokens." -coordination = "standards" +position = "unknown" +chain = "unknown" +notes = "This repo's place in any estate pipeline is not yet documented." +coordination = "unknown" [related-projects] -projects = [ - { name = "standards", relationship = "standard-source", notes = "Defines the RSR standard, contractile canon, and policies that this template operationalises." }, - { name = "stapeln", relationship = "build-tooling", notes = "Layer-based container build system; the template ships stapeln.toml scaffolding." }, - { name = "selur-compose", relationship = "build-tooling", notes = "Service composition; the template ships selur-compose.toml scaffolding." }, - { name = "k9-svc", relationship = "validation-tooling", notes = "Runs the self-validating k9.ncl checks (.machine_readable/self-validating/)." }, - { name = "cerro-torre", relationship = "signing-tooling", notes = "Container/image signing provider referenced by the container scaffolding." }, - { name = "svalinn", relationship = "verification-tooling", notes = "Supply-chain verification referenced by the container scaffolding." }, - { name = "vordr", relationship = "verification-tooling", notes = "Build/artifact verification referenced by the container scaffolding." }, -] +projects = [] # --------------------------------------------------------------------------- -# NOTE FOR CONSUMERS: When using this template to create a new repo, replace -# the project/purpose above and rewrite [related-projects] to describe YOUR -# project's actual ecosystem. The entries above describe the TEMPLATE's own -# position, not yours. +# NOTE: this file previously described rsr-template-repo's own position +# (uninstantiated leftover from scaffolding). Fixed 2026-07-27. If this +# project's actual ecosystem position becomes known, update the fields above. # --------------------------------------------------------------------------- diff --git a/.machine_readable/6a2/STATE.a2ml b/.machine_readable/6a2/STATE.a2ml index 3d2d647..c08b42a 100644 --- a/.machine_readable/6a2/STATE.a2ml +++ b/.machine_readable/6a2/STATE.a2ml @@ -1,49 +1,44 @@ # SPDX-License-Identifier: MPL-2.0 # Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # -# STATE.a2ml — Project state checkpoint (META-TEMPLATE) +# STATE.a2ml — Project state checkpoint # -# This is the STATE file for rsr-template-repo itself. -# When consumed by a new project, replace {{PLACEHOLDER}} tokens -# and customize sections below for the target project. +# knot-rider was scaffolded from rsr-template-repo on 2026-03-16 but never +# instantiated (all {{PLACEHOLDER}} tokens survived, including in the .zig +# sources, which meant the Zig genuinely did not parse). Fixed 2026-07-27: +# identity placeholders substituted, template machinery removed, Justfile +# stubs wired to real commands, Zig FFI seam made to build and test clean. +# The project's specific technical purpose remains undocumented. [metadata] -project = "rsr-template-repo" -version = "0.2.0" -last-updated = "2026-02-28" +project = "knot-rider" +version = "0.1.0" +last-updated = "2026-07-27" status = "active" # active | paused | archived [project-context] -name = "rsr-template-repo" -purpose = "Canonical RSR-compliant repository template providing scaffolding for all hyperpolymath projects — including CI/CD, AI manifests, ABI/FFI standards, container ecosystem, and governance infrastructure." -completion-percentage = 95 +name = "knot-rider" +purpose = "Not yet documented — see README.adoc" +completion-percentage = 0 [position] -phase = "maintenance" # design | implementation | testing | maintenance | archived -maturity = "production" # experimental | alpha | beta | production | lts +phase = "design" # design | implementation | testing | maintenance | archived +maturity = "experimental" # experimental | alpha | beta | production | lts [route-to-mvp] milestones = [ - { name = "Phase 0: Core scaffolding (justfile, CI/CD, .machine_readable)", completion = 100 }, - { name = "Phase 1: ABI/FFI standard (Idris2/Zig templates)", completion = 100 }, - { name = "Phase 1b: AI Gatekeeper Protocol (0-AI-MANIFEST.a2ml)", completion = 100 }, - { name = "Phase 1c: TOPOLOGY.md standard and guide", completion = 100 }, - { name = "Phase 1d: Maintenance gate (axes, checklist, approach)", completion = 100 }, - { name = "Phase 1e: Trustfile / contractiles", completion = 100 }, - { name = "Phase 2: Container ecosystem templates (stapeln)", completion = 100 }, - { name = "Phase 3: Multi-forge sync hardening", completion = 0 }, - { name = "Phase 4: Guix reproducible shells", completion = 50 }, + { name = "Cure RSR template instantiation (identity, Justfile, Zig FFI build)", completion = 100 }, + { name = "Define what this project actually does", completion = 0 }, ] [blockers-and-issues] -# No active blockers +# Blocked on: the project's technical purpose is undocumented anywhere in +# this repository or the wider hyperpolymath estate registry. [critical-next-actions] actions = [ - "Container templates complete — test with `just container-init`", - "Validate container templates across wolfi-base and static Chainguard images", - "Harden multi-forge sync for GitLab/Bitbucket mirroring edge cases", - "Expand Guix development shell templates", + "Define what this project actually does — the RSR scaffolding is now sound but there is no project-specific implementation", + "Update README.adoc / ECOSYSTEM.a2ml / ANCHOR.a2ml once a purpose is known", ] [maintenance-status] @@ -54,11 +49,11 @@ open-warnings = 0 open-failures = 0 [ecosystem] -part-of = ["RSR Framework", "stapeln ecosystem"] -depends-on = ["stapeln", "selur-compose", "cerro-torre", "svalinn", "vordr", "k9-svc"] +part-of = [] +depends-on = [] # --------------------------------------------------------------------------- -# NOTE FOR CONSUMERS: When using this template to create a new repo, reset -# the fields above to your project's values and replace all {{PLACEHOLDER}} -# tokens. The milestones above describe the TEMPLATE's evolution, not yours. +# NOTE: this file previously described rsr-template-repo's own development +# state (uninstantiated leftover from scaffolding, including a false "95% +# complete / production" maturity claim). Fixed 2026-07-27. # --------------------------------------------------------------------------- diff --git a/.machine_readable/6a2/anchors/ANCHOR.a2ml b/.machine_readable/6a2/anchors/ANCHOR.a2ml index 8723899..2168f94 100644 --- a/.machine_readable/6a2/anchors/ANCHOR.a2ml +++ b/.machine_readable/6a2/anchors/ANCHOR.a2ml @@ -1,15 +1,15 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # ANCHOR.a2ml - authoritative anchor for this repository [metadata] version = "1.0.0" -last-updated = "{{CURRENT_DATE}}" +last-updated = "2026-07-27" [anchor] schema = "hyperpolymath.anchor/1" -repo = "{{OWNER}}/{{REPO}}" +repo = "hyperpolymath/knot-rider" authority = "upstream-canonical" purpose = [ @@ -19,10 +19,10 @@ purpose = [ ] [identity] -project = "{{PROJECT_NAME}}" -kind = "{{PROJECT_KIND}}" # language | library | service | tool -one-sentence = "{{PROJECT_PURPOSE}}" -domain = "{{PROJECT_DOMAIN}}" +project = "knot-rider" +kind = "unknown" # language | library | service | tool +one-sentence = "Not yet documented — see README.adoc" +domain = "unknown" [semantic-authority] policy = "canonical" diff --git a/.machine_readable/ENSAID_CONFIG.a2ml b/.machine_readable/ENSAID_CONFIG.a2ml index 1384822..c5c8852 100644 --- a/.machine_readable/ENSAID_CONFIG.a2ml +++ b/.machine_readable/ENSAID_CONFIG.a2ml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # ENSAID_CONFIG.a2ml — eNSAID Environment Configuration # Per-repo configuration for PanLL and eNSAID-compatible tools. @@ -89,8 +89,8 @@ version = "1.0.0" # Example: a custom portfolio for this project # [[portfolios.custom]] -# id = "{{project}}-dev" -# name = "{{PROJECT_NAME}} Development" -# description = "Panels for {{PROJECT_NAME}} development" +# id = "knot-rider-dev" +# name = "knot-rider Development" +# description = "Panels for knot-rider development" # panels = ["valence-shell", "editor-bridge", "build-dashboard"] # default-isolation = "native" diff --git a/.machine_readable/ai/.clinerules b/.machine_readable/ai/.clinerules index 8f38042..4818351 100644 --- a/.machine_readable/ai/.clinerules +++ b/.machine_readable/ai/.clinerules @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # Authoritative source: docs/AI-CONVENTIONS.md # STARTUP: Read 0-AI-MANIFEST.a2ml first, then .machine_readable/6a2/STATE.a2ml. @@ -8,7 +8,7 @@ # All original code: MPL-2.0. # Never AGPL-3.0. MPL-2.0 only as platform-required fallback. # SPDX header required on every source file. -# Copyright: {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright: Jonathan D.A. Jewell (hyperpolymath) # STATE FILES (.machine_readable/ ONLY) # Never create in repo root: STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml, diff --git a/.machine_readable/ai/.cursorrules b/.machine_readable/ai/.cursorrules index c13b393..5255a80 100644 --- a/.machine_readable/ai/.cursorrules +++ b/.machine_readable/ai/.cursorrules @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # Authoritative source: docs/AI-CONVENTIONS.md # Read 0-AI-MANIFEST.a2ml in the repo root FIRST for canonical file locations. @@ -7,7 +7,7 @@ # LICENSE # All original code: MPL-2.0 (SPDX header required on every file). # Never use AGPL-3.0. Fallback to MPL-2.0 only when platform requires it. -# Copyright: {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright: Jonathan D.A. Jewell (hyperpolymath) # STATE FILES # .a2ml metadata files go in .machine_readable/ ONLY. diff --git a/.machine_readable/ai/.windsurfrules b/.machine_readable/ai/.windsurfrules index 8f38042..4818351 100644 --- a/.machine_readable/ai/.windsurfrules +++ b/.machine_readable/ai/.windsurfrules @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # Authoritative source: docs/AI-CONVENTIONS.md # STARTUP: Read 0-AI-MANIFEST.a2ml first, then .machine_readable/6a2/STATE.a2ml. @@ -8,7 +8,7 @@ # All original code: MPL-2.0. # Never AGPL-3.0. MPL-2.0 only as platform-required fallback. # SPDX header required on every source file. -# Copyright: {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright: Jonathan D.A. Jewell (hyperpolymath) # STATE FILES (.machine_readable/ ONLY) # Never create in repo root: STATE.a2ml, META.a2ml, ECOSYSTEM.a2ml, diff --git a/.machine_readable/ai/PLACEHOLDERS.adoc b/.machine_readable/ai/PLACEHOLDERS.adoc deleted file mode 100644 index 2a80900..0000000 --- a/.machine_readable/ai/PLACEHOLDERS.adoc +++ /dev/null @@ -1,144 +0,0 @@ -// SPDX-License-Identifier: CC-BY-SA-4.0 -// Copyright (c) Jonathan D.A. Jewell -= 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 - -```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/{{AUTHOR}}/Jane Doe/g' $(grep -rl '{{AUTHOR}}' .) -sed -i 's/{{AUTHOR_EMAIL}}/jane@example.org/g' $(grep -rl '{{AUTHOR_EMAIL}}' .) -sed -i 's/{{OWNER}}/my-org/g' $(grep -rl '{{OWNER}}' .) -sed -i 's/{{PROJECT_NAME}}/my-project/g' $(grep -rl '{{PROJECT_NAME}}' .) -sed -i 's/{{PROJECT}}/MY_PROJECT/g' $(grep -rl '{{PROJECT}}' .) -sed -i 's/{{project}}/my_project/g' $(grep -rl '{{project}}' .) -sed -i 's/{{REPO}}/my-project/g' $(grep -rl '{{REPO}}' .) -sed -i 's/{{FORGE}}/github.com/g' $(grep -rl '{{FORGE}}' .) -sed -i "s/{{CURRENT_YEAR}}/$(date +%Y)/g" $(grep -rl '{{CURRENT_YEAR}}' .) -sed -i "s/{{CURRENT_DATE}}/$(date +%Y-%m-%d)/g" $(grep -rl '{{CURRENT_DATE}}' .) -``` - -## Placeholder Reference - -### Author & Copyright - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `{{AUTHOR}}` | Full legal name | `Jane Doe` | SPDX headers (all files), MAINTAINERS.md, .mailmap, .reuse/dep5, docs/AI-CONVENTIONS.md | -| `{{AUTHOR_EMAIL}}` | 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 | -|---|---|---|---| -| `{{PROJECT_NAME}}` | 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/interface/abi/*.idr, src/interface/ffi/*.zig | -| `{{project}}` | Lowercase identifier (for C symbols, filenames) | `my_project` | ABI-FFI-README.md, src/interface/ffi/*.zig | -| `{{REPO}}` | Repository name (slug) | `my-project` | CONTRIBUTING.md, SECURITY.md, CODE_OF_CONDUCT.md, cliff.toml | -| `{{OWNER}}` | GitHub/GitLab org or username | `my-org` | SPDX headers, CONTRIBUTING.md, SECURITY.md, GOVERNANCE.md, MAINTAINERS.md, CODEOWNERS, mirror.yml, cliff.toml | -| `{{FORGE}}` | Git forge domain | `github.com` | CONTRIBUTING.md | - -### Dates - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `{{CURRENT_YEAR}}` | 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 | - -### Contact & Security - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `{{SECURITY_EMAIL}}` | Security contact email | `security@example.org` | SECURITY.md | -| `{{PGP_FINGERPRINT}}` | 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_BRANCH}}` | Main branch name | `main` | CONTRIBUTING.md | - -### Build - -| Placeholder | Description | Example | Files | -|---|---|---|---| -| `{{LICENSE}}` | 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/.machine_readable/bot_directives/coverage.a2ml b/.machine_readable/bot_directives/coverage.a2ml index 1bd30fa..1012748 100644 --- a/.machine_readable/bot_directives/coverage.a2ml +++ b/.machine_readable/bot_directives/coverage.a2ml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # coverage.a2ml — Session coverage tracking # Updated at the end of each AI agent session. @@ -9,7 +9,7 @@ [metadata] version = "1.0.0" -last-updated = "{{CURRENT_DATE}}" +last-updated = "2026-07-27" # ============================================================================ # COVERAGE STATE diff --git a/.machine_readable/bot_directives/debt.a2ml b/.machine_readable/bot_directives/debt.a2ml index 3289cbe..708a6f1 100644 --- a/.machine_readable/bot_directives/debt.a2ml +++ b/.machine_readable/bot_directives/debt.a2ml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # debt.a2ml — Meander debt list # Things found but not fixed. Carried between sessions. @@ -9,7 +9,7 @@ [metadata] version = "1.0.0" -last-updated = "{{CURRENT_DATE}}" +last-updated = "2026-07-27" # ============================================================================ # DEBT ITEMS diff --git a/.machine_readable/bot_directives/methodology.a2ml b/.machine_readable/bot_directives/methodology.a2ml index a88ab49..9b2cdc5 100644 --- a/.machine_readable/bot_directives/methodology.a2ml +++ b/.machine_readable/bot_directives/methodology.a2ml @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # methodology.a2ml — AI agent methodology configuration # Declares how agents should approach work in this repository. @@ -9,7 +9,7 @@ [metadata] version = "1.0.0" -last-updated = "{{CURRENT_DATE}}" +last-updated = "2026-07-27" spec = "https://github.com/hyperpolymath/standards/blob/main/agentic-a2ml/docs/ADR-002-methodology-layer.adoc" # ============================================================================ @@ -55,7 +55,7 @@ perfective = 10 # % for SPDX headers, doc updates, formatting, style # Customise this per project — the template default is generic. [methodology.unique-strength] -description = "{{PROJECT_UNIQUE_STRENGTH}}" +description = "Not yet documented" deepen-not-broaden = true # ============================================================================ diff --git a/.machine_readable/coaptation/witness-map.ncl b/.machine_readable/coaptation/witness-map.ncl index 9e7e489..fcf8708 100644 --- a/.machine_readable/coaptation/witness-map.ncl +++ b/.machine_readable/coaptation/witness-map.ncl @@ -53,19 +53,23 @@ # declared capability awaiting a descriptile that actually carries such evidence. # --- INTEND: a committed intent realised by the descriptive self-model --- + # Fixed 2026-07-27: ECOSYSTEM.type was still the literal "repository-template" + # left over from an un-instantiated scaffold. The init intent for an + # INSTANTIATED repo is that it is no longer template-shaped. "intend.repo-initialization" = { kind = "descriptile", - witnesses = [ { fact = "ecosystem.type", op = 'equals, arg = "repository-template" } ], - note = "ECOSYSTEM declares this repo IS a template ⇒ the init intent is realised", + witnesses = [ { fact = "ecosystem.type", op = 'not_equals, arg = "repository-template" } ], + note = "ECOSYSTEM no longer declares this repo IS the template ⇒ the init intent is realised", }, # --- ADJUST: accessibility/hygiene posture (advisory; never gates) --- - # The ANCHOR identity block still carries {{PROJECT_NAME}}; for the template - # itself that is expected, but it is honestly a posture dip worth surfacing. + # Fixed 2026-07-27: the ANCHOR identity block was un-substituted + # ({{PROJECT_NAME}} etc.); it now carries real values, so this witness + # passes for real rather than by coincidence. "adjust.placeholder-drift" = { kind = "descriptile", witnesses = [ { fact = "anchor.project", op = 'not_contains, arg = "{{" } ], - note = "ANCHOR.identity.project is un-substituted ({{PROJECT_NAME}}) ⇒ posture dip", + note = "ANCHOR.identity.project is substituted ⇒ no posture dip", }, # --- BUST: recognised break. For bust, a HOLDING witness means ALARM (active diff --git a/.machine_readable/compliance/reuse/dep5 b/.machine_readable/compliance/reuse/dep5 index 637157c..1c46702 100644 --- a/.machine_readable/compliance/reuse/dep5 +++ b/.machine_readable/compliance/reuse/dep5 @@ -1,56 +1,56 @@ Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ -Upstream-Name: {{PROJECT_NAME}} -Upstream-Contact: {{AUTHOR}} <{{AUTHOR_EMAIL}}> -Source: https://github.com/{{OWNER}}/{{REPO}} +Upstream-Name: knot-rider +Upstream-Contact: Jonathan D.A. Jewell +Source: https://github.com/hyperpolymath/knot-rider # Default: all files are MPL-2.0 Files: * -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Configuration files that cannot carry headers Files: .editorconfig .gitignore .gitattributes .tool-versions .mailmap -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Machine-readable state files Files: .machine_readable/*.a2ml -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Bot directives Files: .machine_readable/bot_directives/* -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Contractiles Files: .machine_readable/contractiles/* -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # GitHub/CI configuration Files: .github/* .github/**/* -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Generated files Files: generated/* -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Lockfiles and auto-generated Files: *.lock Cargo.lock flake.lock -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Devcontainer config (JSON, no comments) Files: .devcontainer/*.json -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Git-cliff config Files: cliff.toml -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: MPL-2.0 # Narrative documentation is CC-BY-SA-4.0 (estate Rule 1). @@ -58,5 +58,5 @@ License: MPL-2.0 # including the GitHub community-health .md files. Machine-readable .a2ml is a # different extension and stays MPL-2.0 per its stanza above. Files: *.adoc *.md -Copyright: {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright: 2026 Jonathan D.A. Jewell (hyperpolymath) License: CC-BY-SA-4.0 diff --git a/.machine_readable/configs/eclexiaiser.toml b/.machine_readable/configs/eclexiaiser.toml index abc542e..6a5552a 100644 --- a/.machine_readable/configs/eclexiaiser.toml +++ b/.machine_readable/configs/eclexiaiser.toml @@ -2,7 +2,7 @@ # SPDX-License-Identifier: MPL-2.0 [project] -name = "{{REPO}}" +name = "knot-rider" [[functions]] name = "build" diff --git a/.machine_readable/configs/git-cliff/cliff.toml b/.machine_readable/configs/git-cliff/cliff.toml index 5c39b48..0d41917 100644 --- a/.machine_readable/configs/git-cliff/cliff.toml +++ b/.machine_readable/configs/git-cliff/cliff.toml @@ -1,12 +1,12 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # git-cliff configuration for conventional commit changelog generation. # https://git-cliff.org/docs/configuration # # Placeholders — replace before first use: -# {{OWNER}} — GitHub organization or username -# {{REPO}} — GitHub repository name +# hyperpolymath — GitHub organization or username +# knot-rider — GitHub repository name [changelog] # Changelog header @@ -21,7 +21,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 # https://keats.github.io/tera/docs/#introduction body = """ {%- macro remote_url() -%} - https://github.com/{{OWNER}}/{{REPO}} + https://github.com/hyperpolymath/knot-rider {%- endmacro -%} {% if version -%} @@ -57,7 +57,7 @@ body = """ # Template for the changelog footer footer = """ {%- macro remote_url() -%} - https://github.com/{{OWNER}}/{{REPO}} + https://github.com/hyperpolymath/knot-rider {%- endmacro -%} {% for release in releases -%} diff --git a/.machine_readable/configs/stapeln.toml b/.machine_readable/configs/stapeln.toml index 7bf5d48..727413b 100644 --- a/.machine_readable/configs/stapeln.toml +++ b/.machine_readable/configs/stapeln.toml @@ -1,16 +1,16 @@ # SPDX-License-Identifier: MPL-2.0 -# stapeln.toml — Layer-based container build for {{SERVICE_NAME}} +# stapeln.toml — Layer-based container build for knot-rider # # stapeln builds containers as composable layers (German: "to stack"). # Each layer is independently cacheable, verifiable, and signable. [metadata] -name = "{{SERVICE_NAME}}" +name = "knot-rider" version = "0.1.0" -description = "{{SERVICE_NAME}} container service" +description = "knot-rider container service" author = "Jonathan D.A. Jewell " license = "MPL-2.0" -registry = "{{REGISTRY}}" +registry = "ghcr.io/hyperpolymath" [build] containerfile = "Containerfile" @@ -32,7 +32,7 @@ packages = [] cache = true [layers.build] -description = "{{SERVICE_NAME}} build" +description = "knot-rider build" extends = "toolchain" commands = [] @@ -43,7 +43,7 @@ packages = ["ca-certificates", "curl"] copy-from = [ { layer = "build", src = "/app/", dst = "/app/" }, ] -entrypoint = ["/app/{{SERVICE_NAME}}"] +entrypoint = ["/app/knot-rider"] user = "nonroot" # ── Security ─────────────────────────────────────────────────── diff --git a/.machine_readable/contractiles/Justfile b/.machine_readable/contractiles/Justfile index b98ac2c..eb05947 100644 --- a/.machine_readable/contractiles/Justfile +++ b/.machine_readable/contractiles/Justfile @@ -18,10 +18,10 @@ set positional-arguments := true # Re-generate with: contractile gen-just import? "build/contractile.just" -# Project metadata — customize these -project := "rsr-template-repo" +# Project metadata +project := "knot_rider" OWNER := "hyperpolymath" -REPO := "rsr-template-repo" +REPO := "knot-rider" version := "0.1.0" tier := "infrastructure" # 1 | 2 | infrastructure @@ -87,39 +87,23 @@ import? "build/just/assess.just" # Build the project (debug mode) build *args: - @echo "Building {{project}} (debug)..." - # TODO: Replace with your build command - # Examples: - # cargo build {{args}} # Rust - # mix compile {{args}} # Elixir - # zig build {{args}} # Zig - # deno task build {{args}} # Deno/ReScript - @echo "Build complete" + cd src/interface/ffi && zig build {{args}} # Build in release mode with optimizations build-release *args: - @echo "Building {{project}} (release)..." - # TODO: Replace with your release build command - # Examples: - # cargo build --release {{args}} - # MIX_ENV=prod mix compile {{args}} - # zig build -Doptimize=ReleaseFast {{args}} - @echo "Release build complete" - -# Build and watch for changes (requires entr or similar) + cd src/interface/ffi && zig build -Doptimize=ReleaseFast {{args}} + +# Build and watch for changes (requires entr) build-watch: - @echo "Watching for changes..." - # TODO: Customize file patterns for your language - # Examples: - # find src -name '*.rs' | entr -c just build - # mix compile --force --warnings-as-errors - # deno task dev + find src -name '*.zig' -o -name '*.idr' | entr -c just build # Clean build artifacts [reversible: rebuild with `just build`] clean: @echo "Cleaning..." - # TODO: Customize for your build system - rm -rf target/ _build/ build/ dist/ out/ obj/ bin/ + rm -rf src/interface/ffi/zig-out src/interface/ffi/.zig-cache + # NOTE: `build/` is NOT included here — it holds this repo's real + # `build/just/*.just` sources and `build/guix.scm`, not build output. + rm -rf target/ _build/ dist/ out/ obj/ bin/ # Deep clean including caches [reversible: rebuild] clean-all: clean @@ -131,64 +115,23 @@ clean-all: clean # Run all tests test *args: - @echo "Running tests..." - # TODO: Replace with your test command - # Examples: - # cargo test {{args}} - # mix test {{args}} - # zig build test {{args}} - # deno test {{args}} - @echo "Tests passed!" + cd src/interface/ffi && zig build test {{args}} # Run tests with verbose output test-verbose: - @echo "Running tests (verbose)..." - # TODO: Replace with verbose test command + cd src/interface/ffi && zig build test --summary all -# Smoke test +# Smoke test (fast compile-only sanity check) test-smoke: - @echo "Smoke test..." - # TODO: Add basic sanity checks + cd src/interface/ffi && zig build # Run end-to-end tests (full pipeline: build → run → verify) e2e: - @echo "Running E2E tests..." - # TODO: Replace with your E2E test command. Examples: - # bash tests/e2e.sh # Shell-based E2E - # npx playwright test # Browser E2E - # mix test test/integration/e2e_test.exs # Elixir E2E - # cargo test --test end_to_end # Rust E2E - @echo "E2E tests passed!" + bash tests/e2e.sh # Run aspect tests (cross-cutting concern validation) aspect: - @echo "Running aspect tests..." - # TODO: Replace with your aspect test command. Examples: - # bash tests/aspect_tests.sh # Shell-based aspect tests - # cargo test --test aspects # Rust aspect tests - # Aspect tests validate architectural invariants: - # - Thread safety (mutex in FFI modules) - # - ABI/FFI contract (declarations match exports) - # - SPDX compliance (all files have license headers) - # - No dangerous patterns (believe_me, assert_total, etc.) - @echo "Aspect tests passed!" - -# Run benchmarks (performance regression detection) -bench: - @echo "Running benchmarks..." - # TODO: Replace with your benchmark command. Examples: - # cargo bench # Rust criterion - # zig build bench # Zig benchmarks - # mix run bench/benchmarks.exs # Elixir benchee - # deno bench # Deno bench - @echo "Benchmarks complete!" - -# Run readiness tests (Component Readiness Grade: D/C/B) -readiness: - @echo "Running readiness tests..." - # TODO: Replace with your readiness test command. Examples: - # cargo test --test readiness -- --nocapture - @echo "Readiness tests complete!" + bash tests/aspect_tests.sh # Print the current CRG grade (reads from READINESS.md '**Current Grade:** X' line) crg-grade: @@ -212,9 +155,8 @@ crg-badge: esac; \ echo "[![CRG $$grade](https://img.shields.io/badge/CRG-$$grade-$$color?style=flat-square)](https://github.com/hyperpolymath/standards/tree/main/component-readiness-grades)" -# Run the full merge-requirement test suite (ALL categories) -# Per STANDING rule: P2P + E2E + aspect + execution + lifecycle + bench -test-all: test e2e aspect bench readiness +# Run the full merge-requirement test suite (no bench/readiness suites exist yet) +test-all: test e2e aspect @echo "All test categories passed — safe to merge!" # Run all quality checks @@ -231,72 +173,37 @@ fix: fmt # Format all source files [reversible: git checkout] fmt: - @echo "Formatting source files..." - # TODO: Replace with your formatter - # Examples: - # cargo fmt - # mix format - # gleam format - # deno fmt + cd src/interface/ffi && zig fmt . # Check formatting without changes fmt-check: - @echo "Checking formatting..." - # TODO: Replace with your format check - # Examples: - # cargo fmt --check - # mix format --check-formatted - # gleam format --check - -# Run linter + cd src/interface/ffi && zig fmt --check . + +# Run linter (typechecks the Idris2 ABI seam) lint: - @echo "Linting source files..." - # TODO: Replace with your linter - # Examples: - # cargo clippy -- -D warnings - # mix credo --strict - # gleam check + idris2 --typecheck abi.ipkg # ═══════════════════════════════════════════════════════════════════════════════ -# RUN & EXECUTE +# INSTALL # ═══════════════════════════════════════════════════════════════════════════════ +# NOTE: there is no `run` recipe — this repo is a C-ABI library (FFI seam), +# not an application with an entry point. There is nothing for `run` to run. -# Run the application -run *args: build - # TODO: Replace with your run command - echo "Run not configured yet" - -# Run with verbose output -run-verbose *args: build - # TODO: Replace with verbose run command - echo "Run not configured yet" - -# Install to user path +# Install the built library to $PREFIX (default: $HOME/.local) install: build-release - @echo "Installing {{project}}..." - # TODO: Replace with your install command + cd src/interface/ffi && zig build --prefix "${PREFIX:-$HOME/.local}" -Doptimize=ReleaseFast # ═══════════════════════════════════════════════════════════════════════════════ # DEPENDENCIES # ═══════════════════════════════════════════════════════════════════════════════ -# Install/check all dependencies +# Check the Zig toolchain is present deps: - @echo "Checking dependencies..." - # TODO: Replace with your dependency check - # Examples: - # cargo check - # mix deps.get - # gleam deps download - @echo "All dependencies satisfied" + @command -v zig >/dev/null 2>&1 && zig version || { echo "zig not found on PATH"; exit 1; } # Audit dependencies for vulnerabilities deps-audit: @echo "Auditing for vulnerabilities..." - # TODO: Replace with your audit command - # Examples: - # cargo audit - # mix audit @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL --quiet . || true @echo "Audit complete" @@ -312,6 +219,22 @@ claude-md: validate-claude-md: @bash .machine_readable/arrival-pack/verify.sh +# ═══════════════════════════════════════════════════════════════════════════════ +# COAPTATION — typed descriptile↔contractile face-off (homeostasis reading) +# ═══════════════════════════════════════════════════════════════════════════════ + +# Emit the coaptation receipt: how the descriptiles coapt with the contractiles (SITREP) +coapt: + @bash .machine_readable/coaptation/coapt.sh --report + +# Assemble a re-anchor basis IF the band is red (the drop itself is a human act) +coapt-reanchor: + @bash .machine_readable/coaptation/coapt.sh --reanchor + +# Fail if the committed coaptation receipt drifted from the contractiles/descriptiles +validate-coapt: + @bash .machine_readable/coaptation/verify.sh + # ═══════════════════════════════════════════════════════════════════════════════ # DOCUMENTATION # ═══════════════════════════════════════════════════════════════════════════════ @@ -425,7 +348,7 @@ state-phase: @grep -oP 'phase\s*=\s*"\K[^"]+' .machine_readable/6a2/STATE.a2ml 2>/dev/null | head -1 || echo "unknown" # ═══════════════════════════════════════════════════════════════════════════════ -# GUIX & NIX +# GUIX # ═══════════════════════════════════════════════════════════════════════════════ # Enter Guix development shell (primary) @@ -436,10 +359,6 @@ guix-shell: guix-build: guix build -f guix.scm -# Enter Nix development shell (fallback) -nix-shell: - @if [ -f "flake.nix" ]; then nix develop; else echo "No flake.nix"; fi - # ═══════════════════════════════════════════════════════════════════════════════ # HYBRID AUTOMATION # ═══════════════════════════════════════════════════════════════════════════════ @@ -543,7 +462,7 @@ assail: # Self-diagnostic — checks dependencies, permissions, paths doctor: - @echo "Running diagnostics for rsr-template-repo..." + @echo "Running diagnostics for knot-rider..." @echo "Checking required tools..." @command -v just >/dev/null 2>&1 && echo " [OK] just" || echo " [FAIL] just not found" @command -v git >/dev/null 2>&1 && echo " [OK] git" || echo " [FAIL] git not found" @@ -553,7 +472,7 @@ doctor: # Guided tour of key features tour: - @echo "=== rsr-template-repo Tour ===" + @echo "=== knot-rider Tour ===" @echo "" @echo "1. Project structure:" @ls -la @@ -568,12 +487,12 @@ tour: # Open feedback channel with diagnostic context help-me: - @echo "=== rsr-template-repo Help ===" + @echo "=== knot-rider Help ===" @echo "Platform: $(uname -s) $(uname -m)" @echo "Shell: $SHELL" @echo "" @echo "To report an issue:" - @echo " https://github.com/hyperpolymath/rsr-template-repo/issues/new" + @echo " https://github.com/hyperpolymath/knot-rider/issues/new" @echo "" @echo "Include the output of 'just doctor' in your report." diff --git a/.machine_readable/contractiles/dust/Dustfile.a2ml b/.machine_readable/contractiles/dust/Dustfile.a2ml index c6bf986..77a7f91 100644 --- a/.machine_readable/contractiles/dust/Dustfile.a2ml +++ b/.machine_readable/contractiles/dust/Dustfile.a2ml @@ -54,7 +54,7 @@ to new repositories. - description: No references to rsr-template-repo in generic template files - run: test -z "$(grep -r 'rsr-template-repo' machine-readable-design/ 2>/dev/null)" - severity: warning -- notes: Generic templates should use {{PROJECT_NAME}} or similar placeholders +- notes: Generic templates should use knot-rider or similar placeholders ### version-sync-checked - description: Version in canonical-directory-structure matches .machine_readable/contractiles diff --git a/.machine_readable/integrations/groove.a2ml b/.machine_readable/integrations/groove.a2ml index ea3fb8b..71ffb20 100644 --- a/.machine_readable/integrations/groove.a2ml +++ b/.machine_readable/integrations/groove.a2ml @@ -9,8 +9,8 @@ (groove-manifest (version "1.0") - ; Service identity — replace {{REPO}} with your project name - (service "{{REPO}}") + ; Service identity — replace knot-rider with your project name + (service "knot-rider") (service-version "0.1.0") ; Primary port — MUST be unique across the ecosystem. diff --git a/.machine_readable/policies/MAINTENANCE-AXES.a2ml b/.machine_readable/policies/MAINTENANCE-AXES.a2ml index c251de6..f6a2fca 100644 --- a/.machine_readable/policies/MAINTENANCE-AXES.a2ml +++ b/.machine_readable/policies/MAINTENANCE-AXES.a2ml @@ -1,11 +1,11 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # Canonical maintenance governance model [metadata] version = "1.0.0" -last-updated = "{{CURRENT_DATE}}" +last-updated = "2026-07-27" scope = "repo" [discovery] diff --git a/.machine_readable/scripts/maintenance/maint-assault.sh b/.machine_readable/scripts/maintenance/maint-assault.sh index f170cab..a533a8d 100644 --- a/.machine_readable/scripts/maintenance/maint-assault.sh +++ b/.machine_readable/scripts/maintenance/maint-assault.sh @@ -8,7 +8,7 @@ set -euo pipefail -BINARY_NAME="{{project}}" +BINARY_NAME="knot-rider" REPORT_PATH="docs/reports/security/assault-latest.json" PA_BIN="${PANIC_ATTACK_BIN:-panic-attack}" diff --git a/.machine_readable/self-validating/README.adoc b/.machine_readable/self-validating/README.adoc index 0062207..4aca2fd 100644 --- a/.machine_readable/self-validating/README.adoc +++ b/.machine_readable/self-validating/README.adoc @@ -131,7 +131,7 @@ K9 contractiles integrate with other RSR standards: ⚠️ **Never run as root unless required** + ⚠️ **Sandbox external components** -**See:** https://github.com/{{OWNER}}/k9-svc/blob/main/docs/SECURITY-BEST-PRACTICES.adoc +**See:** https://github.com/hyperpolymath/k9-svc/blob/main/docs/SECURITY-BEST-PRACTICES.adoc == Template Files @@ -155,14 +155,14 @@ chmod +x nickel && sudo mv nickel /usr/local/bin/ cargo install just # Clone K9-SVC (for must shim and tooling) -git clone https://github.com/{{OWNER}}/k9-svc.git +git clone https://github.com/hyperpolymath/k9-svc.git ---- == Learn More -- **K9-SVC Specification:** https://github.com/{{OWNER}}/k9-svc/blob/main/SPEC.adoc -- **K9 User Guide:** https://github.com/{{OWNER}}/k9-svc/blob/main/GUIDE.adoc -- **Security Documentation:** https://github.com/{{OWNER}}/k9-svc/blob/main/docs/SECURITY-FAQ.adoc +- **K9-SVC Specification:** https://github.com/hyperpolymath/k9-svc/blob/main/SPEC.adoc +- **K9 User Guide:** https://github.com/hyperpolymath/k9-svc/blob/main/GUIDE.adoc +- **Security Documentation:** https://github.com/hyperpolymath/k9-svc/blob/main/docs/SECURITY-FAQ.adoc - **IANA Media Type:** `application/vnd.k9+nickel` == Contributing @@ -175,4 +175,4 @@ When adding K9 contractiles to your repository: 4. Sign Hunt-level components before committing 5. Add K9 validation to CI/CD pipeline -**Questions?** Open an issue on https://github.com/{{OWNER}}/k9-svc +**Questions?** Open an issue on https://github.com/hyperpolymath/k9-svc diff --git a/.machine_readable/self-validating/methodology-guard.k9.ncl b/.machine_readable/self-validating/methodology-guard.k9.ncl index 4c43325..17f1409 100644 --- a/.machine_readable/self-validating/methodology-guard.k9.ncl +++ b/.machine_readable/self-validating/methodology-guard.k9.ncl @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) # # K9 Validator: Methodology Guard # Checks that agent work respects methodology constraints declared in diff --git a/.well-known/humans.txt b/.well-known/humans.txt index e062f4b..0ce0944 100644 --- a/.well-known/humans.txt +++ b/.well-known/humans.txt @@ -2,12 +2,12 @@ # humanstxt.org /* TEAM */ -Maintainer: {{AUTHOR}} ({{OWNER}}) -Contact: {{AUTHOR_EMAIL}} +Maintainer: Jonathan D.A. Jewell (hyperpolymath) +Contact: j.d.a.jewell@open.ac.uk From: United Kingdom /* SITE */ -Last update: {{CURRENT_DATE}} +Last update: 2026-07-27 Standards: RSR (Rhodium Standard Repository) License: MPL-2.0 (Palimpsest MPL) Components: Idris2 ABI, Zig FFI diff --git a/.well-known/security.txt b/.well-known/security.txt index 5414d50..43ee4c8 100644 --- a/.well-known/security.txt +++ b/.well-known/security.txt @@ -2,10 +2,8 @@ # RFC 9116 - security.txt # https://securitytxt.org/ -Contact: mailto:{{SECURITY_EMAIL}} -Expires: {{CURRENT_YEAR}}-12-31T23:59:59.000Z -Encryption: {{PGP_KEY_URL}} +Contact: mailto:j.d.a.jewell@open.ac.uk +Expires: 2026-12-31T23:59:59.000Z Preferred-Languages: en -Canonical: https://{{FORGE}}/{{OWNER}}/{{REPO}}/.well-known/security.txt -Policy: https://{{FORGE}}/{{OWNER}}/{{REPO}}/blob/main/SECURITY.md -Hiring: https://{{WEBSITE}}/careers +Canonical: https://github.com/hyperpolymath/knot-rider/.well-known/security.txt +Policy: https://github.com/hyperpolymath/knot-rider/blob/main/SECURITY.md diff --git a/0-AI-MANIFEST.a2ml b/0-AI-MANIFEST.a2ml index 68aad8c..3e36b40 100644 --- a/0-AI-MANIFEST.a2ml +++ b/0-AI-MANIFEST.a2ml @@ -5,11 +5,11 @@ # [metadata] version = "0.1.0" -last-updated = "{{CURRENT_DATE}}" +last-updated = "2026-07-27" [project] name = "[YOUR-REPO-NAME]" -purpose = "{{PROJECT_DESCRIPTION}}" +purpose = "RSR-scaffolded repository; specific purpose not documented (see README)" [ai-allocation] agents = [ diff --git a/AFFIRMATION.adoc b/AFFIRMATION.adoc index 3a840b4..e4dc3da 100644 --- a/AFFIRMATION.adoc +++ b/AFFIRMATION.adoc @@ -1,16 +1,12 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell -= AFFIRMATION — {{PROJECT_NAME}}, as of += AFFIRMATION — knot-rider, as of 2026-07-27 + :toc: macro :toclevels: 2 _the No-Bullshit file: what we affirm was true and checkable at this moment._ -[NOTE] -==== -*This file is a template.* Replace the `{{…}}` placeholders and the `<…>` anchor -fields, then re-run your project's own checks in the same session before signing. - An *affirmation* is a solemn declaration of the truth of a statement, made by someone who _declines to swear an oath_ — our truth-as-best-believed at a stamped instant, binding on our honesty, not a claim of infallibility. It is the third of @@ -23,36 +19,22 @@ the README / EXPLAINME / AFFIRMATION trio: | `EXPLAINME.adoc` | _How is it built, and what's the evidence?_ — engineering | descriptive / mechanism | *`AFFIRMATION.adoc`* (this file) | _What can we honestly affirm was *true and checkable* at a stamped moment?_ | a frozen instant, falsifiable |=== -==== toc::[] == What this is, and how it works -*What it is.* A short, dated, signed snapshot of what {{OWNER}} can honestly and -verifiably claim about *{{PROJECT_NAME}}* at one exact commit. Nothing here is +*What it is.* A short, dated, signed snapshot of what hyperpolymath can honestly and +verifiably claim about *knot-rider* at one exact commit. Nothing here is marketing and nothing is a promise about the future — those live in the README. This file is the receipt. -*How it stays trustworthy.* Three moving parts: - -. *Ground truth, not memory.* Every claim below must be produced by _running the - project's own checks_ in the session that writes this file (build, tests, - typecheck, `just audit`). Where a status doc, the `Justfile`, or memory says - otherwise, the live run wins and the contradiction is flagged here. -. *A frozen anchor.* The file names the exact commit SHA, branch, UTC timestamp, - and toolchain (see <>), so "true" always means "true _at - this point_". Move the SHA and this file is a draft until it is re-run. -. *A real signature.* It is landed by a *signed git commit*; that signature over - this content at the anchored SHA is what makes the affirmation tamper-evident - and attributable — not the prose alone. - *We are fallible.* This is our best honest belief, not a proof of its own correctness. Treat it as a falsifiable claim, not gospel. == The epistemic contract (read this before you trust _or_ attack) -This document records {{OWNER}}'s *best belief* at the timestamp below. It is +This document records hyperpolymath's *best belief* at the timestamp below. It is *not a guarantee of correctness.* The only guarantee is *no intentional overclaim*: where something is proven we say "proven"; where it is a documented trust boundary, an experiment, or an unwired module, we say so; where a claim is @@ -62,33 +44,50 @@ that later turns out false is an *error to be fixed* — not a lie. *Standing invitation to refute.* You are invited to bulldoze any claim in this file. Bring a counter-example, a failing run, or a contradicting source. -== What we affirm (fill in — delete the examples) +== What we affirm [cols="2,1,3",options="header"] |=== | Claim | Status | Evidence (command / `file:line`) -| _e.g. The library builds clean_ | affirmed | `just build` at the anchor SHA -| _e.g. The ABI seam typechecks_ | affirmed | `idris2 --typecheck abi.ipkg` -| _e.g. Feature X is complete_ | aspiration | README §… (not yet checked) +| The Zig FFI library builds clean | affirmed | `cd src/interface/ffi && zig build` — exit 0 +| The Zig FFI unit + integration tests pass | affirmed | `cd src/interface/ffi && zig build test` — 4/4 tests pass, exit 0 +| Zig sources are correctly formatted | affirmed | `zig fmt --check src/interface/ffi` — exit 0 +| RSR identity placeholders (`{{PROJECT_NAME}}` etc.) are substituted with real values across the tree | affirmed | manual grep sweep + `just verify-template`; remaining `{{...}}` hits are intentional (Justfile interpolation, `docs-template/`, detector patterns, ADR templates) +| The `.github/workflows/container-build.yml` and other edited workflow YAML still parse | affirmed | `python3 -c "import yaml; yaml.safe_load(open(f))"` on each edited workflow +| `CLAUDE.md`'s generated arrival-pack region matches the `.machine_readable/6a2/` a2ml source | affirmed | `just claude-md && just validate-claude-md` — reports in sync +|=== + +[cols="2,1,3",options="header"] +|=== +| Claim | Status | Evidence +| The Idris2 ABI seam (`abi.ipkg`) typechecks | not checked | `idris2` was not available in the environment this affirmation was written in; `just lint` runs `idris2 --typecheck abi.ipkg`, a real command, but its result is unverified +| GitHub Actions CI is green on this branch | not checked | this pass only ran the local toolchain; no CI run was observed before this affirmation was written +| The FFI functions implement real, project-specific logic | false | they are the RSR template's example bodies (`knot_rider_init`, `knot_rider_process`, etc.), unmodified beyond the identifier rename from `{{project}}` +| This project has a known, documented technical purpose | false | see README.adoc — genuinely undocumented anywhere in this repo or the wider estate |=== == What we do NOT claim -* List the known gaps, trust boundaries, postulates, unwired modules, and stale - docs here. Silence is not affirmation — name what you have *not* verified. +* We do NOT claim the Idris2 ABI proofs check — `idris2` was not run. +* We do NOT claim CI is green — no workflow run was observed in this session. +* We do NOT claim the container/stapeln layer builds or deploys — untested. +* We do NOT claim to know what knot-rider is for. +* We do NOT claim every last stray reference to the old template identity is + gone — this was a large, mostly-mechanical sweep across ~90 files; a residual + miss is plausible and should be treated as a bug report, not a betrayal. [#verifiable-anchor] == Verifiable anchor [cols="1,3"] |=== -| Project | {{PROJECT_NAME}} -| Repository | https://{{FORGE}}/{{OWNER}}/{{REPO}} -| Commit (SHA) | -| Branch | {{MAIN_BRANCH}} -| Timestamp (UTC) | -| Toolchain | -| Affirmed by | {{AUTHOR}} <{{AUTHOR_EMAIL}}> +| Project | knot-rider +| Repository | https://github.com/hyperpolymath/knot-rider +| Commit (SHA) | the commit that introduces this AFFIRMATION — see `git log --show-signature` on this file +| Branch | fix/instantiate-template (merges to main) +| Timestamp (UTC) | 2026-07-27 +| Toolchain | zig 0.16.0, just 1.56.0, nickel 1.17.0, jq 1.8 +| Affirmed by | Jonathan D.A. Jewell |=== _Landed by a signed git commit. Verify with `git log --show-signature` that the diff --git a/CITATION.cff b/CITATION.cff index 5de4710..b55357d 100644 --- a/CITATION.cff +++ b/CITATION.cff @@ -1,14 +1,14 @@ cff-version: 1.2.0 message: "If you use this software, please cite it as below." authors: -- family-names: "{{AUTHOR_LAST}}" - given-names: "{{AUTHOR_FIRST}}" +- family-names: "Jewell" + given-names: "Jonathan" orcid: "https://orcid.org/0000-0000-0000-0000" # Placeholder -title: "{{PROJECT_NAME}}" +title: "knot-rider" version: 0.1.0 -date-released: "{{CURRENT_DATE}}" -url: "https://{{FORGE}}/{{OWNER}}/{{REPO}}" -repository-code: "https://{{FORGE}}/{{OWNER}}/{{REPO}}" +date-released: "2026-07-27" +url: "https://github.com/hyperpolymath/knot-rider" +repository-code: "https://github.com/hyperpolymath/knot-rider" license: MPL-2.0 keywords: - "rsr" diff --git a/CLAUDE.md b/CLAUDE.md index b352a59..00772d9 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -6,7 +6,7 @@ SPDX-FileCopyrightText: 2026 Jonathan D.A. Jewell - + # You are in the hyperpolymath estate — orient before acting @@ -54,14 +54,14 @@ Deny: **Nix, Node/npm, TypeScript, Python, Go, AGPL**. (Guix, not Nix.) --- -# This repo: `rsr-template-repo` · clade `rm-rsr-template-repo` +# This repo: `knot-rider` · clade `rm-knot-rider` -- **Identity** — uuid `a5ea1382-a34c-5334-8a46-a2ebe904c810`; clade `rm` (secondary `gv`); born 2026-03-16; forge `hyperpolymath/rsr-template-repo`. -- **IS** — Canonical RSR-compliant repository template: scaffolding (CI/CD, AI manifests, ABI/FFI standards, container ecosystem, governance) that new hyperpolymath projects are instantiated from. -- **IS-NOT** — a project in its own right · Scaffoldia (the full-featured repo designer) · standards (the canon source this template operationalises) -- **Where it sits** — pipeline position **foundation**; chain `standards → rsr-template-repo → (every estate repo)`; coordination = `standards`. +- **Identity** — uuid `a5ea1382-a34c-5334-8a46-a2ebe904c810`; clade `rm` (secondary `gv`); born 2026-03-16; forge `hyperpolymath/knot-rider`. +- **IS** — RSR-scaffolded repository named knot-rider. GitHub's description is a Knight-Rider-intro pun, per README.adoc. No specific technical purpose is implemented or documented beyond that. +- **IS-NOT** — (not yet declared — add ECOSYSTEM.what-this-is-not) +- **Where it sits** — pipeline position **unknown**; chain `unknown`; coordination = `unknown`. - **Constraints here** (AGENTIC) — fail-closed; evidence-per-step; no-silent-skip; rerun-after-fix; release-claim-requires-hard-pass. Never: banned langs (above), secrets, state files in repo root, AGPL. Details: `.machine_readable/bot_directives/{methodology,coverage,debt}.a2ml`. - **Golden path** (ANCHOR) — `just test && just quality` → Core tests pass; Quality gates pass; No unresolved critical security findings. -- **State** — phase maintenance; maturity production; 95% complete; status active. +- **State** — phase design; maturity experimental; 0% complete; status active. - + diff --git a/EXPLAINME.adoc b/EXPLAINME.adoc index 773dbd1..c876a2c 100644 --- a/EXPLAINME.adoc +++ b/EXPLAINME.adoc @@ -1,12 +1,34 @@ +// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell -= RSR Template Repo - Explainme += knot-rider - Explainme image:https://img.shields.io/badge/License-MPL_2.0-blue.svg[License: MPL-2.0,link="https://opensource.org/licenses/MPL-2.0"] :toc: :icons: font -This file explains how the key template claims map to real files. +This file explains how the RSR scaffolding claims map to real files in this +repository, and is honest about what is *not yet* real. + +== What is actually implemented + +* `src/interface/ffi/src/main.zig` — a small C-ABI Zig library (`knot_rider_init`, + `knot_rider_free`, `knot_rider_process`, string and callback helpers). It + compiles and its inline tests pass under Zig 0.16.0 (`just test`). +* `src/interface/ffi/build.zig` — builds `main.zig` as a static library and + wires `zig build test` to the real tests in `src/main.zig` and + `test/integration_test.zig`. +* `src/interface/Abi/*.idr` — Idris2 ABI type/layout declarations + (`abi.ipkg`). `just lint` runs `idris2 --typecheck abi.ipkg`, a real + command; whether it currently passes was not verified in this pass because + `idris2` was not available in this environment — see AFFIRMATION.adoc. + +== What is NOT implemented + +* There is no project-specific behaviour behind the FFI functions — + `knot_rider_process`, `knot_rider_get_string`, etc. are the RSR template's + example bodies, unmodified beyond the identifier rename. +* This project's actual purpose is undocumented. See README.adoc. == Central Session Protocol Authority @@ -56,24 +78,10 @@ Caveat: * Runtime files are intentionally lightweight and require human/agent completion. -== Template Token Policy - -Claim: -Placeholders are explicit template content until initialization. - -How this is implemented: - -* `README.adoc` and bootstrap recipes keep `{{TOKEN}}` placeholders visible. -* `just init` performs token replacement. - -Caveat: - -* Uninitialized placeholders must not be treated as project-specific truth. - == Julia Registry Packages — Standalone Repo Requirement Claim: -If this template is used to create a Julia package, it must remain a standalone repository registered with the Julia package registry. +If this repo were ever used to create a Julia package, it must remain a standalone repository registered with the Julia package registry. How this is implemented: @@ -83,12 +91,8 @@ How this is implemented: Caveat: * Do NOT move this repository into a monorepo or subdirectory, as this breaks registry registration and package discoverability. -* Julia packages published to a registry must each remain a standalone top-level repository (registry registration and package discovery require it). -* Non-registry Julia packages can be organized differently if they are not published to any registry. - +* This repo does not currently ship a `Project.toml` — this section is inherited RSR-standard guidance, not a claim that knot-rider is a Julia package. == License -This project is licensed under the Mozilla Public License, v. 2.0. See the `LICENSE` file for details. - -SPDX-License-Identifier: CC-BY-SA-4.0 +This project is licensed under the Mozilla Public License, v. 2.0. See the `LICENSE` file for details. Documentation is `CC-BY-SA-4.0`. diff --git a/Justfile b/Justfile index c6c157e..eb05947 100644 --- a/Justfile +++ b/Justfile @@ -18,10 +18,10 @@ set positional-arguments := true # Re-generate with: contractile gen-just import? "build/contractile.just" -# Project metadata — customize these -project := "rsr-template-repo" +# Project metadata +project := "knot_rider" OWNER := "hyperpolymath" -REPO := "rsr-template-repo" +REPO := "knot-rider" version := "0.1.0" tier := "infrastructure" # 1 | 2 | infrastructure @@ -87,39 +87,23 @@ import? "build/just/assess.just" # Build the project (debug mode) build *args: - @echo "Building {{project}} (debug)..." - # TODO: Replace with your build command - # Examples: - # cargo build {{args}} # Rust - # mix compile {{args}} # Elixir - # zig build {{args}} # Zig - # deno task build {{args}} # Deno/ReScript - @echo "Build complete" + cd src/interface/ffi && zig build {{args}} # Build in release mode with optimizations build-release *args: - @echo "Building {{project}} (release)..." - # TODO: Replace with your release build command - # Examples: - # cargo build --release {{args}} - # MIX_ENV=prod mix compile {{args}} - # zig build -Doptimize=ReleaseFast {{args}} - @echo "Release build complete" - -# Build and watch for changes (requires entr or similar) + cd src/interface/ffi && zig build -Doptimize=ReleaseFast {{args}} + +# Build and watch for changes (requires entr) build-watch: - @echo "Watching for changes..." - # TODO: Customize file patterns for your language - # Examples: - # find src -name '*.rs' | entr -c just build - # mix compile --force --warnings-as-errors - # deno task dev + find src -name '*.zig' -o -name '*.idr' | entr -c just build # Clean build artifacts [reversible: rebuild with `just build`] clean: @echo "Cleaning..." - # TODO: Customize for your build system - rm -rf target/ _build/ build/ dist/ out/ obj/ bin/ + rm -rf src/interface/ffi/zig-out src/interface/ffi/.zig-cache + # NOTE: `build/` is NOT included here — it holds this repo's real + # `build/just/*.just` sources and `build/guix.scm`, not build output. + rm -rf target/ _build/ dist/ out/ obj/ bin/ # Deep clean including caches [reversible: rebuild] clean-all: clean @@ -131,64 +115,23 @@ clean-all: clean # Run all tests test *args: - @echo "Running tests..." - # TODO: Replace with your test command - # Examples: - # cargo test {{args}} - # mix test {{args}} - # zig build test {{args}} - # deno test {{args}} - @echo "Tests passed!" + cd src/interface/ffi && zig build test {{args}} # Run tests with verbose output test-verbose: - @echo "Running tests (verbose)..." - # TODO: Replace with verbose test command + cd src/interface/ffi && zig build test --summary all -# Smoke test +# Smoke test (fast compile-only sanity check) test-smoke: - @echo "Smoke test..." - # TODO: Add basic sanity checks + cd src/interface/ffi && zig build # Run end-to-end tests (full pipeline: build → run → verify) e2e: - @echo "Running E2E tests..." - # TODO: Replace with your E2E test command. Examples: - # bash tests/e2e.sh # Shell-based E2E - # npx playwright test # Browser E2E - # mix test test/integration/e2e_test.exs # Elixir E2E - # cargo test --test end_to_end # Rust E2E - @echo "E2E tests passed!" + bash tests/e2e.sh # Run aspect tests (cross-cutting concern validation) aspect: - @echo "Running aspect tests..." - # TODO: Replace with your aspect test command. Examples: - # bash tests/aspect_tests.sh # Shell-based aspect tests - # cargo test --test aspects # Rust aspect tests - # Aspect tests validate architectural invariants: - # - Thread safety (mutex in FFI modules) - # - ABI/FFI contract (declarations match exports) - # - SPDX compliance (all files have license headers) - # - No dangerous patterns (believe_me, assert_total, etc.) - @echo "Aspect tests passed!" - -# Run benchmarks (performance regression detection) -bench: - @echo "Running benchmarks..." - # TODO: Replace with your benchmark command. Examples: - # cargo bench # Rust criterion - # zig build bench # Zig benchmarks - # mix run bench/benchmarks.exs # Elixir benchee - # deno bench # Deno bench - @echo "Benchmarks complete!" - -# Run readiness tests (Component Readiness Grade: D/C/B) -readiness: - @echo "Running readiness tests..." - # TODO: Replace with your readiness test command. Examples: - # cargo test --test readiness -- --nocapture - @echo "Readiness tests complete!" + bash tests/aspect_tests.sh # Print the current CRG grade (reads from READINESS.md '**Current Grade:** X' line) crg-grade: @@ -212,9 +155,8 @@ crg-badge: esac; \ echo "[![CRG $$grade](https://img.shields.io/badge/CRG-$$grade-$$color?style=flat-square)](https://github.com/hyperpolymath/standards/tree/main/component-readiness-grades)" -# Run the full merge-requirement test suite (ALL categories) -# Per STANDING rule: P2P + E2E + aspect + execution + lifecycle + bench -test-all: test e2e aspect bench readiness +# Run the full merge-requirement test suite (no bench/readiness suites exist yet) +test-all: test e2e aspect @echo "All test categories passed — safe to merge!" # Run all quality checks @@ -231,72 +173,37 @@ fix: fmt # Format all source files [reversible: git checkout] fmt: - @echo "Formatting source files..." - # TODO: Replace with your formatter - # Examples: - # cargo fmt - # mix format - # gleam format - # deno fmt + cd src/interface/ffi && zig fmt . # Check formatting without changes fmt-check: - @echo "Checking formatting..." - # TODO: Replace with your format check - # Examples: - # cargo fmt --check - # mix format --check-formatted - # gleam format --check - -# Run linter + cd src/interface/ffi && zig fmt --check . + +# Run linter (typechecks the Idris2 ABI seam) lint: - @echo "Linting source files..." - # TODO: Replace with your linter - # Examples: - # cargo clippy -- -D warnings - # mix credo --strict - # gleam check + idris2 --typecheck abi.ipkg # ═══════════════════════════════════════════════════════════════════════════════ -# RUN & EXECUTE +# INSTALL # ═══════════════════════════════════════════════════════════════════════════════ +# NOTE: there is no `run` recipe — this repo is a C-ABI library (FFI seam), +# not an application with an entry point. There is nothing for `run` to run. -# Run the application -run *args: build - # TODO: Replace with your run command - echo "Run not configured yet" - -# Run with verbose output -run-verbose *args: build - # TODO: Replace with verbose run command - echo "Run not configured yet" - -# Install to user path +# Install the built library to $PREFIX (default: $HOME/.local) install: build-release - @echo "Installing {{project}}..." - # TODO: Replace with your install command + cd src/interface/ffi && zig build --prefix "${PREFIX:-$HOME/.local}" -Doptimize=ReleaseFast # ═══════════════════════════════════════════════════════════════════════════════ # DEPENDENCIES # ═══════════════════════════════════════════════════════════════════════════════ -# Install/check all dependencies +# Check the Zig toolchain is present deps: - @echo "Checking dependencies..." - # TODO: Replace with your dependency check - # Examples: - # cargo check - # mix deps.get - # gleam deps download - @echo "All dependencies satisfied" + @command -v zig >/dev/null 2>&1 && zig version || { echo "zig not found on PATH"; exit 1; } # Audit dependencies for vulnerabilities deps-audit: @echo "Auditing for vulnerabilities..." - # TODO: Replace with your audit command - # Examples: - # cargo audit - # mix audit @command -v trivy >/dev/null && trivy fs --severity HIGH,CRITICAL --quiet . || true @echo "Audit complete" @@ -555,7 +462,7 @@ assail: # Self-diagnostic — checks dependencies, permissions, paths doctor: - @echo "Running diagnostics for rsr-template-repo..." + @echo "Running diagnostics for knot-rider..." @echo "Checking required tools..." @command -v just >/dev/null 2>&1 && echo " [OK] just" || echo " [FAIL] just not found" @command -v git >/dev/null 2>&1 && echo " [OK] git" || echo " [FAIL] git not found" @@ -565,7 +472,7 @@ doctor: # Guided tour of key features tour: - @echo "=== rsr-template-repo Tour ===" + @echo "=== knot-rider Tour ===" @echo "" @echo "1. Project structure:" @ls -la @@ -580,12 +487,12 @@ tour: # Open feedback channel with diagnostic context help-me: - @echo "=== rsr-template-repo Help ===" + @echo "=== knot-rider Help ===" @echo "Platform: $(uname -s) $(uname -m)" @echo "Shell: $SHELL" @echo "" @echo "To report an issue:" - @echo " https://github.com/hyperpolymath/rsr-template-repo/issues/new" + @echo " https://github.com/hyperpolymath/knot-rider/issues/new" @echo "" @echo "Include the output of 'just doctor' in your report." diff --git a/README.adoc b/README.adoc index 4552201..6e80e07 100644 --- a/README.adoc +++ b/README.adoc @@ -1,55 +1,56 @@ +// SPDX-License-Identifier: MPL-2.0 // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell // SPDX-FileCopyrightText: 2024-2026 Jonathan D.A. Jewell (hyperpolymath) -= {{PROJECT_NAME}} += knot-rider :toc: :toc-placement: preamble -image:https://img.shields.io/badge/OpenSSF-Best_Practices-green?logo=opensourcesecurity[OpenSSF Best Practices,link="https://www.bestpractices.dev/en/projects/new?repo_url=https://{{FORGE}}/{{OWNER}}/{{REPO}}"] +image:https://img.shields.io/badge/OpenSSF-Best_Practices-green?logo=opensourcesecurity[OpenSSF Best Practices,link="https://www.bestpractices.dev/en/projects/new?repo_url=https://github.com/hyperpolymath/knot-rider"] image:https://img.shields.io/badge/License-MPL_2.0-blue.svg[License: MPL-2.0,link="https://opensource.org/licenses/MPL-2.0"] image:https://raw.githubusercontent.com/hyperpolymath/palimpsest-license/main/assets/badges/svg/badge-quantum-safe.svg[Quantum-Safe Provenance,link="https://github.com/hyperpolymath/palimpsest-license/blob/main/v1.0/exhibits/EXHIBIT-B-QUANTUM-SAFE.txt"] image:https://img.shields.io/badge/Docs-CC--BY--SA--4.0-blue.svg[Docs: CC-BY-SA-4.0,link="https://creativecommons.org/licenses/by-sa/4.0/"] -image:https://api.thegreenwebfoundation.org/greencheckimage/{{FORGE}}[Green Web,link="https://www.thegreenwebfoundation.org/green-web-check/?url={{FORGE}}"] +image:https://api.thegreenwebfoundation.org/greencheckimage/github.com[Green Web,link="https://www.thegreenwebfoundation.org/green-web-check/?url=github.com"] -{{PROJECT_DESCRIPTION}} +GitHub's one-line description for this repository is a pun on the _Knight +Rider_ television introduction ("A shadowy flight into the dangerous world of +a man who does not exist"): -[IMPORTANT] -==== -*This file is a template.* You are reading `README.adoc` from the *RSR template repo* -(or a freshly-cloned copy of it). Run `just init` to replace every `{{PLACEHOLDER}}` -token with your project's details, then delete this admonition. Until you do, the -`{{...}}` markers below are intentional placeholders, not content. -==== +____ +A shadowy flight into the dangerous world of a man, who is either permanently +or very often undone by circumstance. +____ == What this is -A new repository scaffolded from the *Rhodium Standard Repository (RSR)* template: -a batteries-included starting point that ships with CI/CD, machine-readable project -metadata, an AI-agent gatekeeper protocol, a formally-typed ABI/FFI seam -(Idris2 + Zig), container and reproducible-build scaffolding, and governance -infrastructure — all wired and passing the RSR validators on day one. - -Replace this section with a description of *your* project once initialised. +`knot-rider` is a repository scaffolded from the *Rhodium Standard Repository +(RSR)* template (`hyperpolymath/rsr-template-repo`). It was never +instantiated after scaffolding — `{{PLACEHOLDER}}` tokens survived +throughout, including in the `.zig` sources, which meant the Zig genuinely +did not parse. That has now been cured: identity placeholders are +substituted, the Justfile recipes are wired to real commands, and the Zig FFI +seam builds and tests clean. + +*What it is not* is a description of what this project actually *does*. +Beyond its name and the description above, this project's specific technical +purpose has not been implemented or documented anywhere in this repository +or the wider hyperpolymath estate registry. If you know why this repo +exists, please open an issue or a PR against this README — don't guess and +don't invent a product story on its behalf. == Quick start [source,bash] ---- -# 1. Create a repo from this template (or clone it), then from the repo root: -just init # interactive bootstrap: fills every {{PLACEHOLDER}} - -# 2. See the available tasks: -just # lists all phases (build, test, validate, audit, ...) - -# 3. Check the repo still satisfies the RSR shape: -just validate # structure + metadata checks +git clone https://github.com/hyperpolymath/knot-rider.git +cd knot-rider +just deps # verify the Zig toolchain is present +just build # cd src/interface/ffi && zig build +just test # cd src/interface/ffi && zig build test +just # list all available recipes ---- -`just init` prompts for the project name, owner, author, licence contact, and the -other values listed in `.machine_readable/ai/PLACEHOLDERS.adoc`, substitutes them -across the tree, validates the result, and (if available) runs the `k9-svc` checks. - -== What you get +== What you get (from the RSR scaffold) * *Machine-readable metadata* (`.machine_readable/6a2/`) — `STATE`, `META`, `ECOSYSTEM`, `PLAYBOOK`, `AGENTIC`, `NEUROSYM`, `CLADE`, and `anchors/ANCHOR`, @@ -57,12 +58,12 @@ across the tree, validates the result, and (if available) runs the `k9-svc` chec * *AI gatekeeper protocol* — `0-AI-MANIFEST.a2ml` is the universal entry point that tells an AI agent how to work in this repo before it touches anything. * *Typed ABI/FFI seam* — `src/interface/Abi/` (Idris2 type + layout proofs) over - `src/interface/ffi/` (Zig implementation), with generated C headers. + `src/interface/ffi/` (Zig implementation, builds and tests clean with Zig 0.16). * *CI/CD* — GitHub Actions for quality, security (CodeQL, Scorecard, secret scanning), multi-forge mirroring, and RSR anti-pattern enforcement. * *Supply-chain & reproducibility* — container layering (stapeln), Guix shells, SBOM, and signing hooks. -* *Governance* — `GOVERNANCE.adoc`, `MAINTAINERS.adoc`, `.github/` community health +* *Governance* — `GOVERNANCE.md`, `MAINTAINERS`, `.github/` community health files, and a release `AUDIT.adoc` gate. == Repository map @@ -85,7 +86,6 @@ across the tree, validates the result, and (if available) runs the `k9-svc` chec * `EXPLAINME.adoc` — the engineering deep-dive: how the pieces actually work. * `AFFIRMATION.adoc` — the dated, signed honesty snapshot of the repo's true state. * `AUDIT.adoc` — the release audit gate. -* `.machine_readable/ai/PLACEHOLDERS.adoc` — the full placeholder reference. == Licence diff --git a/benches/template_bench.sh b/benches/template_bench.sh deleted file mode 100755 index 5fb58a8..0000000 --- a/benches/template_bench.sh +++ /dev/null @@ -1,227 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# Template Benchmarks -# Measures performance characteristics of template validation and build system - -set -euo pipefail - -REPO_ROOT="${1:-.}" -OUTPUT_FORMAT="${2:-human}" # human | json | csv - -# ANSI colors -BLUE='\033[0;34m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -NC='\033[0m' # No Color - -log_info() { - echo -e "${BLUE}→${NC} $*" -} - -log_pass() { - echo -e "${GREEN}✓${NC} $*" -} - -# Ensure we have required commands -command -v /usr/bin/time >/dev/null 2>&1 || { - echo "Warning: /usr/bin/time not available, using built-in time" - TIME_CMD="time" -} - -TIME_CMD="/usr/bin/time -f %e" 2>/dev/null || TIME_CMD="time" - -echo "" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "Template Benchmarks" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "" - -declare -A results - -#============================================================================== -# BENCHMARK 1: Template Validation -#============================================================================== - -log_info "Running template validation benchmark" - -# Warm-up run -if [ -f "$REPO_ROOT/scripts/validate-template.sh" ]; then - bash "$REPO_ROOT/scripts/validate-template.sh" "$REPO_ROOT" 0 > /dev/null 2>&1 || true -fi - -# Timed runs -BENCH_RUNS=3 -TOTAL_TIME=0 - -for i in $(seq 1 $BENCH_RUNS); do - START=$(date +%s%N) - bash "$REPO_ROOT/scripts/validate-template.sh" "$REPO_ROOT" 0 > /dev/null 2>&1 || true - END=$(date +%s%N) - - # Convert to milliseconds - RUN_TIME=$(( (END - START) / 1000000 )) - TOTAL_TIME=$(( TOTAL_TIME + RUN_TIME )) - - [ "$OUTPUT_FORMAT" = "human" ] && echo " Run $i: ${RUN_TIME}ms" -done - -AVG_VALIDATION_TIME=$(( TOTAL_TIME / BENCH_RUNS )) -results[validation]=$AVG_VALIDATION_TIME -log_pass "Validation: ${AVG_VALIDATION_TIME}ms average (${BENCH_RUNS} runs)" - -#============================================================================== -# BENCHMARK 2: Zig Build -#============================================================================== - -log_info "Running Zig build benchmark" - -if ! command -v zig &> /dev/null; then - echo " ⚠ Zig compiler not found - skipping Zig build benchmark" - results[zig_build]="skipped" -else - cd "$REPO_ROOT/src/interface/ffi" - - # Warm-up - zig build --summary off > /dev/null 2>&1 || true - - # Clean build - BENCH_RUNS=2 - TOTAL_TIME=0 - - for i in $(seq 1 $BENCH_RUNS); do - rm -rf zig-cache - - START=$(date +%s%N) - zig build --summary off > /dev/null 2>&1 || true - END=$(date +%s%N) - - RUN_TIME=$(( (END - START) / 1000000 )) - TOTAL_TIME=$(( TOTAL_TIME + RUN_TIME )) - - [ "$OUTPUT_FORMAT" = "human" ] && echo " Run $i: ${RUN_TIME}ms" - done - - AVG_BUILD_TIME=$(( TOTAL_TIME / BENCH_RUNS )) - results[zig_build]=$AVG_BUILD_TIME - log_pass "Zig build: ${AVG_BUILD_TIME}ms average (clean build, ${BENCH_RUNS} runs)" - - cd - > /dev/null -fi - -#============================================================================== -# BENCHMARK 3: Zig Tests -#============================================================================== - -log_info "Running Zig test benchmark" - -if ! command -v zig &> /dev/null; then - echo " ⚠ Zig compiler not found - skipping Zig test benchmark" - results[zig_test]="skipped" -else - cd "$REPO_ROOT/src/interface/ffi" - - # Warm-up - zig build test --summary off > /dev/null 2>&1 || true - - START=$(date +%s%N) - TEST_OUTPUT=$(zig build test --summary off 2>&1 || true) - END=$(date +%s%N) - - TEST_TIME=$(( (END - START) / 1000000 )) - results[zig_test]=$TEST_TIME - log_pass "Zig tests: ${TEST_TIME}ms" - - # Count tests - TEST_COUNT=$(echo "$TEST_OUTPUT" | grep -c "^test " || echo "unknown") - echo " Test count: $TEST_COUNT" - - cd - > /dev/null -fi - -#============================================================================== -# BENCHMARK 4: Workflow Validation -#============================================================================== - -log_info "Running workflow validation benchmark" - -if [ -f "$REPO_ROOT/tests/workflows/validate_workflows_test.sh" ]; then - START=$(date +%s%N) - bash "$REPO_ROOT/tests/workflows/validate_workflows_test.sh" "$REPO_ROOT/.github/workflows" > /dev/null 2>&1 || true - END=$(date +%s%N) - - WORKFLOW_TIME=$(( (END - START) / 1000000 )) - results[workflow_validation]=$WORKFLOW_TIME - log_pass "Workflow validation: ${WORKFLOW_TIME}ms" -fi - -#============================================================================== -# BENCHMARK 5: Template Instantiation -#============================================================================== - -log_info "Running template instantiation benchmark" - -if [ -f "$REPO_ROOT/tests/e2e/template_instantiation_test.sh" ]; then - START=$(date +%s%N) - bash "$REPO_ROOT/tests/e2e/template_instantiation_test.sh" "$REPO_ROOT" > /dev/null 2>&1 || true - END=$(date +%s%N) - - INSTANTIATION_TIME=$(( (END - START) / 1000000 )) - results[instantiation]=$INSTANTIATION_TIME - log_pass "Template instantiation: ${INSTANTIATION_TIME}ms" -fi - -#============================================================================== -# SUMMARY -#============================================================================== - -echo "" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "BENCHMARK RESULTS" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "" - -if [ "$OUTPUT_FORMAT" = "json" ]; then - echo "{" - echo " \"timestamp\": \"$(date -u +%Y-%m-%dT%H:%M:%SZ)\"," - echo " \"repo\": \"$REPO_ROOT\"," - echo " \"results\": {" - - count=0 - for key in "${!results[@]}"; do - value="${results[$key]}" - [ $count -gt 0 ] && echo "," - if [ "$value" = "skipped" ]; then - echo -n " \"$key\": \"skipped\"" - else - echo -n " \"$key\": $value" - fi - count=$((count + 1)) - done - echo "" - echo " }" - echo "}" -elif [ "$OUTPUT_FORMAT" = "csv" ]; then - echo "metric,value_ms,timestamp" - for key in "${!results[@]}"; do - value="${results[$key]}" - if [ "$value" != "skipped" ]; then - echo "$key,$value,$(date -u +%Y-%m-%dT%H:%M:%SZ)" - fi - done -else - # Human-readable format - for key in "${!results[@]}"; do - value="${results[$key]}" - if [ "$value" = "skipped" ]; then - printf " %-30s %s\n" "$key:" "SKIPPED" - else - printf " %-30s %5d ms\n" "$key:" "$value" - fi - done -fi - -echo "" -echo "Benchmark complete." -echo "" diff --git a/build/.guix-channel b/build/.guix-channel index f9bdf68..3b8eb05 100644 --- a/build/.guix-channel +++ b/build/.guix-channel @@ -1,20 +1,20 @@ ;; SPDX-License-Identifier: MPL-2.0 -;; Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ;; -;; Guix channel definition for {{PROJECT_NAME}} +;; Guix channel definition for knot-rider ;; ;; To use this channel, add to ~/.config/guix/channels.scm: ;; ;; (channel -;; (name '{{PROJECT_NAME}}) -;; (url "https://github.com/{{OWNER}}/{{PROJECT_NAME}}") +;; (name 'knot-rider) +;; (url "https://github.com/hyperpolymath/knot-rider") ;; (branch "main")) ;; ;; Then: guix pull (channel (version 0) - (url "https://github.com/{{OWNER}}/{{PROJECT_NAME}}") + (url "https://github.com/hyperpolymath/knot-rider") (dependencies (channel (name 'guix) diff --git a/build/guix.scm b/build/guix.scm index 33b1a9a..f4293df 100644 --- a/build/guix.scm +++ b/build/guix.scm @@ -1,13 +1,13 @@ ;; SPDX-License-Identifier: MPL-2.0 -;; Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +;; Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ;; -;; Guix package definition for {{PROJECT_NAME}} +;; Guix package definition for knot-rider ;; ;; Usage: ;; guix shell -D -f guix.scm # Enter development shell ;; guix build -f guix.scm # Build package ;; -;; TODO: Replace {{PROJECT_NAME}} and customize inputs for your language/stack. +;; TODO: Replace knot-rider and customize inputs for your language/stack. ;; See: https://guix.gnu.org/manual/en/html_node/Defining-Packages.html (use-modules (guix packages) @@ -18,7 +18,7 @@ (gnu packages base)) (package - (name "{{PROJECT_NAME}}") + (name "knot-rider") (version "0.1.0") (source (local-file "." "source" #:recursive? #t @@ -63,8 +63,8 @@ (list ;; TODO: Add runtime dependencies )) - (home-page "https://github.com/{{OWNER}}/{{PROJECT_NAME}}") - (synopsis "{{PROJECT_PURPOSE}}") + (home-page "https://github.com/hyperpolymath/knot-rider") + (synopsis "Not yet documented — see README.adoc") (description "RSR-compliant project. See README.adoc for details.") (license (list ;; MPL-2.0 extends MPL-2.0 diff --git a/container/Containerfile b/container/Containerfile index 5bf6b00..f15f54f 100644 --- a/container/Containerfile +++ b/container/Containerfile @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# {{PROJECT_NAME}} Container Image +# knot-rider Container Image # # Multi-stage build template for Chainguard Wolfi base images. # Customise the builder stage for your language and copy the @@ -11,13 +11,13 @@ # svalinn files under container/stapeln/ are referenced only as labels. # # Build (engine-agnostic — substitute podman | nerdctl | docker): -# podman build -t {{SERVICE_NAME}}:latest -f container/Containerfile . +# podman build -t knot-rider:latest -f container/Containerfile . # # Run: -# podman run -p {{PORT}}:{{PORT}} {{SERVICE_NAME}}:latest +# podman run -p 8080:8080 knot-rider:latest # # Run with persistent volume: -# podman run -p {{PORT}}:{{PORT}} -v {{SERVICE_NAME}}-data:/data {{SERVICE_NAME}}:latest +# podman run -p 8080:8080 -v knot-rider-data:/data knot-rider:latest # # Via the Justfile (auto-detects engine, prefers cerro-torre when present): # just container-build @@ -37,7 +37,7 @@ # COPY Cargo.toml Cargo.lock ./ # COPY src/ ./src/ # RUN cargo build --release -# # Output: /build/target/release/{{SERVICE_NAME}} +# # Output: /build/target/release/knot-rider # # --- Elixir --- # RUN apk add --no-cache erl27-elixir-1.18 erlang-27 erlang-27-dev git build-base @@ -47,14 +47,14 @@ # ENV MIX_ENV=prod # RUN mix local.hex --force && mix local.rebar --force && \ # mix deps.get --only prod && mix compile && mix release -# # Output: /build/_build/prod/rel/{{SERVICE_NAME}}/ +# # Output: /build/_build/prod/rel/knot-rider/ # # --- Zig --- # RUN apk add --no-cache zig build-base # COPY build.zig build.zig.zon ./ # COPY src/ ./src/ # RUN zig build -Doptimize=ReleaseFast -# # Output: /build/zig-out/bin/{{SERVICE_NAME}} +# # Output: /build/zig-out/bin/knot-rider # # Base image: `:latest` is right for a template scaffold (Chainguard rebuilds # Wolfi daily). For PRODUCTION builds, pin by digest for reproducibility/supply- @@ -82,13 +82,13 @@ COPY . . FROM cgr.dev/chainguard/wolfi-base:latest # OCI image labels (compatible with cerro-torre .ctp bundle metadata) -LABEL org.opencontainers.image.title="{{PROJECT_NAME}}" \ - org.opencontainers.image.description="{{PROJECT_DESCRIPTION}}" \ - org.opencontainers.image.url="https://{{FORGE}}/{{OWNER}}/{{REPO}}" \ - org.opencontainers.image.source="https://{{FORGE}}/{{OWNER}}/{{REPO}}" \ - org.opencontainers.image.vendor="{{OWNER}}" \ - org.opencontainers.image.licenses="{{LICENSE}}" \ - org.opencontainers.image.authors="{{AUTHOR}} <{{AUTHOR_EMAIL}}>" \ +LABEL org.opencontainers.image.title="knot-rider" \ + org.opencontainers.image.description="RSR-scaffolded repository; specific purpose not documented (see README)" \ + org.opencontainers.image.url="https://github.com/hyperpolymath/knot-rider" \ + org.opencontainers.image.source="https://github.com/hyperpolymath/knot-rider" \ + org.opencontainers.image.vendor="hyperpolymath" \ + org.opencontainers.image.licenses="MPL-2.0" \ + org.opencontainers.image.authors="Jonathan D.A. Jewell " \ dev.cerrotorre.manifest="container/stapeln/manifest.toml" \ dev.cerrotorre.gatekeeper="container/stapeln/.gatekeeper.yaml" \ dev.stapeln.compose="container/stapeln/compose.toml" @@ -109,9 +109,9 @@ WORKDIR /app # TODO: Copy compiled binary/release from builder stage. # Examples: -# COPY --from=builder /build/target/release/{{SERVICE_NAME}} /app/{{SERVICE_NAME}} -# COPY --from=builder /build/_build/prod/rel/{{SERVICE_NAME}} /app/release/ -# COPY --from=builder /build/zig-out/bin/{{SERVICE_NAME}} /app/{{SERVICE_NAME}} +# COPY --from=builder /build/target/release/knot-rider /app/knot-rider +# COPY --from=builder /build/_build/prod/rel/knot-rider /app/release/ +# COPY --from=builder /build/zig-out/bin/knot-rider /app/knot-rider # Copy entrypoint script COPY container/entrypoint.sh /app/entrypoint.sh @@ -132,7 +132,7 @@ RUN chown -R appuser:appuser /app # Environment variables — customise for your application ENV APP_HOST=[::] -ENV APP_PORT={{PORT}} +ENV APP_PORT=8080 ENV APP_LOG_FORMAT=json ENV APP_DATA_DIR=/data @@ -143,7 +143,7 @@ VOLUME ["/data"] USER appuser # Expose the application port -EXPOSE {{PORT}} +EXPOSE 8080 # Health check — the application must respond 2xx at /health HEALTHCHECK --interval=30s --timeout=5s --start-period=10s --retries=3 \ diff --git a/container/README.adoc b/container/README.adoc index 0c49ffb..506c8f3 100644 --- a/container/README.adoc +++ b/container/README.adoc @@ -1,6 +1,6 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell -= {{PROJECT_NAME}} Containerisation += knot-rider Containerisation :toc: left :toclevels: 3 :sectnums: @@ -138,7 +138,7 @@ The sovereign tier wires together the stapeln container stack: (Kennel / Yard / Hunt). The request path in the full stack is: -`svalinn` (edge) → `rokur` (secrets gate) → `{{SERVICE_NAME}}` (app). +`svalinn` (edge) → `rokur` (secrets gate) → `knot-rider` (app). == Initialise diff --git a/container/compose.yaml b/container/compose.yaml index 3ccbe94..b68352b 100644 --- a/container/compose.yaml +++ b/container/compose.yaml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MPL-2.0 # -# {{PROJECT_NAME}} — portable compose stack (Tier B) +# knot-rider — portable compose stack (Tier B) # # This is the runtime-agnostic, OCI compose-spec file. It works unchanged with: # podman compose -f container/compose.yaml up -d @@ -20,23 +20,23 @@ services: # ────────────────────────────────────────────────────────────────────── # Primary application service # ────────────────────────────────────────────────────────────────────── - "{{SERVICE_NAME}}": + "knot-rider": build: context: .. dockerfile: container/Containerfile - image: "{{REGISTRY}}/{{SERVICE_NAME}}:latest" + image: "ghcr.io/hyperpolymath/knot-rider:latest" ports: - - "{{PORT}}:{{PORT}}" + - "8080:8080" environment: APP_HOST: "[::]" - APP_PORT: "{{PORT}}" + APP_PORT: "8080" APP_LOG_FORMAT: "json" APP_DATA_DIR: "/data" volumes: - - "{{SERVICE_NAME}}-data:/data" + - "knot-rider-data:/data" restart: unless-stopped healthcheck: - test: ["CMD", "curl", "-sf", "http://localhost:{{PORT}}/health"] + test: ["CMD", "curl", "-sf", "http://localhost:8080/health"] interval: 30s timeout: 5s retries: 3 @@ -50,7 +50,7 @@ services: rokur: image: ghcr.io/hyperpolymath/rokur:latest environment: - ROKUR_BACKEND: "http://{{SERVICE_NAME}}:{{PORT}}" + ROKUR_BACKEND: "http://knot-rider:8080" ROKUR_LISTEN: "[::]:8081" ROKUR_REQUIRED_SECRETS: "" # comma-separated env names that MUST be set ROKUR_AUDIT_LOG: "/var/log/rokur/audit.jsonl" @@ -60,7 +60,7 @@ services: volumes: - rokur-audit:/var/log/rokur depends_on: - "{{SERVICE_NAME}}": + "knot-rider": condition: service_healthy restart: unless-stopped healthcheck: @@ -95,5 +95,5 @@ services: retries: 3 volumes: - "{{SERVICE_NAME}}-data": + "knot-rider-data": rokur-audit: diff --git a/container/entrypoint.sh b/container/entrypoint.sh index a7a0369..620ed9b 100755 --- a/container/entrypoint.sh +++ b/container/entrypoint.sh @@ -1,6 +1,6 @@ #!/bin/sh # SPDX-License-Identifier: MPL-2.0 -# {{PROJECT_NAME}} container entrypoint +# knot-rider container entrypoint # # Handles signal propagation, startup logging, and health check # preparation before exec-ing into the main application process. @@ -15,7 +15,7 @@ set -e # when Podman sends stop signals (e.g. `podman stop`, `selur-compose down`). cleanup() { - echo "Received shutdown signal — stopping {{SERVICE_NAME}}..." + echo "Received shutdown signal — stopping knot-rider..." # If the main process is backgrounded, kill it here: # kill "$MAIN_PID" 2>/dev/null || true # wait "$MAIN_PID" 2>/dev/null || true @@ -27,9 +27,9 @@ trap cleanup TERM INT # Startup logging # --------------------------------------------------------------------------- -echo "Starting {{SERVICE_NAME}}..." +echo "Starting knot-rider..." echo " Host: ${APP_HOST:-[::]}" -echo " Port: ${APP_PORT:-{{PORT}}}" +echo " Port: ${APP_PORT:-8080}" echo " Data: ${APP_DATA_DIR:-/data}" echo " Log: ${APP_LOG_FORMAT:-json}" @@ -56,8 +56,8 @@ fi # # TODO: Replace the command below with your application binary. # Examples: -# exec /app/{{SERVICE_NAME}} -# exec /app/release/bin/{{SERVICE_NAME}} start -# exec /app/{{SERVICE_NAME}} serve --host "${APP_HOST}" --port "${APP_PORT}" +# exec /app/knot-rider +# exec /app/release/bin/knot-rider start +# exec /app/knot-rider serve --host "${APP_HOST}" --port "${APP_PORT}" exec "$@" diff --git a/container/stapeln/.gatekeeper.yaml b/container/stapeln/.gatekeeper.yaml index 4aac671..62e0ee4 100644 --- a/container/stapeln/.gatekeeper.yaml +++ b/container/stapeln/.gatekeeper.yaml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MPL-2.0 # -# Svalinn gatekeeper policy for {{PROJECT_NAME}} +# Svalinn gatekeeper policy for knot-rider # # Controls which operations are permitted through the edge gateway. # This template provides moderate security defaults — not wide-open test @@ -65,9 +65,9 @@ rate_limits: trust: # Only accept .ctp bundles signed by these keys. trusted_signers: - - key_id: "{{SERVICE_NAME}}-release" + - key_id: "knot-rider-release" algorithm: "Ed25519" - public_key_file: "/etc/svalinn/keys/{{SERVICE_NAME}}-release.pub" + public_key_file: "/etc/svalinn/keys/knot-rider-release.pub" # Require these attestations on all .ctp bundles. required_attestations: diff --git a/container/stapeln/compose.toml b/container/stapeln/compose.toml index db42fb9..ca9766a 100644 --- a/container/stapeln/compose.toml +++ b/container/stapeln/compose.toml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MPL-2.0 # -# {{PROJECT_NAME}} selur-compose configuration +# knot-rider selur-compose configuration # # Orchestrates the container stack as verified container bundles (.ctp). # Uses selur zero-copy IPC between services on the same host. @@ -10,7 +10,7 @@ # selur-compose up --detach # Start in background # selur-compose verify # Verify all .ctp signatures # selur-compose ps # Check status -# selur-compose logs -f {{SERVICE_NAME}} # Stream logs +# selur-compose logs -f knot-rider # Stream logs # selur-compose down # Stop all services # # Fallback (when selur is not installed): this TOML is selur-native and is @@ -25,18 +25,18 @@ version = "1.0" # ============================================================================ # Primary application service -[services.{{SERVICE_NAME}}] -image = "{{REGISTRY}}/{{SERVICE_NAME}}:latest.ctp" -ports = ["{{PORT}}:{{PORT}}"] +[services.knot-rider] +image = "ghcr.io/hyperpolymath/knot-rider:latest.ctp" +ports = ["8080:8080"] environment = { APP_HOST = "[::]", - APP_PORT = "{{PORT}}", + APP_PORT = "8080", APP_LOG_FORMAT = "json", APP_DATA_DIR = "/data", } -volumes = ["{{SERVICE_NAME}}-data:/data"] +volumes = ["knot-rider-data:/data"] restart = "always" -healthcheck = { test = "curl -sf http://localhost:{{PORT}}/health", interval = "30s", timeout = "5s", retries = 3 } +healthcheck = { test = "curl -sf http://localhost:8080/health", interval = "30s", timeout = "5s", retries = 3 } # Rokur secrets gate: refuses to start (and refuses to proxy) unless the # declared secrets are present; emits a structured audit log of every access. @@ -45,14 +45,14 @@ healthcheck = { test = "curl -sf http://localhost:{{PORT}}/health", interval = " image = "ghcr.io/hyperpolymath/rokur:latest.ctp" ports = ["8081:8081"] environment = { - ROKUR_BACKEND = "http://{{SERVICE_NAME}}:{{PORT}}", + ROKUR_BACKEND = "http://knot-rider:8080", ROKUR_LISTEN = "[::]:8081", ROKUR_REQUIRED_SECRETS = "", ROKUR_AUDIT_LOG = "/var/log/rokur/audit.jsonl", ROKUR_LOG_FORMAT = "json", } volumes = ["rokur-audit:/var/log/rokur"] -depends_on = ["{{SERVICE_NAME}}"] +depends_on = ["knot-rider"] restart = "always" healthcheck = { test = "curl -sf http://localhost:8081/health", interval = "30s", timeout = "5s", retries = 3 } @@ -75,7 +75,7 @@ healthcheck = { test = "curl -sf http://localhost:80/health", interval = "30s", # Volumes # ============================================================================ -[volumes.{{SERVICE_NAME}}-data] +[volumes.knot-rider-data] driver = "local" [volumes.rokur-audit] diff --git a/container/stapeln/ct-build.sh b/container/stapeln/ct-build.sh index 19ef9bc..3f46a22 100755 --- a/container/stapeln/ct-build.sh +++ b/container/stapeln/ct-build.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash # SPDX-License-Identifier: MPL-2.0 # -# {{PROJECT_NAME}} — Cerro Torre build, sign, and verify pipeline +# knot-rider — Cerro Torre build, sign, and verify pipeline # # Builds the container image, packages it as a verified .ctp bundle, # signs it with Ed25519, and verifies the result. Gracefully degrades @@ -18,8 +18,8 @@ # CT_KEY_ID=my-key ./ct-build.sh # Use specific signing key # # Environment variables: -# CT_KEY_ID — Signing key identifier (default: {{SERVICE_NAME}}-release) -# CT_REGISTRY — OCI registry to push to (default: {{REGISTRY}}) +# CT_KEY_ID — Signing key identifier (default: knot-rider-release) +# CT_REGISTRY — OCI registry to push to (default: ghcr.io/hyperpolymath) # CT_TAG — Image tag (default: latest) set -euo pipefail @@ -44,15 +44,15 @@ for arg in "$@"; do fi done -CT_KEY_ID="${CT_KEY_ID:-{{SERVICE_NAME}}-release}" -CT_REGISTRY="${CT_REGISTRY:-{{REGISTRY}}}" +CT_KEY_ID="${CT_KEY_ID:-knot-rider-release}" +CT_REGISTRY="${CT_REGISTRY:-ghcr.io/hyperpolymath}" CT_TAG="${CT_TAG:-latest}" -IMAGE_NAME="{{SERVICE_NAME}}" +IMAGE_NAME="knot-rider" FULL_IMAGE="${CT_REGISTRY}/${IMAGE_NAME}:${CT_TAG}" CTP_FILE="${SCRIPT_DIR}/${IMAGE_NAME}-${CT_TAG}.ctp" -echo "=== {{PROJECT_NAME}} Cerro Torre Build Pipeline ===" +echo "=== knot-rider Cerro Torre Build Pipeline ===" echo " Image: ${FULL_IMAGE}" echo " Key: ${CT_KEY_ID}" echo " Bundle: ${CTP_FILE}" diff --git a/container/stapeln/deploy.k9.ncl b/container/stapeln/deploy.k9.ncl index 02b7df4..6339ea3 100644 --- a/container/stapeln/deploy.k9.ncl +++ b/container/stapeln/deploy.k9.ncl @@ -1,5 +1,5 @@ # SPDX-License-Identifier: MPL-2.0 -# deploy.k9.ncl — {{PROJECT_NAME}} deployment component (Hunt level) +# deploy.k9.ncl — knot-rider deployment component (Hunt level) # # k9-svc deployment specification with full pedigree (L1-L5). # Security Level: 'Hunt (requires cryptographic handshake for execution). @@ -18,11 +18,11 @@ let component_pedigree = { # L1: The Snout — Identity # ───────────────────────────────────────────────────────────── metadata = { - name = "{{SERVICE_NAME}}-deploy", - version = "{{VERSION}}", + name = "knot-rider-deploy", + version = "0.1.0", breed = "application/vnd.k9+nickel", magic_number = "K9!", - description = "{{PROJECT_NAME}} deployment component (Hunt level)", + description = "knot-rider deployment component (Hunt level)", }, # ───────────────────────────────────────────────────────────── @@ -93,8 +93,8 @@ let deployment = { # Container configuration container = { - image = "{{REGISTRY}}/{{SERVICE_NAME}}", - port = {{PORT}}, + image = "ghcr.io/hyperpolymath/knot-rider", + port = 8080, health_check = "/health", readiness_check = "/ready", }, @@ -113,7 +113,7 @@ let scripts = { pre_deploy = m%" #!/bin/sh set -eu -echo "K9: Pre-deployment validation for {{SERVICE_NAME}}..." +echo "K9: Pre-deployment validation for knot-rider..." cd container/stapeln && selur-compose verify || podman compose --file ../compose.yaml config echo "K9: Validation passed." "%, @@ -123,7 +123,7 @@ echo "K9: Validation passed." #!/bin/sh set -eu ENV="${1:-dev}" -echo "K9: Deploying {{SERVICE_NAME}} to $ENV environment..." +echo "K9: Deploying knot-rider to $ENV environment..." cd container/stapeln ./ct-build.sh selur-compose up --detach || podman compose --file ../compose.yaml up --detach @@ -134,7 +134,7 @@ echo "K9: Deployment to $ENV complete." rollback = m%" #!/bin/sh set -eu -echo "K9: Rolling back {{SERVICE_NAME}} deployment..." +echo "K9: Rolling back knot-rider deployment..." cd container/stapeln selur-compose down || podman compose --file ../compose.yaml down echo "K9: Rollback complete." diff --git a/container/stapeln/manifest.toml b/container/stapeln/manifest.toml index f55fcb3..76ca13d 100644 --- a/container/stapeln/manifest.toml +++ b/container/stapeln/manifest.toml @@ -1,27 +1,27 @@ # SPDX-License-Identifier: MPL-2.0 # -# Cerro Torre manifest for {{PROJECT_NAME}} .ctp bundle +# Cerro Torre manifest for knot-rider .ctp bundle # # This manifest describes the container image for verified # container packaging. Used by `ct pack` to create .ctp bundles. [metadata] -name = "{{SERVICE_NAME}}" -version = "{{VERSION}}" +name = "knot-rider" +version = "0.1.0" revision = 1 -summary = "{{PROJECT_DESCRIPTION}}" +summary = "RSR-scaffolded repository; specific purpose not documented (see README)" description = """ -{{PROJECT_NAME}} — containerised service packaged as a verified +knot-rider — containerised service packaged as a verified cerro-torre .ctp bundle with Ed25519 signing and full provenance tracking. """ -license = "{{LICENSE}}" -homepage = "https://{{FORGE}}/{{OWNER}}/{{REPO}}" -maintainer = "{{AUTHOR}} <{{EMAIL}}>" +license = "MPL-2.0" +homepage = "https://github.com/hyperpolymath/knot-rider" +maintainer = "Jonathan D.A. Jewell " [provenance] -upstream = "https://{{FORGE}}/{{OWNER}}/{{REPO}}" -import_date = {{CURRENT_DATE}}T00:00:00Z +upstream = "https://github.com/hyperpolymath/knot-rider" +import_date = 2026-07-27T00:00:00Z [dependencies] runtime = ["ca-certificates", "curl"] @@ -32,10 +32,10 @@ system = "podman" [build.environment] APP_HOST = "[::]" -APP_PORT = "{{PORT}}" +APP_PORT = "8080" [outputs] -primary = "{{SERVICE_NAME}}" +primary = "knot-rider" split = [] [attestations] @@ -54,7 +54,7 @@ drop = ["ALL"] add = ["NET_BIND_SERVICE"] [security.network] -listen_tcp = [{{PORT}}] +listen_tcp = [8080] [security.filesystem] read = ["/app/", "/data/"] diff --git a/container/stapeln/rokur.toml b/container/stapeln/rokur.toml index 87d7919..2b19048 100644 --- a/container/stapeln/rokur.toml +++ b/container/stapeln/rokur.toml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MPL-2.0 # -# Rokur secrets-gate configuration for {{PROJECT_NAME}} +# Rokur secrets-gate configuration for knot-rider # # Rokur (stapeln container stack) is a secrets-management gate: a small # Deno service that sits in front of the application and refuses to pass @@ -16,8 +16,8 @@ # # or, in the stack, via compose (see compose.toml / compose.yaml) [metadata] -name = "{{SERVICE_NAME}}-gate" -version = "{{VERSION}}" +name = "knot-rider-gate" +version = "0.1.0" # ============================================================================ # Listener / routing (env: ROKUR_LISTEN, ROKUR_BACKEND) @@ -27,7 +27,7 @@ version = "{{VERSION}}" # Address rokur listens on (inside the container). listen = "[::]:8081" # The upstream application rokur fronts once the gate is satisfied. -backend = "http://{{SERVICE_NAME}}:{{PORT}}" +backend = "http://knot-rider:8080" # Health/readiness endpoints rokur exposes for vordr / orchestrators. health_path = "/health" ready_path = "/ready" diff --git a/container/stapeln/vordr.toml b/container/stapeln/vordr.toml index 93842e3..b8b6691 100644 --- a/container/stapeln/vordr.toml +++ b/container/stapeln/vordr.toml @@ -1,6 +1,6 @@ # SPDX-License-Identifier: MPL-2.0 # -# Vordr runtime monitoring configuration for {{PROJECT_NAME}} +# Vordr runtime monitoring configuration for knot-rider # # Vordr watches container health, detects crashes, tracks resource usage, # and emits structured logs. It runs alongside the application stack and @@ -12,8 +12,8 @@ # vordr report [metadata] -name = "{{SERVICE_NAME}}" -version = "{{VERSION}}" +name = "knot-rider" +version = "0.1.0" # ============================================================================ # Health Monitoring @@ -25,13 +25,13 @@ version = "{{VERSION}}" [health] # Primary health endpoint — must return 2xx. -endpoint = "http://localhost:{{PORT}}/health" +endpoint = "http://localhost:8080/health" interval = "30s" timeout = "5s" failure_threshold = 3 # Readiness endpoint — checked during startup and after restarts. -readiness_endpoint = "http://localhost:{{PORT}}/ready" +readiness_endpoint = "http://localhost:8080/ready" readiness_timeout = "10s" # Action on failure: "alert" (log + notify) or "restart" (alert + restart). @@ -96,7 +96,7 @@ format = "json" level = "info" # Write vordr logs to stdout (captured by Podman) and optionally to file. output = "stdout" -# file = "/var/log/vordr/{{SERVICE_NAME}}.log" +# file = "/var/log/vordr/knot-rider.log" # ============================================================================ # Notifications (optional) @@ -111,7 +111,7 @@ output = "stdout" # on = ["failure", "recovery", "resource_critical"] # [notifications.email] -# to = "{{EMAIL}}" -# from = "vordr@{{SERVICE_NAME}}.local" +# to = "j.d.a.jewell@open.ac.uk" +# from = "vordr@knot-rider.local" # smtp = "smtp://localhost:25" # on = ["failure", "resource_critical"] diff --git a/docs/QUICKSTART.adoc b/docs/QUICKSTART.adoc index 754fd5e..ac03390 100644 --- a/docs/QUICKSTART.adoc +++ b/docs/QUICKSTART.adoc @@ -11,16 +11,19 @@ Get up and running in 60 seconds. * just (command runner) * Your language toolchain (see Justfile for details) -== From Template (New Project) +== Clone and build [source,bash] ---- -git clone https://github.com/{{OWNER}}/rsr-template-repo my-project -cd my-project -rm -rf .git && git init -b main -just init # interactive placeholder replacement +git clone https://github.com/hyperpolymath/knot-rider.git +cd knot-rider +just deps # verify the Zig toolchain is present +just build # cd src/interface/ffi && zig build +just test # cd src/interface/ffi && zig build test ---- == Project Structure -See README.adoc in the root for the Dual-Track architecture summary. +See README.adoc in the root for the repository map. Note: this repo's +specific technical purpose is undocumented — see README.adoc's "What this +is" section before assuming what it's for. diff --git a/docs/architecture/THREAT-MODEL.adoc b/docs/architecture/THREAT-MODEL.adoc index 5f36b22..e1670b1 100644 --- a/docs/architecture/THREAT-MODEL.adoc +++ b/docs/architecture/THREAT-MODEL.adoc @@ -2,18 +2,18 @@ // Copyright (c) Jonathan D.A. Jewell = Threat Model - + -# Threat Model: {{PROJECT_NAME}} +# Threat Model: knot-rider ## Document Info | Field | Value | |---------------|--------------------------------| -| Project | {{PROJECT_NAME}} | +| Project | knot-rider | | Version | 1.0 | -| Last Reviewed | {{DATE}} | -| Author | {{AUTHOR}} | +| Last Reviewed | 2026-07-27 | +| Author | Jonathan D.A. Jewell | | Methodology | STRIDE | ## Scope @@ -36,7 +36,7 @@ ## System Overview -Brief description of {{PROJECT_NAME}} and its architecture. +Brief description of knot-rider and its architecture. > See [STATE-VISUALIZER.adoc](../STATE-VISUALIZER.adoc) for the full architecture diagram and completion dashboard. diff --git a/docs/attribution/CITATIONS.adoc b/docs/attribution/CITATIONS.adoc index 0a8b419..8e67e29 100644 --- a/docs/attribution/CITATIONS.adoc +++ b/docs/attribution/CITATIONS.adoc @@ -1,36 +1,36 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell -= {{PROJECT_NAME}} - Citation Guide += knot-rider - Citation Guide :toc: == BibTeX [source,bibtex] ---- -@software{{{PROJECT_NAME}}_{{CURRENT_YEAR}}, - author = {{{AUTHOR_LAST}}, {{AUTHOR_FIRST}}}, - title = {{{PROJECT_NAME}}}, - year = {{{CURRENT_YEAR}}}, - url = {https://github.com/{{OWNER}}/{{PROJECT_NAME}}}, +@software{knot-rider_2026, + author = {Jewell, Jonathan}, + title = {knot-rider}, + year = {2026}, + url = {https://github.com/hyperpolymath/knot-rider}, license = {MPL-2.0} } ---- == Harvard Style -{{AUTHOR_LAST}}, {{AUTHOR_INITIALS}} ({{CURRENT_YEAR}}) _{{PROJECT_NAME}}_ [Computer software]. Available at: https://github.com/{{OWNER}}/{{PROJECT_NAME}} +Jewell, J. (2026) _knot-rider_ [Computer software]. Available at: https://github.com/hyperpolymath/knot-rider == OSCOLA -{{AUTHOR}}, '{{PROJECT_NAME}}' ({{CURRENT_YEAR}}) +Jonathan D.A. Jewell, 'knot-rider' (2026) == MLA -{{AUTHOR_LAST}}, {{AUTHOR_FIRST}} "{{PROJECT_NAME}}." {{CURRENT_YEAR}}, github.com/{{OWNER}}/{{PROJECT_NAME}}. +Jewell, Jonathan "knot-rider." 2026, github.com/hyperpolymath/knot-rider. == APA 7 -{{AUTHOR_LAST}}, {{AUTHOR_INITIALS}} ({{CURRENT_YEAR}}). _{{PROJECT_NAME}}_ [Computer software]. GitHub. https://github.com/{{OWNER}}/{{PROJECT_NAME}} +Jewell, J. (2026). _knot-rider_ [Computer software]. GitHub. https://github.com/hyperpolymath/knot-rider == See Also diff --git a/docs/attribution/MAINTAINERS.adoc b/docs/attribution/MAINTAINERS.adoc index 7908bff..aa23a55 100644 --- a/docs/attribution/MAINTAINERS.adoc +++ b/docs/attribution/MAINTAINERS.adoc @@ -11,9 +11,9 @@ This document lists the maintainers of this project and their responsibilities. |=== | Name | Role | Contact -| {{AUTHOR}} +| Jonathan D.A. Jewell | Lead Maintainer -| https://github.com/{{OWNER}}[@{{OWNER}}] +| https://github.com/hyperpolymath[@hyperpolymath] |=== == Responsibilities diff --git a/docs/decisions/0001-adopt-rsr-standard.adoc b/docs/decisions/0001-adopt-rsr-standard.adoc index e8c6ed5..ab983a8 100644 --- a/docs/decisions/0001-adopt-rsr-standard.adoc +++ b/docs/decisions/0001-adopt-rsr-standard.adoc @@ -2,7 +2,7 @@ // Copyright (c) Jonathan D.A. Jewell = Architecture Decision Record: 0001-adopt-rsr-standard - + # 1. Adopt Rhodium Standard Repository (RSR) Template @@ -53,7 +53,7 @@ The RSR template provides: New repositories are created by cloning the template: ```bash -git clone https://github.com/{{OWNER}}/rsr-template-repo new-repo-name +git clone https://github.com/hyperpolymath/rsr-template-repo new-repo-name cd new-repo-name rm -rf .git && git init ``` diff --git a/docs/developer/ABI-FFI-README.adoc b/docs/developer/ABI-FFI-README.adoc index 95d0c82..9cad716 100644 --- a/docs/developer/ABI-FFI-README.adoc +++ b/docs/developer/ABI-FFI-README.adoc @@ -1,9 +1,7 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell = ABI/FFI Standards -{{~ Aditionally delete this line and fill out the template below ~}} - -# {{PROJECT}} ABI/FFI Documentation +# knot-rider ABI/FFI Documentation ## Overview @@ -29,7 +27,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ▼ ┌─────────────────────────────────────────────┐ │ C Headers (auto-generated) │ -│ generated/abi/{{project}}.h │ +│ generated/abi/knot_rider.h │ └─────────────────┬───────────────────────────┘ │ │ imported by @@ -42,7 +40,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ - Memory-safe by default │ └─────────────────┬───────────────────────────┘ │ - │ compiled to lib{{project}}.so/.a + │ compiled to libknot_rider.so/.a ▼ ┌─────────────────────────────────────────────┐ │ Any Language via C ABI │ @@ -53,7 +51,7 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: ## Directory Structure ``` -{{project}}/ +knot_rider/ ├── src/ │ ├── abi/ # ABI definitions (Idris2) │ │ ├── Types.idr # Core type definitions with proofs @@ -70,11 +68,11 @@ This library follows the **Hyperpolymath RSR Standard** for ABI and FFI design: │ ├── test/ │ │ └── integration_test.zig │ └── include/ -│ └── {{project}}.h # C header (optional, can be generated) +│ └── knot_rider.h # C header (optional, can be generated) │ ├── generated/ # Auto-generated files │ └── abi/ -│ └── {{project}}.h # Generated from Idris2 ABI +│ └── knot_rider.h # Generated from Idris2 ABI │ └── bindings/ # Language-specific wrappers (optional) ├── rust/ @@ -202,7 +200,7 @@ zig build test # Run tests ```bash cd src/abi -idris2 --cg c-header Types.idr -o ../../generated/abi/{{project}}.h +idris2 --cg c-header Types.idr -o ../../generated/abi/knot_rider.h ``` ### Cross-Compile @@ -225,32 +223,32 @@ zig build -Dtarget=x86_64-windows ### From C ```c -#include "{{project}}.h" +#include "knot_rider.h" int main() { - void* handle = {{project}}_init(); + void* handle = knot_rider_init(); if (!handle) return 1; - int result = {{project}}_process(handle, 42); + int result = knot_rider_process(handle, 42); if (result != 0) { - const char* err = {{project}}_last_error(); + const char* err = knot_rider_last_error(); fprintf(stderr, "Error: %s\n", err); } - {{project}}_free(handle); + knot_rider_free(handle); return 0; } ``` Compile with: ```bash -gcc -o example example.c -l{{project}} -L./zig-out/lib +gcc -o example example.c -lknot_rider -L./zig-out/lib ``` ### From Idris2 ```idris -import {{PROJECT}}.ABI.Foreign +import Abi.Foreign main : IO () main = do @@ -267,22 +265,22 @@ main = do ### From Rust ```rust -#[link(name = "{{project}}")] +#[link(name = "knot_rider")] extern "C" { - fn {{project}}_init() -> *mut std::ffi::c_void; - fn {{project}}_free(handle: *mut std::ffi::c_void); - fn {{project}}_process(handle: *mut std::ffi::c_void, input: u32) -> i32; + fn knot_rider_init() -> *mut std::ffi::c_void; + fn knot_rider_free(handle: *mut std::ffi::c_void); + fn knot_rider_process(handle: *mut std::ffi::c_void, input: u32) -> i32; } fn main() { unsafe { - let handle = {{project}}_init(); + let handle = knot_rider_init(); assert!(!handle.is_null()); - let result = {{project}}_process(handle, 42); + let result = knot_rider_process(handle, 42); assert_eq!(result, 0); - {{project}}_free(handle); + knot_rider_free(handle); } } ``` @@ -290,21 +288,21 @@ fn main() { ### From Julia ```julia -const lib{{project}} = "lib{{project}}" +const libknot_rider = "libknot_rider" function init() - handle = ccall((:{{project}}_init, lib{{project}}), Ptr{Cvoid}, ()) + handle = ccall((:knot_rider_init, libknot_rider), Ptr{Cvoid}, ()) handle == C_NULL && error("Failed to initialize") handle end function process(handle, input) - result = ccall((:{{project}}_process, lib{{project}}), Cint, (Ptr{Cvoid}, UInt32), handle, input) + result = ccall((:knot_rider_process, libknot_rider), Cint, (Ptr{Cvoid}, UInt32), handle, input) result end function cleanup(handle) - ccall((:{{project}}_free, lib{{project}}), Cvoid, (Ptr{Cvoid},), handle) + ccall((:knot_rider_free, libknot_rider), Cvoid, (Ptr{Cvoid},), handle) end # Usage @@ -358,7 +356,7 @@ When modifying the ABI/FFI: 2. **Generate C header** ```bash - idris2 --cg c-header src/interface/Abi/Types.idr -o generated/abi/{{project}}.h + idris2 --cg c-header src/interface/Abi/Types.idr -o generated/abi/knot_rider.h ``` 3. **Update FFI implementation** (`ffi/zig/src/main.zig`) @@ -377,10 +375,10 @@ When modifying the ABI/FFI: ## License -{{LICENSE}} +MPL-2.0 ## See Also - [Idris2 Documentation](https://idris2.readthedocs.io) - [Zig Documentation](https://ziglang.org/documentation/master/) -- [Rhodium Standard Repositories](https://github.com/{{OWNER}}/rhodium-standard-repositories) +- [Rhodium Standard Repositories](https://github.com/hyperpolymath/rhodium-standard-repositories) diff --git a/docs/onboarding/QUICKSTART-DEV.adoc b/docs/onboarding/QUICKSTART-DEV.adoc index 80321fe..bb752be 100644 --- a/docs/onboarding/QUICKSTART-DEV.adoc +++ b/docs/onboarding/QUICKSTART-DEV.adoc @@ -1,14 +1,13 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell // Template: QUICKSTART-DEV.adoc — clone → build → test → PR -// Replace rsr-template-repo, {{BUILD_CMD}}, {{TEST_CMD}}, {{LANG_STACK}} with actuals -= rsr-template-repo — Quick Start for Developers += knot-rider — Quick Start for Developers :toc: :toclevels: 2 == Tech Stack -{{LANG_STACK}} +Idris2 (ABI, scaffolded) + Zig 0.16.0 (FFI) == Set Up Development Environment @@ -32,14 +31,14 @@ just setup-dev [source,bash] ---- -{{BUILD_CMD}} +cd src/interface/ffi && zig build ---- == Test [source,bash] ---- -{{TEST_CMD}} +cd src/interface/ffi && zig build test ---- == Project Structure @@ -81,10 +80,13 @@ just panic-scan # No new security issues == Contractile Invariants -Read `.machine_readable/MUST.contractile` before making changes. -Key invariants that must never be violated: +Read `.machine_readable/contractiles/must/Mustfile.a2ml` before making changes. +Key invariants that must never be violated (critical severity): -{{MUST_INVARIANTS}} +* LICENSE, README.adoc, SECURITY.md, 0-AI-MANIFEST.a2ml must exist +* GOVERNANCE.adoc/md, MAINTAINERS.adoc/md, .github/CODEOWNERS must exist +* `.machine_readable/` and its required contractile directories/files must exist +* The 6a2 directory must exist with its required files == LLM/AI Agent Development diff --git a/docs/onboarding/QUICKSTART-MAINTAINER.adoc b/docs/onboarding/QUICKSTART-MAINTAINER.adoc index 7642fa6..9b5d623 100644 --- a/docs/onboarding/QUICKSTART-MAINTAINER.adoc +++ b/docs/onboarding/QUICKSTART-MAINTAINER.adoc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell // Template: QUICKSTART-MAINTAINER.adoc — packaging, deploying, and maintaining -// Replace rsr-template-repo, {{PACKAGE_NAME}}, {{DEPS}} with actuals +// Replace rsr-template-repo, knot-rider, Zig 0.16.0 with actuals = rsr-template-repo — Quick Start for Platform Maintainers :toc: :toclevels: 2 @@ -13,7 +13,7 @@ distribution on your platform. == Runtime Dependencies -{{DEPS}} +Zig 0.16.0 == Build from Source @@ -24,7 +24,7 @@ cd rsr-template-repo just build-release ---- -Output: `{{BUILD_OUTPUT_PATH}}` +Output: `src/interface/ffi/zig-out` == Packaging @@ -59,10 +59,10 @@ Files installed: | `$PREFIX/bin/` | Executables -| `$PREFIX/share/{{PACKAGE_NAME}}/` +| `$PREFIX/share/knot-rider/` | Data files, assets -| `$PREFIX/share/doc/{{PACKAGE_NAME}}/` +| `$PREFIX/share/doc/knot-rider/` | Documentation | `$PREFIX/share/applications/` @@ -74,9 +74,9 @@ Files installed: == Configuration -Default config location: `$XDG_CONFIG_HOME/{{PACKAGE_NAME}}/config.toml` +Default config location: `$XDG_CONFIG_HOME/knot-rider/config.toml` -Fallback: `$HOME/.config/{{PACKAGE_NAME}}/config.toml` +Fallback: `$HOME/.config/knot-rider/config.toml` == Health Checks @@ -96,7 +96,7 @@ just build-release just install --prefix=/usr/local ---- -Or via OPSM: `opsm update {{PACKAGE_NAME}}` +Or via OPSM: `opsm update knot-rider` == Security Notes @@ -111,8 +111,8 @@ For deploying multiple instances (e.g., different users or tenants): [source,bash] ---- -just install --prefix=/opt/{{PACKAGE_NAME}}-instance1 --config=/etc/{{PACKAGE_NAME}}/instance1.toml -just install --prefix=/opt/{{PACKAGE_NAME}}-instance2 --config=/etc/{{PACKAGE_NAME}}/instance2.toml +just install --prefix=/opt/knot-rider-instance1 --config=/etc/knot-rider/instance1.toml +just install --prefix=/opt/knot-rider-instance2 --config=/etc/knot-rider/instance2.toml ---- Each instance has isolated config, data, and logs. diff --git a/docs/practice/AI-CONVENTIONS.adoc b/docs/practice/AI-CONVENTIONS.adoc index 320b150..19e30f0 100644 --- a/docs/practice/AI-CONVENTIONS.adoc +++ b/docs/practice/AI-CONVENTIONS.adoc @@ -2,7 +2,7 @@ // Copyright (c) Jonathan D.A. Jewell = AI Conventions - + # AI Conventions (Authoritative Source) @@ -29,9 +29,9 @@ Per-tool config files (.cursorrules, .clinerules, etc.) reference this document. ## Author Attribution -- Name: **{{AUTHOR}}** -- Email: **{{AUTHOR_EMAIL}}** -- Copyright: `Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}>` +- Name: **Jonathan D.A. Jewell** +- Email: **j.d.a.jewell@open.ac.uk** +- Copyright: `Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) ` ## State Files diff --git a/docs/practice/STATE-VISUALIZER-GUIDE.adoc b/docs/practice/STATE-VISUALIZER-GUIDE.adoc index 49dfd55..6252911 100644 --- a/docs/practice/STATE-VISUALIZER-GUIDE.adoc +++ b/docs/practice/STATE-VISUALIZER-GUIDE.adoc @@ -1,7 +1,7 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell = TOPOLOGY.md — Generation Guide -{{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Jonathan D.A. Jewell (hyperpolymath) :toc: :sectnums: @@ -153,4 +153,4 @@ _structured data_ for tooling. Both should agree. == Copyright -Copyright (c) {{CURRENT_YEAR}} {{AUTHOR}} ({{OWNER}}) <{{AUTHOR_EMAIL}}> +Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) diff --git a/docs/status/PROOF-NEEDS.adoc b/docs/status/PROOF-NEEDS.adoc index 96b529d..974db9a 100644 --- a/docs/status/PROOF-NEEDS.adoc +++ b/docs/status/PROOF-NEEDS.adoc @@ -2,7 +2,7 @@ // Copyright (c) Jonathan D.A. Jewell // Template: rsr-template-repo/docs/status/PROOF-NEEDS.adoc // Authoritative master list: ~/Desktop/PROOF-REQUIREMENTS-MASTER.adoc -= Proof Requirements — {{PROJECT}} += Proof Requirements — knot_rider == Proof Tier diff --git a/docs/status/PROOF-STATUS.adoc b/docs/status/PROOF-STATUS.adoc index aca702c..67da36a 100644 --- a/docs/status/PROOF-STATUS.adoc +++ b/docs/status/PROOF-STATUS.adoc @@ -2,7 +2,7 @@ // Copyright (c) Jonathan D.A. Jewell // Template: rsr-template-repo/docs/status/PROOF-STATUS.adoc // Tracks proof completion. Requirements defined in PROOF-NEEDS.adoc -= Proof Status — {{PROJECT}} += Proof Status — knot_rider == Summary diff --git a/docs/status/READINESS.adoc b/docs/status/READINESS.adoc index 32647e6..d510284 100644 --- a/docs/status/READINESS.adoc +++ b/docs/status/READINESS.adoc @@ -1,10 +1,10 @@ // SPDX-License-Identifier: CC-BY-SA-4.0 // Copyright (c) Jonathan D.A. Jewell -= {{PROJECT_NAME}} Component Readiness Assessment += knot-rider Component Readiness Assessment -*Standard:* link:https://{{FORGE}}/{{OWNER}}/standards/tree/main/component-readiness-grades[Component Readiness Grades (CRG) v2.0 STRICT] + -*Assessed:* {{CURRENT_DATE}} + -*Assessor:* {{AUTHOR}} + +*Standard:* link:https://github.com/hyperpolymath/standards/tree/main/component-readiness-grades[Component Readiness Grades (CRG) v2.0 STRICT] + +*Assessed:* 2026-07-27 + +*Assessor:* Jonathan D.A. Jewell + *Previous assessment:* __ *Current Grade:* X @@ -59,7 +59,7 @@ Below B, any publication must be explicitly abstract or provisional. ''' -== 2. Headline Evidence (as of {{CURRENT_DATE}}) +== 2. Headline Evidence (as of 2026-07-27) [cols="2,3,3", options="header"] |=== @@ -67,7 +67,7 @@ Below B, any publication must be explicitly abstract or provisional. | Test count | __ | `.machine_readable/6a2/STATE.a2ml` or CI | Formal-verification posture | __ | grep of proof dirs -| Dangerous patterns (`assert_total`, `unsafeCoerce`, `Obj.magic`) | __ | grep {{CURRENT_DATE}} +| Dangerous patterns (`assert_total`, `unsafeCoerce`, `Obj.magic`) | __ | grep 2026-07-27 | Per-unit README coverage | __ | filesystem scan of unit dirs | CI status | __ | `.github/workflows/` | RSR mandatory workflows | __ | `.github/workflows/` @@ -87,9 +87,9 @@ unless noted. |=== | Component | Grade | Posture | Evidence Summary | Promotion blocker | Last Assessed -| __ | X/F/E/D/C/B/A | __ | __ | __ | {{CURRENT_DATE}} -| __ | … | … | … | … | {{CURRENT_DATE}} -| __ | … | … | … | … | {{CURRENT_DATE}} +| __ | X/F/E/D/C/B/A | __ | __ | __ | 2026-07-27 +| __ | … | … | … | … | 2026-07-27 +| __ | … | … | … | … | 2026-07-27 |=== *Rules of thumb for populating this table:* @@ -164,7 +164,7 @@ Real-world external feedback confirming value. Populate ''' -== 7. Summary ({{CURRENT_DATE}}) +== 7. Summary (2026-07-27) * Project grade: __. Why: _<1-2 line justification>_. * Delta since last assessment: __. diff --git a/examples/web-project-deno.json b/examples/web-project-deno.json index 028e4f1..5ddd3bd 100644 --- a/examples/web-project-deno.json +++ b/examples/web-project-deno.json @@ -10,7 +10,7 @@ "imports": { "rescript": "^12.0.0", "@rescript/core": "npm:@rescript/core@^1.6.0", - "safe-dom/": "https://raw.githubusercontent.com/{{OWNER}}/rescript-dom-mounter/main/src/", + "safe-dom/": "https://raw.githubusercontent.com/hyperpolymath/rescript-dom-mounter/main/src/", "proven/": "../proven/bindings/rescript/src/" }, "compilerOptions": { diff --git a/scripts/check-root-shape.sh b/scripts/check-root-shape.sh index 8f75343..63ac181 100644 --- a/scripts/check-root-shape.sh +++ b/scripts/check-root-shape.sh @@ -5,8 +5,8 @@ # check-root-shape.sh — fail when the repository root contains entries that # are not on the canonical allowlist (.machine_readable/root-allow.txt). # -# Companion to scripts/validate-template.sh: that script enforces required -# files; this one enforces that nothing else has crept in. +# This script enforces that nothing extra has crept in at the repository +# root (required-file presence is enforced by must-check / must.a2ml). # # Exit codes: # 0 — root matches allowlist diff --git a/scripts/validate-template.sh b/scripts/validate-template.sh deleted file mode 100755 index a1608fd..0000000 --- a/scripts/validate-template.sh +++ /dev/null @@ -1,382 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# RSR Template Validation Script -# Verifies that a repository follows the RSR template structure and contains all required files -# -# Exit codes: -# 0 = validation passed -# 1 = validation failed with errors -# 2 = validation failed with warnings (but can proceed) - -set -euo pipefail - -REPO_ROOT="${1:-.}" -VERBOSE="${2:-0}" -ERRORS=0 -WARNINGS=0 - -# ANSI colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Helper functions -log_error() { - echo -e "${RED}ERROR${NC}: $*" >&2 - ERRORS=$((ERRORS + 1)) -} - -log_warning() { - echo -e "${YELLOW}WARN${NC}: $*" >&2 - WARNINGS=$((WARNINGS + 1)) -} - -log_info() { - echo -e "${BLUE}INFO${NC}: $*" >&2 -} - -log_pass() { - echo -e "${GREEN}PASS${NC}: $*" >&2 -} - -check_file_exists() { - local file="$1" - local description="${2:-}" - if [ -f "$REPO_ROOT/$file" ]; then - [ "$VERBOSE" = "1" ] && log_pass "File exists: $file" - return 0 - else - log_error "Required file missing: $file ${description:+(${description})}" - return 1 - fi -} - -check_dir_exists() { - local dir="$1" - local description="${2:-}" - if [ -d "$REPO_ROOT/$dir" ]; then - [ "$VERBOSE" = "1" ] && log_pass "Directory exists: $dir" - return 0 - else - log_error "Required directory missing: $dir ${description:+(${description})}" - return 1 - fi -} - -# Case-tolerant ABI seam checks: accept the canonical case-consistent -# src/interface/Abi/ (matches `module Abi.*`) OR a lowercase src/interface/abi/ -# that some downstream repos ship. Never require BOTH (that would be a case-fold -# collision on case-insensitive filesystems). -check_abi_dir_exists() { - local description="${1:-}" - if [ -d "$REPO_ROOT/src/interface/Abi" ] || [ -d "$REPO_ROOT/src/interface/abi" ]; then - [ "$VERBOSE" = "1" ] && log_pass "Directory exists: src/interface/{Abi,abi}" - return 0 - fi - log_error "Required directory missing: src/interface/Abi ${description:+(${description})}" - return 1 -} -check_abi_file_exists() { - local fname="$1" - local description="${2:-}" - if [ -f "$REPO_ROOT/src/interface/Abi/$fname" ] || [ -f "$REPO_ROOT/src/interface/abi/$fname" ]; then - [ "$VERBOSE" = "1" ] && log_pass "File exists: src/interface/{Abi,abi}/$fname" - return 0 - fi - log_error "Required file missing: src/interface/Abi/$fname ${description:+(${description})}" - return 1 -} - -has_spdx_header() { - local file="$1" - if head -10 "$file" | grep -q "SPDX-License-Identifier"; then - return 0 - fi - return 1 -} - -has_placeholder() { - local file="$1" - if grep -q "{{REPO\|{{OWNER\|{{FORGE\|{{PROJECT\|{{project\|{{AUTHOR" "$file" 2>/dev/null; then - return 0 - fi - return 1 -} - -#============================================================================== -# VALIDATION PHASE 1: CORE STRUCTURE -#============================================================================== - -echo "" -log_info "Phase 1: Core repository structure" -echo "" - -# Root files -check_file_exists "0-AI-MANIFEST.a2ml" "AI manifest (universal entry point)" -check_file_exists "README.adoc" "High-level pitch" -check_file_exists "EXPLAINME.adoc" "Developer deep-dive" -check_file_exists "LICENSE" "License file" -check_file_exists "Justfile" "Task runner" -check_file_exists "AUDIT.adoc" "Release audit gate" - -# Directories -check_dir_exists ".machine_readable" "Machine-readable metadata" -check_dir_exists ".github" "GitHub community metadata" -check_abi_dir_exists "Idris2 ABI definitions" -check_dir_exists "src/interface/ffi" "Zig FFI implementation" -check_dir_exists "src/interface/generated/abi" "Generated C headers" -check_dir_exists "docs" "Documentation" - -#============================================================================== -# VALIDATION PHASE 2: MACHINE-READABLE METADATA -#============================================================================== - -echo "" -log_info "Phase 2: Machine-readable metadata (.machine_readable/)" -echo "" - -check_file_exists ".machine_readable/6a2/STATE.a2ml" "Project state" -check_file_exists ".machine_readable/6a2/META.a2ml" "Architecture decisions" -check_file_exists ".machine_readable/6a2/ECOSYSTEM.a2ml" "Ecosystem position" -check_file_exists ".machine_readable/6a2/anchors/ANCHOR.a2ml" "Semantic boundary anchor" -check_file_exists ".machine_readable/policies/MAINTENANCE-AXES.a2ml" "Maintenance axes" - -#============================================================================== -# VALIDATION PHASE 3: REQUIRED WORKFLOWS (17 minimum) -#============================================================================== - -echo "" -log_info "Phase 3: GitHub Actions workflows" -echo "" - -REQUIRED_WORKFLOWS=( - "hypatia-scan.yml" - "codeql.yml" - "scorecard.yml" - "quality.yml" - "mirror.yml" - "instant-sync.yml" - "guix-policy.yml" - "security-policy.yml" - "wellknown-enforcement.yml" - "workflow-linter.yml" - "npm-bun-blocker.yml" - "ts-blocker.yml" - "secret-scanner.yml" -) - -# Check required workflows -for workflow in "${REQUIRED_WORKFLOWS[@]}"; do - if [ -f "$REPO_ROOT/.github/workflows/$workflow" ]; then - [ "$VERBOSE" = "1" ] && log_pass "Workflow found: $workflow" - else - log_error "Required workflow missing: $workflow" - fi -done - -# Verify all workflows have SPDX headers and proper structure -WORKFLOW_FILES=$(find "$REPO_ROOT/.github/workflows" -name "*.yml" -type f 2>/dev/null || true) -WORKFLOW_COUNT=$(echo "$WORKFLOW_FILES" | grep -c "." || true) - -if [ "$WORKFLOW_COUNT" -ge 15 ]; then - log_pass "Found $WORKFLOW_COUNT workflows (>= 15 expected)" -else - log_warning "Found only $WORKFLOW_COUNT workflows (expected >= 15)" -fi - -# Spot-check workflow files for issues -while IFS= read -r workflow_file; do - if [ -z "$workflow_file" ]; then continue; fi - - # Check for SPDX header (optional in YAML workflows, but best practice) - if ! head -5 "$workflow_file" | grep -q "SPDX-License-Identifier"; then - log_warning "Workflow missing SPDX header: $(basename "$workflow_file")" - fi - - # Check for proper YAML structure - if ! grep -q "^name:" "$workflow_file"; then - log_error "Workflow missing 'name' field: $(basename "$workflow_file")" - fi -done <<< "$WORKFLOW_FILES" - -#============================================================================== -# VALIDATION PHASE 4: ABI/FFI SOURCE FILES -#============================================================================== - -echo "" -log_info "Phase 4: Idris2 ABI and Zig FFI source files" -echo "" - -# Idris2 ABI files -check_abi_file_exists "Types.idr" "Core type definitions" -check_abi_file_exists "Layout.idr" "Memory layout specifications" -check_abi_file_exists "Foreign.idr" "FFI foreign declarations" - -# Zig FFI files -check_file_exists "src/interface/ffi/build.zig" "Zig build configuration" -check_file_exists "src/interface/ffi/src/main.zig" "Zig implementation" -check_file_exists "src/interface/ffi/test/integration_test.zig" "Integration tests" - -#============================================================================== -# VALIDATION PHASE 5: PLACEHOLDER TOKENS -#============================================================================== - -echo "" -log_info "Phase 5: Placeholder token replacement (skipped in template repo)" -echo "" - -# Note: Template repo is allowed to have placeholders -# For derived repos, we'd check that placeholders are replaced -if [ "$(basename "$REPO_ROOT")" = "rsr-template-repo" ]; then - log_pass "Skipping placeholder check for template repo" -else - # Check that key files don't have unresolved placeholders - for file in "$REPO_ROOT/README.adoc" "$REPO_ROOT/Justfile" "$REPO_ROOT/.machine_readable/6a2/STATE.a2ml"; do - if [ -f "$file" ]; then - if has_placeholder "$file"; then - log_warning "File contains unresolved placeholders: $(basename "$file")" - fi - fi - done -fi - -#============================================================================== -# VALIDATION PHASE 6: SPDX LICENSE HEADERS -#============================================================================== - -echo "" -log_info "Phase 6: SPDX License Headers" -echo "" - -# Check source files for SPDX headers (excluding build artifacts) -SOURCE_FILES=$(find "$REPO_ROOT/src" -type f \( -name "*.idr" -o -name "*.zig" \) \ - ! -path "*/.zig-cache/*" ! -path "*/zig-cache/*" 2>/dev/null || true) -SOURCE_COUNT=$(echo "$SOURCE_FILES" | grep -c "." || true) -SPDX_COUNT=0 - -while IFS= read -r src_file; do - if [ -z "$src_file" ]; then continue; fi - if has_spdx_header "$src_file"; then - SPDX_COUNT=$((SPDX_COUNT + 1)) - else - log_warning "Source file missing SPDX header: $(basename "$src_file")" - fi -done <<< "$SOURCE_FILES" - -if [ "$SOURCE_COUNT" -gt 0 ]; then - PERCENT=$((SPDX_COUNT * 100 / SOURCE_COUNT)) - log_pass "SPDX headers: $SPDX_COUNT/$SOURCE_COUNT ($PERCENT%)" - if [ "$PERCENT" -lt 100 ]; then - log_warning "Not all source files have SPDX headers" - fi -fi - -#============================================================================== -# VALIDATION PHASE 7: BUILD VERIFICATION -#============================================================================== - -echo "" -log_info "Phase 7: Build system verification" -echo "" - -# Check Zig build -if [ -f "$REPO_ROOT/src/interface/ffi/build.zig" ]; then - if command -v zig &> /dev/null; then - cd "$REPO_ROOT/src/interface/ffi" - if zig build 2>&1 | grep -q "error"; then - log_error "Zig build failed" - else - log_pass "Zig build successful" - fi - cd - > /dev/null - else - log_warning "Zig compiler not found - skipping Zig build check" - fi -else - log_error "Zig build.zig not found" -fi - -# Check Idris2. Prefer a REAL typecheck via the package (abi.ipkg sets the -# sourcedir so the `module Abi.*` namespace resolves); this catches namespace / -# path / import breakage that a bare per-file `idris2 --check` masks as a -# tolerated "module name does not match file name" warning. -if command -v idris2 &> /dev/null; then - if [ -f "$REPO_ROOT/abi.ipkg" ]; then - if (cd "$REPO_ROOT" && idris2 --typecheck abi.ipkg) > /dev/null 2>&1; then - log_pass "Idris2 ABI typechecks (abi.ipkg)" - else - log_error "Idris2 ABI does NOT typecheck (abi.ipkg)" - fi - else - # No package: fall back to a best-effort per-file syntax check (warns on - # the expected namespace/path mismatch). Look in either case of the dir. - IDS_FILES=$(find "$REPO_ROOT/src/interface/Abi" "$REPO_ROOT/src/interface/abi" -name "*.idr" -type f 2>/dev/null || true) - while IFS= read -r ids_file; do - if [ -z "$ids_file" ]; then continue; fi - if ! idris2 --check "$ids_file" 2>&1 | grep -q "Error"; then - log_pass "Idris2 syntax OK: $(basename "$ids_file")" - else - log_warning "Idris2 syntax issue: $(basename "$ids_file")" - fi - done <<< "$IDS_FILES" - fi -else - log_warning "Idris2 compiler not found - skipping Idris2 syntax checks" -fi - -#============================================================================== -# VALIDATION PHASE 8: DOCUMENTATION -#============================================================================== - -echo "" -log_info "Phase 8: Documentation requirements" -echo "" - -check_file_exists "docs/developer/ABI-FFI-README.adoc" "ABI/FFI documentation" -# TOPOLOGY may live at root or under docs/architecture/, .md or .adoc -if [ -f "$REPO_ROOT/TOPOLOGY.adoc" ] || [ -f "$REPO_ROOT/TOPOLOGY.md" ] || \ - [ -f "$REPO_ROOT/docs/architecture/TOPOLOGY.adoc" ] || [ -f "$REPO_ROOT/docs/architecture/TOPOLOGY.md" ]; then - [ "$VERBOSE" = "1" ] && log_pass "Architecture topology found" -else - log_error "Required file missing: TOPOLOGY (root or docs/architecture/, .adoc or .md)" -fi -# CONTRIBUTING.md may live at root or in .github/ (GitHub auto-discovers either) -if [ -f "$REPO_ROOT/CONTRIBUTING.md" ] || [ -f "$REPO_ROOT/.github/CONTRIBUTING.md" ]; then - [ "$VERBOSE" = "1" ] && log_pass "Contribution guide found" -else - log_error "Required file missing: CONTRIBUTING.md (root or .github/)" -fi - -# Governance can be at root or in docs/governance/ -if [ -f "$REPO_ROOT/GOVERNANCE.adoc" ] || [ -f "$REPO_ROOT/GOVERNANCE.md" ] || [ -d "$REPO_ROOT/docs/governance" ]; then - [ "$VERBOSE" = "1" ] && log_pass "Governance files found" -else - log_warning "Governance documentation not found" -fi - -#============================================================================== -# VALIDATION SUMMARY -#============================================================================== - -echo "" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "VALIDATION SUMMARY" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "" -echo -e "Errors: ${RED}${ERRORS}${NC}" -echo -e "Warnings: ${YELLOW}${WARNINGS}${NC}" -echo "" - -if [ "$ERRORS" -eq 0 ]; then - echo -e "${GREEN}✓ Validation PASSED${NC}" - [ "$WARNINGS" -gt 0 ] && echo -e " (with $WARNINGS warnings)" - exit 0 -else - echo -e "${RED}✗ Validation FAILED${NC}" - echo " Please fix the errors above." - exit 1 -fi diff --git a/src/interface/ffi/build.zig b/src/interface/ffi/build.zig index 2607c11..e736431 100644 --- a/src/interface/ffi/build.zig +++ b/src/interface/ffi/build.zig @@ -1,19 +1,42 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell // -// Template FFI Build Configuration (Zig 0.15.2+) -// Note: This is a minimal build file that demonstrates Zig integration +// knot-rider FFI build (Zig 0.16.0+) +// +// Builds src/main.zig as a C-ABI static library (the FFI seam consumed by +// the Idris2 ABI side) and wires `zig build test` to the real test suites +// in src/main.zig and test/integration_test.zig. const std = @import("std"); pub fn build(b: *std.Build) void { - _ = b.standardTargetOptions(.{}); - _ = b.standardOptimizeOption(.{}); + const target = b.standardTargetOptions(.{}); + const optimize = b.standardOptimizeOption(.{}); + + const mod = b.createModule(.{ + .root_source_file = b.path("src/main.zig"), + .target = target, + .optimize = optimize, + .link_libc = true, + }); + + const lib = b.addLibrary(.{ + .name = "knot_rider", + .root_module = mod, + .linkage = .static, + }); + b.installArtifact(lib); + + const test_step = b.step("test", "Run the FFI unit + integration tests"); + + const main_tests = b.addTest(.{ .root_module = mod }); + test_step.dependOn(&b.addRunArtifact(main_tests).step); - // In Zig 0.15+, tests are run directly with: - // zig build-exe -ftest-runner src/main.zig - // zig build-exe -ftest-runner test/integration_test.zig - // - // This minimal build file provides scaffolding for future expansion. - // Tests can be invoked via command line without explicit build.zig configuration. + const integration_mod = b.createModule(.{ + .root_source_file = b.path("test/integration_test.zig"), + .target = target, + .optimize = optimize, + }); + const integration_tests = b.addTest(.{ .root_module = integration_mod }); + test_step.dependOn(&b.addRunArtifact(integration_tests).step); } diff --git a/src/interface/ffi/src/main.zig b/src/interface/ffi/src/main.zig index f1b2633..6f049ae 100644 --- a/src/interface/ffi/src/main.zig +++ b/src/interface/ffi/src/main.zig @@ -1,6 +1,6 @@ // SPDX-License-Identifier: MPL-2.0 // Copyright (c) Jonathan D.A. Jewell -// {{PROJECT}} FFI Implementation +// knot_rider FFI Implementation // // This module implements the C-compatible FFI declared in src/abi/Foreign.idr // All types and layouts must match the Idris2 ABI definitions. @@ -10,7 +10,7 @@ const std = @import("std"); // Version information (keep in sync with project) const VERSION = "0.1.0"; -const BUILD_INFO = "{{PROJECT}} built with Zig " ++ @import("builtin").zig_version_string; +const BUILD_INFO = "knot_rider built with Zig " ++ @import("builtin").zig_version_string; /// Thread-local error storage threadlocal var last_error: ?[]const u8 = null; @@ -38,8 +38,11 @@ pub const Result = enum(c_int) { null_pointer = 4, }; -/// Library handle (opaque to prevent direct access) -pub const Handle = opaque { +/// Library handle. Opaque to C callers because only pointers to it ever +/// cross the FFI boundary and the struct definition is never exposed in the +/// generated headers — Zig's `opaque` type cannot carry fields (0.16+), so a +/// plain `struct` is used instead and kept opaque *by convention*. +pub const Handle = struct { // Internal state hidden from C allocator: std.mem.Allocator, initialized: bool, @@ -52,7 +55,7 @@ pub const Handle = opaque { /// Initialize the library /// Returns a handle, or null on failure -export fn {{project}}_init() ?*Handle { +export fn knot_rider_init() ?*Handle { const allocator = std.heap.c_allocator; const handle = allocator.create(Handle) catch { @@ -71,7 +74,7 @@ export fn {{project}}_init() ?*Handle { } /// Free the library handle -export fn {{project}}_free(handle: ?*Handle) void { +export fn knot_rider_free(handle: ?*Handle) void { const h = handle orelse return; const allocator = h.allocator; @@ -87,7 +90,7 @@ export fn {{project}}_free(handle: ?*Handle) void { //============================================================================== /// Process data (example operation) -export fn {{project}}_process(handle: ?*Handle, input: u32) Result { +export fn knot_rider_process(handle: ?*Handle, input: u32) Result { const h = handle orelse { setError("Null handle"); return .null_pointer; @@ -111,7 +114,7 @@ export fn {{project}}_process(handle: ?*Handle, input: u32) Result { /// Get a string result (example) /// Caller must free the returned string -export fn {{project}}_get_string(handle: ?*Handle) ?[*:0]const u8 { +export fn knot_rider_get_string(handle: ?*Handle) ?[*:0]const u8 { const h = handle orelse { setError("Null handle"); return null; @@ -133,7 +136,7 @@ export fn {{project}}_get_string(handle: ?*Handle) ?[*:0]const u8 { } /// Free a string allocated by the library -export fn {{project}}_free_string(str: ?[*:0]const u8) void { +export fn knot_rider_free_string(str: ?[*:0]const u8) void { const s = str orelse return; const allocator = std.heap.c_allocator; @@ -146,7 +149,7 @@ export fn {{project}}_free_string(str: ?[*:0]const u8) void { //============================================================================== /// Process an array of data -export fn {{project}}_process_array( +export fn knot_rider_process_array( handle: ?*Handle, buffer: ?[*]const u8, len: u32, @@ -182,7 +185,7 @@ export fn {{project}}_process_array( /// Get the last error message /// Returns null if no error -export fn {{project}}_last_error() ?[*:0]const u8 { +export fn knot_rider_last_error() ?[*:0]const u8 { const err = last_error orelse return null; // Return C string (static storage, no need to free) @@ -196,12 +199,12 @@ export fn {{project}}_last_error() ?[*:0]const u8 { //============================================================================== /// Get the library version -export fn {{project}}_version() [*:0]const u8 { +export fn knot_rider_version() [*:0]const u8 { return VERSION.ptr; } /// Get build information -export fn {{project}}_build_info() [*:0]const u8 { +export fn knot_rider_build_info() [*:0]const u8 { return BUILD_INFO.ptr; } @@ -210,10 +213,10 @@ export fn {{project}}_build_info() [*:0]const u8 { //============================================================================== /// Callback function type (C ABI) -pub const Callback = *const fn (u64, u32) callconv(.C) u32; +pub const Callback = *const fn (u64, u32) callconv(.c) u32; /// Register a callback -export fn {{project}}_register_callback( +export fn knot_rider_register_callback( handle: ?*Handle, callback: ?Callback, ) Result { @@ -244,7 +247,7 @@ export fn {{project}}_register_callback( //============================================================================== /// Check if handle is initialized -export fn {{project}}_is_initialized(handle: ?*Handle) u32 { +export fn knot_rider_is_initialized(handle: ?*Handle) u32 { const h = handle orelse return 0; return if (h.initialized) 1 else 0; } @@ -254,22 +257,22 @@ export fn {{project}}_is_initialized(handle: ?*Handle) u32 { //============================================================================== test "lifecycle" { - const handle = {{project}}_init() orelse return error.InitFailed; - defer {{project}}_free(handle); + const handle = knot_rider_init() orelse return error.InitFailed; + defer knot_rider_free(handle); - try std.testing.expect({{project}}_is_initialized(handle) == 1); + try std.testing.expect(knot_rider_is_initialized(handle) == 1); } test "error handling" { - const result = {{project}}_process(null, 0); + const result = knot_rider_process(null, 0); try std.testing.expectEqual(Result.null_pointer, result); - const err = {{project}}_last_error(); + const err = knot_rider_last_error(); try std.testing.expect(err != null); } test "version" { - const ver = {{project}}_version(); + const ver = knot_rider_version(); const ver_str = std.mem.span(ver); try std.testing.expectEqualStrings(VERSION, ver_str); } diff --git a/tests/aspect_tests.sh b/tests/aspect_tests.sh index 028b2c0..c92fec6 100755 --- a/tests/aspect_tests.sh +++ b/tests/aspect_tests.sh @@ -39,7 +39,7 @@ fail() { red " FAIL: $1"; FAIL=$((FAIL + 1)); } warn() { yellow " WARN: $1"; WARN=$((WARN + 1)); } echo "═══════════════════════════════════════════════════════════════" -echo " {{PROJECT}} — Aspect Tests (Cross-Cutting Concerns)" +echo " knot_rider — Aspect Tests (Cross-Cutting Concerns)" echo "═══════════════════════════════════════════════════════════════" echo "" @@ -54,7 +54,7 @@ while IFS= read -r -d '' f; do warn "Missing SPDX header: $f" MISSING_SPDX=$((MISSING_SPDX + 1)) fi -done < <(find src/ -type f \( -name "*.rs" -o -name "*.zig" -o -name "*.res" -o -name "*.ex" -o -name "*.exs" -o -name "*.gleam" -o -name "*.idr" -o -name "*.sh" \) -print0 2>/dev/null) +done < <(find src/ \( -name ".zig-cache" -o -name "zig-out" \) -prune -o -type f \( -name "*.rs" -o -name "*.zig" -o -name "*.res" -o -name "*.ex" -o -name "*.exs" -o -name "*.gleam" -o -name "*.idr" -o -name "*.sh" \) -print0 2>/dev/null) if [ "$MISSING_SPDX" -eq 0 ]; then pass "All source files have SPDX headers" @@ -77,7 +77,9 @@ else fi # Coq/Lean dangerous patterns -DANGEROUS_PROOF=$(grep -rn '\bAdmitted\b\|\bsorry\b\|\bunsafeCoerce\b\|\bObj\.magic\b' src/ verification/ 2>/dev/null | grep -v "test" | grep -v "comment" || true) +# --exclude *.adoc/*.md: prose that documents/prohibits these patterns by +# name (e.g. "NO Admitted allowed") is not the same as code that uses them. +DANGEROUS_PROOF=$(grep -rn --exclude='*.adoc' --exclude='*.md' '\bAdmitted\b\|\bsorry\b\|\bunsafeCoerce\b\|\bObj\.magic\b' src/ verification/ 2>/dev/null | grep -v "test" | grep -v "comment" | grep -v "NO Admitted allowed" || true) if [ -n "$DANGEROUS_PROOF" ]; then fail "Dangerous proof patterns found:" echo "$DANGEROUS_PROOF" | head -5 diff --git a/tests/e2e.sh b/tests/e2e.sh index 11143fc..8311d01 100755 --- a/tests/e2e.sh +++ b/tests/e2e.sh @@ -62,7 +62,7 @@ skip_test() { } echo "═══════════════════════════════════════════════════════════════" -echo " {{PROJECT}} — End-to-End Tests" +echo " knot_rider — End-to-End Tests" echo "═══════════════════════════════════════════════════════════════" echo "" @@ -122,7 +122,7 @@ echo "" # else # STATUS=$(curl -s -o /dev/null -w "%{http_code}" -X POST "$VERISIM_URL/api/v1/hexads" \ # -H "Content-Type: application/json" \ -# -d '{"tool":"{{PROJECT}}","modality":"document","content":"e2e test"}') +# -d '{"tool":"knot_rider","modality":"document","content":"e2e test"}') # check_status "hexad POST" "201" "$STATUS" # fi diff --git a/tests/e2e/template_instantiation_test.sh b/tests/e2e/template_instantiation_test.sh deleted file mode 100755 index f991d5d..0000000 --- a/tests/e2e/template_instantiation_test.sh +++ /dev/null @@ -1,268 +0,0 @@ -#!/bin/bash -# SPDX-License-Identifier: MPL-2.0 -# Copyright (c) 2026 Jonathan D.A. Jewell (hyperpolymath) -# -# E2E Test: Template Instantiation -# Verifies that the template can be cloned and instantiated into a working project -# -# This test: -# 1. Clones the template to a temp directory -# 2. Replaces all placeholder tokens with test values -# 3. Validates the resulting repository structure -# 4. Verifies builds work after instantiation -# 5. Cleans up - -set -euo pipefail - -# Test configuration -TEMPLATE_ROOT="${1:-.}" -TEST_DIR="${TMPDIR:-/tmp}/rsr-template-test-$$" -TEST_REPO_NAME="test-instantiated-repo" -TEST_OWNER="test-owner" -TEST_FORGE="github" -TEST_AUTHOR="Test Author" -TEST_AUTHOR_EMAIL="test@example.com" -TEST_PROJECT_NAME="Test Project" -TEST_DESCRIPTION="A test project instantiated from the RSR template" -TEST_PRIMARY_LANGUAGE="Rust" - -# ANSI colors -RED='\033[0;31m' -GREEN='\033[0;32m' -YELLOW='\033[1;33m' -BLUE='\033[0;34m' -NC='\033[0m' # No Color - -# Helper functions -log_step() { - echo "" - echo -e "${BLUE}→${NC} $*" -} - -log_pass() { - echo -e "${GREEN}✓${NC} $*" -} - -log_error() { - echo -e "${RED}✗${NC} $*" >&2 -} - -cleanup() { - if [ -d "$TEST_DIR" ]; then - log_step "Cleaning up test directory: $TEST_DIR" - rm -rf "$TEST_DIR" - log_pass "Cleanup complete" - fi -} - -trap cleanup EXIT - -#============================================================================== -# PHASE 1: SETUP -#============================================================================== - -echo "" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "E2E TEST: Template Instantiation" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "" - -log_step "Creating test directory: $TEST_DIR" -mkdir -p "$TEST_DIR" -log_pass "Test directory created" - -#============================================================================== -# PHASE 2: CLONE TEMPLATE -#============================================================================== - -log_step "Cloning template from $TEMPLATE_ROOT" - -# Copy template to test location (simulating git clone) -TEST_REPO_PATH="$TEST_DIR/$TEST_REPO_NAME" -cp -r "$TEMPLATE_ROOT" "$TEST_REPO_PATH" -log_pass "Template cloned to $TEST_REPO_PATH" - -# Remove .git directory for clean state -if [ -d "$TEST_REPO_PATH/.git" ]; then - rm -rf "$TEST_REPO_PATH/.git" - log_pass ".git directory removed (fresh clone)" -fi - -#============================================================================== -# PHASE 3: PLACEHOLDER REPLACEMENT -#============================================================================== - -log_step "Replacing placeholder tokens" - -# Function to replace all occurrences of a placeholder in a file -replace_placeholder() { - local file="$1" - local placeholder="$2" - local value="$3" - - if [ ! -f "$file" ]; then - return 0 - fi - - # Use sed to replace (platform-portable) - if grep -q "$placeholder" "$file" 2>/dev/null; then - sed -i "s|$placeholder|$value|g" "$file" - echo " Replaced $placeholder in $(basename "$file")" - fi -} - -# Replace in all text files -find "$TEST_REPO_PATH" -type f \ - \( -name "*.md" -o -name "*.adoc" -o -name "*.a2ml" -o -name "*.zig" -o -name "*.idr" \ - -o -name "Justfile" -o -name "Containerfile" -o -name "*.yml" -o -name "*.yaml" \ - -o -name "*.json" -o -name "*.scm" -o -name "contractile" \) \ - -exec bash -c ' - file="$1" - placeholder_pairs=( - "{{REPO}}|$TEST_REPO_NAME" - "{{OWNER}}|$TEST_OWNER" - "{{FORGE}}|$TEST_FORGE" - "{{PROJECT}}|$TEST_PROJECT_NAME" - "{{project}}|'"${TEST_REPO_NAME//-/_}"'" - "{{REPO_DESCRIPTION}}|$TEST_DESCRIPTION" - "{{PRIMARY_LANGUAGE}}|$TEST_PRIMARY_LANGUAGE" - "{{AUTHOR}}|$TEST_AUTHOR" - "{{AUTHOR_EMAIL}}|$TEST_AUTHOR_EMAIL" - "{{CURRENT_DATE}}|2026-04-04" - ) - - for pair in "${placeholder_pairs[@]}"; do - IFS="|" read -r placeholder value <<< "$pair" - if grep -q "$placeholder" "$file" 2>/dev/null; then - sed -i "s|$placeholder|$value|g" "$file" - fi - done - ' _ "$file" - -log_pass "All placeholder tokens replaced" - -#============================================================================== -# PHASE 4: VALIDATE STRUCTURE -#============================================================================== - -log_step "Validating instantiated repository structure" - -# Run validation script on the instantiated repo -if [ -f "$TEMPLATE_ROOT/scripts/validate-template.sh" ]; then - bash "$TEMPLATE_ROOT/scripts/validate-template.sh" "$TEST_REPO_PATH" 0 - log_pass "Repository structure validation passed" -else - log_error "Validation script not found" - exit 1 -fi - -#============================================================================== -# PHASE 5: VERIFY BUILD -#============================================================================== - -log_step "Verifying build system works after instantiation" - -if [ -f "$TEST_REPO_PATH/src/interface/ffi/build.zig" ]; then - if command -v zig &> /dev/null; then - cd "$TEST_REPO_PATH/src/interface/ffi" - if zig build 2>&1; then - log_pass "Zig build successful" - else - log_error "Zig build failed" - exit 1 - fi - cd - > /dev/null - else - log_error "Zig compiler not found - cannot verify build" - exit 1 - fi -fi - -#============================================================================== -# PHASE 6: VERIFY NO REMAINING PLACEHOLDERS -#============================================================================== - -log_step "Checking for remaining placeholders" - -REMAINING_PLACEHOLDERS=$( - find "$TEST_REPO_PATH" -type f \ - \( -name "*.md" -o -name "*.adoc" -o -name "*.a2ml" -o -name "*.zig" -o -name "*.idr" \ - -o -name "Justfile" -o -name "*.yml" \) \ - -exec grep -l "{{[A-Z_]*}}" {} \; 2>/dev/null || true -) - -if [ -z "$REMAINING_PLACEHOLDERS" ]; then - log_pass "No remaining placeholders found" -else - log_error "Found remaining placeholders in:" - echo "$REMAINING_PLACEHOLDERS" | sed 's/^/ /' - exit 1 -fi - -#============================================================================== -# PHASE 7: VERIFY CRITICAL FILES ARE NOT TEMPLATES -#============================================================================== - -log_step "Verifying critical files have been instantiated" - -CRITICAL_FILES=( - "README.adoc" - "EXPLAINME.adoc" - "Justfile" -) - -for file in "${CRITICAL_FILES[@]}"; do - if [ -f "$TEST_REPO_PATH/$file" ]; then - # Check that it's not just a template (contains some actual content) - if grep -q "$TEST_PROJECT_NAME\|$TEST_AUTHOR\|$TEST_REPO_NAME" "$TEST_REPO_PATH/$file" 2>/dev/null || \ - [ $(wc -l < "$TEST_REPO_PATH/$file") -gt 10 ]; then - log_pass "File instantiated: $file" - else - log_error "File appears to be a template: $file" - exit 1 - fi - else - log_error "Critical file missing: $file" - exit 1 - fi -done - -#============================================================================== -# PHASE 8: VERIFY METADATA -#============================================================================== - -log_step "Verifying machine-readable metadata" - -METADATA_FILES=( - ".machine_readable/6a2/STATE.a2ml" - ".machine_readable/6a2/META.a2ml" -) - -for file in "${METADATA_FILES[@]}"; do - if [ -f "$TEST_REPO_PATH/$file" ]; then - log_pass "Metadata file exists: $file" - else - log_error "Metadata file missing: $file" - exit 1 - fi -done - -#============================================================================== -# SUMMARY -#============================================================================== - -echo "" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo -e "${GREEN}✓ E2E TEMPLATE INSTANTIATION TEST PASSED${NC}" -echo "═══════════════════════════════════════════════════════════════════════════════" -echo "" -echo "Summary:" -echo " - Template cloned successfully" -echo " - All placeholders replaced" -echo " - Repository structure valid" -echo " - Build system works" -echo " - No remaining placeholders" -echo " - Metadata intact" -echo "" -echo "Test repository: $TEST_REPO_PATH (will be cleaned up)" -echo ""