{"id":50147653,"url":"https://github.com/hoangsonww/aegisvision-computer-vision-system","last_synced_at":"2026-06-02T08:00:32.703Z","repository":{"id":359904609,"uuid":"1247945712","full_name":"hoangsonww/AegisVision-Computer-Vision-System","owner":"hoangsonww","description":"🛰️ A distributed, GPU-native visual-intelligence OS. Ingests any video, runs detection and reasoning on partitioned GPUs, and drives bounded-autonomy agents over the result. Built on the scars of running CV at scale.","archived":false,"fork":false,"pushed_at":"2026-06-02T06:08:58.000Z","size":2343,"stargazers_count":9,"open_issues_count":24,"forks_count":8,"subscribers_count":9,"default_branch":"master","last_synced_at":"2026-06-02T07:23:10.980Z","etag":null,"topics":["argocd","docker","go","grafana","grpc","helm","istio","k3s","kafka","kubernetes","loki","nvidia","oidc","opentelemetry","postgresql","prometheus","tempo","triton-inference-server","webrtc","xds"],"latest_commit_sha":null,"homepage":"https://hoangsonww.github.io/AegisVision-Computer-Vision-System/","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/hoangsonww.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":"CONTRIBUTING.md","funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":"CITATION.cff","codeowners":".github/CODEOWNERS","security":"SECURITY.md","support":"SUPPORT.md","governance":"GOVERNANCE.md","roadmap":"ROADMAP.md","authors":"AUTHORS","dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":"MAINTAINERS","copyright":null,"agents":"docs/agents.md","dco":null,"cla":null},"funding":{"github":["hoangsonww"],"custom":["https://sonnguyenhoang.com","https://linkedin.com/in/hoangsonw"]}},"created_at":"2026-05-24T01:45:08.000Z","updated_at":"2026-06-02T06:33:33.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/hoangsonww/AegisVision-Computer-Vision-System","commit_stats":null,"previous_names":["hoangsonww/aegisvision-computer-vision-system"],"tags_count":6,"template":false,"template_full_name":null,"purl":"pkg:github/hoangsonww/AegisVision-Computer-Vision-System","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoangsonww%2FAegisVision-Computer-Vision-System","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoangsonww%2FAegisVision-Computer-Vision-System/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoangsonww%2FAegisVision-Computer-Vision-System/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoangsonww%2FAegisVision-Computer-Vision-System/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/hoangsonww","download_url":"https://codeload.github.com/hoangsonww/AegisVision-Computer-Vision-System/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/hoangsonww%2FAegisVision-Computer-Vision-System/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":33812204,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-02T02:00:07.132Z","response_time":109,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["argocd","docker","go","grafana","grpc","helm","istio","k3s","kafka","kubernetes","loki","nvidia","oidc","opentelemetry","postgresql","prometheus","tempo","triton-inference-server","webrtc","xds"],"created_at":"2026-05-24T06:01:03.355Z","updated_at":"2026-06-02T08:00:32.695Z","avatar_url":"https://github.com/hoangsonww.png","language":"Go","funding_links":["https://github.com/sponsors/hoangsonww","https://sonnguyenhoang.com","https://linkedin.com/in/hoangsonw"],"categories":[],"sub_categories":[],"readme":"\u003cdiv align=\"center\"\u003e\n\n\u003ch1\u003e🛡️ AegisVision\u003c/h1\u003e\n\n\u003cp\u003e\u003cb\u003eAn open, distributed, GPU-native computer-vision platform \u003cem\u003etemplate\u003c/em\u003e\nthat any individual or organization can fork, brand, and operate as the\nbackbone of their own realtime perception product — multimodal inference on\nNVIDIA Triton, bounded-autonomy agents, gated promotion, and signed\nair-gapped delivery, out of the box.\u003c/b\u003e\u003c/p\u003e\n\n\u003cp\u003e\n  \u003cimg alt=\"Go\" src=\"https://img.shields.io/badge/Go-1.26-00ADD8.svg?style=flat-square\u0026logo=go\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"gRPC\" src=\"https://img.shields.io/badge/gRPC-protobuf-244c5a.svg?style=flat-square\u0026logo=grpc\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Protobuf\" src=\"https://img.shields.io/badge/Protobuf-Buf-1A1A1A.svg?style=flat-square\u0026logo=protobuf\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Bash\" src=\"https://img.shields.io/badge/Bash-CLI-4EAA25.svg?style=flat-square\u0026logo=gnubash\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"HTML5\" src=\"https://img.shields.io/badge/HTML5-Console-E34F26.svg?style=flat-square\u0026logo=html5\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"JavaScript\" src=\"https://img.shields.io/badge/JavaScript-Console-F7DF1E.svg?style=flat-square\u0026logo=javascript\u0026logoColor=black\"\u003e\n  \u003cimg alt=\"Mermaid\" src=\"https://img.shields.io/badge/Mermaid-diagrams-FF3670.svg?style=flat-square\u0026logo=mermaid\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Kubernetes\" src=\"https://img.shields.io/badge/Kubernetes-1.27%2B-326CE5.svg?style=flat-square\u0026logo=kubernetes\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Helm\" src=\"https://img.shields.io/badge/Helm-charts-0F1689.svg?style=flat-square\u0026logo=helm\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Istio\" src=\"https://img.shields.io/badge/Istio-Ambient_mTLS-466BB0.svg?style=flat-square\u0026logo=istio\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"ArgoCD\" src=\"https://img.shields.io/badge/ArgoCD-GitOps-EF7B4D.svg?style=flat-square\u0026logo=argo\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"OPA\" src=\"https://img.shields.io/badge/OPA-AuthZ-7D4698.svg?style=flat-square\u0026logo=openpolicyagent\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Kyverno\" src=\"https://img.shields.io/badge/Kyverno-admission-1D8BF1.svg?style=flat-square\u0026logo=kubernetes\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"SPIRE\" src=\"https://img.shields.io/badge/SPIRE-SPIFFE-1F4493.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"External Secrets\" src=\"https://img.shields.io/badge/External_Secrets-ESO-3A2D7E.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"Vault\" src=\"https://img.shields.io/badge/Vault-transit_keys-FFEC6E.svg?style=flat-square\u0026logo=vault\u0026logoColor=black\"\u003e\n  \u003cimg alt=\"Terraform\" src=\"https://img.shields.io/badge/Terraform-IaC-7B42BC.svg?style=flat-square\u0026logo=terraform\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"PostgreSQL\" src=\"https://img.shields.io/badge/PostgreSQL-Patroni_HA-316192.svg?style=flat-square\u0026logo=postgresql\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"ClickHouse\" src=\"https://img.shields.io/badge/ClickHouse-3%C3%972_replicated-FFCC01.svg?style=flat-square\u0026logo=clickhouse\u0026logoColor=black\"\u003e\n  \u003cimg alt=\"Redis\" src=\"https://img.shields.io/badge/Redis-Sentinel_HA-DC382D.svg?style=flat-square\u0026logo=redis\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"NATS\" src=\"https://img.shields.io/badge/NATS-JetStream-27AAE1.svg?style=flat-square\u0026logo=natsdotio\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Kafka\" src=\"https://img.shields.io/badge/Kafka-durable_bus-231F20.svg?style=flat-square\u0026logo=apachekafka\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Object Store\" src=\"https://img.shields.io/badge/Object_Store-S3%2FMinIO%2FCeph-569A31.svg?style=flat-square\u0026logo=amazons3\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"SQLite\" src=\"https://img.shields.io/badge/SQLite-dev_mode-003B57.svg?style=flat-square\u0026logo=sqlite\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"pgvector\" src=\"https://img.shields.io/badge/pgvector-RAG-336791.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"NVIDIA Triton\" src=\"https://img.shields.io/badge/NVIDIA-Triton_Inference-76B900.svg?style=flat-square\u0026logo=nvidia\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"TensorRT-LLM\" src=\"https://img.shields.io/badge/TensorRT--LLM-LLM_serving-76B900.svg?style=flat-square\u0026logo=nvidia\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"DeepStream\" src=\"https://img.shields.io/badge/DeepStream-SDK-76B900.svg?style=flat-square\u0026logo=nvidia\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"MIG\" src=\"https://img.shields.io/badge/MIG-default_partitioning-76B900.svg?style=flat-square\u0026logo=nvidia\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"ByteTrack\" src=\"https://img.shields.io/badge/ByteTrack-tracker-555555.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"DeepSORT\" src=\"https://img.shields.io/badge/DeepSORT-tracker-555555.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"vLLM\" src=\"https://img.shields.io/badge/vLLM-OSS_backend-3F6FE0.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"OpenAI compat\" src=\"https://img.shields.io/badge/OpenAI-compatible_API-412991.svg?style=flat-square\u0026logo=openai\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Anthropic\" src=\"https://img.shields.io/badge/Anthropic-supported_backend-D97757.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"Bedrock\" src=\"https://img.shields.io/badge/AWS_Bedrock-supported_backend-FF9900.svg?style=flat-square\u0026logo=amazonaws\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"OpenTelemetry\" src=\"https://img.shields.io/badge/OpenTelemetry-OTLP-425CC7.svg?style=flat-square\u0026logo=opentelemetry\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Prometheus\" src=\"https://img.shields.io/badge/Prometheus-RED_metrics-E6522C.svg?style=flat-square\u0026logo=prometheus\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Loki\" src=\"https://img.shields.io/badge/Loki-logs-FCB037.svg?style=flat-square\u0026logo=grafana\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Tempo\" src=\"https://img.shields.io/badge/Tempo-traces-F46800.svg?style=flat-square\u0026logo=grafana\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Grafana\" src=\"https://img.shields.io/badge/Grafana-dashboards-F46800.svg?style=flat-square\u0026logo=grafana\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"slog\" src=\"https://img.shields.io/badge/slog-structured_logs-00ADD8.svg?style=flat-square\u0026logo=go\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Cosign\" src=\"https://img.shields.io/badge/Cosign-keyless_signing-3D8B40.svg?style=flat-square\u0026logo=sigstore\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Sigstore\" src=\"https://img.shields.io/badge/Sigstore-Rekor-3D8B40.svg?style=flat-square\u0026logo=sigstore\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"SLSA\" src=\"https://img.shields.io/badge/SLSA-v1_provenance-1D5CC8.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"Syft\" src=\"https://img.shields.io/badge/Syft-SBOM_SPDX-1B6EC2.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"OIDC\" src=\"https://img.shields.io/badge/OIDC-JWT%20%2B%20JWKS-1D5CC8.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"RFC 9457\" src=\"https://img.shields.io/badge/RFC_9457-problem%2Bjson-555555.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"GDPR\" src=\"https://img.shields.io/badge/GDPR-DPIA-005EB8.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"SOC 2\" src=\"https://img.shields.io/badge/SOC_2-controls-005EB8.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"EU AI Act\" src=\"https://img.shields.io/badge/EU_AI_Act-conformity-003399.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"chaos-mesh\" src=\"https://img.shields.io/badge/chaos--mesh-resilience_gate-A21B7B.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"k6\" src=\"https://img.shields.io/badge/k6-load_tests-7D64FF.svg?style=flat-square\u0026logo=k6\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"WAL-G\" src=\"https://img.shields.io/badge/WAL--G-PostgreSQL_backup-316192.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"clickhouse-backup\" src=\"https://img.shields.io/badge/clickhouse--backup-snapshots-FFCC01.svg?style=flat-square\u0026logo=clickhouse\u0026logoColor=black\"\u003e\n  \u003cimg alt=\"GitHub Actions\" src=\"https://img.shields.io/badge/GitHub_Actions-CI-2088FF.svg?style=flat-square\u0026logo=githubactions\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Docker\" src=\"https://img.shields.io/badge/Docker-distroless-2496ED.svg?style=flat-square\u0026logo=docker\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Buf\" src=\"https://img.shields.io/badge/Buf-proto_lint_%2B_breaking-1A1A1A.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"release-please\" src=\"https://img.shields.io/badge/release--please-versioning-4285F4.svg?style=flat-square\u0026logo=googlecloud\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"Task\" src=\"https://img.shields.io/badge/Task-runner-29BEB0.svg?style=flat-square\u0026logo=task\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"zstd\" src=\"https://img.shields.io/badge/zstd-bundle_compression-4343431.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"k3s\" src=\"https://img.shields.io/badge/k3s-edge-FFC61C.svg?style=flat-square\u0026logo=k3s\u0026logoColor=black\"\u003e\n  \u003cimg alt=\"Jetson\" src=\"https://img.shields.io/badge/NVIDIA_Jetson-edge-76B900.svg?style=flat-square\u0026logo=nvidia\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"RTSP\" src=\"https://img.shields.io/badge/RTSP-stream_ingest-123123.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"WebRTC\" src=\"https://img.shields.io/badge/WebRTC-stream_ingest-333333.svg?style=flat-square\u0026logo=webrtc\u0026logoColor=white\"\u003e\n  \u003cimg alt=\"SSE\" src=\"https://img.shields.io/badge/SSE-realtime_push-123456.svg?style=flat-square\"\u003e\n  \u003cimg alt=\"WebSocket\" src=\"https://img.shields.io/badge/WebSocket-realtime-999999.svg?style=flat-square\"\u003e\n\u003c/p\u003e\n\n\u003chr/\u003e\n\n\u003cimg src=\"https://readme-typing-svg.demolab.com?font=Fira+Code\u0026pause=900\u0026color=00ADD8\u0026center=true\u0026vCenter=true\u0026width=900\u0026lines=Frames+never+go+on+the+bus.+(ADR-0008);Agents+do+not+auto-execute+consequential+actions.+(ADR-0014%2F0017);One+LLM+gateway.+(ADR-0018);Wilson+lower-bound+%2B+min-sample+floor.+(ADR-0023);Air-gapped+bundle+as+day-one+CI+artifact.+(ADR-0027)\" alt=\"taglines\" /\u003e\n\n\u003c/div\u003e\n\n---\n\n\n\nAegisVision is a **production-grade template** for building computer-vision\nproducts. Fork it, point it at your cameras and your **NVIDIA Triton\nInference Server**, and you have the backbone of a realtime perception\nplatform — without re-inventing claim-check ring buffers, MIG-aware GPU\nscheduling, Wilson-bound canary promotion, RAG-cited agents, or a\nsigned air-gap bundle. It encodes the lessons learned from operating\nlarge CV platforms (Matroid, Scale, Roboflow, ClearML, Sensible) as\nload-bearing architectural rules:\n\n- **Frames must never go on the bus.** (Claim-check, ADR-0008.)\n- **The control plane must never see per-frame work.** (Two-plane separation,\n  ADR-0001.)\n- **GPUs are partitioned, not shared by hope.** (MIG-default + Triton\n  model-control, ADR-0003.)\n- **Agents must not auto-execute consequential actions.** (Bounded autonomy,\n  ADR-0014/0017.)\n- **Every public answer about platform state must cite its source.** (RAG over\n  plain LLM, ADR-0020.)\n- **Canary promotion is a statistical test, not a hand-wave.** (Wilson lower\n  bound, ADR-0023.)\n- **Air-gapped installation is a first-class CI artifact, not an afterthought.**\n  (Bundle-as-day-one, ADR-0027.)\n\nThis repository ships **35 Go services + 1 Next.js console**, **14\nshared libraries**, **39 Helm charts** (including a dedicated, hardened\nNVIDIA Triton chart), **30 Architecture Decision Records**, and a\ncomplete set of **compliance evidence packages** (SOC 2, EU AI Act, GDPR\nDPIA, pen-test scope). The codebase is **green end-to-end** under a\ncross-service integration smoke suite and a 39-chart Helm conformance\ntest, with a production-ready Next.js console at\n[`services/console/`](./services/console) that exposes every public API as\na usable page. Everything in this repository is permissively licensed\n(Apache 2.0) — you can lift it wholesale and use it as the foundation of\nyour own CV product.\n\n---\n\n## Table of contents\n\n1. [What is AegisVision?](#what-is-aegisvision)\n2. [Use AegisVision as a template](#use-aegisvision-as-a-template)\n3. [Capabilities at a glance](#capabilities-at-a-glance)\n4. [Repository layout](#repository-layout)\n5. [Quickstart — walking skeleton](#quickstart--walking-skeleton)\n6. [The 35 services](#the-35-services)\n7. [NVIDIA Triton — the GPU inference core](#nvidia-triton--the-gpu-inference-core)\n8. [Architectural commitments (the ADRs)](#architectural-commitments-the-adrs)\n9. [Public API discipline](#public-api-discipline)\n10. [Errors, idempotency, pagination](#errors-idempotency-pagination)\n11. [Observability](#observability)\n12. [Security posture](#security-posture)\n13. [Deploy](#deploy)\n14. [How to contribute](#how-to-contribute)\n15. [Further reading](#further-reading)\n\n---\n\n## What is AegisVision?\n\nAegisVision is a **horizontally-scaled, multi-tenant, GPU-native visual\nintelligence platform**. In one sentence: it ingests video streams from any\nsource, runs configurable detection / tracking / reasoning pipelines on\nGPUs, fires rule-based and ML-based events, supports an agentic conversational\ninterface over the platform, continuously learns from operator feedback, and\ndeploys to anything from a single laptop to a 10,000-stream production\nKubernetes cluster (or an air-gapped DMZ).\n\nConcretely, the platform answers questions like:\n\n- *\"Was there a person on the loading dock between 02:00 and 02:15?\"*\n- *\"How many forklifts crossed zone 7 today, and which ones lingered more\n  than 60 seconds?\"*\n- *\"This new model improves recall by 4% — promote it if the drop in\n  precision is statistically insignificant.\"*\n- *\"Alert me whenever the dwell-time SLO burns a quarter of its monthly\n  error budget in under an hour.\"*\n- *\"Show me the five most recent uncertain detections so I can label them.\"*\n- *\"Has data drift in stream pool A crossed the model owner's threshold?\"*\n\nIt does this with **bounded autonomy**: agents can answer, advise, and execute\nreversible work, but anything consequential (promoting a model, overriding a\nretention policy, force-rolling-back a canary) routes through a\nhuman-approval gate by design. There is no force-promote endpoint anywhere\nin the platform — that is a deliberate architectural property, not an\nomission.\n\n```mermaid\nflowchart LR\n    subgraph Edge / On-prem\n        CAM[Cameras / RTSP / Files]\n    end\n    subgraph Stream tier\n        SM[stream-manager]\n        DR[dataplane-runner]\n    end\n    subgraph GPU tier\n        IR[inference-router]\n        TRT[Triton + TRT-LLM]\n        GS[gpu-scheduler]\n    end\n    subgraph Control plane\n        AG[api-gateway]\n        PS[pipeline-service]\n        MR[model-registry]\n        TS[tenant-service]\n    end\n    subgraph Event tier\n        ES[event-service]\n        RH[realtime-hub]\n        NS[notification-service]\n    end\n    subgraph Storage\n        CH[(ClickHouse)]\n        PG[(Postgres)]\n        OBJ[(Object store)]\n    end\n    subgraph Intelligence tier\n        LG[llm-gateway]\n        AS[agent-service]\n        PG2[policy-gate-service]\n        KS[knowledge-service]\n    end\n\n    CAM --\u003e SM\n    SM --\u003e DR\n    DR --\u003e IR\n    IR --\u003e TRT\n    DR -- detections --\u003e ES\n    ES --\u003e CH\n    ES --\u003e RH\n    RH --\u003e NS\n    AG --\u003e PS\n    AG --\u003e ES\n    AG --\u003e AS\n    AS --\u003e LG\n    AS --\u003e KS\n    AS --\u003e PG2\n    IR --\u003e GS\n    PS --\u003e MR\n```\n\n---\n\n## Use AegisVision as a template\n\nAegisVision is structured to be **forked and adapted** — not just admired.\nThe pieces you usually have to glue together yourself are already wired:\n\n- **A hardened NVIDIA Triton chart** with MIG-aware scheduling, KServe v2\n  client, response-cache, dynamic batching, model warm-up, model-control\n  modes, and KEDA-driven autoscaling on Triton's own queue-duration\n  metrics. See [`docs/triton.md`](./docs/triton.md) and\n  [`deploy/helm/triton/`](./deploy/helm/triton).\n- **A two-plane architecture** (control plane / data plane) with strict\n  rules about what is allowed where, so your perception product scales\n  without becoming an event-loop tar pit.\n- **A bounded-autonomy agent runtime** that you can extend with your own\n  tools while inheriting the tier-3 human-gate refusal in code.\n- **Compliance scaffolding** (SOC 2 / EU AI Act / GDPR / pen-test) you\n  can adopt verbatim or trim, with evidence pipelines wired to the\n  audit log.\n- **GitOps-first deploy** (ArgoCD ApplicationSet + 39 Helm charts) and\n  a signed air-gap bundle for regulated environments.\n\n### Adapt it to your product in three moves\n\n1. **Rename the brand.** Run\n   `task template:rebrand:dry-run PRODUCT_NAME=YourProduct PRODUCT_SLUG=yourproduct ENV_PREFIX=YOURPROD`\n   first to preview, then drop `:dry-run` to apply. The full\n   playbook — module path rewrite, LICENSE handling, secrets,\n   IdP wiring, observability, and an adoption checklist — lives in\n   [`TEMPLATE.md`](./TEMPLATE.md).\n2. **Plug in your models.** Drop your TensorRT / ONNX / PyTorch / Python\n   models into the Triton model repository (see\n   [`docs/triton.md`](./docs/triton.md) for the layout, plus an\n   example tree at\n   [`deploy/helm/triton/examples/`](./deploy/helm/triton/examples))\n   and register them via the platform's `/v1/models` endpoint.\n3. **Pick a deploy path.** Walking-skeleton on a laptop, ArgoCD on a\n   cluster, or signed air-gap bundle on a DMZ — see\n   [`SETUP_GUIDE.md`](./SETUP_GUIDE.md).\n\nThe ADRs explain *why* each rule exists, so you can override them on\npurpose — never by accident.\n\nAfter your first deploy, run `task template:check` — it walks the\nadoption checklist (modules build, `go vet`, race-detected tests,\nHelm conformance, integration smoke, proto lint) and reports\nanything red.\n\nTo exercise the full stack locally with one command:\n\n```bash\ntask dev:up           # docker-compose: Postgres + NATS + Kafka + ClickHouse + MinIO + OTel\ntask run:event-service \u0026\ntask run:api-gateway \u0026\n# … any other services you want to iterate on …\ntask seed:demo        # seeds a demo tenant, pipeline, model, stream\n```\n\nSee [`deploy/dev/README.md`](./deploy/dev/README.md) for env-var\nexports and connection URLs.\n\n---\n\n## Capabilities at a glance\n\nThe platform is organized into seven capability areas. Every area is\nload-bearing and verified end-to-end under unit, conformance, and\nintegration suites.\n\n| Capability area | What it gives you |\n| --- | --- |\n| **Foundations** | Buf-managed protobuf contracts, the golden-path `pkg/platform` library (logging, OTel, metrics, problem+json, idempotency, pagination, health, shutdown), and a walking-skeleton spine. |\n| **Glass-to-event ingest** | `api-gateway`, `pipeline-service`, `stream-manager`, `event-service`, `dataplane-runner` — produces a real detection event end-to-end with p95 ≈ 2.7 ms on local hardware (300 ms target). |\n| **GPU hot path** | NVIDIA Triton Inference Server with MIG-aware scheduling, dynamic batching, response cache, model warm-up, KServe v2 client; `inference-router` + `gpu-scheduler` + canary plumbing. |\n| **Multi-tenant + edge + storage** | Patroni Postgres, ClickHouse, Vault transit per-tenant keys, Redis Sentinel, k3s edge profile with outbox sync. |\n| **Intelligence tier** | One LLM/VLM gateway, bounded-autonomy agent runtime, RAG citation discipline, NLQ, active learning, policy-gate-service. |\n| **Adaptive autonomy** | Canary controller (Wilson lower bound), shadow inference, drift detection (JS/KL/TVD), multi-window SLO burn-rate, predictive prefetch, autonomy orchestrator. |\n| **Operations \u0026 compliance** | Compliance evidence service, air-gapped bundle builder, chaos engineering harness, DR drill runner, release automation, append-only audit log. |\n| **Production console** | Next.js 14 + Tailwind UI exposing every public REST endpoint as a usable page (33 routes). Conformance-clean Helm chart. |\n\n**49 of 49 Go modules** build and test green under `-race`.\n**39 of 39 Helm charts** pass the conformance test (mTLS STRICT, AuthZ ALLOW\nlist, NetworkPolicy default-deny, ServiceMonitor, HPA, PDB).\n**Cross-service integration smoke tests** cover bus subjects, wildcards,\nconcurrent gate resolutions, the bounded-autonomy round trip, and LLM\nsafety refusal.\n\nAdopting AegisVision as a template means you inherit all of this on day\none. A real production rollout still needs your own SOC 2 / EU AI Act\naudit window and a physical cluster — the platform is *ready for* them.\n\n---\n\n## Repository layout\n\n```\n/proto                    Buf-managed protobuf contracts. ADR-0007.\n/pkg\n  /platform               Golden-path Go library: logging, OTel, metrics,\n                          problem+json, health, pagination, idempotency,\n                          shutdown, config, auth, middleware, RFC9457.\n  /bus                    Event bus abstraction: NATS, Kafka, in-process, DualBus.\n  /dataplane              Streaming operator runtime + claim-check ring +\n                          operators (ingest, sampler, detect, tracker, rule, emit).\n  /store                  SQL access + migrate runner (Patroni, sqlite for dev).\n  /llm                    LLM gateway client + safety layer (sanitize + redact +\n                          refusal threshold).\n  /agent                  Bounded-autonomy agent runtime + tool router + gate hook.\n  /embeddings             Vector store + chunker; pgvector + faiss-compatible.\n  /intelligence           Active learning + uncertainty + NLQ types.\n  /canary                 Wilson lower bound + min-sample floor + traffic split.\n  /autonomy               Cron + signal scheduler + divergence math (JS / KL / TVD).\n/services                 35 Go services + 1 Next.js console. Each its own\n                          bounded context, each its own deployable.\n/deploy\n  /helm                   39 charts. One per service, plus nats, dataplane\n                          runtime, triton, edge-profile, and the console.\n  /argocd                 ApplicationSet for GitOps reconciliation of all charts.\n  /k8s\n    /base                 Namespaces, priority classes, default-deny network policy.\n    /policies             Kyverno admission policies.\n    /quotas               Per-namespace resource quotas.\n  /platform\n    /istio                Ambient mTLS STRICT + AuthorizationPolicies.\n    /observability        OpenTelemetry collector, Prometheus, Loki, Tempo.\n    /spire                SPIRE workload identity.\n    /vault                Vault + transit + ExternalSecrets bootstrap.\n    /data                 Patroni Postgres, Redis Sentinel, ClickHouse Operator.\n    /argocd               ArgoCD bootstrap.\n  /chaos                  10 chaos experiments (chaos-mesh manifests).\n  /terraform              Cloud-side infrastructure (managed Kubernetes etc.).\n/tools\n  /airgap                 build.sh / install.sh / verify.sh — bundle the world\n                          for offline install. ADR-0027.\n  /conformance            38-chart Helm chart conformance test (mTLS, AuthZ, NP).\n  /integration            5-test cross-service contract smoke suite.\n  /loadtest               k6 scripts: 10k streams, 1k agents, slo gate.\n  /dr-drills              Quarterly DR drill harness + per-component restore.\n  /audit                  Audit-log append validator + signature verifier.\n  /proto                  Lint + breaking-change checker for /proto.\n  /scaffold               Service scaffolder (used to bootstrap a new service).\n  /scripts                Misc operational scripts.\n/docs\n  /adr                    30 Architecture Decision Records.\n  /compliance             SOC 2 controls, EU AI Act conformity, GDPR DPIA,\n                          pen-test scope, full evidence packages.\n  /runbooks               Operational runbooks (incident, oncall, DR, chaos,\n                          drift spike, canary rollback, agent incident).\n```\n\n---\n\n## Quickstart — walking skeleton\n\nThe walking skeleton (ADR-0016) is the smallest end-to-end slice of the\nplatform — five services + an embedded NATS in five terminals — and\nproduces a real detection event in under five seconds. It is the\nrecommended starting point if you are evaluating AegisVision as a\ntemplate for your own product.\n\n```bash\nbrew install go-task                       # task runner\ntask bootstrap                             # install tools + first build\ntask proto                                 # regenerate protobuf bindings\ntask build                                 # build every Go module\ntask test                                  # run unit tests with -race\n```\n\nThen in five terminals:\n\n```bash\n# 1) event-service embeds NATS in dev mode\nAEGIS_EMBED_NATS=true task run:event-service\n# Note the URL it logs, then export it for the others:\nexport AEGIS_NATS_URL=nats://127.0.0.1:NNNNN\n\n# 2-4) The control + data plane\ntask run:pipeline-service\nAEGIS_NATS_URL=$AEGIS_NATS_URL task run:stream-manager\nAEGIS_NATS_URL=$AEGIS_NATS_URL task run:dataplane-runner\n\n# 5) The public REST + SSE entrypoint + console\nAEGIS_STREAM_MANAGER_ADDR=localhost:9092 \\\nAEGIS_EVENT_SERVICE_URL=http://localhost:8090 \\\nAEGIS_CONSOLE_DIR=$(pwd)/services/api-gateway/console \\\n  task run:api-gateway\n```\n\nIn two more terminals:\n\n```bash\n# Subscribe to the SSE feed:\ncurl -N -H 'X-Tenant-Id: t-demo' \\\n  'http://localhost:8080/v1/events:stream?stream_id=stream-dock-1'\n\n# Create a stream (this fires the synthetic detector, the dwell rule\n# trips at ~5 s, the event lands on NATS, event-service consumes it, and\n# the SSE pushes it to your subscriber):\ncurl -X POST -H 'X-Tenant-Id: t-demo' -H 'Idempotency-Key: 1' \\\n  -H 'Content-Type: application/json' \\\n  -d '{\"name\":\"dock-1\",\"project_id\":\"p1\",\"protocol\":\"file\",\"url\":\"file:///x\",\"pipeline_id\":\"p-walking\"}' \\\n  http://localhost:8080/v1/streams\n```\n\nOr, simpler, open \u003chttp://localhost:8080/console/\u003e in a browser.\n\nThe walking-skeleton flow is:\n\n```mermaid\nsequenceDiagram\n    actor User\n    participant AG as api-gateway\n    participant SM as stream-manager\n    participant DR as dataplane-runner\n    participant NATS as NATS JetStream\n    participant ES as event-service\n\n    User-\u003e\u003eAG: POST /v1/streams (Idempotency-Key)\n    AG-\u003e\u003eSM: gRPC CreateStream\n    SM-\u003e\u003eNATS: operator.control (start)\n    NATS-\u003e\u003eDR: receive control msg\n    DR-\u003e\u003eDR: build operator DAG\u003cbr/\u003e(ingest→sampler→detect→tracker→rule→emit)\n    DR-\u003e\u003eNATS: events.v1 (KIND_DWELL)\n    NATS-\u003e\u003eES: consume\n    ES--\u003e\u003eUser: SSE event push\n```\n\nFor full deployment paths (online ArgoCD / offline air-gapped), see\n[`SETUP_GUIDE.md`](./SETUP_GUIDE.md).\n\n---\n\n## The 35 services\n\nThe platform is decomposed into **35 services**, each in its own Go module,\neach with a single bounded responsibility, each communicating over typed\nprotobuf contracts (gRPC + JSON/REST for tenant-facing APIs).\n\n### Control plane (Temporal-friendly)\n\n| Service | Purpose |\n| --- | --- |\n| `api-gateway` | Public REST entrypoint. JWT verify via JWKS, OPA AuthZ, RFC 9457 errors, idempotency, cursor pagination, SSE proxy. |\n| `pipeline-service` | CRUD + revisions for pipeline DAGs. ADR-friendly resource model. |\n| `stream-manager` | Stream lifecycle. Dispatches control messages to dataplane-runner via NATS `operator.control`. |\n| `model-registry` | Versioned model artifacts + signatures + canary planning. |\n| `dataset-service` | Datasets + dataset versions + lineage. |\n| `annotation-service` | Labels + label-policy versions. |\n| `training-orchestrator` | Wraps training jobs (Kubeflow / Ray). Tracks artifacts. |\n| `media-service` | Recordings + clips + retention policies (crypto-shredded by tenant key). |\n| `tenant-service` | Tenants + projects + members + RBAC. |\n| `auth-proxy` | JWT verify against JWKS. Tenant injection. No HMAC support (ADR-0018). |\n| `audit-service` | Append-only audit log. Hash-chained. Failed-audit-required (ADR-0014). |\n\n### Data plane (per-frame, never on Temporal)\n\n| Service | Purpose |\n| --- | --- |\n| `dataplane-runner` | Hosts the streaming operator DAG (ingest → sampler → detect → tracker → rule → emit). The `Detector` interface lets you swap the Go-native operator for NVIDIA DeepStream, a pure-Triton client, or a custom backend without touching the rest of the pipeline. |\n| `inference-router` | The GPU front door. Routes inference requests to NVIDIA Triton over the KServe v2 protocol (HTTP today, gRPC streaming + shared memory swap-in via the same `Detector` interface), surfaces Triton response-cache hits, applies per-tenant model allow-lists, and publishes `inference.completed.v1` + `inference.baseline.v1` + `inference.outcome.v1`. |\n| `gpu-scheduler` | MIG-default GPU reservation ledger. Coordinates Triton model placement against MIG slices for hard isolation between tenants and pipelines. |\n| `rule-engine` | Rule evaluation: dwell, count, line-cross, zone-enter. |\n| `event-service` | Consumes `events.v1` from NATS; serves SSE feed; persists to ClickHouse. |\n| `realtime-hub` | Fan-out WebSocket hub for console + integrations. |\n| `notification-service` | Webhooks, email, Slack with replay-safe idempotency. |\n| `edge-gateway` | k3s-friendly reduced-operator runtime; sync to core via outbox. |\n\n### Intelligence tier\n\n| Service | Purpose |\n| --- | --- |\n| `llm-gateway` | OpenAI-compatible internal endpoint. Sanitizer + PII redactor + refusal threshold + token accounting. No raw model calls anywhere else (ADR-0018). |\n| `agent-service` | Bounded-autonomy agent runtime. Tier-3 tools route through policy-gate-service. Auto-resume on `gate.resolved.\u003e`. |\n| `policy-gate-service` | Human-in-the-loop approval gate. Audit on every decision. |\n| `knowledge-service` | RAG corpus over docs + ADRs + runbooks. Citation-mandatory (ADR-0020). |\n| `active-learning-service` | Uncertainty + diversity sampling (ADR-0019). |\n| `nlq-service` | Natural-language query → structured queries against event-service / ClickHouse. |\n\n### Adaptive autonomy\n\n| Service | Purpose |\n| --- | --- |\n| `canary-controller` | Wilson lower-bound + min-sample floor proportion test. Promotion gated; rollback automatic (ADR-0023). |\n| `shadow-inference-service` | Same-URN candidate-vs-baseline comparator (ADR-0024). |\n| `drift-detection-service` | JS / KL / TVD divergence vs reference (ADR-0025). |\n| `slo-watchdog` | Multi-window burn-rate. Google SRE workbook implementation. |\n| `prefetch-service` | 7×24 EMA grid; warm-ups dispatched at horizon ahead of demand (ADR-0026). |\n| `autonomy-orchestrator` | Cron + signal-driven agent sessions (ADR-0022). |\n\n### Operations \u0026 compliance\n\n| Service | Purpose |\n| --- | --- |\n| `compliance-evidence-service` | Owns no data; composes evidence via Collector interface (ADR-0029). |\n| `semantic-search` | Cross-tenant semantic search over events + clips. |\n| `cost-accounting` | Per-tenant GPU-second + token + storage accounting. |\n| `metering-service` | Billable-event aggregation (consumes `inference.completed.v1`). |\n\n### Production console\n\n| Service | Purpose |\n| --- | --- |\n| `console` | Next.js 14 + TanStack Query + Tailwind. Exposes every public REST endpoint as a usable page. 33 routes covering dashboard, streams, pipelines, models, datasets, annotations, training, media, rules, events, agents (chat UI with citations + tier-3 gate banner), gates inbox, canary decision board, drift, SLO, prefetch heatmap, knowledge RAG, NLQ, active-learning, semantic search, tenants/projects/members, cost, compliance evidence bundles, audit log + chain-verify, settings. Read the per-service README at [`services/console/`](./services/console). |\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"./docs/console.md\"\u003e\n    \u003cimg src=\"./docs/img/console.png\" alt=\"AegisVision operator console — Mission control\" width=\"900\"/\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003csub\u003e\u003cem\u003eMission control — live SSE feed, pending tier-3 approvals, canary plans (Wilson lower-bound), drift (KL / JS / TVD), SLO burn-rate. Full doc at \u003ca href=\"./docs/console.md\"\u003e\u003ccode\u003edocs/console.md\u003c/code\u003e\u003c/a\u003e.\u003c/em\u003e\u003c/sub\u003e\n\u003c/p\u003e\n\n---\n\n## NVIDIA Triton — the GPU inference core\n\nAegisVision treats **NVIDIA Triton Inference Server** as the canonical\nmodel-serving runtime. Triton is not a footnote in this template — it is\nthe load-bearing layer that turns model artifacts into low-latency\npredictions, and the platform is shaped around getting the most out of it.\n\nWhat you get out of the box:\n\n- **A dedicated, conformance-clean Helm chart** at\n  [`deploy/helm/triton/`](./deploy/helm/triton) — KServe v2 HTTP, gRPC,\n  and dedicated metrics ports, MIG-aware resource requests, ServiceAccount,\n  PeerAuthentication (mTLS STRICT), AuthorizationPolicy ALLOW list,\n  default-deny NetworkPolicy, PDB, ServiceMonitor scraping Triton's\n  metrics on `:8002`, and an HPA backed by both CPU and Triton's own\n  `nv_inference_queue_duration_us` metric (via KEDA when enabled).\n- **A model repository contract** described in\n  [`docs/triton.md`](./docs/triton.md): TensorRT, ONNX, PyTorch, Python,\n  Ensemble, and BLS backends are all supported with the same naming\n  conventions and the same model warm-up policy.\n- **Production model-control mode** (`explicit`) by default in\n  production-shape values, so deploys never auto-load every model in the\n  bucket. Models are loaded by `model-registry` via the Triton\n  `POST /v2/repository/models/{name}/load` API.\n- **A native KServe v2 client** in\n  [`pkg/dataplane/operators/detector.go`](./pkg/dataplane/operators/detector.go)\n  and [`services/inference-router/internal/detector/triton.go`](./services/inference-router/internal/detector/triton.go)\n  — connection pooling, deadline propagation, retries with jitter,\n  response-cache hit/miss surfacing, OTel spans around every `ModelInfer`,\n  and a graceful drain on shutdown.\n- **Dynamic batching + response caching** defaults wired in the chart and\n  documented in [`docs/triton.md`](./docs/triton.md). Per-model overrides\n  live in the `config.pbtxt` checked in alongside the model.\n- **Air-gap and SBOM coverage** — the Triton container is pinned to\n  `nvcr.io/nvidia/tritonserver:24.10-py3` and bundled by\n  `tools/airgap/build.sh`, with Cosign signatures and Syft SBOMs attached\n  to the air-gap tarball.\n- **A Triton-specific runbook** in\n  [`docs/runbooks/triton.md`](./docs/runbooks/triton.md) — model load\n  storms, response-cache thrash, MIG slice exhaustion, OOM, queue\n  duration spikes, with the corresponding chaos experiment at\n  [`deploy/chaos/triton-model-evict.yaml`](./deploy/chaos/triton-model-evict.yaml).\n\nThe architectural rule:\n[ADR-0003 (MIG-default)](./docs/adr/0003-mig-default.md) and\n[ADR-0008 (no frames on the bus)](./docs/adr/0008-claim-check-for-frames.md)\ntogether mean every byte that hits Triton came from object storage via a\nclaim-check URN, on a hardware-isolated MIG slice. That is the property\nthat lets the platform scale to thousands of concurrent streams without\nturning the GPU pool into a noisy neighbourhood.\n\nFor the full operating manual see [`docs/triton.md`](./docs/triton.md).\n\n---\n\n## Architectural commitments (the ADRs)\n\nViolating any of these is the kind of change that should be flagged for the\narchitecture working group, not slipped into a feature PR.\n\n| ADR | Decision |\n| --- | --- |\n| 0001 | Control plane / data plane are **hard-separated**. Temporal never sees a frame; the data plane never persists per-step history. |\n| 0002 | ClickHouse holds the detection firehose. PostgreSQL holds metadata. Neither alone is sufficient. |\n| 0003 | MIG is the **default** GPU sharing mode for production inference. Hard isolation bounds blast radius. |\n| 0007 | Protobuf-everywhere, Buf-managed. `/proto` has the strictest CODEOWNERS review. |\n| 0008 | Frames and media **never** travel on Kafka or NATS. The bus carries references (claim-check). |\n| 0014 | Bounded autonomy. Agents auto-execute read/advisory + reversible ops; consequential actions require a human-signal gate. |\n| 0016 | Walking skeleton first — thin but complete on the real architecture before going wide. |\n| 0017 | 4-tier risk model encoded in tool schemas; tier-3 tools route through `policy-gate-service`. Refusal is in code. |\n| 0018 | One LLM/VLM gateway speaks OpenAI-compatible internally; backends are swappable without caller changes. |\n| 0019 | Active learning samples by uncertainty + diversity, never random firehose draw. |\n| 0020 | Platform-fact answers are retrieval-augmented; no plain-LLM hallucinated identifiers. |\n| 0021 | Prompt-injection defense in depth — sanitizer + PII redactor + translator hardening + rate limit + gate. |\n| 0022 | Continuous autonomy: cron + signal-driven agent sessions; bounded-autonomy unchanged. |\n| 0023 | Canary uses Wilson lower-bound proportion test + min-sample floor. Promotion gated, rollback automatic. |\n| 0024 | Shadow inference compares candidate vs baseline on the same frame URN; tenant traffic untouched. |\n| 0025 | Drift = JS / KL / TVD over class distributions vs reference; SLO = multi-window burn-rate. |\n| 0026 | Predictive prefetch via 7×24 EMA grid; warm-ups dispatched at horizon ahead of demand. |\n| 0027 | Air-gapped bundle as day-one CI artifact (images + charts + manifests + signatures, one tarball). |\n| 0028 | Chaos engineering as production-readiness gate; every resilience claim has an experiment + assertion. |\n| 0029 | `compliance-evidence-service` owns no data; composes per-control evidence from authoritative stores. |\n| 0030 | release-please + signed air-gap bundle promotion; single platform version. |\n\nFull text: [`docs/adr/`](./docs/adr/).\n\n---\n\n## Public API discipline\n\nPublic API uses **product nouns**, never internal model names:\n\n- `/v1/pipelines` (not `/v1/pipeline-revisions/`)\n- `/v1/streams` (not `/v1/feeds/`)\n- `/v1/models` (not `/v1/networks/`)\n\nIDs are **opaque strings**. Storage details (Postgres keys, Mongo\nObjectIDs) never leak. Path segments are plural. This is direct scar\ntissue from operating CV platforms at scale.\n\n---\n\n## Errors, idempotency, pagination\n\n- **Errors** use **RFC 9457 `application/problem+json`**. Construct them\n  with `pkg/platform/problem`.\n- **Mutating endpoints** accept `Idempotency-Key`; replays within 24h\n  return the cached response. Wire via `pkg/platform/middleware`.\n- **List endpoints** use **opaque cursor pagination** (never offset).\n  Use `pkg/platform/pagination`. Keys are HMAC-signed with a key ≥ 32\n  bytes (`AEGIS_CURSOR_KEY`).\n- **Versioning** is URI-based (`/v1/`); N-1 compatibility for ≥2\n  releases.\n\n---\n\n## Observability\n\n- **Logs** are structured (`slog`), with `tenant_id`, `request_id`,\n  `trace_id` propagated through context.\n- **Metrics** follow **RED** (rate / errors / duration). Use\n  `pkg/platform/metrics`. Every chart ships a `ServiceMonitor`.\n- **Traces** use OpenTelemetry over OTLP; the collector lives in\n  `deploy/platform/observability`. Sample rate is per-tenant\n  configurable.\n- **Dashboards** live in `deploy/platform/observability/grafana/`.\n\nSee [`docs/observability.md`](./docs/observability.md).\n\n---\n\n## Security posture\n\n- **Istio Ambient mTLS STRICT** between every pod.\n- **OPA AuthorizationPolicy** ALLOW list per service.\n- **NetworkPolicy** default-deny per namespace.\n- **SPIRE** workload identity issued to every pod.\n- **Vault transit** for per-tenant crypto-shredding keys.\n- **External Secrets Operator** for all credentials; nothing in git.\n- **Cosign keyless** signing of every image; **Kyverno** admission\n  verifies signatures against `github.com/hoangsonww/AegisVision-Computer-Vision-System/.github/workflows/build-and-verify.yml@refs/heads/master`.\n- **SLSA v1** build provenance + **Syft SBOM** attached to every release.\n\nSee [`docs/security.md`](./docs/security.md) and\n[`docs/compliance/`](./docs/compliance/).\n\n---\n\n## Deploy\n\nThree paths, each documented in `SETUP_GUIDE.md`:\n\n1. **Local walking skeleton** — five terminals, zero external deps.\n2. **Online cluster** — ArgoCD reconciles the ApplicationSet against a\n   real Kubernetes cluster with Istio Ambient + ESO + SPIRE + Patroni +\n   Redis Sentinel + ClickHouse Operator + NATS JetStream.\n3. **Air-gapped** — `./tools/airgap/build.sh` produces a single signed\n   tarball containing every image, chart, manifest, and signature; the\n   target environment runs `./install.sh --registry \u003cinternal\u003e`.\n\n---\n\n## How to contribute\n\nSee [`docs/contributing.md`](./docs/contributing.md) and the per-directory\nREADMEs. The TL;DR:\n\n1. Define the API in `/proto` first. Run `task proto`.\n2. Copy the structure of `services/pipeline-service` (smallest reference).\n3. Wire `pkg/platform` for logging / OTel / metrics / health / shutdown.\n4. Add a Helm chart under `deploy/helm/\u003cservice\u003e` (mTLS STRICT, OPA\n   AuthorizationPolicy, NetworkPolicy default-deny, ServiceMonitor, HPA).\n5. Add it to `go.work`.\n6. Add it to the ArgoCD ApplicationSet in `deploy/argocd/`.\n\nDon't bypass `pkg/platform` for \"just this one log line.\" Don't add a new\ntransport without a protobuf contract. Don't grow a second agent runtime.\n\n---\n\n## Further reading\n\n- [`ARCHITECTURE.md`](./ARCHITECTURE.md) — the canonical architecture deep dive.\n- [`TEMPLATE.md`](./TEMPLATE.md) — the rebrand + adoption playbook for forking the template.\n- [`SETUP_GUIDE.md`](./SETUP_GUIDE.md) — local dev → online cluster → air-gapped install.\n- [`docs/triton.md`](./docs/triton.md) — NVIDIA Triton operating manual.\n- [`docs/runbooks/triton.md`](./docs/runbooks/triton.md) — Triton runbook.\n- [`deploy/helm/triton/examples/`](./deploy/helm/triton/examples) — example Triton model repository.\n- [`deploy/platform/observability/prometheus/triton-rules.yaml`](./deploy/platform/observability/prometheus/triton-rules.yaml) — Triton alert rules.\n- [`CHANGELOG.md`](./CHANGELOG.md) — release notes.\n- [`CLAUDE.md`](./CLAUDE.md) — working notes for Claude Code.\n- [`docs/adr/`](./docs/adr/) — 30 Architecture Decision Records.\n- [`docs/compliance/`](./docs/compliance/) — SOC 2, EU AI Act, GDPR, pen-test.\n- [`docs/runbooks/`](./docs/runbooks/) — operational runbooks.\n- [`docs/`](./docs/) — concepts, data flow, security, agents, autonomy,\n  observability, deployment, troubleshooting, glossary.\n- [`index.html`](./index.html) — the project landing page / wiki.\n- [`ACKNOWLEDGMENTS.md`](./ACKNOWLEDGMENTS.md) — the open-source giants this stands on.\n- [`AUTHORS`](./AUTHORS), [`MAINTAINERS`](./MAINTAINERS), [`GOVERNANCE.md`](./GOVERNANCE.md) — who runs this.\n\n---\n\n## Maintainer\n\n\u003cdiv align=\"center\"\u003e\n\n\u003ctable\u003e\n\u003ctr\u003e\n\u003ctd align=\"center\"\u003e\n  \u003ca href=\"https://github.com/hoangsonww\"\u003e\n    \u003cimg src=\"https://github.com/hoangsonww.png\" width=\"120\" height=\"120\" style=\"border-radius:50%\" alt=\"Son Nguyen\"/\u003e\n  \u003c/a\u003e\n  \u003cbr/\u003e\n  \u003cb\u003eSon Nguyen\u003c/b\u003e\n  \u003cbr/\u003e\n  \u003csub\u003eMaintainer\u003c/sub\u003e\n  \u003cbr/\u003e\n  \u003cbr/\u003e\n  \u003ca href=\"https://github.com/hoangsonww\"\u003e\u003cimg src=\"https://img.shields.io/badge/GitHub-hoangsonww-181717?style=flat-square\u0026logo=github\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://linkedin.com/in/hoangsonw\"\u003e\u003cimg src=\"https://img.shields.io/badge/LinkedIn-hoangsonw-0A66C2?style=flat-square\u0026logo=linkedin\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"https://sonnguyenhoang.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/Web-sonnguyenhoang.com-1F6FEB?style=flat-square\u0026logo=safari\u0026logoColor=white\"\u003e\u003c/a\u003e\n  \u003ca href=\"mailto:hoangson091104@gmail.com\"\u003e\u003cimg src=\"https://img.shields.io/badge/Email-hoangson091104@gmail.com-D14836?style=flat-square\u0026logo=gmail\u0026logoColor=white\"\u003e\u003c/a\u003e\n\u003c/td\u003e\n\u003c/tr\u003e\n\u003c/table\u003e\n\n\u003c/div\u003e\n\nGovernance is in [`GOVERNANCE.md`](./GOVERNANCE.md); contributors are\nlisted in [`AUTHORS`](./AUTHORS). New maintainers welcome — see\n[`CONTRIBUTING.md`](./CONTRIBUTING.md).\n\n---\n\n## License\n\n**AegisVision** is published under the **Apache License, Version 2.0** —\nchosen specifically so that individuals and organizations can fork this\nrepository, rebrand it, embed it in commercial products, and operate it\nas the foundation of their own computer-vision platform. See\n[`LICENSE`](./LICENSE) for the full text and [`NOTICE`](./NOTICE) for\nattribution of the open-source projects this template stands on. Cite\nvia [`CITATION.cff`](./CITATION.cff).\n\n\u003cdiv align=\"center\"\u003e\n\n\u003csub\u003e\n  Copyright © 2026 \u003ca href=\"https://sonnguyenhoang.com\"\u003eSon Nguyen\u003c/a\u003e.\n  Built with care.\n\u003c/sub\u003e\n\n\u003c/div\u003e\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoangsonww%2Faegisvision-computer-vision-system","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fhoangsonww%2Faegisvision-computer-vision-system","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fhoangsonww%2Faegisvision-computer-vision-system/lists"}