diff --git a/.cursor/rules/wfl-rules.mdc b/.cursor/rules/wfl-rules.mdc index bf4cd6fb..d2610785 100644 --- a/.cursor/rules/wfl-rules.mdc +++ b/.cursor/rules/wfl-rules.mdc @@ -7,8 +7,9 @@ alwaysApply: true Canonical instructions live at the repository root — read them instead of relying on this file, and do not let this file override them: -- `AGENTS.md` — shared agent instructions (project structure, build/test - commands, syntax pitfalls) +- `CLAUDE.md` — canonical shared agent instructions (project structure, + build/test commands, syntax pitfalls, Cursor Cloud setup); `AGENTS.md` points + here - `GOVERNANCE.md`, `testing.md` (binding TDD/testing policy), `REPOSITORY_HYGIENE.md` (placement/output policy), `AI_POLICY.md`, `CONTRIBUTING.md`, `SECURITY.md` diff --git a/.jules/bolt.md b/.jules/bolt.md index 3e1649f8..adca20ff 100644 --- a/.jules/bolt.md +++ b/.jules/bolt.md @@ -3,7 +3,8 @@ Canonical instructions live at the repository root — do not duplicate or redefine them here: -- `AGENTS.md` — shared agent instructions (start here) +- `CLAUDE.md` — canonical shared agent instructions (start here); `AGENTS.md` + points here - `GOVERNANCE.md`, `testing.md`, `REPOSITORY_HYGIENE.md`, `AI_POLICY.md`, `CONTRIBUTING.md`, `SECURITY.md` — binding policy - `History/perf-lessons.md` — the optimization lessons formerly kept in this diff --git a/AGENTS.md b/AGENTS.md index 5b7b127d..45fb4b54 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -1,224 +1,16 @@ # Repository Guidelines -## Project Governance (do not dig — start here) +**Canonical agent instructions live in [`CLAUDE.md`](CLAUDE.md) — read that file first.** -WFL is a **maintainer-led** open-source project (primary Maintainer: **Brad**, Logbie LLC). -Binding community and contribution policy lives at the **repo root** (not only under `Docs/`): +`CLAUDE.md` is the single source of truth for shared agent guidance: project +structure and architecture, build/test/dev commands, coding style, the binding +Testing and Repository-Hygiene policies, documentation rules, LSP workflow, and +the **Cursor Cloud specific instructions** (Rust ≥ 1.94 toolchain requirement and +the `run_integration_tests.sh` / `run_web_tests.sh` end-to-end flows). -| File | What it is | -|---|---| -| `GOVERNANCE.md` | Authority, roles (Maintainer / Contributor / Participant), decision rights, binding technical policies | -| `CODE_OF_CONDUCT.md` | Community standards and enforcement | -| `AI_POLICY.md` | **AI-assisted work is welcome** — WFL was built with AI; do not discriminate against AI use; human author remains accountable | -| `CONTRIBUTING.md` | How to contribute; **Contributor application** process (Discussion or email) | -| `SECURITY.md` | Private vulnerability reporting only — never file security bugs as public issues | -| `testing.md` | **Binding Logbie Testing Policy + WFL testing profile** — Red→Green TDD evidence, required test layers, risk classes, and merge/release gates (see **Testing Guidelines** below) | -| `REPOSITORY_HYGIENE.md` | **Binding Repository Hygiene and Layout Policy** — canonical home for every class of content, tracked-vs-ephemeral rules, approved output roots, archive manifest, exceptions; profile in `.repo-hygiene.toml`, enforced by `scripts/check_repo_hygiene.py` in CI | +This file intentionally carries no policy of its own, so `AGENTS.md` and +`CLAUDE.md` can never drift — update `CLAUDE.md` and everything stays in sync. -**Agent implications (already in force via governance):** - -- **AI is first-class** — use coding agents freely; same quality bar as hand-written work (tests, docs, compatibility, reviewability). -- **Backward compatibility is sacred** — never break existing WFL programs without the documented deprecation path. -- **TDD mandatory** — failing tests first (`tests/`, `TestPrograms/`), governed by the binding **Logbie Testing Policy** in root `testing.md`: auditable **Red→Green** evidence for every behavioral change, coverage at the lowest useful layer plus every affected higher layer. -- **Docs ship with the feature** — same change; validate examples; Dev Diary entry under `History/dev-diary//` for non-trivial work. -- **Hygiene is enforced** — every file has one canonical home (`REPOSITORY_HYGIENE.md`); tests and tools write only under `target/` or temp dirs; never track dumps, logs, caches, local settings, or personal paths. The `repo-hygiene` CI job blocks violations — fix placement, don't widen allowlists. -- **Quality gates** — `cargo fmt`, `clippy -D warnings`, `cargo test`; conventional commits. -- **Do not invent maintainer identity or process** — Contributor status is by application; Maintainers own merges and releases unless those responsibilities are **explicitly delegated**. Prefer first name **Brad** only if referring to the primary maintainer in docs (no last name). -- Community tone: follow `CODE_OF_CONDUCT.md`; technical disagreement is fine; harassment and AI-shaming are not. - -When changing contribution workflow, community rules, or project authority, update the root governance suite **and** keep this section accurate. - -## Project Structure & Modules -Layout is governed by `REPOSITORY_HYGIENE.md` (placement table + root allowlist in `.repo-hygiene.toml`); put new files in their canonical home, not at the root. - -- `src/`: Core compiler/runtime (`main.rs`, `lib.rs`, `repl.rs`, `builtins.rs`). -- `tests/`: Rust integration/unit tests; consumed fixtures under `tests/fixtures//` (intentionally invalid programs: `tests/fixtures/diagnostics/` + an exit-status-asserting test). -- `TestPrograms/`: End‑to‑end WFL programs that must all pass (feature subdirs like `modules/`, `constants/`, `nexus/`; asserted via `describe`/`expect`). -- `examples/`: Polished, validated WFL programs (`web/`, `tools/`). -- `experiments/`: Owned, time-bounded, non-gating prototypes — each `experiments//` needs a `README.md` with Owner/Status/Issue/Created/Review-by/Exit criteria (checker-enforced). -- `benches/`: Performance benchmarks (Criterion). `fuzz/`: standalone cargo-fuzz workspace. -- `wfl-lsp/`: Language Server workspace member (independently versioned). `vscode-extension/`: VS Code extension. -- `Docs/`: Maintained user documentation (6 sections + guides/reference; contributor docs under `Docs/contributing/`). See `Docs/README.md`. -- `Engineering/`: Active designs (`designs/`), plans (`plans/`), evidence (`evidence/`), component records (`components/`). -- `History/`: Chronological, non-normative history — Dev Diary at `History/dev-diary//`, `perf-lessons.md`. -- `Archive/`: Retained inactive material, indexed by `Archive/manifest.json` (non-normative; checker verifies checksums). -- `scripts/`: Maintained automation (`run_integration_tests.*`, `check_repo_hygiene.py`, `build_windows_installer.ps1`, `bump_version.py`, `metrics/`, `docs/`). -- `wix/`: Windows Installer (MSI) configuration. -- `.cursor/rules/`, `.jules/`: thin adapters pointing back to this file and root policy — no policy content of their own. - -## Core Architecture -The WFL compiler pipeline consists of: -``` -Source Code → Lexer → Parser → Analyzer → Type Checker → Interpreter - ↓ ↓ ↓ ↓ ↓ - Tokens AST Validated Type Info Execution -``` - -### Key Components -- **Lexer** (`src/lexer/`): High-performance tokenization using Logos crate -- **Parser** (`src/parser/`): Recursive descent parser with natural language constructs and error recovery - - Includes specialized parsers for containers and AST generation - - Maintains contextual keyword handling for natural language syntax -- **Analyzer** (`src/analyzer/`): Semantic validation and static analysis -- **Type Checker** (`src/typechecker/`): Static type analysis with intelligent inference -- **Interpreter** (`src/interpreter/`): Async-capable direct AST execution using Tokio runtime - - Includes subprocess handling with security sanitization - - Web server support with HTTP request/response handling (integrated via `warp`) - - Environment management with scope control -- **Pattern Module** (`src/pattern/`): Pattern matching engine with bytecode VM - - Compiler for pattern expressions - - VM-based execution for regex-like patterns - - Unicode support and advanced pattern features -- **Standard Library** (`src/stdlib/`): Built-in modules - - Core functions (print, typeof, etc.) - - Math operations (abs, round, random, etc.) - - Text manipulation (length, uppercase, substring, etc.) - - List operations (push, pop, contains, etc.) - - Filesystem I/O with async support - - Crypto module with WFLHASH (custom hash function) - - Time functions - - Random number generation -- **LSP Server** (`wfl-lsp/`): Language Server Protocol implementation for IDE integration -- **REPL** (`src/repl.rs`): Interactive Read-Eval-Print Loop for experimentation - -## Build, Test, and Dev Commands -- **Build**: `cargo build` (release: `cargo build --release`). -- **Run**: `cargo run -- ` or `target/release/wfl `. -- **Test**: `cargo test`; integration requires release binary. - - Integration: `./scripts/run_integration_tests.ps1` or `.sh` - - Web Server: `./scripts/run_web_tests.ps1` or `.sh` - - Docs Validation: `python scripts/validate_docs_examples.py` -- **Bench**: `cargo bench` (Criterion). -- **Format**: `cargo fmt --all`. -- **Lint**: `cargo clippy --all-targets --all-features -- -D warnings`. - -### WFL CLI -- `wfl `: Run a WFL program. -- `wfl`: Start interactive REPL. -- `wfl --lint `: Lint WFL code. -- `wfl --lint --fix --in-place`: Auto-fix WFL code. -- `wfl --edit `: Open the specified file in the default editor. -- `wfl --step `: Run in single-step debug mode. -- `wfl --time `: Run with execution timing. -- `wfl --lex ` / `wfl --parse `: Dump tokens or AST (written under `target/reports/dumps/`). -- `wfl --init [dir]`: Create .wflcfg interactively (default: current directory). -- `wfl --configCheck` / `wfl --configFix`: Check/fix configuration. -- `wfl --dump-env`: Dump environment for troubleshooting. -- `wfl --analyze `: Run static analysis. -- `wfl --test `: Run file in test mode (executes describe/test blocks). - -## Key Language Features -- **Natural Language Syntax**: `store name as "value"`, `check if x is greater than 5`. -- **Type Safety**: Static typing with intelligent type inference. -- **Async Support**: Built-in async/await using Tokio runtime. -- **Pattern Matching**: Regex-like engine with Unicode support. -- **Container System**: OOP with containers. -- **Testing Framework**: Built-in testing with `describe`, `test`, and natural language assertions. -- **Security**: WFLHASH custom crypto, secure subprocess spawning. - -## Coding Style & Naming -- **Format**: `cargo fmt --all` (see `.rustfmt.toml`). -- **Lint**: `cargo clippy --all-targets --all-features -- -D warnings`. -- **Naming**: - - Functions/Files: `snake_case` - - Types/Traits: `CamelCase` - - Constants: `SCREAMING_SNAKE_CASE` - -## Testing Guidelines - -**Binding policy:** root `testing.md` holds the **Logbie Testing Policy** and the -WFL testing profile. It governs every behavioral change. Non-negotiables an agent -MUST follow: - -- **Red → Green → Refactor → Broaden → Record** — write the smallest useful test - FIRST, run it, confirm it **fails for the intended reason**, then make it pass; - a defect fix reproduces the defect. Keep auditable Red evidence (a Red commit - that is an ancestor of Green, or a timestamped CI artifact). A test first - observed after the code already passed is **not** a valid Red step. (§3, §6) -- **Classify risk first (R0–R3)** — concurrency, cancellation, lifecycle, - streaming, untrusted input, crypto/secrets, and backward compatibility are - **R3** and require negative/failure-path plus §11 risk-triggered tests. Risk is - never lowered to dodge a gate. (§5, §11) -- **Real boundaries, real assertions** — don't mock the boundary under test; - assert outcomes + side effects (not "didn't crash"); use negative assertions - for cancellation, writes-after-close, denial. (§7, §8.3) -- **No manufactured green** — never retry/skip/quarantine a required test to go - green; a flaky required test is failing. Non-executable docs programs use the - runner's `// CI-SKIP:` first-line directive and stay statically validated. (§8.2) -- **Concurrency/streaming/lifecycle (§11.3)** — for this repo's async/web/ - streaming work, prove races/ordering, cancellation, timeouts, disconnects, - bounded queues/backpressure, resource limits, clean shutdown, writes-after- - close, and that one slow/failed handler doesn't block unrelated work. -- **PR evidence (§15)** — record risk class, acceptance criteria → tests, Red - evidence, layers run, and residual risk (template in `testing.md`). - -### Mechanics -- **Locations**: - - Rust Unit/Integration: `tests/` (fixtures in `tests/fixtures//`) - - WFL End-to-End: `TestPrograms/` and `TestPrograms//` (must pass with release build; a file belongs here only if the gated runner executes it and failure exits nonzero) - - WFL Test Framework: Use `describe`/`test` blocks, run with `wfl --test ` - - Test output: only under a temp dir or `target/test-artifacts//` — the hygiene checker's working-tree mode fails CI on droppings -- **Conventions**: feature‑oriented names (`*_test.rs`, `*.test.wfl`), keep perf benches under `benches/`. -- **Commands & profile**: one command per layer + the "run all presubmit" block are in root `testing.md`. -- **Testing Guide**: See `Docs/guides/testing-guide.md` for WFL testing framework documentation. - -## Commit & Pull Request Guidelines -- **Conventional Commits**: `feat:`, `fix:`, `docs:`, `test:`, `refactor:`. -- **Pull Requests**: Clear description, linked issues, tests added/updated, repro steps. -- **Pre‑PR Checks**: - - `cargo fmt --all -- --check` - - `cargo clippy --all-targets --all-features -- -D warnings` - - `cargo test --all --verbose` - -## Documentation Development -- **Location**: `Docs/` organized in 6 sections (Introduction, Getting Started, Language Basics, Advanced Features, Standard Library, Best Practices). -- **Structure**: Follow `Docs/wfl-documentation-policy.md` and 19 principles in `Docs/wfl-foundation.md`. -- **Reference Documentation**: Two-tiered system for keywords - - `Docs/reference/keyword-reference.md` - Quick scannable lookup (2-3 pages, all 181 keywords) - - `Docs/reference/reserved-keywords.md` - Complete technical reference (10-15 pages, classifications, edge cases) - - Both updated together; quick reference for speed, comprehensive for understanding -- **Validation**: ALL code examples MUST be validated with MCP tools before adding to docs. - - Test examples in `TestPrograms/docs_examples/` with manifest tracking in `_meta/manifest.json`. - - Run validation: `python scripts/validate_docs_examples.py` - - Use MCP tools: `mcp__wfl-lsp__parse_wfl`, `mcp__wfl-lsp__analyze_wfl`, `mcp__wfl-lsp__typecheck_wfl`, `mcp__wfl-lsp__lint_wfl` -- **Critical Syntax**: - - Conditionals use NESTED blocks: `otherwise: check if`, NOT `otherwise check if` - - Reserved keywords: **181 keywords total** (54 structural, 29 contextual, 96 other, 7 literals; see `Docs/reference/reserved-keywords.md`) - - Always reserved: `is`, `file`, `add`, `current`, `check`, `store`, etc. - - Contextual (can be variables in some contexts): `count`, `list`, `pattern`, `text`, `at`, etc. - - Use underscores to avoid conflicts: `is_active`, `filename`, `my_list` - - See `Docs/reference/keyword-reference.md` (quick) and `Docs/reference/reserved-keywords.md` (complete) - - List push syntax: `push with and `, NOT `push to` - - Loop variable: `count` in count loops, NOT `the current count` - - Typeof syntax: `typeof of value`, NOT `typeof(value)` - - Action syntax: `define action called name with parameters x:`, NOT `action name with x:` -- **Working Examples**: - - Core syntax: `TestPrograms/basic_syntax_comprehensive.wfl`, `file_io_comprehensive.wfl`, `comprehensive_web_server_demo.wfl`, `containers_comprehensive.wfl`, `patterns_comprehensive.wfl` - - Keyword examples: `TestPrograms/docs_examples/keyword_reference/` (11 example files with validation manifest) - -## Agent‑Specific Policies (Critical Rules) -- **Governance**: Follow root `GOVERNANCE.md`, `CODE_OF_CONDUCT.md`, `AI_POLICY.md`, `CONTRIBUTING.md` (see **Project Governance** above). Do not re-litigate AI use; do not skip quality gates because AI produced the draft. -- **Backward Compatibility**: Sacred. Never break existing WFL programs without the documented deprecation path (`GOVERNANCE.md`). Run all `TestPrograms/`. -- **Integration Tests**: Require `cargo build --release` and provided scripts. -- **Documentation**: Keep `Docs/` current. Validate ALL code examples with MCP before adding. Major changes warrant a Dev Diary note in `History/dev-diary//`. User-facing behavior changes ship docs in the same change. -- **Repository Hygiene**: Binding (`REPOSITORY_HYGIENE.md`). One canonical home per file; write test/tool output only under `target/` or temp dirs; archive additions require an `Archive/manifest.json` entry; run `python3 scripts/check_repo_hygiene.py --mode static` before pushing structural changes. -- **Security**: Review `SECURITY.md`. Avoid logging secrets. Use zeroization. No public security issues. - -## Technical Requirements -- **Rust Edition**: 2024 (Min: 1.94+ — raised by the `sqlx` 0.9 dependency; Dev: 1.94+) -- **Versioning**: YY.MM.BUILD (e.g., 26.1.22). Major version always < 256 (Windows MSI compatibility). -- **Key Dependencies**: - - `logos`: Lexer - - `tokio`: Async runtime - - `reqwest`: HTTP client - - `sqlx`: DB support - - `warp`: Web server - - `tower-lsp`: LSP server - - `zeroize`, `subtle`: Crypto - -## LSP Development Workflow -- **Location**: `wfl-lsp/` (LSP), `vscode-extension/` (VS Code). -- **Build/Run**: `cargo build -p wfl-lsp`. -- **Debug**: `RUST_LOG=trace cargo run -p wfl-lsp`. -- **Setup**: `scripts/configure_lsp.ps1`, `scripts/install_vscode_extension.ps1`. -- **Docs**: See `Docs/contributing/lsp-integration.md` for dev guides and `Docs/02-getting-started/editor-setup.md` for user setup. +Binding policy referenced throughout lives at the repository root: `GOVERNANCE.md`, +`CODE_OF_CONDUCT.md`, `AI_POLICY.md`, `CONTRIBUTING.md`, `SECURITY.md`, +`testing.md`, and `REPOSITORY_HYGIENE.md`. diff --git a/CLAUDE.md b/CLAUDE.md index c282863e..15c4009f 100644 --- a/CLAUDE.md +++ b/CLAUDE.md @@ -76,7 +76,7 @@ Layout is governed by `REPOSITORY_HYGIENE.md` (placement table + root allowlist - `Archive/`: Retained inactive material, indexed by `Archive/manifest.json` (non-normative; checker verifies checksums). - `scripts/`: Maintained automation (`run_integration_tests.*`, `check_repo_hygiene.py`, `build_windows_installer.ps1`, `bump_version.py`, `metrics/`, `docs/`). - `wix/`: Windows Installer (MSI) configuration. -- `.cursor/rules/`, `.jules/`: thin adapters pointing back to `AGENTS.md` and root policy — no policy content of their own. +- `.cursor/rules/`, `.jules/`, `AGENTS.md`: thin adapters pointing back to this file (`CLAUDE.md`, the canonical shared agent instructions) and root policy — no policy content of their own. ## Core Architecture The WFL compiler pipeline consists of: @@ -281,6 +281,41 @@ agent MUST follow: - **Setup**: `scripts/configure_lsp.ps1`, `scripts/install_vscode_extension.ps1`. - **Docs**: See `Docs/contributing/lsp-integration.md` for dev guides and `Docs/02-getting-started/editor-setup.md` for user setup. +## Cursor Cloud specific instructions +Guidance for Cloud Agents (and similar ephemeral CI-like VMs) working in this repo. + +- **Rust toolchain (critical).** The stock Cloud Agent base image has shipped an + older Rust (observed: 1.83.0), but this crate requires **Rust ≥ 1.94** (edition + 2024 plus the `sqlx` 0.9 dependency, whose `rust-version` is `1.94`). A stock + image therefore cannot build WFL at all — install a satisfying stable toolchain + first: + ```bash + rustup toolchain install stable --profile default # includes rustfmt + clippy + rustup default stable + ``` + `scripts/cloud-agent-install.sh` is the canonical, idempotent bootstrap: it does + exactly this (and enforces the `>= 1.94` floor), then runs `cargo fetch --locked` + and `cargo build --release`. The Cloud Agent environment's install step runs the + equivalent sequence, so a fresh agent boots with the release `wfl` binary ready. +- **Disk.** See the disk-space note in **Build, Test, and Dev Commands**: a full + `target/` tree is ~30 GB and a constrained VM can SIGBUS mid-link. `cargo clean` + first only when free space is tight. +- **End-to-end test flows (require the release binary).** Build it first + (`cargo build --release`), then: + - `./scripts/run_integration_tests.sh` — ensures the release binary, runs the + Rust integration tests, and executes every gated `TestPrograms/*.wfl` + end-to-end. `--test-only` reuses an already-built binary. + - `./scripts/run_web_tests.sh` — starts real WFL web servers on `localhost` and + drives them with `curl` (plain HTTP, route params/headers/404, and TLS with + the HTTP→HTTPS 301 redirect). Needs `curl`; the TLS case also needs `openssl` + to mint a throwaway cert (that case is skipped if `openssl` is absent). +- **Presubmit gates** (same as CI): `cargo fmt --all -- --check`, + `cargo clippy --all-targets --all-features -- -D warnings`, and + `cargo test --workspace`. +- **No always-on server.** WFL has no background dev server (the web server is + launched per-program by a `listen` statement), so a Cloud Agent needs nothing in + a `start` phase — all setup belongs in the install step. + ## Claude Code Hooks - **Location**: `.claude/hooks/` (hook scripts), `.claude/settings.json` (configuration). - **Auto-format**: Rust files are automatically formatted after Edit/Write operations via `PostToolUse` hook. diff --git a/GOVERNANCE.md b/GOVERNANCE.md index 45889cbc..64fd4905 100644 --- a/GOVERNANCE.md +++ b/GOVERNANCE.md @@ -84,8 +84,9 @@ breaking changes; Maintainers still own the compatibility bar. ## 3. Binding technical policies These policies are **non-negotiable** for accepted contributions. They already -appear in `AGENTS.md`, `CLAUDE.md`, the contributing guide, and collaboration -docs; this section makes them governance-level requirements. +appear in `CLAUDE.md` (the canonical shared agent instructions, to which +`AGENTS.md` points), the contributing guide, and collaboration docs; this +section makes them governance-level requirements. ### 3.1 Backward compatibility is sacred diff --git a/REPOSITORY_HYGIENE.md b/REPOSITORY_HYGIENE.md index 257c40fa..78d08b65 100644 --- a/REPOSITORY_HYGIENE.md +++ b/REPOSITORY_HYGIENE.md @@ -153,8 +153,8 @@ keeps every mirror in agreement. - Tool-required configuration stays in its conventional location only while a current workflow consumes it. - Configuration summaries in agent files and READMEs are non-authoritative - pointers. `AGENTS.md` is the canonical source of shared agent instructions; - `CLAUDE.md`, `.cursor/`, `.jules/`, and similar tool-specific files carry + pointers. `CLAUDE.md` is the canonical source of shared agent instructions; + `AGENTS.md`, `.cursor/`, `.jules/`, and similar tool-specific files carry only discovery adapters and genuine tool-specific deltas, and may not redefine governance, testing, compatibility, or placement policy. diff --git a/scripts/cloud-agent-install.sh b/scripts/cloud-agent-install.sh new file mode 100755 index 00000000..563aab5a --- /dev/null +++ b/scripts/cloud-agent-install.sh @@ -0,0 +1,57 @@ +#!/usr/bin/env bash +# Cloud Agent install script for WFL. +# +# Idempotent repository bootstrap run after the source tree is checked out. +# It prepares the exact toolchain and build state a Cloud Agent needs to build, +# test, lint, and run WFL end to end: +# +# * a stable Rust toolchain that satisfies the crate's rust-version (>= 1.94, +# required by edition 2024 and the sqlx 0.9 dependency), with the rustfmt +# and clippy components the CI gates use; +# * all Cargo dependencies fetched against the committed Cargo.lock; +# * the release `wfl` binary, which the integration and web-server test +# runners (scripts/run_integration_tests.sh, scripts/run_web_tests.sh) +# require to exist. +# +# It starts no long-running processes: WFL has no always-on dev server (the web +# server is launched per-program by `listen`), so nothing belongs in `start`. +set -euo pipefail + +# Run from the repository root regardless of the caller's working directory. +repo_root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)" +cd "$repo_root" + +# Minimum Rust version required by Cargo.toml (`rust-version`). +required_rust_minor=94 + +echo "==> Ensuring a stable Rust toolchain (>= 1.${required_rust_minor}) is installed" +if ! command -v rustup >/dev/null 2>&1; then + echo "error: rustup is not available on PATH; the base image must provide the Rust toolchain installer." >&2 + exit 1 +fi + +# The `default` profile pulls in rustfmt and clippy, matching the CI toolchain +# (dtolnay/rust-toolchain@stable). Re-running is a cheap no-op once installed. +rustup toolchain install stable --profile default --no-self-update +rustup default stable + +# Fail fast with a clear message if the resolved stable is somehow older than +# the crate's MSRV, instead of dying deep in a compile. +rust_minor="$(rustc +stable --version | sed -E 's/^rustc 1\.([0-9]+)\..*/\1/')" +if [ "${rust_minor:-0}" -lt "$required_rust_minor" ]; then + echo "error: stable Rust is 1.${rust_minor}, but WFL requires >= 1.${required_rust_minor}." >&2 + exit 1 +fi +echo "==> Using $(rustc --version)" + +echo "==> Fetching Cargo dependencies (locked to Cargo.lock)" +cargo fetch --locked + +# Build the release binary the integration/web test runners depend on. The +# release profile keeps debuginfo (Cargo.toml sets debug = true), so this is the +# largest single step; running it here bakes the binary into the environment so +# fresh agents start ready to run WFL programs. +echo "==> Building the release wfl binary" +cargo build --release --locked + +echo "==> WFL install complete: $(./target/release/wfl --version)"