{"slug": "automated-code-review-with-coderift", "title": "Automated code review with CodeRift", "summary": "A developer built CodeRift, an automated code review platform that analyzes every GitLab merge request through a seven-step pipeline combining TOML-based regex rules, tree-sitter AST analysis, and parallel specialized AI agents. The system runs on IronFlow, the developer's Rust workflow engine, with an API/worker architecture that scales by launching additional workers and posts inline review comments directly to merge requests.", "body_md": "Code review is the bottleneck of most teams. The merge request is open, the author waits, the reviewer is busy with something else. When the review finally comes, it's often superficial: a quick glance at the diff, a \"LGTM\", merge. Logic bugs, security flaws and architecture violations slip through.\n\nI built CodeRift to solve this problem. It's an automated code review platform that analyzes every GitLab merge request with a 7-step pipeline: diff parsing, AST analysis via tree-sitter, TOML rule engine, parallel specialized AI agents, cross-file correlation, false positive validation, and inline comment publishing directly in the MR. The whole thing is orchestrated by [IronFlow](https://dev.to/blog/en/why-rust-workflow-engine-ironflow), my Rust workflow engine.\n\nCodeRift follows an API + Workers model. The API (Rust/Axum/SQLx) handles persistence, GitLab OAuth authentication and webhooks. IronFlow workers poll the API for pending reviews, execute them, and post results.\n\nThe API/Worker separation is the same as [IronFlow](https://dev.to/blog/en/why-rust-workflow-engine-ironflow): the API owns persistence and never executes. Scaling means launching more workers.\n\nThe `review-merge-request` workflow implements IronFlow's `WorkflowHandler` trait. Each step is an IronFlow operation with automatic retry and structured logging.\n\nThe worker updates the review status in the database, posts a \"review in progress\" note on the GitLab MR, and sets the commit status to `running`. The developer immediately sees that the AI review has started.\n\n```\nctx.operation(\"update-review-status\", &update_status_op).await?;\n\nctx.http(\n    \"post-review-started\",\n    HttpConfig::post(&notes_url)\n        .header(\"PRIVATE-TOKEN\", &CONFIG.gitlab.bot_token)\n        .json(serde_json::json!({ \"body\": review_started_message(language) })),\n).await?;\n\ncommit_status::set(ctx, \"set-commit-status-running\", &proj,\n    &payload.head_sha, payload.review_id, \"running\",\n    \"AI review in progress...\").await?;\n```\n\nThis is where the work happens. The pipeline follows this sequence:\n\n**TOML rules**: CodeRift loads a set of rules embedded at compile time (`include_dir!`). Each rule targets a language, file patterns, and defines a regex pattern with exceptions. For example, the `rust-unwrap` rule detects `.unwrap()` in production code while excluding test files:\n\n```\n[[rules]]\nid = \"rust-unwrap\"\nseverity = \"error_handling\"\nscore = 7\ntitle = \".unwrap() in production code\"\nlanguages = [\"rust\"]\nfile_patterns = [\"*.rs\"]\nexclude_patterns = [\"*_test.rs\", \"tests/*\"]\ntype = \"regex\"\npattern = '\\.unwrap\\(\\)'\nnegative_pattern = '#\\[test\\]|#\\[cfg\\(test\\)\\]|mod tests'\n```\n\nRules cover Rust, TypeScript, Python, Go, SQL, and common patterns (OWASP, prompt injection). Each project can add its own rules or disable server rules via a `.coderift/context.md` file.\n\n**AST analysis**: tree-sitter parses the modified files and extracts a symbol index (definitions, references, cross-file edges). This index serves two purposes: building a dependency graph to group related files into the same chunks, and detecting structural patterns that regex can't see.\n\n**Chunking**: files are grouped into chunks of 5 (configurable) for parallel review. When the dependency graph is available, related files stay in the same chunk to give the agent context on both sides of an interface.\n\n**Specialized AI agents**: each chunk is reviewed by 3 agents in parallel, each with a different focus:\n\n| Agent | Model | Focus | \n|---|---|---|\n| Security | Opus 4.6 | Injections, XSS, SSRF, access control, secrets | \n| Bugs | Opus 4.6 | Incorrect logic, edge cases, type errors | \n| Performance | Sonnet 4.6 | N+1, unnecessary allocations, algorithmic complexity | \n\nEach agent has a configurable USD budget and a maximum of 4 turns. The IronFlow provider manages execution and cost tracking. If an agent fails (schema error, timeout), the pipeline continues with results from the others.\n\n``` js\nlet mut agent = Agent::new()\n    .system_prompt(system)\n    .prompt(prompt)\n    .model(Model::OPUS_46)\n    .max_turns(4)\n    .max_budget_usd(budget)\n    .output::<FindingsOutput>();\n```\n\n**Cross-file correlation**: a Sonnet 4.6 agent receives all findings from all chunks and identifies vulnerabilities that span multiple files. For example, an unvalidated input in a handler that reaches a SQL query in another file.\n\n**False positive validation**: a final agent filters out irrelevant findings. Common false positives: an `.unwrap()` in test code, a pattern flagged in a comment, a finding targeting unchanged code, or a score inflated relative to actual risk.\n\nThe worker posts results to the GitLab MR:\n\nThe GitLab commit status changes to `success` or `failed`. If the review has Critical findings, the pipeline can block the merge.\n\nEach finding has a precise structure:\n\n```\npub struct Finding {\n    pub file: String,\n    pub line: u32,\n    pub end_line: Option<u32>,\n    pub severity: Severity,    // Bug | Security | Performance | ErrorHandling | Suggestion\n    pub score: u8,             // 0-10, maps to Critical/Major/Moderate/Minor\n    pub title: String,\n    pub comment: String,\n    pub suggestion: Option<String>,\n    pub analysis_chain: Vec<String>,\n    pub ai_fix_prompt: Option<String>,\n}\n```\n\nThe `analysis_chain` field contains the agent's step-by-step reasoning. The `ai_fix_prompt` field is a ready-to-use prompt to automatically fix the finding.\n\nThe first version of this system used [an n8n node that invoked Claude Code CLI](https://dev.to/projects/n8n-claude-code). It worked for small MRs, but the limitations showed up fast:\n\nCodeRift solves each of these problems. The structured pipeline (rules + AST + specialized agents + validation) produces more accurate findings than the \"send the entire diff to an LLM and hope\" approach.\n\nEach project can customize the review via `.coderift/context.md`:\n\n```\n# Architecture\n\n4 strict layers: rest, services, repositories, entities.\nViolations to flag:\n- rest importing repositories directly\n- services doing raw SQL\n- repositories containing business logic\n\n# Frontend\n\nAPI types in app/types/generated.ts are auto-generated.\nNever manually redefine a type that exists in this file.\n```\n\nThis file is injected into agent prompts as untrusted context (sandboxed, with no ability to alter review instructions). Agents use it to understand project conventions and flag specific violations.\n\nCodeRift is built with the ecosystem I developed: [IronFlow](https://dev.to/blog/en/why-rust-workflow-engine-ironflow) for workflow orchestration, the same layered architecture (entities/repositories/services/rest) as [Netir](https://dev.to/projects/netir), and [MCP RTK](https://dev.to/blog/en/mcp-rtk-reduce-token-usage-mcp-servers) optionally to reduce tokens on connected MCP servers. The [Claude Code setup](https://dev.to/blog/en/claude-code-setup-2026) and [skills](https://dev.to/blog/en/writing-effective-claude-code-skills) I use daily served as the foundation for structuring CodeRift's review prompts.", "url": "https://wpnews.pro/news/automated-code-review-with-coderift", "canonical_source": "https://dev.to/thomastartrau/automated-code-review-with-coderift-49g9", "published_at": "2026-09-11 16:54:23+00:00", "updated_at": "2026-09-11 17:13:58.843757+00:00", "lang": "en", "topics": ["ai-tools", "developer-tools", "ai-agents", "ai-products", "mlops"], "entities": ["CodeRift", "IronFlow", "GitLab", "Rust", "tree-sitter", "Axum", "SQLx", "Opus 4.6"], "alternates": {"html": "https://wpnews.pro/news/automated-code-review-with-coderift", "markdown": "https://wpnews.pro/news/automated-code-review-with-coderift.md", "text": "https://wpnews.pro/news/automated-code-review-with-coderift.txt", "jsonld": "https://wpnews.pro/news/automated-code-review-with-coderift.jsonld"}}