Pranor Documentation
Welcome to the Pranor documentation. Pranor is a unified, modular backend infrastructure engine with its own programming language, designed to build high-performance microservices with zero glue code.
Quick Navigation
| Section | Description |
|---|---|
| Getting Started | Install Pranor and build your first service in 5 minutes |
| Language Reference | Syntax, standard library, CLI commands |
| Module Docs | Full documentation for each Pranor module |
| Deployment | Docker, Kubernetes, standalone deployment guides |
| Architecture | System design, security model, observability |
| Enterprise | EE features, licensing, and comparison |
| Changelog | Unified release history |
Modules
| Module | What it does | Docs |
|---|---|---|
| Pranor (CLI) | Compiler & language runtime | Language → |
| Gate | API Gateway & AI Guard | gate.md → |
| Pulse | Async Event Broker & Message Queue | pulse.md → |
| Vault | S3 Storage & Vector Search | vault.md → |
| Chrono | Distributed Job Scheduler | chrono.md → |
| Auth | Identity & Access Control | auth.md → |
| Cache | Distributed Cache Engine | cache.md → |
| Mesh | Service Discovery & Load Balancing | mesh.md → |
| Trace | Distributed Tracing Engine | trace.md → |
| Console | Observability Dashboard | console.md → |
| Pool | Database Connection Proxy | pool.md → |
| Notify | Email/Slack/SMS Gateway | notify.md → |
| Flow | Workflow Engine & Saga Orchestrator | flow.md → |
| Deploy | Docker/K8s Deployment Pipeline | deploy.md → |
| Tunnel | WebSocket Dev Tunneling | tunnel.md → |
| Hub | Package Registry | hub.md → |
| Lock | Distributed Locking | lock.md → |
| Secret | Secret Management | secret.md → |
Install
# macOS/Linux
brew tap vyuvaraj/pranor && brew install pranor
# Windows
scoop bucket add pranor https://github.com/vyuvaraj/scoop-pranor
scoop install pranor
# From source
git clone https://github.com/vyuvaraj/pranor && cd pranor/lang && go build -o pranor .
First Service
pranor init myapp && cd myapp && pranor run main.pnr --watch
Getting Started with Pranor
Build and deploy a backend service in 5 minutes.
Prerequisites
- Go 1.22+ installed (download)
- A terminal (bash, PowerShell, or cmd)
Install
macOS / Linux (Homebrew)
brew tap vyuvaraj/pranor
brew install pranor
Windows (Scoop)
scoop bucket add pranor https://github.com/vyuvaraj/scoop-pranor
scoop install pranor
From Source
git clone https://github.com/vyuvaraj/pranor.git
cd pranor/lang
go build -o pranor .
# Add to PATH or move to /usr/local/bin
Verify
pranor --version
Create Your First Service
pranor init myapp
cd myapp
This creates a main.pnr file:
server "8080"
database "sqlite://app.db"
migration "create_users" {
db.query("CREATE TABLE IF NOT EXISTS users (
id INTEGER PRIMARY KEY,
name TEXT NOT NULL,
email TEXT UNIQUE
)")
}
export route "GET" "/api/users" (req) {
let users = db.query("SELECT * FROM users")
return { "users": users }
}
export route "POST" "/api/users" (req) {
let name = req.body.name
let email = req.body.email
db.query("INSERT INTO users (name, email) VALUES (?, ?)", name, email)
return { "status": "created" }
}
Run
pranor run main.pnr --watch
Your API is now running at http://localhost:8080. The --watch flag auto-reloads on file changes.
Test It
# Create a user
curl -X POST http://localhost:8080/api/users \
-H "Content-Type: application/json" \
-d '{"name": "Alice", "email": "alice@example.com"}'
# List users
curl http://localhost:8080/api/users
Build for Production
pranor build main.pnr -o myapp
./myapp # Single binary, no runtime needed
Add More Capabilities
Pranor modules extend your service without glue code:
// Add a scheduled task
every 5m {
log.info("Running cleanup...")
db.query("DELETE FROM sessions WHERE expires_at < datetime('now')")
}
// Add caching
cache "in-memory"
export route "GET" "/api/users/:id" (req) {
let cached = cache.get("user:" + req.params.id)
if cached != nil { return cached }
let user = db.query("SELECT * FROM users WHERE id = ?", req.params.id)
cache.set("user:" + req.params.id, user, 300)
return user
}
Deploy
# Docker
pranor deploy --target docker
# Kubernetes
pranor deploy --target k8s --namespace production
What's Next
- Language Reference — Full syntax guide
- Module Docs — Gate, Pulse, Vault, Auth, and more
- Deployment Guide — Production Docker/K8s setup
- Architecture Overview — How modules connect
Pranor: A Programming Language for Background Services
Pranor is a modern, high-level DSL (Domain-Specific Language) designed specifically for building background services, schedulers, event-driven applications, and API microservices. It compiles directly into native binaries via Go code generation, providing high performance, low resource consumption, and rapid development.
Table of Contents
- Key Features
- Getting Started
- Editor Support
- CLI Commands Reference
- Language Syntax Guide
- Multi-File Import System
- Async & Concurrent Primitives
- Multi-Target Code Generation
- Breaking Change Detector
- Web Playground
- Standard Library
- Package Management
- Testing Support
- Compilation & Deployment
- Documentation
Key Features
- Declarative Infrastructure: Routes, schedulers, pub/sub, databases, caches, and WebSockets as language keywords — not library calls.
- Compiles to Native Binaries: Go code generation → single binary deployment. No runtime dependencies.
- Optional Static Typing: Gradual type system with
int,float,string,bool, optional types (T?), union types (T | error), and generics with constraints. - 48 Standard Library Modules: Auth, JWT, retry, circuit breaker, pagination, CORS, rate limiting, validation, and more — written in Pranor itself.
- Built-in Test Framework:
test "name" { assert expr }blocks with structured assertion messages. - Multiple Database Backends: SQLite, PostgreSQL, Oracle, MongoDB — same
db.query()API. - Multiple Broker Backends: Kafka, NATS, RabbitMQ, MQTT — same
subscribe/publishsyntax. - Concurrency Primitives:
spawn,async/await, channels, worker pools. - Middleware & Auth: Declarative middleware with
use [auth, logging]on routes. - Python Interop: Call Python scripts via
extern fnbindings. - Go Package FFI: Import any Go package with
pranor add <package>and auto-generated declarations. - VS Code Extension: Full LSP with diagnostics, autocomplete, hover, go-to-definition, and 30+ snippets.
- OpenTelemetry & Prometheus: Built-in tracing and metrics export.
- Docker Support:
pranor dockerizegenerates production-ready Dockerfiles. - Multi-File Import System: Import types and schemas across
.pnrfiles with cross-file type resolution and circular import detection. asyncTask &concurrent {}Primitives: First-class language support for async task execution and parallel concurrent blocks.- Multi-Target Code Generation: Generate Rust (
pranor generate --lang rust) or Python (pranor generate --lang python) client code from.pnrservice definitions. - Breaking Change Detector:
pranor diff old.pnr new.pnrdetects field removals, type changes, and new required fields — safe to use in CI pipelines. - Zero-Install WASM Playground: Try Pranor in the browser at playground.pranor.dev — runs the full compiler in WebAssembly, no install required.
Getting Started
Prerequisites
- Go: Version 1.22 or higher is required to build the compiler and execute Go-transpiled code.
- Python 3.x: Optional (needed if using Python external functions).
Install via Scoop (Windows)
scoop bucket add pranor https://github.com/vyuvaraj/scoop-pranor
scoop install pranor
Install via Homebrew (macOS / Linux)
brew tap vyuvaraj/pranor
brew install pranor
Install via Script (Windows)
irm https://raw.githubusercontent.com/vyuvaraj/Pranor/main/release-scripts/install.ps1 | iex
Build from Source
git clone https://github.com/vyuvaraj/Pranor.git
cd Pranor
go build -o pranor.exe .
Add the binary to your system PATH for global access.
Editor Support
VS Code Extension
Install Pranor Language Support from the VS Code Marketplace (or from .vsix in the repo):
- Syntax highlighting for
.pnrfiles - Real-time diagnostics (type errors, unused variables, missing returns)
- Autocomplete and hover information
- Go-to-definition across files
- 30+ code snippets (
route,fn,struct,test,every,subscribe, etc.) - Commands: Run (
Ctrl+Shift+R), Build (Ctrl+Shift+B), Test (Ctrl+Shift+T) - Format on save
CLI Commands Reference
| Command | Description |
|---|---|
pranor build <file.pnr> [-o output] | Compile to native binary |
pranor run <file.pnr> [--watch] | Compile and run (with optional hot-reload) |
pranor test <file.pnr> [--cover] [--filter name] | Run test blocks |
pranor lint <file.pnr> | Check syntax and static analysis |
pranor fmt <file.pnr> [--check] | Format code (4-space indent) |
pranor repl | Interactive shell |
pranor add <go-package> | Generate .pnr.d declaration for a Go package |
pranor packages | List installed package declarations |
pranor remove <package> | Remove a package declaration |
pranor install <name> | Install a community package |
pranor publish <dir> | Publish a package to the registry |
pranor init [name] | Create a new Pranor project |
pranor dockerize <file.pnr> | Generate a production Dockerfile |
pranor debug <file.pnr> | Debug with Delve |
pranor audit | Audit Go dependencies for vulnerabilities |
Language Syntax Guide
Core Architecture Statements
Pranor allows you to declare global settings and connections dynamically or using values loaded from environment variables:
// Declare port dynamically from environment variables
server env("PORT")
// Setup global message broker (options: "in-memory", or Kafka address)
broker "in-memory"
// Setup databases (SQLite, PostgreSQL, Oracle, MongoDB)
database "sqlite://service_data.db"
database env("DATABASE_URL")
// Setup in-memory cache
cache "in-memory"
Static Typing & Type Annotations
Pranor supports optional static typing on variables and function signatures. Providing types compiles them directly into native Go types, skipping the performance overhead of runtime interface{} conversions.
Supported types: int, string, bool.
Variable Type Annotations
Specify types using : type after the identifier:
let count: int = 100
let label: string = "Items in queue"
let isActive: bool = true
Function Signature Type Annotations
Specify parameter and return types to optimize function calls and compiler math:
fn calculateTotal(base: int, tax: int) -> int {
let result: int = base + tax
return result
}
Schedulers (every & cron)
Easily define background routines that run periodically or at scheduled times.
Interval Scheduler
Runs a block of code at a specific time duration (e.g., s for seconds, m for minutes, h for hours).
every 5s {
log.info("System healthcheck running...")
}
Cron Scheduler
Executes using standard cron patterns. Can load patterns from environment variables.
cron "0 */2 * * * *" {
log.info("This runs every 2 minutes.")
}
// Load from environment variable
cron env("BACKUP_CRON") {
log.warn("Starting system database backup...")
}
Web Servers & HTTP APIs (route)
Declare HTTP request endpoints with simple routes. Pranor handles request body parsing natively.
route "GET" "/status" (req) {
log.info("Status check requested")
return {
"status": "Pranor is operating normally",
"timestamp": time.now()
}
}
route "POST" "/webhook" (req) {
let body = req.body
log.info("Received body payload: ", body)
return { "received": true }
}
Pub/Sub Broker (publish & subscribe)
Publish event messages and register subscriptions.
// Publish message onto a topic channel
publish "events.incoming" { "user_id": 101, "action": "login" }
// Subscribe to messages on a topic
subscribe "events.incoming" (msg) {
log.info("Broker received event: ", msg)
}
Concurrency & Worker Pools (spawn)
You can execute operations asynchronously without blocking the main workflow thread.
Fire-and-Forget Goroutines
subscribe "incoming.tasks" (msg) {
// Spawns a lightweight concurrent thread
spawn processTask(msg)
}
Rate-Limited Worker Pools
Specify a worker limit to control resource consumption:
// Spawns up to 5 concurrent workers maximum
spawn(5) handleHeavyCalculation(data)
Database Operations (db.query)
Execute queries directly on the configured databases.
SQL Databases (SQLite, PostgreSQL, Oracle)
Supports query parsing and placeholders (? translates automatically to appropriate placeholders like $1 dynamically for PostgreSQL).
// Create schema table on startup
db.query("CREATE TABLE IF NOT EXISTS metrics (id INTEGER PRIMARY KEY, ts TEXT)")
// Insert records
db.query("INSERT INTO metrics (ts) VALUES (?)", time.now())
// Read records
let results = db.query("SELECT * FROM metrics LIMIT 5")
log.info("Metrics: ", results)
MongoDB Operations
Executes collection queries using standardized document queries:
let result = db.query("insert", "logs", "{\"service\": \"Pranor\", \"action\": \"db_test\"}")
Cache Operations (cache.set & cache.get)
Leverage native in-memory caching to save and read states quickly:
// Set key with cache TTL (Time to Live)
cache.set("session_user_1", { "id": 1, "role": "admin" }, "10m")
// Fetch value from cache
let session = cache.get("session_user_1")
log.info("Active Session: ", session)
S3 & Pranor Vault Client Operations (s3)
Interact with S3-compatible endpoints or a Pranor Vault gateway using the native s3 runtime functions. You can also import the helper wrapper from the standard library:
import { newClient, put, get, deleteObject, list, at, search } from "stdlib/s3.pnr"
// Initialize client
let client = newClient("http://localhost:8080", "admin", "adminsecret")
// Create and configure a bucket
client.createBucket("my-bucket")
client.setBucketVersioning("my-bucket", true)
// Upload and retrieve objects
client.put("my-bucket", "config.json", "{\"status\": \"active\"}")
let content = client.get("my-bucket", "config.json")
log.info("Content: ", content)
// Time-travel to retrieve previous versions of an object (Pranor Vault only)
let historicalContent = client.at("my-bucket", "config.json", "2026-06-15T09:00:00Z")
// Perform semantic search queries (Pranor Vault only)
let searchResults = client.search("my-bucket", "find active config files", 5)
Python Interoperability (extern fn)
Map complex algorithms or specialized Python libraries directly to Pranor functions:
// Map external Python method
extern fn analyzeText(text) from "python:./scripts/analyzer.py:analyze"
let result = analyzeText("Hello world!")
log.info("Python output: ", result)
Built-in Functions & Utilities
JSON Support
let obj = json.parse("{\"status\": true}")
let rawString = json.stringify(obj)
String Interpolation (f-strings)
let name = "Pranor"
let statusMessage = f"System: {name} is running!"
Pattern Matching (match)
match eventType {
"PAYMENT_COMPLETED" => {
log.info("Processing checkout success...")
}
"USER_LOGOUT" => {
log.info("Cleaning session...")
}
_ => {
log.warn("Unknown event category received")
}
}
Exception Handling (try-catch)
try {
let res = http.get("http://invalid-url.com")
} catch (err) {
log.error("HTTP request failed: ", err)
}
Web Playground
Pranor includes an interactive Web Playground for trying the language in-browser.
- WASM Compiler: Syntax analysis and formatting run client-side
- Sandbox Runner: Compiles and executes code server-side with auto-termination
go build -o web_playground/server/server.exe web_playground/server/main.go
./web_playground/server/server.exe
# Open http://localhost:8080
Standard Library
Pranor ships with 48 importable modules written in Pranor itself:
| Category | Modules |
|---|---|
| Auth & Security | auth, jwt, crypto, cors, sanitize, ip |
| Resilience | retry, circuit_breaker, timeout, semaphore, dlq |
| HTTP | http_client, response, middleware, ratelimit, webhook |
| Data | validation, pagination, pagination_cursor, csv, diff, sort, collections |
| Config & Env | config, env, feature_flags |
| Observability | tracing, metrics, health, audit |
| Utilities | strings_util, datetime, math, url, base64, mask, idempotency, batch, queue |
| Infra | s3, cache_patterns, tenant, scheduler, job, graceful |
Import with:
import { hashPassword, verifyPassword } from "stdlib/crypto"
import { ok, notFound, created } from "stdlib/response"
import { retry } from "stdlib/retry"
Package Management
Publishing
pranor publish <package-dir>
Installing
pranor install <package-name>
Using
import { Helper, helperFunc } from "mypkg"
Resolves to packages/mypkg/index.pnr or packages/mypkg/main.pnr. Only export-marked declarations are accessible.
Testing Support
Pranor includes a native test harness built into the language itself. This makes it trivial to write unit tests alongside your code and verify logic without external framework setups.
Defining Tests
Add test blocks and use the assert statement to check variables:
fn doubleValue(val) {
return val * 2
}
test "doubling math verification" {
assert doubleValue(2) == 4
assert doubleValue(5) == 10
}
test "check string comparison" {
let val = "Pranor" + "Lang"
assert val == "ServLang"
}
Running Tests
Execute:
pranor test test_sample.pnr
Output:
Running tests from test_sample.pnr...
=== RUN Test_DoublingMathVerification
--- PASS: Test_DoublingMathVerification (0.00s)
=== RUN Test_CheckStringComparison
--- PASS: Test_CheckStringComparison (0.00s)
PASS
ok pranor/.build 1.518s
Compilation & Deployment
When pranor build or pranor test is executed, the compiler compiles the input .pnr code into a temporary directory called .build.
Inside .build:
service.go: Synthesizes code for all declarations, routes, and background routines.main.go: Provides the service runtime engine and entry points.pranor_test.go: Aggregates thetestblocks translated to Go's native testing framework.
The output binary compiles out all debug logs and features a fast, low-overhead native runtime engine.
Documentation
- Language Reference — Full syntax and type system
- Getting Started — First project walkthrough
- Standard Library — All modules documented
- CLI Reference — All commands and flags
- Deployment Guide — Docker, TLS, observability
- Examples — Examples & technical articles
Multi-File Import System
Pranor supports splitting service definitions across multiple .pnr files. Types and schemas defined in one file can be imported and used in another:
// types/user.pnr
type User {
id: string
name: string
email: string
}
// services/auth.pnr
import "./types/user.pnr"
route POST "/api/users" {
body: User
handler: createUser
}
Features:
- Cross-file type resolution with full type checking
- Circular import detection with descriptive error messages
- Wildcard imports:
import "./types/*" - Re-export:
export type AdminUser extends User { role: string }
Async & Concurrent Primitives
Pranor provides first-class async and concurrent language constructs:
// Async task — fire and forget
async fn sendNotification(userID: string) {
call POST "http://notifications/send" { userID }
}
route POST "/api/orders" {
handler: fn(req) {
let order = db.insert("orders", req.body)
// Fire async — doesn't block the response
async sendNotification(req.body.userID)
return { order_id: order.id }
}
}
// Concurrent block — run steps in parallel, collect results
route GET "/api/dashboard" {
handler: fn(req) {
let results = concurrent {
orders: call GET "http://orders/summary"
inventory: call GET "http://inventory/levels"
analytics: call GET "http://analytics/today"
}
return results // all three completed in parallel
}
}
Multi-Target Code Generation
Generate type-safe client code for other languages from your Pranor service definitions:
# Generate Go client (default — used within Pranor compilation)
pranor generate --lang go services/orders.pnr
# Generate Rust client
pranor generate --lang rust services/orders.pnr -o ./clients/rust/
# Generate Python client
pranor generate --lang python services/orders.pnr -o ./clients/python/
Generated Rust client:
#![allow(unused)] fn main() { // Auto-generated by `pranor generate --lang rust` pub struct OrdersClient { base_url: String } impl OrdersClient { pub async fn create_order(&self, body: CreateOrderRequest) -> Result<Order, Error> { ... } pub async fn get_order(&self, id: &str) -> Result<Order, Error> { ... } } }
Generated Python client:
# Auto-generated by `pranor generate --lang python`
class OrdersClient:
def create_order(self, body: CreateOrderRequest) -> Order: ...
def get_order(self, id: str) -> Order: ...
Breaking Change Detector
pranor diff compares two .pnr files (or two git revisions) and detects breaking API changes — safe to run in CI before merging:
pranor diff api/v1/orders.pnr api/v2/orders.pnr
Example output:
⚠️ BREAKING CHANGES DETECTED
[FIELD_REMOVED] Order.discount_code (line 12 → removed)
[TYPE_CHANGED] Order.total: int → float (line 8)
[REQUIRED_ADDED] CreateOrderRequest.currency (line 23 → now required)
✅ NON-BREAKING CHANGES
[FIELD_ADDED] Order.created_at (optional)
Detected breaking change categories:
- Field removals from request/response types
- Type changes (e.g.,
int→string) - Making optional fields required
- Route removal or method change
- Removing enum variants
Use in CI:
# GitHub Actions
- run: pranor diff main:api/orders.pnr HEAD:api/orders.pnr
# Exits with code 1 if breaking changes detected
License
Apache 2.0 — see LICENSE
Links
- GitHub: github.com/vyuvaraj/pranor
- Playground: playground.pranor.dev — zero-install WASM browser playground
- VS Code Extension: Search "Pranor Language Support" in Extensions
- Issues: github.com/vyuvaraj/pranor/issues
Pranor Standard Library
Reusable .pnr modules for common service patterns. Import what you need:
import { ok, notFound } from "stdlib/response.pnr"
import { requireAuth, bearerToken } from "stdlib/auth.pnr"
Module Index
| Module | Exports | Category |
|---|---|---|
auth.pnr | bearerToken, basicAuth, requireAuth | Security |
crypto.pnr | hashPassword, verifyPassword, randomToken, randomHex, hmacSign, hmacVerify | Security |
jwt.pnr | jwtEncode, jwtDecode, jwtIsExpired | Security |
sanitize.pnr | escapeHTML, stripTags, escapeSQL, sanitizeFilename, normalizeWhitespace | Security |
ratelimit.pnr | createLimiter, isAllowed, remaining, resetLimiter | Security |
validation.pnr | required, isEmail, isURL, minLength, maxLength, validateFields | Input |
response.pnr | ok, created, badRequest, notFound, serverError, errorResponse | HTTP |
pagination.pnr | offset, pageResponse, parsePageParams | HTTP |
middleware.pnr | corsHeaders, requestId, logRequest, isPreflight | HTTP |
http_client.pnr | getJSON, postJSON, isSuccess, isClientError, isServerError | HTTP |
url.pnr | encodeURI, parseQuery, buildQuery, joinPath, extractPath | HTTP |
datetime.pnr | now, timestamp, isExpired, formatDuration, sleep | Utilities |
strings_util.pnr | slugify, truncate, capitalize, isEmpty, repeat, matches | Utilities |
math.pnr | min, max, clamp, abs, percent, between, sum, average | Utilities |
sort.pnr | sortAsc, sortDesc, reverse, minOf, maxOf | Utilities |
collections.pnr | groupBy, unique, flatten, chunk, first, last, countWhere | Data |
csv.pnr | parseCSV, parseRow, toRow, toCSV | Data |
diff.pnr | hasChanged, fieldChanged, changeRecord | Data |
env.pnr | requireEnv, envOrDefault, envInt, envBool, envExists | Config |
retry.pnr | backoffDelay, defaultMaxRetries, defaultBaseDelay | Resilience |
circuit_breaker.pnr | createBreaker, isOpen, recordSuccess, recordFailure, resetBreaker, failureCount | Resilience |
queue.pnr | createQueue, enqueue, dequeue, queueSize, queueIsEmpty | Resilience |
events.pnr | on, emit, hasHandler | Messaging |
metrics.pnr | counter, counterWithLabel, gauge, recordLatency, trackRequest | Observability |
testing_helpers.pnr | assertEqual, assertNotNil, assertNil, assertContains, assertTrue, assertFalse, assertLength | Testing |
health.pnr | healthy, unhealthy, degraded, buildHealthResponse | Ops |
scheduler.pnr | scheduleAfter, isScheduled, cancelSchedule, getDelay | Scheduling |
webhook.pnr | buildPayload, sendWebhook, verifySignature, retryRecord | Integration |
cors.pnr | allowOrigin, allowAll, preflightResponse, isOriginAllowed | HTTP |
graceful.pnr | initShutdown, isShuttingDown, connectionOpened, connectionClosed, isDrained | Ops |
tracing.pnr | traceId, spanId, startSpan, endSpan, addTag, traceContext | Observability |
semaphore.pnr | createSemaphore, tryAcquire, release, available, utilization | Concurrency |
batch.pnr | createBatch, addToBatch, batchSize, isBatchFull, flushBatch | Processing |
idempotency.pnr | checkIdempotency, markProcessed, isProcessed, getProcessedResult | Reliability |
job.pnr | createJob, startJob, completeJob, failJob, jobStatus | Processing |
feature_flags.pnr | enableFlag, disableFlag, isEnabled, toggleFlag, initFlag | Config |
config.pnr | getConfig, requireConfig, configInt, configBool, configList, hasConfig | Config |
tenant.pnr | extractTenant, tenantConfig, isTenantActive, tenantCacheKey, tenantFilter | Multi-tenancy |
dlq.pnr | createDLQ, sendToDLQ, dlqSize, dlqHasItems, clearDLQ | Reliability |
audit.pnr | auditLog, auditAction, auditAccess, auditAuth, auditDenied | Compliance |
cache_patterns.pnr | cacheKey, cacheGet, cacheSet, invalidate, invalidatePrefix, cacheTTL, computeIfAbsent | Caching |
pagination_cursor.pnr | encodeCursor, decodeCursor, hasCursor, extractCursor, cursorResponse, cursorResponseWith | HTTP |
timeout.pnr | withDeadline, isTimedOut, remainingTime, startTimer, elapsed, hasExceeded | Resilience |
ip.pnr | extractIP, isPrivate, isTrustedProxy, rateLimitKey, anonymizeIP | Security |
mask.pnr | maskEmail, maskPhone, maskCard, maskString, redact | Security |
Categories
Security
- auth.pnr — Token extraction, bearer/basic auth, auth guards
- crypto.pnr — Password hashing, HMAC signing, token generation
- jwt.pnr — JWT encode/decode/expiry (lightweight; use
pranor add github.com/golang-jwt/jwt/v5for production)
HTTP
- response.pnr — Standard HTTP response builders (ok, notFound, etc.)
- pagination.pnr — Page offset calculation, response envelope
- middleware.pnr — CORS headers, request ID generation, preflight detection
- http_client.pnr — JSON GET/POST wrappers, status code helpers
Utilities
- datetime.pnr — Timestamps, expiry checks, duration formatting
- strings_util.pnr — Slugify, truncate, capitalize, pattern matching
- collections.pnr — Array utilities (unique, flatten, chunk, first/last)
Config & Environment
- env.pnr — Required env vars, defaults, type coercion (int/bool)
Resilience
- retry.pnr — Exponential backoff calculation
Messaging
- events.pnr — In-process event bus (emit/on pattern)
Testing
- testing_helpers.pnr — Expressive assertions for test blocks
Operations
- health.pnr — Custom health check builders
- graceful.pnr — Shutdown state, connection draining, drain detection
Scheduling
- scheduler.pnr — Dynamic runtime scheduling beyond
every/cron
Integration
- webhook.pnr — Outgoing webhook payloads, signature verification, retry records
- cors.pnr — CORS header generation, origin checking, preflight responses
Concurrency
- semaphore.pnr — Named semaphores with slot tracking and utilization metrics
Processing
- batch.pnr — Accumulate-and-flush batch pattern with size tracking
- job.pnr — Background job lifecycle (pending → running → completed/failed)
Reliability
- idempotency.pnr — Idempotency key pattern for deduplication
- dlq.pnr — Dead letter queue for failed message tracking
Multi-tenancy
- tenant.pnr — Tenant extraction from requests, scoped config/cache/DB keys
Compliance
- audit.pnr — Structured audit trail (actions, access, auth, denied events)
Usage Example
import { requireAuth, bearerToken } from "stdlib/auth.pnr"
import { ok, badRequest } from "stdlib/response.pnr"
import { required, isEmail } from "stdlib/validation.pnr"
import { envOrDefault } from "stdlib/env.pnr"
server envOrDefault("PORT", "8080")
route "POST" "/api/users" (req) {
let authErr = requireAuth(req)
if authErr != nil {
return authErr
}
let errors = validate(req.body, {
"email": "required,email",
"name": "required"
})
if errors != nil {
return badRequest(errors)
}
return ok({ "created": true })
}
Contributing
Add new modules as stdlib/<name>.pnr. Export functions with export fn. Follow existing patterns:
- Pure functions where possible
- No side effects unless explicitly documented
- Use
interface{}params (no type annotations) for maximum flexibility
Pranor CLI Reference
The pranor command is the single entry point for all development and deployment tasks.
Usage
pranor <command> [options] [arguments]
Commands
Development
| Command | Description |
|---|---|
pranor init <name> | Create a new Pranor project |
pranor run <file.pnr> [--watch] | Run a .pnr service (with optional hot-reload) |
pranor dev <file.pnr> | Run with hot-reload enabled (alias for run --watch) |
pranor build <file.pnr> -o <binary> | Compile to a native binary |
pranor test <file.pnr> [--cover] [--filter] | Run test blocks |
pranor lint <file.pnr> | Static analysis and syntax checking |
pranor fmt <file.pnr> | Auto-format source code |
pranor repl | Interactive Pranor shell |
Package Management
| Command | Description |
|---|---|
pranor add <package> | Add a Go package dependency |
pranor remove <package> | Remove a package |
pranor packages | List installed packages |
pranor publish | Publish to Pranor Hub registry |
Deployment
| Command | Description |
|---|---|
pranor deploy [--target docker|k8s] | Deploy service to Docker or Kubernetes |
pranor dockerize <file.pnr> | Generate a production Dockerfile |
Infrastructure
| Command | Description |
|---|---|
pranor gate | Manage Pranor Gate (API gateway) |
pranor pulse | Manage Pranor Pulse (message queue) |
pranor cache | Manage Pranor Cache |
pranor mesh | Manage Pranor Mesh (service discovery) |
pranor tunnel | Manage Pranor Tunnel (dev tunneling) |
pranor trace | Manage Pranor Trace (distributed tracing) |
pranor lock | Acquire/release distributed locks |
pranor secret | Manage secrets (inject, unseal) |
Tooling
| Command | Description |
|---|---|
pranor bench <file.pnr> | Generate load test scripts from routes |
pranor doc <file.pnr> | Generate HTML API documentation |
pranor diff <old.pnr> <new.pnr> | Detect breaking API changes |
pranor migrate | Run database migrations |
pranor doctor | Diagnose environment issues |
pranor upgrade | Check for and apply Pranor updates |
pranor audit | Scan dependencies for vulnerabilities |
Global Flags
| Flag | Description |
|---|---|
--version | Print Pranor version |
--help | Show help for any command |
--env <name> | Set environment profile (dev, staging, prod) |
--verbose | Enable verbose output |
Environment Variables
| Variable | Description |
|---|---|
PRANOR_HOME | Path to Pranor installation (runtime, stdlib) |
PRANOR_OTLP_ENDPOINT | OpenTelemetry collector URL for tracing |
PRANOR_DISCOVERY | JSON service discovery manifest |
Examples
# Create and run a project
pranor init my-api
cd my-api
pranor run main.pnr --watch
# Build for production
pranor build main.pnr -o my-api --target linux/amd64
# Run tests with coverage
pranor test main.pnr --cover
# Deploy to Docker
pranor deploy --target docker
# Add a package
pranor add github.com/google/uuid
Blog & Articles
Technical articles about Pranor architecture and design decisions.
These articles were originally published on Medium and provide deep-dives into individual modules.
| Article | Topic |
|---|---|
| Introducing Pranor | Platform vision and architecture |
| Getting Started with Pranor Language | Language tutorial |
| API Gateway Deep Dive | Gate architecture |
| Caching Strategies | Cache patterns |
| Event-Driven Architecture | Pulse design |
| Full-Stack SaaS | Building complete apps |
Note: Blog filenames retain historical names but content has been updated for the Pranor rebrand.
Pranor Gate
docker compose up -d
Pranor Gate is a high-performance, AI-native programmable API Gateway and reverse proxy for the Pranor ecosystem. It combines classical gateway capabilities (routing, auth, rate limiting) with cutting-edge AI middleware (prompt guard, semantic cache, MCP tool registry) and enterprise-grade reliability (circuit breaker, canary, WASM inline processing).
Performance & Benchmarks
Pranor Gate is engineered in Go for extreme throughput and low latency:
| Benchmark Metric | Result | Benchmark File |
|---|---|---|
| Throughput | 50,000+ req/sec | pkg/proxy/performance_test.go |
| P99 Added Latency | < 0.8 ms per request | pkg/proxy/performance_test.go |
| WASM Cold Start | ~0.3 ms compilation | pkg/proxy/performance_test.go |
| WASM Warm Exec | ~0.01 ms execution | pkg/proxy/performance_test.go |
Quickstart & Docker Compose
1. Minimal Standalone Setup
Copy config.example.json to config.json and launch Pranor Gate:
cp config.example.json config.json
docker run -p 8080:8080 -v ./config.json:/config.json ghcr.io/vyuvaraj/pranor-gate:latest
2. End-to-End AI Gateway + Ollama Setup
Run Pranor Gate connected to a local Ollama LLM endpoint with automatic prompt guard & semantic cache:
docker compose up -d
# Test AI route with automatic prompt guard inspection
curl -X POST http://localhost:8080/ai/v1/chat \
-H "Content-Type: application/json" \
-d '{"prompt": "Tell me a joke about distributed systems"}'
Table of Contents
- Key Features
- Performance & Benchmarks
- Configuration &
config.example.json - Command Line & Subcommands
- AI & LLM Gateway
- Security
- Observability
- Enterprise Edition
Key Features
🔀 Reverse Proxy & Routing
- Dynamic path-based routing: Pattern-match prefix rules (e.g.
/api/v1/orders/*→http://backend:8081) with automatic URL prefix stripping - Hot-reload config: Zero-dropped-request configuration reload — update routes, middleware, and targets without restarting
- WebSocket proxy: Full WebSocket upgrade proxying with multi-client stability and load distribution
- Traffic replay engine: Capture and replay live traffic logs (
.jsonl) against WASM modules for shadow testing
🧩 WASM & Policy-as-Code
- Sandboxed WASI execution: Compile guest WASM modules to run inline on request/response cycles
- Policy-as-Code Compiler: Compile
.policyrule files directly to sandboxed.wasmmodules usingpranor-gate policy compile
🤖 AI & LLM Gateway (AI-native)
- Prompt Guard: Injection detection & input sanitization (blocks prompt injection attempts before they reach LLMs)
- PII Redaction: Automatically scrub emails, SSNs, and phone numbers from prompts/responses
- Graceful AI Degradation: If no embedding model endpoint is configured, semantic cache gracefully bypasses without returning errors
- MCP Tool Registry: Auto-expose backend services as tools for AI agents
Configuration & config.example.json
Pranor Gate uses a simple JSON configuration. A minimal config.example.json is included in the repository:
{
"addr": ":8080",
"auth_token": "gateway-secret-token",
"routes": [
{
"prefix": "/api/v1/services",
"target": "http://127.0.0.1:8081",
"middleware": "uppercase",
"rate_limit_rpm": 120
},
{
"prefix": "/ai/v1",
"target": "http://127.0.0.1:11434",
"enable_semantic_cache": true,
"enable_prompt_guard": true
}
]
}
Command Line & Subcommands
Pranor Gate includes CLI subcommands for shadow traffic testing and policy compilation:
1. Traffic Replay Engine (pranor-gate replay)
Replay historical production traffic logs (.jsonl) against a WASM middleware module to evaluate performance and correctness before deploying:
pranor-gate replay \
--log traffic_log.jsonl \
--middleware auth_filter.wasm \
--output report.json
2. Policy-as-Code Compiler (pranor-gate policy compile)
Compile human-readable API security policy files (.policy) directly into WebAssembly modules:
pranor-gate policy compile rules.policy -o security_rules.wasm
Security
- OAuth2 Bearer token validation per route (JWKS-based)
- WASM sandbox isolation (no host syscall access by default)
- Prompt injection multi-layer detection (pattern matching + ML classifier)
- PII scrubbing before forwarding to external LLMs
Observability
- OpenTelemetry:
traceparentpropagation on all proxied requests; span per route, per WASM execution - Prometheus
/metrics: request rate, latency histograms, error rates, circuit breaker state, cache hit rates, AI cost counters - Pranor Console Inspector: Live route table, WASM module management, Swagger UI, AI cost dashboard, prompt guard violation log
Enterprise Edition
| Feature | Tier |
|---|---|
| FIPS 140-3 TLS & mTLS SPIFFE Engine | EE |
| Active-Active Global Edge Mesh & Anycast | EE |
| Kubernetes Gateway API v1 CRD Controller | EE |
| Enterprise AI Budget Guardrails | EE |
| Multi-Model Provider Fallback Chain | EE |
| AI Agent Session Context Tracker | EE |
| Tool Call Audit Log & Per-Session AI Cost Attribution | EE |
Pranor Pulse
docker run -p 9090:9090 ghcr.io/vyuvaraj/pranor-pulse:latest
Pranor Pulse is a full-featured, enterprise-grade message broker for the Pranor ecosystem. It supports server-side STOMP brokering, browser-local OPFS-backed queueing, multi-protocol adapters (Kafka wire, MQTT v5), and advanced security (FIPS 140-3, post-quantum cryptography, blind E2EE).
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Protocols Supported
- Browser / OPFS Features
- Security
- Observability
- Kubernetes & Distribution
- Getting Started
- Enterprise Edition
Key Features
📨 Core Broker
- STOMP 1.2 message broker: Topic/queue routing with fan-out, competing consumers, and durable subscriptions
- Exactly-once delivery semantics: Idempotent message IDs with deduplication window
- DLQ + Exponential Backoff Engine: Failed messages automatically moved to Dead Letter Queue with configurable retry policies; exponential backoff with jitter
- Point-in-time event replay: Replay messages from any historical offset on demand
- Schema Registry & Validation: Embedded schema registry for message contract enforcement (Avro/JSON Schema/Protobuf); schema evolution with compatibility checks
- Atomic Multi-Topic Transactions: ACID-style multi-topic publish/consume transactions
- Cooperative Consumer Rebalancing: Sticky partition assignment with graceful rebalance on consumer join/leave
🌐 Browser & OPFS (Local-First)
- OPFS Storage Driver (
pkg/opfs): Full browser-native persistent queue using Origin Private File System - WASM/JS FFI bindings (
@pranor/pulse-wasm): Use Pranor Pulse from the browser with a TypeScript SDK - SharedWorker multi-tab coordination: Single broker across all browser tabs via SharedWorker
- Multi-tab OPFS leader election:
navigator.locks-based lease protocol ensures only one tab acts as queue leader at a time - Client-side AES-256-GCM encryption at rest: Messages encrypted before writing to OPFS
- WebTransport HTTP/3 QUIC relay: Browser outbox relay over QUIC for low-latency connectivity
- Offline outbox & reconnect relay: Queue messages offline; auto-relay when connectivity restores
- Auto-compaction & quota manager: Automatic OPFS quota management with configurable size limits
- Client-side WASM stream filters: Run sandboxed WASM modules to transform/filter messages in-browser
- Persistent storage eviction safeguard: Priority-based eviction prevents silent data loss at storage limits
🗜️ Storage & Compaction
- Write-Ahead Log (WAL) with corruption recovery and CRC checksums
- Topic Log Compaction Policy Engine: Key-based compaction (retain only latest value per key), tombstone purging, TTL-based retention
- Tiered cloud storage offloading: Hot/warm/cold tier management with S3-compatible backend
- Automated storage tiering & compaction: Background compaction scheduler with configurable policies
📡 Protocol Adapters
- Kafka Wire Protocol Compatibility: Drop-in replacement for Kafka consumers/producers (Kafka binary protocol)
- MQTT v5.0 IoT Gateway: Full MQTT v5 adapter — QoS 0/1/2, retain, session persistence, will messages
🔁 Streaming & CDC
- Change Data Capture (CDC) Engine: Database change event streaming (row-level insert/update/delete events)
- Real-time Stream SQL Windowing: Tumbling, sliding, and session windows with aggregations (COUNT, SUM, AVG)
🏢 Multi-Tenant
- Multi-tenant VHosts & rate quotas: Isolated virtual hosts per tenant with per-tenant rate limits and storage quotas
- Zero-Trust OAuth2 & SPIFFE auth: Per-connection authentication with SPIFFE workload identity attestation
Architecture
┌─────────────────────────────────────────────────────────────┐
│ Pranor Pulse │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────────┐ │
│ │ STOMP Broker │ │ Kafka Compat │ │ MQTT v5 Gateway │ │
│ └──────┬───────┘ └──────┬───────┘ └────────┬─────────┘ │
│ └─────────────────┼──────────────────-─┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ Schema Registry & Validation │ │
│ └────────────────────────────┬───────────────────────────┘ │
│ ▼ │
│ ┌────────────────────────────────────────────────────────┐ │
│ │ WAL Storage Engine │ Compaction │ Tiered Offload │ │
│ └────────────────────────────────────────────────────────┘ │
│ │
│ ┌─────────────┐ ┌──────────────┐ ┌────────────────────┐ │
│ │ DLQ Engine │ │ CDC Streamer │ │ SQL Window Engine │ │
│ └─────────────┘ └──────────────┘ └────────────────────┘ │
└─────────────────────────────────────────────────────────────┘
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/topics | Create a topic |
GET | /api/v1/topics | List all topics |
POST | /api/v1/publish | Publish a message to a topic |
POST | /api/v1/subscribe | Subscribe to a topic (SSE or WebSocket) |
GET | /api/v1/consumers | List consumer groups |
GET | /api/v1/consumers/{group}/lag | Consumer group lag per partition |
POST | /api/v1/schemas | Register a message schema |
GET | /api/v1/schemas/{topic} | Get schema for a topic |
GET | /api/v1/dlq/{topic} | Browse DLQ for a topic |
POST | /api/v1/dlq/{topic}/replay | Replay DLQ messages |
POST | /api/v1/replay | Point-in-time replay from offset |
POST | /api/v1/compact/{topic} | Trigger log compaction for topic |
GET | /api/v1/transactions/{id} | Query atomic transaction status |
/metrics | GET | Prometheus metrics (per-topic lag, throughput, error rates) |
Protocols Supported
| Protocol | Transport | Notes |
|---|---|---|
| STOMP 1.2 | TCP / WebSocket | Primary protocol |
| Kafka Binary | TCP | Wire-compatible; use existing Kafka clients |
| MQTT v5.0 | TCP / WebSocket | IoT device support, QoS 0/1/2 |
| OPFS (browser) | WASM | Local-first browser queue |
| WebTransport | HTTP/3 QUIC | Browser outbox relay |
Browser / OPFS Features
Install the browser SDK:
npm install @pranor/pulse-wasm
import { Pranor Pulse } from '@pranor/pulse-wasm';
const queue = new Pranor Pulse({ encryption: 'aes-256-gcm' });
await queue.publish('orders', { id: 1, item: 'Widget' });
await queue.subscribe('orders', (msg) => console.log(msg));
// Auto-syncs to server when online; stores locally when offline
await queue.enableOfflineSync({ serverUrl: 'wss://queue.pranor.net' });
Security
| Feature | Description |
|---|---|
| FIPS 140-3 & HSM key unsealing | HSM-backed key management for regulated environments |
| Blind Broker E2EE | End-to-end encryption — broker never sees plaintext |
| Post-Quantum Hybrid Crypto (PQC) | X25519+Kyber hybrid key exchange |
| Tamper-Evident Merkle Audit Ledger | Append-only Merkle tree audit log for every message event |
| Inline WASM AI Guardrails | Sandboxed WASM interceptors on message payloads |
| Byzantine Fault Tolerant Consensus | BFT Raft variant for tamper-resistant cluster consensus |
| Zero-Trust OAuth2 & SPIFFE | Per-connection workload identity attestation |
| AES-256-GCM (OPFS) | Client-side encryption for browser-local messages |
Observability
- Prometheus
/metrics: Per-topic message rate, consumer lag, DLQ depth, compaction stats - OTel W3C Trace Context:
traceparentheader propagated per message through full pipeline - Pranor Console Queue Inspector: Live topic browser, consumer group lag dashboard, DLQ browser with one-click replay, schema registry browser
Kubernetes & Distribution
# Standalone daemon
pranor-pulsed --port 9090 --storage ./data --tls
# CLI
pranor-pulse publish orders '{"id": 1}'
pranor-pulse consume orders --group my-service
pranor pulse publish orders '{"id": 1}' # Pranor integration
# Kubernetes Operator
kubectl apply -f pranor-pulsecluster.yaml
# KEDA auto-scaling
kubectl apply -f keda-scaledobject.yaml # Scale consumers on lag
Multi-language client SDKs: Go, TypeScript/JS, Python, Rust, Java.
Cross-cloud active-active geo-replication with automated failover and conflict resolution.
Getting Started
docker run -p 9090:9090 \
-e PRANOR_PULSE_STORAGE_PATH=/data \
-e PRANOR_PULSE_OTEL_ENDPOINT=http://pranor-trace:4318 \
-v queue-data:/data \
ghcr.io/vyuvaraj/pranor-pulse:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_PULSE_PORT | 9090 | Listener port |
PRANOR_PULSE_STORAGE_PATH | ./data | WAL and segment storage directory |
PRANOR_PULSE_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
PRANOR_PULSE_S3_BUCKET | — | S3 bucket for tiered offloading |
PRANOR_PULSE_KAFKA_COMPAT | false | Enable Kafka wire protocol adapter |
PRANOR_PULSE_MQTT_PORT | — | MQTT listener port |
PRANOR_PULSE_FIPS | false | Enable FIPS 140-3 mode (EE) |
Enterprise Edition
| Feature | Tier |
|---|---|
| Geo-Replication across clouds | EE |
| Kafka Protocol Adapter | EE |
| FIPS 140-3 HSM & Sovereign Security | EE |
| Inline WASM AI Guardrails | EE |
| eBPF Kernel Bypass & XDP Acceleration | EE |
| Multi-Cloud Tiered Storage Compaction | EE |
| AWS EventBridge & Enterprise Webhooks Connector | EE |
| Multi-Cluster Kubernetes Federation | EE |
| SIMD/AVX-512 Vectorized Filter Engine | EE |
| Byzantine Fault Tolerant Consensus | EE |
| Post-Quantum Hybrid Cryptography | EE |
Pranor Vault
docker compose up -d
Pranor Vault is a high-performance, S3-compatible distributed object storage system for the Pranor ecosystem. It combines classical cloud storage (erasure coding, multi-region replication) with advanced capabilities: AI-native semantic vector search, browser-local OPFS sync, P2P chunk seeding, and Git-like bucket branching.
Quickstart (S3 & AI Vector Search in 30 Seconds)
1. Launch Pranor Vault Standalone Daemon & Admin Console
docker compose up -d
# S3 API listening at http://localhost:9000
# Admin Console UI listening at http://localhost:9001/ui/
2. Standard S3 Operations (via AWS S3 CLI or pranor-vault CLI)
export AWS_ACCESS_KEY_ID=minioadmin
export AWS_SECRET_ACCESS_KEY=minioadmin
# Create a bucket and upload a document via AWS CLI
aws s3 mb s3://knowledge --endpoint-url http://localhost:9000
aws s3 cp ./deploy/helm/pranor-vault/README.md s3://knowledge/deploy-guide.md --endpoint-url http://localhost:9000
# Or use the unified pranor-vault CLI
pranor-vault mb s3://knowledge
pranor-vault put knowledge deploy-guide.md ./deploy/helm/pranor-vault/README.md
pranor-vault ls knowledge
3. AI-Native Semantic Vector Search (End-to-End)
Text uploaded to Pranor Vault is automatically indexed and vectorized on PUT. Query semantically without external vector databases:
curl -X POST http://localhost:9000/api/v1/search/hybrid \
-H "Content-Type: application/json" \
-d '{
"bucket": "knowledge",
"query": "how to deploy helm chart to Kubernetes",
"k": 5
}'
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Unified CLI Reference
- Vector Search (AI-Native)
- Bucket Branching
- Browser / P2P
- Security
- Observability
- Getting Started & Docker Compose
- Enterprise Edition
Key Features
☁️ Core Object Storage
- 100% S3 Wire Protocol Compatibility: Drop-in replacement for AWS S3 — works with all existing S3 clients (aws-cli, boto3, aws-sdk-js, etc.)
- Erasure Coding (Reed-Solomon): Configurable data/parity shard ratios for space-efficient fault tolerance
- Standalone daemon (
pranor-vaultd): Production-ready daemon serving S3 API (:9000) and Admin Console (:9001) - Unified CLI (
pranor-vault): Single CLI for object storage management, IAM policies, and cluster administration - Multi-language client SDKs: Go, Python, TypeScript/JS, Rust
🔀 Tiering & Replication
- Multi-cloud S3 bucket tiering: Hot/warm/cold tier management — auto-migrate objects to cheaper storage tiers based on last-access time
- Cold archive mirroring: Mirror rarely-accessed objects to AWS Glacier, Azure Archive, or GCS Nearline
- Multi-region active-active CRDT replication: Conflict-free replicated data types for last-write-wins semantics across regions
- Cross-region active-active bucket replication: Sync buckets across cloud regions with configurable consistency guarantees
🤖 AI-Native Vector Search
- Automatic embedding generation: Text objects are automatically embedded on
PUTusing configurable embedding models - Hybrid keyword + vector semantic search (RRF): Reciprocal Rank Fusion combines BM25 keyword scores with vector similarity for optimal relevance
- Per-bucket vector index namespace management: Isolated vector index per bucket; configurable distance metrics (Cosine, Euclidean, DotProduct)
- ANN query API:
k-nearest-neighbor queries with min-score filtering, metadata filters, and hybrid mode - Persistent mmap-backed HNSW graph engine: High-performance Hierarchical Navigable Small World graph with incremental node insertion and mmap persistence for zero-copy access
🌿 Bucket Branching (Git-like)
- Copy-on-Write (CoW) virtual metadata pointer engine: Branch a bucket in O(1) — no data copy; branches share storage until modified
- Bucket branch diff & merge:
pranor-vault diff branch-a branch-bshows changed objects; merge branches with conflict resolution - Isolated virtual namespace router: Each branch gets its own S3-compatible namespace; branches are fully isolated
- REST API:
POST /api/v1/buckets/{name}/branch,POST /api/v1/buckets/{name}/merge - CLI:
pranor-vault branch create,pranor-vault branch diff,pranor-vault branch merge
🌐 Browser & P2P
- OPFS local sync (
@pranor/store-wasm): Browser-local object storage using Origin Private File System; syncs to server when online - WebTorrent P2P chunk seeder: Seed object chunks via WebTorrent — reduce CDN egress costs
- WebRTC peer signaling relay: Broker WebRTC connections between peers for direct chunk transfer
- P2P SHA-256 integrity verification: All chunks verified cryptographically before acceptance
🔍 S3 Select
- S3 Select engine: Query CSV, JSON, and Parquet objects with SQL expressions without downloading entire objects
Architecture
┌────────────────────────────────────────────────────────────┐
│ Pranor Vault │
│ │
│ ┌─────────────────────────────────────────────────────┐ │
│ │ S3 Wire Protocol Router │ │
│ │ GET/PUT/DELETE/LIST/SELECT compatible with AWS S3 │ │
│ └───────────────────────┬─────────────────────────────┘ │
│ │ │
│ ┌────────────┐ ┌────────▼──────┐ ┌────────────────┐ │
│ │ CoW Branch │ │ Object Store │ │ Vector Index │ │
│ │ Namespaces│ │ (Reed-Solomon│ │ (HNSW + RRF) │ │
│ └────────────┘ │ Erasure) │ └────────────────┘ │
│ └───────┬───────┘ │
│ ┌────────────┐ ┌───────▼───────┐ ┌────────────────┐ │
│ │ S3 Select│ │ Tiered Store │ │ CRDT Repl. │ │
│ │ Engine │ │ Hot/Warm/Cold│ │ Multi-Region │ │
│ └────────────┘ └───────────────┘ └────────────────┘ │
│ │
│ ┌────────────────────────────────────────────────────┐ │
│ │ P2P / OPFS / WebRTC Layer (Browser) │ │
│ └────────────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────────────┘
API Endpoints
S3 Compatible (use any S3 client)
| Method | Path | Description |
|---|---|---|
PUT | /{bucket}/{key} | Upload object (triggers auto-embedding if text) |
GET | /{bucket}/{key} | Download object |
DELETE | /{bucket}/{key} | Delete object |
GET | /{bucket}?list-type=2 | List objects in bucket |
POST | /{bucket}/{key}?select | S3 Select query (CSV/JSON/Parquet) |
Pranor Vault-Specific APIs
| Method | Path | Description |
|---|---|---|
POST | /api/v1/buckets | Create bucket |
POST | /api/v1/buckets/{name}/branch | Create a CoW branch |
POST | /api/v1/buckets/{name}/merge | Merge a branch back |
GET | /api/v1/buckets/{name}/diff | Diff two branches |
POST | /api/v1/search/vector | Vector ANN search |
POST | /api/v1/search/hybrid | Hybrid keyword+vector search (RRF) |
GET | /api/v1/search/namespaces | List vector index namespaces per bucket |
GET | /api/v1/tiers/{bucket}/policy | Get tiering policy |
PUT | /api/v1/tiers/{bucket}/policy | Set tiering policy |
/metrics | GET | Prometheus metrics |
Unified CLI Reference (pranor-vault)
Pranor Vault ships a single, unified CLI tool (pranor-vault) that connects to both the S3 API endpoint and the Admin management API:
# Global flags
pranor-vault --endpoint http://localhost:9000 --admin-endpoint http://localhost:9001 <command>
# S3 & Data Management
pranor-vault mb s3://my-bucket # Make bucket
pranor-vault rb s3://my-bucket # Remove bucket
pranor-vault ls s3://my-bucket # List bucket contents
pranor-vault put my-bucket photo.jpg ./photo.jpg # Upload object
pranor-vault get my-bucket photo.jpg ./dest.jpg # Download object
pranor-vault rm my-bucket photo.jpg # Delete object
pranor-vault lock my-bucket photo.jpg 30d # WORM Object Lock (30 days)
# Admin & Server Health
pranor-vault status # Daemon status & uptime
pranor-vault admin-buckets # List buckets via Admin API
Vector Search (AI-Native)
Objects uploaded to enabled buckets are automatically embedded:
# Upload a text document — embedding generated automatically
aws s3 cp docs/manual.txt s3://my-bucket/manual.txt \
--endpoint-url http://pranor-vault:7070
# Hybrid search (keyword + vector, RRF combined)
curl -X POST http://pranor-vault:7070/api/v1/search/hybrid \
-d '{"bucket": "my-bucket", "query": "installation guide", "k": 5, "metric": "cosine"}'
# Pure vector ANN search
curl -X POST http://pranor-vault:7070/api/v1/search/vector \
-d '{"bucket": "my-bucket", "vector": [0.12, -0.34, ...], "k": 10, "min_score": 0.8}'
Vector Index Configuration
{
"bucket": "my-bucket",
"vector_index": {
"enabled": true,
"embedding_model": "text-embedding-3-small",
"dimensions": 1536,
"metric": "cosine",
"hnsw": { "m": 16, "ef_construction": 200 }
}
}
Bucket Branching
# Create a branch (instant, no data copy)
pranor-vault branch create my-bucket --name feature-x
# Make changes to the branch
aws s3 cp new-file.txt s3://my-bucket@feature-x/new-file.txt
# Diff branch vs main
pranor-vault branch diff my-bucket feature-x
# Merge branch back
pranor-vault branch merge my-bucket --source feature-x --into main
Browser / P2P
npm install @pranor/store-wasm
import { Pranor Vault } from '@pranor/store-wasm';
const store = new Pranor Vault({ bucket: 'my-bucket', syncUrl: 'https://store.pranor.net' });
// Works offline via OPFS
await store.put('key', new Uint8Array([1, 2, 3]));
const data = await store.get('key');
// P2P chunk seeding (reduces server egress)
await store.enableP2PSeed({ torrentTracker: 'wss://tracker.pranor.net' });
Security
| Feature | Description |
|---|---|
| Blind-Store E2EE | Client-side encryption; server never sees plaintext |
| FIPS 140-3 + HSM Key Unsealing | Hardware security module key management |
| WORM Object Lock | Write-Once-Read-Many immutable objects |
| Merkle Immutability Ledger | Tamper-evident audit chain for every object write |
| io_uring + Direct I/O | Bypasses page cache for NVMe-level throughput (EE) |
Observability
- Prometheus
/metrics: Object throughput, IOPS, cache hit rates, vector index query latency, tiering migration stats - OTel tracing: Per-request spans for upload, download, search, and compaction operations
- Pranor Console Inspector: Bucket browser, vector index namespace management, tiering policy editor
aws s3 cp myfile.txt s3://my-bucket/ --endpoint-url http://localhost:7070
### Environment Variables
| Variable | Default | Description |
|----------|---------|-------------|
| `PRANOR_VAULT_PORT` | `7070` | HTTP listener port |
| `PRANOR_VAULT_DATA_DIR` | `./data` | Object storage root directory |
| `PRANOR_VAULT_ERASURE_DATA_SHARDS` | `6` | Reed-Solomon data shards |
| `PRANOR_VAULT_ERASURE_PARITY_SHARDS` | `2` | Reed-Solomon parity shards |
| `PRANOR_VAULT_VECTOR_ENABLED` | `false` | Enable auto-embedding & HNSW index |
| `PRANOR_VAULT_EMBEDDING_MODEL` | — | Embedding model endpoint URL |
| `PRANOR_VAULT_OTEL_ENDPOINT` | — | OpenTelemetry collector URL |
| `PRANOR_VAULT_S3_TIER_COLD_URL` | — | Cold tier S3 endpoint |
---
## Enterprise Edition
| Feature | Tier |
|---------|------|
| Blind-Store E2EE & FIPS HSM | EE |
| Cross-Region Active-Active Replication | EE |
| io_uring & Direct I/O NVMe Acceleration | EE |
| WORM Object Lock & Merkle Ledger | EE |
| Enterprise Multi-Tenant CoW Encryption | EE |
| Enterprise P2P Token-Gated Content DRM | EE |
Pranor Chrono
docker run -p 8085:8085 ghcr.io/vyuvaraj/pranor-chrono:latest
Pranor Chrono is the distributed, fault-tolerant job scheduling service for the Pranor ecosystem. It supports interval and cron scheduling, exactly-once semantics, DAG job chaining, Pranor cron-as-code declarations, persistent S3 job registries, and full OTel tracing.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Scheduling Expressions
- DAG Job Chaining
- Cron-as-Code (Pranor)
- Getting Started
Key Features
⏰ Core Scheduling
- Interval & cron execution: Run jobs at fixed intervals (e.g.,
10s,5m,2h) or standard 5-field cron patterns (e.g.,0 9 * * 1-5for weekdays at 9 AM) - Exactly-once scheduling semantics: Distributed Redis-based leader election ensures only one node fires each scheduled job, even across a cluster
- Dynamic load balancing: Distributes job execution slots across active cluster nodes
🔗 DAG Job Chaining
- Multi-step job graphs: Define jobs with dependency constraints —
job-conly runs afterjob-aANDjob-bsucceed - Topological sort execution: Automatically resolves execution order from the dependency graph
- Fan-out / fan-in patterns: Parallelize independent steps, then synchronize at a join step
🔁 Retry Policies
- Configurable retry count: Per-job max retry attempts
- Backoff strategies: Fixed, linear, or exponential backoff between retries
- Jitter: Randomized jitter on backoff to prevent thundering herds
- Dead-letter after exhaustion: After all retries fail, job moves to a dead-letter audit record
📋 Cron-as-Code (Pranor)
- Define jobs in
.pnrfiles: Declare scheduled jobs using Pranorcronandeverysyntax - Version control your schedules: Job definitions live alongside application code
- Hot-reload: Pranor Chrono watches
.pnrfiles for changes and automatically re-registers modified jobs
💾 Persistence
- Persistent job registry to Pranor Vault S3: Job definitions serialized to
jobs.jsonin a Pranor Vault bucket — survive node restarts - Execution audit history: Every job execution is logged to
audit/<jobID>_<timestamp>.json(execution time, duration, response status, response body) - Automatic restore on startup: Reloads all job definitions from S3 on node boot
🔭 Observability
- OTel tracing: Client spans for every job trigger;
traceparentheader propagated to downstream callback HTTP requests - Prometheus metrics: Job fire rate, success/failure counters, execution duration histograms
- Execution history API: Query past executions for any job
Architecture
┌─────────────────────────────────────────────────────────┐
│ Pranor Chrono │
│ │
│ ┌───────────────────────────────────────────────────┐ │
│ │ Scheduler (interval + cron expression evaluator) │ │
│ └────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼──────────────────────────────┐ │
│ │ Leader Election (Redis-based distributed lock) │ │
│ │ → only one node fires each job per tick │ │
│ └────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼──────────────────────────────┐ │
│ │ DAG Runner (topological sort + fan-out/join) │ │
│ └────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼──────────────────────────────┐ │
│ │ HTTP Callback Dispatcher (with traceparent) │ │
│ └────────────────────┬──────────────────────────────┘ │
│ │ │
│ ┌────────────────────▼──────────────────────────────┐ │
│ │ Retry Engine + Audit Log (→ Pranor Vault S3) │ │
│ └───────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────┘
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/jobs | Create a scheduled job |
GET | /api/v1/jobs | List all jobs |
GET | /api/v1/jobs/{id} | Get job definition and status |
PUT | /api/v1/jobs/{id} | Update a job |
DELETE | /api/v1/jobs/{id} | Delete a job |
POST | /api/v1/jobs/{id}/run | Trigger a job manually |
GET | /api/v1/jobs/{id}/history | Execution history for a job |
POST | /api/v1/dag | Define a DAG job chain |
GET | /api/v1/dag/{id} | Get DAG execution state |
/metrics | GET | Prometheus metrics |
/healthz | GET | Liveness probe |
Scheduling Expressions
# Every 30 seconds
curl -X POST http://pranor-chrono:8085/api/v1/jobs \
-d '{"name": "health-check", "schedule": "30s", "callback_url": "http://myapp/health", "retry": {"max": 3, "backoff": "exponential"}}'
# Every weekday at 9 AM (cron)
curl -X POST http://pranor-chrono:8085/api/v1/jobs \
-d '{"name": "daily-report", "schedule": "0 9 * * 1-5", "callback_url": "http://myapp/reports/daily"}'
# Every hour
curl -X POST http://pranor-chrono:8085/api/v1/jobs \
-d '{"name": "cache-warmer", "schedule": "1h", "callback_url": "http://myapp/cache/warm"}'
DAG Job Chaining
curl -X POST http://pranor-chrono:8085/api/v1/dag \
-d '{
"name": "nightly-pipeline",
"schedule": "0 2 * * *",
"steps": [
{ "id": "extract", "callback_url": "http://etl/extract", "depends_on": [] },
{ "id": "transform", "callback_url": "http://etl/transform", "depends_on": ["extract"] },
{ "id": "load-a", "callback_url": "http://etl/load/warehouse", "depends_on": ["transform"] },
{ "id": "load-b", "callback_url": "http://etl/load/reporting", "depends_on": ["transform"] },
{ "id": "notify", "callback_url": "http://notify/done", "depends_on": ["load-a", "load-b"] }
]
}'
This runs extract → transform → load-a and load-b in parallel → notify.
Cron-as-Code (Pranor)
Define jobs in a .pnr file alongside your application code:
// jobs.pnr
cron "daily-report" at "0 9 * * 1-5" {
call POST "http://myapp/reports/daily"
}
every 30s "health-check" {
call GET "http://myapp/health"
retry max=3 backoff=exponential
}
Pranor Chrono auto-reloads job definitions when .pnr files change.
Getting Started
docker run -p 8085:8085 \
-e PRANOR_CHRONO_REDIS_URL=redis://redis:6379 \
-e PRANOR_CHRONO_PRANOR_VAULT_BUCKET=pranor-chrono-jobs \
-e PRANOR_CHRONO_PRANOR_VAULT_URL=http://pranor-vault:7070 \
-e PRANOR_CHRONO_OTEL_ENDPOINT=http://pranor-trace:4318 \
ghcr.io/vyuvaraj/pranor-chrono:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_CHRONO_PORT | 8085 | HTTP listener port |
PRANOR_CHRONO_REDIS_URL | — | Redis URL for distributed leader election |
PRANOR_CHRONO_PRANOR_VAULT_URL | — | Pranor Vault URL for job persistence |
PRANOR_CHRONO_PRANOR_VAULT_BUCKET | pranor-chrono-jobs | S3 bucket name for job registry |
PRANOR_CHRONO_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
PRANOR_CHRONO_PRANOR_FILES_DIR | — | Directory to watch for .pnr job definitions |
Pranor Auth
# 5-Minute Auth Quickstart
curl -X POST http://localhost:8086/api/auth/register -d '{"username":"dev","password":"secretpassword"}'
curl -X POST http://localhost:8086/api/auth/login -d '{"username":"dev","password":"secretpassword"}'
# → Returns JWT token; pass header 'Authorization: Bearer <token>' to protected APIs
docker run -p 8086:8086 ghcr.io/vyuvaraj/pranor-auth:latest
Pranor Auth is the authentication and authorization service for the Pranor ecosystem. It provides passkey/WebAuthn login, adaptive MFA, OAuth2/OIDC provider functionality, JWT issuance and rotation, RBAC, and seamless integration with Pranor Gate for API-level enforcement.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Passkeys & WebAuthn
- MFA & Adaptive Step-Up
- JWT & OAuth2/OIDC
- RBAC
- Pranor Gate Integration
- Getting Started
Key Features
🔑 Passkeys & WebAuthn (FIDO2)
- Passkey registration: Register hardware security keys, biometric authenticators (Face ID, Touch ID, Windows Hello), and platform authenticators
- WebAuthn authentication: Full FIDO2/WebAuthn ceremony — challenge/response with attestation verification
- Cross-device passkeys: Synced passkeys via cloud keychains (iCloud Keychain, Google Password Manager)
- Passkey management: List, rename, and revoke registered passkeys per user
🔐 Session Management
- Secure session tokens: Cryptographically signed session tokens with configurable expiry
- Automatic token rotation: Sessions are silently rotated on each request within the rotation window — reduces token theft risk
- Session invalidation: Immediately invalidate all sessions for a user (e.g., on password change or security alert)
- Device session tracking: Track active sessions per device with last-seen timestamps
📱 Multi-Factor Authentication (MFA)
- TOTP (Time-based OTP): Standard RFC 6238 TOTP — compatible with Google Authenticator, Authy, 1Password
- SMS OTP: Send one-time codes via SMS (configurable SMS provider)
- Email OTP: Send one-time codes via email (integrates with
Pranor Notify) - Backup codes: Generate and manage one-time recovery backup codes
- MFA enforcement policies: Enforce MFA per user group, per role, or per app
🎯 Adaptive MFA Step-Up (EE)
- Risk-based authentication: Dynamically require additional MFA factors based on risk signals (new device, unusual location, high-value transaction)
- Configurable risk rules: Define risk scoring rules (IP reputation, device fingerprint, behavioral anomaly)
- Step-up on demand: Applications can request MFA step-up mid-session for sensitive operations
🌐 OAuth2 & OIDC Provider
- OAuth2 authorization server: Full OAuth2 flow support — Authorization Code (with PKCE), Client Credentials, Refresh Token
- OIDC identity provider: OpenID Connect 1.0 — issues ID tokens with standard claims (
sub,email,name,picture) - JWKS endpoint: Standard
/.well-known/jwks.jsonfor token verification by downstream services - Dynamic client registration: Register OAuth2 clients via API
- Scope management: Define custom scopes and map to RBAC roles
🎫 JWT Issuance & Validation
- JWT issuance: RS256/ES256 signed JWTs with configurable claims and expiry
- JWT rotation: Automatic signing key rotation with JWKS rollover period — zero-downtime key rotation
- Token introspection: RFC 7662 token introspection endpoint
- Token revocation: RFC 7009 token revocation — immediately invalidate any issued token
🏷️ Role-Based Access Control (RBAC)
- Role definitions: Create hierarchical roles with inheritance (e.g.,
admin→editor→viewer) - Permission assignment: Assign granular permissions (e.g.,
orders:read,orders:write) to roles - User-role binding: Assign roles to users, groups, or OAuth2 clients
- Policy enforcement: Pranor Auth validates role/permission on every API call when integrated with Pranor Gate
Architecture
Client (Browser/App)
│
├── Passkey Auth (WebAuthn ceremony)
├── MFA Challenge (TOTP / SMS / Email)
├── OAuth2 Authorization Code (PKCE)
│
▼
┌──────────────────────────────────────────────┐
│ Pranor Auth │
│ │
│ ┌───────────────┐ ┌──────────────────────┐ │
│ │ WebAuthn │ │ Session Manager │ │
│ │ FIDO2 Engine │ │ (rotate + track) │ │
│ └───────────────┘ └──────────────────────┘ │
│ │
│ ┌───────────────┐ ┌──────────────────────┐ │
│ │ MFA Engine │ │ JWT / OIDC Provider │ │
│ │ TOTP/SMS/OTP │ │ RS256 + JWKS │ │
│ └───────────────┘ └──────────────────────┘ │
│ │
│ ┌───────────────────────────────────────┐ │
│ │ RBAC Engine (roles + permissions) │ │
│ └───────────────────────────────────────┘ │
└──────────────────────────────────────────────┘
│
└── Pranor Gate (enforces JWT + RBAC per route)
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/auth/passkey/register/begin | Begin passkey registration (get challenge) |
POST | /api/v1/auth/passkey/register/finish | Complete passkey registration |
POST | /api/v1/auth/passkey/login/begin | Begin passkey authentication (get challenge) |
POST | /api/v1/auth/passkey/login/finish | Complete passkey authentication |
POST | /api/v1/auth/mfa/setup | Set up MFA for a user |
POST | /api/v1/auth/mfa/verify | Verify an MFA code |
POST | /api/v1/auth/mfa/step-up | Request MFA step-up (adaptive) |
POST | /api/v1/auth/token | OAuth2 token endpoint |
GET | /api/v1/auth/authorize | OAuth2 authorization endpoint |
GET | /.well-known/openid-configuration | OIDC discovery document |
GET | /.well-known/jwks.json | JSON Web Key Set for token verification |
POST | /api/v1/auth/token/introspect | RFC 7662 token introspection |
POST | /api/v1/auth/token/revoke | RFC 7009 token revocation |
POST | /api/v1/sessions/invalidate | Invalidate all sessions for a user |
GET | /api/v1/sessions | List active sessions for a user |
POST | /api/v1/rbac/roles | Create a role |
GET | /api/v1/rbac/roles | List roles |
POST | /api/v1/rbac/roles/{role}/permissions | Assign permissions to a role |
POST | /api/v1/rbac/users/{id}/roles | Assign roles to a user |
/healthz | GET | Liveness probe |
Passkeys & WebAuthn
// Browser: Begin registration
const { challenge } = await fetch('/api/v1/auth/passkey/register/begin', {
method: 'POST', body: JSON.stringify({ user_id: 'user-123' })
}).then(r => r.json());
const credential = await navigator.credentials.create({ publicKey: challenge });
// Finish registration
await fetch('/api/v1/auth/passkey/register/finish', {
method: 'POST', body: JSON.stringify(credential)
});
JWT & OAuth2/OIDC
Configure Pranor Gate to verify Pranor Auth JWTs:
{
"routes": [{
"prefix": "/api/orders",
"target": "http://orders:3000",
"auth": {
"type": "bearer",
"jwks_url": "http://pranor-auth:8086/.well-known/jwks.json",
"required_scope": "orders:read"
}
}]
}
RBAC
# Create roles
curl -X POST http://pranor-auth:8086/api/v1/rbac/roles \
-d '{"name": "admin", "permissions": ["orders:read", "orders:write", "orders:delete"]}'
# Assign role to user
curl -X POST http://pranor-auth:8086/api/v1/rbac/users/user-123/roles \
-d '{"roles": ["admin"]}'
Getting Started
docker run -p 8086:8086 \
-e PRANOR_AUTH_JWT_SECRET=my-rsa-key.pem \
-e PRANOR_AUTH_SESSION_SECRET=32-byte-random-secret \
-e PRANOR_AUTH_PRANOR_NOTIFY_URL=http://pranor-notify:8091 \
-e PRANOR_AUTH_OTEL_ENDPOINT=http://pranor-trace:4318 \
ghcr.io/vyuvaraj/pranor-auth:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_AUTH_PORT | 8086 | HTTP listener port |
PRANOR_AUTH_JWT_ALGORITHM | RS256 | JWT signing algorithm (RS256 or ES256) |
PRANOR_AUTH_JWT_KEY_PATH | — | Path to RSA/EC private key for JWT signing |
PRANOR_AUTH_SESSION_SECRET | — | 32-byte secret for session token signing |
PRANOR_AUTH_MFA_TOTP_ISSUER | Pranor | TOTP issuer name shown in authenticator apps |
PRANOR_AUTH_PRANOR_NOTIFY_URL | — | Pranor Notify URL for email OTP delivery |
PRANOR_AUTH_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
Enterprise Edition (Planned)
| Feature | Tier |
|---|---|
| Adaptive Risk-Based MFA Step-Up Engine | EE |
| Device Fingerprinting & Trusted Device Registry | EE |
| Per-Tenant OIDC Provider Federation (Okta, Azure AD, Google Workspace) | EE |
Pranor Cache
docker run -p 8084:8084 ghcr.io/vyuvaraj/pranor-cache:latest
Pranor Cache is the distributed, high-performance caching service for the Pranor ecosystem. It exposes a low-latency REST API backed by pluggable engines (in-memory or Redis) with native support for OpenTelemetry context propagation, read-through/write-behind database synchronisation, key pattern invalidation, and multi-region replication.
Features
- Pluggable Engines: Swap transparently between thread-safe local in-memory storage and high-throughput Redis/Valkey clusters.
- TTL Eviction: Automatic, background time-based pruning of expired cache keys.
- Key Pattern Invalidation: Delete matching keys dynamically via wildcards and prefix matching.
- Read-Through Cache: Cache misses automatically load data from a backend database (
PRANOR_CACHE_BACKEND_DB) and populate the cache. - Write-Behind Cache: Writes asynchronously update the backend database in the background to ensure eventually consistent writes without blocking clients.
- Multi-Region Replication: Forward mutations asynchronously to peer cache nodes (
PRANOR_CACHE_PEERS) to maintain global cache consistency. - OTel Instrumentation: Standardized hit/miss/latency metrics automatically exported via OTel tracing context.
API Endpoints
1. Health Checks
GET /health- Health probe showing cache readiness and connection status.
2. Cache Operations
Set Cache Entry
- Path:
POST /api/cache - Headers:
Content-Type: application/json - Body:
(TTL uses standard Go duration strings like{ "key": "user:101", "value": { "name": "Alice", "role": "admin" }, "ttl": "5m" }10s,5m,1h)
Get Cache Entry
- Path:
GET /api/cache/{key} - Response (200 OK):
{ "key": "user:101", "value": { "name": "Alice", "role": "admin" } } - Response (404 Not Found): If key doesn't exist (and no database read-through is configured/succeeds).
Delete Cache Entry
- Path:
DELETE /api/cache/{key}
Clear Cache / Invalidate Pattern
- Path:
DELETE /api/cache - Query Parameters:
pattern(Optional) - Wildcard pattern matching keys to delete (e.g.user:*). If omitted, fully clears the cache.replicated(Internal) - Used by peer nodes to denote replication loops.
Configuration (Environment Variables)
Configure Pranor Cache dynamically by setting these parameters at startup:
| Variable | Description | Default |
|---|---|---|
PORT | HTTP Server port | 8088 |
REDIS_URL | Redis cluster URL (e.g. redis://localhost:6379). Uses in-memory engine if unset. | (In-Memory) |
PRANOR_CACHE_BACKEND_DB | Endpoint URL of the backend database for read-through & write-behind sync. | (Disabled) |
PRANOR_CACHE_PEERS | Comma-separated URLs of peer Pranor Cache nodes to replicate mutations (e.g. http://peer1:8088,http://peer2:8088). | (Disabled) |
Running Locally
1. In-Memory Mode
go run main.go --addr :8088
2. Redis Mode
go run main.go --addr :8088 --redis-url redis://localhost:6379
3. Verification Suite
Run integration and unit tests:
go test -v ./...
Use Without Pranor (Standalone Quickstart)
Pranor Cache can be used as a standalone HTTP memory caching microservice (Redis alternative for development):
-
Run Pranor Cache in standalone mode (uses in-memory engine by default):
go run main.go --standalone --addr :8084 -
Set a cache entry (with a 5-minute TTL):
curl -X POST http://localhost:8084/api/cache \ -H "Content-Type: application/json" \ -d '{"key": "my-key", "value": "my-cached-payload", "ttl": "5m"}' -
Retrieve the cache entry:
curl http://localhost:8084/api/cache/my-key -
Delete the cache entry:
curl -X DELETE http://localhost:8084/api/cache/my-key
Pranor Mesh
docker run -p 8095:8095 ghcr.io/vyuvaraj/pranor-mesh:latest
Pranor Mesh is the intelligent service mesh for the Pranor ecosystem, providing latency-aware load balancing, distributed rate limiting, live topology telemetry, and chaos fault injection — all without requiring sidecar proxies.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Load Balancing
- Rate Limiting
- Chaos Fault Injection
- Getting Started
Key Features
⚖️ Load Balancing
- Latency-aware Power-of-Two-Choices (P2C): On each routing decision, sample two random backends and pick the one with lower observed latency — dramatically reduces tail latency compared to round-robin
- Locality preference: Prefer backends in the same availability zone/region before spilling over to remote nodes; configurable locality weight
- Health-aware routing: Unhealthy backends are automatically excluded; exponential recovery probing
🚦 Distributed Rate Limiting
- Global rate limiting via Pranor Cache token buckets: Rate limit counters stored in Pranor Cache — all mesh nodes share state for true global enforcement (not per-node)
- Per-service and per-route policies: Define separate rate limits per service, per endpoint pattern
- Burst control: Token bucket allows short bursts above sustained rate
🗺️ Live Topology Telemetry
- Real-time service topology graph: Pranor Mesh tracks all observed service-to-service call edges and pushes live updates to Pranor Console via WebSocket
- Traffic flow visualization: Annotates edges with RPS, error rate, and p99 latency in real-time
- Dependency discovery: Automatically discovers service dependencies without manual configuration
💥 Chaos Fault Injection
- Latency injection: Add artificial delay (configurable distribution: fixed, uniform, normal) to selected service calls
- Error rate simulation: Inject synthetic HTTP errors (configurable status code and percentage)
- Network partition simulation: Block traffic between specified service pairs
- Abort experiments: Immediately restore normal traffic flow; auto-expiry on configured duration
- Blast radius preview: Preview which service pairs are affected before triggering
Architecture
Service A ──→ Pranor Mesh Router ──→ Service B (selected by P2C)
│
├── Pranor Cache (distributed rate limit counters)
├── Chaos Engine (inject faults)
└── Topology Emitter (→ Pranor Console WebSocket)
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/services | Register a service endpoint |
GET | /api/v1/services | List all registered services |
POST | /api/v1/route | Route a request (P2C selection) |
GET | /api/v1/topology | Current topology graph snapshot |
POST | /api/v1/ratelimit/policy | Set rate limit policy for a service |
GET | /api/v1/ratelimit/policy | List rate limit policies |
POST | /api/v1/chaos/inject | Inject a chaos fault |
POST | /api/v1/chaos/abort/{id} | Abort an active chaos fault |
GET | /api/v1/chaos/active | List active chaos faults |
/metrics | GET | Prometheus metrics (routing decisions, rate limit hits, fault injection events) |
/healthz | GET | Liveness probe |
Load Balancing
# Register backends for a service
curl -X POST http://pranor-mesh:8095/api/v1/services \
-d '{"name": "orders-api", "endpoints": ["http://orders-1:3000", "http://orders-2:3000", "http://orders-3:3000"], "locality_zone": "us-east-1a"}'
# Route a request (pranor-mesh selects backend via P2C)
curl -X POST http://pranor-mesh:8095/api/v1/route \
-d '{"service": "orders-api", "caller_zone": "us-east-1a"}'
# → { "selected_endpoint": "http://orders-2:3000", "latency_p99_ms": 12 }
Rate Limiting
# Set global rate limit for a service
curl -X POST http://pranor-mesh:8095/api/v1/ratelimit/policy \
-d '{"service": "orders-api", "requests_per_second": 500, "burst": 1000}'
Pranor Mesh uses Pranor Cache token buckets — the rate limit is enforced globally across all Pranor Mesh nodes:
Node 1 ──┐
Node 2 ──┼──→ Pranor Cache token bucket ──→ allow/deny
Node 3 ──┘ (shared global counter)
Chaos Fault Injection
# Inject 200ms latency into 30% of calls to payments-api
curl -X POST http://pranor-mesh:8095/api/v1/chaos/inject \
-d '{
"target_service": "payments-api",
"fault_type": "latency",
"latency_ms": 200,
"percentage": 30,
"duration": "5m"
}'
# Inject 5% HTTP 503 errors
curl -X POST http://pranor-mesh:8095/api/v1/chaos/inject \
-d '{"target_service": "inventory-api", "fault_type": "error", "error_code": 503, "percentage": 5, "duration": "2m"}'
# Abort an experiment
curl -X POST http://pranor-mesh:8095/api/v1/chaos/abort/exp-123
Getting Started
docker run -p 8095:8095 \
-e PRANOR_MESH_PRANOR_CACHE_URL=http://pranor-cache:6379 \
-e PRANOR_MESH_PRANOR_CONSOLE_WS_URL=ws://pranor-console:8083/ws/topology \
-e PRANOR_MESH_OTEL_ENDPOINT=http://pranor-trace:4318 \
ghcr.io/vyuvaraj/pranor-mesh:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_MESH_PORT | 8095 | HTTP listener port |
PRANOR_MESH_PRANOR_CACHE_URL | — | Pranor Cache URL for distributed rate limit state |
PRANOR_MESH_PRANOR_CONSOLE_WS_URL | — | Pranor Console WebSocket URL for topology push |
PRANOR_MESH_LOCALITY_ZONE | — | Availability zone for locality-preference routing |
PRANOR_MESH_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
Enterprise Edition (Planned)
| Feature | Tier |
|---|---|
| Automatic WireGuard Kernel Tunnel Mesh | EE |
| SPIFFE/SPIRE mTLS Workload Identity Attestation | EE |
Pranor Trace
docker run -p 8090:8090 ghcr.io/vyuvaraj/pranor-trace:latest
Pranor Trace is the distributed tracing and continuous profiling service for the Pranor ecosystem. It ingests OTLP-format traces, assembles waterfall hierarchies, provides SLO burn rate alerting, and delivers eBPF-powered flamegraph profiling with automatic OTel correlation.
Table of Contents
Key Features
📡 OTLP Ingestion & Span Assembly
- OTLP/HTTP ingestion: Standard
/v1/tracesendpoint compatible with all OpenTelemetry SDKs and collectors - Trace reassembly: Groups spans by trace ID, links parent-child relationships, calculates absolute and relative duration offsets
- Waterfall hierarchy tree: Full span waterfall with nested children, duration bars, and critical path highlighting
- Configurable in-memory store: Thread-safe store with oldest-first trace eviction at configurable capacity
🔥 eBPF Flamegraph Profiling
- Continuous eBPF CPU & memory profiler: Kernel-level profiling via eBPF — no code instrumentation required
- OTel trace-to-flamegraph correlator: Automatically correlates a slow trace span to the flamegraph profile captured during that span's execution window
- In-browser flamegraph visualization: Interactive flamegraph rendered in Pranor Console — click to zoom, search symbol names
📊 SLO & Error Budget
- SLO burn rate alert engine: Configurable SLO targets (e.g. 99.9% availability) with dual burn rate windows
- Fast burn window (1h): Catches sudden spikes consuming error budget rapidly
- Slow burn window (6h/24h): Catches gradual degradation
- Error budget tracking: Real-time remaining error budget per service per SLO definition
- Pranor Console integration: Live SLO burn rate dashboard with alert status
📈 Prometheus Exemplars
- Exemplar-linked OpenMetrics generator: Produces Prometheus-compatible OpenMetrics text with
# TYPE/# UNITannotations and trace exemplar links embedded in histogram observations
🗺️ Distributed Dependency Analysis
- Critical path analyzer: Identifies the longest-latency path across a distributed trace — pinpoints bottleneck services
- Distributed dependency map: Builds a service-call graph from observed trace data; visualized in Pranor Console topology view
Architecture
OTLP SDK (Go/Python/JS/...)
│ POST /v1/traces
▼
┌──────────────────────────────────────────┐
│ Pranor Trace │
│ │
│ ┌────────────────────────────────────┐ │
│ │ Span Ingestion & Reassembly │ │
│ │ (Group by TraceID, Link parents) │ │
│ └─────────────┬──────────────────────┘ │
│ │ │
│ ┌─────────────▼──────────────────────┐ │
│ │ In-Memory Trace Store (evicting) │ │
│ └─────────────┬──────────────────────┘ │
│ │ │
│ ┌─────────────▼──────────────────────┐ │
│ │ Query Engine │ │
│ │ Waterfall │ Critical Path │ Deps │ │
│ └────────────────────────────────────┘ │
│ │
│ ┌─────────────────────┐ ┌───────────┐ │
│ │ eBPF Flamegraph │ │ SLO Burn │ │
│ │ Profiler + Correlat│ │ Rate Eng.│ │
│ └─────────────────────┘ └───────────┘ │
└──────────────────────────────────────────┘
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /v1/traces | OTLP/HTTP trace ingestion (standard OTel endpoint) |
GET | /api/v1/traces | List recent traces (filterable by service, status, duration) |
GET | /api/v1/traces/{traceID} | Get full trace with span waterfall hierarchy |
GET | /api/v1/traces/{traceID}/critical-path | Critical path analysis for a trace |
GET | /api/v1/services | List all services seen in ingested traces |
GET | /api/v1/dependencies | Distributed service dependency map |
GET | /api/v1/flamegraph/{service} | Latest eBPF flamegraph for a service (SVG/JSON) |
GET | /api/v1/flamegraph/{service}/correlated/{traceID}/{spanID} | Flamegraph slice correlated to a span |
GET | /api/v1/slo/{service}/burn-rate | SLO burn rate for a service |
POST | /api/v1/slo | Define an SLO for a service |
GET | /api/v1/slo | List all SLO definitions |
GET | /metrics | Prometheus OpenMetrics text with exemplar links |
GET | /healthz | Liveness probe |
SLO Burn Rate Alerting
Define SLOs with dual burn windows:
curl -X POST http://pranor-trace:8090/api/v1/slo \
-d '{
"service": "orders-api",
"slo_name": "availability",
"target_ratio": 0.999,
"windows": [
{ "name": "fast", "duration": "1h", "burn_rate_threshold": 14.4 },
{ "name": "slow", "duration": "6h", "burn_rate_threshold": 6.0 }
]
}'
Query burn rate:
curl http://pranor-trace:8090/api/v1/slo/orders-api/burn-rate
# → { "slo": "availability", "budget_remaining": 0.82, "burn_rate_1h": 2.1, "burn_rate_6h": 0.8, "alerting": false }
Flamegraph Profiling
eBPF profiling runs continuously in the background. Access profiles via:
# Get current CPU flamegraph for orders-api
curl http://pranor-trace:8090/api/v1/flamegraph/orders-api > flamegraph.svg
# Get flamegraph slice correlated to a specific slow span
curl http://pranor-trace:8090/api/v1/flamegraph/orders-api/correlated/abc123/span456
Getting Started
docker run -p 8090:8090 \
-e PRANOR_TRACE_MAX_TRACES=50000 \
-e PRANOR_TRACE_EBPF_ENABLED=true \
-e PRANOR_TRACE_OTEL_EXPORT=http://collector:4318 \
ghcr.io/vyuvaraj/pranor-trace:latest
Configure your services to send OTLP traces:
# Go
OTEL_EXPORTER_OTLP_ENDPOINT=http://pranor-trace:8090 ./my-service
# Python
opentelemetry-instrument --exporter-otlp-endpoint http://pranor-trace:8090 python app.py
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_TRACE_PORT | 8090 | HTTP listener port |
PRANOR_TRACE_MAX_TRACES | 10000 | Max traces in memory before eviction |
PRANOR_TRACE_EBPF_ENABLED | false | Enable eBPF continuous profiling |
PRANOR_TRACE_OTEL_EXPORT | — | Re-export spans to another OTLP collector |
Pranor Console
docker run -p 8083:8083 ghcr.io/vyuvaraj/pranor-console:latest
Pranor Console is the unified, premium management dashboard and observability console for the Pranor ecosystem. It provides a single pane of glass for managing Pranor Gate, Pranor Pulse, Pranor Vault, Pranor Mesh, Pranor Deploy, Pranor Trace, Pranor Flow, and all other Pranor components — with a glassmorphic, real-time UI designed for power users.
Table of Contents
Key Features
🎛️ Unified Management
- Single pane of glass: Manage the entire Pranor stack from one premium UI
- Glassmorphic dark UI: Premium visual design with smooth animations and real-time data refresh
- Multi-tab navigation: Navigate between components in organized tabs without page reloads
- Global
⌘Ksearch: Fuzzy search across all Pranor resources — services, routes, queues, buckets, workflows, traces — instantly
🚪 API Gateway Management (Pranor Gate)
- Live route audits: View, create, and delete proxy routes in real-time
- WASM hot-swap interface: Upload and activate WASM middleware modules without restarting Pranor Gate
- AI middleware audit panel: Monitor Prompt Guard violations, Semantic Cache similarity hits, PII scrubbing events, AI cost per request
- OpenAPI Swagger UI: Interactive API documentation browser for all registered gateway routes
- Circuit breaker status board: Live open/half-open/closed state per route with SLO metrics
📨 Queue Inspector (Pranor Pulse)
- Topic browser: Real-time topic list with message rates, partition counts, and replication status
- Schema registry browser: Browse, compare, and evolve message schemas
- DLQ browser & one-click replay: Inspect dead letter messages; replay individual or bulk messages with one click
- Consumer group lag dashboard: Per-consumer-group, per-partition offset lag visualization with historical trend
🗃️ Storage Inspector (Pranor Vault)
- Bucket browser: Navigate bucket contents, upload/download files, manage object metadata
- Vector index namespace browser: Inspect HNSW graph stats, index namespaces, embedding coverage
- Branch management: Create, diff, and merge CoW bucket branches from the UI
- Tiering policy editor: Configure hot/warm/cold tiering rules visually
🔭 Observability & Telemetry
- eBPF flamegraph telemetry: Live CPU and memory flamegraph profiling from the kernel layer — visualized in-browser
- OTel trace correlation: Click from a slow request directly into its distributed trace waterfall
- SLO burn rate alerts: Real-time error budget burn rate dashboards per service, with fast/slow window indicators
- Service topology live graph: Interactive dependency map of all Pranor services with live traffic flow edges
🔥 Chaos Engineering Panel
- Chaos control panel: Design and trigger chaos experiments (latency injection, error rate simulation, network partition) across Pranor Mesh nodes
- Experiment lifecycle management: Start, monitor, and abort experiments; view blast radius before triggering
- Historical experiment log: Full audit trail of past chaos events with impact metrics
🛎️ Alerts & Incidents
- Alert rule management: Define threshold and anomaly-based alert rules across all Pranor metrics
- Incident timeline: Structured incident management with severity triage, notes, and resolution tracking
🌿 Provisioning & Environments
- Environment provisioner: Create complete isolated Pranor environments (dev/staging/prod) with one click
- Branch preview provisioner: Automatically spin up ephemeral Pranor Deploy environments per git branch for PR previews
⚙️ Customization
- Theme selector: Dark, light, and glassmorphism themes; custom accent color
- Pinned dashboard widgets: Pin any metric chart or panel to a personal dashboard
- Custom keyboard shortcuts: User-configurable keybindings for common operations
Architecture
Browser
│
├─── Glassmorphic UI (SPA)
│ ├─── Global ⌘K Search
│ ├─── Real-time WebSocket feeds
│ └─── Multi-tab navigation
│
▼
Pranor Console Backend (Go)
│
├─── /api/v1/gateway/* → Pranor Gate integration
├─── /api/v1/queue/* → Pranor Pulse integration
├─── /api/v1/storage/* → Pranor Vault integration
├─── /api/v1/mesh/* → Pranor Mesh integration
├─── /api/v1/trace/* → Pranor Trace integration
├─── /api/v1/chaos/* → Chaos control plane
├─── /api/v1/incidents/* → Incident management
├─── /api/v1/search → Global resource search
└─── WebSocket /ws/feeds → Live topology & metrics
Dashboard Modules
| Module | Description |
|---|---|
| Gateway Inspector | Pranor Gate routes, WASM modules, circuit breakers, AI middleware stats |
| Queue Inspector | Topic browser, consumer lag, DLQ management, schema registry |
| Storage Inspector | Bucket browser, vector index namespaces, branch management |
| Topology Graph | Live service dependency graph with traffic flow visualization |
| Flamegraph Profiler | eBPF-powered CPU/memory flamegraph per service |
| Chaos Panel | Design, trigger, and monitor chaos experiments |
| SLO Dashboard | Error budget burn rate, SLO compliance per service |
| Trace Explorer | Distributed trace waterfall search and correlation |
| Incident Manager | Alert rules, incident triage, resolution tracking |
| Provisioner | Environment and branch preview management |
| AI Cost Dashboard | Per-service AI token spend, model routing savings |
API Endpoints
| Method | Path | Description |
|---|---|---|
GET | /api/v1/search?q= | Global resource search (⌘K) |
GET | /api/v1/topology/graph | Live service topology graph data |
GET | /ws/topology | WebSocket: real-time topology updates |
GET | /api/v1/flamegraph/{service} | eBPF flamegraph for a service |
GET | /api/v1/slo/{service}/burn-rate | SLO burn rate metrics |
POST | /api/v1/chaos/experiments | Create a chaos experiment |
DELETE | /api/v1/chaos/experiments/{id} | Abort a chaos experiment |
GET | /api/v1/incidents | List active incidents |
POST | /api/v1/incidents | Create an incident |
GET | /api/v1/queue/dlq/{topic} | DLQ browser |
POST | /api/v1/queue/dlq/{topic}/replay | One-click DLQ replay |
GET | /api/v1/queue/consumers/{group}/lag | Consumer lag per group |
POST | /api/v1/environments | Provision an environment |
POST | /api/v1/branch-preview | Provision a branch preview |
GET | /api/v1/preferences | Get user preferences |
PUT | /api/v1/preferences | Update user preferences |
Getting Started
docker run -p 8083:8083 \
-e PRANOR_CONSOLE_PRANOR_GATE_URL=http://pranor-gate:8080 \
-e PRANOR_CONSOLE_PRANOR_PULSE_URL=http://pranor-pulse:9090 \
-e PRANOR_CONSOLE_PRANOR_VAULT_URL=http://pranor-vault:7070 \
-e PRANOR_CONSOLE_PRANOR_TRACE_URL=http://pranor-trace:4318 \
-e PRANOR_CONSOLE_PRANOR_MESH_URL=http://pranor-mesh:8095 \
ghcr.io/vyuvaraj/pranor-console:latest
Open http://localhost:8083 in your browser.
Configuration
| Variable | Description |
|---|---|
PRANOR_CONSOLE_PORT | HTTP port (default: 8083) |
PRANOR_CONSOLE_PRANOR_GATE_URL | Pranor Gate backend URL |
PRANOR_CONSOLE_PRANOR_PULSE_URL | Pranor Pulse backend URL |
PRANOR_CONSOLE_PRANOR_VAULT_URL | Pranor Vault backend URL |
PRANOR_CONSOLE_PRANOR_TRACE_URL | Pranor Trace OTLP URL |
PRANOR_CONSOLE_PRANOR_MESH_URL | Pranor Mesh backend URL |
PRANOR_CONSOLE_AUTH_TOKEN | Static admin auth token |
Pranor Pool
docker run -p 8094:8094 ghcr.io/vyuvaraj/pranor-pool:latest
Pranor Pool is an intelligent, observable database connection pool manager for the Pranor ecosystem. It provides read/write splitting, connection health validation, leak detection, query telemetry, prepared statement caching, and pool saturation alerting.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Read/Write Split Routing
- Connection Health & Leak Detection
- Query Analytics
- Prepared Statement Cache
- Getting Started
Key Features
🔀 Read/Write Split Routing
- Primary for writes, replica for reads: Automatically routes
SELECTqueries to read replicas andINSERT/UPDATE/DELETEto the primary - Configurable replica weighting: Assign traffic weights per replica (e.g., 70% to replica-1, 30% to replica-2) for load distribution
- Transaction pinning: Within an active transaction, all queries are pinned to the primary regardless of query type
- Replica lag awareness: Skip replicas with lag > configurable threshold (uses
SHOW SLAVE STATUSor Postgrespg_stat_replication)
✅ Connection Health Validation
- Pre-checkout validation: Before handing a connection to a caller, Pranor Pool pings it and runs a configurable validation query (e.g.,
SELECT 1) — eliminates "stale connection" errors - Unhealthy connection eviction: Connections that fail validation are immediately evicted and replaced with fresh ones
- Background health sweeps: Periodic background sweeps validate idle connections in the pool
🔍 Connection Leak Detection
- Age-based detection: Connections held longer than configurable
max_checkout_durationare flagged as leaked - Activity-based detection: Connections with no query activity for
idle_timeoutare reclaimed - Goroutine tracking: Each checkout is tracked with the acquiring goroutine ID and stack trace for leak attribution
- Forced reclaim: Leaked connections are forcibly returned to the pool and the offending caller is logged
📊 Query Analytics
- Per-query execution time histogram: Tracks
p50,p75,p90,p99query latency per query signature - Slow query logger: Queries exceeding configurable
slow_query_thresholdare logged with full context (query, args, duration, caller) - Query normalization: Normalizes queries by replacing literal values for accurate aggregation
- Prometheus metrics: Exposes per-query latency histograms via
/metrics - Pranor Console integration: Pool saturation and query analytics visible in Pranor Console dashboard
💾 Prepared Statement Cache
- Multi-dialect support: Caches prepared statements for PostgreSQL, MySQL, and SQLite
- Automatic cache invalidation: Detects schema changes and invalidates affected prepared statements
- Connection-local cache: Each connection maintains its own prepared statement cache; Pranor Pool manages the lifecycle
- Cache hit rate metrics: Track cache hits vs. prepared statement re-preparations
🚨 Saturation Alerting
- Pool utilization monitoring: Tracks checked-out vs. total connections as a utilization percentage
- Wait queue depth: Monitors how many callers are waiting for a connection — leading indicator of saturation
- Pranor Console alert: Pushes saturation alerts to Pranor Console when utilization exceeds configurable thresholds (e.g., >80%, >95%)
- Prometheus alerting rules: Pre-built alert rules for pool saturation and wait queue depth
Architecture
Application Caller
│ checkout connection
▼
┌──────────────────────────────────────────────────┐
│ Pranor Pool │
│ │
│ ┌─────────────────────────────────────────────┐ │
│ │ Read/Write Router │ │
│ │ SELECT → Replica Pool │ DML → Primary │ │
│ └──────────┬──────────────────────────────────┘ │
│ │ │
│ ┌──────────▼─────────────────────────────────┐ │
│ │ Pre-checkout Health Validator │ │
│ │ Ping + Validation Query → evict if fail │ │
│ └──────────┬─────────────────────────────────┘ │
│ │ │
│ ┌──────────▼─────────────────────────────────┐ │
│ │ Leak Detector + Goroutine Tracker │ │
│ └─────────────────────────────────────────────┘ │
│ │
│ ┌───────────────────┐ ┌──────────────────────┐ │
│ │ Query Analytics │ │ Prepared Stmt Cache │ │
│ │ (p99 histograms) │ │ (per-connection) │ │
│ └───────────────────┘ └──────────────────────┘ │
└──────────────────────────────────────────────────┘
│
├── Primary DB (writes)
├── Replica-1 DB (reads, weight: 70%)
└── Replica-2 DB (reads, weight: 30%)
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/pools | Create a connection pool |
GET | /api/v1/pools | List all pools |
GET | /api/v1/pools/{name}/stats | Pool stats (utilization, wait queue, active connections) |
GET | /api/v1/pools/{name}/leaks | List detected connection leaks |
POST | /api/v1/pools/{name}/reclaim | Force-reclaim all leaked connections |
GET | /api/v1/pools/{name}/slow-queries | Recent slow queries log |
GET | /api/v1/pools/{name}/query-stats | Per-query latency histograms |
GET | /api/v1/pools/{name}/prepared-cache | Prepared statement cache contents |
/metrics | GET | Prometheus metrics (pool utilization, query latency, cache hit rates) |
/healthz | GET | Liveness probe |
Read/Write Split Routing
# Create a pool with primary + replicas
curl -X POST http://pranor-pool:8094/api/v1/pools \
-d '{
"name": "orders-db",
"primary": "postgres://user:pass@primary:5432/orders",
"replicas": [
{ "dsn": "postgres://user:pass@replica1:5432/orders", "weight": 70 },
{ "dsn": "postgres://user:pass@replica2:5432/orders", "weight": 30 }
],
"max_connections": 50,
"min_idle": 5,
"validation_query": "SELECT 1",
"max_checkout_duration": "30s",
"slow_query_threshold_ms": 100
}'
Connection Health & Leak Detection
# Check pool stats (utilization + wait queue depth)
curl http://pranor-pool:8094/api/v1/pools/orders-db/stats
# → { "total": 50, "active": 38, "idle": 12, "wait_queue": 2, "utilization_pct": 76 }
# View detected leaks
curl http://pranor-pool:8094/api/v1/pools/orders-db/leaks
# → [ { "conn_id": "conn-42", "held_since": "2026-07-26T10:00:00Z", "goroutine": "main.go:84", ... } ]
# Force reclaim leaked connections
curl -X POST http://pranor-pool:8094/api/v1/pools/orders-db/reclaim
Query Analytics
# View p99 latency by query signature
curl http://pranor-pool:8094/api/v1/pools/orders-db/query-stats
# → { "queries": [ { "signature": "SELECT * FROM orders WHERE id = ?", "p50": 3, "p99": 45, "count": 10234 }, ... ] }
# Recent slow queries
curl http://pranor-pool:8094/api/v1/pools/orders-db/slow-queries
Prepared Statement Cache
Pranor Pool automatically caches prepared statements per connection:
// Application uses Pranor Pool client — no special code needed
db := pranor-pool.Open("orders-db", "http://pranor-pool:8094")
rows, err := db.Query("SELECT id, total FROM orders WHERE user_id = $1", userID)
// Pranor Pool automatically uses cached prepared statement on subsequent calls
Getting Started
docker run -p 8094:8094 \
-e PRANOR_POOL_OTEL_ENDPOINT=http://pranor-trace:4318 \
-e PRANOR_POOL_PRANOR_CONSOLE_URL=http://pranor-console:8083 \
ghcr.io/vyuvaraj/pranor-pool:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_POOL_PORT | 8094 | HTTP listener port |
PRANOR_POOL_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
PRANOR_POOL_PRANOR_CONSOLE_URL | — | Pranor Console URL for saturation alerts |
PRANOR_POOL_DEFAULT_MAX_CONN | 25 | Default max connections per pool |
PRANOR_POOL_LEAK_CHECK_INTERVAL | 30s | How often to run leak detection sweep |
Pranor Notify
docker run -p 8091:8091 ghcr.io/vyuvaraj/pranor-notify:latest
Pranor Notify is the transactional email and deliverability management service for the Pranor ecosystem. It handles sending, receiving, bounce management, unsubscribe compliance, DMARC enforcement, and provides a rich templating DSL and delivery analytics.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Template DSL
- DMARC & Deliverability
- Compliance
- Getting Started
Key Features
📤 Sending
- Transactional email API: Simple REST API to send emails with HTML/plain text body, attachments, CC/BCC
- SMTP relay integration: Route outgoing mail through your own SMTP relay (Postfix, SendGrid, AWS SES, Mailgun)
- Template rendering: Render emails from reusable templates with the Pranor Notify DSL
📥 Inbound Routing
- Inbound email webhook router: Route inbound emails to HTTP endpoints based on configurable rules (match by
From,Subject, header patterns, or recipient address) - Rule-based routing: Priority-ordered rules with regex matching; fallback default handler
📝 Template Engine DSL
- Variable interpolation:
{{ user.name }},{{ order.total }} - Conditionals:
{% if user.verified %} ... {% endif %} - Loops:
{% for item in order.items %} ... {% endfor %} - Partials / includes:
{% include "components/footer.html" %} - Layouts: Extend base layouts for consistent header/footer across templates
📊 Bounce & Complaint Management
- Automatic suppression list: Bounced and complained addresses are automatically added to a suppression list; future sends are blocked
- Bounce classification: Distinguishes hard bounces (invalid address) from soft bounces (mailbox full) — hard bounces are immediately suppressed, soft bounces retry with backoff
- Webhook callbacks: Configure webhooks for bounce, complaint, and delivery events
- Retry policies: Configurable retry count and backoff strategy for soft bounces
🔒 DMARC & Deliverability
- DMARC policy enforcement: Check incoming mail against sender's DMARC DNS record; reject, quarantine, or report non-compliant messages
- SPF/DKIM alignment checking: Validate SPF and DKIM headers are aligned with the
From:domain - DMARC aggregation reports (RUA): Generate and send periodic DMARC aggregate reports to the domain owner's
ruaaddress - Deliverability scoring: Pre-send score estimation based on SPF/DKIM/DMARC alignment, suppression list checks, and content scoring
✅ Compliance
- One-click unsubscribe (RFC 8058):
List-Unsubscribe-Postheader injected on all bulk emails; honor unsubscribe POSTs from email clients (Gmail, Apple Mail) - List management API: Subscribe, unsubscribe, and manage mailing list membership; segmentation support
- Automatic unsubscribe link injection: Pranor Notify injects a unique unsubscribe link in every outgoing email footer
📈 Analytics
- Delivery analytics telemetry: Per-campaign delivery rates, open rates, click rates, bounce rates, complaint rates
- Per-recipient event tracking: Track individual recipient events (delivered, opened, clicked, bounced, unsubscribed)
- Pranor Console dashboard integration: Live analytics charts for mail campaigns
Architecture
Outbound Flow:
API Request → Template Render → Deliverability Check → SMTP Relay → Recipient
Inbound Flow:
Inbound SMTP → DMARC/SPF/DKIM Check → Webhook Router → Your HTTP Endpoint
Event Callbacks:
Bounce/Complaint Events → Suppression List + Webhook → Pranor Console Analytics
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/send | Send a transactional email |
POST | /api/v1/send/template | Send using a named template |
POST | /api/v1/templates | Create/update an email template |
GET | /api/v1/templates | List all templates |
GET | /api/v1/templates/{name} | Get a template |
DELETE | /api/v1/templates/{name} | Delete a template |
GET | /api/v1/suppression | List suppressed addresses |
POST | /api/v1/suppression | Manually suppress an address |
DELETE | /api/v1/suppression/{email} | Remove from suppression list |
POST | /api/v1/inbound/rules | Create an inbound routing rule |
GET | /api/v1/inbound/rules | List inbound routing rules |
POST | /api/v1/lists | Create a mailing list |
POST | /api/v1/lists/{id}/subscribe | Subscribe to a list |
POST | /api/v1/lists/{id}/unsubscribe | Unsubscribe from a list |
GET | /api/v1/analytics/campaigns/{id} | Analytics for a campaign |
GET | /api/v1/dmarc/report | Generate DMARC aggregate report |
/healthz | GET | Liveness probe |
Template DSL
Create a template:
curl -X POST http://pranor-notify:8091/api/v1/templates \
-d '{
"name": "welcome-email",
"subject": "Welcome, {{ user.name }}!",
"html": "<h1>Welcome, {{ user.name }}!</h1>\n{% if user.verified %}<p>Your account is verified.</p>{% endif %}\n{% include \"components/footer.html\" %}"
}'
Send using the template:
curl -X POST http://pranor-notify:8091/api/v1/send/template \
-d '{
"template": "welcome-email",
"to": "alice@example.com",
"variables": { "user": { "name": "Alice", "verified": true } }
}'
DMARC & Deliverability
# Check DMARC policy for a domain
curl http://pranor-notify:8091/api/v1/dmarc/check?domain=example.com
# Generate DMARC aggregate report
curl -X POST http://pranor-notify:8091/api/v1/dmarc/report \
-d '{"reporting_period": "2026-07", "report_to": "dmarc-reports@example.com"}'
Compliance
Pranor Notify automatically injects unsubscribe headers on bulk sends:
List-Unsubscribe: <https://pranor-notify.yourapp.com/unsubscribe?token=xxx>
List-Unsubscribe-Post: List-Unsubscribe=One-Click
When a mail client (Gmail, Apple Mail) sends the one-click unsubscribe POST, Pranor Notify handles it and suppresses the recipient automatically.
Getting Started
docker run -p 8091:8091 \
-e PRANOR_NOTIFY_SMTP_HOST=smtp.sendgrid.net \
-e PRANOR_NOTIFY_SMTP_PORT=587 \
-e PRANOR_NOTIFY_SMTP_USER=apikey \
-e PRANOR_NOTIFY_SMTP_PASS=SG.xxxxx \
-e PRANOR_NOTIFY_FROM_DOMAIN=yourapp.com \
-e PRANOR_NOTIFY_OTEL_ENDPOINT=http://pranor-trace:4318 \
ghcr.io/vyuvaraj/pranor-notify:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_NOTIFY_PORT | 8091 | HTTP listener port |
PRANOR_NOTIFY_SMTP_HOST | — | Outbound SMTP relay host |
PRANOR_NOTIFY_SMTP_PORT | 587 | Outbound SMTP relay port |
PRANOR_NOTIFY_SMTP_USER | — | SMTP authentication username |
PRANOR_NOTIFY_SMTP_PASS | — | SMTP authentication password |
PRANOR_NOTIFY_FROM_DOMAIN | — | Default sending domain |
PRANOR_NOTIFY_INBOUND_PORT | — | SMTP port for inbound mail reception |
PRANOR_NOTIFY_DMARC_ENABLED | true | Enable DMARC enforcement |
PRANOR_NOTIFY_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
Pranor Flow
docker run -p 8089:8089 ghcr.io/vyuvaraj/pranor-flow:latest
Pranor Flow is a stateful, DAG-based workflow orchestrator and Saga compensation engine for the Pranor ecosystem. It supports durable execution with checkpointing, WASM step functions, sub-workflow composition, per-execution tracing, and a Dead Letter Workflow Queue with manual retry.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Defining Workflows
- Saga Compensation
- WASM Step Functions
- Sub-workflow Composition
- Getting Started
Key Features
🔀 DAG Orchestration
- Multi-step DAG execution: Runs execution graphs sorted topologically by dependency constraints — steps run in parallel when their dependencies are satisfied
- Step output propagation: Output from each step is passed as input to dependent steps
- Fan-out / fan-in: Parallelize independent branches, synchronize at join steps
- Conditional branching: Steps can be skipped based on upstream output conditions
💾 Durable Execution
- Checkpoint persistence: Workflow state serialized to
.statefiles on disk after every step — executions survive engine restarts - Resume from checkpoint:
POST /api/workflows/resumerestarts a workflow from its last successful checkpoint - Idempotent step execution: Steps can be marked idempotent; on replay, Pranor Flow skips already-completed steps
🔄 Saga Compensation
- Automatic rollback on failure: When a step fails after earlier steps have succeeded, Pranor Flow triggers
CompensateActionin reverse topological order - Per-step compensation actions: Each step optionally declares a compensate endpoint — called when rolling back
- Partial compensation: Compensates only completed steps — not future/skipped steps
🧩 WASM Step Functions
- Sandboxed WASM step execution: Run any step logic as a WASI-compliant WebAssembly module — language-agnostic step implementations (Rust, C, Go)
- I/O via stdin/stdout: Step input passed as JSON on stdin; step output read from stdout
- Timeout enforcement: Per-step WASM execution timeout prevents runaway steps
🧱 Sub-workflow Composition
- Nested workflow manager: Compose complex workflows from smaller reusable sub-workflows
- Sub-workflow as a step: Any step can invoke another workflow definition by name — the parent pauses and waits for the child to complete
- Recursive composition: Sub-workflows can themselves contain sub-workflows
📊 Observability & Cost Tracking
- Per-execution OTel span attribution: Each workflow execution and each individual step gets its own OTel span, linked to a root trace
- AI cost tracking: Steps that call AI/LLM endpoints have token cost annotations added to their spans
- Execution timeline: Full execution log with step start times, durations, status, and outputs
📭 Dead Letter Workflow Queue
- DLQ for failed workflows: Workflows that exhaust retries are moved to the DLWQ with full failure context
- Manual retry endpoint:
POST /api/workflows/dlq/{id}/retryre-queues a DLWQ workflow from the beginning or from last checkpoint - DLWQ browser: Pranor Console shows failed workflows with their error details
Architecture
{
"id": "order-checkout-flow",
"name": "Order Checkout Pipeline",
"tasks": [
{ "name": "reserve-inventory", "action": "http://inventory-svc/reserve" },
{ "name": "process-payment", "action": "http://payment-svc/charge", "depends_on": ["reserve-inventory"], "compensate_action": "http://payment-svc/refund" },
{ "name": "ship-order", "action": "http://shipping-svc/label", "depends_on": ["process-payment"] }
]
}
Define Workflow (POST /api/workflows/define)
└── DAG Spec: steps, dependencies, compensations, WASM modules
Execute Workflow (POST /api/workflows/execute)
│
▼
┌────────────────────────────────────────────────────┐
│ Pranor Flow Engine │
│ │
│ Topological Sort → Parallel Ready Steps │
│ │ │
│ ┌────▼─────┐ ┌───────────┐ ┌─────────────────┐ │
│ │ HTTP Step│ │ WASM Step │ │ Sub-workflow │ │
│ │ Executor │ │ Executor │ │ Invoker │ │
│ └────┬─────┘ └─────┬─────┘ └────────┬────────┘ │
│ └──────────────┼─────────────────┘ │
│ │ │
│ ┌───────────────────▼───────────────────────────┐ │
│ │ Checkpoint Store (.state files) │ │
│ └───────────────────────────────────────────────┘ │
│ │ │
│ ┌───────────────────▼───────────────────────────┐ │
│ │ On failure: Saga Compensator (reverse order) │ │
│ └───────────────────────────────────────────────┘ │
└────────────────────────────────────────────────────┘
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/workflows/define | Define a new DAG workflow |
GET | /api/workflows | List all workflow definitions |
POST | /api/workflows/execute | Execute a workflow instance |
GET | /api/workflows/instances/{id} | Get execution status and step logs |
POST | /api/workflows/resume | Resume from checkpoint file |
GET | /api/workflows/dlq | Browse Dead Letter Workflow Queue |
POST | /api/workflows/dlq/{id}/retry | Retry a DLQ workflow |
/metrics | GET | Prometheus metrics (workflow success rate, step durations, DLQ depth) |
/healthz | GET | Liveness probe |
Defining Workflows
curl -X POST http://pranor-flow:8089/api/workflows/define \
-d '{
"name": "order-fulfillment",
"steps": [
{
"id": "reserve-inventory",
"type": "http",
"url": "http://inventory/reserve",
"depends_on": [],
"compensate_url": "http://inventory/release"
},
{
"id": "charge-payment",
"type": "http",
"url": "http://payments/charge",
"depends_on": ["reserve-inventory"],
"compensate_url": "http://payments/refund"
},
{
"id": "notify-customer",
"type": "http",
"url": "http://notifications/send",
"depends_on": ["charge-payment"]
}
]
}'
Execute it:
curl -X POST http://pranor-flow:8089/api/workflows/execute \
-d '{"workflow": "order-fulfillment", "input": {"order_id": "ord-123", "amount": 99.99}}'
# → { "instance_id": "wf-abc-001", "status": "running" }
Saga Compensation
If charge-payment fails after reserve-inventory succeeded:
1. reserve-inventory → ✅ SUCCESS
2. charge-payment → ❌ FAILURE
3. Pranor Flow triggers compensations in reverse:
→ POST http://inventory/release (compensate reserve-inventory)
WASM Step Functions
curl -X POST http://pranor-flow:8089/api/workflows/define \
-d '{
"name": "ml-pipeline",
"steps": [
{
"id": "preprocess",
"type": "wasm",
"wasm_module": "preprocess.wasm",
"timeout": "30s",
"depends_on": []
},
{
"id": "predict",
"type": "wasm",
"wasm_module": "model-inference.wasm",
"depends_on": ["preprocess"]
}
]
}'
Sub-workflow Composition
curl -X POST http://pranor-flow:8089/api/workflows/define \
-d '{
"name": "full-onboarding",
"steps": [
{ "id": "create-account", "type": "http", "url": "http://accounts/create", "depends_on": [] },
{
"id": "setup-billing",
"type": "sub-workflow",
"workflow": "billing-setup",
"depends_on": ["create-account"]
},
{ "id": "send-welcome", "type": "http", "url": "http://mail/welcome", "depends_on": ["setup-billing"] }
]
}'
Getting Started
docker run -p 8089:8089 \
-e PRANOR_FLOW_CHECKPOINT_DIR=/data/checkpoints \
-e PRANOR_FLOW_OTEL_ENDPOINT=http://pranor-trace:4318 \
-v flow-data:/data \
ghcr.io/vyuvaraj/pranor-flow:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_FLOW_PORT | 8089 | HTTP listener port |
PRANOR_FLOW_CHECKPOINT_DIR | ./checkpoints | Directory for workflow state checkpoint files |
PRANOR_FLOW_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
PRANOR_FLOW_WASM_MODULES_DIR | ./wasm | Directory for WASM step module files |
PRANOR_FLOW_DLQ_MAX_SIZE | 1000 | Max workflows retained in DLQ |
Pranor Deploy
docker run -p 8088:8088 ghcr.io/vyuvaraj/pranor-deploy:latest
Pranor Deploy is the managed deployment platform and process orchestrator for the Pranor ecosystem. It provides PaaS-style service deployment, blue/green and canary strategies, per-branch preview environments, container isolation, and deep integration with Pranor Gate for automatic routing registration.
Table of Contents
Key Features
🚀 Core Deployment Platform
- PaaS deployment API: Compile and run
.pnrbackground services on demand via REST API - Process isolation: Dedicated port allocation per deployment; process metrics tracking
- Dynamic gateway routing registration: Newly deployed services are automatically registered with
Pranor Gate— zero manual route configuration - Ring-buffer log streaming: Capture stdout/stderr into a ring buffer; stream logs via REST API
- OTel tracing: Deep integration with
Pranor Tracevia shared tracing — per-deployment spans
🔵🟢 Blue/Green Deployment
- Zero-downtime traffic switch: Atomic cutover — Pranor Gate switches 100% of traffic to new (green) deployment in a single atomic update
- Instant rollback: If issues arise, switch back to blue with one API call
- Health gate: Green deployment must pass health checks before cutover is triggered
- Audit trail: Every cutover and rollback event logged with timestamp and operator identity
🐤 Canary Deployment
- Configurable traffic split: Route a percentage (e.g., 5%, 10%, 25%) of traffic to the canary deployment
- Automatic rollback: Monitor error rate on canary; if it exceeds configurable threshold, automatically revert 100% traffic to stable
- Progressive promotion: Incrementally increase canary traffic weight on success (5% → 25% → 50% → 100%)
- Pranor Gate integration: Traffic split is enforced by Pranor Gate's weighted routing — no client-side changes required
🌿 Preview Environments
- Per-branch preview provisioner: Automatically create complete isolated Pranor environments per git branch — ideal for PR review workflows
- Ephemeral lifecycle: Preview environments are automatically cleaned up when the branch is deleted or after a configurable TTL
- Independent routing: Each preview gets its own Pranor Gate subdomain (e.g.,
feature-x.preview.pranor.net) - Full stack provisioning: Preview environments include isolated Pranor Pulse, Pranor Vault, and Pranor Cache instances
🐳 Container Isolation
- Docker/OCI container mode: Deploy services as fully isolated containers (via Docker or OCI runtime) rather than raw processes
- Resource limits: Configure per-container CPU and memory limits
- Network isolation: Container deployments run in isolated bridge networks
Architecture
Developer API Request
│ POST /api/v1/deployments
▼
┌───────────────────────────────────────────────┐
│ Pranor Deploy │
│ │
│ ┌────────────────────────────────────────┐ │
│ │ Deployment Orchestrator │ │
│ │ Build → Deploy → Health Check │ │
│ └───────────┬────────────────────────────┘ │
│ │ │
│ ┌───────────▼────────────────────────────┐ │
│ │ Strategy Manager │ │
│ │ Direct │ Blue/Green │ Canary │ │
│ └───────────┬────────────────────────────┘ │
│ │ │
│ ┌───────────▼────────────────────────────┐ │
│ │ Pranor Gate Registration │ │
│ │ (auto-register routes on deploy) │ │
│ └────────────────────────────────────────┘ │
│ │
│ ┌────────────────────┐ ┌─────────────────┐ │
│ │ Log Streamer │ │ Preview Env Mgr │ │
│ │ (ring buffer) │ │ (branch → env) │ │
│ └────────────────────┘ └─────────────────┘ │
└───────────────────────────────────────────────┘
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/deployments | Deploy a service (direct, blue/green, or canary) |
GET | /api/v1/deployments | List all deployments |
GET | /api/v1/deployments/{id} | Get deployment status and metrics |
POST | /api/v1/deployments/{id}/promote | Promote canary to stable |
POST | /api/v1/deployments/{id}/rollback | Roll back to previous version |
POST | /api/v1/deployments/{id}/cutover | Blue/Green: cut all traffic to new version |
GET | /api/v1/deployments/{id}/logs | Stream deployment logs (ring buffer) |
DELETE | /api/v1/deployments/{id} | Stop and remove a deployment |
POST | /api/v1/previews | Create a preview environment for a branch |
GET | /api/v1/previews | List active preview environments |
DELETE | /api/v1/previews/{id} | Destroy a preview environment |
/metrics | GET | Prometheus metrics (deployments active, error rates, rollback events) |
/healthz | GET | Liveness probe |
Deployment Strategies
Direct Deploy
curl -X POST http://pranor-deploy:8088/api/v1/deployments \
-d '{"service": "orders-api", "image": "ghcr.io/myorg/orders:v2.1.0", "strategy": "direct", "port": 3000}'
Blue/Green Deploy
# Deploy green (new version)
curl -X POST http://pranor-deploy:8088/api/v1/deployments \
-d '{"service": "orders-api", "image": "ghcr.io/myorg/orders:v2.2.0", "strategy": "blue-green"}'
# → { "id": "dep-456", "status": "green-standby", "green_url": "http://green-orders:3001" }
# Cut over all traffic to green
curl -X POST http://pranor-deploy:8088/api/v1/deployments/dep-456/cutover
# → Pranor Gate atomically switches all /api/orders traffic to green
# Rollback if needed
curl -X POST http://pranor-deploy:8088/api/v1/deployments/dep-456/rollback
Canary Deploy
# Deploy canary at 5% traffic
curl -X POST http://pranor-deploy:8088/api/v1/deployments \
-d '{
"service": "orders-api",
"image": "ghcr.io/myorg/orders:v2.3.0",
"strategy": "canary",
"canary_weight": 5,
"auto_rollback_error_rate": 0.05
}'
# Progressive promotion: 5% → 25% → 50% → 100%
curl -X POST http://pranor-deploy:8088/api/v1/deployments/dep-789/promote \
-d '{"weight": 25}'
Preview Environments
# Create preview environment for a feature branch
curl -X POST http://pranor-deploy:8088/api/v1/previews \
-d '{"branch": "feature/new-checkout", "ttl": "7d"}'
# → { "id": "prev-001", "url": "https://feature-new-checkout.preview.pranor.net", "expires_at": "..." }
# Destroy preview
curl -X DELETE http://pranor-deploy:8088/api/v1/previews/prev-001
Getting Started
docker run -p 8088:8088 \
-e PRANOR_DEPLOY_PRANOR_GATE_URL=http://pranor-gate:8080 \
-e PRANOR_DEPLOY_OTEL_ENDPOINT=http://pranor-trace:4318 \
-e PRANOR_DEPLOY_CONTAINER_RUNTIME=docker \
-v /var/run/docker.sock:/var/run/docker.sock \
ghcr.io/vyuvaraj/pranor-deploy:latest
Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_DEPLOY_PORT | 8088 | HTTP listener port |
PRANOR_DEPLOY_PRANOR_GATE_URL | — | Pranor Gate URL for route registration |
PRANOR_DEPLOY_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
PRANOR_DEPLOY_CONTAINER_RUNTIME | process | process (raw) or docker (OCI container) |
PRANOR_DEPLOY_PREVIEW_DOMAIN | — | Base domain for preview environments |
PRANOR_DEPLOY_PREVIEW_TTL | 7d | Default preview environment TTL |
Pranor Tunnel
pranor-tunnel client --port 3000 --server tunnel.pranor.net
# → Exposes local port 3000 at https://abc123.tunnel.pranor.net
docker run -p 8092:8092 ghcr.io/vyuvaraj/pranor-tunnel:latest
Pranor Tunnel is a secure, instant tunneling service for exposing local Pranor services to the internet during development and testing. One command creates a public URL that forwards requests to your local machine — ideal for webhook testing, OAuth callbacks, mobile app dev, and sharing work in progress.
Table of Contents
- Key Features
- Architecture
- API Endpoints
- Getting Started
- Request Inspection & Replay
- Authentication & Access Control
- Resilience & Reconnection
- Configuration
Key Features
🌐 Core Tunneling
- Subdomain-based routing: Each tunnel gets a unique subdomain (e.g.,
myapp.pranor.net) - WebSocket transport: Firewall-friendly tunneling over WebSocket — no special network configuration required
- WebSocket connection multiplexing: Binary-framed multiplexed streams (
4-byte StreamID + 1-byte Type + 4-byte PayloadLen) allow multiple simultaneous requests over a single WebSocket connection - OTel traceparent propagation:
traceparentandtracestateheaders forwarded natively through the tunnel for distributed tracing continuity
🔍 Request Inspection & Replay
- Full request & response body capture: Ring-buffer captures all requests and responses for debugging
- Replay-on-demand: Replay any captured request to your local service with one API call
- Real-time request log: Colorful terminal output with status codes, latency, and method — like a local dev proxy
🔒 Authentication & Access Control
- JWT auth gating: Require a valid JWT token to open a tunnel connection — prevents unauthorized forwarding
- API-key auth: Alternative to JWT; pass a static API key in the
Authorizationheader - Shareable tunnel URLs with expiry: Generate a time-limited shareable URL (e.g., valid for 1h) — auto-expires after
- One-time access tokens: Single-use tunnel URLs that invalidate after first use
🔄 Resilience & Reconnection
- Persistent reconnect with exponential backoff: Client auto-reconnects on disconnect; configurable max retries, initial delay, max delay, and jitter multiplier
- Connection state recovery: In-flight requests are retried on reconnect within configurable grace window
- Health & readiness probes: Standard
/healthzand/readyzendpoints for container orchestration
Architecture
Browser / Webhook Sender
│ HTTPS request to myapp.pranor.net
▼
┌─────────────────────────┐
│ Pranor Tunnel Server │
│ │
│ Subdomain Router │
│ myapp → Conn#1 │
│ WS Multiplexer │
│ (StreamID framing) │
└──────────┬──────────────┘
│ WebSocket (multiplexed)
▼
Pranor Tunnel Client (local machine)
│
▼
Local Service (http://localhost:3000)
API Endpoints
| Method | Path | Description |
|---|---|---|
POST | /api/v1/tunnels | Create a new tunnel |
GET | /api/v1/tunnels | List active tunnels |
DELETE | /api/v1/tunnels/{id} | Close a tunnel |
GET | /api/v1/tunnels/{id}/requests | Browse captured requests (ring buffer) |
POST | /api/v1/tunnels/{id}/replay/{reqID} | Replay a captured request |
POST | /api/v1/tunnels/{id}/share | Generate a shareable URL with expiry |
GET | /healthz | Liveness probe |
GET | /readyz | Readiness probe |
Getting Started
Server (self-hosted)
docker run -p 8092:8092 \
-e PRANOR_TUNNEL_DOMAIN=pranor.net \
-e PRANOR_TUNNEL_JWT_SECRET=my-secret \
-e PRANOR_TUNNEL_OTEL_ENDPOINT=http://pranor-trace:4318 \
ghcr.io/vyuvaraj/pranor-tunnel:latest
Client (local machine)
# Install client
go install github.com/vyuvaraj/pranor/Pranor Tunnel/cmd/pranor-tunnel@latest
# Expose local port 3000 to a public URL
pranor-tunnel --server wss://tunnel.pranor.net --local http://localhost:3000
# Output:
# ✓ Tunnel active: https://abc123.pranor.net
# Forwarding: https://abc123.pranor.net → http://localhost:3000
# Press Ctrl+C to close tunnel
Request Inspection & Replay
All requests are captured in a ring buffer:
# View captured requests
curl http://localhost:8092/api/v1/tunnels/tun-abc/requests
# Replay a specific captured request
curl -X POST http://localhost:8092/api/v1/tunnels/tun-abc/replay/req-001
The terminal client shows real-time request logs:
[2026-07-26 11:42:00] POST /webhook/payment 200 43ms
[2026-07-26 11:42:01] GET /api/orders/123 200 12ms
[2026-07-26 11:42:03] POST /webhook/payment 500 89ms ← error highlighted
Authentication & Access Control
# Create a tunnel with JWT auth requirement
pranor-tunnel --server wss://tunnel.pranor.net \
--local http://localhost:3000 \
--auth jwt \
--jwt-token eyJhbGciOi...
# Generate a shareable URL (expires in 1 hour)
curl -X POST http://localhost:8092/api/v1/tunnels/tun-abc/share \
-d '{"expires_in": "1h", "one_time": false}'
# → { "url": "https://abc123.pranor.net?token=xyz789", "expires_at": "..." }
Resilience & Reconnection
Configure reconnect behavior in the client:
pranor-tunnel \
--server wss://tunnel.pranor.net \
--local http://localhost:3000 \
--reconnect-max-retries 10 \
--reconnect-initial-delay 500ms \
--reconnect-max-delay 30s \
--reconnect-jitter 0.2
Configuration
Server Environment Variables
| Variable | Default | Description |
|---|---|---|
PRANOR_TUNNEL_PORT | 8092 | HTTP/WebSocket listener port |
PRANOR_TUNNEL_DOMAIN | — | Base domain for subdomains (e.g. pranor.net) |
PRANOR_TUNNEL_JWT_SECRET | — | JWT signing secret for auth gating |
PRANOR_TUNNEL_MAX_RING_BUFFER | 100 | Max captured requests per tunnel |
PRANOR_TUNNEL_OTEL_ENDPOINT | — | OpenTelemetry collector URL |
PRANOR_TUNNEL_TLS_CERT | — | TLS certificate path |
PRANOR_TUNNEL_TLS_KEY | — | TLS key path |
Wildcard DNS
Configure your DNS provider with a wildcard A/CNAME record pointing *.pranor.net to the Pranor Tunnel server IP.
Pranor Hub
docker run -p 8090:8090 ghcr.io/vyuvaraj/pranor-hub:latest
Pranor Hub is the lightweight, S3-backed community package hub and registry server for the Pranor ecosystem. It allows sharing, versioning, and resolving packages written for pranor microservices.
Features
- S3 / Pranor Vault Backend: Packages are stored as tarballs in a dedicated S3 bucket (or
Pranor Vault). - Dependency Resolution: Exposes APIs to resolve package dependency trees dynamically.
- Token Authorization: Supports JWT signature verification to protect package publication.
- Ecosystem Landing Dashboard: Built-in web dashboard displaying active packages, sizes, and versions.
API Endpoints
1. Health Checks
GET /healthz- Health probe.GET /readyz- Readiness probe.
2. Publish Package
POST /publishorPOST /api/v1/publish- Uploads a package tarball (
.tar.gz). - Expects a
pranor.tomlmanifest file in the root of the archive to parse the package name, version, and dependencies. - If
PRANOR_JWT_SECRETis enabled, requires a valid token via theAuthorization: Bearer <token>header.
- Uploads a package tarball (
3. Fetch Package Tarball
GET /packages/{name}.tar.gzorGET /api/v1/packages/{name}.tar.gz- Fetches the latest published version of the package.
GET /packages/{name}/{version}/{name}-{version}.tar.gzorGET /api/v1/packages/{name}/{version}/{name}-{version}.tar.gz- Fetches a specific version of the package.
4. Search Packages
GET /api/packages/search?q={query}orGET /api/v1/packages/search?q={query}- Returns a list of packages matching the query string.
5. Listing and Dependencies
GET /api/packages/orGET /api/v1/packages/- Lists all packages in the registry.
GET /api/packages/{name}/versionsorGET /api/v1/packages/{name}/versions- Retrieves all published versions of a package.
GET /api/packages/{name}/depsorGET /api/packages/{name}/deps- Returns the resolved dependency tree for the latest package version.
GET /api/packages/{name}/{version}/depsorGET /api/packages/{name}/{version}/deps- Returns the resolved dependency tree for a specific version.
Configuration (Environment Variables)
| Variable | Description | Default |
|---|---|---|
PORT | Local server port | 8088 |
PRANOR_STORE_ENDPOINT | Pranor Vault or external S3 URL | http://localhost:9000 |
PRANOR_STORE_ACCESS_KEY | Access key for S3 bucket | admin |
PRANOR_STORE_SECRET_KEY | Secret key for S3 bucket | admin123 |
PRANOR_JWT_SECRET | Secret key to validate signature for publishing | (Disabled) |
Running Locally
go run main.go --addr :8088 --s3-endpoint http://localhost:9000
Pranor Lock — Distributed Lock Manager
Pranor Lock is a high-performance distributed locking manager for the Pranor ecosystem, providing cross-service mutual exclusion with lease-based locks, fencing tokens, reentrant locking, deadlock cycle detection, and metrics observability.
Features
- Lease-based Locks: Automatic expiration of locks to prevent permanent resource hangs.
- Reentrant Locks: Reentrant support via
client_idtracking (recursive acquisition). - Fencing Tokens: Monotonically increasing tokens to prevent stale writes/updates in concurrency.
- Deadlock Cycle Detection: Active graph cycle detection aborts cyclic lock wait queues with error status.
- Observability Metrics: Prometheus-compatible metric exporter endpoint.
- Lease Persistence: Crash-safe persistent lease locking via local JSON file-backing.
Getting Started
Prerequisites
- Go 1.20+ installed
Running locally
# Start in-memory mode on default port 8089
go run main.go
# Start on custom port
go run main.go --port 8090
API Specification
All endpoints support standard auth and tenant isolation headers.
1. Acquire Lock
Acquires a lock for a key. Blocks up to wait_ms if held, and supports reentrancy if matching client_id is supplied.
- Endpoint:
POST /api/locks/acquire - Request Payload:
{ "key": "payment-order-123", "owner": "worker-node-1", "client_id": "session-abc", "duration_ms": 30000, "wait_ms": 5000 } - Response (200 OK):
{ "status": "success", "lock": { "key": "payment-order-123", "owner": "worker-node-1", "client_id": "session-abc", "reentrancy_count": 1, "fencing_token": 15, "expires_at": "2026-07-17T20:25:00Z" } }
2. Renew Lock Lease
Extends active lease TTL. Rejects request if the provided fencing token does not match the active lock lease.
- Endpoint:
POST /api/locks/renew - Request Payload:
{ "key": "payment-order-123", "owner": "worker-node-1", "fencing_token": 15, "duration_ms": 30000 }
3. Release Lock
Frees the lock immediately. If reentrancy count is greater than 1, decrements count instead.
- Endpoint:
POST /api/locks/release - Request Payload:
{ "key": "payment-order-123", "owner": "worker-node-1", "fencing_token": 15 }
4. Observability & Metrics
List Active Locks
Retrieves list of active leases along with queued waiters.
- Endpoint:
GET /api/locks/observability
Prometheus Metrics
Retrieves Prometheus gauges/counters.
- Endpoint:
GET /api/locks/metrics
License
This project is licensed under Apache 2.0 - see the LICENSE file for details.
Pranor Secret — Secret & Credential Management
Pranor Secret is the centralized secrets, credentials, and configuration protection engine for the Pranor ecosystem. It provides tenant-isolated secret storage encrypted at rest using AES-GCM (Galois/Counter Mode).
Features
- Centralized Encrypted Storage: Encrypts all stored secrets using a 32-byte master key.
- Tenant Isolation: Organizes secrets dynamically per tenant context.
- Microservice Ready: Plugs directly into
Pranor Coremiddleware for authentication, tracing, and rate limiting. - Graceful Shutdown: Stops safely without corrupting the encrypted local storage file.
Getting Started
Local Development
-
Provide a Master Key: Define the 32-byte master key as a hex-encoded string in the environment:
# Example hex key (32 bytes) export PRANOR_SECRET_MASTER_KEY="000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f"Note: If no master key is supplied, a temporary random key will be generated at startup, and stored secrets will not persist across restarts.
-
Run the Service:
go run main.go --port 8091 --file secrets.enc
API Documentation
All endpoints support standard header authentication and X-Tenant-ID routing (integrated with Pranor Core).
1. Set or Update a Secret
- Endpoint:
POST /api/v1/secrets - Headers:
X-Tenant-ID: tenant-aAuthorization: Bearer<token>
- Request Body:
{ "key": "database-password", "value": "super-secret-passphrase" } - Response (201 Created):
{ "key": "database-password", "value": "super-secret-passphrase" }
2. Get a Secret
- Endpoint:
GET /api/v1/secrets/{key} - Response (200 OK):
{ "key": "database-password", "value": "super-secret-passphrase" }
3. List Stored Secret Keys
- Endpoint:
GET /api/v1/secrets - Response (200 OK):
{ "keys": ["database-password"] }
4. Delete a Secret
- Endpoint:
DELETE /api/v1/secrets/{key} - Response (200 OK):
{ "status": "deleted", "key": "database-password" }
License
This project is licensed under Apache 2.0 - see the LICENSE file for details.
Docker Deployment Guide
Run the full Pranor platform or individual modules using Docker Compose.
Quick Start — Full Platform
git clone https://github.com/vyuvaraj/pranor.git
cd pranor
docker compose up -d
This starts all modules:
| Service | Port | Description |
|---|---|---|
| pranor-gate | 8080 | API Gateway |
| pranor-vault | 8081 | Object Storage (S3) |
| pranor-pulse | 8082 | Message Broker (STOMP) |
| pranor-console | 8083 | Dashboard UI |
| pranor-deploy | 8085 | Deployment Orchestrator |
| pranor-cache | 8086 | Cache Engine |
| pranor-chrono | 8087 | Job Scheduler |
| pranor-hub | 8088 | Package Registry |
| pranor-mesh | 8089 | Service Mesh |
| pranor-trace | 8090 | Tracing Collector |
| pranor-notify | 8094 | Notification Gateway |
| pranor-flow | 8096 | Workflow Engine |
| pranor-pool | 8097 | DB Connection Pool |
| pranor-auth | 8098 | Auth Provider |
| pranor-tunnel | 8443 | Dev Tunnel |
Single Module
Run any module standalone:
# Just the API Gateway
docker run -p 8080:8080 ghcr.io/vyuvaraj/pranor-gate:latest
# Just the Object Storage
docker run -p 8081:8081 -v vault-data:/data ghcr.io/vyuvaraj/pranor-vault:latest
# Just the Message Broker
docker run -p 8082:8082 -p 61613:61613 ghcr.io/vyuvaraj/pranor-pulse:latest
Environment Variables
All modules accept:
| Variable | Description |
|---|---|
PRANOR_OTLP_ENDPOINT | OpenTelemetry collector URL |
PRANOR_DISCOVERY | JSON map of module URLs for service discovery |
Module-specific variables are documented in each module's docs.
Docker Compose (Production)
services:
pranor-gate:
image: ghcr.io/vyuvaraj/pranor-gate:latest
ports:
- "8080:8080"
environment:
- PRANOR_OTLP_ENDPOINT=http://pranor-trace:8090
depends_on:
pranor-trace:
condition: service_healthy
healthcheck:
test: ["CMD", "wget", "--spider", "http://localhost:8080/healthz"]
interval: 5s
timeout: 3s
retries: 5
pranor-vault:
image: ghcr.io/vyuvaraj/pranor-vault:latest
ports:
- "8081:8081"
volumes:
- vault-data:/data
environment:
- PRANOR_OTLP_ENDPOINT=http://pranor-trace:8090
pranor-trace:
image: ghcr.io/vyuvaraj/pranor-trace:latest
ports:
- "8090:8090"
networks:
default:
name: pranor-net
volumes:
vault-data:
Health Checks
Every module exposes GET /healthz returning:
{"status": "UP", "service": "pranor", "version": "1.0.0"}
Observability
Connect all modules to Pranor Trace for distributed tracing:
PRANOR_OTLP_ENDPOINT=http://pranor-trace:8090
View traces in Pranor Console at http://localhost:8083 or forward to Jaeger/Grafana.
Next Steps
Kubernetes Deployment
Deploy Pranor modules to Kubernetes using Helm charts or raw manifests.
Helm Chart (Recommended)
helm repo add pranor https://vyuvaraj.github.io/pranor/charts
helm install pranor-vault pranor/pranor-vault --namespace pranor --create-namespace
helm install pranor-gate pranor/pranor-gate --namespace pranor
helm install pranor-pulse pranor/pranor-pulse --namespace pranor
Minimal Manifest
apiVersion: apps/v1
kind: Deployment
metadata:
name: pranor-gate
namespace: pranor
spec:
replicas: 2
selector:
matchLabels:
app: pranor-gate
template:
metadata:
labels:
app: pranor-gate
spec:
containers:
- name: pranor-gate
image: ghcr.io/vyuvaraj/pranor-gate:latest
ports:
- containerPort: 8080
env:
- name: PRANOR_OTLP_ENDPOINT
value: "http://pranor-trace:8090"
livenessProbe:
httpGet:
path: /healthz
port: 8080
initialDelaySeconds: 5
periodSeconds: 10
resources:
requests:
memory: "64Mi"
cpu: "100m"
limits:
memory: "256Mi"
cpu: "500m"
---
apiVersion: v1
kind: Service
metadata:
name: pranor-gate
namespace: pranor
spec:
selector:
app: pranor-gate
ports:
- port: 8080
targetPort: 8080
type: ClusterIP
KEDA Auto-Scaling (Pranor Pulse)
Scale consumers based on message queue lag:
apiVersion: keda.sh/v1alpha1
kind: ScaledObject
metadata:
name: pranor-pulse-consumer
spec:
scaleTargetRef:
name: order-processor
minReplicaCount: 1
maxReplicaCount: 10
triggers:
- type: external
metadata:
scalerAddress: pranor-pulse:8082
topic: orders
consumerGroup: processors
lagThreshold: "100"
Service Discovery
Set PRANOR_DISCOVERY as a ConfigMap:
apiVersion: v1
kind: ConfigMap
metadata:
name: pranor-discovery
data:
PRANOR_DISCOVERY: |
{
"gate": "http://pranor-gate:8080",
"vault": "http://pranor-vault:8081",
"pulse": "http://pranor-pulse:8082",
"cache": "http://pranor-cache:8086",
"trace": "http://pranor-trace:8090",
"auth": "http://pranor-auth:8098"
}
Next Steps
- Docker Deployment — Local/staging setup
- Standalone Binaries — No containers needed
- Security Model — mTLS between modules
Standalone Deployment
Run individual Pranor modules as native binaries without containers.
Build from Source
Each module can be built independently:
cd pranor/gate && go build -o pranor-gate .
cd pranor/vault && go build -o pranor-vault .
cd pranor/pulse && go build -o pranor-pulse .
cd pranor/trace && go build -o pranor-trace .
cd pranor/auth && go build -o pranor-auth .
cd pranor/cache && go build -o pranor-cache .
Run
# Start tracing first (other modules send traces here)
./pranor-trace --port 8090 &
# Start object storage
./pranor-vault --port 8081 --data-dir ./data &
# Start API gateway
./pranor-gate --port 8080 --config config.json &
# Start message broker
./pranor-pulse --port 8082 &
Unified Binary (pranord)
Run all modules in a single process:
cd pranor/platform
go build -o pranord .
./pranord --modules gate,vault,pulse,trace,auth,cache
systemd Service
[Unit]
Description=Pranor Gate API Gateway
After=network.target
[Service]
Type=simple
ExecStart=/usr/local/bin/pranor-gate --port 8080
Restart=always
RestartSec=5
Environment=PRANOR_OTLP_ENDPOINT=http://localhost:8090
[Install]
WantedBy=multi-user.target
Environment Setup
export PRANOR_HOME=/opt/pranor
export PRANOR_OTLP_ENDPOINT=http://localhost:8090
export PRANOR_DISCOVERY='{"gate":"http://localhost:8080","vault":"http://localhost:8081"}'
Next Steps
- Docker Deployment — Container-based setup
- Kubernetes — Production cluster deployment
Architecture Overview
Pranor is a modular backend infrastructure engine. Each module runs independently or together as a unified platform.
System Diagram
┌─────────────────────┐
│ Clients │
│ (Web, Mobile, API) │
└──────────┬──────────┘
│
┌──────────▼──────────┐
│ Pranor Gate │
│ API Gateway & │
│ Ingress Router │
└──────────┬──────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
┌─────────▼────────┐ ┌────────▼────────┐ ┌────────▼────────┐
│ Pranor Auth │ │ Pranor Mesh │ │ Pranor Cache │
│ Identity/RBAC │ │ Service Discovery│ │ Redis/Memory │
└──────────────────┘ └────────┬────────┘ └─────────────────┘
│
┌─────────────────────────┼─────────────────────────┐
│ │ │
┌────────▼────────┐ ┌────────────▼────────────┐ ┌─────────▼────────┐
│ Your Services │ │ Pranor Pulse │ │ Pranor Vault │
│ (.pnr files) │ │ Async Event Broker │ │ Object Storage │
└────────┬────────┘ └────────────┬────────────┘ └──────────────────┘
│ │
│ ┌───────────┼───────────┐
│ │ │ │
┌────────▼───────┐ ┌──▼──┐ ┌─────▼─────┐ ┌───▼───┐
│ Pranor Chrono │ │Flow │ │ Notify │ │ Pool │
│ Scheduler │ │ │ │ Email/SMS │ │ DB │
└────────────────┘ └─────┘ └───────────┘ └───────┘
│
┌────────▼───────────────────────────────────┐
│ Pranor Trace │
│ Distributed Tracing (OTLP) │
└────────────────────────────────────────────┘
│
┌────────▼───────────────────────────────────┐
│ Pranor Console │
│ Observability Dashboard UI │
└────────────────────────────────────────────┘
How Modules Connect
| From | To | Protocol | Purpose |
|---|---|---|---|
| Gate → Services | pranor:// | HTTP/gRPC via Mesh | Route requests to backends |
| Services → Pulse | STOMP/TCP | Async messaging | Publish events, consume queues |
| Services → Vault | S3 HTTP API | Object storage | Store files, vectors, configs |
| Services → Cache | Redis protocol | Caching | TTL-based key-value cache |
| Services → Pool | PostgreSQL wire | DB proxy | Connection pooling, read/write split |
| All → Trace | OTLP HTTP | Telemetry | Spans, metrics, logs |
| Chrono → Services | HTTP webhook | Scheduling | Trigger jobs on cron schedule |
| Flow → Services | HTTP | Orchestration | DAG workflow execution |
| Auth → Gate | JWT validation | Security | Token verification on every request |
Module Independence
Each module is:
- A standalone Go binary with zero external dependencies
- Independently deployable (Docker, K8s, bare metal)
- Horizontally scalable
- Observable via standard OTLP
No module requires any other module to function. The Pranor language compiler orchestrates them together when running a unified .pnr service, but each works alone.
Data Flow Example
A typical request through the full platform:
- Client sends
POST /api/ordersto Gate (port 8080) - Gate validates JWT via Auth, applies rate limiting
- Gate routes to your order service via Mesh discovery
- Your service writes order to Vault (S3 storage)
- Your service publishes
order.createdevent to Pulse - Chrono triggers a delayed notification job
- Notify sends confirmation email/SMS
- Trace captures the full request waterfall
- Console displays the trace in real-time
Next Steps
- Security Model
- Observability
- Module Docs — Detailed per-module documentation
Security Architecture
Pranor implements defense-in-depth across all modules.
Authentication & Authorization
| Layer | Mechanism | Module |
|---|---|---|
| API clients | JWT (RS256/ES256) + OAuth2/OIDC | Auth |
| Inter-service | mTLS with auto-rotating certificates | Mesh |
| Admin APIs | API key + RBAC | All modules |
| Browser sessions | Secure cookies + MFA (TOTP/WebAuthn) | Auth |
Zero-Trust Model
Every request between modules is authenticated:
Client → Gate (JWT validation)
→ Mesh (mTLS between services)
→ Target Service (RBAC enforcement)
No module trusts another implicitly. Mesh provides workload identity via SPIFFE.
Encryption
| Scope | Algorithm | Where |
|---|---|---|
| Data at rest | AES-256-GCM | Vault, Pulse |
| Data in transit | TLS 1.3 | All inter-module traffic |
| Secrets storage | AES-256-GCM + Shamir sharing | Secret |
| Browser queue | AES-256-GCM client-side | Pulse (OPFS) |
| JWT signing | RS256 or ES256 | Auth |
Enterprise Security (EE)
| Feature | Description |
|---|---|
| FIPS 140-3 mode | HSM-backed key management |
| Post-quantum crypto | X25519 + Kyber hybrid key exchange |
| Byzantine consensus | BFT Raft for tamper-resistant clusters |
| eBPF XDP acceleration | Kernel-level packet filtering |
| Blind broker E2EE | Pulse broker never sees plaintext messages |
| Merkle audit ledger | Tamper-evident append-only audit trail |
RBAC Model
// Define roles in Auth
POST /api/v1/rbac/roles
{
"name": "editor",
"permissions": ["read:articles", "write:articles"]
}
// Assign to users
POST /api/v1/rbac/users/user-123/roles
{ "roles": ["editor"] }
Gate enforces RBAC policies on every routed request.
Secret Management
Pranor Secret provides:
- Dynamic secret injection into processes
- Shamir key splitting for master key unsealing
- Automatic rotation with versioning
- Leak detection scanning
pranor secret inject --env production -- ./my-service
Next Steps
Observability
Every Pranor module emits traces, metrics, and logs through OpenTelemetry.
Stack
Your Services → Pranor Trace (OTLP collector) → Pranor Console (dashboard)
→ Jaeger / Grafana (optional)
Distributed Tracing
All modules propagate W3C traceparent headers automatically. A single request generates a connected trace across Gate → Mesh → Service → Pulse → Vault.
Setup
Set one environment variable on every module:
PRANOR_OTLP_ENDPOINT=http://pranor-trace:8090
View Traces
Open Pranor Console at http://localhost:8083:
- Waterfall trace view
- Service dependency map
- Latency percentiles (p50, p95, p99)
- Error rate tracking
- Trace search by ID, service, duration
Metrics
Every module exposes Prometheus-compatible metrics at GET /metrics:
| Metric | Type | Description |
|---|---|---|
pranor_http_requests_total | Counter | Total HTTP requests by route, method, status |
pranor_http_duration_seconds | Histogram | Request latency distribution |
pranor_queue_messages_total | Counter | Messages published/consumed (Pulse) |
pranor_queue_consumer_lag | Gauge | Consumer group lag (Pulse) |
pranor_cache_hits_total | Counter | Cache hit/miss ratio (Cache) |
pranor_pool_connections_active | Gauge | Active DB connections (Pool) |
pranor_vault_objects_total | Gauge | Stored objects count (Vault) |
Structured Logging
All modules emit JSON-structured logs with trace correlation:
{
"level": "info",
"msg": "request completed",
"trace_id": "abc123def456",
"span_id": "789xyz",
"service": "pranor-gate",
"duration_ms": 42,
"status": 200
}
Alerting
Pranor Console supports SLO-based burn rate alerts:
- Define SLOs (99.9% availability, p95 < 200ms)
- Multi-window burn rate detection
- Alert routing to Slack, email, PagerDuty
Health Checks
Every module exposes:
| Endpoint | Purpose |
|---|---|
GET /healthz | Liveness (is the process running?) |
GET /readyz | Readiness (can it serve traffic?) |
GET /metrics | Prometheus metrics |
Grafana Integration
Pranor Trace implements the Prometheus remote-write receiver protocol. Point your existing Grafana at:
Data Source: Prometheus
URL: http://pranor-trace:8090/api/v1/query
Next Steps
Complete Pranor Ecosystem Error Code Reference
This document provides an exhaustive, centralized index of all 140+ unique error codes used across Pranor microservices and language tools.
Every HTTP error response follows the standard format:
{
"error": "Detailed description",
"code": "ERR_EXAMPLE_CODE",
"status": 400
}
Pranor Auth (9 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/auth service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/auth service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/auth service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/auth service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/auth service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/auth service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/auth service layer. |
ERR_SESSION_REVOKED | Domain Policy | Error triggered in pranor/auth service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/auth service layer. |
Pranor Cache (6 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/cache service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/cache service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/cache service layer. |
ERR_INVALID_PAYLOAD | Client Error | Error triggered in pranor/cache service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/cache service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/cache service layer. |
Pranor Chrono (7 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_ADD_JOB_FAILED | Server Error | Error triggered in pranor/chrono service layer. |
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/chrono service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/chrono service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/chrono service layer. |
ERR_JOB_NOT_FOUND | Domain Policy | Error triggered in pranor/chrono service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/chrono service layer. |
ERR_TRIGGER_JOB_FAILED | Server Error | Error triggered in pranor/chrono service layer. |
Pranor Console (40 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_ALERT_NOT_FOUND | Domain Policy | Error triggered in pranor/console service layer. |
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/console service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/console service layer. |
ERR_CACHE_UNREACHABLE | Server Error | Error triggered in pranor/console service layer. |
ERR_CLOUD_UNREACHABLE | Server Error | Error triggered in pranor/console service layer. |
ERR_CONFIG_LOAD_FAILED | Server Error | Error triggered in pranor/console service layer. |
ERR_CONFIG_SAVE_FAILED | Server Error | Error triggered in pranor/console service layer. |
ERR_CREATE_REQUEST_FAILED | Server Error | Error triggered in pranor/console service layer. |
ERR_CRON_UNREACHABLE | Server Error | Error triggered in pranor/console service layer. |
ERR_DEPLOYMENT_NOT_FOUND | Domain Policy | Error triggered in pranor/console service layer. |
ERR_EE_REQUIRED | Domain Policy | Error triggered in pranor/console service layer. |
ERR_ENTERPRISE_REQUIRED | Domain Policy | Error triggered in pranor/console service layer. |
ERR_FETCH_TRACE_FAILED | Server Error | Error triggered in pranor/console service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/console service layer. |
ERR_INTERNAL | Server Error | Error triggered in pranor/console service layer. |
ERR_INTERNAL_ERROR | Server Error | Error triggered in pranor/console service layer. |
ERR_INVALID_BODY | Client Error | Error triggered in pranor/console service layer. |
ERR_INVALID_ENVIRONMENT | Client Error | Error triggered in pranor/console service layer. |
ERR_INVALID_PAYLOAD | Client Error | Error triggered in pranor/console service layer. |
ERR_INVALID_ROUTE_PAYLOAD | Client Error | Error triggered in pranor/console service layer. |
ERR_INVALID_SPAN_FORMAT | Client Error | Error triggered in pranor/console service layer. |
ERR_LOCK_CONNECT | Domain Policy | Error triggered in pranor/console service layer. |
ERR_MESH_UNREACHABLE | Server Error | Error triggered in pranor/console service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/console service layer. |
ERR_MISSING_FIELDS | Client Error | Error triggered in pranor/console service layer. |
ERR_MISSING_ID | Client Error | Error triggered in pranor/console service layer. |
ERR_MISSING_PARAM | Client Error | Error triggered in pranor/console service layer. |
ERR_MISSING_TRACE_ID | Client Error | Error triggered in pranor/console service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/console service layer. |
ERR_PARSE_TRACE_FAILED | Server Error | Error triggered in pranor/console service layer. |
ERR_REGISTRY_UNREACHABLE | Server Error | Error triggered in pranor/console service layer. |
ERR_ROUTE_NOT_FOUND | Domain Policy | Error triggered in pranor/console service layer. |
ERR_RUNBOOK_NOT_FOUND | Domain Policy | Error triggered in pranor/console service layer. |
ERR_SECRET_CONNECT | Domain Policy | Error triggered in pranor/console service layer. |
ERR_TENANT_ID_REQUIRED | Domain Policy | Error triggered in pranor/console service layer. |
ERR_TEST | Domain Policy | Error triggered in pranor/console service layer. |
ERR_TRACE_ID_REQUIRED | Domain Policy | Error triggered in pranor/console service layer. |
ERR_TRACE_NOT_FOUND | Domain Policy | Error triggered in pranor/console service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/console service layer. |
ERR_UNSUPPORTED_DRIVER | Domain Policy | Error triggered in pranor/console service layer. |
Pranor Core (10 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_API_KEY_REQUIRED | Domain Policy | Error triggered in pranor/core service layer. |
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/core service layer. |
ERR_CHAOS_DROPPED | Domain Policy | Error triggered in pranor/core service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/core service layer. |
ERR_INVALID_TOKEN | Client Error | Error triggered in pranor/core service layer. |
ERR_MISSING_AUTH | Client Error | Error triggered in pranor/core service layer. |
ERR_RATE_LIMIT_EXCEEDED | Domain Policy | Error triggered in pranor/core service layer. |
ERR_SCOPE_REQUIRED | Domain Policy | Error triggered in pranor/core service layer. |
ERR_TENANT_MISMATCH | Domain Policy | Error triggered in pranor/core service layer. |
ERR_VALIDATION_FAILED | Server Error | Error triggered in pranor/core service layer. |
Pranor Deploy (8 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/deploy service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/deploy service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/deploy service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/deploy service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/deploy service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/deploy service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/deploy service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/deploy service layer. |
Pranor Flow (8 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/flow service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/flow service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/flow service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/flow service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/flow service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/flow service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/flow service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/flow service layer. |
Pranor Gate (36 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_ACCESS_DENIED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_AI_WAF_BLOCKED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_BACKPRESSURE_TIMEOUT | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_BAD_GATEWAY | Client Error | Error triggered in pranor/gate service layer. |
ERR_BAD_GATEWAY_TARGET | Client Error | Error triggered in pranor/gate service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/gate service layer. |
ERR_CIRCUIT_OPEN | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_CONFIG_LOAD_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_CONFIG_SAVE_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_EE_REQUIRED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_FORBIDDEN_ROUTE | Client Error | Error triggered in pranor/gate service layer. |
ERR_GO_PLUGIN_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/gate service layer. |
ERR_INVALID_API_KEY | Client Error | Error triggered in pranor/gate service layer. |
ERR_INVALID_PATH | Client Error | Error triggered in pranor/gate service layer. |
ERR_INVALID_PAYLOAD | Client Error | Error triggered in pranor/gate service layer. |
ERR_INVALID_ROUTE_PAYLOAD | Client Error | Error triggered in pranor/gate service layer. |
ERR_IP_ACCESS_DENIED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_MISSING_API_KEY | Client Error | Error triggered in pranor/gate service layer. |
ERR_POLICY_DENIED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_PROMPT_INJECTION_DETECTED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_QUEUE_BRIDGE_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_QUEUE_FULL | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_QUEUE_RESPONSE_ERROR | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_RATE_LIMIT_EXCEEDED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_ROUTE_NOT_FOUND | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_SCHEMA_VALIDATION_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_TENANT_ACCESS_DENIED | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_TENANT_POLICY_VIOLATION | Domain Policy | Error triggered in pranor/gate service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/gate service layer. |
ERR_VALIDATION_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_WASM_COMPILATION_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_WASM_MIDDLEWARE_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_WS_HIJACK_FAILED | Server Error | Error triggered in pranor/gate service layer. |
ERR_WS_HIJACK_NOT_SUPPORTED | Domain Policy | Error triggered in pranor/gate service layer. |
Pranor Hub (26 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/hub service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/hub service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/hub service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/hub service layer. |
ERR_INVALID_JWT | Client Error | Error triggered in pranor/hub service layer. |
ERR_INVALID_PACKAGE_VERSION | Client Error | Error triggered in pranor/hub service layer. |
ERR_INVALID_PATH | Client Error | Error triggered in pranor/hub service layer. |
ERR_INVALID_PUBLIC_KEY | Client Error | Error triggered in pranor/hub service layer. |
ERR_INVALID_SCHEMA | Client Error | Error triggered in pranor/hub service layer. |
ERR_INVALID_SIGNATURE | Client Error | Error triggered in pranor/hub service layer. |
ERR_METADATA_UPLOAD_FAILED | Server Error | Error triggered in pranor/hub service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_MISSING_FILENAME | Client Error | Error triggered in pranor/hub service layer. |
ERR_MISSING_NAME_PARAMETER | Client Error | Error triggered in pranor/hub service layer. |
ERR_MISSING_SIGNATURE | Client Error | Error triggered in pranor/hub service layer. |
ERR_NAME_REQUIRED | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_PACKAGE_NOT_FOUND | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_PACKAGE_UPLOAD_FAILED | Server Error | Error triggered in pranor/hub service layer. |
ERR_PROVENANCE_NOT_FOUND | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_SCHEMA_NOT_FOUND | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_SIGNATURE_UPLOAD_FAILED | Server Error | Error triggered in pranor/hub service layer. |
ERR_SIGNATURE_VERIFICATION_FAILED | Server Error | Error triggered in pranor/hub service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/hub service layer. |
ERR_VERSION_CONFLICT | Domain Policy | Error triggered in pranor/hub service layer. |
ERR_VERSION_NOT_FOUND | Domain Policy | Error triggered in pranor/hub service layer. |
Pranor Lang (14 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_FORBIDDEN | Client Error | Error triggered in pranor/lang service layer. |
ERR_RATE_LIMIT_EXCEEDED | Domain Policy | Error triggered in pranor/lang service layer. |
ERR_ROUTE_NOT_FOUND | Domain Policy | Error triggered in pranor/lang service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/lang service layer. |
SRV-E001 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E002 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E003 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E004 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E005 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E006 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E007 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E008 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E009 | Domain Policy | Error triggered in pranor/lang service layer. |
SRV-E010 | Domain Policy | Error triggered in pranor/lang service layer. |
Pranor Mesh (8 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/mesh service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/mesh service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/mesh service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/mesh service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/mesh service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/mesh service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/mesh service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/mesh service layer. |
Pranor Notify (6 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/notify service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/notify service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/notify service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/notify service layer. |
ERR_TEMPLATE_COMPILE_ERROR | Domain Policy | Error triggered in pranor/notify service layer. |
ERR_UNSUPPORTED_CHANNEL | Domain Policy | Error triggered in pranor/notify service layer. |
Pranor Pool (9 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/pool service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/pool service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/pool service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/pool service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/pool service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/pool service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/pool service layer. |
ERR_SERVICE_UNAVAILABLE | Domain Policy | Error triggered in pranor/pool service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/pool service layer. |
Pranor Pulse (22 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/pulse service layer. |
ERR_BAD_REQUEST_BODY | Client Error | Error triggered in pranor/pulse service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/pulse service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/pulse service layer. |
ERR_INVALID_PATH | Client Error | Error triggered in pranor/pulse service layer. |
ERR_INVALID_TOKEN | Client Error | Error triggered in pranor/pulse service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/pulse service layer. |
ERR_MISSING_AUTH_HEADER | Client Error | Error triggered in pranor/pulse service layer. |
ERR_MISSING_DLQ_TOPIC | Client Error | Error triggered in pranor/pulse service layer. |
ERR_MISSING_FIELDS | Client Error | Error triggered in pranor/pulse service layer. |
ERR_MISSING_PARAMETERS | Client Error | Error triggered in pranor/pulse service layer. |
ERR_MISSING_TOPIC | Client Error | Error triggered in pranor/pulse service layer. |
ERR_MISSING_TOPIC_PARAMETER | Client Error | Error triggered in pranor/pulse service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/pulse service layer. |
ERR_QUERY_FAILED | Server Error | Error triggered in pranor/pulse service layer. |
ERR_RATE_LIMIT_EXCEEDED | Domain Policy | Error triggered in pranor/pulse service layer. |
ERR_REPLAY_FAILED | Server Error | Error triggered in pranor/pulse service layer. |
ERR_SEEK_FAILED | Server Error | Error triggered in pranor/pulse service layer. |
ERR_SQLITE_UNAVAILABLE | Domain Policy | Error triggered in pranor/pulse service layer. |
ERR_STREAMING_UNSUPPORTED | Domain Policy | Error triggered in pranor/pulse service layer. |
ERR_WASM_COMPILATION_FAILED | Server Error | Error triggered in pranor/pulse service layer. |
ERR_WASM_TRANSFORM_FAILED | Server Error | Error triggered in pranor/pulse service layer. |
Pranor Secret (5 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/secret service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/secret service layer. |
ERR_INTERNAL | Server Error | Error triggered in pranor/secret service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/secret service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/secret service layer. |
Pranor Trace (8 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/trace service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/trace service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/trace service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/trace service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/trace service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/trace service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/trace service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/trace service layer. |
Pranor Tunnel (10 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_GATEWAY | Client Error | Error triggered in pranor/tunnel service layer. |
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/tunnel service layer. |
ERR_CONFLICT | Domain Policy | Error triggered in pranor/tunnel service layer. |
ERR_FORBIDDEN | Client Error | Error triggered in pranor/tunnel service layer. |
ERR_GATEWAY_TIMEOUT | Domain Policy | Error triggered in pranor/tunnel service layer. |
ERR_INTERNAL_SERVER_ERROR | Server Error | Error triggered in pranor/tunnel service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/tunnel service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/tunnel service layer. |
ERR_NOT_IMPLEMENTED | Domain Policy | Error triggered in pranor/tunnel service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/tunnel service layer. |
Pranor Vault (29 Error Codes)
| Error Code | Category | Description / Typical Trigger |
|---|---|---|
ERR_BAD_REQUEST | Client Error | Error triggered in pranor/vault service layer. |
ERR_CLUSTER_NOT_ENABLED | Domain Policy | Error triggered in pranor/vault service layer. |
ERR_INVALID_PATH | Client Error | Error triggered in pranor/vault service layer. |
ERR_INVALID_POLICY | Client Error | Error triggered in pranor/vault service layer. |
ERR_INVALID_REQUEST_BODY | Client Error | Error triggered in pranor/vault service layer. |
ERR_INVALID_STATE | Client Error | Error triggered in pranor/vault service layer. |
ERR_METHOD_NOT_ALLOWED | Domain Policy | Error triggered in pranor/vault service layer. |
ERR_MISSING_CODE | Client Error | Error triggered in pranor/vault service layer. |
ERR_MISSING_PARAMETER | Client Error | Error triggered in pranor/vault service layer. |
ERR_NOT_FOUND | Domain Policy | Error triggered in pranor/vault service layer. |
ERR_NOT_LEADER | Domain Policy | Error triggered in pranor/vault service layer. |
ERR_OIDC_AUTH_URL_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_OIDC_NOT_CONFIGURED | Domain Policy | Error triggered in pranor/vault service layer. |
ERR_PLACEMENT_LOOKUP_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_POLICY_DELETE_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_POLICY_GET_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_POLICY_PUT_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_PRESIGNED_URL_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_RAFT_JOIN_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_RAFT_PROPOSE_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_SCHEMA_GET_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_SCHEMA_LIST_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_SCHEMA_NOT_FOUND | Domain Policy | Error triggered in pranor/vault service layer. |
ERR_SCHEMA_PUT_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_STORE_PUT_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_TOKEN_EXCHANGE_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_TOKEN_GENERATION_FAILED | Server Error | Error triggered in pranor/vault service layer. |
ERR_UNAUTHORIZED | Client Error | Error triggered in pranor/vault service layer. |
ERR_USER_INFO_FAILED | Server Error | Error triggered in pranor/vault service layer. |
Pranor Enterprise Edition
Pranor EE extends the open-source platform with features for regulated, high-scale, and multi-tenant environments.
Feature Comparison
| Feature | OSS | Enterprise |
|---|---|---|
| API Gateway (Gate) | ✅ | ✅ + WAF, GraphQL federation, eBPF XDP |
| Message Broker (Pulse) | ✅ | ✅ + Geo-replication, Kafka wire, BFT consensus |
| Object Storage (Vault) | ✅ | ✅ + Multi-cloud tiering, WORM compliance |
| Auth (OAuth2/OIDC/RBAC) | ✅ | ✅ + SAML, credential stuffing detection |
| Distributed Tracing (Trace) | ✅ | ✅ + NL query, cold-tier archival |
| Service Mesh | ✅ | ✅ + WireGuard overlay, adaptive LB |
| Workflow Engine (Flow) | ✅ | ✅ + Saga orchestrator, ML cost predictor |
| FIPS 140-3 / HSM | ❌ | ✅ |
| Post-Quantum Cryptography | ❌ | ✅ |
| eBPF Kernel Bypass | ❌ | ✅ |
| Multi-tenant isolation | Basic | Full namespace + quota |
| SLA: 99.99% uptime | ❌ | ✅ |
| Priority support | Community | 24/7 dedicated |
Key Enterprise Capabilities
Security
- FIPS 140-3 mode — HSM-backed key management for regulated industries
- Post-quantum hybrid crypto — X25519 + Kyber key exchange
- Blind broker E2EE — Pulse broker never sees message plaintext
- Byzantine Fault Tolerant consensus — Tamper-resistant Raft clustering
- Merkle audit ledger — Cryptographic proof of every operation
Scale
- Geo-replication — Active-active multi-region for Vault and Pulse
- eBPF XDP acceleration — Kernel-bypass packet processing for Gate
- SIMD/AVX-512 filters — Vectorized message filtering in Pulse
- Multi-cloud tiering — Automatic hot/warm/cold storage lifecycle
Compliance
- SOC 2 Type II evidence generation
- GDPR data residency controls
- WORM storage — Write-once-read-many for regulatory archives
- Audit trails — Every operation logged with tamper-proof integrity
Licensing
Enterprise features are gated behind //go:build enterprise build tags. They compile into the same binary — no separate installation needed.
# Build with enterprise features
go build -tags enterprise -o pranor-gate .
Contact
Enterprise Repo: github.com/vyuvaraj/pranor-ee (Private)
Next Steps
Enterprise Licensing & Edition Split
Pranor is distributed under a dual-licensing model designed for both open-source developers and enterprise organizations.
Edition Matrix
| Capability | Open-Source Edition (OSS) | Enterprise Edition (EE) |
|---|---|---|
| Core Monorepo Modules | 16 Modules Included | 16 Modules Included |
| License | Apache 2.0 / MIT | Commercial Enterprise License |
| High Availability & Clustering | Standalone & Basic Mesh | Active-Active Multi-Region, Raft Consensus |
| Security & Compliance | TLS 1.3, JWT, RBAC | FIPS 140-3, HSM Key Unsealing, PQC (Kyber) |
| Observability | OTel Tracing, Metrics | eBPF Continuous Profiling, Flamegraphs |
| Support | Community (GitHub / Discord) | 24/7 SLA, Dedicated Solutions Engineer |
Licensing Terms
Open-Source Edition (OSS)
The open-source components in github.com/vyuvaraj/pranor are available for free use, modification, and self-hosted deployment under standard open-source licenses.
Enterprise Edition (EE)
Enterprise overlay modules in github.com/vyuvaraj/pranor-ee require a commercial license key issued by Pranor Inc. Features are gated at compile time using Go build tags (//go:build enterprise).
Pranor Unified Changelog
Consolidated from all module changelogs.
auth
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
cache
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
chrono
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
console
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.1.0] - 2026-07-17
Added
- Implemented
/api/message/flowendpoint for tracking visual message timelines. - Implemented
/api/incidents/postmortemendpoint for automated incident postmortem generation.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
deploy
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
extension
3.4.0
Added
async&concurrentSyntax & Snippets (VS.G1): Full TextMate grammar highlighting and code snippets forasync fn,asynctask calls, andconcurrent {}parallel blocks.pranorctlCluster Administration Integration (VS.G2): Command palette commandPranor: pranorctl Cluster Administrationto runpranorctl get services,pranorctl get nodes,pranorctl restart service, andpranorctl apply config.pranor diffBreaking Change Detector (VS.G3): CommandPranor: Check Breaking API Changes (pranor diff)to run schema diffing against git base branch (main) with dedicated output logging.- Multi-Target Client Code Generation (VS.G4): Commands
Pranor: Generate Rust Client Code(--lang rust) andPranor: Generate Python Client Code(--lang python). - Platform Chaos Control Panel (VS.G5): Dedicated Webview panel to trigger/abort network delay, CPU stress, memory pressure, disk throttle, and clock skew faults across cluster nodes (
PL.G3). - WASM Playground & Pranor Console Export (VS.G6): Deep-linking command
Pranor: Export Current File to WASM Playground(playground.pranor.dev). pranordSingle-Binary Unified Console Webview (VS.G7): Unified multi-tab webview console (pranor.openServdConsole) with auto-detection forpranordsingle-binary status and health rollups.
3.3.0
Added
- Phase 35 Built-in Namespace Support: Integrated autocomplete suggestion lists, signature helper tooltips, and hover documentation for all 23 new Phase 35 built-in utility namespaces (including
exec,csv,yaml,diff,proto, etc.) and their sub-namespaces (e.g.encoding.base64,encoding.hex).
3.2.0
Added
- Symbol Renaming (CD.114): Added workspace-wide rename symbol refactoring support, allowing renaming variables, functions, and structs across all
.pnrfiles.
Fixed
- Light Theme Sidebar Contrast: Fixed sidebar action button contrast issues in light themes by using standard VS Code secondary state color variables.
3.1.0
Added
pranor.openPlaygroundCommand (CD.121): Embedded Monaco Web Playground directly inside a VS Code Webview panel, launching a local background compiler sandbox server.- Extended
pranor doctor(17.1): Enhanced diagnostics to automatically verify installed local WASM runtimes (node, wasmtime, wasmer) and local plugin/extension versions. - WinGet Installer Manifest (PKG.7): Created the
Yuvaraj.Pranor.yamlpackage manifest underrelease-scripts/to support automated Winget platform setups.
Fixed
- LSP Windows URI Normalization: Fixed a bug where differences in Windows path/URI casing and URL-encoding caused autocomplete lookups to return empty results.
- Robust JSON-RPC Parser: Fixed a stream desynchronization hang by parsing multiple incoming headers (e.g.
Content-Type) correctly and usingio.ReadFull. - Trace Options Fix: Fixed a
LanguageClientstart hang by correcting the trace configuration type to string'verbose'for compatibility withvscode-languageclientv9.
3.0.7
Added
- Project Scaffolding (CD.117) —
Pranor: New Project from Templateopens a 3-step flow: (1) Quick Pick from 5 templates (API Service, Worker, Scheduled, Full Stack, Minimal); (2) Input project name with validation; (3) Folder picker. Generatesmain.pnr,tests/,pranor.toml,.gitignore, andREADME.mdready to run. Opens the new project immediately. - One-Click Deploy (CD.118) —
Pranor: Deploy to Pranor Deployopens an environment picker (Production / Staging / Preview), then shows a dark Webview panel with live build log: compile → test → package → upload → provision → health check → deployed URL. Calls Pranor Deploy API at:8084; animates a mock flow when offline. - Coverage Line Highlights (CD.122) —
Pranor: Run Tests with Coverage Highlightsrunspranor test --coverage, then paints green-tinted lines for covered code and red-highlighted lines with✗ uncoveredannotations for uncovered code. Results appear in both the editor and the overview ruler. Falls back to realistic mock coverage when the binary isn’t available.Pranor: Clear Coverage Highlightsresets all decorations.
3.0.6
Added
- Pranor Activity Bar Panel (CD.119) — Dedicated sidebar icon in VS Code's Activity Bar showing all 17 services with live 🟢/🔴 health icons, port numbers, and uptime. Polls Pranor Hub every 6s. Shows mock data with
offlinebadge when registry is unreachable. Refresh button in panel title bar. - Pranor Tunnel Session Viewer (CD.120) —
pranor.viewTunnelsWebview dashboard showing active tunnel sessions with client IP, target host:port, protocol, duration, bytes in/out totals. Completes 17/17 service dashboard coverage. - Import Auto-Organization (CD.116) — Three-part feature: (1) Completion provider on
use <Tab>shows all 18 stdlib modules with description and API signature docs; (2) CodeActions quick-fix lightbulb adds missinguse <module>whendb.,cache.,http.etc. are used without import; (3)Pranor: Add Missing Importscommand adds all missing imports at once.
3.0.5
Added
- Inlay Type Hints (CD.113) — Always-on inline type hints in the editor for
fnreturn types (→ string) andletbindings (: int). Infers from return expression patterns:db.query()→Result,http.get()→Response, literals →string/int/bool/float. Togglable viapranor.enableInlayHintssetting. - Test Gutter Decorations (CD.115) — Run
pranor testvia the newPranor: Run Tests (with Gutter Decorations)command to paint 🟡 yellow dots on all test blocks before running, then 🟢 green or 🔴 red based on results. Results persist when switching tabs. Parses PASS/FAIL output lines; falls back to exit-code if unstructured. IncludesPranor: Clear Test Gutter Markersto reset all decorations.
3.0.4
Added
- Pranor Test Explorer — Sidebar panel in Explorer listing all
test "..."blocks from every.pnrfile, grouped by file with collapse/expand. Refreshes on save. - pranor bench panel (
pranor.runBench) — Runspranor bench <file>in terminal and opens a live p50/p99/throughput results panel per route. - Pranor Deploy Deployments (
pranor.viewDeployments) — Live table of branch preview deployments with URLs, build status, and auto-refresh. - Pranor Pool Inspector (
pranor.inspectPool) — DB connection pool dashboard showing active/idle/max connections per named pool, with wait-queue alerts. - Pranor Notify Queue (
pranor.inspectMail) — Email queue dashboard showing queued/sent/bounced counts and per-item status with template names.
3.0.3
Added
- Pranor Auth Progressive Risk Scoring Dashboard (
pranor.inspectAuth) tracing user devices, countries, and MFA step-ups. - Interactive REPL Launcher (
pranor.openREPL) — Spawns apranor replterminal inside VS Code for live expression evaluation without a full project build. - Pranor Mesh Topology Viewer (
pranor.viewMesh) — Renders a live Mermaid.js graph of all mesh service connections, with fallback static topology offline. - Pranor Trace Request Tracer (
pranor.traceRequests) — Shows distributed trace spans with filterable trace ID, service, operation, latency, and OK/ERROR status. Auto-refreshes every 5s. - Pranor Hub Health Monitor (
pranor.viewRegistry) — Full table of all registered microservices with live health checks, ports, and uptime. Auto-refreshes every 4s. - Status Bar Health Indicator — Persistent
$(circuit-board) Pranoritem in the editor footer, clicking opens the Registry Monitor. Turns amber with service count when any service is down.
3.0.2
Added
- Visual DAG Flowchart Designer (
pranor.visualizeWorkflow) rendering step sequences using Mermaid.js. - Pranor Pulse Broker Explorer (
pranor.exploreQueue) listing active partitions and consumer groups. - Pranor Vault Bucket Manager (
pranor.exploreStore) showing S3 directories. - Pranor Lock Contention Dashboard (
pranor.exploreLocks) tracing active lock waiters. - Pranor Gate Route Simulator (
pranor.simulateRoute) validating paths against config routes. - Pranor Chrono Scheduler Explorer (
pranor.exploreCron) monitoring schedules and smart analysis warnings. - Pranor Cache Stats Dashboard (
pranor.inspectCache) displaying cache hit ratios.
3.0.1
Fixed
- Colocated LSP path autodetection fixes and cross-platform terminal escaping corrections.
3.0.0
Added
- Full LSP integration (diagnostics, autocomplete, hover, go-to-definition)
- Commands: Run, Build, Test, Watch with keybindings
- Format on Save support via
pranor fmt - 30+ code snippets for common patterns
- Real-time diagnostics (type errors, unused variables, missing returns)
- Hover information for all symbols and built-in objects
- Editor title run button for
.pnrfiles
Improved
- TextMate grammar extended for generics, optional types, union types
- Snippet coverage for all language features (MCP tools, migrations, WebSocket, etc.)
2.0.0
Added
- Extended snippet library (structs, methods, error handling, middleware)
- Support for new language features (enums, generics, optional chaining)
- Configuration options for LSP and compiler paths
1.0.0
Added
- Initial release
- TextMate syntax highlighting for
.pnrfiles - Basic code snippets for routes, functions, and schedulers
- Extension icon and branding
flow
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
gate
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
lang
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.1.0] - 2026-07-17
Added
- Implemented
pranor changelogCLI command to display and filter the ecosystem release notes. - Added
--attach <host:port>flag topranor replto verify connectivity to a live service before prompt startup. - Implemented cross-service dead route static linter checking (
CD.78). - Added automated dependencies start mapping to
pranor devenvironment CLI.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
lock
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
mesh
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
notify
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
pool
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
pulse
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
trace
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
tunnel
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.
vault
All notable changes to this project will be documented in this file.
The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.
[1.0.0] - 2026-07-15
Added
- Standardized error format returning JSON structure (error, code, and race_id).
- Implemented /api/v1/ endpoint prefix support.
- Configured global protection middlewares: TraceMiddleware, RateLimitMiddleware, CORSMiddleware, MaxBytesMiddleware, AuthMiddleware, and TenantMiddleware.
- Upgraded and pinned all internal ecosystem dependency versions to target v1.0.0.