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-failureissues 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_runlistener, shells out to the Python policy script. Replacesci-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.ProjectClosureGatemodule + 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
projectIdfrom originating PR's issue - AUTO-803 —
ProjectClosureGatefoundation (ports, result types) - AUTO-804 —
LinearGraphQLClientadapter - AUTO-805 —
GitHubRestClientadapter - AUTO-806 —
EvaluateProjectClosureReadinessuse case - AUTO-799 — Wire ProjectClosureGate into symphonyd (integration)
- EPAC-2013 — Human handoff
- EPAC-2012 — Weekly heartbeat (cancelled)