Skip to Content
Krad ADE

Checks

The commands every change passes and the rules of the engineering guide, summarised.

Run these before opening an issue or a pull request:

just format-check        # rustfmt with the pinned nightly
just lint                # clippy, pedantic, no unwrap / expect / panic
cargo test --workspace

just release-preflight runs all three in that order.

Formatting

Never run cargo fmt on stable in this repository. just format, just format-check or plain cargo fmt select the pinned nightly through rust-toolchain.toml.

The full rules are in CLAUDE.md. This page summarises them.

Lint set

just lint runs clippy on every crate and target with warnings denied:

cargo clippy --workspace --all-targets -- -D warnings -W clippy::pedantic \
  -W clippy::unwrap_used -W clippy::expect_used -W clippy::panic \
  -W clippy::dbg_macro -W clippy::print_stdout -W clippy::print_stderr \
  -W clippy::todo -W clippy::undocumented_unsafe_blocks

For one crate, run cargo fmt -p <crate> -- --check, the same clippy line with -p <crate>, and cargo test -p <crate> <test_name>.

Crate boundaries

The root Cargo.toml is a virtual workspace with one responsibility per crate. The dependency rules are mandatory:

  • krad-app -> krad-ui -> {krad-session -> {krad-pty, krad-term}, krad-repo, krad-store, krad-agents, krad-chat, krad-gitlab, krad-github, krad-update, krad-lsp, krad-extensions, krad-host}, plus krad-app -> krad-agents and krad-app -> krad-store.
  • krad-repo, krad-chat, krad-lsp, krad-extensions and krad-agents may depend on krad-host, which depends only on krad-domain. Any crate may depend on krad-domain. No other edges and no cycles.
  • krad-domain depends on no workspace crate and on none of gpui, libghostty-vt or tokio.
  • krad-term does not depend on krad-pty; it is tested by feeding raw bytes.
  • gpui is allowed only in krad-ui and krad-app. After a change to a Cargo.toml, cargo tree -i gpui-pre -e normal --workspace confirms it.
  • External dependencies are declared once in [workspace.dependencies]. Adding, removing or upgrading a crate is asked first.

Error handling

  • thiserror enums per crate or module boundary in library crates; anyhow only in krad-app and top-level task handlers.
  • Errors propagate with ? and gain context when they cross a layer. A Result that matters is never silenced with let _ = or .ok().
  • No .unwrap(), .expect() or panic! in production code. expect is allowed only where the invariant is proven locally, and its message states it. Tests may unwrap.

Naming and style

  • Names follow the vocabulary in CONTEXT.md.
  • snake_case for functions, modules and variables, UpperCamelCase for types and traits, SCREAMING_SNAKE_CASE for constants. No I prefixes, no Impl, Manager or Helper suffixes.
  • foo.rs plus foo/ for submodules, never foo/mod.rs. A file past about 400 lines, or one that mixes responsibilities, is split.
  • Private by default, pub(crate) for crate internals, pub only for what another crate uses.
  • The domain is modelled with types: newtypes for identifiers and units, enums instead of boolean flags or string states, no magic values.
  • No comments, except the // SAFETY: comment every unsafe block needs and the # Errors, # Panics and # Safety sections clippy requires.
  • tracing instead of println!, and no secrets, tokens or terminal contents in logs or error messages.
  • The UI thread never blocks: PTY, process, file and network I/O run on the background executor or dedicated threads.

Tests

  • Behaviour changes add or update tests: unit tests in #[cfg(test)] mod tests next to the code, cross-crate behaviour in the crate's tests/, and GPUI interaction tests when UI behaviour changes.
  • Domain logic is testable without a window, and terminal behaviour is tested by feeding raw ANSI bytes to krad-term.
  • A change to platform code states on which platforms it was compiled and tested.

On this page