Architecture¶
Guisu is a Cargo workspace with 7 crates organised in strict layers. Higher layers depend on lower layers, never the reverse. There are no circular dependencies; cargo tree --workspace --no-dedupe confirms it.
Dependency table¶
The arrows below are read as "depends on". The table lists every cross-crate dependency; an absent row means the crate is fully self-contained.
| ↓ depends on → | core |
crypto |
vault |
template |
config |
engine |
cli |
|---|---|---|---|---|---|---|---|
core (Layer 0) |
— | ||||||
crypto (Layer 1) |
✓ | — | |||||
vault (Layer 1) |
✓ | — | |||||
template (Layer 2) |
✓ | ✓ | ✓ | — | |||
config (Layer 2) |
✓ | ✓ | — | ||||
engine (Layer 3) |
✓ | ✓ | ✓ | ✓ | ✓ | — | |
cli (Layer 4) |
✓ | ✓ | ✓ | ✓ | ✓ | — |
Read row-by-row:
corehas no first-party dependencies (onlystd, plusgit2/serde/serde_json/thiserrorforErrorenum variants).cryptoandvaultdepend only oncore.templatedepends oncore,crypto,vault(so it can call encryption and vault lookups during rendering).configdepends oncoreandcryptoonly. It does not depend ontemplate— when it finds a.guisu.toml.j2, it emits a helpful error and lets the CLI layer do the rendering (seeConfig::load_from_sourceincrates/config/src/config.rs). The CLI renders the template, caches the result keyed by template hash in the state DB, then feeds the rendered TOML back toConfig::from_toml_str.enginedepends on all ofcore,crypto,vault,template,config(it orchestrates the apply pipeline).clidepends on every other crate (it is the user-facing binary).
Layer responsibilities (one-line summary)¶
| Crate | Layer | Role |
|---|---|---|
guisu-core |
0 | Newtype path types, platform detection, error types. Only depends on std. |
guisu-crypto |
1 | age identity loading, encryption, decryption, file + inline. |
guisu-vault |
1 | SecretProvider trait; built-in bw and rbw in bw.rs, bws in bws.rs. |
guisu-template |
2 | minijinja env, ~30 functions and filters, platform-aware context. |
guisu-config |
2 | .guisu.toml loading, per-platform variables, path resolution. |
guisu-engine |
3 | Three-state model, persistent redb state, parallel processing. |
guisu-cli |
4 | clap argument parsing, command implementations, conflict TUI. |
Module map¶
guisu-engine is the largest crate. Its src/ layout is:
| File | What it contains |
|---|---|
state.rs |
SourceState, TargetState, DestinationState, PersistentState trait, redb-backed implementation. |
entry.rs |
SourceEntry, TargetEntry, DestEntry, EntryKind enums. |
attr.rs |
FileAttributes (plain struct: is_template, is_encrypted, mode). |
content.rs |
The raw byte pipeline: read, decrypt, render. |
processor.rs |
ContentProcessor<D, R> — generic decrypt + render pipeline. |
database.rs |
redb table definitions. |
hash.rs |
BLAKE3 helpers. |
system.rs |
Platform-specific destination state reads. |
validator.rs |
Cross-state validation (e.g. is the source well-formed?). |
verify.rs |
Per-entry drift detection between target and destination; shared comparison primitive for apply/verify. |
git.rs |
In-process git operations (init, fetch, merge) using git2. |
hooks/ |
Pre/post hook discovery and execution (modes: always/once/onchange, set in TOML). |
adapters/ |
Adapters to alternative implementations (e.g. an HTTP-based SourceState reader for tests). |
Why strict layers?¶
The strict layering buys two things:
- Bounded compile time. A change to
guisu-corerebuilds the whole workspace; a change toguisu-clirebuilds onlyguisu-cliand the libraries it transitively depends on (which is everything in practice, but the layer check still catches accidental layering violations). - Substitutability. Library users can pick a subset: a CI tool that just renders templates and never touches the engine can depend on
guisu-templatealone.
See also¶
- Three-State Model — what the engine does.
- Data Flow — how a request moves through the layers.
- Crates — per-crate public API and responsibility.