feat: Forgejo integration + Receipt protocol

Tasks completed:
- 4.1: Forgejo API client (reqwest, HMAC-SHA256, Issue/Comment/Label/PR)
- 4.2: POST /api/v1/webhooks/forgejo (signature verify, event parse)
- 4.3: Issue → Task conversion (agent:* → type, priority:* → priority)
- 4.4: Task status → Issue label sync (status:todo/doing/done)
- 4.5: Receipt → Issue comment (emoji + summary + artifacts)
- 4.6: Reconciliation stub
- 4.7: Tests for HMAC, Issue→Task conversion
- 6.1: POST /api/v1/receipts (validate + transition)
- 6.2: PR artifact validation via Forgejo API
- 6.3: No-trust check (only Completed after validation)
- 6.4: Receipt tests

19/19 tests pass. cargo check clean.
This commit is contained in:
Zer4tul 2026-05-11 19:42:03 +08:00
parent b75546bda6
commit f60f028f96
7 changed files with 735 additions and 22 deletions

View file

@ -1,6 +1,7 @@
mod api;
mod config;
mod core;
mod integrations;
use clap::Parser;
@ -81,6 +82,8 @@ async fn main() {
));
tokio::spawn(async move { heartbeat_checker.run().await });
let app_state = api::AppState::new(config.clone(), store.clone());
let app = axum::Router::new()
.route("/healthz", axum::routing::get(|| async { "ok" }))
.route("/api/v1/agents/register", axum::routing::post(api::register_agent))
@ -92,7 +95,7 @@ async fn main() {
"/api/v1/webhooks/forgejo",
axum::routing::post(api::forgejo_webhook),
)
.with_state(store.clone());
.with_state(app_state);
let listener = tokio::net::TcpListener::bind(format!(
"{}:{}",