Closed-loop intelligence layer for engineering teams.
Agentic OS captures engineering activity across Linear, GitHub, Slack, and Notion, builds a real-time knowledge graph, detects when execution drifts from intent (e.g., "you're building the wrong thing"), and surfaces actionable alerts with full evidence chains via Slack.
This is a pre-seed MVP built by a 2-person team. It demonstrates the core closed-loop architecture: Observe → Orient → Decide → Act → Learn.
Linear Issues / GitHub PRs / Slack Messages / Notion Docs
|
[ Webhook Ingestion ]
|
[ Event Source ]
(PostgreSQL + pgvector)
|
+-------------+-------------+
| |
[ KG Builder ] [ Embedding Pipeline ]
| |
[ Knowledge Graph ] [ Vector Store ]
(PostgreSQL + pgvector) |
| |
+-------------+-------------+
|
[ OODA Reasoning Engine ]
Rule-based -> Embedding -> LLM
(with confidence gating)
|
[ Drift Detection ]
|
[ Action Dispatcher ]
(Slack alerts with
Approve/Reject/Modify)
|
[ Human Feedback ]
(learn loop)
| Decision | Choice | Rationale |
|---|---|---|
| Database | PostgreSQL + pgvector | Single DB handles relational + embeddings + graph queries. No Neo4j until multi-hop queries prove insufficient |
| LLM Routing | LiteLLM + OpenAI | GPT-4o-mini (80%) for speed/cost, Claude Sonnet (20%) for complex reasoning |
| Orchestration | LangGraph OSS | State machine pattern for OODA loop |
| Queue | Redis Streams | Managed service, lighter than Kafka for MVP |
| Infra | Docker Compose locally, Railway in prod | No Kubernetes until Series A |
- Docker + Docker Compose
- (Optional) ngrok for local webhook testing
- (Optional) OpenAI API key for embeddings and LLM drift detection
git clone <repo-url>
cd agentic-os
# Copy and edit environment variables
cp .env.example .env
# Edit .env with your API keysdocker-compose up -d postgres redisThis starts:
- PostgreSQL 16 + pgvector on port 5432
- Redis on port 6379
cd backend
python -m venv .venv
source .venv/bin/activate
pip install -r requirements.txt
# Initialize database
python -c "import asyncio; from app.core.database import init_db; asyncio.run(init_db())"
# Start server
uvicorn app.main:app --reload --port 8000The API will be available at http://localhost:8000.
API Docs: http://localhost:8000/docs (Swagger UI)
cd frontend
npm install
npm startThe UI will be available at http://localhost:3000.
# From project root
docker-compose up --buildThis starts all services: Postgres, Redis, Backend (port 8000), Frontend (port 3000).
Open the UI at http://localhost:3000 and create your first workspace.
Or via API:
curl -X POST "http://localhost:8000/api/v1/workspaces/?name=Acme+Engineering&slug=acme-eng"Go to Connectors in the UI and connect:
- Linear — for sprint goals and ticket data
- GitHub — for PR and commit data
- Slack — for drift alerts and approvals
For local development without real OAuth, the system will store events and demonstrate drift detection with synthetic data.
curl -X POST "http://localhost:8000/api/v1/workspaces/{workspace_id}/seed"This creates sample sprint goals, tickets, PRs, and drift detections so you can explore the UI immediately.
POST /api/v1/workspaces/— Create workspaceGET /api/v1/workspaces/— List workspacesGET /api/v1/workspaces/{id}— Get workspace with stats
POST /api/v1/connectors/{ws_id}/connect?connector_type=linear— Start OAuthGET /api/v1/connectors/{ws_id}/status— List connectors
GET /api/v1/events/{ws_id}/events— List events (filter by source_system, object_type)GET /api/v1/events/{ws_id}/events/stats— Event statistics
GET /api/v1/drift/{ws_id}/drifts— List drift detectionsGET /api/v1/drift/{ws_id}/drifts/{id}— Get drift detailPOST /api/v1/drift/{ws_id}/drifts/{id}/feedback— Submit feedbackGET /api/v1/drift/{ws_id}/drifts/stats— Drift statistics
GET /api/v1/actions/{ws_id}/actions— List actionsPOST /api/v1/actions/{ws_id}/actions/{id}/approve— Approve actionPOST /api/v1/actions/{ws_id}/actions/{id}/reject— Reject action
POST /webhooks/linear— Linear webhook endpointPOST /webhooks/github— GitHub webhook endpointPOST /webhooks/slack— Slack interactive events
GET /api/v1/dashboard/{ws_id}/overview— Dashboard overviewGET /api/v1/dashboard/{ws_id}/graph-summary— KG summary
- Ingest: Linear/GitHub webhooks push events into the event store
- Build: KG Builder processes events into entities (tickets, PRs, commits) and relationships
- Extract: Intent Extractor parses sprint goals from Linear cycles
- Detect: Reasoning Engine runs 3-layer drift detection:
- Rule-based: "Sprint goal has no linked tickets"
- Evidence-based: "No recent activity matching requirements"
- LLM-based: Deep semantic comparison (high-priority intents only)
- Alert: Action Dispatcher sends Slack alerts with Approve/Reject/Modify
- Learn: Human feedback improves precision over time
agentic-os/
├── docker-compose.yml # Infrastructure: Postgres, Redis, Backend, Frontend
├── .env.example # Environment variable template
├── backend/
│ ├── Dockerfile
│ ├── requirements.txt
│ ├── migrations/
│ │ └── init.sql # pgvector extension setup
│ └── app/
│ ├── main.py # FastAPI application
│ ├── core/
│ │ ├── config.py # Settings (pydantic)
│ │ └── database.py # SQLAlchemy + asyncpg
│ ├── models/ # Database models
│ │ ├── workspace.py # Workspace, ConnectorConfig
│ │ ├── event.py # Event (immutable log)
│ │ ├── entity.py # KG entities + relationships + embeddings
│ │ ├── intent.py # Intent sources + parsed intent
│ │ ├── drift.py # Drift detections
│ │ └── action.py # Actions (alerts, drafts)
│ ├── api/routes/ # REST API endpoints
│ │ ├── workspace.py
│ │ ├── connectors.py
│ │ ├── events.py
│ │ ├── drift.py
│ │ ├── actions.py
│ │ ├── webhooks.py
│ │ └── dashboard.py
│ └── workers/ # Background processors
│ ├── kg_builder.py # Event -> Entity/Relationship
│ ├── llm_service.py # Embeddings + Chat + Drift LLM
│ ├── reasoning_engine.py # OODA loop + 3-layer detection
│ ├── intent_extractor.py # Sprint goal parsing
│ └── action_dispatcher.py # Slack alerts
├── frontend/
│ ├── Dockerfile
│ ├── package.json
│ ├── tailwind.config.js
│ ├── public/
│ └── src/
│ ├── App.js
│ ├── index.js
│ ├── index.css
│ ├── lib/api.js # API client
│ ├── components/
│ │ └── Layout.js # Sidebar + header
│ └── pages/
│ ├── WorkspaceSetup.js
│ ├── Dashboard.js
│ ├── DriftList.js
│ ├── DriftDetail.js
│ ├── EventFeed.js
│ └── ConnectorSetup.js
| Layer | Technology | Monthly Cost (100 users) |
|---|---|---|
| Database | PostgreSQL 16 + pgvector | $19 (Neon) |
| Cache/Queue | Redis (Upstash) | $0-30 |
| Backend | Python 3.11 + FastAPI | Free (self-hosted) |
| Frontend | React 18 + Tailwind | Free (self-hosted) |
| LLM | OpenAI GPT-4o-mini + Claude Sonnet | $400-800 |
| Embeddings | OpenAI text-embedding-3-small | ~$50 |
| Gateway | LiteLLM (OSS) + Portkey | $50 |
| Total | ~$625-1,180/mo |
cd backend
pytest -v# Format
black app/
# Lint
ruff check app/cd backend
alembic revision --autogenerate -m "description"
alembic upgrade head| Variable | Required | Description |
|---|---|---|
DATABASE_URL |
Yes | PostgreSQL connection string |
REDIS_URL |
Yes | Redis connection string |
SECRET_KEY |
Yes | JWT signing key |
OPENAI_API_KEY |
Yes | OpenAI API for embeddings + chat |
ANTHROPIC_API_KEY |
No | Anthropic for complex reasoning |
LINEAR_CLIENT_ID |
No | Linear OAuth app ID |
LINEAR_CLIENT_SECRET |
No | Linear OAuth secret |
GITHUB_CLIENT_ID |
No | GitHub OAuth app ID |
GITHUB_CLIENT_SECRET |
No | GitHub OAuth secret |
SLACK_BOT_TOKEN |
No | Slack bot token for alerts |
SLACK_CLIENT_ID |
No | Slack OAuth app ID |
SLACK_CLIENT_SECRET |
No | Slack OAuth secret |
WEBHOOK_BASE_URL |
No | Public URL for webhooks (ngrok for local) |
MIT
Built with conviction by a 2-person pre-seed team betting that the future of work is closed-loop, not dashboard-driven.