Documentation
Rosentic catches compatibility conflicts between AI coding agents before they break your main branch. AST-level detection across 11 languages, deployed as a GitHub Action.
Installation
GitHub Action (recommended)
Create this file in your repository. The engine runs on GitHub's infrastructure. Your code is analyzed and discarded - never stored.
name: Rosentic Scan
on:
pull_request:
branches: [main]
jobs:
rosentic:
runs-on: ubuntu-latest
permissions:
contents: read
pull-requests: write
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: Rosentic/rosentic-action@v1
Commit this file to your repo. Rosentic scans automatically on every PR targeting main.
What to expect
First scan. The first scan on a repo pulls the Docker image (~200MB) and parses every active branch from scratch. The engine deduplicates files across branches so most files are only parsed once. Scan time depends on file count and active branch count. Subsequent scans are faster as the index is cached.
What gets scanned. Rosentic scans all branches with commits in the last 30 days. Stale branches are skipped. The engine compares every active branch pair across five detection layers: function signature mismatches, HTTP API contract breaks, GraphQL schema conflicts, OpenAPI/Pydantic/Zod typed contract breaks, and protobuf/gRPC message conflicts.
Where results appear. Rosentic posts a comment directly on your PR with the conflict report. By default, Rosentic runs in audit mode - conflicts are reported but the check passes (green checkmark) so merges are never blocked. Results live on the PR - nothing is stored externally.
Audit vs enforce mode. New installs start in audit mode - Rosentic reports conflicts without blocking merges. When you trust the results, switch to enforce mode to block merges when conflicts are found. One line change in your YAML:
- uses: Rosentic/rosentic-action@v1 (audit, default)
with:
mode: enforce (blocks merge on conflicts)
Your code is never stored. The engine runs as a Docker container on GitHub's ephemeral runners. Your code is parsed, the conflict report is posted as a PR comment, and the runner is destroyed. No source code is persisted to disk, transmitted to external servers, or retained after the scan completes.
Read our trust model →
If no conflicts are found. That's good - it means your active branches are compatible with each other. Rosentic posts a clean scan confirmation on the PR. The check passes and merge is unblocked.
How It Works
Rosentic uses tree-sitter to build an AST (Abstract Syntax Tree) for every file on every active branch. From the AST, it extracts function definitions, call sites, HTTP route declarations, and HTTP client calls. Then it compares every branch pair to find incompatibilities.
The engine is deterministic. Same input, same output. No LLM inference, no hallucination, no false positives from model uncertainty. Tree-sitter parsing is production-grade from day one.
Supported Languages
Full AST parsing and symbol extraction across 11 languages:
Python
TypeScript
JavaScript
Go
Ruby
Java
Kotlin
Swift
Rust
C#
C++
More coming
Detection Layers
| Layer | What It Detects | Status |
| L1 - Symbol Graph | Function signature mismatches across 11 languages. Function changed parameters but callers still use old signature. | Built |
| L2 - Interface Graph | HTTP contract conflicts. Route changed required fields, client still sends old fields. Supports Python (Flask, FastAPI) and TypeScript (Express, Fastify, Next.js). | Built |
| L3a - GraphQL | GraphQL schema conflicts. Schema field removed or renamed, query on another branch still references it. | Built |
| L3b - Typed Contracts | Pydantic and Zod schema conflicts. API request model changed, client still uses old shape. | Built |
| L3c - Protobuf/gRPC | Protobuf message and RPC conflicts. Field removed or field number changed, consumer still depends on old contract. | Built |
Performance
The engine deduplicates files across branches and caches scan data between runs. Most files are identical across branches and only get parsed once. Subsequent scans skip unchanged branches entirely.
| Benchmark | First Scan | Subsequent |
| Demo repo (11 branches, 69 conflicts) | 1.0s | 0.6s |
Performance on larger repos varies by file count and active branch count. The engine deduplicates files across branches and uses contract-key prefiltering to minimize comparison time.
GitHub Action
When deployed as a GitHub Action, the workflow is:
Agent opens PR - GitHub spins up temporary runner - downloads Docker image - scans PR branch against all active branches - posts PR comment with conflict report - runner is destroyed. In audit mode (default), the check always passes. In enforce mode, the check fails when conflicts are found.
Security: Your code is never stored. The engine runs on GitHub's ephemeral runners, analyzes the AST, posts results, and the container is destroyed. No data is persisted or transmitted externally.
Output Formats
Text (default)
Rosentic Scan Results
Repository: ./my-app
Branches: 5 active
Pairs: 10 checked
Conflicts: 3 found
CONFLICT agent/alice ↔ agent/charlie
Type: API contract mismatch
Source: backend/main.py:create_order()
Target: frontend/api.ts:fetch('/order')
Detail: Required param 'shipping_id' added
in source, missing in target call
JSON
Machine-readable output for CI integration, dashboards, or custom tooling.