Fix 410 Gone on bootstrap fetch with API transport
execute() was calling transition(Active) before spawning quire-ci,
setting the DB state to 'active'. The GET /api/run/bootstrap handler
checks state == 'pending' and returns 410 if not, so quire-ci always
got 410 on its first (and only) bootstrap fetch.

For API transport, the bootstrap endpoint owns the pending→active
transition (it also stamps started_at_ms). Skip the DB write in
execute() for that transport mode; update local state only so the
later transition(Complete/Failed) call passes the state-machine check.

https://claude.ai/code/session_01VwRTUXLHcJ48iQUwB3wfgE
change
commit 3d456f487f52c69dac31276efcd98220d74723c9
author Claude <noreply@anthropic.com>
date
parent vyorwupt
diff --git a/quire-server/src/ci/run.rs b/quire-server/src/ci/run.rs
index d4c1c66..d86e0b3 100644
--- a/quire-server/src/ci/run.rs
+++ b/quire-server/src/ci/run.rs
@@ -307,7 +307,20 @@ impl Run {
         sentry_dsn: Option<&str>,
         transport: Option<&Transport>,
     ) -> Result<()> {
-        self.transition(RunState::Active, None)?;
+        // For API transport the GET /api/run/bootstrap endpoint owns the
+        // pending → active transition (it sets started_at_ms when quire-ci
+        // fetches the payload). Calling transition() here would set state =
+        // 'active' in the DB before quire-ci connects, causing the endpoint
+        // to return 410 Gone. Update local state only so the later
+        // transition(Complete/Failed) call passes the state-machine check.
+        let uses_api_transport = transport
+            .map(|t| t.mode == TransportMode::Api)
+            .unwrap_or(false);
+        if uses_api_transport {
+            self.state = RunState::Active;
+        } else {
+            self.transition(RunState::Active, None)?;
+        }
 
         let run_dir = self.path();
         let log_path = run_dir.join("quire-ci.log");