vision: CI provider adapter + signal classifier — decouple agents from forge-specific CI #1138
Labels
No labels
action
backlog
blocked
bug-report
cannot-reproduce
in-progress
in-triage
needs-triage
prediction/actioned
prediction/dismissed
prediction/unreviewed
priority
rejected
reproduced
tech-debt
underspecified
vision
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference: disinto-admin/disinto#1138
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "%!s()"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Architectural response to the 2026-04-21 CI chaos-monkey cascade (Codeberg #843). Long-horizon; filed as vision, not a near-term task.
Motivation
dev-poll, review-poll, supervisor, and the gardener all reach directly into Woodpecker internals (SQLite at
/var/lib/woodpecker/woodpecker.sqlite, REST at/api/repos/2/pipelines/...) and into Forgejo's combined commit status endpoint. This is fine while disinto targets only Woodpecker+Forgejo on a single box. It will not generalize.Disinto's stated direction is to bootstrap factories for arbitrary projects — mobile (Xcode + emulator CI), web (Playwright + Vite), crypto (Anvil, Hardhat fork, ZK provers), data (Spark, Airflow). Each domain has radically different:
We cannot hardcode "
docker restart disinto-woodpecker-agent" as the universal recovery action.Proposal
Two separable pieces.
Part A — CI Provider adapter
A narrow interface in
lib/ci/that every consumer calls:One implementation per backend:
lib/ci/woodpecker.sh,lib/ci/gh-actions.sh,lib/ci/gitlab.sh. Project declares its backend inprojects/<name>.toml:All dev-poll / reviewer / supervisor / gardener code reads only through these helpers. No direct SQLite, no direct Forgejo combined-status calls from decision paths.
Part B — Signal classifier
Between the adapter and every consumer, a classifier function:
Inputs to the classifier:
ci_get_provider_health()..disinto/ci-flakes.ymlper-project allowlist of known flaky patterns. A crypto project declares"anvil port 8545 in use"; a mobile project declares"no provisioning profile found". Shared patterns (network timeouts, DNS failures) live in a shared library file.unknowncases, a small prompt takes the per-step log tail + PR diff and returns one of {code, test-harness, ci-config, flake}. This is the #894 triage pattern, promoted from supervisor sweeper to first-class service.Agents never see raw pipeline state. They subscribe to verdicts. CI-fix prompts (#1050/#1051) receive classified context rather than a combined log tail.
Non-goals
USE_CI_ADAPTER=1.Why this is vision and not backlog
Incremental steps when work begins
lib/ci/woodpecker.shbehind the interface — pure refactor, no consumer changes.Related
Scope-compression note (2026-04-21 vision-pass review):
This vision is long-arc — it pays off when disinto targets a second CI provider (GitHub Actions, GitLab, Buildkite). Today disinto targets only Woodpecker+Forgejo on a single host, so the adapter's generalization benefit is hypothetical.
Explicit non-blocker statement: this issue does not block #1139 (circuit breaker) or #894 (supervisor stuck-PR sweeper). Both can ship as Woodpecker-specific implementations now and migrate to this adapter later. The circuit breaker's v1 threshold evaluator reads Woodpecker directly; the stuck-PR sweeper's triage prompt takes raw step logs. Neither needs the adapter interface to exist.
Suggested policy: leave this issue parked as
visionindefinitely. Escalate only when one of:dev-poll/reviewer/supervisorbecome a measurable bottleneck to solving a separate fragility problem.Until then, prefer inlining Woodpecker-specific calls over anticipatory abstraction. Premature abstraction is itself a fragility source (harder to modify, harder to debug, harder for dev-agents to pattern-match on).
No change requested in scope or acceptance criteria — just clarifying that this vision shouldn't be read as a precondition for the near-term resilience work.