Riddim main Projects CI Failure Feedback Mechanism

CI Failure Feedback Mechanism

Auto-create Linear issues when watched epac CI workflows fail (especially post-merge), and auto-close them when CI goes green again.

Why now

We auto-merge unreviewed PRs once gating CI passes. Non-gated checks and post-merge workflows (TestFlight Build, App Store submission, backend deploys, scheduled regressions) can fail silently after merge, eroding the quality bar. The existing handler listened to a single workflow and only fired on pull_request events, so push-to-main failures never surfaced as work.

Motivating failure: TestFlight Build run 26349982662 failed after merge of PR #550 (EPAC-1993). No Linear issue was created. CI stayed red unattended.

Objective

Every failure on a watched epac CI workflow surfaces as a Linear issue within minutes, with enough context that a developer (autonomous or human) can pick it up cold. The same mechanism auto-closes the issue when CI goes green again. Symphonyd does not declare an EPAC Project ready for human handoff until post-merge CI has settled.

Success criteria

  • Failure on any watched workflow opens a Linear issue in EPAC within 5 minutes, priority Urgent, state Todo, label ci-failure.
  • A flapping workflow does not open N copies — repeat failures comment on the existing open issue (capped at 5).
  • When the same workflow + branch reports a successful run, the matching open issue auto-closes with a comment linking the green run.
  • Symphonyd parks on its existing handoff path until the closure gate signals ready: all non-handoff issues terminal, zero open ci-failure issues in the Project, every watched workflow on every Project merge commit reported success.

Architecture

Three artifacts, two repos:

  • .github/workflows/ci-failure-handler.yml (epac) — Adapter: workflow_run listener, shells out to the Python policy script. Replaces ci-failure-linear.yml.
  • scripts/ci/ci_failure_to_linear.py (epac) — Policy: typed inputs; thin Linear client + thin GitHub PR-resolver client. Unit-testable without GitHub Actions.
  • ProjectClosureGate module + symphonyd stop-condition swap (autopilot) — Policy: pure evaluator. Replaces "all issues terminal" with multi-signal readiness for EPAC-team Projects.

Architecture rubric: existing handler scored 4.0/10. This project targets ~9.0/10 by extracting policy behind a typed interface and thin clients.

Child issues

  • EPAC-2007 — Extract policy into ci_failure_to_linear.py (foundation)
  • EPAC-2008 — Replace handler YAML + expand watched workflows
  • EPAC-2009 — Dedup by (workflow_name, branch)
  • EPAC-2010 — Auto-close on success
  • EPAC-2011 — Inherit projectId from originating PR's issue
  • AUTO-803 — ProjectClosureGate foundation (ports, result types)
  • AUTO-804 — LinearGraphQLClient adapter
  • AUTO-805 — GitHubRestClient adapter
  • AUTO-806 — EvaluateProjectClosureReadiness use case
  • AUTO-799 — Wire ProjectClosureGate into symphonyd (integration)
  • EPAC-2013 — Human handoff
  • EPAC-2012 — Weekly heartbeat (cancelled)