Skip to content

Architecture

kedge is a Rust CLI built around a three-layer pipeline: detection, triage, and remediation. Each layer has clear inputs and outputs, and the layers compose into the full kedge update pipeline.

Module map

src/
├── main.rs              Command routing and orchestration
├── lib.rs               Library exports (re-exports all modules)
├── cli.rs               Clap command definitions
├── config.rs            kedge.toml parsing (Config, DetectionConfig, TriageConfig, etc.)
├── models.rs            All data types (Anchor, DriftReport, TriagedReport, AgentPayload, etc.)
├── frontmatter.rs       YAML frontmatter parsing and provenance updates
├── output.rs            Agent output parsing (JSON and URL scraping)
├── safety.rs            Input validation (provenance, paths, URLs, git refs)
├── detection/
│   ├── mod.rs           detect_drift() — orchestrates anchor scanning and comparison
│   ├── fingerprint.rs   AST fingerprinting via tree-sitter; content-hash fallback
│   └── git.rs           Git CLI operations (read_file_at_rev, diff_with_summary, head_sha)
├── triage/
│   ├── mod.rs           Prompt building, response parsing, classification application
│   └── provider.rs      API integration (Anthropic, OpenAI, command)
├── remediation/
│   ├── mod.rs           Payload construction, partition_by_action, auto-merge logic
│   └── agent.rs         Agent process spawning with timeout and stdin/stdout handling
└── install/
    ├── mod.rs           Steering file installation (copy/symlink), gitignore management
    └── repo_cache.rs    Doc repo cloning and caching (~/.cache/kedge/repos/)

Data flow

                    kedge update
                         │
         ┌───────────────┼───────────────┐
         ▼               ▼               ▼
    ┌─────────┐    ┌──────────┐    ┌─────────────┐
    │Detection│───►│  Triage  │───►│Remediation  │
    └─────────┘    └──────────┘    └─────────────┘
         │               │               │
    DriftReport    TriagedReport    RemediationSummary

Detection → DriftReport

Input: Code repo path, docs directory, repo URL.

Process: 1. frontmatter::scan_docs() discovers steering files 2. For each anchor, fingerprint::compute_sig() computes the current fingerprint 3. Compare against stored provenance (direct comparison for sig:, git history for legacy SHA) 4. Partition docs into drifted and clean

Output: DriftReport with repo, ref, commit, drifted[], clean[].

Triage → TriagedReport

Input: DriftReport, TriageConfig, doc contents.

Process: 1. For each drifted doc, build_triage_prompt() constructs the AI prompt 2. provider::classify() dispatches to the configured backend (Anthropic/OpenAI/command) 3. parse_triage_response() extracts { path, symbol, severity } classifications from the response 4. apply_classifications() maps classifications onto the drift report anchors

Output: TriagedReport with classified anchors and doc-level severity (max of anchor severities).

Remediation → RemediationSummary

Input: TriagedReport, RemediationConfig.

Process: 1. partition_by_action() splits docs: those needing agent remediation vs those needing only provenance sync 2. For remediable docs: build AgentPayload or BatchAgentPayload, invoke agent via agent::invoke_agent() 3. For sync-only docs: recompute fingerprints and update provenance in steering files 4. Parse agent output for MR URLs

Output: RemediationSummary with remediated[], provenance_advanced[], errors[].

Key types

Type Module Purpose
Anchor models A code location reference in a steering file
DocFile models Parsed steering file with frontmatter and content
DriftReport models Detection output: drifted and clean docs
DriftedAnchor models An anchor whose code has changed
Severity models Enum: NoUpdate, Minor, Major
TriagedReport models Triage output: classified anchors
AgentPayload models JSON sent to agent (per-doc mode)
BatchAgentPayload models JSON sent to agent (batch mode)
RemediationSummary models Final pipeline output
Config config Parsed kedge.toml

Design decisions

No AI in detection

Detection is fully deterministic. AST fingerprinting uses tree-sitter (compiled C grammars) with no AI inference, keeping detection fast, free, and auditable.

Tree-sitter for AST parsing

Tree-sitter grammars are fast (native C), incremental, and available for most languages. Each grammar is a Cargo dependency, so adding a language means adding a crate.

Agent agnostic

Remediation delegates to an external process via stdin/stdout. kedge doesn't know or care what the agent is. It could be Kiro, Claude Code, a shell script, or any other tool. kedge composes with any AI coding agent.

Git CLI over libgit2

kedge shells out to git for operations like show, diff, and rev-parse. Shelling out avoids the complexity of libgit2 bindings, works with any git version the user has installed, and handles authentication (SSH keys, credential helpers) without kedge needing to know about them.

Single binary, no runtime dependencies

The binary links statically with rustls (no OpenSSL). The only runtime requirement is git on PATH.