Architecture
Lexicon is a Rust workspace of 15 crates organized into strict dependency layers. This document describes the crate graph, key design decisions, data flow, and extension points.
Crate dependency graph
Section titled “Crate dependency graph”Layer 6 (frontends) cli tui \ / |Layer 5 (orchestrator) \ core / | / | \ | \ |Layer 4 (AI) ai | \ | \ | | | \| \ |Layer 3 (domain) conversation scaffold | | | |Layer 2 (services) repo audit gates coverage | | / | |Layer 1 (engines) fs scoring conformance api \ | / /Layer 0 (types) \ spec /--------/Layer 0 — spec: Zero-dependency leaf crate. All domain types, schemas,
and validation rules live here. Every other crate depends on it.
Layer 1 — fs, scoring, conformance, api: Low-level engines with no
cross-dependencies. fs handles atomic file I/O, scoring computes weighted
scores, conformance checks structural compliance, and api handles
syn-based public API extraction, diffing, and baseline management.
Layer 2 — repo, audit, gates, coverage: Repository layout discovery,
audit trail persistence, gate execution (subprocess runner), and contract
coverage analysis. coverage scans test files for lexicon tags and matches
them against contract clauses to compute coverage metrics.
Layer 3 — conversation, scaffold: Interactive workflow engine and
file-generation templates. conversation is a generic state machine;
scaffold emits TOML/Markdown files.
Layer 4 — ai: Optional AI integration. Defines the provider trait and
edit-policy engine. The system works fully without this crate doing anything.
Layer 5 — core: Orchestration layer that wires everything together.
Exposes high-level operations: init, verify, sync_claude, contract.
Layer 6 — cli, tui: User-facing frontends. cli uses clap; tui
uses ratatui/crossterm.
Key design decisions
Section titled “Key design decisions”spec is a pure-types crate
Section titled “spec is a pure-types crate”spec contains every domain type (contracts, gates, scoring models, audit
records, sessions, manifests) but zero business logic. This keeps compilation
fast and ensures all crates agree on a single source of truth for shapes.
Conversation as state machine, not chat
Section titled “Conversation as state machine, not chat”Workflows implement a Workflow trait that models a finite sequence of steps,
not a free-form chat:
pub trait Workflow { type Context; type Output;
fn name(&self) -> &str; fn steps(&self) -> &[WorkflowStep]; fn initial_context(&self) -> Self::Context; fn execute_step(&self, step_idx: usize, ctx: &mut Self::Context, input: StepInput) -> StepOutput; fn finalize(&self, ctx: Self::Context) -> Option<Self::Output>;}The ConversationEngine drives any Workflow through a ConversationDriver,
which abstracts I/O (terminal prompts, TUI widgets, or test mocks).
AI is optional
Section titled “AI is optional”The AiProvider trait defines the boundary to external AI services:
pub trait AiProvider { fn enhance_proposal(&self, prompt: &str, context: &str) -> AiResult<String>; fn suggest_improvement(&self, context: &str, failure: &str) -> AiResult<String>;}A NoOpProvider is the default. Every workflow, verification, and sync
operation works without AI. AI only enhances proposals and suggests fixes.
Safe file operations
Section titled “Safe file operations”All file writes go through lexicon-fs, which writes to a temporary file
first, then atomically renames into place. This prevents partial writes from
corrupting spec files or audit records.
Managed blocks in CLAUDE.md
Section titled “Managed blocks in CLAUDE.md”sync claude patches CLAUDE.md using marker-delimited sections
(<!-- lexicon:start --> / <!-- lexicon:end -->). Content outside the
markers is never touched, so hand-written guidance coexists with generated
context.
Gate commands run as subprocesses
Section titled “Gate commands run as subprocesses”Gates are arbitrary shell commands executed via sh -c. This means any
existing CI check, linter, or test suite can be a gate without writing
Rust code.
Audit trail for every mutation
Section titled “Audit trail for every mutation”Every verification run, contract creation, and score computation is recorded as a timestamped audit entry (JSON). This provides a history of project health over time.
AI edit policy
Section titled “AI edit policy”The ai crate enforces file-level permissions through glob-based policy:
pub enum EditPermission { Allowed, // AI may freely edit RequiresReview, // AI changes need manual review Protected, // AI must not edit}Policy defaults protect .lexicon/ and spec files while allowing source edits.
Data flow
Section titled “Data flow”lexicon init
Section titled “lexicon init”Creates the .lexicon/ directory structure and writes manifest.toml with
project metadata, default policy, and version info.
lexicon chat (contract creation)
Section titled “lexicon chat (contract creation)”- AI-guided conversation collects: contract ID, title, description, obligations, guarantees
CREATE_CONTRACTaction directive produces aContractSpecscaffold::contractwrites the TOML file tospecs/contracts/<id>.toml- Session is recorded as JSON in
.lexicon/conversations/
lexicon verify
Section titled “lexicon verify”- Loads
RepoLayoutto discover.lexicon/paths - Loads gate definitions from
specs/gates.toml - Runs each gate command as a subprocess via
sh -c - Loads scoring model from
specs/scoring.toml - Computes weighted score from gate results and conformance checks
- Writes an audit record to
.lexicon/audit/ - Returns
VerifyResultwith gate results and score report
SYNC_CLAUDE (via lexicon chat)
Section titled “SYNC_CLAUDE (via lexicon chat)”- Loads manifest, contracts, scoring model, and gate definitions
- Assembles a context document with project structure and rules
- Reads existing
CLAUDE.md(if any) - Patches or creates the managed block between markers
- Writes the file atomically
Extension points
Section titled “Extension points”| Extension | Trait / Mechanism | Purpose |
|---|---|---|
| AI backends | AiProvider trait | Swap in Claude API, local LLM, or mock |
| I/O backends | ConversationDriver trait | Terminal, TUI, or test harness |
| New workflows | Workflow trait | Add new interactive creation flows |
| Gate commands | Shell commands in TOML | Any sh -c-compatible check |
File formats
Section titled “File formats”| Format | Files | Audience |
|---|---|---|
| TOML | manifest.toml, contracts/*.toml, scoring.toml, gates.toml | Human-editable specs |
| JSON | .lexicon/sessions/*.json, .lexicon/audit/*.json | Machine state and history |
TOML files are the user-facing configuration surface. JSON files are internal state that users rarely need to inspect directly.