diff --git a/.machine_read/ANCHOR.scope-arrest.2026-01-01.scm b/.machine_read/ANCHOR.scope-arrest.2026-01-01.scm new file mode 100644 index 0000000..643d8b2 --- /dev/null +++ b/.machine_read/ANCHOR.scope-arrest.2026-01-01.scm @@ -0,0 +1,50 @@ +;; ANCHOR.scope-arrest.2026-01-01.Jewell.scm (anvomidav) +;; SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2026 hyperpolymath +;; +;; This anchor file defines the scope arrest for phase f0. +;; It freezes the project identity and establishes the conformance baseline. + +(define anchor + '((schema . "hyperpolymath.anchor/1") + (repo . "hyperpolymath/anvomidav") + (date . "2026-01-01") + (authority . "repo-superintendent") + (purpose . ("Scope arrest + make repo unambiguously runnable + freeze identity.")) + (identity + . ((project . "Anvomidav") + (kind . "domain-language + CLI toolchain") + (domain . "figure-skating choreography") + (one-sentence . "A DSL and toolchain for expressing skating choreography and validating rule constraints."))) + + (semantic-anchor + . ((policy . "dual") + (reference-impl . ("Rust workspace" "CLI is authoritative behavior")) + (formal-spec . ("SPEC.core.scm defines syntax/semantics; conformance corpus is binding")))) + + (allowed-implementation-languages + . ("Rust")) ;; keep narrow in f0; editors/tooling optional later + (forbidden + . ("Expanding into unrelated domains" + "Adding new backends" + "Rewriting as a different project")) + + (golden-path + . ((smoke-test-command . "cargo test && cargo run -p anv-cli -- check examples/*") + (success-criteria . ("parse+check succeeds on at least 1 example" + "at least 5 invalid examples produce stable diagnostics")))) + + (mandatory-files + . ("./.machine_read/LLM_SUPERINTENDENT.scm" + "./.machine_read/SPEC.core.scm" + "./.machine_read/ROADMAP.f0.scm" + "./conformance/")) + + (first-pass-directives + . ("Ensure README(s) do not contradict this identity." + "If multiple READMEs exist, create one canonical machine README pointer (no prose needed)." + "Quarantine tree-sitter/editor integration as optional: it must not block core build." + "Add conformance corpus representing core grammar + rule checks.")) + + (rsr + . ((target-tier . "bronze-now") (upgrade-path . "silver-after-f1"))))) diff --git a/.machine_read/AUTHORITY_STACK.scm b/.machine_read/AUTHORITY_STACK.scm new file mode 100644 index 0000000..420f08e --- /dev/null +++ b/.machine_read/AUTHORITY_STACK.scm @@ -0,0 +1,47 @@ +;; AUTHORITY_STACK.mustfile-nickel.scm +;; SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2026 hyperpolymath +;; +;; Shared drop for hyperpolymath repos: defines task routing + config authority. + +(define authority-stack + '((schema . "hyperpolymath.authority-stack/1") + (intent + . ("Stop agentic drift and toolchain creep." + "Make the repo executable via a single blessed interface." + "Prevent the LLM from inventing commands, tools, or files.")) + + (operational-authority + . ((local-tasks . "just") + (deployment-transitions . "must") + (config-manifests . "nickel") + (container-engine . "podman-first"))) + + (hard-rules + . ("Makefiles are forbidden." + "All operations must be invoked via `just ` (local) or `must ` (deployment)." + "If a recipe/transition does not exist, the correct action is to ADD it (and document it), not to run ad-hoc commands." + "Nickel manifests are the single source of truth for config; do not hand-edit generated outputs." + "No network-required runtime paths for demos/tests unless explicitly permitted in ANCHOR.")) + + (workflow + . ((first-run + . ("Read ANCHOR*.scm" + "Read STATE.scm" + "Run: just --list" + "Run: just test" + "Run: just demo (if defined)")) + (adding-new-capability + . ("Update SPEC/ROADMAP first" + "Add a `just` recipe (and tests) that implements the capability" + "Only then edit code")))) + + (tooling-contract + . ((mustfile-notes + . ("Mustfile is the deployment contract (physical state transitions)." + "must is the supervisor/enforcer for must-spec; it routes through just where appropriate.")) + (nickel-notes + . ("Nickel provides validated, type-safe manifests." + "Prefer .ncl for machine-truth; render docs from it via your conversion pipeline.")) + (shell-entrypoints + . ("Shell wrappers may exist; all must route to just/must without inventing extra logic.")))))) diff --git a/.machine_read/CANONICAL_README.scm b/.machine_read/CANONICAL_README.scm new file mode 100644 index 0000000..b2922c8 --- /dev/null +++ b/.machine_read/CANONICAL_README.scm @@ -0,0 +1,89 @@ +;; SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2025-2026 hyperpolymath +;; +;; CANONICAL_README.scm - Pointer to Canonical Documentation +;; +;; This file establishes the documentation hierarchy for the repository. +;; Multiple READMEs exist for different purposes; this file clarifies authority. + +(define canonical-docs + '((schema . "hyperpolymath.canonical-docs/1") + (updated . "2026-01-01") + + ;; ========================================================================== + ;; PRIMARY DOCUMENTATION + ;; ========================================================================== + (primary + . ((readme + . ((path . "./README.adoc") + (purpose . "Main project documentation, quick start, syntax examples") + (authority . "canonical"))) + (roadmap + . ((path . "./ROADMAP.adoc") + (purpose . "Development phases and milestones") + (authority . "canonical"))) + (contributing + . ((path . "./CONTRIBUTING.adoc") + (purpose . "How to contribute") + (authority . "canonical"))) + (security + . ((path . "./SECURITY.md") + (purpose . "Security policy and vulnerability reporting") + (authority . "canonical"))))) + + ;; ========================================================================== + ;; MACHINE-READABLE DOCUMENTATION + ;; ========================================================================== + (machine-readable + . ((superintendent + . ((path . "./.machine_read/LLM_SUPERINTENDENT.scm") + (purpose . "Instructions for AI/LLM agents"))) + (spec + . ((path . "./.machine_read/SPEC.core.scm") + (purpose . "Core language specification (binding)"))) + (roadmap-f0 + . ((path . "./.machine_read/ROADMAP.f0.scm") + (purpose . "Phase f0 scope arrest roadmap"))) + (state + . ((path . "./STATE.scm") + (purpose . "Current project state"))))) + + ;; ========================================================================== + ;; SUPPLEMENTARY DOCUMENTATION (Non-authoritative for Core) + ;; ========================================================================== + (supplementary + . ((academic + . ((path . "./docs/academic/README.adoc") + (purpose . "Academic papers and formal proofs") + (status . "optional"))) + (implementation + . ((path . "./docs/IMPLEMENTATION.adoc") + (purpose . "Implementation details") + (status . "optional"))))) + + ;; ========================================================================== + ;; EDITOR/TOOLING DOCUMENTATION (OPTIONAL - Does not affect core) + ;; ========================================================================== + (optional-tooling + . ((neovim + . ((path . "./editors/neovim/README.md") + (purpose . "Neovim integration") + (status . "optional - does not block core build"))) + (helix + . ((path . "./editors/helix/README.md") + (purpose . "Helix editor integration") + (status . "optional - does not block core build"))) + (tree-sitter + . ((path . "./tree-sitter-anvomidav/") + (purpose . "Tree-sitter grammar for syntax highlighting") + (status . "optional - does not block core build"))))) + + ;; ========================================================================== + ;; READING ORDER FOR NEW CONTRIBUTORS + ;; ========================================================================== + (reading-order + . (("README.adoc" . "Start here for project overview") + ("ROADMAP.adoc" . "Understand development phases") + ("CONTRIBUTING.adoc" . "How to participate") + (".machine_read/SPEC.core.scm" . "Language specification") + ("crates/anv-cli/src/main.rs" . "CLI entry point"))))) diff --git a/.machine_read/LLM_SUPERINTENDENT.scm b/.machine_read/LLM_SUPERINTENDENT.scm new file mode 100644 index 0000000..3eeb81d --- /dev/null +++ b/.machine_read/LLM_SUPERINTENDENT.scm @@ -0,0 +1,81 @@ +;; SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2025-2026 hyperpolymath +;; +;; LLM_SUPERINTENDENT.scm - Instructions for AI/LLM agents operating on this repository +;; +;; This file provides machine-readable directives for LLM code assistants. + +(define superintendent + '((schema . "hyperpolymath.superintendent/1") + (updated . "2026-01-01") + + ;; Project identity - DO NOT DEVIATE + (identity + . ((name . "Anvomidav") + (kind . "domain-specific language + CLI toolchain") + (domain . "figure skating choreography") + (one-sentence . "A DSL and toolchain for expressing skating choreography and validating ISU rule constraints."))) + + ;; Implementation constraints + (implementation + . ((language . "Rust") + (workspace . "Cargo.toml defines workspace members") + (cli-binary . "anv-cli") + (reference-behavior . "CLI output is authoritative"))) + + ;; What to protect + (invariants + . (("Core semantics must match SPEC.core.scm") + ("ISU rule validation must pass for valid examples in conformance/valid/") + ("Invalid examples in conformance/invalid/ must produce stable diagnostics") + ("All 90+ tests must pass after any change"))) + + ;; What is allowed + (allowed + . (("Bug fixes in existing crates") + ("Extending ISU rule coverage") + ("Adding new conformance tests") + ("Improving error messages") + ("Documentation improvements"))) + + ;; What is forbidden + (forbidden + . (("Changing project identity or domain") + ("Adding non-Rust implementation languages") + ("Adding external service dependencies") + ("Rewriting the parser without migration plan") + ("Breaking existing conformance tests"))) + + ;; Before making changes, verify + (verification + . ((smoke-test . "just smoke-test") + (conformance . "just conformance") + (tests . "just test"))) + + ;; Operational authority - HOW to run commands + (authority-stack + . ((local-tasks . "just ") + (see-also . ".machine_read/AUTHORITY_STACK.scm") + (hard-rules + . ("Makefiles are forbidden" + "All operations via `just ` - do not run ad-hoc commands" + "If a recipe does not exist, ADD it to justfile first")))) + + ;; Key files to understand the system + (key-files + . (("justfile" . "Task runner - use `just --list` to see recipes") + ("README.adoc" . "Project overview and quick start") + ("ROADMAP.adoc" . "Development phases and milestones") + ("Cargo.toml" . "Workspace configuration") + ("crates/anv-syntax/src/lib.rs" . "Lexer and parser entry") + ("crates/anv-semantics/src/lib.rs" . "ISU rules validation") + ("crates/anv-cli/src/main.rs" . "CLI entry point") + (".machine_read/SPEC.core.scm" . "Core language specification") + (".machine_read/AUTHORITY_STACK.scm" . "Task routing rules"))) + + ;; Current phase and scope limits + (phase + . ((current . "f0") + (focus . "Make repo unambiguously runnable and establish conformance baseline") + (scope-arrest . #t) + (no-new-features . #t))))) diff --git a/.machine_read/ROADMAP.f0.scm b/.machine_read/ROADMAP.f0.scm new file mode 100644 index 0000000..c75544d --- /dev/null +++ b/.machine_read/ROADMAP.f0.scm @@ -0,0 +1,94 @@ +;; SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2025-2026 hyperpolymath +;; +;; ROADMAP.f0.scm - Phase f0: Scope Arrest & Baseline Establishment +;; +;; This roadmap defines the immediate stabilization phase. +;; Focus: Make the repository unambiguously runnable and freeze identity. + +(define roadmap-f0 + '((schema . "hyperpolymath.roadmap/1") + (phase . "f0") + (name . "Scope Arrest") + (goal . "Establish stable, runnable baseline with conformance corpus") + (started . "2026-01-01") + (target-tier . "bronze") + + ;; ========================================================================== + ;; PHASE F0 OBJECTIVES + ;; ========================================================================== + (objectives + . (("O1" . "Repository is unambiguously runnable") + ("O2" . "Identity is frozen and documented") + ("O3" . "Conformance corpus exists with valid/invalid examples") + ("O4" . "Tree-sitter/editor integration is marked optional") + ("O5" . "Smoke test passes reliably"))) + + ;; ========================================================================== + ;; ACCEPTANCE CRITERIA + ;; ========================================================================== + (acceptance-criteria + . ((smoke-test + . ((command . "cargo test && cargo run -p anv-cli -- check examples/*") + (expected . "All tests pass, at least 1 example parses successfully"))) + (conformance-valid + . ((command . "cargo run -p anv-cli -- check conformance/valid/*") + (expected . "All valid examples parse and validate without errors"))) + (conformance-invalid + . ((command . "for f in conformance/invalid/*; do cargo run -p anv-cli -- check $f 2>&1; done") + (expected . "Each invalid example produces stable diagnostic output") + (count . ">= 5 invalid examples"))))) + + ;; ========================================================================== + ;; TASKS (CHECKLIST) + ;; ========================================================================== + (tasks + . ((done + . (("Create .machine_read directory") + ("Add LLM_SUPERINTENDENT.scm") + ("Add SPEC.core.scm") + ("Add ROADMAP.f0.scm") + ("Add CANONICAL_README.scm") + ("Fix STATE.scm language reference") + ("Add conformance/valid/ examples (4 files)") + ("Add conformance/invalid/ examples (7 files, exceeds >= 5)") + ("Mark tree-sitter as optional (OPTIONAL.md)") + ("Mark editors as optional (OPTIONAL.md)") + ("Verify smoke test passes (152 tests)") + ("Verify conformance tests pass"))) + (pending + . ()))) + + ;; ========================================================================== + ;; SCOPE BOUNDARIES + ;; ========================================================================== + (scope + . ((in-scope + . (("Bug fixes in core crates") + ("Conformance test additions") + ("Documentation corrections") + ("Error message improvements"))) + (out-of-scope + . (("New language features") + ("New crates or binaries") + ("Editor/IDE integration work") + ("Visualization features") + ("IR layer implementation"))))) + + ;; ========================================================================== + ;; SUCCESS METRICS + ;; ========================================================================== + (success-metrics + . ((tests-passing . ">= 90") + (valid-conformance-files . ">= 3") + (invalid-conformance-files . ">= 5") + (smoke-test-reliable . #t))) + + ;; ========================================================================== + ;; NEXT PHASE + ;; ========================================================================== + (next-phase + . ((name . "f1") + (focus . "IR layer and code generation") + (prerequisite . "f0 acceptance criteria met") + (target-tier . "silver"))))) diff --git a/.machine_read/SPEC.core.scm b/.machine_read/SPEC.core.scm new file mode 100644 index 0000000..a70d251 --- /dev/null +++ b/.machine_read/SPEC.core.scm @@ -0,0 +1,163 @@ +;; SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +;; SPDX-FileCopyrightText: 2025-2026 hyperpolymath +;; +;; SPEC.core.scm - Core Language Specification (Binding) +;; +;; This specification defines the authoritative syntax and semantics for Anvomidav. +;; The CLI implementation in Rust is the reference behavior. +;; Conformance tests in conformance/ are binding test cases. + +(define core-spec + '((schema . "hyperpolymath.spec/1") + (version . "0.1.0") + (status . "draft-binding") + + ;; ========================================================================== + ;; 1. LEXICAL STRUCTURE + ;; ========================================================================== + (lexical + . ((keywords + . ((program-kw . "program") + (segment-kw . "segment") + (sequence-kw . "sequence") + (jump-kw . "jump") + (spin-kw . "spin") + (step-kw . "step") + (lift-kw . "lift") + (throw-kw . "throw") + (twist-kw . "twist") + (death-spiral-kw . "death_spiral") + (choreographic-kw . "choreographic") + (pattern-kw . "pattern") + (sync-kw . "sync") + (parallel-kw . "parallel"))) + + (rotations + . ((single . "single") + (double . "double") + (triple . "triple") + (quad . "quad"))) + + (jump-kinds + . ((axel . "axel") + (lutz . "lutz") + (flip . "flip") + (loop . "loop") + (salchow . "salchow") + (toe-loop . "toe_loop") + (euler . "euler"))) + + (spin-positions + . ((upright . "upright") + (sit . "sit") + (camel . "camel") + (layback . "layback") + (biellmann . "biellmann"))) + + (step-patterns + . ((straight . "straight") + (circular . "circular") + (serpentine . "serpentine"))) + + (levels + . ((base . "B") + (level-1 . "L1") + (level-2 . "L2") + (level-3 . "L3") + (level-4 . "L4"))) + + (lift-groups + . ((group-1 . "Gr1") + (group-2 . "Gr2") + (group-3 . "Gr3") + (group-4 . "Gr4") + (group-5 . "Gr5"))) + + (edges + . ((lfo . "LFO") (lfi . "LFI") (lbo . "LBO") (lbi . "LBI") + (rfo . "RFO") (rfi . "RFI") (rbo . "RBO") (rbi . "RBI"))) + + (segment-types + . ((short . "short") + (free . "free") + (rhythm . "rhythm") + (pattern-dance . "pattern") + (exhibition . "exhibition"))) + + (choreographic-kinds + . ((spiral . "spiral") + (spread . "spread") + (ina . "ina") + (hydroblading . "hydroblading") + (pivot . "pivot"))))) + + ;; ========================================================================== + ;; 2. GRAMMAR (EBNF-like) + ;; ========================================================================== + (grammar + . ((program . "program IDENT { segment+ }") + (segment . "segment IDENT : SEGMENT_TYPE { sequence+ }") + (sequence . "sequence IDENT { element+ }") + (element . "jump-elem | spin-elem | step-elem | lift-elem | throw-elem | twist-elem | death-spiral-elem | choreographic-elem | pattern-elem | sync-block") + (jump-elem . "jump ROTATION JUMP_KIND") + (spin-elem . "spin SPIN_POSITION+ LEVEL") + (step-elem . "step STEP_PATTERN LEVEL") + (lift-elem . "lift LIFT_GROUP LEVEL") + (throw-elem . "throw ROTATION JUMP_KIND") + (twist-elem . "twist ROTATION LEVEL") + (death-spiral-elem . "death_spiral EDGE LEVEL") + (choreographic-elem . "choreographic CHOREO_KIND") + (pattern-elem . "pattern DANCE_NAME") + (sync-block . "sync { element+ }"))) + + ;; ========================================================================== + ;; 3. DISCIPLINES AND CONSTRAINTS + ;; ========================================================================== + (disciplines + . ((singles + . ((description . "Men's and Ladies' singles skating") + (allowed-elements . (jump spin step choreographic)) + (forbidden-elements . (lift throw twist death-spiral)))) + + (pairs + . ((description . "Pairs skating") + (allowed-elements . (jump spin step lift throw twist death-spiral choreographic sync)))) + + (ice-dance + . ((description . "Ice dance") + (allowed-elements . (spin step choreographic pattern)) + (jump-constraint . "only single jumps allowed") + (forbidden-elements . (throw twist death-spiral)))))) + + ;; ========================================================================== + ;; 4. SEGMENT LIMITS (ISU Technical Rules) + ;; ========================================================================== + (segment-limits + . ((singles-short + . ((max-jumps . 3) + (max-spins . 3) + (max-steps . 1))) + (singles-free + . ((max-jumps . 7) + (max-spins . 3) + (max-steps . 1))) + (pairs-short + . ((required-lift . 1) + (required-throw . 1) + (required-twist . 1) + (required-death-spiral . 1))) + (ice-dance-rhythm + . ((max-jumps . 1) + (jump-constraint . "single only"))))) + + ;; ========================================================================== + ;; 5. SEMANTIC INVARIANTS + ;; ========================================================================== + (invariants + . (("Each program must have at least one segment") + ("Each segment must have at least one sequence") + ("Each sequence must have at least one element") + ("Jump rotations must be single, double, triple, or quad") + ("Spin levels must be B, L1, L2, L3, or L4") + ("Death spiral edges must be valid (LFO, LBI, RFO, RBI, etc.)") + ("Discipline constraints are enforced at semantic analysis"))))) diff --git a/STATE.scm b/STATE.scm index 1165c84..88656b2 100644 --- a/STATE.scm +++ b/STATE.scm @@ -13,8 +13,8 @@ (project (name . "anvomidav") (tier . "infrastructure") - (license . "AGPL-3.0-or-later") - (language . "ada")) + (license . "MIT OR AGPL-3.0-or-later") + (language . "rust")) (compliance (rsr . #t) diff --git a/conformance/README.md b/conformance/README.md new file mode 100644 index 0000000..b3ee398 --- /dev/null +++ b/conformance/README.md @@ -0,0 +1,56 @@ + + + +# Conformance Test Corpus + +This directory contains the **binding** conformance test corpus for Anvomidav. +These tests define authoritative behavior for the language. + +## Structure + +``` +conformance/ +├── valid/ # Programs that MUST parse and validate without errors +└── invalid/ # Programs that MUST produce specific diagnostics +``` + +## Usage + +### Validate All Valid Examples +```bash +cargo run -p anv-cli -- check conformance/valid/* +``` +All files in `valid/` must succeed without errors. + +### Validate Invalid Examples +```bash +for f in conformance/invalid/*.anv; do + echo "=== $f ===" + cargo run -p anv-cli -- check "$f" 2>&1 +done +``` +Each file in `invalid/` must produce a diagnostic. The diagnostics should be +stable across runs (same error message structure). + +## Adding New Tests + +### Valid Examples +- Add to `valid/` directory +- Must represent legal Anvomidav programs +- Should cover different disciplines and element types +- Name descriptively: `singles_minimal.anv`, `pairs_lift_types.anv` + +### Invalid Examples +- Add to `invalid/` directory +- Each file should trigger ONE specific error type +- Name should indicate the error: `err_missing_program.anv` +- Document the expected error in a comment at the top + +## Stability Requirement + +Conformance tests are **binding**. Once added: +- Valid tests must remain valid across all future versions +- Invalid tests must continue to produce diagnostics +- Error messages should remain structurally stable + +Breaking changes require version bump and migration documentation. diff --git a/conformance/invalid/err_empty_segment.anv b/conformance/invalid/err_empty_segment.anv new file mode 100644 index 0000000..89bcdb3 --- /dev/null +++ b/conformance/invalid/err_empty_segment.anv @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_empty_segment.anv +// Purpose: Missing segment type specification +// Expected Error: Parse error - expected segment type after colon + +program missing_segment_type { + segment sp: { + sequence elements { + jump triple axel + } + } +} diff --git a/conformance/invalid/err_invalid_jump_kind.anv b/conformance/invalid/err_invalid_jump_kind.anv new file mode 100644 index 0000000..bfe5019 --- /dev/null +++ b/conformance/invalid/err_invalid_jump_kind.anv @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_invalid_jump_kind.anv +// Purpose: Invalid jump type (walley is not a recognized jump) +// Expected Error: Lexical or parse error - unknown jump kind + +program invalid_jump { + segment sp: short { + sequence elements { + jump triple walley + } + } +} diff --git a/conformance/invalid/err_invalid_level.anv b/conformance/invalid/err_invalid_level.anv new file mode 100644 index 0000000..2deeba3 --- /dev/null +++ b/conformance/invalid/err_invalid_level.anv @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_invalid_level.anv +// Purpose: Invalid level designation (L5 does not exist) +// Expected Error: Lexical or parse error - unknown level + +program invalid_level { + segment sp: short { + sequence elements { + spin camel L5 + } + } +} diff --git a/conformance/invalid/err_invalid_rotation.anv b/conformance/invalid/err_invalid_rotation.anv new file mode 100644 index 0000000..d272cc1 --- /dev/null +++ b/conformance/invalid/err_invalid_rotation.anv @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_invalid_rotation.anv +// Purpose: Invalid jump rotation (quintuple does not exist) +// Expected Error: Lexical or parse error - unknown rotation + +program invalid_rotation { + segment sp: short { + sequence elements { + jump quintuple axel + } + } +} diff --git a/conformance/invalid/err_missing_program.anv b/conformance/invalid/err_missing_program.anv new file mode 100644 index 0000000..4e16ce6 --- /dev/null +++ b/conformance/invalid/err_missing_program.anv @@ -0,0 +1,10 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_missing_program.anv +// Purpose: Missing program declaration +// Expected Error: Parse error - expected 'program' keyword + +segment sp: short { + sequence elements { + jump triple axel + } +} diff --git a/conformance/invalid/err_pairs_in_singles.anv b/conformance/invalid/err_pairs_in_singles.anv new file mode 100644 index 0000000..21ef479 --- /dev/null +++ b/conformance/invalid/err_pairs_in_singles.anv @@ -0,0 +1,12 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_pairs_in_singles.anv +// Purpose: Invalid element - death spiral edge format +// Expected Error: Parse error - invalid edge specification + +program invalid_edge { + segment sp: short { + sequence elements { + death_spiral INVALID L4 + } + } +} diff --git a/conformance/invalid/err_unclosed_brace.anv b/conformance/invalid/err_unclosed_brace.anv new file mode 100644 index 0000000..a13f489 --- /dev/null +++ b/conformance/invalid/err_unclosed_brace.anv @@ -0,0 +1,9 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: invalid/err_unclosed_brace.anv +// Purpose: Unclosed brace - syntax error +// Expected Error: Parse error - expected '}' + +program unclosed { + segment sp: short { + sequence elements { + jump triple axel diff --git a/conformance/valid/ice_dance_minimal.anv b/conformance/valid/ice_dance_minimal.anv new file mode 100644 index 0000000..b95bac7 --- /dev/null +++ b/conformance/valid/ice_dance_minimal.anv @@ -0,0 +1,24 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: valid/ice_dance_minimal.anv +// Purpose: Minimal valid ice dance program (only single jumps allowed) +// Expected: Parses and validates without errors + +program ice_dance_test { + segment rd: rhythm { + sequence pattern_dance { + pattern waltz + } + + sequence steps { + step serpentine L4 + } + + sequence spin_elem { + spin upright L3 + } + + sequence choreo { + choreographic spiral + } + } +} diff --git a/conformance/valid/pairs_minimal.anv b/conformance/valid/pairs_minimal.anv new file mode 100644 index 0000000..f76c0a7 --- /dev/null +++ b/conformance/valid/pairs_minimal.anv @@ -0,0 +1,36 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: valid/pairs_minimal.anv +// Purpose: Minimal valid pairs program with required elements +// Expected: Parses and validates without errors + +program pairs_test { + segment sp: short { + sequence jumps { + jump triple salchow + } + + sequence lift_elem { + lift Gr5 L4 + } + + sequence throw_elem { + throw triple flip + } + + sequence twist_elem { + twist triple L3 + } + + sequence death_spiral_elem { + death_spiral LBI L4 + } + + sequence spin_elem { + spin camel L4 + } + + sequence step_elem { + step circular L3 + } + } +} diff --git a/conformance/valid/singles_free.anv b/conformance/valid/singles_free.anv new file mode 100644 index 0000000..23599bb --- /dev/null +++ b/conformance/valid/singles_free.anv @@ -0,0 +1,33 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: valid/singles_free.anv +// Purpose: Valid singles free skate with multiple sequences +// Expected: Parses and validates without errors + +program singles_free_test { + segment fs: free { + sequence opening { + jump quad lutz + jump triple toe_loop + } + + sequence spins { + spin camel L4 + spin sit L3 + spin layback L4 + } + + sequence jumps_middle { + jump triple axel + jump triple flip + jump triple loop + } + + sequence footwork { + step circular L4 + } + + sequence closing { + jump double axel + } + } +} diff --git a/conformance/valid/singles_minimal.anv b/conformance/valid/singles_minimal.anv new file mode 100644 index 0000000..76fc2a8 --- /dev/null +++ b/conformance/valid/singles_minimal.anv @@ -0,0 +1,14 @@ +// SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +// Conformance: valid/singles_minimal.anv +// Purpose: Minimal valid singles short program +// Expected: Parses and validates without errors + +program singles_test { + segment sp: short { + sequence elements { + jump triple axel + spin camel L3 + step circular L4 + } + } +} diff --git a/editors/OPTIONAL.md b/editors/OPTIONAL.md new file mode 100644 index 0000000..f9bec81 --- /dev/null +++ b/editors/OPTIONAL.md @@ -0,0 +1,42 @@ + + + +# Editor Integrations (OPTIONAL) + +**Status: Optional - Does NOT block core build** + +This directory contains editor-specific configurations for Anvomidav support. +These are provided for developer convenience but are **not required** for the +core language toolchain to function. + +## Included Editors + +| Directory | Editor | Status | +|-----------|--------|--------| +| `neovim/` | Neovim | Optional | +| `helix/` | Helix | Optional | +| `vscode/` | VS Code / VSCodium | Optional | +| `zed/` | Zed | Optional | + +## Core Build Independence + +The core Anvomidav toolchain (`cargo build` / `cargo test`) does not depend on +any editor configuration. You can: + +- Build and run `anv-cli` without editor plugins +- Run all conformance tests without editor configuration +- Develop new language features using any text editor + +## Maintenance Priority + +During scope-arrest phases (f0), editor integration maintenance is deferred. +Focus is on core language semantics and ISU rule validation. + +The LSP server (`anv-lsp`) is part of the Cargo workspace but is not required +for core functionality. + +## See Also + +- `tree-sitter-anvomidav/` - Tree-sitter grammar for syntax highlighting +- `crates/anv-lsp/` - Language Server Protocol implementation +- `crates/anv-cli/` - Core CLI tool (authoritative) diff --git a/justfile b/justfile new file mode 100644 index 0000000..de325a9 --- /dev/null +++ b/justfile @@ -0,0 +1,115 @@ +# SPDX-License-Identifier: MIT OR AGPL-3.0-or-later +# SPDX-FileCopyrightText: 2025-2026 hyperpolymath +# +# justfile - Local task runner for Anvomidav +# +# Per AUTHORITY_STACK: All local operations must be invoked via `just `. +# Do not run ad-hoc commands; add recipes here instead. + +# Default recipe: show available commands +default: + @just --list + +# === BUILD & TEST === + +# Run all tests +test: + cargo test + +# Build all crates (debug) +build: + cargo build + +# Build all crates (release) +build-release: + cargo build --release + +# Check code without building +check: + cargo check + +# Run clippy lints +lint: + cargo clippy --all-targets --all-features + +# Format code +fmt: + cargo fmt + +# Check formatting without modifying +fmt-check: + cargo fmt -- --check + +# === CLI OPERATIONS === + +# Check example files with anv-cli +check-examples: + cargo run -p anv-cli -- check examples/* + +# Check conformance valid examples +check-conformance-valid: + cargo run -p anv-cli -- check conformance/valid/* + +# Check that conformance invalid examples produce errors +check-conformance-invalid: + #!/usr/bin/env bash + set -e + echo "Checking invalid conformance examples produce errors..." + errors=0 + for f in conformance/invalid/*.anv; do + if cargo run -q -p anv-cli -- check "$f" 2>/dev/null; then + echo "FAIL: $f should have produced an error" + errors=$((errors+1)) + else + echo "OK: $f produced expected error" + fi + done + if [ $errors -gt 0 ]; then + echo "FAILED: $errors files did not produce expected errors" + exit 1 + fi + echo "All invalid examples produced expected errors" + +# Run full conformance suite +conformance: check-conformance-valid check-conformance-invalid + +# === DEMO === + +# Demo: parse and show AST for a singles program +demo: + @echo "=== Anvomidav Demo ===" + @echo "" + @echo "Parsing conformance/valid/singles_minimal.anv..." + cargo run -q -p anv-cli -- parse conformance/valid/singles_minimal.anv + @echo "" + @echo "Checking all valid conformance examples..." + cargo run -q -p anv-cli -- check conformance/valid/* + @echo "All examples valid!" + +# === SMOKE TEST (Golden Path) === + +# Run the golden-path smoke test per ANCHOR +smoke-test: test check-examples + @echo "Smoke test passed!" + +# === CLEAN === + +# Clean build artifacts +clean: + cargo clean + +# === INSTALL === + +# Install anv-cli locally +install: + cargo install --path crates/anv-cli + +# === DEVELOPMENT === + +# Watch for changes and run tests +watch-test: + cargo watch -x test + +# Run specific crate tests +test-crate crate: + cargo test -p {{crate}} diff --git a/tree-sitter-anvomidav/OPTIONAL.md b/tree-sitter-anvomidav/OPTIONAL.md new file mode 100644 index 0000000..ef332a4 --- /dev/null +++ b/tree-sitter-anvomidav/OPTIONAL.md @@ -0,0 +1,37 @@ + + + +# Tree-sitter Grammar (OPTIONAL) + +**Status: Optional - Does NOT block core build** + +This directory contains the tree-sitter grammar for Anvomidav syntax highlighting. +It is provided for editor integration convenience but is **not required** for the +core language toolchain to function. + +## Core Build Independence + +The core Anvomidav toolchain (`cargo build` / `cargo test`) does not depend on +tree-sitter. You can: + +- Build and run `anv-cli` without tree-sitter +- Run all conformance tests without tree-sitter +- Develop new language features without tree-sitter + +## When to Use + +Use the tree-sitter grammar when you want: + +- Syntax highlighting in editors (Neovim, Helix, VS Code, etc.) +- Fast incremental parsing for editor features +- Structural code navigation + +## Maintenance Priority + +During scope-arrest phases (f0), tree-sitter maintenance is deferred. +Focus is on core language semantics and ISU rule validation. + +## See Also + +- `editors/` - Editor-specific configurations +- `crates/anv-syntax/` - Authoritative lexer/parser (Rust)