AI Release Intelligence and PR Risk Copilot
VANGUARD is a local-first engineering intelligence platform for pull request and release operations. It evaluates risk before merge, maps change blast radius, detects test and CI gaps, enforces policy gates, and generates grounded summaries for PR and release decision-making.
Modern delivery pipelines fail less from syntax errors and more from weak change visibility:
- PRs touch critical paths without complete ownership context.
- CI failures hide in flaky or retried jobs.
- Releases proceed with unresolved policy debt.
- Teams rely on intuition when risk evidence should be explicit.
VANGUARD makes delivery intelligence inspectable and operational.
| Capability | What VANGUARD does |
|---|---|
| Pull Request Intelligence | Ingests PR metadata, changed files, CI/test signals, ownership, and generates grounded analysis |
| Dependency Impact | Traverses service dependency graph and computes transitive blast radius |
| Risk Scoring | Computes explainable score with weighted factors and confidence warnings |
| Test Intelligence | Surfaces coverage deltas, flaky tests, failure diagnostics, and missing test suggestions |
| CI Intelligence | Aggregates failing jobs, retries, and unstable pipelines into release signals |
| Policy Engine | Evaluates approval and release-blocking rules with rationale |
| Release Center | Produces release readiness score, blocker list, approval state, and notes preview |
| Auditability | Logs analyses, eval runs, approvals, and overrides with actor/rationale |
| Evals | Runs benchmark suite for reviewer relevance, impact quality, policy correctness |
| Observability | Structured logs, request IDs, dependency health checks, stage-aware diagnostics |
- Dashboard
- PR Workspace
- Release Center
- Impact Explorer
- Test Intelligence
- CI Health
- Policy Center
- Approvals Queue
- Audit Log Viewer
- Engineering Insights
- Status and Dependency Health
- Settings and Provider Visibility
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'primaryColor': '#dbeafe',
'primaryBorderColor': '#145DA0',
'primaryTextColor': '#0C2D48',
'lineColor': '#145DA0',
'secondaryColor': '#dcfce7',
'tertiaryColor': '#fff7ed'
}}}%%
flowchart LR
UI[Next.js Web App] --> API[FastAPI API Layer]
API --> DS[Seeded Dataset Loader]
API --> RISK[Risk Engine]
API --> POLICY[Policy Engine]
API --> GRAPH[Impact Graph Service]
API --> EVAL[Evaluation Service]
API --> AUDIT[Audit Service]
API --> PG[(PostgreSQL)]
API --> REDIS[(Redis)]
API --> NEO4J[(Neo4j)]
API --> OS[(OpenSearch)]
GRAPH --> NEO4J
EVAL --> AUDIT
classDef entry fill:#dbeafe,stroke:#145DA0,color:#0C2D48,stroke-width:2px;
classDef core fill:#dcfce7,stroke:#1f8a70,color:#14532d,stroke-width:2px;
classDef service fill:#fff7ed,stroke:#ea580c,color:#9a3412,stroke-width:2px;
classDef storage fill:#ede9fe,stroke:#7c3aed,color:#4c1d95,stroke-width:2px;
class UI entry;
class API core;
class DS,RISK,POLICY,GRAPH,EVAL,AUDIT service;
class PG,REDIS,NEO4J,OS storage;
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'actorBkg': '#dbeafe',
'actorBorder': '#145DA0',
'actorTextColor': '#0C2D48',
'activationBkgColor': '#dcfce7',
'activationBorderColor': '#1f8a70',
'signalColor': '#145DA0',
'signalTextColor': '#0C2D48',
'labelBoxBkgColor': '#fff7ed',
'labelBoxBorderColor': '#ea580c',
'labelTextColor': '#9a3412'
}}}%%
sequenceDiagram
participant User
participant UI
participant API
participant Risk
participant Policy
participant Graph
participant Audit
User->>UI: Open PR workspace
UI->>API: POST /api/v1/pull-requests/{id}/analyze
API->>Graph: Expand impacted services/modules
API->>Risk: Score weighted risk factors
API->>Policy: Evaluate governance rules
API->>Audit: Persist analysis event
API-->>UI: Grounded analysis payload
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'primaryColor': '#dbeafe',
'primaryBorderColor': '#145DA0',
'primaryTextColor': '#0C2D48',
'lineColor': '#145DA0',
'secondaryColor': '#dcfce7',
'tertiaryColor': '#fff7ed'
}}}%%
flowchart TD
CHANGED[Changed services from PR] --> BFS[Bounded traversal max depth=2]
BFS --> EDGES[depends_on/calls/consumes/publishes_to]
EDGES --> IMPACT[Impacted service set]
IMPACT --> DEPTH[Blast radius depth]
IMPACT --> OWNERS[Owner/team enrichment]
classDef entry fill:#dbeafe,stroke:#145DA0,color:#0C2D48,stroke-width:2px;
classDef process fill:#dcfce7,stroke:#1f8a70,color:#14532d,stroke-width:2px;
classDef output fill:#fff7ed,stroke:#ea580c,color:#9a3412,stroke-width:2px;
class CHANGED entry;
class BFS,EDGES process;
class IMPACT,DEPTH,OWNERS output;
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'primaryColor': '#dbeafe',
'primaryBorderColor': '#145DA0',
'primaryTextColor': '#0C2D48',
'lineColor': '#145DA0',
'secondaryColor': '#dcfce7',
'tertiaryColor': '#fff7ed'
}}}%%
flowchart LR
TEST[Test runs] --> JOIN[Signal aggregation]
CI[CI jobs + retries] --> JOIN
JOIN --> GAP[Test gap detector]
GAP --> RISK[Risk confidence adjustments]
JOIN --> PANEL[PR and release diagnostics]
classDef input fill:#dbeafe,stroke:#145DA0,color:#0C2D48,stroke-width:2px;
classDef process fill:#dcfce7,stroke:#1f8a70,color:#14532d,stroke-width:2px;
classDef output fill:#fff7ed,stroke:#ea580c,color:#9a3412,stroke-width:2px;
class TEST,CI input;
class JOIN,GAP process;
class RISK,PANEL output;
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'primaryColor': '#dbeafe',
'primaryBorderColor': '#145DA0',
'primaryTextColor': '#0C2D48',
'lineColor': '#145DA0',
'secondaryColor': '#dcfce7',
'tertiaryColor': '#fff7ed'
}}}%%
flowchart TD
PRS[Merged PR candidates] --> READINESS[Compute readiness score]
READINESS --> CHECK1{High risk unresolved?}
CHECK1 -->|Yes| BLOCK[Block release]
CHECK1 -->|No| CHECK2{Required approvals complete?}
CHECK2 -->|No| BLOCK
CHECK2 -->|Yes| READY[Release ready]
BLOCK --> OVERRIDE{Override with rationale?}
OVERRIDE -->|Yes| READY
OVERRIDE -->|No| HOLD[Hold candidate]
classDef input fill:#dbeafe,stroke:#145DA0,color:#0C2D48,stroke-width:2px;
classDef process fill:#dcfce7,stroke:#1f8a70,color:#14532d,stroke-width:2px;
classDef decision fill:#fef3c7,stroke:#d97706,color:#92400e,stroke-width:2px;
classDef risk fill:#fee2e2,stroke:#dc2626,color:#991b1b,stroke-width:2px;
classDef success fill:#dcfce7,stroke:#16a34a,color:#166534,stroke-width:2px;
classDef hold fill:#ede9fe,stroke:#7c3aed,color:#5b21b6,stroke-width:2px;
class PRS input;
class READINESS process;
class CHECK1,CHECK2,OVERRIDE decision;
class BLOCK risk;
class READY success;
class HOLD hold;
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'primaryColor': '#dbeafe',
'primaryBorderColor': '#145DA0',
'primaryTextColor': '#0C2D48',
'lineColor': '#145DA0',
'secondaryColor': '#dcfce7',
'tertiaryColor': '#fff7ed'
}}}%%
flowchart LR
INPUT[PR paths + risk + release context] --> RULES[Policy ruleset]
RULES --> MATCH[Path/risk condition matcher]
MATCH --> FINDINGS[Policy findings]
FINDINGS --> STATE[pass/blocked]
STATE --> AUDIT[Audit log event]
classDef input fill:#dbeafe,stroke:#145DA0,color:#0C2D48,stroke-width:2px;
classDef process fill:#dcfce7,stroke:#1f8a70,color:#14532d,stroke-width:2px;
classDef output fill:#fff7ed,stroke:#ea580c,color:#9a3412,stroke-width:2px;
class INPUT input;
class RULES,MATCH process;
class FINDINGS,STATE,AUDIT output;
%%{init: {'theme': 'base', 'themeVariables': {
'fontFamily': 'Trebuchet MS, Verdana, sans-serif',
'primaryColor': '#dbeafe',
'primaryBorderColor': '#145DA0',
'primaryTextColor': '#0C2D48',
'lineColor': '#145DA0',
'secondaryColor': '#dcfce7',
'tertiaryColor': '#fff7ed'
}}}%%
flowchart TD
BENCH[Seeded benchmark cases] --> RUN[POST /api/v1/evals/run]
RUN --> CHECKS[Impact/reviewer/policy/risk checks]
CHECKS --> SCORE[Pass rate + quality metrics]
SCORE --> STORE[Persist eval run history]
STORE --> GATE{Pass threshold met?}
GATE -->|Yes| MERGE[Allow CI gate]
GATE -->|No| FAIL[Fail CI gate]
classDef input fill:#dbeafe,stroke:#145DA0,color:#0C2D48,stroke-width:2px;
classDef process fill:#dcfce7,stroke:#1f8a70,color:#14532d,stroke-width:2px;
classDef decision fill:#fef3c7,stroke:#d97706,color:#92400e,stroke-width:2px;
classDef success fill:#dcfce7,stroke:#16a34a,color:#166534,stroke-width:2px;
classDef fail fill:#fee2e2,stroke:#dc2626,color:#991b1b,stroke-width:2px;
class BENCH input;
class RUN,CHECKS,SCORE,STORE process;
class GATE decision;
class MERGE success;
class FAIL fail;
Risk score is the weighted sum of measurable factors capped at 100:
Factors currently include:
- changed file count
- protected path touches
- critical service impact
- CI failures and retries
- coverage regression and failed/flaky tests
- transitive dependency depth
Each analysis response includes factor-level rationale and confidence metadata.
Implemented baseline governance:
- Critical payments path changes require platform approval.
- Auth configuration changes require security approval.
- High-risk release candidates block readiness without justified override.
Override requests require actor and rationale and are audit-logged.
- Structured JSON logs with request IDs.
- API latency headers (
x-latency-ms). - Dependency health endpoint for PostgreSQL, Redis, Neo4j, OpenSearch.
- Audit event stream for analysis, eval runs, approvals, and overrides.
- Contribution guide: .github/CONTRIBUTING.md
- Commit guidance: docs/project-management/commit-guidelines.md
- Labels and triage: docs/project-management/labels.md and docs/project-management/triage.md
- Review and release discipline: docs/project-management/review-guidelines.md and docs/project-management/release-checklist.md
- Initial backlog: docs/project-management/initial-backlog.md
Core endpoints:
GET /healthGET /health/dependenciesGET /api/v1/pull-requestsGET /api/v1/pull-requests/{id}POST /api/v1/pull-requests/{id}/analyzeGET /api/v1/pull-requests/{id}/impactGET /api/v1/pull-requests/{id}/reviewersGET /api/v1/pull-requests/{id}/testsGET /api/v1/pull-requests/{id}/ciGET /api/v1/pull-requests/{id}/riskGET /api/v1/releasesGET /api/v1/releases/{id}POST /api/v1/releases/{id}/evaluateGET /api/v1/releases/{id}/readinessPOST /api/v1/releases/{id}/approvePOST /api/v1/releases/{id}/overrideGET /api/v1/servicesGET /api/v1/services/{id}GET /api/v1/services/{id}/graphGET /api/v1/policiesPOST /api/v1/policies/evaluateGET /api/v1/auditGET /api/v1/evalsPOST /api/v1/evals/runGET /api/v1/providersGET /api/v1/config/public
cp .env.example .env
make upcd apps/api && uv run uvicorn app.main:app --reload --host 0.0.0.0 --port 8080
cd apps/web && npm install && npm run devcurl http://localhost:8080/health
curl http://localhost:8080/api/v1/pull-requests
open http://localhost:3000The default local CORS configuration allows both http://localhost:3000 and http://127.0.0.1:3000. If you override API_CORS_ORIGINS, keep both entries unless you intentionally want a stricter local setup.
VANGUARD/
apps/
api/
web/
datasets/
docs/
infra/
packages/
scripts/
- Local deterministic provider is used to keep outputs grounded and reproducible.
- Neo4j and OpenSearch are provisioned for realistic infra shape; graph traversal currently uses seeded graph logic for deterministic local runs.
- SQLAlchemy models are included as a migration-ready baseline while seeded JSON provides immediate offline scenarios.
- Open PR Workspace and analyze PR-3413.
- Inspect high risk factors (CI failures, auth config changes, coverage drop).
- Review blocked policy findings requiring security approval.
- Move to Release Center and inspect unresolved blockers.
- Process pending team approval in Approvals Queue.
- Run eval benchmark and inspect audit trail.
- Live ingestion from GitHub webhooks and CI providers.
- Persisted analysis snapshots in PostgreSQL.
- Neo4j-backed query mode with incremental graph updates.
- Better flaky test trend modeling.
- Release note templating with policy/risk provenance tags.
- SLO dashboards and alerting hooks.



