Pipeline & Architecture

How a keystroke becomes a production signal — and how the system stays swappable

The five-layer pipeline

Shift-left in practice: the same rules run everywhere, just later and deeper each layer down.
runs on developer's device runs automated on the server
Layer 1 · IDE< 1 sec

Linter + type checker run as a language server the moment you type. Config lives in the repo, not on anyone's machine.

ESLintTypeScript strictRuffmypy
Layer 2 · Pre-commit< 10 sec

Format + auto-fix on changed files only — never the whole repo, or developers will route around it.

Huskylint-stagedpre-commit
Layer 3 · Pull request< 10 min

SAST, tests + coverage, dependency scan and AI review run in parallel — nothing waits on anything else.

SemgrepCodeQLClaude reviewSnyk
Layer 4 · Quality gateinstant

Clean-as-you-code: only the new diff is judged. Fail one required check and merge is locked — including for admins.

Branch protectionRequired checks
Layer 5 · Post-mergescheduled

The slow, deep checks that would make a PR wait too long — run nightly instead, and feed findings back as new rules.

FuzzingMutation testingSentry
Why five layers, not one big check?

The earlier a layer catches something, the cheaper it is to fix. A typo caught in the IDE costs a keystroke; the same typo caught in production costs an incident.


System architecture — four independent layers

Each layer only talks to its neighbor. Swap what's inside a layer and nothing above or below has to change — that's how the platform absorbs whatever tooling comes next.
Interface How teams reach the platform Changes freely — nothing below it notices
Web UIThis dashboard — Next.js, static-exportable
IDE pluginVS Code · JetBrains, real-time squiggles
CLIzcv scan for local & CI use
APIREST / gRPC, for third-party integration
WebhookGitHub · GitLab · Bitbucket receivers
Primary surface today: Web UI IDE plugin CLI Headless API
Service Business logic Stateless — scales horizontally, redeploys independently
Analysis serviceSAST · AI review · lint, results merged into one report
Python 3.12+
Pipeline serviceJob queue · quality gate · notifications
Go / TypeScript
Report serviceMetrics · trend · alerting
Python / Go

The three services never call each other directly — they publish and subscribe over a message bus (NATS or Kafka), so any one can be redeployed or rewritten without the other two noticing.

SAST engine: Semgrep CodeQL SonarQube + next engine
AI reviewer: Claude OpenAI Local model + next provider

Every provider implements one AIReviewer interface — adding a new one is a new adapter class, never a change to the pipeline that calls it.

Data Polyglot persistence The stable core — the piece that changes least often
PostgreSQL 16+Issues · rules · users · projects
ACID + pgvector, ready for future AI features
TimescaleDB 2.xMetrics · trend · coverage over time
100× faster than plain SQL for time-series
Redis / Valkey 7+Job queue · cache · session
Fast, simple, open-source fork of Redis
S3-compatible · API v4SBOMs · artifacts · raw scan results
Vendor-agnostic — MinIO, R2, GCS all work
Hosting model: Managed (RDS / ElastiCache) Self-hosted (StatefulSet)
Infrastructure Where it all runs Swap cloud provider without rewriting a line of app code
KubernetesEKS · GKE · AKS · on-premise — same manifests everywhere
DockerEvery service ships as one portable image
Terraform / PulumiInfra as code — cloud provider is a variable
GitOpsArgoCD or Flux — Git is the source of truth
Message busNATS or Kafka — event-driven, decouples services
SecretsHashiCorp Vault or AWS Secrets Manager
ObservabilityPrometheus + Grafana — metrics & alerting
Tracing & logsOpenTelemetry + Jaeger · Loki or ELK
Cloud target: AWS GCP Azure On-prem
Built to outlive today's tools

A new SAST engine, a different LLM provider, a new cloud, even a new interface (say, a chat surface or an agentic reviewer) — each is a swap at one layer. The contract between layers is the API, not the implementation, so the rest of the stack never has to know.