- Status: Accepted
- Date: 2026-07-12
- Deciders: thulasi.ram (architect)
Context
Section titled “Context”There are two different needs that many CIs blur: composing sub-pipelines within one run, and triggering separate pipelines (possibly cross-repo, cross-team) on completion.
Decision
Section titled “Decision”Two clean primitives:
invoke= nest — a sub-pipeline in the same Run (shared lineage, one durable lifecycle, one permission scope). Composition/reuse (0006).on: upstream= trigger — a new Run, causally linked (on: { upstream: { pipeline, status } }). Works cross-repo via the same event mechanism, gated by RBAC. The causation edge is recorded in the event log (0013) for lineage/audit (“why did this run start”).- Monorepo needs no cross-repo machinery: CEL path/branch/tag trigger filters
(
on: { push, paths: ["services/api/**"] }).
Mental model: nest = one run; trigger = new run.
Consequences
Section titled “Consequences”- Tidy model that composes with everything; lineage is first-class.
- Cross-repo triggering is an RBAC-gated event, not a special subsystem.
Alternatives considered
Section titled “Alternatives considered”- invoke-only (no cross-run) — crams unrelated pipelines/teams into one run + one perm scope.
- Concourse-style resource-triggered cross-pipeline graph — revives deferred resource complexity; heavy for v1.