AI-native distributed logistics intelligence platform combining production-grade backend engineering with practical AI systems engineering.
LogiSynapse is a modern, event-driven shipment and billing platform with distributed workflow orchestration. It's designed as a learning project and production reference implementation that demonstrates:
- Distributed Systems: microservices, event-driven architecture, saga patterns, eventual consistency
- Production Engineering: idempotency, retries, observability, auditability, clean architecture
- AI Systems: retrieval-augmented generation (RAG), typed tools, workflow orchestration, AI evals
- Backend Mastery: Go service design, PostgreSQL/Redis/Kafka patterns, gRPC/GraphQL, authentication, authorization
LogiSynapse manages the complete shipment lifecycle: order creation β carrier selection β tracking updates β exception handling β billing β AI-assisted operational decisions.
- Architecture Overview
- Key Features
- Tech Stack
- Quick Start
- Service Domains
- Project Structure
- Development
- Learning Resources
LogiSynapse is organized into four loose-coupled planes that separate concerns and scale independently:
graph TB
subgraph "Product Plane"
GW["GraphQL Gateway"]
OrdSvc["Order Service"]
TrackSvc["Tracking Service"]
AuthSvc["Authentication Service"]
end
subgraph "Data Plane"
PG[("PostgreSQL")]
REDIS[("Redis<br/>Cache")]
KAFKA["Kafka"]
PGVEC[("pgVector<br/>Search")]
end
subgraph "Workflow Plane"
TEMPORAL["Temporal<br/>Orchestrator"]
WF["Workflow<br/>Service"]
end
subgraph "Intelligence Plane"
AIGTW["AI Gateway"]
RETR["Retrieval<br/>Service"]
MODEL["Model<br/>Gateway"]
EVAL["Eval<br/>Service"]
end
subgraph "External"
SHIPPO["Shippo API"]
STRIPE["Stripe"]
SMTP["Email/SMS"]
end
GW -->|validate token| AuthSvc
GW -->|GraphQL| OrdSvc
GW -->|GraphQL| TrackSvc
OrdSvc -->|read/write| PG
OrdSvc -->|publish events| KAFKA
TrackSvc -->|cache reads| REDIS
TrackSvc -->|fallback| PG
KAFKA -->|consume| WF
KAFKA -->|consume| EVAL
WF -->|orchestrate| TEMPORAL
WF -->|integrate| SHIPPO
AuthSvc -->|persist| PG
AIGTW -->|retrieve context| RETR
RETR -->|semantic search| PGVEC
RETR -->|read facts| PG
AIGTW -->|call model| MODEL
MODEL -->|tokens| STRIPE
EVAL -->|quality checks| KAFKA
| Plane | Purpose | Components | Why It Matters |
|---|---|---|---|
| Product Plane | User-facing workflows | GraphQL Gateway, Order, Tracking, Auth | Low latency, clear APIs, user experience |
| Data Plane | Durable facts & read models | PostgreSQL, Redis, Kafka, pgVector | Correctness, replay, consistency, search |
| Workflow Plane | Long-running execution | Temporal, workflow workers | Durability, retry safety, compensation |
| Intelligence Plane | AI retrieval, reasoning, tools | AI Gateway, Retrieval, Model Gateway, Evals | Grounded context, tool safety, quality control |
-
Event-Driven Architecture
- Transactional outbox pattern for reliable event publishing
- Kafka topic-per-aggregate-type for replay and consumer groups
- Idempotent event handlers prevent duplicate processing
-
Durable Workflow Orchestration
- Temporal-backed long-running business processes
- Automatic retry, compensation, and saga support
- Transparent replay on failures without data corruption
-
Multi-Tenant Authentication & Authorization
- JWT-based access tokens with refresh-token rotation
- Tenant membership with role-based access (RBAC)
- Audit trail for all security events
-
AI-Native Capabilities
- Semantic search over shipment data and policies
- Retrieval-augmented generation (RAG) for operator assistance
- Typed tools prevent AI hallucination and enforce data validation
- Quality evaluation pipeline tracks AI reliability
-
Production-Grade Observability
- OpenTelemetry traces across all services
- Structured logging with correlation IDs
- Prometheus metrics and health checks
- Audit logs for compliance and debugging
-
Clean Architecture
- Domain β Application β Port β Adapter separation
- No business logic leaks into database or HTTP layers
- Testable, swappable infrastructure
- Clear bounded contexts per service
| Layer | Technology | Purpose | Why Chosen |
|---|---|---|---|
| Services | Go 1.24+ | Backend services, gRPC, CLI tools | Fast, concurrent, simple, strong typing, production reliability |
| API Gateway | GraphQL + gRPC | Public and internal service boundaries | Type safety, strong contracts, code generation, federation |
| Database | PostgreSQL 15+ | Transactional data, JSONB, full-text search | ACID compliance, rich querying, proven at scale, pgVector for embeddings |
| Caching | Redis | Hot read cache, session storage | Sub-millisecond latency, atomic operations, Pub/Sub |
| Events | Apache Kafka | Domain events, event replay, consumer groups | Distributed durability, topic replay, ordering guarantees |
| Workflows | Temporal | Long-running orchestration, retries | Durable execution, automatic compensation, visibility |
| Search | pgVector + PostgreSQL | Semantic and hybrid search | Embedding storage, HNSW indexing, single database |
| Message Queue | RabbitMQ | Async task distribution, notifications | Dead-letter queues, manual ack, familiar for operations |
| Observability | OpenTelemetry + Prometheus | Tracing, metrics, logs | Vendor-neutral, standard instrumentation, ecosystem |
| Container | Docker & Docker Compose | Local development, deployment units | Reproducibility, isolation, multi-service orchestration |
| Auth | JWT (HMAC SHA-256) | Stateless access tokens, session management | Fast verification, no central lookup, refresh-token rotation |
Get LogiSynapse running in ~5 minutes.
# Verify versions
go version # Go 1.24+
docker --version # Docker 24.0+
docker compose version # Docker Compose 2.0+git clone https://github.com/Tanmoy095/LogiSynapse.git
cd LogiSynapseThe .env file is already configured with sensible defaults for local development:
# Review/edit if needed (most defaults are fine for local dev)
cat .env
# For production, create a separate config and update:
# - AUTH_JWT_SECRET (change from default)
# - STRIPE_SECRET_KEY (add your actual key)
# - SHIPPO_API_KEY (add your actual key)If you need the template for reference:
cp .env.example .env.local # Keep original, create a variant# Build all service images and start containers
docker compose up --build
# First run: images build and migrations run (~30-60s)
# Subsequent runs: just start containers (~5-10s)
# Logs stream in real-time; press Ctrl+C to stop# In another terminal, verify containers are running:
docker compose ps
# Expected output: all services showing "Up"
# - postgres (port 5432)
# - authentication-service (port 50052)
# - shipment-service (port 50051)
# - graphql-gateway (port 8080)
# - kafka (port 9092)
# - rabbitmq (ports 5672, 15672)
# - temporal, temporal-db, temporal-ui# GraphQL Gateway health
curl http://localhost:8080/health
# Expected: {"status":"healthy","service":"graphql-gateway"}
# GraphQL playground (no auth required for UI)
open http://localhost:8080/
# RabbitMQ Management UI
open http://localhost:15672/ # guest:guest
# Temporal Workflow UI
open http://localhost:8088/# 1. Register a user (no auth required)
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { registerUser(input: {email: \"user@example.com\" password: \"SecurePass123!\" firstName: \"John\" lastName: \"Doe\"}) { userId } }"
}'
# 2. Login to get tokens
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-d '{
"query": "mutation { loginUser(input: {email: \"user@example.com\" password: \"SecurePass123!\"}) { accessToken refreshToken } }"
}'
# 3. Use the accessToken in protected queries
# Replace TOKEN with the actual token from login response
curl -X POST http://localhost:8080/query \
-H "Content-Type: application/json" \
-H "Authorization: Bearer TOKEN" \
-d '{
"query": "query { shipments { id status carrier } }"
}'Or use the GraphQL Playground UI at http://localhost:8080/ with the same queries.
# Test all services
go test ./...
# Test with verbose output
go test -v ./...
# Test a specific service
cd services/shipment-service
go test ./...
# Run with race detector (recommended)
go test -race ./...# Stop all containers
docker compose down
# Also remove volumes (WARNING: deletes database data)
docker compose down -v| Service | Responsibility | Primary API | Integrations | Language |
|---|---|---|---|---|
| GraphQL Gateway | Public GraphQL API, bearer-token auth, tenant routing | GraphQL over HTTP | Auth Service, Shipment Service | Go |
| Authentication Service | Users, tenants, memberships, JWT tokens, auth audit | gRPC (JSON codec) | PostgreSQL, Kafka | Go |
| Shipment Service | Shipment creation, tracking, carrier integration | gRPC | Shippo API, PostgreSQL, Kafka | Go |
| Billing Service | Usage tracking, invoices, ledger, payments | gRPC | PostgreSQL, Stripe API, Kafka | Go |
| Workflow Orchestrator | Long-running shipment workflows, retries, compensation | Temporal SDK | Temporal Server, Shippo API, RabbitMQ | Go |
| Communications Service | Email, SMS, webhook notifications | gRPC | Email provider, SMS provider, RabbitMQ | Go |
LogiSynapse/
βββ services/ # Microservices (each is independent, deployable)
β βββ authentication-service/ # User, tenant, role, token management
β β βββ cmd/main.go # Service entrypoint
β β βββ internal/
β β β βββ domain/ # Business logic (no dependencies)
β β β βββ app/ # Use cases (coordinates domain)
β β β βββ ports/ # Interfaces (contracts)
β β β βββ infra/ # Adapters (SQL, gRPC, HTTP)
β β β βββ transport/ # API handlers
β β β βββ config/ # Configuration
β β βββ db/migrations/ # SQL migrations (Goose)
β β βββ Dockerfile
β β βββ go.mod
β β
β βββ graphql-gateway/ # Public GraphQL entry point
β β βββ cmd/main.go
β β βββ graph/ # GraphQL resolvers
β β βββ client/ # gRPC clients to services
β β βββ Dockerfile
β β
β βββ shipment-service/ # Shipment lifecycle, carrier integration
β β βββ cmd/main.go
β β βββ service/
β β βββ handler/grpc/
β β βββ store/
β β βββ db/migrations/
β β βββ Dockerfile
β β
β βββ billing-service/ # Usage, invoices, payments
β β βββ internal/
β β β βββ accounts/
β β β βββ billing/
β β β βββ invoice/
β β β βββ ledger/
β β β βββ payment/
β β β βββ usage/
β β βββ db/migrations/
β β βββ go.mod
β β
β βββ workflow-orchestrator/ # Temporal-based durable workflows
β β βββ cmd/main.go
β β βββ workflows/
β β βββ activities/
β β βββ go.mod
β β
β βββ communications-service/ # Email, SMS, webhooks
β βββ cmd/main.go
β βββ go.mod
β
βββ shared/ # Shared libraries (contracts, Kafka, config)
β βββ contracts/ # Protobuf models
β βββ kafka/ # Kafka producer/consumer
β βββ proto/ # .proto files and generated code
β βββ rabbitmq/ # RabbitMQ client
β βββ config/ # Configuration loading
β βββ go.mod
β
βββ docs/ # Architecture, decisions, learning
β βββ mainreadme.md # High-level overview
β βββ 01-business/ # Business context
β βββ 02-system-design/ # HLD & LLD documents
β β βββ 00-implementation-status.md
β β βββ 01-system-overview-hld.md
β β βββ 02-architecture-design-hld.md
β β βββ 03-database-design-hld.md
β β βββ 04-caching-and-async-hld.md
β β βββ 05-networking-concepts-hld.md
β β βββ 06-low-level-design-lld.md
β β βββ 07-project-structure-lld.md
β βββ 03-microservices/
β βββ 05-infrastructure/
β βββ 06-observability/
β βββ 07-roadmaps/
β βββ 08-deployment/
β βββ 09-decisions/ # ADRs (Architecture Decision Records)
β βββ 10-learning/
β
βββ docker-compose.yml # Local development stack
βββ .env.example # Environment template
βββ go.mod # Root module (if used)
βββ LICENSE # GPLv3
βββ README.md # This file
- Learn System Design: Start with docs/mainreadme.md
- Architecture Decisions: See docs/09-decisions/
- Implementation Status: Check docs/02-system-design/00-implementation-status.md
- Service Structure: Review docs/02-system-design/07-project-structure-lld.md
- Database Schema: See docs/02-system-design/03-database-design-hld.md
Client Request (GraphQL)
β
GraphQL Gateway
ββ Validate bearer token (auth-service)
ββ Parse tenant from X-Tenant-ID header
ββ Route to shipment-service
β
Shipment Service
ββ Validate order data
ββ Insert shipment + outbox rows (single transaction)
ββ Return shipment ID
β
Outbox Relay (background job)
ββ Poll outbox table
ββ Publish to Kafka: shipment.created.v1
ββ Mark as published
β
Kafka Consumers
ββ Workflow Service β starts fulfillment
ββ Tracking Service β creates read model
ββ Billing Service β records usage event
ββ Notification Service β schedules customer email
Client Query (GraphQL)
β
Tracking Service
ββ Try Redis cache lookup (key: tracking:{shipment_id})
ββ Hit? β Return cached result (99% case)
ββ Miss?
ββ Query PostgreSQL
ββ Update Redis cache (60s TTL)
ββ Return result
Client Login Request
β
Auth Service
ββ Normalize email
ββ Hash password with Argon2id
ββ Verify against stored hash
ββ Generate JWT access token (15 min TTL)
ββ Generate refresh token (opaque, 7 days)
ββ Hash and store refresh token in DB
ββ Return both tokens
β
GraphQL Gateway (subsequent requests)
ββ Extract bearer token from Authorization header
ββ Call auth-service: ValidateAccessToken
ββ Extract claims (user_id, tenant_id, role)
ββ Store in request context
ββ Resolve GraphQL query with identity context
Containers fail to start or crash immediately
# Check logs for the failing service
docker compose logs graphql-gateway
docker compose logs authentication-service
docker compose logs shipment-service
# Rebuild from scratch
docker compose down
docker system prune -a --volumes
docker compose up --buildPort already in use
# Check which process is using the port
lsof -i :8080 # GraphQL gateway
lsof -i :50052 # Auth service
lsof -i :50051 # Shipment service
# Kill the process
kill -9 <PID>
# Or update docker-compose.yml portsMigrations fail on startup
# Check auth service logs
docker compose logs authentication-service
# Manually run migrations
docker compose exec postgres psql -U postgres -d logisynapse -f /migrations/001_create_users.sqlDatabase connection refused
# Ensure PostgreSQL is healthy
docker compose ps postgres
# Check health status
docker compose logs postgres | grep "ready to accept"
# Wait a bit longer and retry
docker compose down
docker compose up --build --waitCannot connect to authentication-service from gateway
# Verify services are on the same network
docker network inspect loginet
# Check gateway logs for connection errors
docker compose logs graphql-gateway | grep "failed to connect"
# Ping from gateway container
docker compose exec graphql-gateway ping authentication-service
# Verify DNS resolution
docker compose exec graphql-gateway getent hosts authentication-servicegRPC connection timeouts
# Ensure AUTH_SERVICE_ADDR in .env matches docker-compose
# Should be: authentication-service:50052 (not localhost:50052)
# Check if service is actually listening
docker compose exec authentication-service netstat -tulnp | grep 50052Tests fail with "dial tcp: lookup localhost: no such host"
# When testing in Docker, use service names, not localhost
# In docker-compose: authentication-service:50052
# In localhost dev: localhost:50052
# Run tests locally (not in container)
go test ./services/authentication-service/...# Test all services
go test ./...
# Test with coverage
go test -cover ./...
# Test a specific service
cd services/shipment-service && go test ./...
# Run tests with race detector
go test -race ./...Migrations are managed per-service using Goose:
# Apply migrations (happens automatically on service startup with AUTO_MIGRATE=true)
cd services/authentication-service
goose postgres "postgres://user:pass@localhost/db" up
# Rollback
goose postgres "postgres://user:pass@localhost/db" downRegenerate artifacts after schema changes:
# GraphQL (from schema.graphql)
cd services/graphql-gateway
go generate ./...
# Protocol Buffers (from .proto files)
cd shared/proto
protoc --go_out=. --go-grpc_out=. *.proto-
Create
services/my-service/with structure matching existing services:services/my-service/ βββ cmd/main.go # Service entrypoint βββ internal/ β βββ domain/ # Business logic β βββ app/ # Use cases β βββ ports/ # Interfaces β βββ infra/ # Adapters (SQL, gRPC) β βββ transport/ # API handlers β βββ config/ # Configuration βββ db/migrations/ # SQL migrations βββ Dockerfile βββ go.mod βββ go.sum βββ README.md # Service-specific docs -
Create a service
README.mddocumenting:- Service purpose and responsibilities
- API/gRPC contracts
- Database schema
- Configuration options
- Example requests
- Known limitations
-
Add to
docker-compose.ymlwith:- Build context and Dockerfile
- Port mappings
- Environment variables
- Health check
- Dependencies
- Network and volumes
-
Wire into GraphQL gateway if needed:
// Add client in services/graphql-gateway/client/my-service.client.go // Update resolver.go to inject the client
-
Document in docs/02-system-design/07-project-structure-lld.md
- Use
docker compose upfor the full stack (simulates production) - Run
go mod tidyafter changing dependencies - Run
go fmt ./...before committing - Add tests for new behavior (unit + integration)
- Document decisions in
docs/09-decisions/
-
Distributed Systems
- Event-driven architecture patterns
- Eventual consistency and CAP theorem tradeoffs
- Saga patterns for distributed transactions
- Idempotency, retries, and circuit breakers
-
Backend Engineering
- Clean architecture and hexagonal design
- Database transactions and outbox pattern
- gRPC, GraphQL, and API design
- Authentication, authorization, multi-tenancy
-
Production Patterns
- Observability: tracing, logging, metrics
- Audit trails and compliance
- Configuration management
- Health checks and graceful shutdown
-
AI Systems Engineering
- Retrieval-augmented generation (RAG)
- Semantic search with embeddings
- Agent workflows and tool calling
- AI quality evaluation
- docs/mainreadme.md β High-level vision
- docs/02-system-design/01-system-overview-hld.md β System architecture
- docs/02-system-design/02-architecture-design-hld.md β Design deep-dive
- docs/09-decisions/ β Architecture decision records
- Service READMEs β Start with services/authentication-service/
- Event Sourcing by Martin Fowler
- Microservices Patterns by Chris Richardson
- Temporal Workflow Orchestration
- PostgreSQL Best Practices
- Authentication: JWT access tokens with SHA-256 HMAC, refresh-token rotation
- Authorization: Role-based access control (RBAC), tenant isolation
- Audit: Complete audit trail of user actions and state changes
- Data: PostgreSQL transactions, no unencrypted secrets in code
- API: Bearer token validation on every protected endpoint
All services are instrumented with:
- Traces: OpenTelemetry context propagation across service boundaries
- Metrics: Prometheus-compatible metrics (request latency, error rates, queue depth)
- Logs: Structured JSON logging with correlation IDs
- Health:
/healthendpoints with service readiness checks
View observability data:
# (Add observability stack to docker-compose.yml)
# Jaeger: http://localhost:16686 (traces)
# Prometheus: http://localhost:9090 (metrics)
# Grafana: http://localhost:3000 (dashboards)- Multi-service Go architecture with clean boundaries
- PostgreSQL with migrations and transactional consistency
- GraphQL gateway with authentication middleware
- JWT-based multi-tenant authentication and authorization
- gRPC service-to-service communication
- Docker Compose local development stack
- Basic service documentation and architecture decisions
- Kafka topic-per-service event publishing
- Transactional outbox pattern in shipment-service
- Event replay and consumer group support
- Idempotent event handlers across services
- Temporal workflow definitions for shipment lifecycle
- Activity implementations for carrier integration
- Compensation and saga patterns
- Temporal Web UI integration with logs
- Retrieval service with pgVector semantic search
- Embedding generation for shipments and policies
- AI gateway for quota and token management
- Orchestrated AI agents for investigation and decisions
- LangGraph integration for multi-step reasoning
- Distributed tracing with Jaeger
- Prometheus metrics and custom dashboards
- Structured logging with correlation IDs
- Health checks and graceful shutdown
- Service resilience patterns (circuit breaker, etc.)
- Order service with outbox pattern
- Billing service ledger and invoice generation
- Notification service with email/SMS/webhook
- Rate limiting and quota enforcement
- API versioning and backward compatibility
- Kubernetes deployment manifests
- CI/CD pipeline (GitHub Actions)
- Automated testing suite (unit, integration, E2E)
- Security audit and penetration testing
- Performance benchmarks and load testing
We welcome contributions! Please:
- Follow conventional commits:
feat(service): description - Keep changes focused: One feature or fix per PR
- Add tests: New behavior must have unit + integration tests
- Document decisions: Architecture changes deserve a brief ADR
- Run the full stack:
docker compose up --build && go test ./...
GPLv3 β see the LICENSE file for details.
- Issues: Report bugs or request features via GitHub Issues
- Discussions: Ask questions in GitHub Discussions
- Documentation: See docs/ for architecture and design decisions
Built with β€οΈ for learning and production engineering excellence.
LogiSynapse is designed around clear, loosely coupled planes that separate product concerns, data ownership, orchestration, and intelligence.
- Event-driven architecture with transactional outbox and Kafka for replayable domain events
- Durable workflow orchestration using Temporal for long-running, retryable processes
- AI-native capabilities including retrieval, RAG, typed tools, and audited AI workflows
- Microservices design with clear bounded contexts for order, tracking, billing, notifications, and AI
- Observability and auditability with OpenTelemetry, metrics, traces, and a full audit trail
- Production patterns such as idempotency, retries, compensation, and strong testing boundaries
- Product plane: API gateway, order, tracking, support, dispatch
- Data plane: PostgreSQL, Redis, Kafka, vector DB for durable facts and read models
- Workflow plane: Temporal workers and orchestrators for durable business processes
- Intelligence plane: AI gateway, model gateway, retrieval, tool-service, and eval pipelines
- Order write: API -> order-service -> Postgres + outbox -> outbox relay -> Kafka -> downstream consumers
- Tracking read: API -> tracking-service -> Redis cache -> Postgres fallback
- AI assistant: ai-gateway -> retrieval -> model -> typed tools -> validated, cited response
| Service | Responsibility | Primary Integrations |
|---|---|---|
| api-gateway | Public API surface, auth, rate limits | GraphQL / REST |
| order-service | Accept orders, outbox, idempotency | Postgres, Kafka |
| tracking-service | Shipment timeline and read models | Redis, Postgres |
| workflow-service | Temporal workflows and retries | Temporal, Shippo |
| billing-service | Usage aggregation, ledger, invoices | Stripe, Postgres |
| notification-service | Email, SMS, webhooks | RabbitMQ, SQS |
| ai-gateway | Tenant AI requests, quotas, streaming | model-gateway, retrieval |
| retrieval-service | Embeddings and hybrid search | pgvector / Qdrant |
LogiSynapse/
βββ services/
β βββ shipment-service/
β βββ workflow-orchestrator/
β βββ graphql-gateway/
β βββ communications-service/
β βββ billing-service/
βββ shared/
βββ docs/
βββ graphify-out/
βββ docker-compose.yml
βββ README.md
- Go 1.24+
- Docker and Docker Compose
- Shippo API key for shipment workflows
- Stripe API key for billing workflows
-
Clone the repository.
git clone https://github.com/Tanmoy095/LogiSynapse.git cd LogiSynapse -
Create a
.envfile in the project root with the required database and integration settings. -
Start the local stack.
docker compose up --build
-
Open the local tools.
- GraphQL Playground: http://localhost:8080/
- Temporal Web UI: http://localhost:8088/
- RabbitMQ Management: http://localhost:15672/
- Mutations:
createShipment,updateShipment, and related workflow actions - Queries:
shipments,usageSummary,invoiceHistory
- ShipmentService:
CreateShipment,GetShipments - BillingService:
GetInvoices,CreateInvoice,FinalizeInvoice
- Usage summary by tenant, period, and type
- Invoice history and invoice details
- Ledger views for transaction-level auditability
-
Run tests:
go test ./... -
Database migrations are managed with Goose under service migration folders.
-
Regenerate proto and GraphQL artifacts after schema changes.
-
Keep health checks and observability hooks in place for each service.
-
Use OpenTelemetry for traces and metrics across the stack.
- Add Kafka to local compose for end-to-end event testing
- Expand unit, integration, and E2E coverage
- Strengthen logging, tracing, and AI evaluation pipelines
- Harden the gateway with authentication and authorization
- Add CI/CD, Makefile tasks, and deployment manifests
- Follow conventional commits.
- Keep changes small and focused on one responsibility.
- Add tests and documentation for new behavior.
- Document tradeoffs and failure modes for architecture changes.
GPLv3 - see the LICENSE file for details.