Skip to content

Commit 7c1449f

Browse files
committed
init: coven-github GitHub App scaffold
coven-github is the Coven-native GitHub App adapter: assign an issue to your familiar, get a PR back. ## Structure Rust workspace with four crates: - crates/config — Config/FamiliarConfig types (TOML-loaded) - crates/github — GitHub API client: Check Runs, installation tokens, PR + issue comment stubs - crates/webhook — HMAC-validated webhook receiver (axum); event parsing; task dispatch - crates/worker — Task runner: spawns coven-code --headless, streams progress, opens PRs; ephemeral workspace lifecycle - crates/server — Binary entry point (clap CLI: `serve`) ## Also included - COVEN-GITHUB.md — full product spec (vision, arch, session lifecycle, headless delta, GitHub App registration, familiar identity, Cave integration, sponsor/premium tier, recovery design, V1 milestones, V2 backlog) - README.md — public-facing description and self-hosting overview - config/example.toml — annotated config template - docs/self-hosting.md — GitHub App registration walkthrough - .github/workflows/ci.yml — cargo check + clippy + test cargo check --all-targets: clean (zero errors)
0 parents  commit 7c1449f

25 files changed

Lines changed: 4431 additions & 0 deletions

File tree

.github/workflows/ci.yml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
env:
10+
CARGO_TERM_COLOR: always
11+
12+
jobs:
13+
check:
14+
name: cargo check + clippy + test
15+
runs-on: ubuntu-latest
16+
steps:
17+
- uses: actions/checkout@v4
18+
- uses: dtolnay/rust-toolchain@stable
19+
with:
20+
components: clippy
21+
- uses: Swatinem/rust-cache@v2
22+
- name: cargo check
23+
run: cargo check --all-targets
24+
- name: clippy
25+
run: cargo clippy --all-targets -- -D warnings
26+
- name: test
27+
run: cargo test --all

.gitignore

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
/target/
2+
config/local.toml
3+
keys/
4+
*.pem
5+
.env

COVEN-GITHUB.md

Lines changed: 326 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,326 @@
1+
# COVEN-GITHUB.md — Product Spec
2+
3+
*coven-github: Coven-native GitHub App coding agent*
4+
*Authors: Cody 🦄 + Sage 🌿 · June 3, 2026*
5+
6+
---
7+
8+
## Vision
9+
10+
A GitHub App that turns any Coven-configured familiar into a first-class GitHub coding agent. Assign an issue to `@cody` (or any familiar bot user), and the familiar plans, edits, commits, and opens a pull request — with live oversight in CovenCave and no black-box model lock-in.
11+
12+
---
13+
14+
## Problem
15+
16+
Every existing GitHub coding agent is a closed system:
17+
18+
- **GitHub Copilot Workspace** — GitHub's model, GitHub's context window, GitHub's behavior. No familiar identity, no persistent memory, no operator skills. Paid gate (Pro+ / Enterprise).
19+
- **Devin** — Full-VM agent, strong execution, but ~$500/month, proprietary, model-locked.
20+
- **OpenHands** — Open source, model-agnostic, GitHub integration exists — but no identity, no skills, no cross-session memory.
21+
- **Sweep AI** — Closest structural analogue (true GitHub App), but GPT-4-locked, no identity, effectively abandoned the GitHub-first path.
22+
23+
**No competitor has:** persistent familiar identity + composable skill system + cross-session memory + BYOM + open source + self-hostable + owned oversight UI.
24+
25+
That combination is unoccupied territory. Coven owns all five primitives already.
26+
27+
---
28+
29+
## Architecture
30+
31+
### Two-Layer Separation
32+
33+
```
34+
Layer 1 — GitHub ingress (coven-github)
35+
Webhooks · auth · event routing · Check Runs · PR lifecycle
36+
37+
Layer 2 — Execution quality (coven-code)
38+
Agent loop · model · tools · memory · skills · output
39+
```
40+
41+
Mixing these creates a monolith that is hard to test, deploy, and reason about.
42+
`coven-github` is a thin adapter. `coven-code` is the runtime.
43+
44+
### Session Lifecycle
45+
46+
```
47+
1. Webhook arrives
48+
→ validate HMAC signature (reject invalid)
49+
→ parse event: repo, ref, issue body/diff, assignee/label/mention
50+
51+
2. Task enqueued
52+
→ create GitHub Check Run (status: in_progress)
53+
→ post "starting…" comment on issue
54+
55+
3. Worker dequeues
56+
→ provision ephemeral workspace (tmp dir or container)
57+
→ clone repo via installation access token
58+
→ write session-brief.json: issue body, repo context, familiar config
59+
60+
4. coven-code session spawned
61+
→ --headless --context session-brief.json --output result.json
62+
→ familiar reads code, edits files, runs tests, commits
63+
64+
5. Progress streaming
65+
→ coven-code emits structured events (file_changed, test_run, etc.)
66+
→ worker updates Check Run annotations in real time
67+
→ "Cody: 3/8 tests passing…" visible inline in GitHub UI
68+
69+
6. Completion
70+
→ coven-code pushes branch via installation token
71+
→ worker opens draft PR (body: familiar summary + session link)
72+
→ Check Run updated: completed / success or failure
73+
→ issue comment: "PR #42 opened — watch in Cave →"
74+
75+
7. Iteration
76+
→ PR review comment "@cody fix the type error on line 42"
77+
→ re-triggers step 3 with review context appended to brief
78+
```
79+
80+
### Infrastructure
81+
82+
| Component | Role |
83+
|---|---|
84+
| **Webhook receiver** | HTTP server; validates HMAC; publishes to task queue |
85+
| **Task queue** | Decouples ingest from execution; Redis, SQS, or in-process (dev) |
86+
| **Worker pool** | Pulls tasks; manages coven-code processes; streams progress |
87+
| **Ephemeral workspaces** | Per-task isolated filesystems; Docker containers in production |
88+
| **GitHub API client** | Installation tokens (1hr TTL + refresh); Check Runs; PRs; comments |
89+
| **Config store** | Per-installation familiar config; model routing; secret storage |
90+
91+
---
92+
93+
## coven-code Delta: Headless Mode
94+
95+
The execution runtime needs the following additions to work as a GitHub App backend:
96+
97+
### `--headless` flag
98+
- Disables ratatui TUI entirely
99+
- Routes all output to stdout (structured JSON events) + `--output <result.json>`
100+
- Exits 0 on success, non-0 on failure
101+
102+
### `--context <session-brief.json>`
103+
Session brief schema:
104+
```json
105+
{
106+
"trigger": "issue_assigned",
107+
"repo": { "owner": "OpenCoven", "name": "coven-code", "clone_url": "...", "default_branch": "main" },
108+
"issue": { "number": 42, "title": "...", "body": "...", "labels": [] },
109+
"familiar": { "id": "cody", "model": "anthropic/claude-sonnet-4-6", "skills": ["systematic-debugging"] },
110+
"workspace": { "root": "/tmp/task-abc123" },
111+
"auth": { "token": "<installation_access_token>" }
112+
}
113+
```
114+
115+
### `--output <result.json>`
116+
Result envelope schema:
117+
```json
118+
{
119+
"status": "success" | "failure" | "partial",
120+
"branch": "cody/fix-issue-42",
121+
"commits": [{ "sha": "...", "message": "..." }],
122+
"files_changed": ["src/auth.rs"],
123+
"summary": "Fixed OAuth token refresh by adding a 60-second clock skew buffer.",
124+
"pr_body": "## Summary\n\n...",
125+
"events": [...],
126+
"exit_reason": null | "test_failure" | "ambiguous_spec" | "git_conflict" | "infra_error"
127+
}
128+
```
129+
130+
### Git auth forwarding
131+
- Accept `GIT_ASKPASS` or `GIT_TOKEN` env var for push operations
132+
- Use installation access token — not user credentials
133+
134+
### Exit codes
135+
```
136+
0 — success: commits made, result.json written
137+
1 — failure: agent gave up, result.json written with exit_reason
138+
2 — infra error: workspace, git, or tool failure (retry-safe)
139+
3 — ambiguous: agent needs clarification (posts comment, exits cleanly)
140+
```
141+
142+
---
143+
144+
## GitHub App Registration
145+
146+
### Required Permissions
147+
148+
| Permission | Level |
149+
|---|---|
150+
| Contents | Read + Write |
151+
| Issues | Read + Write |
152+
| Pull requests | Read + Write |
153+
| Checks | Write |
154+
| Metadata | Read (baseline) |
155+
| Workflows | Write (optional; needed if touching CI config) |
156+
157+
### Webhook Events
158+
159+
| Event | Use |
160+
|---|---|
161+
| `issues``assigned` | Primary task trigger |
162+
| `issue_comment``created` | `@mention` and iteration |
163+
| `pull_request_review_comment``created` | Review feedback iteration |
164+
| `check_suite` / `check_run` | CI awareness |
165+
| `push` | Branch tracking (optional) |
166+
167+
### Bot User
168+
169+
The GitHub App creates a bot user. Bot username configurable per installation.
170+
Default: `coven-cody[bot]`. Orgs can configure `@cody`, `@nova`, etc. via familiar mapping.
171+
172+
---
173+
174+
## Familiar Identity in GitHub
175+
176+
The PR body and issue comments are written in the familiar's voice:
177+
178+
```markdown
179+
## Hey, I'm Cody 🦄
180+
181+
I looked at issue #42 and here's what I found:
182+
183+
The OAuth token refresh path in `src/auth/refresh.rs` wasn't accounting for
184+
clock skew between the client and the auth server. I added a 60-second buffer\nto the expiry check.
185+
186+
**Changed:** `src/auth/refresh.rs` (+12 / -3)
187+
**Tests:** 8/8 passing (added 2 regression cases)
188+
189+
[Watch this session in CovenCave →](https://cave.opencoven.ai/sessions/abc123)
190+
```
191+
192+
The `pr_body` field in `result.json` is generated by the familiar — not a template. This is familiar voice, not boilerplate.
193+
194+
---
195+
196+
## CovenCave Integration
197+
198+
### Coven Board — `coven-github` Tasks
199+
200+
A new task source in the Coven Board alongside manual sessions:
201+
202+
```
203+
Inbox | Running | Review | GitHub
204+
205+
GitHub tab shows:
206+
● coven-code #42 — Fix OAuth refresh running 2m ago
207+
↳ Cody · 3/8 tests passing · fix/issue-42
208+
● cast-codes #18 — Implement spell compiler review 18m ago
209+
↳ Cody · PR #31 opened
210+
● coven-cave #7 — Browser seam fix done 1h ago
211+
↳ Cody · merged as #88
212+
```
213+
214+
Click any row → open Cave session for live oversight.
215+
216+
### Check Run Deep Link
217+
218+
Every Check Run summary includes a `details_url` pointing to the Cave session:
219+
`https://cave.opencoven.ai/sessions/<id>` (or `localhost:3000/sessions/<id>` for self-hosted).
220+
221+
---
222+
223+
## Sponsor / Premium Tier
224+
225+
`coven-github` is open source and self-hostable. The hosted tier monetizes around managed infra and advanced orchestration.
226+
227+
### Open Source (self-hosted)
228+
- Full GitHub App functionality
229+
- BYOM
230+
- Single familiar per installation
231+
- Local CovenCave oversight
232+
- Community support
233+
234+
### Sponsor Tier (GitHub Sponsors)
235+
- **Small sponsor:** Early access + hosted worker credits (5 tasks/day)
236+
- **Medium sponsor:** 50 tasks/day + cloud familiar memory (cross-repo)
237+
- **Large sponsor / org:** Unlimited tasks + multi-familiar routing + dedicated worker + SLA
238+
239+
### Hosted Premium (Enterprise)
240+
- Managed worker fleet (no infra to run)
241+
- Multi-familiar routing (Nova dispatches Cody vs security familiar vs ops familiar)
242+
- Cloud familiar memory — persistent cross-repo, cross-PR context
243+
- Organization-wide installation
244+
- Proactive PR review (familiar reviews incoming PRs unprompted)
245+
- Priority model credits / usage bundling
246+
- White-label bot username
247+
248+
---
249+
250+
## Recovery Design (Sweep's Lesson)
251+
252+
**80% of agent failures are infra, not reasoning.** Design for it from day one.
253+
254+
| Failure class | Behavior |
255+
|---|---|
256+
| Git conflict | Agent posts comment: "I hit a conflict on `main` — can you rebase and re-trigger?" |
257+
| Test failure (fixable) | Agent iterates up to 3 times, then posts partial PR with test output |
258+
| Test failure (unknown root cause) | Posts comment with test output + what it tried; exits with `exit_reason: test_failure` |
259+
| Ambiguous spec | Posts clarifying question as issue comment; exits cleanly (code 3) |
260+
| Infra error (container, git, OOM) | Retries up to 2 times; marks Check Run `failure` with infra note |
261+
| Token expiry | Automatic refresh; transparent to agent session |
262+
263+
All failures are visible in CovenCave with full session replay.
264+
265+
---
266+
267+
## V1 Milestones
268+
269+
### M1 — coven-code headless mode (~3 days)
270+
- `--headless`, `--context`, `--output` flags
271+
- `result.json` envelope
272+
- Git token forwarding
273+
- Exit code contract
274+
- Basic integration test: inject synthetic issue context → verify PR-shaped output
275+
276+
### M2 — coven-github webhook service (~4 days)
277+
- GitHub App registration (manifest + private key handling)
278+
- Webhook receiver with HMAC validation
279+
- In-process task queue (Redis/SQS in production)
280+
- Worker: spawns coven-code, streams progress
281+
- Check Runs client: create / update / complete
282+
- Issue comment: start + PR link
283+
284+
### M3 — PR lifecycle + iteration (~3 days)
285+
- Branch push via installation token
286+
- Draft PR opener with familiar-voice body
287+
- PR review comment re-trigger
288+
- `@cody` mention in issue comments
289+
290+
### M4 — CovenCave GitHub tab (~2 days)
291+
- New task source in Coven Board
292+
- Check Run deep link → Cave session
293+
- Running/review/done states
294+
295+
### M5 — Docs + self-hosting guide (~2 days)
296+
- `docs/self-hosting.md`
297+
- GitHub App registration walkthrough
298+
- `config/example.toml`
299+
- Sponsor tier landing copy
300+
301+
**Total: ~2 weeks to a working V1 end-to-end.**
302+
303+
---
304+
305+
## V2 Backlog
306+
307+
- Multi-familiar routing (Nova dispatches based on issue labels / repo context)
308+
- Cross-repo familiar memory
309+
- Skill auto-detection from repo type (Rust → rust-expert skill, etc.)
310+
- Organization-wide installation
311+
- Proactive PR review (unprompted)
312+
- `coven-github` CLI: `coven-github assign --issue 42 --familiar cody`
313+
- Metrics dashboard in CovenCave (tasks completed, PR merge rate, avg time)
314+
315+
---
316+
317+
## Open Questions
318+
319+
1. **Bot username strategy** — single `coven-cody[bot]` app vs. per-org custom bot username (requires separate GitHub App per org)?
320+
2. **Container isolation** — Docker per task vs. Fly Machines vs. GitHub Actions ephemeral runners for the execution environment?
321+
3. **Memory persistence** — where does cross-PR familiar memory live in the hosted tier? Convex? Postgres? Coven's own storage?
322+
4. **Model billing** — does the operator bring their own API key, or does OpenCoven proxy model calls in the hosted tier?
323+
324+
---
325+
326+
*Spec: Cody 🦄 + Sage 🌿 · June 3, 2026*

0 commit comments

Comments
 (0)