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

Code Department

Code intelligence, implementation, debugging, testing, refactoring

Overview

The Code Department provides AI-powered code intelligence for RUSVEL. It parses Rust source files, builds a symbol dependency graph, computes project metrics (file counts, symbol counts, largest function), and exposes BM25-ranked symbol search. It is the department a developer uses to understand a codebase before making changes, and it produces code.analyzed events that the Content department consumes to auto-generate technical blog posts from code snapshots.

Engine (code-engine)

  • Crate: crates/code-engine/src/lib.rs
  • Lines: 307 (lib.rs) + submodules (parser, graph, metrics, search, error)
  • Status: Wired (real business logic)

Public API

MethodSignatureDescription
newfn new(storage: Arc<dyn StoragePort>, event_port: Arc<dyn EventPort>) -> SelfConstruct with storage and event port
analyzeasync fn analyze(&self, repo_path: &Path) -> Result<CodeAnalysis>Parse directory, build symbol graph, compute metrics, build search index, persist to ObjectStore, emit code.analyzed event
searchfn search(&self, query: &str, limit: usize) -> Result<Vec<SearchResult>>BM25-ranked search over previously indexed symbols; returns error if analyze() not yet called

Internal Structure

  • parser (parser.rs) – Rust source file parser that extracts Symbol structs (functions, structs, enums, traits, impls) with name, kind, file path, line number, and body text.
  • graph (graph.rs) – SymbolGraph built from parsed symbols representing call/dependency relationships.
  • metrics (metrics.rs) – count_lines() per file and compute_project_metrics() aggregate: total files, total symbols, largest function.
  • search (search.rs) – SearchIndex with BM25 ranking. Built from (name, file_path, body, line) tuples.
  • error (error.rs) – Engine-specific error types.

Data Types

#![allow(unused)]
fn main() {
pub struct CodeAnalysis {
    pub snapshot: CodeSnapshotRef,   // ID + repo path + analyzed_at timestamp
    pub symbols: Vec<Symbol>,        // All parsed symbols
    pub graph: SymbolGraph,          // Dependency graph
    pub metrics: ProjectMetrics,     // Aggregate metrics
}
}

CodeAnalysis::summary() produces a CodeAnalysisSummary (snapshot_id, repo_path, total_files, total_symbols, top 10 function names, largest function) that the Content engine uses for code-to-content generation.

Department Wrapper (dept-code)

  • Crate: crates/dept-code/src/lib.rs
  • Lines: 154
  • Manifest: crates/dept-code/src/manifest.rs

The wrapper creates a CodeEngine during registration with StoragePort and EventPort, then registers 2 agent tools. No event handlers or job handlers are registered.

Manifest Declaration

System Prompt

You are the Code department of RUSVEL.

You have full access to Claude Code tools:

  • Read, Write, Edit files across all project directories
  • Run shell commands (build, test, git, pnpm, cargo, etc.)
  • Search codebases with grep and glob
  • Fetch web content and search the web
  • Spawn sub-agents for parallel work
  • Manage background tasks

Focus: code intelligence, implementation, debugging, testing, refactoring. When writing code, follow existing patterns. Be thorough.

Capabilities

  • code_analysis
  • tool_use

Quick Actions

LabelPrompt
Analyze codebaseAnalyze the codebase structure, dependencies, and code quality.
Run testsRun cargo test and report results. If any fail, show the errors.
Find TODOsFind all TODO, FIXME, and HACK comments across the codebase.
Self-improveRead docs/status/current-state.md and docs/status/gap-analysis.md. Identify the highest-impact fix you can make right now. Implement it, run tests, and verify.
Fix build warningsRun cargo build and fix any warnings. Then run cargo test to verify nothing broke.

Registered Tools

Tool NameParametersDescription
code.analyzepath: string (required)Analyze a codebase directory for symbols, metrics, and dependencies
code.searchquery: string (required), limit: integer (default: 10)Search previously indexed code symbols

Personas

NameRoleDefault ModelAllowed ToolsPurpose
code-engineerSenior software engineer with code intelligencesonnetcode.analyze, code.search, file_read, file_write, shellFull-stack code work with engine tools

Skills

NameDescriptionTemplate
Code ReviewAnalyze code quality and suggest improvementsAnalyze the code at: {{path}}. Focus on: code quality, patterns, potential bugs, and improvements.

Rules

No rules are declared for the Code department.

Jobs

Job KindDescriptionRequires Approval
code.analyzeRun code analysis on a directoryNo

Events

Produced

Event KindWhen Emitted
code.analyzedanalyze() completes successfully. Payload includes snapshot_id, total_symbols, total_files.
code.searchedA symbol search is executed (declared in manifest).

Consumed

The Code department does not consume events from other departments.

API Routes

MethodPathDescription
POST/api/dept/code/analyzeAnalyze a codebase directory. Body: {"path": "..."}. Returns full CodeAnalysis JSON.
GET/api/dept/code/searchSearch indexed symbols. Query params: query, limit. Returns ranked search results.

CLI Commands

rusvel code analyze [path]   # Analyze a codebase (default: current directory)
rusvel code search <query>   # Search indexed symbols

Entity Auto-Discovery

Agents, skills, rules, hooks, and MCP servers scoped to the Code department are stored with metadata.engine = "code". The shared CRUD API routes filter by this key so each department sees only its own entities.

Chat Flow

sequenceDiagram
    participant User
    participant API as rusvel-api
    participant Chat as Chat Handler
    participant Config as ConfigPort
    participant Skills as Skill Resolver
    participant Rules as Rule Loader
    participant Agent as AgentRuntime
    participant Code as CodeEngine
    participant Events as EventPort
    participant Hooks as Hook Dispatcher

    User->>API: POST /api/dept/code/chat {message}
    API->>Chat: route to department chat handler
    Chat->>Config: load department config (model, effort, add_dirs)
    Chat->>Skills: resolve_skill() -- check for {{input}} interpolation
    Chat->>Chat: check agent override (custom agent for code)
    Chat->>Rules: load_rules_for_engine("code") -- append to system prompt
    Note over Chat: Inject capabilities: code_analysis, tool_use
    Note over Chat: System prompt: "You are the Code department..."
    Note over Chat: Default config: effort=high, add_dirs=["."]
    Chat->>Agent: AgentRuntime::run_streaming(config, tools, prompt)
    Agent->>Code: tool calls (code.analyze, code.search)
    Code->>Events: emit code.analyzed
    Agent-->>Chat: SSE stream (AgentEvent chunks)
    Chat-->>User: SSE response
    Chat->>Events: emit chat completion event
    Chat->>Hooks: tokio::spawn hook dispatch

Extending This Department

1. Add a new tool

Register the tool in crates/dept-code/src/lib.rs inside the register() method using ctx.tools.add("code", "code.new_tool", ...). Add a matching ToolContribution entry in crates/dept-code/src/manifest.rs in the tools vec.

2. Add a new event kind

Add a new pub const in the events module inside crates/code-engine/src/lib.rs. Emit it from the engine method. Add the event kind string to events_produced in crates/dept-code/src/manifest.rs.

3. Add a new persona

Add a PersonaContribution entry in the personas vec in crates/dept-code/src/manifest.rs.

4. Add a new skill

Add a SkillContribution entry in the skills vec in crates/dept-code/src/manifest.rs. Use {{variable}} placeholders for runtime interpolation.

5. Add a new API route

Add a RouteContribution entry in the routes vec in crates/dept-code/src/manifest.rs. Implement the handler in crates/rusvel-api/src/engine_routes.rs and wire the route in crates/rusvel-api/src/lib.rs.

Port Dependencies

PortRequiredPurpose
StoragePortYesPersist code analysis results via ObjectStore
EventPortYesEmit code.analyzed and code.searched events

Default Configuration

The Code department ships with a non-default LayeredConfig:

  • effort: "high" – maximizes analysis thoroughness
  • permission_mode: "default"
  • add_dirs: ["."] – adds the current directory to the agent’s working set

Object Store Kinds

KindSchemaUsed By
code_analysisCodeAnalysis { snapshot, symbols, graph, metrics }analyze() persists, Content department reads for code-to-content

Cross-Department Integration

The Code department is a producer in the code-to-content pipeline:

  1. Code -> Content: When analyze() completes, it emits code.analyzed with snapshot_id, total_symbols, and total_files in the payload. The Content department’s event handler receives this and calls draft_blog_from_code_snapshot() to generate a technical blog post.

  2. Code -> Forge: The Forge department can use the CodeWriter persona to analyze code during executive brief generation for the code department section.

This is achieved entirely through the event system – the Code engine never imports the Content engine.

Parser Details

The parser module handles Rust source file parsing:

  • Scans .rs files in the given directory (recursive)
  • Extracts symbols: functions (fn), structs, enums, traits, impl blocks
  • Each Symbol includes: name, SymbolKind, file_path, line number, body text
  • Used by SymbolGraph::build() to construct a dependency graph
  • Used by SearchIndex::build() to create BM25-searchable index

Symbol Kinds

Function, Struct, Enum, Trait, Impl

Search Index

The BM25 search index is built from tuples of (name, file_path, body, line):

  • Index: Built once per analyze() call, stored in-memory behind a Mutex
  • Query: search(query, limit) returns ranked SearchResult entries
  • Error: Returns RusvelError::Internal if called before analyze()
#![allow(unused)]
fn main() {
pub struct SearchResult {
    pub symbol_name: String,
    pub file_path: String,
    pub line: usize,
    pub score: f64,
}
}

Metrics

The metrics module computes:

  • Per-file: count_lines() returns FileMetrics (total lines, code lines, comment lines, blank lines)
  • Project-wide: compute_project_metrics() aggregates across all files:
#![allow(unused)]
fn main() {
pub struct ProjectMetrics {
    pub total_files: usize,
    pub total_symbols: usize,
    pub largest_function: Option<String>,
    // ... additional fields
}
}

UI Integration

The manifest declares a dashboard card and 10 tabs:

  • Dashboard card: “Code Intelligence” (medium) – Symbol index, metrics, and search
  • Tabs: actions, engine, agents, workflows, skills, rules, mcp, hooks, dirs, events
  • has_settings: true (supports department-level settings)

Testing

cargo test -p code-engine    # Tests in lib.rs

Key test scenarios:

  • Analyze a temp directory with Rust files, verify symbol count
  • Search after analysis, verify results
  • Health returns healthy (with and without index)
  • Event emission on analyze
cargo test -p dept-code      # Department wrapper tests

Key test scenarios:

  • Department creates with correct manifest ID
  • Manifest declares 2 routes, 2 tools, 2 events
  • Manifest requires StoragePort and EventPort
  • Manifest serializes to valid JSON