Automated code review with CodeRift 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. 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. I 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. CodeRift 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. The 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. The review-merge-request workflow implements IronFlow's WorkflowHandler trait. Each step is an IronFlow operation with automatic retry and structured logging. The 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. ctx.operation "update-review-status", &update status op .await?; ctx.http "post-review-started", HttpConfig::post ¬es url .header "PRIVATE-TOKEN", &CONFIG.gitlab.bot token .json serde json::json { "body": review started message language } , .await?; commit status::set ctx, "set-commit-status-running", &proj, &payload.head sha, payload.review id, "running", "AI review in progress..." .await?; This is where the work happens. The pipeline follows this sequence: 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: rules id = "rust-unwrap" severity = "error handling" score = 7 title = ".unwrap in production code" languages = "rust" file patterns = " .rs" exclude patterns = " test.rs", "tests/ " type = "regex" pattern = '\.unwrap\ \ ' negative pattern = ' \ test\ | \ cfg\ test\ \ |mod tests' Rules 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. 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. 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. Specialized AI agents : each chunk is reviewed by 3 agents in parallel, each with a different focus: | Agent | Model | Focus | |---|---|---| | Security | Opus 4.6 | Injections, XSS, SSRF, access control, secrets | | Bugs | Opus 4.6 | Incorrect logic, edge cases, type errors | | Performance | Sonnet 4.6 | N+1, unnecessary allocations, algorithmic complexity | Each 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. js let mut agent = Agent::new .system prompt system .prompt prompt .model Model::OPUS 46 .max turns 4 .max budget usd budget .output::