ADR-0001: Where batch and pipeline work runs¶
Status: Accepted · Date: 2026-08-14
Context¶
The platform had three ways to run work that isn't a long-lived service, and no
written rule for choosing between them. That produced a specific oddity: Argo
Workflows was installed in every environment — opt-in locally, on by default on
AWS, with an S3 artifact bucket and an IRSA role — to carry exactly one
manifest, a DR failover runbook. Zero WorkflowTemplates, zero CronWorkflows.
Meanwhile the ML training story it had been installed for was a single bare
kind: Job, submitted by the idp:run-training-job scaffolder action.
The recurring question — "should this move to Argo Workflows?" — kept being re-litigated because the answer was never recorded.
Decision¶
Argo Workflows is for multi-step, artifact-passing, human-gated, in-cluster work. Nothing else moves there.
| Mechanism | Use it when | Do not use it when |
|---|---|---|
| GitHub Actions | The work is triggered by a source change, gates a merge, or must run for an external contributor with no cluster access | It needs in-cluster endpoints, or must pause for a human mid-run |
| Kubernetes CronJob | A single container on a schedule, no DAG, no artifacts | You need step ordering, per-step images, or a gate |
| Argo Workflows | Multiple steps with different images, artifacts passed between them, a conditional gate, or a suspend step for human approval |
It's a single container, or it must work where Argo isn't installed |
What this means concretely¶
Stays in GitHub Actions. All build/test/scan/image-push/GitOps promotion
(.github/workflows/build-and-deploy.yml, ci.yml, contract-check.yml,
codeql.yml, eval.yml). Moving CI into the cluster would trade fast PR
feedback and a well-understood secret model for nothing — and it would stop
working for anyone without cluster credentials, which for an open-source template
is most contributors.
Stays a CronJob. The DORA exporter, the Tech Insights exporter, and the two flaky-test exporters. Each is one container on a schedule with no artifacts. They must also keep working on a cluster where Argo Workflows is not installed, which is now the default (it is part of the opt-in AI/ML layer).
Moves to Argo Workflows. Two WorkflowTemplates, plus the DR runbook that
was already there:
ml-training-pipeline—train → evaluate → register → deploy-gate. The evaluate step fails the run below a minimum accuracy, anddeploy-gateis asuspendstep. Those two things are the entire justification: aJobwould log a bad model and exit 0, and it has nowhere to pause for a human.llm-eval-pipeline— the full nightly / pre-promotion eval matrix, which needs in-cluster endpoints (the MCP servers, the KAgent A2A endpoint, an in-cluster model server, Langfuse) that GitHub Actions cannot reach. PR-time smoke evals stay in Actions, where they gate the merge.
Consequences¶
idp:run-training-jobsubmits aWorkflowwhen theworkflowtemplates.argoproj.ioCRD is present, and falls back to the originalJobwhen it is not. The fallback is not optional: Argo Workflows is part of the opt-in AI/ML layer, so a core-only install legitimately lacks it, and the scaffolder template must still work there.IDP_TRAINING_BACKEND=jobforces the fallback.- The fallback path silently loses the accuracy gate and the approval step. The action logs a warning saying so rather than pretending they ran.
- A single-region AWS install without
--with-aihas no Argo Workflows, so the DR failover runbook is unavailable there. Acceptable — DR is a multi-region feature andbootstrap-multiregion.shinstalls it — but worth knowing. - The training pipeline runs 5 pods where the Job ran 1. Requests are modest and the Job fallback remains for constrained clusters.
Alternatives considered¶
Move CI into Argo Workflows (Tekton-style). Rejected: it loses PR-time feedback, complicates the secret model, and breaks for contributors without a cluster.
Move the exporters to CronWorkflow. Rejected: they gain nothing from a DAG
and would acquire a hard dependency on an optional component.
Remove Argo Workflows entirely and keep the bare Job. Genuinely tempting
given it carried one manifest — but the accuracy gate and the approval step are
real requirements that a Job cannot express, and the DR runbook already needs
typed parameters and per-step images.
References¶
kubernetes/argo-workflows/workflowtemplates/backstage/app/packages/backend/src/modules/idpRunTrainingJob.tsaws/argo-workflows/failover-runbook.yamldocs/multi-region.md