Agentic PR security: isolated execution, layered multi-agent tool-loop orchestration, interactive audit surface, and optional validated fix commits on the branch — single deployable application
A GitHub App delivers signed webhooks into a serverless route handler; platform-specific bot adapters keep PR thread state and @mention routing. Workloads run in an ephemeral microVM (repository checkout, diff-aware commands, optional custom tooling). An AgentOrchestrator schedules tool-using agents in topological layers (parallel within a layer, dependency-respecting across layers), then runs threat synthesis and scoring. Audit payloads persist in a REST-backed key-value store; long-lived TCP Redis holds chat/session state separately. The bot posts a structured summary with a deep link; the report route streams progress over SSE and renders charts, diagrams, highlighted code, and tabbed findings.
Static scanners and linters are fast but often miss cross-file and abuse-path context. Reviews that stop at comments rarely ship patches. ClawGuard targets the gap between detection and remediation: one path from PR event → stored audit → human-readable report → optional validated fix + commit + re-audit.
| Track | What ships |
|---|---|
| MVP | @mention trigger, recon + layered multi-agent scan, Zod-typed AuditResult, interactive report, webhook idempotency |
| Remediation | Deterministic fix.before/fix.after, fallback fix ToolLoopAgent, validation gate (tsc/eslint/biome/tests), Octokit commits to PR branch, re-audit |
| Product | Dashboard, org learnings / knowledge injection, post-merge tracking metrics, optional Slack/Teams/Linear routes |
| Config | Target-repo .clawguard/config.yml + policies.yml; defaults in lib/config/defaults.ts |
Product UI assets live under public/ (same files power the landing #features carousel). The interactive report (/report/[owner]/[repo]/[pr]) covers verdict, findings-by-severity, PR summary and sequence diagrams, threat model, and compliance cross-walks.
flowchart TB
subgraph ingress [Ingress]
GH[GitHub webhook]
WH["POST /api/webhooks/github"]
BOT["lib/bot.ts Chat SDK"]
end
subgraph exec [Execution]
RUN["runAuditPipeline github-audit-runner.ts"]
PIPE["runSecurityPipeline pipeline.ts"]
SB[Vercel Sandbox clone diff bash]
end
subgraph ai [AI layer]
GW[Vercel AI Gateway]
ORCH["AgentOrchestrator orchestrator.ts"]
TLS[ToolLoopAgent specialists]
end
subgraph data [Persistence]
KV["Upstash REST audits SSE keys lib/redis.ts"]
TCP["TCP REDIS_URL Chat SDK state"]
end
subgraph surfaces [Surfaces]
CARD[PR JSX card]
REP["/report SSE stream"]
DASH["/dashboard"]
end
GH --> WH --> BOT --> RUN --> PIPE --> SB
PIPE --> ORCH --> TLS
ORCH --> GW
PIPE --> KV
BOT --> TCP
KV --> CARD
KV --> REP
KV --> DASH
sequenceDiagram
participant GH as GitHub
participant WH as Webhook route
participant Bot as Chat SDK bot
participant Pipe as runSecurityPipeline
participant SB as Sandbox
participant Orch as AgentOrchestrator
participant Redis as Upstash audit keys
participant UI as Report SSE plus UI
GH->>WH: POST delivery signed
WH->>WH: Dedup X-GitHub-Delivery
WH->>Bot: Route PR thread event
Bot->>Pipe: Audit intent
Pipe->>SB: Checkout PR branch
Pipe->>Orch: Recon plus layered agents
Orch-->>Redis: Stream events findings
Pipe->>Redis: Audit JSON complete
Bot->>GH: Summary card with report URL
Redis->>UI: GET report SSE plus page
The webhook path is not a dumb proxy: deduplication, Chat SDK routing, sandbox lifecycle, Redis-backed progress, and SSE are all first-class.
Recon → AgentOrchestrator.run (layered parallel ToolLoopAgents, PipelineMemory, stream hooks) → optional PR summary → runThreatSynthesis → postProcessAudit (score, grade, compliance tags). Each agent uses stopWhen: stepCountIs(...), structured Output.object / Zod schemas, and optional skills from lib/skills.
flowchart LR
R[Recon languages deps secrets]
L[Layered ToolLoopAgents]
T[Threat synthesis]
P[Post-process score grade]
R --> L --> T --> P
buildExecutionLayers topologically sorts agents by dependsOn. Each layer runs with Promise.all. Example shape: parallel specialists → compliance-auditor (after core scanners) → learnings (after prior agents; may emit finalFindings and verdict).
flowchart TD
L1["Layer N parallel independent agents"]
L2["compliance-auditor depends on security-scan dependency-audit secret-scanner"]
L3["learnings depends on all prior"]
L1 --> L2 --> L3
Definitions are side-effect registered from lib/agents/definitions/index.ts; resolution via lib/agents/registry.ts.
| Agent | Role | Definition |
|---|---|---|
security-scan |
Principal AppSec on diff, CWE/OWASP, optional fix hints | security-scan.ts |
pentest |
Offensive reasoning, attack surface | pentest.ts |
api-security |
HTTP handlers, auth, IDOR, CSRF | api-security.ts |
secret-scanner |
Secrets on added lines | secret-scanner.ts |
dependency-audit |
npm audit / CVE interpretation | dependency-audit.ts |
infrastructure-review |
Docker, K8s, Terraform, CI | infrastructure-review.ts |
compliance-auditor |
Maps findings to PCI/SOC2/HIPAA/NIST/ASVS | compliance-auditor.ts |
code-quality |
AST smells, complexity | code-quality.ts |
architecture |
Coupling, Mermaid from graphs | architecture.ts |
test-coverage |
Changed logic vs tests | test-coverage.ts |
documentation |
Doc gaps, API drift | documentation.ts |
performance |
N+1, blocking async | performance.ts |
pr-summary |
Structured PR narrative | pr-summary.ts |
learnings |
Verdict, team patterns, finalFindings |
learnings.ts |
Critical/high findings with fix hints → sandbox on PR branch → apply patch or fix agent → validate → Octokit commit → optional reviewPullRequest re-run. See lib/fix/.
| Layer | Choices |
|---|---|
| App | Next.js 16 App Router, React 19, TypeScript, proxy.ts + NextAuth |
| AI | ai@6 ToolLoopAgent, Vercel AI Gateway, Zod 4 structured output |
| Bot | chat + @chat-adapter/github, @chat-adapter/state-redis (TCP) |
| Sandbox | @vercel/sandbox, bash-tool |
| Data | @upstash/redis REST for audits; REDIS_URL TCP for Chat SDK |
| Report UI | Recharts, Mermaid, Shiki, react-diff-viewer-continued |
| Quality | Biome, Vitest |
More: .planning/research/STACK.md, CLAUDE.md.
- Webhook deduplication via
X-GitHub-Delivery+ Redis SETNX - Zod at API boundaries;
AuditResultSchemafor stored payloads - Sandboxed git and commands; partial failure recorded per agent in orchestrator
- Rate limits and cooldowns in audit runner and auto-trigger helpers
- Node 20+
- GitHub App → webhook
POST /api/webhooks/github - Upstash REST (
KV_*/UPSTASH_*per.env.example) for audits - TCP
REDIS_URLfor Chat SDK state (distinct from Upstash) - Vercel AI Gateway (OIDC on Vercel;
vercel link+vercel env pulllocally)
npm install
cp .env.example .env.local
npm run devPoint the GitHub App webhook at your deployment (or ngrok) with path /api/webhooks/github.
See .env.example for the full list. Highlights:
| Variable | Role |
|---|---|
GITHUB_APP_*, GITHUB_WEBHOOK_SECRET, GITHUB_BOT_USERNAME |
GitHub App |
GITHUB_TOKEN |
Octokit: PRs, commits, sandbox git |
KV_REST_API_URL, KV_REST_API_TOKEN (or Upstash names) |
Audit + stream storage |
REDIS_URL |
Chat SDK adapter |
NEXTAUTH_*, GITHUB_CLIENT_ID, GITHUB_CLIENT_SECRET |
Dashboard OAuth |
NEXT_PUBLIC_APP_URL |
Absolute /report/... links in comments |
dev, build, start, lint / lint:fix, test, v0:generate — see package.json.
app/api/webhooks/github/ # Primary webhook
app/api/report/.../ # Audit JSON + SSE
app/dashboard/ # OAuth, demo, learnings, knowledge, tracking
app/report/.../ # Interactive report
lib/analysis/ # Pipeline, recon, threat synthesis, scoring
lib/agents/ # Orchestrator, registry, definitions
lib/bot.ts # Chat SDK entry, intents
lib/fix/ # Apply, validate, commit
lib/redis.ts # Upstash audit storage
Deeper structure: clawguard-plan.md.
MIT — see LICENSE.
Built for OpenClaw Hack_001 — Vienna · OpenClaw & Agents · Cybersecurity

