PR gate
Local model execution conflicts with ephemeral CI: every CI job would need model credentials, a warm checkout, and minutes-per-slice runtimes. TheSpider's first-class team pattern is a persistent runner daemon plus a cheap gate poll — CI does no model work at all.
Architecture
forge webhook ──▶ server (creates incremental campaign, changed_paths from forge API)
▲
│ polls claimable campaigns
thespider-agent daemon (team box / self-hosted runner)
• holds project-scoped token + model creds
• managed clone: fetch + checkout exact commit
• claim → run models locally → submit
│
CI job ──GET /v1/campaigns/{id}/gate──▶ server
• exit 0 pass / 1 fail / 2 pending
• NO secrets, NO model runtime in CI
Enable the forge webhook
Set GITHUB_WEBHOOK_SECRET on the server to enable POST /v1/webhooks/github. On a pull_request opened/synchronized event, the server:
- Maps the PR's
repo_remote_urlto a project. - Fetches changed paths from the forge API (paths only — consistent with the data boundary).
- Creates an incremental campaign scoped by pass-scope globs + risk triggers.
Run the daemon
On a team box or self-hosted CI runner:
thespider-agent daemon --workdir /var/lib/thespider --models sonnet
The daemon polls GET /v1/projects/{id}/campaigns/claimable, does a managed clone of the campaign's exact commit into a stable per-repo directory, then claims/runs/submits. See The agent for the full loop, robustness, and git-auth notes.
repo_remote_url to a URL the runner can actually clone (SSH with a loaded ssh-agent, or HTTPS with an embedded token / credential helper).Poll the gate from CI
CI itself only calls one cheap endpoint:
thespider-agent gate --campaign <id>
# exit 0 = pass, 1 = fail (new findings), 2 = pending
Under the hood that is GET /v1/campaigns/{id}/gate → { status: pass|fail|pending, new_findings:[...] }. No model credentials, no long runtimes in CI — see deploy/ci-gate-example.md for a drop-in workflow.
Interpret gate results
| Exit | Meaning | CI action |
|---|---|---|
0 | pass — no new findings on the PR | allow merge |
1 | fail — new findings whose earliest sighting is the PR branch (and intersect changed_paths) | block / require triage |
2 | pending — the daemon hasn't finished yet | wait and re-poll |
Next steps
- The agent — every daemon flag.
- Data handling — what the webhook and daemon transmit.