Overview Installation What to Expect How It Works Languages Detection Layers Performance GitHub Action Output Formats

Documentation

Rosentic catches compatibility conflicts between AI coding agents before they break your main branch. AST-level detection across 15+ languages, deployed as a GitHub Action.

Installation

GitHub Action (recommended)

Add one file to your repo. Rosentic runs automatically on every PR after that.

Step 1: Create the file. In your repo, create the folders .github/workflows/ if they don't already exist. Then create a file called rosentic.yml inside. The full path from your repo root should be:
File locationpath
your-repo/ .github/ workflows/ rosentic.yml ← create this file src/ package.json ...
Step 2: Paste the YAML. Copy this into rosentic.yml. That's the entire install. The engine runs on GitHub's infrastructure. Your code is analyzed and discarded, never stored.
.github/workflows/rosentic.ymlyaml
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

That's it. Commit and push. Rosentic scans automatically on every PR targeting main.

Step 3: Open a PR. Push any branch and open a pull request. Rosentic will run and post a comment on the PR with the results. First scan takes about 60 seconds (Docker image pull). Subsequent scans are faster.

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. The scan runs locally. Code never leaves your runner. Anonymous summary telemetry (conflict counts, branch counts, timing) is sent. With an API key, scan metadata and finding details (function names, file paths, verdicts) are stored for dashboard history. Source code is never uploaded in any mode.
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 15+ languages:

Python
TypeScript
JavaScript
Go
Ruby
Java
Kotlin
Swift
Rust
C#
C++
More coming

Detection Layers

LayerWhat It DetectsStatus
L1 - Symbol GraphFunction signature mismatches across 15+ languages. Function changed parameters but callers still use old signature.Built
L2 - Route ContractsHTTP contract conflicts. Route changed required fields, client still sends old fields. Supports Go (Chi, Gin, Echo, Gorilla, Fiber, stdlib), Java/Kotlin (Spring, Micronaut, Ktor, JAX-RS), Python (Flask, FastAPI, Django), Ruby (Rails, Sinatra, Grape), TypeScript (Express, Hono, Fastify, Next.js, Koa), C# (ASP.NET), PHP (Laravel), Rust (Actix, Axum, Rocket).Built
L3a - GraphQLGraphQL schema conflicts. Schema field removed or renamed, query on another branch still references it.Built
L3b - Typed ContractsPydantic and Zod schema conflicts. API request model changed, client still uses old shape.Built
L3c - Protobuf/gRPCProtobuf 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.

BenchmarkFirst ScanSubsequent
Demo repo (11 branches, 69 conflicts)1.0s0.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: The scan runs locally on GitHub's ephemeral runners. Source code never leaves your runner. Without an API key, anonymous summary telemetry is sent. With an API key, scan metadata and finding details (not source code) are stored for dashboard history. Full trust model

Dashboard

The Rosentic dashboard shows scan history, findings, trends, and the Merge Index for your repos. Sign in at api.rosentic.com/onboard.

Authentication. GitHub OAuth or magic link email. After sign-in, select your GitHub org to create a workspace.

Dashboard pages: Overview (Merge Posture), Repos, Findings, Trends, and Settings. Finding drill-down includes the Impact Layer visualization showing the blast radius of a change across branches.

Enable dashboard history

To connect scans to your dashboard, add your API key to the workflow:

Step 1: Sign up at api.rosentic.com/onboard and copy your API key.
Step 2: Add the key as a GitHub secret. In your repo, go to Settings > Secrets and variables > Actions > New repository secret. Name: ROSENTIC_API_KEY. Value: your key.
Step 3: Add the key to your workflow YAML:
.github/workflows/rosentic.ymlyaml
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 env: ROSENTIC_API_KEY: ${{ secrets.ROSENTIC_API_KEY }}

PR comments continue to work the same way. The API key adds dashboard history and finding lifecycle tracking on top.

Inline Review Comments

Rosentic posts inline review comments on the specific lines where conflicts are detected, in addition to the summary PR comment. Each inline comment shows the conflict type, the affected function or route, and the branch that would be impacted.

Output Formats

Text (default)

Outputtext
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.