Version: 1.0.1 documentation baseline Status: Reference architecture document; not a current release-readiness claim. Audience: Systems Engineers, Architects, Technical Reviewers
RepoLens is an evidence-first repository and pull-request intelligence platform. It combines deterministic structural static analysis, cross-layer dependency graph traversal, and evidence-grounded agentic reasoning to inspect multi-language codebases, verify candidate security remediations, and analyze the blast radius of pull requests.
RepoLens treats all submitted codebases as untrusted data, enforcing strict containment boundaries, tenant isolation, human authorization gates, and guarded GitHub API writes.
- Deterministic Evidence Precedes Model Reasoning: Structural AST parsing (Tree-sitter), static vulnerability analysis (Semgrep, Trivy, OSV), and dependency graph modeling execute prior to agentic reasoning. Models reason only over verified machine facts.
- Untrusted Repository Confinement: Submitted repositories are passive data. RepoLens never executes arbitrary repository code, never runs test suites, never imports dynamic reflection modules, and never triggers external build scripts or Makefiles.
- Cross-Layer Contract Parity: Frontend HTTP client calls, backend API routes, Pydantic schemas, database models, and migration steps are cross-referenced across architectural boundaries to detect contract breaks.
- Guarded GitHub Boundaries: Public repository and PR analyses remain credential-free. Optional private-repository PR analysis uses a user-bound GitHub App installation and repository-scoped, short-lived credentials. Remote GitHub writes require
OPERATORprivileges, resource ownership, human approval, explicit feature flags, and remote branch drift checks. - Human-in-the-Loop Authority: Remediation patches pause at human approval boundaries (
VERIFIED/NEEDS_REVIEW). Machine systems never mark patches asAPPROVED. GitHub delivery approval is content-bound to the exact patch diff, fix-plan snapshot, finding, tenant, scan revision/branch, reviewer, and approval time. Delivery revalidates that binding before remote writes; an active or already-started delivery cannot be revoked through the patch rejection endpoint. Existing approvals created before this binding are moved back toNEEDS_REVIEWby the migration and require explicit reapproval. - Optional Infrastructure: The deterministic core operates in-process without Docker, Redis, Celery, or Kafka. Redis can improve cache reuse and loopback Ollama can handle eligible low-risk generation, but neither is required.
RepoLens consists of a Next.js frontend communicating over typed REST and Server-Sent Events (SSE) with a FastAPI backend. Workflow orchestration is governed by LangGraph state machines, persisting execution state into SQLAlchemy relational models (SQLite by default, PostgreSQL compatible).
The optional GitHub App control plane adds signed webhook intake and installation-scoped private PR reads without replacing the existing durable analysis or publication paths. It is disabled by default; see GitHub App integration for configuration, permissions, and authorization boundaries.
flowchart TB
subgraph Client["Client Tier"]
Browser["Modern Web Browser"]
NextJS["Next.js / React 19 Frontend<br/>(TailwindCSS, SSE Stream Receiver)"]
Browser -->|HTTPS / UI Interactions| NextJS
end
subgraph API["FastAPI Application Tier"]
AuthMid["Security Headers & Auth Middleware<br/>(Argon2id, Session Tokens, CSRF)"]
QuotaSvc["Atomic Daily Quota Engine<br/>(Scans, Changes, Patches)"]
Router["FastAPI REST & SSE Routers<br/>(/api/v1/scans, /api/v1/change-analyses)"]
NextJS -->|REST Requests + CSRF Header| AuthMid
AuthMid --> QuotaSvc
QuotaSvc --> Router
end
subgraph Orchestration["Agent & Analysis Tier"]
ScanWorkflow["Scan Orchestrator<br/>(LangGraph State Machine)"]
ChangeWorkflow["Change Analysis Engine<br/>(Dual AST Diff & Blast Radius)"]
RepoGraph["RepositoryGraph<br/>(NetworkX Structural Graph)"]
LLMRouter["Canonical LLMRouter<br/>(cache + local/cheap-first + bounded cloud fallback)"]
Router -->|Dispatch Scan| ScanWorkflow
Router -->|Dispatch PR Review| ChangeWorkflow
ScanWorkflow --> RepoGraph
ScanWorkflow --> LLMRouter
ChangeWorkflow --> RepoGraph
ChangeWorkflow --> LLMRouter
end
subgraph Persistence["Persistence Tier"]
SQLAlchemy["SQLAlchemy ORM + Alembic (001–010)"]
Checkpointer["Official LangGraph Checkpoints (SQLite local / PostgreSQL production)"]
RelationalDB[(Relational DB<br/>SQLite / PostgreSQL)]
ScanWorkflow --> SQLAlchemy
ChangeWorkflow --> SQLAlchemy
ScanWorkflow --> Checkpointer
SQLAlchemy --> RelationalDB
end
subgraph External["External Services & Safe Boundaries"]
GitHubPublic["GitHub REST API<br/>(Public Read / Credential-Free)"]
GitHubWrite["GitHub Git Data API<br/>(Operator Write / Guarded by Flags)"]
ScannerCLIs["Static Scanners<br/>(Semgrep, Trivy, OSV / Graceful Degradation)"]
ModelProviders["Model Providers<br/>(Ollama loopback + configured cloud providers)"]
ScanWorkflow -->|Git Shallow Clone| GitHubPublic
ChangeWorkflow -->|PR Metadata & Dual Snapshot| GitHubPublic
Router -->|Operator PR Delivery / Comment| GitHubWrite
ScanWorkflow --> ScannerCLIs
LLMRouter --> ModelProviders
end
The scan pipeline ingests a public GitHub repository, enforces resource budgets, extracts deterministic AST symbols and static scanner findings, constructs a structural graph, invokes specialist agents, and produces verified findings with candidate remediation patches.
flowchart TD
A[User Request: POST /api/v1/scans] --> B[Validate URL, Branch & Quota]
B --> C[Development-only Safe Git Acquisition<br/>Timeout/tree admission/object-store monitor; production acquisition fails closed pending hard boundary]
C --> D[Tree-sitter AST Parsing<br/>Python, JS, TS, TSX, JSX]
C --> E[Deterministic Scanners<br/>Semgrep, Trivy, OSV-Scanner]
D --> F[Construct RepositoryGraph<br/>Nodes: Files, Symbols, Routes<br/>Edges: CALLS, IMPORTS, EXPOSES_API, CONSUMES_API]
E --> G[Ingest Scanner Findings into EvidenceStore]
F --> H[LangGraph Multi-Agent Orchestrator]
G --> H
H --> I[Specialist Analysis Agents<br/>Architecture, Bug Hunter, Security, Contract]
I --> J[Deterministic Finding Verifier<br/>Validates AST References & Line Ranges]
J --> K{Verifier Decision}
K -->|Evidence Validated| L[CONFIRMED Finding in Database]
K -->|Partial Evidence| M[POSSIBLE Finding in Database]
K -->|Unsubstantiated| N[REJECTED Finding Discarded]
L --> O[Candidate Patch Generation<br/>Unified Diff + 12-Check AST Patch Verifier]
O --> P[Patch State: VERIFIED / NEEDS_REVIEW]
P --> Q[Human Review Boundary<br/>Awaiting User Approval]
Q -->|User Approves| R[Patch State: APPROVED]
R -->|Operator Requested + Flag Enabled| S[Guarded GitHub PR Delivery via Git Data API]
The change analysis pipeline assesses the structural and contract blast radius between two repository revisions or from a public GitHub pull request without requiring credentials.
flowchart TD
A[User Request: POST /api/v1/change-analyses/from-pr] --> B[Validate PR URL & Quota]
B --> C[Credential-Free GitHub PR Resolver<br/>Extracts exact Base SHA & Head SHA]
C --> D[Acquire Dual Snapshots<br/>Base Workspace & Head Workspace]
D --> E[AST Structural Diff Engine<br/>Tree-sitter Symbol, Route & Schema Diffing]
E --> F[Cross-Layer Contract Matcher<br/>Detects Broken Frontend-to-Backend Endpoints]
E --> G[NetworkX Graph Blast Radius Traversal<br/>Upstream Callers, Impact Scoring & Cycle Prevention]
F --> H[Evidence-Grounded AI Reviewer]
G --> H
H --> I[Review Finding Verifier<br/>Enforces Diff Fact Grounding]
I --> J[Persist ChangeAnalysis & Verified Findings]
J --> K[Generate Markdown & JSON Reports with Epistemic Limitations]
K --> L[Operator Review & UI Preview]
L -->|Operator Decides to Publish| M{Safety Invariant Checks<br/>OPERATOR Role? GITHUB_PR_REVIEW_WRITE_ENABLED?<br/>Remote Base Drift Check?}
M -->|Passed| N[Publish Safe COMMENT to GitHub PR<br/>Never APPROVE / REQUEST_CHANGES]
M -->|Failed / Drift| O[Block Delivery & Record Audit Log]
RepoLens treats findings as unverified hypotheses until backed by deterministic machine facts.
EvidenceStore/EvidenceRegistry: Central registry recording exact repository files, 40-character commit SHAs, line numbers, symbol names, and scanner diagnostic outputs.- Evidence Verification Rules:
- Every finding must cite a valid file and line span present in the scanned snapshot.
- AST symbol claims must resolve to actual syntax nodes parsed by Tree-sitter.
- Cross-layer contract breaks must show the explicit producer route definition and consumer client invocation.
- LLM hallucinations (referencing non-existent files, inventing phantom routes, or misquoting line numbers) are rejected by the finding verifier.
Workflow execution is driven by LangGraph state machines with typed state dictionaries:
- Strict State Schema: State carries immutable identifiers (
scan_id,repository_id,commit_sha), collected evidence, candidate findings, and verification statuses. - Deterministic vs Reasoning Nodes:
- Deterministic Nodes: File ingestion, Tree-sitter parsing, scanner execution, graph traversal, diff calculation, patch validation, and drift checking.
- LLM Reasoning Nodes: Root-cause explanation, multi-file synthesis, architectural summarization, fix strategy generation, and PR review comments.
- Termination Guarantees: State graphs have bounded iteration counts, explicit error edges, and graceful exit conditions to prevent infinite execution loops.
- Durable Checkpointing: Local runs use SQLite; production graph runs require the official PostgreSQL saver. Production saver schema setup is an explicit deployment bootstrap, and each graph uses synchronous checkpoint durability plus generation-bound resume checks.
- Optional Evidence Investigator: When
AGENT_INVESTIGATOR_ENABLED=true, only genuine verifierPOSSIBLEtargets enter a boundedprepare -> decide -> tool -> compactloop. The model selects one next evidence action, application policy authorizes and executes it throughAgentToolRegistry, and revision plus the independent verifier remain authoritative. The disabled path continues to use deterministic MCP enrichment.
Persistence is managed with SQLAlchemy 2.0 ORM and Alembic migrations spanning revisions 001 through 010:
| Table | Migration | Purpose |
|---|---|---|
users |
009 | Multi-user identities, Argon2id password hashes, roles (USER, OPERATOR), lockouts |
user_sessions |
009 | 256-bit opaque session tokens (SHA-256 in DB), expiry, IP/User-Agent metadata |
daily_usage_quotas |
009 | Atomic daily usage counters for scans, change analyses, and patch generation |
repositories |
001, 009 | Indexed repository metadata, remote URLs, default branches, user ownership |
scans |
001, 009 | Scan lifecycles, status, commit SHAs, user ownership, summary metrics |
findings |
001, 002, 009 | Security & quality findings, severity, evidence citations, verification verdicts |
patches |
003, 009 | Candidate patches, unified diffs, 12-check validation results, approval states |
workflow_events |
004, 009 | Audit trail and SSE event log with sequential IDs and timestamps |
deliveries |
005, 009 | Safe GitHub PR delivery records, branch names, PR URLs, drift check records |
change_analyses |
006, 007, 008, 009 | Dual-revision AST diffs, blast radius metrics, contract deltas, user ownership |
review_publications |
007, 009 | Safe GitHub PR review comment publication records, comment IDs, drift validation |
RepoLens implements defense-in-depth access controls:
- Password Hashing: Argon2id with random 16-byte salts.
- Session Management: Opaque 256-bit entropy tokens transmitted via
HttpOnly,SameSite=Laxcookies; database stores SHA-256 digests. - CSRF Defense: Double-submit cookie pattern (
repolens_csrfcookie +X-CSRF-Tokenheader) validated on state-mutating requests (POST,PUT,PATCH,DELETE). - Role Hierarchy:
USER: Standard registered user. Can trigger repository scans, change analyses, and candidate patch generation within daily quotas. Tenant-isolated (can only access owned resources).OPERATOR: Privileged operator. Required to invoke external GitHub writes (PR creation, PR review comment publication). Remains strictly tenant-isolated to resources within their own tenant scope.
- Tenant Isolation: All queries filter by
user_id == current_user.id. Accessing another user's scan, finding, patch, or analysis returns404 Not Found(fail-closed IDOR prevention).
RepoLens cleanly separates unauthenticated public reads from privileged operator writes:
| Action | Authentication Required | Privileged Token Used | Safety Checks |
|---|---|---|---|
| Public Repository Scan | None / Normal User Session | None (Public Git Clone) | Development: shallow clone, tree/file admission budgets, reactive object-store monitor, process-tree termination, symlink confinement. Production Git acquisition is disabled until a quota-enforced workspace and controlled-egress boundary are integrated; new scan/change-analysis requests receive a stable 503 before quota or work admission, while existing idempotency replays remain stable. |
| Public PR Resolution | None / Normal User Session | None (Public GitHub REST) | Validates GitHub URL, parses base/head SHAs |
| Safe PR Delivery (Phase 5) | OPERATOR Session |
Server GITHUB_TOKEN |
GITHUB_DELIVERY_ENABLED=True, Human Approved, Base Drift Check, Git Data API only |
| PR Review Publish (Phase 7) | OPERATOR Session |
Server GITHUB_TOKEN |
GITHUB_PR_REVIEW_WRITE_ENABLED=True, Base Drift Check, COMMENT event only |
- Never writes to default branch: Creates unique isolated branches (
repolens/fix-...). - Never merges pull requests: Auto-merge is strictly unsupported.
- Never submits approving reviews: PR review publication is restricted to
COMMENTevents.APPROVEandREQUEST_CHANGESare prohibited in code. - Drift Protection: Verifies remote branch HEAD matches the scanned commit SHA before creating refs or comments.
Model interactions are managed by a centralized LLMRouter:
- Single Routing Authority: Task classification, provider policy, retry, fallback, health, quota, and explicit overrides remain owned by
LLMRouter; embedding generation uses the separateEmbeddingProviderboundary. - Deterministic and Cheap First: Machine evidence and early exits precede optional low-risk local generation, then cheap/free configured cloud models, with stronger models reserved for complex work.
- Evidence-Scoped Reuse: Exact cache identity includes tenant, capability, prompt/schema/policy versions, repository evidence hashes, and route identity. Semantic reuse is explicit, conservative, non-authoritative, and denied for security verification, patching, authorization, and writes.
- Bounded Coalescing: Concurrent identical deterministic requests share one in-process provider execution without durable locks or cross-tenant reuse.
- Optional Local Models: Local Sentence Transformers load lazily and fail back to exact/lexical/graph retrieval. Ollama is disabled by default, restricted to loopback, limited to low-risk capabilities, and enters a cooldown after connection failure.
- Fault Tolerance: Provider attempts, retries, and fallback are bounded; cache/local failures preserve deterministic artifacts and the existing cloud path.
- Zero-Key Degradation: With no API keys, local model, or Redis, Tree-sitter, static analyzers, repository graphs, exact/lexical retrieval, contract analysis, deterministic verification, and reports remain available.
The core technical differentiator of RepoLens is its ability to reason across architectural tiers using static AST graphs:
- Frontend-to-Backend Contract Tracing: Identifies fetch / axios client calls in React/TypeScript files and traces them to matching
@app.get/@app.postFastAPI route decorators in Python. - Route-to-Schema Mapping: Connects endpoint definitions to their Pydantic request and response models.
- Schema-to-Model Validation: Connects Pydantic schemas to underlying SQLAlchemy database models and Alembic migration versions.
- Breaking Delta Detection: When a pull request modifies a route path, removes a schema field, or alters parameter types, the change engine traces the impact across the relationship graph to flag broken consumer contracts.
| Failure Mode | System Response |
|---|---|
| External Scanner CLI Missing | Logs diagnostic note; proceeds with Tree-sitter AST analysis without crashing. |
| Local embedding dependency/model missing | Records degradation and continues with exact, lexical, graph, and deterministic analysis; normal CI never downloads a model. |
| Ollama unavailable | Stops repeated loopback attempts for a bounded cooldown and continues through the router's eligible configured path. |
| Redis/cache unavailable | Cache reads/writes fail open; the underlying model request remains available. |
| LLM Provider Outage / 429 | Retries with backoff; switches to configured fallback provider; if all fail, records LLM stage failure while preserving deterministic scan artifacts. |
| Ingestion Limit Exceeded | Development clones fail closed when tree/file limits, the observed object-store threshold, or timeout is exceeded. Object-store monitoring is reactive and may overshoot between polls; it is not a hard per-scan disk/network quota. Production clone and snapshot acquisition fail before workspace allocation until a hard boundary is integrated. |
| Server Crash Mid-Scan | On restart, ScanRecoveryService detects unfinished scans in database and marks them as failed/cancelled without corrupting state. |
| GitHub Remote Branch Drift | Aborts delivery or publication immediately; records drift event in audit trail. |
RepoLens intentionally does NOT:
- Execute untrusted code, run repository test suites, or invoke dynamic sandboxes.
- Perform unmoderated autonomous commits or auto-merges to user repositories.
- Issue GitHub
APPROVEorREQUEST_CHANGESreview verdicts. - Provide general shell execution or arbitrary container hosting.
- Act as a substitute for compiler verification or human security audits.