This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
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/):
| 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 Policy 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 |
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 roottesting.md(see Testing Policy below): every behavioral change needs auditable Red→Green evidence and 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/<year>/for non-trivial work. - Hygiene is enforced — every file has one canonical home (
REPOSITORY_HYGIENE.md); tests and tools write only undertarget/or temp dirs; never track dumps, logs, caches, local settings, or personal paths. Therepo-hygieneCI 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.
These 19 principles are the foundation of WFL's design. Every language, documentation, and tooling change should uphold them. Full descriptions live in Docs/wfl-foundation.md.
- Natural-Language Syntax — Mirror natural language so code reads like English and lowers the learning curve.
- Minimize Special Characters — Prefer words over symbols; use special characters only when they serve a clear purpose.
- Readability & Clarity — Favor self-explanatory code over terse or cryptic expressions.
- Clear & Actionable Error Reporting — Provide context-aware, Elm-inspired errors that suggest solutions.
- Type Safety & Compatibility — Enforce strict type checking with inference to prevent runtime errors.
- Support for Modern Features — Express async operations and pattern matching naturally.
- Interoperability with Web Standards — Integrate seamlessly with JavaScript, CSS, and HTML.
- Built-in Security Features — Embed secure defaults (e.g., output escaping) to prevent common vulnerabilities.
- Accessibility for Beginners — Keep features approachable and easy to learn.
- Expressiveness for Experienced Developers — Offer powerful, concise features for sophisticated code.
- Balanced Simplicity & Power — Stay simple to use while retaining robust capabilities.
- Community & Collaboration — Foster sharing and mutual learning through clear code.
- Performance Optimization — Optimize transparently (short-circuiting, caching) without manual tuning.
- Integration with Standard Libraries — Provide a comprehensive stdlib aligned with natural-language syntax.
- Scalability & Maintainability — Support small scripts and large applications with modular structures.
- Gradual Learning Curve — Introduce advanced concepts progressively.
- Error Transparency — Make error handling and debugging straightforward and transparent.
- Encouragement of Best Practices — Promote standards that yield high-quality, maintainable code.
- Avoidance of Unnecessary Conventions — Challenge legacy conventions (e.g., mandatory semicolons) that lack clear justification.
WFL is deliberately both a "my first language" and a language strong enough for production. This only works as a gradient, not a compromise — the beginner path must be a subset of the expert path, with no cliffs between them. When principles appear to conflict, this invariant takes precedence:
For every feature, the beginner form and the expert form must be the same form, or connected by a smooth path with nothing to unlearn.
Apply it as a test on every language, docs, or tooling change: if a beginner learns a habit that a production user must later undo — or must work around the language to do the most natural thing — that is a crack in the tightrope to fix, not to document. Terser expert forms are welcome only when a beginner can grow into them without unlearning the simple form. Full description in Docs/wfl-foundation.md.
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 undertests/fixtures/<feature>/(intentionally invalid programs:tests/fixtures/diagnostics/+ an exit-status-asserting test).TestPrograms/: End‑to‑end WFL programs that must all pass (feature subdirs likemodules/,constants/,nexus/; asserted viadescribe/expect).examples/: Polished, validated WFL programs (web/,tools/).experiments/: Owned, time-bounded, non-gating prototypes — eachexperiments/<topic>/needs aREADME.mdwith 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 underDocs/contributing/). SeeDocs/README.md.Engineering/: Active designs (designs/), plans (plans/), evidence (evidence/), component records (components/).History/: Chronological, non-normative history — Dev Diary atHistory/dev-diary/<year>/,perf-lessons.md.Archive/: Retained inactive material, indexed byArchive/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/,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.
The WFL compiler pipeline consists of:
Source Code → Lexer → Parser → Analyzer → Type Checker → Interpreter
↓ ↓ ↓ ↓ ↓
Tokens AST Validated Type Info Execution
- 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
- Disk space (clean before building when disk is low): The
target/tree (debug + release, withdebug = trueon release) grows to ~30 GB and can exhaust a constrained environment's disk allowance, causingNo space left on device/ linkerBus errorfailures mid-build. When a build dies that way you have tocargo cleanand rebuild from scratch anyway — so cleaning up front is strictly cheaper than paying for a failed build plus the clean-and-rebuild. Don't clean unconditionally, though (that throws away incremental compilation on machines with plenty of disk). Instead clean intelligently, based on free space — clean only when there isn't room for a full build (~30 GB here):On a roomy machine this stays fully incremental; in the constrained environment it cleans just-in-time. (A lighter, incrementality-preserving alternative is to shrink# Linux build env: cargo clean first only when free space is tight, then build. [ "$(df -BG --output=avail . | tail -1 | tr -dc '0-9')" -lt 30 ] && cargo clean cargo build # or: cargo build --release
target/via profile tweaks — e.g.debug = 0for dependencies — not adopted here so release backtraces stay intact.) - Build:
cargo build(release:cargo build --release) — see the disk-space note above before building in a constrained environment. - Run:
cargo run -- <file.wfl>ortarget/release/wfl <file.wfl>. - Test:
cargo test; integration requires release binary.- Integration:
./scripts/run_integration_tests.ps1or.sh - Web Server:
./scripts/run_web_tests.ps1or.sh - Docs Validation:
python scripts/validate_docs_examples.py
- Integration:
- Bench:
cargo bench(Criterion). - Format:
cargo fmt --all. - Lint:
cargo clippy --all-targets --all-features -- -D warnings.
wfl <file>: Run a WFL program.wfl: Start interactive REPL.wfl --lint <file>: Lint WFL code.wfl --lint --fix <file> --in-place: Auto-fix WFL code.wfl --edit <file>: Open the specified file in the default editor.wfl --step <file>: Run in single-step debug mode.wfl --time <file>: Run with execution timing.wfl --lex <file>/wfl --parse <file>: Dump tokens or AST (written undertarget/reports/dumps/).wfl init: Create missing.wflcfg,AGENTS.md, andCLAUDE.mdin the current directory; preserve existing files (no directory argument).wfl config: Configure global WFL defaults interactively (no directory argument).wfl --configCheck/wfl --configFix: Check/fix configuration.wfl --dump-env: Dump environment for troubleshooting.wfl --analyze <file>: Run static analysis.wfl --test <file>: Run file in test mode (executes describe/test blocks).wfl --execution-timeout <seconds> <file>: Override only this invocation's shared deadline; whole seconds from 1 through 31536000, before the filename. Defaults, config caps and other limits remain unchanged.
- 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.
- 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
- Functions/Files:
WFL adopts the Logbie Testing Policy (full text + the WFL testing profile in
root testing.md). It is binding for every behavioral change; the highlights an
agent MUST follow:
- Red → Green → Refactor → Broaden → Record. Write the smallest useful test FIRST and run it to confirm it fails for the intended reason, then make it pass. A defect fix MUST reproduce the defect. Keep auditable evidence (a Red test-only commit that is an ancestor of the Green commit, or a timestamped CI artifact) — a test first observed after the code already passed does not establish Red. (§3, §6)
- Risk class first. Classify R0–R3 before implementing; when ambiguous, the higher class applies, and it MUST NOT be lowered to dodge a gate. Anything touching concurrency, cancellation, lifecycle, streaming, untrusted input, crypto/secrets, or backward compatibility is R3 and needs negative/ failure-path + the §11.3/§11.1 risk-triggered tests. (§5, §11)
- Real boundaries. A test MUST NOT mock the boundary it claims to verify; "end-to-end" means the real binary/socket/file. Assert outcomes and side effects, not "did not crash." Use negative assertions where absence matters (cancellation, writes-after-close, denial). (§7, §8.3)
- No manufactured green. Required tests are never made green via retries,
skips, ignores, quarantine, or relaxed assertions; a flaky required test is a
failing test. Non-executable docs examples use the runner's
// CI-SKIP:first-line directive and are still validated statically. (§8.2) - Concurrency/streaming/lifecycle (§11.3) — always required for this repo's async/web/streaming work: prove races/ordering, cancellation, timeouts, disconnects, bounded queues/backpressure, resource limits, clean shutdown, and writes-after-close, and that one slow/failed handler does not block unrelated work.
- PR evidence (§15). Every behavioral PR records risk class, acceptance
criteria → tests, Red evidence, the layers run, and residual risk (template in
testing.md). - Same bar for AI work. AI-authored code/tests get the same verification — "the model said it works" is not evidence.
- Locations:
- Rust Unit/Integration:
tests/(fixtures intests/fixtures/<feature>/) - WFL End-to-End:
TestPrograms/andTestPrograms/<feature>/(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/testblocks, run withwfl --test <file> - Test output: only under a temp dir or
target/test-artifacts/<suite>/— the hygiene checker's working-tree mode fails CI on droppings
- Rust Unit/Integration:
- Conventions: feature‑oriented names (
*_test.rs,*.test.wfl), keep perf benches underbenches/. - Commands & profile: one command per layer + the "run all presubmit" block are in root
testing.md. - Testing Guide: See
Docs/guides/testing-guide.mdfor WFL testing framework documentation. - CLI prompt portability: Piped stdin is not a terminal, and rustyline's
prompt output depends on
TERMand the platform. Tests that assert rustyline prompts with piped input must explicitly select line-oriented mode using.env("TERM", "dumb")on the childCommand; see the helper intests/config_command_test.rs. Keep the setting local to that child, retain prompt/value/exit-status assertions, and verify Linux and Windows results. Tests of terminal editing or TTY behavior need a real pseudo-terminal instead. - Separate Cargo lockfiles: The root workspace and
fuzz/resolve dependencies separately. Adding, removing, moving, or changing dependencies or features can require updatingfuzz/Cargo.lockeven when the rootCargo.lockis unchanged, especially when moving a dev-dependency into runtime dependencies. Inspect both lockfiles, refresh only the required dependency resolution, and commit affected lockfiles together with the manifest change. Root builds/tests do not cover the standalone fuzz workspace; run its locked compile check listed below. Avoid unrelated dependency upgrades.
- Conventional Commits:
feat:,fix:,docs:,test:,refactor:. - Pull Requests: Clear description, linked issues, tests added/updated, repro steps.
- Pre‑PR Checks:
cargo fmt --all -- --checkcargo clippy --all-targets --all-features -- -D warningscargo test --all --verbosecargo check --locked --manifest-path fuzz/Cargo.toml(stable compile check; does not run fuzz campaigns)
- Verify the pushed revision: Inspect required GitHub Actions jobs for the actual PR head after each push, including Linux and Windows integration and fuzz compilation. Read failing job logs before attributing a failure to a known issue; cancellation by matrix fail-fast is not evidence of a timeout. Record the commit and run link, and distinguish passed, pending, failed, and canceled checks. Preserve unexplained local failures in the evidence and linked issue even if CI passes; an issue does not waive a required gate.
- Docs Are Part of the Feature (MANDATORY): Every change that adds, removes, or alters user-facing behavior — new/changed language syntax, keywords, statements, stdlib functions, CLI flags, or config options — MUST update or add the corresponding documentation in the same change. A feature is not complete until its docs are written. This includes:
- The relevant guide under
Docs/(e.g. a new statement → its section in the matchingDocs/04-advanced-features/*orDocs/05-standard-library/*page). - Both keyword references (
Docs/reference/keyword-reference.mdandDocs/reference/reserved-keywords.md) when keywords are added or reclassified — update them together. - A working example (in
TestPrograms/, validated with MCP) demonstrating the feature. - A Dev Diary entry in
History/dev-diary/<year>/for any non-trivial feature or behavior change. - When a feature is removed or its syntax changes, remove or fix the now-stale docs and examples — don't leave contradictions.
- The relevant guide under
- Docs Must Be Honest — "validate docs" (MANDATORY): Documentation describes what actually ships today, not what is aspirational. This is a binding policy, not a preference:
- No overclaiming runtime behavior. Never describe behavior the runtime does not have (e.g. calling serial request handlers "parallel" or saying they "don't block others"). Prefer the precise word — say "concurrent" (interleaved on one thread) vs "parallel" (multiple cores) deliberately, and describe the transport/handler split accurately.
- Mark planned/future behavior explicitly. Anything not yet implemented must be labeled as planned/future so a reader never mistakes it for current behavior.
- Validate, don't just assert. Every user-visible change ships validated docs (MCP tools +
python scripts/validate_docs_examples.pyfor any touched example) and a Dev Diary entry, in the same change. "Validate docs" means both: the examples run, and the prose matches the implementation. - When behavior changes, fix the now-stale claims in the same change — a doc that contradicts the code is a bug.
- Location:
Docs/organized in 6 sections (Introduction, Getting Started, Language Basics, Advanced Features, Standard Library, Best Practices). - Structure: Follow
Docs/wfl-documentation-policy.mdand 19 principles inDocs/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
- Test examples in
- Critical Syntax:
- Conditionals use NESTED blocks:
otherwise: check if, NOTotherwise 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) andDocs/reference/reserved-keywords.md(complete)
- Always reserved:
- List push syntax:
push with <list> and <value>, NOTpush to - Loop variable:
countin count loops, NOTthe current count - Typeof syntax:
typeof of value, NOTtypeof(value) - Action syntax:
define action called name with parameters x:, NOTaction name with x:
- Conditionals use NESTED blocks:
- 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)
- Core syntax:
- 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 allTestPrograms/. - Integration Tests: Require
cargo build --releaseand provided scripts. - Documentation: MANDATORY — any added or changed feature MUST ship its docs in the same change (see "Documentation Development"). Keep
Docs/current, validate ALL code examples with MCP before adding, and add a Dev Diary note inHistory/dev-diary/<year>/for non-trivial changes. - Repository Hygiene: Binding (
REPOSITORY_HYGIENE.md). One canonical home per file; write test/tool output only undertarget/or temp dirs; archive additions require anArchive/manifest.jsonentry; runpython3 scripts/check_repo_hygiene.py --mode staticbefore pushing structural changes. - Security: Review
SECURITY.md. Avoid logging secrets. Use zeroization. No public security issues.
- Rust Edition: 2024 (MSRV: 1.94+ — raised by the
sqlx0.9 dependency; Dev: 1.94+) - Versioning: YY.MM.BUILD (e.g., 26.1.22). Major version always < 256 (Windows MSI compatibility).
- Key Dependencies:
logos: Lexertokio: Async runtimereqwest: HTTP clientsqlx: DB supportwarp: Web servertower-lsp: LSP serverzeroize,subtle: Crypto
- 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.mdfor dev guides andDocs/02-getting-started/editor-setup.mdfor user setup.
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
sqlx0.9 dependency, whoserust-versionis1.94). A stock image therefore cannot build WFL at all — install a satisfying stable toolchain first:rustup toolchain install stable --profile default # includes rustfmt + clippy rustup default stablescripts/cloud-agent-install.shis the canonical, idempotent bootstrap: it does exactly this (and enforces the>= 1.94floor), then runscargo fetch --lockedandcargo build --release. The Cloud Agent environment's install step runs the equivalent sequence, so a fresh agent boots with the releasewflbinary 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 cleanfirst 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 gatedTestPrograms/*.wflend-to-end.--test-onlyreuses an already-built binary../scripts/run_web_tests.sh— starts real WFL web servers onlocalhostand drives them withcurl(plain HTTP, route params/headers/404, and TLS with the HTTP→HTTPS 301 redirect). Needscurl; the TLS case also needsopensslto mint a throwaway cert (that case is skipped ifopensslis absent).
- Presubmit gates (same as CI):
cargo fmt --all -- --check,cargo clippy --all-targets --all-features -- -D warnings, andcargo test --workspace. - No always-on server. WFL has no background dev server (the web server is
launched per-program by a
listenstatement), so a Cloud Agent needs nothing in astartphase — all setup belongs in the install step.
- Location:
.claude/hooks/(hook scripts),.claude/settings.json(configuration). - Auto-format: Rust files are automatically formatted after Edit/Write operations via
PostToolUsehook. - Prerequisites:
- Windows PowerShell: Default configuration (built into Windows).
- PowerShell Core (pwsh): Optional cross-platform alternative (requires installation).
- Bash: Alternative hook available (
format-rust.sh) for Unix/Linux/macOS/Git Bash.
- Docs: See
.claude/hooks/README.mdfor configuration options and troubleshooting.