diff --git a/.machine_read/LLM_SUPERINTENDENT.scm b/.machine_read/LLM_SUPERINTENDENT.scm new file mode 100644 index 0000000..26778b9 --- /dev/null +++ b/.machine_read/LLM_SUPERINTENDENT.scm @@ -0,0 +1,106 @@ +;; SPDX-License-Identifier: AGPL-3.0-or-later +;; LLM_SUPERINTENDENT.scm - AI Governance for Hub Orchestrator +;; Authority: repo-superintendent | Schema: hyperpolymath.anchor/1 + +(llm-superintendent + (version . "1.0.0") + (schema . "hyperpolymath.superintendent/1") + (updated . "2026-01-01T00:00:00Z") + + ;; Identity Constraints + (identity + (project . "Language Playgrounds") + (kind . "hub-orchestrator") + (purpose . "Experimentation sandboxes for language and learning (pinned satellite submodules)") + (authority . "repo-superintendent")) + + ;; Scope Arrest - Prevent Identity Drift + (scope-arrest + (this-repo-is + ("A hub/orchestrator of pinned satellite playground submodules" + "A coordination point for unified versioning" + "An entry point for exploring hyperpolymath languages")) + (this-repo-is-not + ("A language implementation repository" + "A monorepo containing actual language code" + "A place for experiments directory" + "A location for compilers, runtimes, or interpreters")) + (enforcement + ("Reject PRs adding language implementation code" + "Reject PRs adding non-orchestrator experiments" + "Flag drift when satellite descriptions mismatch"))) + + ;; LLM Operational Boundaries + (llm-boundaries + (allowed-operations + ("Read any file in hub or satellites" + "Edit orchestration files (justfile, *.scm, *.adoc)" + "Update submodule pins (git submodule commands)" + "Create/update validation scripts in hooks/" + "Modify .machine_read/ files" + "Run smoke tests and drift checks")) + (forbidden-operations + ("Edit satellite source code directly in hub checkout" + "Add new satellites without explicit user request" + "Remove satellites without explicit user request" + "Push to satellite remotes from hub context" + "Modify satellite .git directories" + "Add compilers/runtimes to hub" + "Create experiments/ directories")) + (requires-confirmation + ("Updating submodule pins to new commits" + "Modifying .gitmodules" + "Creating new validation hooks" + "Changes to CI/CD workflows"))) + + ;; File Authority Matrix + (file-authority + (hub-owned + ("justfile" "Makefile" "Mustfile") + ("*.scm" "*.adoc" "*.md") + (".machine_read/*") + ("hooks/*") + (".github/workflows/*")) + (satellite-owned + ("*/src/*" "*/lib/*" "*/bin/*") + ("*/Cargo.toml" "*/deno.json" "*/rescript.json") + ("*/.git/*")) + (shared-schema + ("STATE.scm" "META.scm" "ECOSYSTEM.scm") + ("PLAYBOOK.scm" "AGENTIC.scm" "NEUROSYM.scm"))) + + ;; Semantic Binding Rules + (semantic-binding + (source-of-truth + ((".machine_read/SPEC.hub.scm" . "satellite registry") + (".gitmodules" . "submodule URLs and paths") + ("STATE.scm" . "satellite status"))) + (derived-from-satellites + ("Satellite descriptions should match satellite README headings" + "Satellite status should reflect actual satellite state")) + (drift-detection + ("Compare SPEC.hub.scm descriptions with satellite READMEs" + "Flag when satellite README heading differs from registry" + "Warn but don't auto-fix - requires human decision"))) + + ;; Golden Path Enforcement + (golden-path + (required-commands + ("just smoke" . "Run matrix of satellite checks") + ("just drift-lint" . "Check for description drift") + ("just submodule-check" . "Verify submodule integrity")) + (success-criteria + ("All submodules initialized to pinned commits" + "All satellite golden-path commands exit 0" + "No dirty submodules (uncommitted changes)" + "Registry matches .gitmodules"))) + + ;; Upgrade Path + (rsr-compliance + (current-tier . "silver-now") + (upgrade-path . "gold-after-f1") + (gold-requirements + ("CI matrix for all satellites" + "Automated drift-lint in CI" + "Pinned toolchains (Guix/Nix)" + "Signed commits")))) diff --git a/.machine_read/ROADMAP.f0.scm b/.machine_read/ROADMAP.f0.scm new file mode 100644 index 0000000..0820786 --- /dev/null +++ b/.machine_read/ROADMAP.f0.scm @@ -0,0 +1,88 @@ +;; SPDX-License-Identifier: AGPL-3.0-or-later +;; ROADMAP.f0.scm - First-Pass (F0) Roadmap for Hub Orchestrator +;; Authority: repo-superintendent | Schema: hyperpolymath.anchor/1 + +(roadmap-f0 + (version . "1.0.0") + (schema . "hyperpolymath.roadmap/1") + (updated . "2026-01-01T00:00:00Z") + (phase . "f0-first-pass") + + ;; F0 Objectives (from anchor first-pass-directives) + (f0-objectives + ((id . "f0-01") + (title . "Add SPEC.hub.scm") + (status . "complete") + (description . "Define satellite registry schema and per-satellite golden-path command") + (deliverables + (".machine_read/SPEC.hub.scm with registry schema" + "All 10 satellites registered with golden-path commands" + "Validation rules documented"))) + + ((id . "f0-02") + (title . "Add hub drift-lint") + (status . "in-progress") + (description . "Compare registry descriptions against satellite README headings") + (deliverables + ("hooks/drift-lint.sh script" + "just drift-lint recipe" + "Best-effort README heading extraction" + "Clear drift report output"))) + + ((id . "f0-03") + (title . "Fix known drift") + (status . "pending") + (description . "Align hub text with satellite repo identity (e.g., ephapax entry)") + (deliverables + ("Review each satellite README" + "Update SPEC.hub.scm descriptions to match" + "Update README.adoc satellite table"))) + + ((id . "f0-04") + (title . "Implement golden-path smoke test") + (status . "in-progress") + (description . "just smoke command that validates all satellites") + (deliverables + ("Submodule init check" + "Pinned commit verification" + "Per-satellite golden-path execution" + "Matrix output format")))) + + ;; Success Criteria for F0 + (f0-success-criteria + ("just smoke runs without errors" + "just drift-lint produces actionable report" + "All mandatory .machine_read/ files present" + "README.adoc satellite table matches SPEC.hub.scm")) + + ;; Future Phases + (future-phases + ((phase . "f1-ci-integration") + (tier . "gold") + (objectives + ("CI matrix running smoke on all satellites" + "Automated drift-lint in PR checks" + "Submodule update bot"))) + + ((phase . "f2-toolchain-pinning") + (tier . "gold") + (objectives + ("Guix manifest for reproducible builds" + "Nix flake fallback" + "SHA-pinned tool versions"))) + + ((phase . "f3-satellite-health") + (tier . "gold") + (objectives + ("Per-satellite health badges" + "Dependency audit across satellites" + "Cross-satellite integration tests")))) + + ;; RSR Tier Progression + (rsr-progression + (current . "silver-now") + (target . "gold-after-f1") + (blockers + ("CI matrix not yet implemented" + "Drift-lint not in CI" + "Toolchains not pinned")))) diff --git a/.machine_read/SPEC.hub.scm b/.machine_read/SPEC.hub.scm new file mode 100644 index 0000000..71c67e3 --- /dev/null +++ b/.machine_read/SPEC.hub.scm @@ -0,0 +1,135 @@ +;; SPDX-License-Identifier: AGPL-3.0-or-later +;; SPEC.hub.scm - Hub Specification and Satellite Registry Schema +;; Authority: repo-superintendent | Schema: hyperpolymath.anchor/1 + +(spec-hub + (version . "1.0.0") + (schema . "hyperpolymath.hub-spec/1") + (updated . "2026-01-01T00:00:00Z") + + ;; Registry Schema Definition + (registry-schema + (satellite-entry + (required-fields + (name . "string: submodule directory name") + (url . "string: git remote URL (HTTPS)") + (description . "string: one-sentence purpose") + (status . "enum: active | framework | partial | dormant") + (golden-path . "string: command to verify satellite works")) + (optional-fields + (language . "string: primary implementation language") + (maintainer . "string: primary contact") + (rsr-tier . "enum: bronze | silver | gold")))) + + ;; Satellite Registry (source of truth for hub) + (satellites + ((name . "mylang-playground") + (url . "https://github.com/hyperpolymath/mylang-playground.git") + (description . "My-Lang progressive family (Me -> Solo -> Duet -> Ensemble)") + (status . "active") + (golden-path . "cargo check") + (language . "Rust") + (rsr-tier . "silver")) + + ((name . "affinescript-playground") + (url . "https://github.com/hyperpolymath/affinescript-playground.git") + (description . "Affine types for WebAssembly, memory safety") + (status . "framework") + (golden-path . "just --list") + (language . "OCaml") + (rsr-tier . "bronze")) + + ((name . "anvomidav-playground") + (url . "https://github.com/hyperpolymath/anvomidav-playground.git") + (description . "Experimental language exploration") + (status . "framework") + (golden-path . "just --list") + (language . "Scheme") + (rsr-tier . "bronze")) + + ((name . "betlang-playground") + (url . "https://github.com/hyperpolymath/betlang-playground.git") + (description . "Ternary probabilistic programming, uncertainty modeling") + (status . "framework") + (golden-path . "just --list") + (language . "ReScript") + (rsr-tier . "bronze")) + + ((name . "eclexia-playground") + (url . "https://github.com/hyperpolymath/eclexia-playground.git") + (description . "Economics as Code experimentation") + (status . "active") + (golden-path . "just --list") + (language . "ReScript") + (rsr-tier . "silver")) + + ((name . "ephapax-playground") + (url . "https://github.com/hyperpolymath/ephapax-playground.git") + (description . "Ephemeral single-use application framework") + (status . "partial") + (golden-path . "just --list") + (language . "Rust") + (rsr-tier . "bronze")) + + ((name . "jtv-playground") + (url . "https://github.com/hyperpolymath/jtv-playground.git") + (description . "Julia-the-Viper Harvard Architecture systems programming") + (status . "active") + (golden-path . "just --list") + (language . "Julia") + (rsr-tier . "silver")) + + ((name . "oblibeny-playground") + (url . "https://github.com/hyperpolymath/oblibeny-playground.git") + (description . "Privacy-preserving oblivious computation") + (status . "framework") + (golden-path . "just --list") + (language . "Rust") + (rsr-tier . "bronze")) + + ((name . "phronesis-playground") + (url . "https://github.com/hyperpolymath/phronesis-playground.git") + (description . "Practical wisdom for ethical decision-making") + (status . "framework") + (golden-path . "just --list") + (language . "Gleam") + (rsr-tier . "bronze")) + + ((name . "wokelang-playground") + (url . "https://github.com/hyperpolymath/wokelang-playground.git") + (description . "Human-centric accessible programming") + (status . "framework") + (golden-path . "just --list") + (language . "ReScript") + (rsr-tier . "bronze"))) + + ;; Validation Rules + (validation-rules + (submodule-integrity + ("All satellites must be git submodules pinned to commits" + "No floating refs or tracking branches allowed" + "Submodule paths must match satellite names")) + (description-sync + ("Hub README satellite descriptions must match SPEC.hub.scm" + "SPEC.hub.scm descriptions should align with satellite README headings" + "Drift detected when any description conflicts")) + (golden-path-check + ("Each satellite must have a working golden-path command" + "Command must exit 0 for satellite to be considered healthy" + "Submodule must be initialized before check"))) + + ;; Semantic Anchor Policy + (semantic-anchor + (policy . "registry-of-truth") + (binding + ("This SPEC.hub.scm is the authoritative satellite registry" + "If .gitmodules conflicts, .gitmodules is canonical for URLs" + "If README.adoc conflicts, SPEC.hub.scm is canonical for descriptions" + "Satellite READMEs are upstream source - sync on update"))) + + ;; Forbidden Operations + (forbidden + ("Editing satellite code directly in hub checkout" + "Adding non-orchestrator code to hub" + "Using floating submodule refs" + "Adding compilers/runtimes to hub"))) diff --git a/hooks/drift-lint.sh b/hooks/drift-lint.sh new file mode 100755 index 0000000..a9adab1 --- /dev/null +++ b/hooks/drift-lint.sh @@ -0,0 +1,163 @@ +#!/usr/bin/env bash +# SPDX-License-Identifier: AGPL-3.0-or-later +# drift-lint.sh - Check for description drift between registry and satellites +# +# Compares: +# 1. SPEC.hub.scm descriptions vs satellite README headings +# 2. README.adoc satellite table vs SPEC.hub.scm +# 3. .gitmodules vs SPEC.hub.scm satellite list + +set -euo pipefail + +SPEC_FILE=".machine_read/SPEC.hub.scm" +README_FILE="README.adoc" +GITMODULES_FILE=".gitmodules" + +# Colors for output +RED='\033[0;31m' +YELLOW='\033[0;33m' +GREEN='\033[0;32m' +NC='\033[0m' # No Color + +echo "=== Drift Lint ===" +echo "" + +warnings=0 +errors=0 + +# Check required files exist +if [[ ! -f "$SPEC_FILE" ]]; then + echo -e "${RED}[ERROR]${NC} Missing $SPEC_FILE" + exit 1 +fi + +if [[ ! -f "$README_FILE" ]]; then + echo -e "${RED}[ERROR]${NC} Missing $README_FILE" + exit 1 +fi + +if [[ ! -f "$GITMODULES_FILE" ]]; then + echo -e "${RED}[ERROR]${NC} Missing $GITMODULES_FILE" + exit 1 +fi + +echo "Checking: SPEC.hub.scm <-> .gitmodules consistency..." +echo "" + +# Extract satellites from .gitmodules +mapfile -t gitmodule_satellites < <(grep '^\[submodule' "$GITMODULES_FILE" | sed 's/.*"\(.*\)".*/\1/') + +# Extract satellites from SPEC.hub.scm (simplified parsing) +mapfile -t spec_satellites < <(grep '(name \. "' "$SPEC_FILE" | sed 's/.*"\(.*\)".*/\1/') + +# Check .gitmodules satellites are in SPEC.hub.scm +for sat in "${gitmodule_satellites[@]}"; do + if ! printf '%s\n' "${spec_satellites[@]}" | grep -q "^${sat}$"; then + echo -e "${RED}[ERROR]${NC} Satellite '$sat' in .gitmodules but missing from SPEC.hub.scm" + ((errors++)) + fi +done + +# Check SPEC.hub.scm satellites are in .gitmodules +for sat in "${spec_satellites[@]}"; do + if ! printf '%s\n' "${gitmodule_satellites[@]}" | grep -q "^${sat}$"; then + echo -e "${RED}[ERROR]${NC} Satellite '$sat' in SPEC.hub.scm but missing from .gitmodules" + ((errors++)) + fi +done + +if [[ $errors -eq 0 ]] && [[ ${#gitmodule_satellites[@]} -eq ${#spec_satellites[@]} ]]; then + echo -e "${GREEN}[OK]${NC} SPEC.hub.scm and .gitmodules satellite lists match" +fi + +echo "" +echo "Checking: SPEC.hub.scm <-> README.adoc consistency..." +echo "" + +# Extract descriptions from SPEC.hub.scm +declare -A spec_descriptions +while IFS= read -r line; do + if [[ "$line" =~ \(name\ \.\ \"([^\"]+)\"\) ]]; then + current_sat="${BASH_REMATCH[1]}" + fi + if [[ "$line" =~ \(description\ \.\ \"([^\"]+)\"\) ]] && [[ -n "${current_sat:-}" ]]; then + spec_descriptions["$current_sat"]="${BASH_REMATCH[1]}" + current_sat="" + fi +done < "$SPEC_FILE" + +# Check README.adoc satellite table entries +for sat in "${spec_satellites[@]}"; do + spec_desc="${spec_descriptions[$sat]:-}" + + # Extract description from README.adoc (look for link:satellite[satellite] followed by | description) + readme_desc=$(grep -A1 "link:${sat}\[" "$README_FILE" 2>/dev/null | tail -1 | sed 's/^| *//' | tr -d '\n' || echo "") + + if [[ -z "$readme_desc" ]]; then + echo -e "${YELLOW}[WARN]${NC} Satellite '$sat' not found in README.adoc satellite table" + ((warnings++)) + elif [[ "$spec_desc" != "$readme_desc" ]]; then + echo -e "${YELLOW}[WARN]${NC} Description mismatch for '$sat':" + echo " SPEC.hub.scm: $spec_desc" + echo " README.adoc: $readme_desc" + ((warnings++)) + fi +done + +echo "" +echo "Checking: Satellite README headings (best-effort)..." +echo "" + +# Check satellite README headings match descriptions (if submodules are initialized) +for sat in "${spec_satellites[@]}"; do + sat_readme="${sat}/README.md" + sat_readme_adoc="${sat}/README.adoc" + + if [[ -f "$sat_readme" ]]; then + # Extract first heading from markdown README + heading=$(grep -m1 '^#' "$sat_readme" 2>/dev/null | sed 's/^#* *//' || echo "") + elif [[ -f "$sat_readme_adoc" ]]; then + # Extract first heading from asciidoc README + heading=$(grep -m1 '^=' "$sat_readme_adoc" 2>/dev/null | sed 's/^=* *//' || echo "") + else + echo -e "${YELLOW}[SKIP]${NC} $sat - not initialized or no README" + continue + fi + + spec_desc="${spec_descriptions[$sat]:-}" + + # Best-effort comparison: check if description contains key terms from heading + # This is intentionally loose - just flags potential drift + if [[ -n "$heading" ]] && [[ -n "$spec_desc" ]]; then + # Normalize for comparison + heading_lower=$(echo "$heading" | tr '[:upper:]' '[:lower:]') + sat_name_lower=$(echo "$sat" | tr '[:upper:]' '[:lower:]' | sed 's/-playground//') + + if [[ "$heading_lower" != *"$sat_name_lower"* ]] && [[ "$heading_lower" != *"playground"* ]]; then + echo -e "${YELLOW}[INFO]${NC} $sat README heading: '$heading'" + echo " Registry description: '$spec_desc'" + echo " (Manual review recommended)" + ((warnings++)) + else + echo -e "${GREEN}[OK]${NC} $sat - heading appears aligned" + fi + fi +done + +echo "" +echo "=== Drift Lint Summary ===" +echo "Errors: $errors | Warnings: $warnings" + +if [[ $errors -gt 0 ]]; then + echo "" + echo "Drift lint failed. Fix errors before proceeding." + exit 1 +elif [[ $warnings -gt 0 ]]; then + echo "" + echo "Drift detected. Review warnings and update registry or satellite descriptions." + exit 0 +else + echo "" + echo "No drift detected." + exit 0 +fi diff --git a/justfile b/justfile index c24ef44..82a411b 100644 --- a/justfile +++ b/justfile @@ -1,28 +1,146 @@ # SPDX-License-Identifier: AGPL-3.0-or-later -# Justfile - hyperpolymath standard task runner +# Justfile - hyperpolymath hub-orchestrator task runner default: @just --list -# Build the project +# ============================================================ +# Golden Path Commands (required by anchor schema) +# ============================================================ + +# Run smoke test matrix across all satellites +smoke: submodule-init submodule-check + #!/usr/bin/env bash + set -euo pipefail + echo "=== Smoke Test Matrix ===" + echo "" + + # Define satellites and their golden-path commands + declare -A satellites=( + ["mylang-playground"]="cargo check" + ["affinescript-playground"]="just --list" + ["anvomidav-playground"]="just --list" + ["betlang-playground"]="just --list" + ["eclexia-playground"]="just --list" + ["ephapax-playground"]="just --list" + ["jtv-playground"]="just --list" + ["oblibeny-playground"]="just --list" + ["phronesis-playground"]="just --list" + ["wokelang-playground"]="just --list" + ) + + passed=0 + failed=0 + skipped=0 + + for sat in "${!satellites[@]}"; do + cmd="${satellites[$sat]}" + if [[ -d "$sat" && -n "$(ls -A "$sat" 2>/dev/null)" ]]; then + echo -n "[$sat] $cmd ... " + if (cd "$sat" && eval "$cmd" >/dev/null 2>&1); then + echo "PASS" + ((passed++)) + else + echo "FAIL" + ((failed++)) + fi + else + echo "[$sat] SKIP (not initialized)" + ((skipped++)) + fi + done + + echo "" + echo "=== Results ===" + echo "Passed: $passed | Failed: $failed | Skipped: $skipped" + + if [[ $failed -gt 0 ]]; then + exit 1 + fi + +# Check for description drift between registry and satellites +drift-lint: + @./hooks/drift-lint.sh + +# Verify submodule integrity (pinned commits, no dirty state) +submodule-check: + #!/usr/bin/env bash + set -euo pipefail + echo "=== Submodule Integrity Check ===" + + errors=0 + + # Check for uninitialized submodules + while IFS= read -r line; do + if [[ "$line" == -* ]]; then + submod=$(echo "$line" | awk '{print $2}') + echo "[WARN] Uninitialized: $submod" + elif [[ "$line" == +* ]]; then + submod=$(echo "$line" | awk '{print $2}') + echo "[ERROR] Modified (not pinned): $submod" + ((errors++)) + fi + done < <(git submodule status 2>/dev/null || echo "") + + # Check for dirty submodules + for dir in */; do + if [[ -d "${dir}.git" ]] || [[ -f "${dir}.git" ]]; then + if (cd "$dir" && git status --porcelain 2>/dev/null | grep -q .); then + echo "[ERROR] Dirty submodule: ${dir%/}" + ((errors++)) + fi + fi + done + + if [[ $errors -gt 0 ]]; then + echo "" + echo "Submodule integrity check failed with $errors error(s)" + exit 1 + else + echo "All submodules OK" + fi + +# Initialize all submodules to pinned commits +submodule-init: + git submodule update --init --recursive + +# Update a single submodule to latest (maintainers only) +submodule-update SATELLITE: + #!/usr/bin/env bash + set -euo pipefail + if [[ ! -d "{{SATELLITE}}" ]]; then + echo "Error: Satellite {{SATELLITE}} not found" + exit 1 + fi + cd "{{SATELLITE}}" + git fetch origin + git checkout origin/main || git checkout origin/master + cd .. + git add "{{SATELLITE}}" + echo "Updated {{SATELLITE}}. Review and commit the change." + +# ============================================================ +# Standard Commands +# ============================================================ + +# Build the project (hub has nothing to build) build: - @echo "Building..." + @echo "Hub orchestrator - nothing to build" # Run tests -test: - @echo "Testing..." +test: smoke # Run lints -lint: - @echo "Linting..." +lint: drift-lint submodule-check # Clean build artifacts clean: @echo "Cleaning..." + @find . -name "*.log" -delete 2>/dev/null || true -# Format code +# Format code (hub has no code to format) fmt: - @echo "Formatting..." + @echo "Hub orchestrator - no code to format" # Run all checks check: lint test @@ -30,4 +148,6 @@ check: lint test # Prepare a release release VERSION: @echo "Releasing {{VERSION}}..." - + @echo "1. Update STATE.scm version" + @echo "2. Update ROADMAP.f0.scm" + @echo "3. Tag: git tag -s v{{VERSION}}"