- All analysis must be grounded in observable facts: logs, stack traces, code paths, compilation errors, or reproduced behavior.
- Do not use speculative qualifiers such as “maybe”, “possibly”, “likely”, “probably”, or “might” when explaining root causes or behavior.
- State what the code does, what the failure is, and what the evidence is. If the root cause is not yet proven, say so explicitly and list the next concrete verification step instead of guessing.
Skills are not post-hoc checklists. They must be read before writing code and used to shape the design.
- Identify the relevant skills for every change. At minimum:
- Concurrency / shared state → m07-concurrency and the "Rust Concurrency and Shared State" section below.
- Error handling → m06-error-handling.
- API / style → coding-guidelines.
- Turn the relevant skill constraints into concrete TodoList items before implementation.
- Use plan mode for any non-trivial change. The plan must explicitly state how each applicable skill constraint is satisfied.
- If the change affects concurrency, produce a lock-order table that lists every thread/loop and the order in which it acquires locks.
When modifying code that uses threads, mutexes, channels, or event loops in this project:
SharedStatehas a single writer. All mutations toSharedStatemust go throughStateEventLoop. Do not mutateSharedStatedirectly fromEventProxy, client handlers, control commands, or any other thread.broadcast_snapshothas a single caller. OnlyStateEventLoopmay callbroadcast_snapshot. Other threads/loops that need a UI refresh must send a state event (e.g.,LocalSessionOutput,RemoteSessionOutput,RemoteSessionInputEcho) and letStateEventLoopbroadcast.- Lock order is part of the design. Before adding or reordering locks, document the lock hierarchy in a code comment and verify that every code path acquires locks in the same order.
- Never hold a lock while calling a callback, broadcasting, or doing I/O. In particular:
clientslock must not be held while callingbuild_snapshotorbroadcast_snapshot.sessionslock must not be held while callingbroadcast_snapshot.Termlock must not be held while callingbroadcast_snapshot.
- Prefer message passing over shared mutable state. Use channels to communicate between loops; keep mutexes for data wholly internal to one thread/loop.
- Verify concurrency changes. After touching concurrency code, run:
cargo clippy -- -D warningscargo test --release ratatui session_sync- If the change affects lock-free paths, add or run a
loommodel test.
Reference skill: actionbook/rust-skills m07-concurrency.
For all Rust code in this project, follow actionbook/rust-skills and coding-guidelines. The non-negotiable subset is:
- Use
?for propagation; do not silentlyunwrap()/expect()in library or runtime code. expect()is only for invariants that indicate a bug, not for user input or I/O failures.- Prefer typed errors with
thiserrorfor domain errors; use context chains where useful.
- Every
unsafeblock must have a// SAFETY:comment explaining why it is sound. - Keep
unsafeblocks minimal; do not wrap large amounts of safe code inunsafe. - Unsafe functions must document their safety contract in a
# Safetysection.
- Naming:
snake_casefor functions/variables,CamelCasefor types/traits,SCREAMING_SNAKE_CASEfor constants. - No
get_prefix on simple getters (fn name()notfn get_name()). - Conversion methods:
as_for cheap references,to_for expensive copies,into_for ownership-consuming conversions. - Use newtypes (
struct Email(String)) to enforce domain semantics at the type level. - Prefer
&[T]/&strover&Vec<T>/&Stringin public APIs. - Pre-allocate collections when the size is known (
Vec::with_capacity,String::with_capacity).
- Keep
main.rsminimal; put logic inlib.rsor modules. - Organize modules by feature, not by type.
- Use builders or typestates for complex construction with invariants.
- Prefer enums over boolean flags for mutually exclusive states.
- Public APIs must be documented (
///); modules use//!.
- Use
std::sync::OnceLock/std::sync::LazyLockinstead oflazy_static!. - Use the
?operator instead oftry!(). - Run
cargo fmt --checkandcargo clippy -- -D warningsbefore committing.