Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

ashlar: rules for agents and developers

ashlar is a Rust library for building fast desktop and web apps: documents and undo, commands, background jobs, files and settings, native OS features, UI components (egui), and a runtime that gives every app crash safety, telemetry and agent control (control port, MCP, CLI) for free. Domain widgets (a timeline, a CAD canvas…) are app-specific and stay in the apps; ashlar only provides the general building blocks they are made from.

0. Never crash

No unwrap/expect/panic!/unreachable!/todo!/unimplemented! outside tests (denied in [workspace.lints.clippy]), no unsafe (forbidden; only ashlar-native may later relax this for FFI, one module at a time, with // SAFETY: comments). Every input-derived number is hostile: get() not [i], checked/saturating math, capped allocations, bounded recursion. Lock poisoning is not fatal (lock().unwrap_or_else(PoisonError::into_inner)). Background work runs under catch_unwind. Integration-test files start with #![allow(clippy::unwrap_used, clippy::expect_used, clippy::panic)].

1. No app code, no app names

A crate here must serve more than one app and never depend on one. Never name the apps that use ashlar, anywhere in this repository (public API, identifiers, docs, agent instructions, commit messages): describe them by kind instead, “a video editor”, “a DAW”. cargo xtask names enforces this over every file in the repository (the names are kept only as hashes; false positives go in xtask/names-allow.txt). The one exception is the “Built with ashlar” section of the root README, allowed in that file only.

2. Layering (cargo xtask layers)

Crates have a rank (see xtask/src/main.rs); a crate depends only on lower ranks. Ranks 0–4 never depend on egui/eframe/winit: the core is headless and builds for wasm32.

3. Performance is a feature

Idle apps do zero work (repaint on demand). Caches are keyed by revision numbers, not by diffing. Long lists are virtualized. No blocking I/O on the UI thread. Benches guard every hot path.

4. Gates before every commit

cargo xtask ci: fmt check, names, layers, deny-panics, deps (cargo-deny, when installed), then clippy -D warnings, tests and the wasm32 check (ranks 0–1, ashlar-ui, ashlar-app) side by side (--no-wait skips waiting for other checkouts’ builds). Also cargo xtask msrv, advisories and bench; see docs/contributing.md. One task id per commit (AS-P1.2: history merge keys), only green states, attribution line at the end.

5. Stable contracts

Items marked CONTRACT in ashlar-command are shared across crates built in parallel: change them only additively.

6. Working in parallel

One git worktree per agent under .claude/worktrees/<name> (inside the checkout, kept out of git), branch wt/<name>, own CARGO_TARGET_DIR (target/agent-<name> inside the worktree); remove the worktree and its branch once merged. Never commit on main; the integrator merges. Build and test only your crates (cargo test -p <crate>); the full gate runs at integration.