Skip to content

Commit 8b27274

Browse files
committed
feat: architectural remediation, security hardening, and documentation updates
1 parent 85c8150 commit 8b27274

12 files changed

Lines changed: 339 additions & 67 deletions

File tree

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,7 +53,19 @@ Every commitment—whether from Slack or a Git Commit—passes through a determi
5353

5454
---
5555

56-
## 🚀 API Showcase
56+
## � Professional Integrity Audits
57+
58+
Need a deep-dive into your team's commitment reliability? I offer **one-time AI-powered audits** for remote engineering teams.
59+
60+
- **Extract "Shadow Debt"**: Identify technical promises made in commits that never made it to a PR.
61+
- **Predict Burnout**: Recognize linguistic patterns of fatigue before they impact velocity.
62+
- **Reliability Scoring**: Get a multi-dimensional scorecard for your squads.
63+
64+
📧 **[Contact me for an Audit](mailto:adelekedare2012@gmail.com)** to see a sample report and book a 1-hour squad analysis.
65+
66+
---
67+
68+
## �🚀 API Showcase
5769

5870
> **Note:** All API endpoints require authentication via the `X-API-Key` header.
5971

docs/guides/gitops.md

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,3 +39,18 @@ When you provide a check-in via Slack, CommitGuard cross-references it with your
3939
* **User**: *"I'm almost done refactoring."*
4040
* **Git**: *0 lines changed in 48 hours.*
4141
* **Agent**: *"I noticed no code changes. Is there a blocker I can help with?"* (Tone: Supportive but firm).
42+
### 4. Identity Mapping (Crucial Step)
43+
To link your Git commits to your Slack profile, you must map your email to your user ID:
44+
45+
```bash
46+
curl -X POST \
47+
-H 'X-API-Key: YOUR_API_KEY' \
48+
'http://localhost:8000/api/v1/users/config/git?user_id=Daretechie&email=your-email@example.com'
49+
```
50+
51+
Once mapped, `identity_matched` will return `true` in ingest responses, and the agent will know exactly who to ping in Slack.
52+
53+
---
54+
55+
> [!TIP]
56+
> Use the same `user_id` across both Slack and Git mapping to ensure a unified accountability profile.

docs/guides/production.md

Lines changed: 79 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
# Production & Enterprise Deployment Guide 🚀
2+
3+
Scaling CommitGuard AI to 1000+ users requires moving from a local monolithic setup to a distributed, high-availability architecture.
4+
5+
## 🏗️ Enterprise Architecture
6+
7+
For large-scale teams, we separate the **Ingestion Layer** (API) from the **Processing Layer** (Workers).
8+
9+
1. **API Layer**: Stateless FastAPI pods behind a Load Balancer (AWS ALB / Nginx).
10+
2. **Processing Layer**: Distributed `arq` workers scaling horizontally based on queue depth.
11+
3. **State Layer**: Managed Redis (AWS ElastiCache) and PostgreSQL (AWS RDS).
12+
13+
---
14+
15+
## ☸️ Kubernetes Orchestration
16+
17+
We provide production-ready K8s manifests in [`infra/k8s/`](file:///home/daretechie/DevProject/GitHub/CommitGuard-AI/infra/k8s/).
18+
19+
### Key Scaling Features:
20+
- **Replica Sets**: Run multiple API instances to handle high traffic.
21+
- **Auto-Scaling (HPA)**: Workers automatically scale from **2 to 20+ pods** based on CPU usage or queue backlog.
22+
- **Resource Constraints**: Strict CPU/Memory limits to prevent noisy-neighbor issues on shared clusters.
23+
24+
### Deployment Command:
25+
```bash
26+
kubectl apply -f infra/k8s/
27+
```
28+
29+
---
30+
31+
## 🔄 Automated Org-Wide Ingestion
32+
33+
Managers don't need to manually ingest commits. Use **GitHub Webhooks** at the Organization level:
34+
35+
1. Go to **GitHub Organization Settings** -> **Webhooks**.
36+
2. Add a new webhook:
37+
- **Payload URL**: `https://api.commitguard.yourcloud.com/api/v1/ingest/git`
38+
- **Content Type**: `application/json`
39+
- **Secret**: Your fixed `API_KEY_SECRET`
40+
- **Events**: Select `Pushes`.
41+
42+
**Result**: Every commit from every repo in your organization is automatically processed for accountability.
43+
44+
---
45+
46+
## 🆔 Bulk Identity Sync (SSO)
47+
48+
Mapping 1000+ users via `curl` is inefficient. Implement a **Mapping Sync Service**:
49+
50+
- **Active Directory / Google Workspace**: Write a small cronjob that polls your employee list and calls:
51+
- `POST /api/v1/users/config/slack` (Email -> Slack ID)
52+
- `POST /api/v1/users/config/git` (Email -> Git Email)
53+
- **Automatic Discovery**: CommitGuard can be configured to use the Slack `users.lookupByEmail` API to auto-map users on their first commitment.
54+
55+
---
56+
57+
## 📊 Monitoring & Observability
58+
59+
Enterprise deployment includes **Prometheus + Grafana** integration:
60+
61+
- **SLIs (Service Level Indicators)**:
62+
- `background_jobs_pending`: How many commitments are waiting for AI processing?
63+
- `ai_token_usage_total`: Cost tracking per team/department.
64+
- `intervention_acceptance_rate`: How often are managers acting on AI pings?
65+
66+
---
67+
68+
## 💰 FinOps: Optimizing LLM Costs
69+
70+
At 1000+ users, token costs can add up. CommitGuard helps you optimize:
71+
72+
1. **Provider Switching**: Use **Groq (Llama 3.3 70b)** for high-speed, low-cost extraction, and **OpenAI (GPT-4o)** only for complex tone adaptation.
73+
2. **Mock Mode for Non-Critical Repos**: Use `LLM_PROVIDER="mock"` for internal experimental repositories to save budget.
74+
3. **Caching**: CommitGuard can be extended with a vector cache (like RedisVL) to reuse extracted tasks from similar commit messages.
75+
76+
---
77+
78+
> [!IMPORTANT]
79+
> Always deploy in a **Zero-Trust** environment using encrypted secrets and private network VPCs for the Database and Redis.

docs/guides/slack.md

Lines changed: 66 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -2,30 +2,83 @@
22

33
Transform the agent into a visible collaborator by bridging it to your Slack workspace.
44

5-
## 1. Webhook Setup
6-
To receive notifications, you need an **Incoming Webhook URL**:
7-
1. Go to [Slack API Apps](https://api.slack.com/apps).
8-
2. Create a new app (from scratch).
9-
3. Enable **Incoming Webhooks**.
10-
4. Add a new webhook to your channel and copy the URL.
5+
## 1. Webhook Setup (Step-by-Step)
6+
7+
### Step 1: Access Slack API
8+
1. Open your browser and navigate to **[api.slack.com/apps](https://api.slack.com/apps)**
9+
2. Sign in with your Slack workspace credentials if prompted
10+
11+
### Step 2: Create a New App
12+
1. Click the green **"Create New App"** button
13+
2. Select **"From scratch"** (not from a manifest)
14+
3. Fill in the form:
15+
- **App Name:** `CommitGuard AI` (or any name you prefer)
16+
- **Pick a workspace:** Select your Slack workspace from the dropdown
17+
4. Click **"Create App"**
18+
19+
### Step 3: Enable Incoming Webhooks
20+
1. After creating the app, you'll land on the **Basic Information** page
21+
2. In the left sidebar under **"Features"**, click **"Incoming Webhooks"**
22+
3. Toggle the switch **ON** at the top of the page
23+
4. You'll see a confirmation: *"Incoming Webhooks are On"*
24+
25+
### Step 4: Add Webhook to Channel
26+
1. Scroll down to **"Webhook URLs for Your Workspace"**
27+
2. Click **"Add New Webhook to Workspace"**
28+
3. A popup will ask: *"Where should CommitGuard AI post?"*
29+
4. Select your target channel (e.g., `#engineering`, `#accountability`)
30+
5. Click **"Allow"**
31+
6. Copy the generated webhook URL:
32+
```
33+
https://hooks.slack.com/services/YOUR_WORKSPACE_ID/YOUR_APP_ID/YOUR_WEBHOOK_TOKEN
34+
```
1135

1236
## 2. Configuration
13-
Add the URL to your `.env`:
37+
38+
Add the webhook URL to your `.env` file:
39+
```bash
40+
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/WORKSPACE_ID/APP_ID/TOKEN"
41+
```
42+
43+
Restart the service to apply changes:
1444
```bash
15-
SLACK_WEBHOOK_URL="https://hooks.slack.com/services/T000.../B000.../XXXX..."
45+
docker-compose down && docker-compose up --build
1646
```
1747

18-
## 3. User @Mentions (Identity Mapping)
48+
## 3. Test the Webhook
49+
50+
Verify connectivity with a simple curl command:
51+
```bash
52+
curl -X POST \
53+
-H 'Content-Type: application/json' \
54+
-d '{"text": "🛡️ CommitGuard AI is connected!"}' \
55+
'YOUR_WEBHOOK_URL'
56+
```
57+
58+
You should see `ok` in the terminal and the message in your Slack channel.
59+
60+
## 4. User @Mentions (Identity Mapping)
61+
1962
CommitGuard can ping users directly using their **Slack Member ID**.
2063

21-
### How to map a user:
22-
Call the configuration endpoint with the user's Slack ID (found in their Slack Profile -> More -> Copy Member ID):
64+
### How to Find a Slack Member ID
65+
1. Open Slack and go to the user's profile
66+
2. Click **"More"** (three dots)
67+
3. Select **"Copy Member ID"**
2368

69+
### How to Map a User
70+
Call the configuration endpoint:
2471
```bash
25-
POST /api/v1/users/config/slack?user_id=john_dev&slack_id=U12345678
26-
Headers: X-API-Key: YOUR_API_KEY
72+
curl -X POST \
73+
-H 'X-API-Key: YOUR_API_KEY' \
74+
'http://localhost:8000/api/v1/users/config/slack?user_id=john_dev&slack_id=U12345678'
2775
```
2876

2977
### The Result
3078
When an alert is triggered, Slack turns the ID into a real mention:
3179
> 🔔 **CommitGuard Alert for @John:** Checking in on commitment: fix the CSS bugs
80+
81+
---
82+
83+
> [!TIP]
84+
> You can create multiple webhooks for different channels (e.g., `#urgent-alerts` for critical issues, `#commitment-log` for routine tracking).

infra/k8s/deployment.yaml

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
apiVersion: apps/v1
2+
kind: Deployment
3+
metadata:
4+
name: commitguard-api
5+
labels:
6+
app: commitguard-api
7+
spec:
8+
replicas: 3
9+
selector:
10+
matchLabels:
11+
app: commitguard-api
12+
template:
13+
metadata:
14+
labels:
15+
app: commitguard-api
16+
spec:
17+
containers:
18+
- name: api
19+
image: commitguard-ai:latest
20+
command: ["uvicorn", "src.main:app", "--host", "0.0.0.0", "--port", "8000"]
21+
ports:
22+
- containerPort: 8000
23+
envFrom:
24+
- secretRef:
25+
name: commitguard-secrets
26+
- configMapRef:
27+
name: commitguard-config
28+
resources:
29+
requests:
30+
cpu: "250m"
31+
memory: "512Mi"
32+
limits:
33+
cpu: "1000m"
34+
memory: "1Gi"
35+
36+
---
37+
38+
apiVersion: apps/v1
39+
kind: Deployment
40+
metadata:
41+
name: commitguard-worker
42+
labels:
43+
app: commitguard-worker
44+
spec:
45+
replicas: 5
46+
selector:
47+
matchLabels:
48+
app: commitguard-worker
49+
template:
50+
metadata:
51+
labels:
52+
app: commitguard-worker
53+
spec:
54+
containers:
55+
- name: worker
56+
image: commitguard-ai:latest
57+
command: ["arq", "src.worker.WorkerSettings"]
58+
envFrom:
59+
- secretRef:
60+
name: commitguard-secrets
61+
- configMapRef:
62+
name: commitguard-config
63+
resources:
64+
requests:
65+
cpu: "500m"
66+
memory: "1Gi"
67+
limits:
68+
cpu: "2000m"
69+
memory: "2Gi"
70+
71+
---
72+
73+
apiVersion: autoscaling/v2
74+
kind: HorizontalPodAutoscaler
75+
metadata:
76+
name: commitguard-worker-hpa
77+
spec:
78+
scaleTargetRef:
79+
apiVersion: apps/v1
80+
kind: Deployment
81+
name: commitguard-worker
82+
minReplicas: 2
83+
maxReplicas: 20
84+
metrics:
85+
- type: Resource
86+
resource:
87+
name: cpu
88+
target:
89+
type: Utilization
90+
averageUtilization: 70

src/agents/brain.py

Lines changed: 13 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
BurnoutDetection,
1313
ExcuseAnalysis,
1414
ExcuseCategory,
15-
ExtractedCommitment,
1615
PipelineEvaluation,
1716
RiskAssessment,
1817
RiskLevel,
@@ -37,9 +36,12 @@ async def analyze_excuse(self, user_input: str) -> ExcuseAnalysis:
3736
messages=[
3837
{
3938
"role": "system",
40-
"content": "Analyze the user excuse for commitment failure.",
39+
"content": "Analyze the user excuse for commitment failure provided within <user_excuse> tags.",
40+
},
41+
{
42+
"role": "user",
43+
"content": f"<user_excuse>\n{user_input}\n</user_excuse>",
4144
},
42-
{"role": "user", "content": user_input},
4345
],
4446
)
4547

@@ -53,13 +55,15 @@ async def assess_risk(
5355
{
5456
"role": "system",
5557
"content": (
56-
"Assess the risk of commitment failure based on history."
58+
"Assess the risk of commitment failure based on the provided "
59+
"history and current status within their respective XML tags."
5760
),
5861
},
5962
{
6063
"role": "user",
6164
"content": (
62-
f"History: {historical_context}\nStatus: {current_status}"
65+
f"<historical_context>\n{historical_context}\n</historical_context>\n"
66+
f"<current_status>\n{current_status}\n</current_status>"
6367
),
6468
},
6569
],
@@ -73,29 +77,17 @@ async def detect_burnout(self, user_input: str) -> BurnoutDetection:
7377
{
7478
"role": "system",
7579
"content": (
76-
"Detect signs of professional burnout in the user input."
80+
"Detect signs of professional burnout in the user input provided within <user_input> tags."
7781
),
7882
},
79-
{"role": "user", "content": user_input},
80-
],
81-
)
82-
83-
async def extract_commitment(self, raw_input: str) -> ExtractedCommitment:
84-
return await self.provider.chat_completion(
85-
response_model=ExtractedCommitment,
86-
model=self.model,
87-
messages=[
8883
{
89-
"role": "system",
90-
"content": (
91-
"Extract a task and deadline from the user's "
92-
"natural language promise."
93-
),
84+
"role": "user",
85+
"content": f"<user_input>\n{user_input}\n</user_input>",
9486
},
95-
{"role": "user", "content": raw_input},
9687
],
9788
)
9889

90+
9991
async def evaluate_participation(
10092
self,
10193
user_id: str,

0 commit comments

Comments
 (0)